|
|
|
|
@ -0,0 +1,314 @@
|
|
|
|
|
#include "DataFusionEngine.h"
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <chrono>
|
|
|
|
|
#include <random>
|
|
|
|
|
|
|
|
|
|
namespace Battlefield {
|
|
|
|
|
|
|
|
|
|
DataFusionEngine::DataFusionEngine() {
|
|
|
|
|
// 默认数据源权重
|
|
|
|
|
sourceWeights_ = {
|
|
|
|
|
{DataSourceType::SATELLITE_IMAGERY, 1.0},
|
|
|
|
|
{DataSourceType::UAV_SURVEILLANCE, 0.9},
|
|
|
|
|
{DataSourceType::EM_SIGNAL, 0.7},
|
|
|
|
|
{DataSourceType::FRIENDLY_REPORT, 0.8},
|
|
|
|
|
{DataSourceType::GROUND_SENSOR, 0.6}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DataFusionEngine::~DataFusionEngine() {
|
|
|
|
|
stop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DataFusionEngine::initialize(const std::map<std::string, std::string>& config) {
|
|
|
|
|
// 从配置加载参数
|
|
|
|
|
auto it = config.find("confidence_threshold");
|
|
|
|
|
if (it != config.end()) {
|
|
|
|
|
confidenceThreshold_ = std::stod(it->second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it = config.find("data_timeout_seconds");
|
|
|
|
|
if (it != config.end()) {
|
|
|
|
|
dataTimeoutSeconds_ = std::stod(it->second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it = config.find("max_trajectory_points");
|
|
|
|
|
if (it != config.end()) {
|
|
|
|
|
maxTrajectoryPoints_ = std::stoi(it->second);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log("Data Fusion Engine initialized successfully");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::start() {
|
|
|
|
|
if (!isRunning_) {
|
|
|
|
|
isRunning_ = true;
|
|
|
|
|
processingThread_ = std::thread(&DataFusionEngine::processThread, this);
|
|
|
|
|
log("Data Fusion Engine started");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::stop() {
|
|
|
|
|
isRunning_ = false;
|
|
|
|
|
queueCV_.notify_all();
|
|
|
|
|
|
|
|
|
|
if (processingThread_.joinable()) {
|
|
|
|
|
processingThread_.join();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log("Data Fusion Engine stopped");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::receiveData(const DataPacket& packet) {
|
|
|
|
|
std::lock_guard<std::mutex> lock(queueMutex_);
|
|
|
|
|
dataQueue_.push(packet);
|
|
|
|
|
statistics_.packetsReceived++;
|
|
|
|
|
queueCV_.notify_one();
|
|
|
|
|
|
|
|
|
|
// 触发数据回调
|
|
|
|
|
if (dataCallback_) {
|
|
|
|
|
dataCallback_(packet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::processThread() {
|
|
|
|
|
while (isRunning_) {
|
|
|
|
|
DataPacket packet;
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(queueMutex_);
|
|
|
|
|
queueCV_.wait(lock, [this]() {
|
|
|
|
|
return !dataQueue_.empty() || !isRunning_;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!isRunning_ && dataQueue_.empty()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!dataQueue_.empty()) {
|
|
|
|
|
packet = dataQueue_.front();
|
|
|
|
|
dataQueue_.pop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (packet.payload.empty()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
processDataPacket(packet);
|
|
|
|
|
statistics_.packetsProcessed++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::processDataPacket(const DataPacket& packet) {
|
|
|
|
|
std::vector<IdentifiedTarget> targets;
|
|
|
|
|
|
|
|
|
|
// 根据数据源类型解析
|
|
|
|
|
switch (packet.source) {
|
|
|
|
|
case DataSourceType::UAV_SURVEILLANCE:
|
|
|
|
|
targets = parseUAVData(packet);
|
|
|
|
|
break;
|
|
|
|
|
case DataSourceType::SATELLITE_IMAGERY:
|
|
|
|
|
targets = parseSatelliteData(packet);
|
|
|
|
|
break;
|
|
|
|
|
case DataSourceType::EM_SIGNAL:
|
|
|
|
|
targets = parseEMSensorData(packet);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// 其他数据源可能有自带的目标识别结果
|
|
|
|
|
targets = packet.detectedTargets;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 过滤低置信度目标
|
|
|
|
|
targets.erase(
|
|
|
|
|
std::remove_if(targets.begin(), targets.end(),
|
|
|
|
|
[this](const IdentifiedTarget& target) {
|
|
|
|
|
return target.confidence < confidenceThreshold_;
|
|
|
|
|
}),
|
|
|
|
|
targets.end()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!targets.empty()) {
|
|
|
|
|
updateSituation(targets);
|
|
|
|
|
statistics_.targetsIdentified += targets.size();
|
|
|
|
|
|
|
|
|
|
// 生成日志
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
ss << "Processed packet from source " << static_cast<int>(packet.source)
|
|
|
|
|
<< ", identified " << targets.size() << " targets";
|
|
|
|
|
log(ss.str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<IdentifiedTarget> DataFusionEngine::parseUAVData(const DataPacket& packet) {
|
|
|
|
|
std::vector<IdentifiedTarget> targets;
|
|
|
|
|
|
|
|
|
|
// 模拟AI目标识别
|
|
|
|
|
// 实际项目中会集成深度学习模型(如YOLO, Faster R-CNN)
|
|
|
|
|
|
|
|
|
|
// 示例:模拟识别一个装甲车队
|
|
|
|
|
for (int i = 0; i < 3; ++i) {
|
|
|
|
|
IdentifiedTarget target;
|
|
|
|
|
target.id = IdentifiedTarget::generateID();
|
|
|
|
|
target.type = (i == 0) ? TargetType::MAIN_BATTLE_TANK : TargetType::ARMORED_PERSONNEL_CARRIER;
|
|
|
|
|
target.typeName = (i == 0) ? "主战坦克" : "装甲运兵车";
|
|
|
|
|
target.position = packet.origin;
|
|
|
|
|
target.position.longitude += 0.001 * i; // 模拟位置偏移
|
|
|
|
|
target.confidence = 0.85 + (i * 0.05);
|
|
|
|
|
target.speed = 10.0 + (i * 5.0);
|
|
|
|
|
target.heading = 45.0;
|
|
|
|
|
target.threatLevel = (i == 0) ? ThreatLevel::HIGH : ThreatLevel::MEDIUM;
|
|
|
|
|
target.timestamp = packet.timestamp;
|
|
|
|
|
|
|
|
|
|
// 添加元数据
|
|
|
|
|
target.metadata["source"] = "UAV_SURVEILLANCE";
|
|
|
|
|
target.metadata["sensor_type"] = "Electro-Optical";
|
|
|
|
|
target.metadata["resolution"] = "1920x1080";
|
|
|
|
|
|
|
|
|
|
targets.push_back(target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return targets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<IdentifiedTarget> DataFusionEngine::parseSatelliteData(const DataPacket& packet) {
|
|
|
|
|
std::vector<IdentifiedTarget> targets;
|
|
|
|
|
|
|
|
|
|
// 模拟卫星影像解析
|
|
|
|
|
// 可集成对古代防御工事的识别
|
|
|
|
|
std::vector<std::pair<std::string, TargetType>> possibleTargets = {
|
|
|
|
|
{"古代长城遗迹", TargetType::ANCIENT_FORTIFICATION},
|
|
|
|
|
{"军事基地", TargetType::UNKNOWN},
|
|
|
|
|
{"装甲部队", TargetType::MAIN_BATTLE_TANK},
|
|
|
|
|
{"导弹发射车", TargetType::MOBILE_AIR_DEFENSE}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::random_device rd;
|
|
|
|
|
std::mt19937 gen(rd());
|
|
|
|
|
std::uniform_int_distribution<> dist(1, 3);
|
|
|
|
|
int numTargets = dist(gen);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < numTargets; ++i) {
|
|
|
|
|
auto& [name, type] = possibleTargets[i % possibleTargets.size()];
|
|
|
|
|
|
|
|
|
|
IdentifiedTarget target;
|
|
|
|
|
target.id = IdentifiedTarget::generateID();
|
|
|
|
|
target.type = type;
|
|
|
|
|
target.typeName = name;
|
|
|
|
|
target.position = packet.origin;
|
|
|
|
|
target.position.longitude += 0.01 * i;
|
|
|
|
|
target.position.latitude += 0.01 * i;
|
|
|
|
|
target.confidence = 0.75 + (i * 0.1);
|
|
|
|
|
target.speed = 0.0; // 卫星通常检测静止目标
|
|
|
|
|
target.heading = 0.0;
|
|
|
|
|
target.threatLevel = (type == TargetType::ANCIENT_FORTIFICATION) ?
|
|
|
|
|
ThreatLevel::LOW : ThreatLevel::MEDIUM;
|
|
|
|
|
target.timestamp = packet.timestamp;
|
|
|
|
|
|
|
|
|
|
target.metadata["source"] = "SATELLITE_IMAGERY";
|
|
|
|
|
target.metadata["resolution"] = "1m";
|
|
|
|
|
target.metadata["文化关联"] = (type == TargetType::ANCIENT_FORTIFICATION) ?
|
|
|
|
|
"中国古代防御建筑" : "无";
|
|
|
|
|
|
|
|
|
|
targets.push_back(target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return targets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::updateSituation(const std::vector<IdentifiedTarget>& newTargets) {
|
|
|
|
|
std::lock_guard<std::mutex> lock(situationMutex_);
|
|
|
|
|
|
|
|
|
|
// 更新当前态势
|
|
|
|
|
for (const auto& newTarget : newTargets) {
|
|
|
|
|
// 检查是否是已有目标
|
|
|
|
|
bool isExisting = false;
|
|
|
|
|
for (auto& existingTarget : currentSituation_.enemyTargets) {
|
|
|
|
|
double distance = existingTarget.position.distanceTo(newTarget.position);
|
|
|
|
|
double timeDiff = std::chrono::duration<double>(
|
|
|
|
|
newTarget.timestamp - existingTarget.timestamp).count();
|
|
|
|
|
|
|
|
|
|
if (distance < 100.0 && timeDiff < 10.0 &&
|
|
|
|
|
existingTarget.type == newTarget.type) {
|
|
|
|
|
// 更新现有目标
|
|
|
|
|
existingTarget.position = newTarget.position;
|
|
|
|
|
existingTarget.confidence = std::max(existingTarget.confidence, newTarget.confidence);
|
|
|
|
|
existingTarget.speed = newTarget.speed;
|
|
|
|
|
existingTarget.heading = newTarget.heading;
|
|
|
|
|
existingTarget.timestamp = newTarget.timestamp;
|
|
|
|
|
|
|
|
|
|
// 更新轨迹
|
|
|
|
|
existingTarget.trajectory.push_back(newTarget.position);
|
|
|
|
|
if (existingTarget.trajectory.size() > maxTrajectoryPoints_) {
|
|
|
|
|
existingTarget.trajectory.erase(existingTarget.trajectory.begin());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isExisting = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isExisting) {
|
|
|
|
|
// 添加新目标
|
|
|
|
|
currentSituation_.enemyTargets.push_back(newTarget);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新综合威胁等级
|
|
|
|
|
double totalThreat = 0.0;
|
|
|
|
|
for (const auto& target : currentSituation_.enemyTargets) {
|
|
|
|
|
double threatValue = 0.0;
|
|
|
|
|
switch (target.threatLevel) {
|
|
|
|
|
case ThreatLevel::CRITICAL: threatValue = 1.0; break;
|
|
|
|
|
case ThreatLevel::HIGH: threatValue = 0.7; break;
|
|
|
|
|
case ThreatLevel::MEDIUM: threatValue = 0.4; break;
|
|
|
|
|
case ThreatLevel::LOW: threatValue = 0.1; break;
|
|
|
|
|
}
|
|
|
|
|
totalThreat += threatValue * target.confidence;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentSituation_.overallThreatLevel =
|
|
|
|
|
totalThreat / std::max(1.0, static_cast<double>(currentSituation_.enemyTargets.size()));
|
|
|
|
|
currentSituation_.updateTime = std::chrono::system_clock::now();
|
|
|
|
|
|
|
|
|
|
// 触发态势回调
|
|
|
|
|
if (situationCallback_) {
|
|
|
|
|
situationCallback_(currentSituation_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成威胁检测
|
|
|
|
|
if (currentSituation_.overallThreatLevel > 0.6) {
|
|
|
|
|
std::string threatMsg = "检测到高威胁目标: ";
|
|
|
|
|
for (const auto& target : currentSituation_.enemyTargets) {
|
|
|
|
|
if (target.threatLevel >= ThreatLevel::HIGH) {
|
|
|
|
|
threatMsg += target.typeName + " ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
currentSituation_.detectedThreats.push_back(threatMsg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFusionEngine::log(const std::string& message, const std::string& level) {
|
|
|
|
|
auto now = std::chrono::system_clock::now();
|
|
|
|
|
auto time = std::chrono::system_clock::to_time_t(now);
|
|
|
|
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
|
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S")
|
|
|
|
|
<< " [" << level << "] DataFusionEngine: " << message;
|
|
|
|
|
|
|
|
|
|
// 输出到控制台
|
|
|
|
|
std::cout << ss.str() << std::endl;
|
|
|
|
|
|
|
|
|
|
// 可同时输出到文件
|
|
|
|
|
static std::ofstream logFile("data_fusion.log", std::ios::app);
|
|
|
|
|
if (logFile.is_open()) {
|
|
|
|
|
logFile << ss.str() << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Battlefield
|