生成代码工程

This commit is contained in:
root 2026-06-17 12:58:09 +08:00
parent 1fddc38c2d
commit 01603ce617
15 changed files with 17099 additions and 2 deletions

36
CMakeLists.txt Normal file
View File

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.14)
project(tps VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if (MSVC)
add_compile_options(/utf-8)
endif()
# ============================================================
# TPS
# ============================================================
add_executable(tps
src/main.cpp
src/event_handler.cpp
src/template_manager.cpp
src/plan_manager.cpp
src/distribution_monitor.cpp
)
target_include_directories(tps PRIVATE include)
# ============================================================
# 使 assert
# ============================================================
add_executable(tps_test
tests/basic_test.cpp
src/event_handler.cpp
src/template_manager.cpp
src/plan_manager.cpp
src/distribution_monitor.cpp
)
target_include_directories(tps_test PRIVATE include)

View File

@ -1,3 +1,83 @@
# 任务自主规划软件开发项目
# 任务规划软件TPS— C++ 核心处理单元
暂无描述
## 概述
任务规划软件Task Planning System, TPS是战场任务规划系统的核心处理单元实现从事件感知到任务生成、计划管理、方案分发与状态监控的闭环管理。本工程实现了 TPS 的核心数据模型与业务逻辑。
## 工程结构
```
.
├── CMakeLists.txt # CMake 构建配置
├── README.md # 本文件
├── include/
│ ├── app.hpp # 核心数据结构(数据库表模型)
│ ├── event_handler.hpp # 事件接收与处理模块
│ ├── template_manager.hpp # 模板管理模块
│ ├── plan_manager.hpp # 计划管理模块
│ └── distribution_monitor.hpp # 方案分发与状态监控模块
├── src/
│ ├── main.cpp # 命令行入口(演示流程)
│ ├── event_handler.cpp # 事件处理实现
│ ├── template_manager.cpp # 模板管理实现
│ ├── plan_manager.cpp # 计划管理实现
│ └── distribution_monitor.cpp # 分发监控实现
└── tests/
└── basic_test.cpp # 单元测试(标准库 assert
```
## 需求覆盖
| CSCI需求标识 | 需求名称 | 模块/函数 |
|--------------|----------|-----------|
| SRS-F-01-001 | 接收临机事件和规划事件 | `EventHandler::receiveEvent()` |
| SRS-F-01-002 | 事件数据过滤转化封装 | `EventHandler::processEvent()` |
| SRS-F-02-001 | 接收待处理事件列表 | `EventHandler::getPendingEvents()` |
| SRS-F-02-004 | 生成作战任务并送交处理 | `PlanManager::createPlan()` |
| SRS-F-03-001 | 任务模板先验知识库版本选择 | `TemplateManager::getConfig()` |
| SRS-F-03-002 | 先验知识库配置调整 | `TemplateManager::updateConfig()` |
| SRS-F-04-001 | 接收推送的任务模板集合数据 | `TemplateManager::receiveTemplates()` |
| SRS-F-04-005 | 人环模式下用户选择任务模板 | `TemplateManager::selectTemplate()` |
| SRS-F-04-006 | 自主执行模式下任务模板自动选择提示 | `TemplateManager::autoSelectTemplate()` |
| SRS-F-05-001 | 集中式计划管理与偏好排序 | `PlanManager::sortPlans()` |
| SRS-F-05-002 | 计划详情可视化与HITL通知 | `PlanManager::notifyHITL()` |
| SRS-F-05-003 | 计划重配置操作与可视化 | `PlanManager::reconfigurePlan()` |
| SRS-F-05-004 | 分布式计划管理与算法处理 | `PlanManager::mergeAndCheckConsistency()` |
| SRS-F-06-001 | 方案驱动分发与状态响应 | `DistributionMonitor::distributePlan()` / `receiveAck()` |
| SRS-F-06-002 | 驱动状态监控与异常信息展示 | `DistributionMonitor::receiveTelemetry()` / `triggerAlarm()` |
## 编译与运行
### 前置条件
- CMake ≥ 3.14
- C++17 兼容的编译器GCC 8+, Clang 10+, MSVC 2019+
### 构建
```bash
cd codegen-runs/codegen_af1ed1d727e14f1cb7e99c1a9f65e3f6
mkdir build && cd build
cmake ..
cmake --build .
```
### 运行主程序
```bash
# Linux/macOS
./tps
# Windows
tps.exe
```
### 运行单元测试
```bash
# Linux/macOS
./tps_test
# Windows
tps_test.exe
```

15635
events.ndjson Normal file

File diff suppressed because one or more lines are too long

37
generation.json Normal file

File diff suppressed because one or more lines are too long

132
include/app.hpp Normal file
View File

@ -0,0 +1,132 @@
#ifndef TPS_APP_HPP
#define TPS_APP_HPP
#include <string>
#include <vector>
#include <cstdint>
// ============================================================
// 核心数据结构(对应需求文档中的数据库表结构)
// ============================================================
/**
*
* Event
*/
struct Event {
std::string event_id; ///< 事件ID主键
std::string event_type; ///< 事件类型:"临机" / "规划"
std::string occur_time; ///< 发生时间ISO 8601 格式)
std::string title; ///< 事件标题
std::string description; ///< 事件描述
std::string location; ///< 位置坐标WGS-84
int priority{0}; ///< 优先级,数值越大优先级越高
std::string status; ///< 状态:"未处理" / "已处理" / "拒绝"
std::string create_time; ///< 系统记录时间
};
/**
*
* TaskTemplate
*/
struct TaskTemplate {
std::string template_id; ///< 模板ID主键
std::string name; ///< 模板名称
std::string version; ///< 版本号(如 v1.0.0
std::string content_path; ///< 内容文件路径
std::string scenario; ///< 适用场景(如 "侦察" / "打击"
bool enabled{true}; ///< 是否启用
std::string create_time; ///< 创建时间
};
/**
*
* TemplateVersion
*/
struct TemplateVersion {
uint64_t id{0}; ///< 自增主键
std::string template_id; ///< 关联模板ID
std::string version; ///< 版本标识
std::string release_time; ///< 上线时间
std::string expire_time; ///< 过期时间(可为空)
std::string status; ///< "有效" / "过期" / "草稿"
};
/**
*
* TaskPlan
*/
struct TaskPlan {
std::string plan_id; ///< 计划ID主键
std::string name; ///< 计划名称
std::string event_ids; ///< 关联事件ID列表JSON数组
std::string template_id; ///< 引用模板ID
std::string status; ///< 状态:"草案" / "执行中" / "完成"
std::string create_time; ///< 创建时间
std::string update_time; ///< 最后修改时间
};
/**
*
* PlanNode
*/
struct PlanNode {
std::string node_id; ///< 节点ID主键
std::string plan_id; ///< 关联计划ID
std::string type; ///< 节点类型:"任务" / "决策" / "HITL"
std::string content; ///< 描述或指令
int order_index{0}; ///< 执行顺序
std::string status; ///< 执行状态
bool hitl_required{false}; ///< 是否需人工干预
};
/**
*
* DistributionLog
*/
struct DistributionLog {
uint64_t log_id{0}; ///< 日志ID主键
std::string plan_id; ///< 对应计划ID
std::string asset_type; ///< 目标资产类型
std::string send_time; ///< 发送时刻
std::string status; ///< "成功" / "失败" / "重试"
int retry_count{0}; ///< 重试次数最大3次
std::string ack_code; ///< 响应码ACK/NACK等
};
/**
*
* StatusLog
*/
struct StatusLog {
uint64_t log_id{0}; ///< 日志ID主键
std::string asset_id; ///< 资产ID
std::string status_code; ///< 状态码(如 "OK" / "ERROR_01"
std::string detail_info; ///< 详细信息
std::string timestamp; ///< 数据采集时间
std::string source; ///< 数据来源标识
};
// ============================================================
// 标准化内部事件模型(经过过滤、转换和封装后的标准格式)
// ============================================================
/**
*
* SRS-F-01-002
*/
struct NormalizedEvent {
std::string event_id; ///< 原始事件ID
std::string event_type; ///< 事件类型
std::string normalized_time; ///< 统一转换后的时间戳UTC
std::string title; ///< 标题
std::string description; ///< 描述
double latitude{0.0}; ///< 纬度WGS-84已转换
double longitude{0.0}; ///< 经度WGS-84已转换
int priority{0}; ///< 优先级
std::string status; ///< 状态
std::string receive_time; ///< 系统接收时间
std::string node_id; ///< 处理节点ID
};
#endif // TPS_APP_HPP

View File

@ -0,0 +1,86 @@
#ifndef TPS_DISTRIBUTION_MONITOR_HPP
#define TPS_DISTRIBUTION_MONITOR_HPP
#include "app.hpp"
#include <string>
#include <vector>
// ============================================================
// 方案分发与状态监控模块SU-07 方案分发单元 & SU-08 状态监控单元)
// ============================================================
/**
*
*
*/
class DistributionMonitor {
public:
DistributionMonitor() = default;
~DistributionMonitor() = default;
/**
*
*
* @requirement(name="方案驱动分发与状态响应", id="SRS-F-06-001")
* ACK信号
*
*
* @param planId ID
* @param assetType "卫星" / "无人机" / "雷达"
* @return
*/
DistributionLog distributePlan(const std::string& planId,
const std::string& assetType);
/**
* ACK
*
* @param logId ID
* @param ackCode "ACK" / "NACK"
*/
void receiveAck(uint64_t logId, const std::string& ackCode);
/**
*
*
* @requirement(name="驱动状态监控与异常信息展示", id="SRS-F-06-002")
*
*
*
* @param rawData
* @param source
* @return
*/
StatusLog receiveTelemetry(const std::string& rawData,
const std::string& source);
/**
*
*
* @param statusCode
* @return true
*/
bool triggerAlarm(const std::string& statusCode);
/**
*
*/
std::vector<DistributionLog> getDistributionLogs() const;
/**
*
*/
std::vector<StatusLog> getStatusLogs() const;
private:
std::vector<DistributionLog> distLogs_; ///< 分发日志
std::vector<StatusLog> statusLogs_; ///< 状态日志
uint64_t nextLogId_{1}; ///< 自增日志ID
/**
*
*/
bool sendToAsset(const std::string& planId, const std::string& assetType);
};
#endif // TPS_DISTRIBUTION_MONITOR_HPP

73
include/event_handler.hpp Normal file
View File

@ -0,0 +1,73 @@
#ifndef TPS_EVENT_HANDLER_HPP
#define TPS_EVENT_HANDLER_HPP
#include "app.hpp"
#include <string>
#include <vector>
// ============================================================
// 事件接收与处理模块SU-01 / SU-02 事件接收单元 & 事件处理单元)
// ============================================================
/**
*
* SRS-F-01-001SRS-F-01-002
* SRS-F-02-001
*/
class EventHandler {
public:
EventHandler() = default;
~EventHandler() = default;
/**
*
*
* @requirement(name="接收临机事件和规划事件", id="SRS-F-01-001")
* JSON/XML
* TCP/IP
*
*
* @param rawData JSON/XML
* @param format "json" "xml"
* @return true false
*/
bool receiveEvent(const std::string& rawData, const std::string& format);
/**
*
*
* @requirement(name="事件数据过滤转化封装", id="SRS-F-01-002")
*
* ID等元数据
*
* @param raw
* @return NormalizedEvent
*/
NormalizedEvent processEvent(const Event& raw);
/**
*
*
* @requirement(name="接收待处理事件列表", id="SRS-F-02-001")
*
*
* @return
*/
std::vector<NormalizedEvent> getPendingEvents() const;
/**
*
*/
std::vector<Event> getAllEvents() const;
private:
std::vector<Event> rawEvents_; ///< 原始事件缓存
std::vector<NormalizedEvent> normalized_; ///< 标准化事件缓存
/**
*
*/
bool validateEvent(const std::string& rawData, const std::string& format);
};
#endif // TPS_EVENT_HANDLER_HPP

109
include/plan_manager.hpp Normal file
View File

@ -0,0 +1,109 @@
#ifndef TPS_PLAN_MANAGER_HPP
#define TPS_PLAN_MANAGER_HPP
#include "app.hpp"
#include <string>
#include <vector>
// ============================================================
// 计划管理模块SU-06 计划管理单元)
// ============================================================
/**
*
*
*/
class PlanManager {
public:
PlanManager() = default;
~PlanManager() = default;
/**
*
*
* @requirement(name="生成作战任务并送交处理", id="SRS-F-02-004")
* "生成任务"
*
*
* @param name
* @param eventIds ID列表
* @param templateId 使ID
* @return ID
*/
std::string createPlan(const std::string& name,
const std::vector<std::string>& eventIds,
const std::string& templateId);
/**
*
*
* @requirement(name="集中式计划管理与偏好排序", id="SRS-F-05-001")
*
*
* @param weightPriority
* @param weightTime
* @return
*/
std::vector<TaskPlan> sortPlans(double weightPriority, double weightTime);
/**
*
*
* @requirement(name="计划详情可视化与HITL通知", id="SRS-F-05-002")
*
*
* @param planId ID
* @param nodeId ID
* @param user
* @return true
*/
bool notifyHITL(const std::string& planId,
const std::string& nodeId,
const std::string& user);
/**
*
*
* @requirement(name="计划重配置操作与可视化", id="SRS-F-05-003")
*
*
*
* @param planId ID
* @param newNodes
* @return ID
*/
std::string reconfigurePlan(const std::string& planId,
const std::vector<PlanNode>& newNodes);
/**
*
*
* @requirement(name="分布式计划管理与算法处理", id="SRS-F-05-004")
*
*
* @param externalPlans
* @return true
*/
bool mergeAndCheckConsistency(const std::vector<TaskPlan>& externalPlans);
/**
*
*/
std::vector<TaskPlan> getAllPlans() const;
/**
*
*/
std::vector<PlanNode> getPlanNodes(const std::string& planId) const;
private:
std::vector<TaskPlan> plans_; ///< 本地计划集合
std::map<std::string, std::vector<PlanNode>> planNodes_; ///< planId -> 节点列表
/**
* IDUUID模拟
*/
std::string generateId();
};
#endif // TPS_PLAN_MANAGER_HPP

View File

@ -0,0 +1,99 @@
#ifndef TPS_TEMPLATE_MANAGER_HPP
#define TPS_TEMPLATE_MANAGER_HPP
#include "app.hpp"
#include <string>
#include <vector>
#include <map>
// ============================================================
// 模板管理模块SU-05 模板管理单元)
// ============================================================
/**
*
*
*/
class TemplateManager {
public:
TemplateManager() = default;
~TemplateManager() = default;
/**
*
*
* @requirement(name="接收推送的任务模板集合数据", id="SRS-F-04-001")
*
*
*
* @param payload JSON/XML
* @param format "json" / "xml"
* @return true
*/
bool receiveTemplates(const std::string& payload, const std::string& format);
/**
*
*
* @return
*/
std::vector<TaskTemplate> getTemplateList() const;
/**
*
*
* @requirement(name="任务模板先验知识库版本选择", id="SRS-F-03-001")
*
*
* @param templateId ID
* @return
*/
std::vector<TemplateVersion> getConfig(const std::string& templateId) const;
/**
*
*
* @requirement(name="先验知识库配置调整", id="SRS-F-03-002")
*
*
*
* @param key
* @param value
* @return true
*/
bool updateConfig(const std::string& key, const std::string& value);
/**
*
*
* @requirement(name="自主执行模式下任务模板自动选择提示", id="SRS-F-04-006")
*
*
*
* @param scenario
* @return ID
*/
std::string autoSelectTemplate(const std::string& scenario);
/**
*
*
* @requirement(name="人环模式下用户选择任务模板", id="SRS-F-04-005")
* "选用此模板"
*
*
* @param templateId ID
* @param version
* @return true
*/
bool selectTemplate(const std::string& templateId, const std::string& version);
private:
std::vector<TaskTemplate> templates_; ///< 模板库
std::map<std::string, std::vector<TemplateVersion>> versionMap_; ///< 模板ID -> 版本列表
std::map<std::string, std::string> configStore_; ///< 配置参数存储
std::string selectedTemplateId_; ///< 当前选中模板ID
std::string lockedVersion_; ///< 锁定版本
};
#endif // TPS_TEMPLATE_MANAGER_HPP

View File

@ -0,0 +1,114 @@
#include "distribution_monitor.hpp"
#include <algorithm>
#include <ctime>
#include <sstream>
#include <iomanip>
DistributionLog DistributionMonitor::distributePlan(const std::string& planId,
const std::string& assetType) {
// SRS-F-06-001: 将任务方案分发至作战资产
DistributionLog log;
log.log_id = nextLogId_++;
log.plan_id = planId;
log.asset_type = assetType;
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
log.send_time = oss.str();
// 模拟发送
bool sent = sendToAsset(planId, assetType);
if (sent) {
log.status = "发送中";
log.retry_count = 0;
log.ack_code = "";
} else {
log.status = "失败";
log.retry_count = 0;
log.ack_code = "NACK";
}
distLogs_.push_back(log);
return log;
}
void DistributionMonitor::receiveAck(uint64_t logId, const std::string& ackCode) {
// SRS-F-06-001: 处理ACK响应更新分发状态
for (auto& log : distLogs_) {
if (log.log_id == logId) {
log.ack_code = ackCode;
if (ackCode == "ACK") {
log.status = "成功";
} else {
log.status = "失败";
// 重试机制最多3次
if (log.retry_count < 3) {
log.retry_count++;
log.status = "重试";
}
}
break;
}
}
}
StatusLog DistributionMonitor::receiveTelemetry(const std::string& rawData,
const std::string& source) {
// SRS-F-06-002: 接收资产遥测数据并解析
StatusLog slog;
slog.log_id = nextLogId_++;
slog.asset_id = "ASSET-" + std::to_string(statusLogs_.size() + 1);
// 模拟解析遥测数据
if (rawData.find("ERROR") != std::string::npos ||
rawData.find("FAIL") != std::string::npos) {
slog.status_code = "ERROR_01";
slog.detail_info = rawData;
} else {
slog.status_code = "OK";
slog.detail_info = "遥测数据正常";
}
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
slog.timestamp = oss.str();
slog.source = source;
statusLogs_.push_back(slog);
// 自动检测异常并报警
if (slog.status_code != "OK") {
triggerAlarm(slog.status_code);
}
return slog;
}
bool DistributionMonitor::triggerAlarm(const std::string& statusCode) {
// SRS-F-06-002: 检测异常状态码,触发报警
if (statusCode.empty() || statusCode == "OK") {
return false;
}
// 模拟报警信号(实际应对接告警服务)
// 报警触发成功
return true;
}
std::vector<DistributionLog> DistributionMonitor::getDistributionLogs() const {
return distLogs_;
}
std::vector<StatusLog> DistributionMonitor::getStatusLogs() const {
return statusLogs_;
}
bool DistributionMonitor::sendToAsset(const std::string& planId,
const std::string& assetType) {
// 模拟发送到目标资产,假设总是成功
(void)planId;
(void)assetType;
return true;
}

83
src/event_handler.cpp Normal file
View File

@ -0,0 +1,83 @@
#include "event_handler.hpp"
#include <algorithm>
#include <ctime>
#include <sstream>
#include <iomanip>
bool EventHandler::receiveEvent(const std::string& rawData, const std::string& format) {
// SRS-F-01-001: 接收事件数据包支持JSON/XML格式
if (rawData.empty()) {
return false;
}
if (format != "json" && format != "xml") {
return false;
}
// 模拟解析:将原始数据作为 title生成一个临时 Event
Event evt;
evt.event_id = "EVT-" + std::to_string(rawEvents_.size() + 1);
evt.event_type = (format == "json") ? "临机" : "规划";
evt.occur_time = "2025-01-01T00:00:00";
evt.title = rawData.substr(0, 64);
evt.description = rawData;
evt.location = "0.0,0.0";
evt.priority = 5;
evt.status = "未处理";
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
evt.create_time = oss.str();
rawEvents_.push_back(evt);
// 自动进行标准化处理
NormalizedEvent norm = processEvent(evt);
normalized_.push_back(norm);
return true;
}
NormalizedEvent EventHandler::processEvent(const Event& raw) {
// SRS-F-01-002: 事件数据过滤转化封装
NormalizedEvent norm;
norm.event_id = raw.event_id;
norm.event_type = raw.event_type;
// 模拟时间戳转换:直接使用原始时间作为示例
norm.normalized_time = raw.occur_time;
norm.title = raw.title;
norm.description = raw.description;
// 模拟坐标转换:从字符串解析经纬度
norm.latitude = 0.0;
norm.longitude = 0.0;
norm.priority = raw.priority;
norm.status = raw.status;
// 添加元数据
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
norm.receive_time = oss.str();
norm.node_id = "NODE-TPS-01";
return norm;
}
std::vector<NormalizedEvent> EventHandler::getPendingEvents() const {
// SRS-F-02-001: 获取尚未生成任务的事件集合
std::vector<NormalizedEvent> pending;
for (const auto& evt : normalized_) {
if (evt.status == "未处理") {
pending.push_back(evt);
}
}
return pending;
}
std::vector<Event> EventHandler::getAllEvents() const {
return rawEvents_;
}
bool EventHandler::validateEvent(const std::string& rawData, const std::string& format) {
return !rawData.empty() && (format == "json" || format == "xml");
}

157
src/main.cpp Normal file
View File

@ -0,0 +1,157 @@
/**
* @file main.cpp
* @brief TPS
*
* TPS
*
*/
#include <iostream>
#include <vector>
#include <string>
#include "event_handler.hpp"
#include "template_manager.hpp"
#include "plan_manager.hpp"
#include "distribution_monitor.hpp"
/**
* @brief TPS
*
*
* 1.
* 2.
* 3.
* 4.
* 5.
*
* @return int 退
*/
int main() {
std::cout << "=== 任务规划软件TPS核心模块演示 ===\n\n";
// ==========================================================
// 1. 事件接收与处理
// ==========================================================
std::cout << "[1] 事件接收与处理\n";
EventHandler evtHandler;
// SRS-F-01-001: 接收原始事件
bool ok1 = evtHandler.receiveEvent(R"({"type":"","target":""})", "json");
bool ok2 = evtHandler.receiveEvent(R"(<event type=""><target>无人机编队</target></event>)", "xml");
std::cout << " 接收 JSON 事件: " << (ok1 ? "成功" : "失败") << "\n";
std::cout << " 接收 XML 事件: " << (ok2 ? "成功" : "失败") << "\n";
// SRS-F-02-001: 获取待处理事件
auto pending = evtHandler.getPendingEvents();
std::cout << " 待处理事件数: " << pending.size() << "\n\n";
// ==========================================================
// 2. 模板管理
// ==========================================================
std::cout << "[2] 模板管理\n";
TemplateManager tmplMgr;
// SRS-F-04-001: 接收模板集合
bool tplOk = tmplMgr.receiveTemplates(R"({"name":"","version":"v2.0.0"})", "json");
std::cout << " 接收模板数据: " << (tplOk ? "成功" : "失败") << "\n";
auto templates = tmplMgr.getTemplateList();
std::cout << " 可用模板数: " << templates.size() << "\n";
// SRS-F-04-006: 自主模式自动推荐
std::string recommended = tmplMgr.autoSelectTemplate("侦察");
std::cout << " 自主推荐模板: " << (recommended.empty() ? "无匹配" : recommended) << "\n";
// SRS-F-03-001: 获取版本配置
if (!templates.empty()) {
auto versions = tmplMgr.getConfig(templates[0].template_id);
std::cout << " 模板版本数: " << versions.size() << "\n";
}
// SRS-F-03-002: 更新配置
bool cfgOk = tmplMgr.updateConfig("max_retry", "3");
std::cout << " 更新配置: " << (cfgOk ? "成功" : "失败") << "\n\n";
// ==========================================================
// 3. 计划管理
// ==========================================================
std::cout << "[3] 计划管理\n";
PlanManager planMgr;
// SRS-F-02-004: 创建计划草案(至少选择一个事件)
if (pending.size() >= 2) {
std::vector<std::string> evtIds = {pending[0].event_id, pending[1].event_id};
std::string planId = planMgr.createPlan("打击计划-001", evtIds, "TPL-1");
std::cout << " 创建计划: " << (planId.empty() ? "失败" : planId) << "\n";
// SRS-F-05-001: 权重排序
auto sorted = planMgr.sortPlans(0.7, 0.3);
std::cout << " 排序后计划数: " << sorted.size() << "\n";
// SRS-F-05-002: HITL通知
bool hitlOk = planMgr.notifyHITL(planId, "NODE-001", "commander");
std::cout << " HITL通知: " << (hitlOk ? "已发送" : "失败") << "\n";
}
// SRS-F-05-003: 计划重配置(若无计划则跳过)
if (!planMgr.getAllPlans().empty()) {
std::vector<PlanNode> newNodes;
PlanNode node;
node.node_id = "NODE-NEW-001";
node.type = "任务";
node.content = "无人机侦察目标区域";
node.order_index = 1;
node.status = "待执行";
node.hitl_required = false;
newNodes.push_back(node);
std::string reconfId = planMgr.reconfigurePlan(
planMgr.getAllPlans()[0].plan_id, newNodes);
std::cout << " 重配置计划: " << (reconfId.empty() ? "失败" : reconfId) << "\n";
}
// SRS-F-05-004: 分布式一致性检查
std::vector<TaskPlan> externalPlans;
TaskPlan ext;
ext.plan_id = "EXT-PLAN-001";
ext.name = "外部协同计划";
ext.status = "草案";
ext.create_time = "2025-01-01T00:00:00Z";
ext.update_time = ext.create_time;
externalPlans.push_back(ext);
bool consistent = planMgr.mergeAndCheckConsistency(externalPlans);
std::cout << " 一致性检查: " << (consistent ? "通过" : "冲突") << "\n\n";
// ==========================================================
// 4. 方案分发与状态监控
// ==========================================================
std::cout << "[4] 方案分发与状态监控\n";
DistributionMonitor distMon;
// SRS-F-06-001: 分发计划至资产
DistributionLog dlog = distMon.distributePlan("PLAN-001", "无人机");
std::cout << " 分发日志ID: " << dlog.log_id
<< ", 状态: " << dlog.status << "\n";
// 模拟接收ACK
distMon.receiveAck(dlog.log_id, "ACK");
auto logs = distMon.getDistributionLogs();
if (!logs.empty()) {
std::cout << " 最新分发状态: " << logs.back().status
<< ", ACK: " << logs.back().ack_code << "\n";
}
// SRS-F-06-002: 接收遥测数据
StatusLog slog = distMon.receiveTelemetry("遥测: 高度5000m, 速度200km/h", "数据链-01");
std::cout << " 遥测状态码: " << slog.status_code << "\n";
StatusLog errLog = distMon.receiveTelemetry("ERROR: 通信中断", "数据链-02");
std::cout << " 异常遥测状态码: " << errLog.status_code
<< " (报警: " << (errLog.status_code != "OK" ? "已触发" : "") << ")\n";
std::cout << "\n=== TPS 核心模块演示完成 ===\n";
return 0;
}

132
src/plan_manager.cpp Normal file
View File

@ -0,0 +1,132 @@
#include "plan_manager.hpp"
#include <algorithm>
#include <ctime>
#include <sstream>
#include <iomanip>
#include <set>
std::string PlanManager::createPlan(const std::string& name,
const std::vector<std::string>& eventIds,
const std::string& templateId) {
// SRS-F-02-004: 创建任务计划草案
if (name.empty() || eventIds.empty() || templateId.empty()) {
return "";
}
TaskPlan plan;
plan.plan_id = generateId();
plan.name = name;
plan.event_ids = "[";
for (size_t i = 0; i < eventIds.size(); ++i) {
if (i > 0) plan.event_ids += ",";
plan.event_ids += "\"" + eventIds[i] + "\"";
}
plan.event_ids += "]";
plan.template_id = templateId;
plan.status = "草案";
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
plan.create_time = oss.str();
plan.update_time = plan.create_time;
plans_.push_back(plan);
return plan.plan_id;
}
std::vector<TaskPlan> PlanManager::sortPlans(double weightPriority, double weightTime) {
// SRS-F-05-001: 根据用户设定的权重对计划列表进行加权排序
std::vector<TaskPlan> sorted = plans_;
std::sort(sorted.begin(), sorted.end(),
[weightPriority, weightTime](const TaskPlan& a, const TaskPlan& b) {
// 模拟加权评分:优先级 * weightPriority + 时间因子 * weightTime
double scoreA = 0.0, scoreB = 0.0;
// 从 plan_id 长度模拟时间因子越新的计划ID越长
scoreA = 1.0 * weightPriority + static_cast<double>(a.plan_id.size()) * weightTime * 0.01;
scoreB = 1.0 * weightPriority + static_cast<double>(b.plan_id.size()) * weightTime * 0.01;
return scoreA > scoreB;
});
return sorted;
}
bool PlanManager::notifyHITL(const std::string& planId,
const std::string& nodeId,
const std::string& user) {
// SRS-F-05-002: 遇人工干预节点时推送通知
if (planId.empty() || nodeId.empty() || user.empty()) {
return false;
}
// 模拟推送通知(实际应对接消息服务)
return true;
}
std::string PlanManager::reconfigurePlan(const std::string& planId,
const std::vector<PlanNode>& newNodes) {
// SRS-F-05-003: 执行计划重配置,生成新计划
auto it = std::find_if(plans_.begin(), plans_.end(),
[&planId](const TaskPlan& p) { return p.plan_id == planId; });
if (it == plans_.end() || newNodes.empty()) {
return "";
}
TaskPlan newPlan = *it;
newPlan.plan_id = generateId();
newPlan.name = it->name + "-重配置";
newPlan.status = "草案";
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
newPlan.create_time = oss.str();
newPlan.update_time = newPlan.create_time;
plans_.push_back(newPlan);
planNodes_[newPlan.plan_id] = newNodes;
return newPlan.plan_id;
}
bool PlanManager::mergeAndCheckConsistency(const std::vector<TaskPlan>& externalPlans) {
// SRS-F-05-004: 聚合多源计划并运行一致性检查
if (externalPlans.empty()) {
return true;
}
// 模拟一致性检查:检查是否有重复的 plan_id
std::set<std::string> existingIds;
for (const auto& p : plans_) {
existingIds.insert(p.plan_id);
}
for (const auto& ext : externalPlans) {
if (existingIds.count(ext.plan_id) > 0) {
return false; // 冲突
}
plans_.push_back(ext);
existingIds.insert(ext.plan_id);
}
return true;
}
std::vector<TaskPlan> PlanManager::getAllPlans() const {
return plans_;
}
std::vector<PlanNode> PlanManager::getPlanNodes(const std::string& planId) const {
auto it = planNodes_.find(planId);
if (it != planNodes_.end()) {
return it->second;
}
return {};
}
std::string PlanManager::generateId() {
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << "PLAN-" << now << "-" << plans_.size() + 1;
return oss.str();
}

98
src/template_manager.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "template_manager.hpp"
#include <algorithm>
#include <ctime>
#include <sstream>
#include <iomanip>
#include <climits>
bool TemplateManager::receiveTemplates(const std::string& payload, const std::string& format) {
// SRS-F-04-001: 接收任务模板集合数据包,增量或全量更新
if (payload.empty() || (format != "json" && format != "xml")) {
return false;
}
// 模拟解析:将 payload 作为一条新模板插入
TaskTemplate tmpl;
tmpl.template_id = "TPL-" + std::to_string(templates_.size() + 1);
tmpl.name = "模板-" + std::to_string(templates_.size() + 1);
tmpl.version = "v1.0.0";
tmpl.content_path = "/data/templates/" + tmpl.template_id + ".json";
tmpl.scenario = "通用";
tmpl.enabled = true;
std::time_t now = std::time(nullptr);
std::ostringstream oss;
oss << std::put_time(std::gmtime(&now), "%Y-%m-%dT%H:%M:%SZ");
tmpl.create_time = oss.str();
templates_.push_back(tmpl);
// 同时添加一个默认版本记录
TemplateVersion tv;
tv.id = versionMap_.size() + 1;
tv.template_id = tmpl.template_id;
tv.version = tmpl.version;
tv.release_time = tmpl.create_time;
tv.expire_time = "";
tv.status = "有效";
versionMap_[tmpl.template_id].push_back(tv);
return true;
}
std::vector<TaskTemplate> TemplateManager::getTemplateList() const {
// SRS-F-04-002: 返回可用模板列表
std::vector<TaskTemplate> result;
for (const auto& t : templates_) {
if (t.enabled) {
result.push_back(t);
}
}
return result;
}
std::vector<TemplateVersion> TemplateManager::getConfig(const std::string& templateId) const {
// SRS-F-03-001: 返回指定模板的所有版本记录
auto it = versionMap_.find(templateId);
if (it != versionMap_.end()) {
return it->second;
}
return {};
}
bool TemplateManager::updateConfig(const std::string& key, const std::string& value) {
// SRS-F-03-002: 更新配置参数,验证合法性
if (key.empty() || value.empty()) {
return false;
}
configStore_[key] = value;
return true;
}
std::string TemplateManager::autoSelectTemplate(const std::string& scenario) {
// SRS-F-04-006: 自主模式下运行匹配算法推荐最优模板
if (templates_.empty() || scenario.empty()) {
return "";
}
// 简化的匹配算法:返回第一个启用的模板
for (const auto& t : templates_) {
if (t.enabled) {
selectedTemplateId_ = t.template_id;
return t.template_id;
}
}
return "";
}
bool TemplateManager::selectTemplate(const std::string& templateId, const std::string& version) {
// SRS-F-04-005: 人环模式下用户选择模板并锁定版本
for (const auto& t : templates_) {
if (t.template_id == templateId && t.enabled) {
selectedTemplateId_ = templateId;
lockedVersion_ = version;
return true;
}
}
return false;
}

226
tests/basic_test.cpp Normal file
View File

@ -0,0 +1,226 @@
/**
* @file basic_test.cpp
* @brief TPS 使 assert
*/
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
#include "event_handler.hpp"
#include "template_manager.hpp"
#include "plan_manager.hpp"
#include "distribution_monitor.hpp"
/**
* @brief
*
* @requirement(name="接收临机事件和规划事件", id="SRS-F-01-001")
* @requirement(name="事件数据过滤转化封装", id="SRS-F-01-002")
* @requirement(name="接收待处理事件列表", id="SRS-F-02-001")
*/
void test_event_handler() {
std::cout << "[测试] EventHandler ... ";
EventHandler handler;
// SRS-F-01-001: 接收 JSON 事件
bool r1 = handler.receiveEvent(R"({"type":""})", "json");
assert(r1 == true);
// SRS-F-01-001: 接收 XML 事件
bool r2 = handler.receiveEvent(R"(<event/>)", "xml");
assert(r2 == true);
// 无效格式应返回 false
bool r3 = handler.receiveEvent("data", "yaml");
assert(r3 == false);
// 空数据应返回 false
bool r4 = handler.receiveEvent("", "json");
assert(r4 == false);
// SRS-F-01-002: 验证标准化处理后的数据有元数据
auto allEvents = handler.getAllEvents();
assert(!allEvents.empty());
// SRS-F-02-001: 待处理事件列表不应为空
auto pending = handler.getPendingEvents();
assert(!pending.empty());
// 标准化事件应包含处理节点ID
for (const auto& evt : pending) {
assert(!evt.node_id.empty());
assert(!evt.receive_time.empty());
}
std::cout << "通过\n";
}
/**
* @brief
*
* @requirement(name="接收推送的任务模板集合数据", id="SRS-F-04-001")
* @requirement(name="任务模板先验知识库版本选择", id="SRS-F-03-001")
* @requirement(name="先验知识库配置调整", id="SRS-F-03-002")
* @requirement(name="自主执行模式下任务模板自动选择提示", id="SRS-F-04-006")
* @requirement(name="人环模式下用户选择任务模板", id="SRS-F-04-005")
*/
void test_template_manager() {
std::cout << "[测试] TemplateManager ... ";
TemplateManager mgr;
// SRS-F-04-001: 接收模板数据
bool ok = mgr.receiveTemplates(R"({"name":""})", "json");
assert(ok == true);
// 模板列表应有数据
auto list = mgr.getTemplateList();
assert(!list.empty());
// SRS-F-03-001: 获取版本列表
auto versions = mgr.getConfig(list[0].template_id);
assert(!versions.empty());
assert(versions[0].status == "有效");
// SRS-F-03-002: 更新配置
bool cfgOk = mgr.updateConfig("timeout", "30");
assert(cfgOk == true);
// 空 key 应失败
bool cfgFail = mgr.updateConfig("", "30");
assert(cfgFail == false);
// SRS-F-04-006: 自主推荐
std::string rec = mgr.autoSelectTemplate("打击");
assert(!rec.empty());
// SRS-F-04-005: 人环选择
bool selOk = mgr.selectTemplate(list[0].template_id, "v1.0.0");
assert(selOk == true);
// 不存在的模板应失败
bool selFail = mgr.selectTemplate("NONEXIST", "v1.0.0");
assert(selFail == false);
std::cout << "通过\n";
}
/**
* @brief
*
* @requirement(name="生成作战任务并送交处理", id="SRS-F-02-004")
* @requirement(name="集中式计划管理与偏好排序", id="SRS-F-05-001")
* @requirement(name="计划详情可视化与HITL通知", id="SRS-F-05-002")
* @requirement(name="计划重配置操作与可视化", id="SRS-F-05-003")
* @requirement(name="分布式计划管理与算法处理", id="SRS-F-05-004")
*/
void test_plan_manager() {
std::cout << "[测试] PlanManager ... ";
PlanManager mgr;
// SRS-F-02-004: 创建计划(至少需要一个事件)
std::vector<std::string> evtIds = {"EVT-001", "EVT-002"};
std::string planId = mgr.createPlan("测试计划", evtIds, "TPL-001");
assert(!planId.empty());
// 空事件列表应失败
std::string failPlan = mgr.createPlan("空计划", {}, "TPL-001");
assert(failPlan.empty());
// SRS-F-05-001: 加权排序
auto sorted = mgr.sortPlans(0.8, 0.2);
assert(!sorted.empty());
// SRS-F-05-002: HITL通知
bool hitlOk = mgr.notifyHITL(planId, "NODE-HITL-01", "admin");
assert(hitlOk == true);
// SRS-F-05-003: 计划重配置
std::vector<PlanNode> newNodes;
PlanNode node;
node.node_id = "NODE-01";
node.type = "任务";
node.content = "侦察";
node.order_index = 1;
node.status = "待执行";
newNodes.push_back(node);
std::string reconfId = mgr.reconfigurePlan(planId, newNodes);
assert(!reconfId.empty());
assert(reconfId != planId); // 应是新ID
// SRS-F-05-004: 一致性检查
std::vector<TaskPlan> external;
TaskPlan ext;
ext.plan_id = "EXT-001";
ext.name = "外部计划";
ext.status = "草案";
external.push_back(ext);
bool consistent = mgr.mergeAndCheckConsistency(external);
assert(consistent == true);
// 重复ID应导致冲突
external.push_back(ext); // 相同的 ext.plan_id
bool conflict = mgr.mergeAndCheckConsistency(external);
assert(conflict == false);
std::cout << "通过\n";
}
/**
* @brief
*
* @requirement(name="方案驱动分发与状态响应", id="SRS-F-06-001")
* @requirement(name="驱动状态监控与异常信息展示", id="SRS-F-06-002")
*/
void test_distribution_monitor() {
std::cout << "[测试] DistributionMonitor ... ";
DistributionMonitor mon;
// SRS-F-06-001: 分发方案
DistributionLog dlog = mon.distributePlan("PLAN-001", "无人机");
assert(dlog.log_id > 0);
assert(dlog.plan_id == "PLAN-001");
assert(dlog.asset_type == "无人机");
// 接收 ACK
mon.receiveAck(dlog.log_id, "ACK");
auto logs = mon.getDistributionLogs();
assert(!logs.empty());
assert(logs.back().ack_code == "ACK");
// SRS-F-06-002: 接收正常遥测
StatusLog slog = mon.receiveTelemetry("正常数据包", "数据链-01");
assert(slog.status_code == "OK");
// SRS-F-06-002: 接收异常遥测(应触发报警)
StatusLog errLog = mon.receiveTelemetry("ERROR: 传感器故障", "数据链-02");
assert(errLog.status_code != "OK");
// 报警触发
bool alarm = mon.triggerAlarm("ERROR_01");
assert(alarm == true);
// "OK" 不应触发报警
bool noAlarm = mon.triggerAlarm("OK");
assert(noAlarm == false);
std::cout << "通过\n";
}
/**
* @brief
*/
int main() {
std::cout << "=== TPS 核心模块单元测试 ===\n\n";
test_event_handler();
test_template_manager();
test_plan_manager();
test_distribution_monitor();
std::cout << "\n所有测试通过!\n";
return 0;
}