更新:1、TAS航迹不关联时间戳更早的TWS点迹,但标记点迹已使用,避免生成TWS航迹;

2、调整目录结构,将过期的文档都放到archived_docs文件夹中留档;

Signed-off-by: waiwaylee <waiwaylee@foxmail.com>
This commit is contained in:
2026-09-12 10:01:15 +08:00
parent d6cdbc0120
commit 604f1585f6
4 changed files with 7 additions and 34 deletions
+186
View File
@@ -0,0 +1,186 @@
# Bug 修复报告
根据 `BUG_REPORT.md` 中的“是否修复”指示,本次完成了所有标记为“按建议修改/按建议修复”的项;标记为“暂不修复/暂不修改/暂不处理”的项保持原样未改动。
---
## 修复状态汇总
| 编号 | 标题 | 指示 | 状态 |
|---|---|---|---|
| BUG-01 | 基类无虚析构函数 | 暂不修复 | 未修改 |
| BUG-02 | Hight_smooth 无限增长 | 暂不修复 | 未修改 |
| BUG-03 | 工厂单例非线程安全 | 暂不修复 | 未修改 |
| BUG-04 | TAS Point_Sum 未限幅 | 按建议修复 | ✅ 已修复 |
| BUG-05 | Track_to_start.size()-1 下溢 | 按建议修复 | ✅ 已修复 |
| BUG-06 | track_start_point_num 未校验 | 按建议修复 | ✅ 已修复 |
| BUG-07 | 禁止区域个数未限制 | 暂不修复 | 未修改 |
| BUG-08 | 消亡航迹输出无容量检查 | 暂不修改 | 未修改 |
| BUG-09 | Beam_Ctrl 输出计数越界风险 | 按建议修改 | ✅ 已修复 |
| BUG-10 | 航迹号数组下标未校验 | 按建议修改 | ✅ 已修复 |
| BUG-11 | TAS model_filter 未初始化变量 | 按建议修改 | ✅ 已修复 |
| BUG-12 | tas_beam_output 未初始化变量 | 按建议修改 | ✅ 已修复 |
| BUG-13 | Work_Parameter 未初始化 | 暂不修复 | 未修改 |
| BUG-14 | lastest_index 未初始化 | 按建议修改 | ✅ 已修复 |
| BUG-15 | TWS delta_T<=0 仍关联 | 按建议修改 | ✅ 已修复 |
| BUG-16 | TAS 无 delta_T>0 检查 | 按建议修改 | ✅ 已修复 |
| BUG-17 | TAS 外推负时间差 | 按建议修改 | ✅ 已修复 |
| BUG-18 | 卡尔曼时间差除零 | 暂不修改 | 未修改 |
| BUG-19 | Bind_speed prt=0 除零 | 按建议修改 | ✅ 已修复 |
| BUG-20 | 门限重复平方 | 暂不修改 | 未修改 |
| BUG-21 | 近程模型 3 门限整数除法 | 按建议修改 | ✅ 已修复 |
| BUG-22 | EKF/凝聚方位角未环绕 | 按建议修改 | ✅ 已修复 |
| BUG-23 | IMM 概率零分母/奇异矩阵 | 按建议修改 | ✅ 已修复 |
| BUG-24 | EKF 似然只取 2x2 S | 按建议修改 | ✅ 已修复 |
| BUG-25 | TWS 处理 TAS 航迹 | 暂不处理 | 未修改 |
| BUG-26 | 输出航向角使用 atan | 按建议修改 | ✅ 已修复 |
| BUG-27 | asin(height/range) 未保护 | 按建议修改 | ✅ 已修复 |
| BUG-28 | track_clear_all 清理不彻底 | 按建议修改 | ✅ 已修复 |
| BUG-29 | tracking_stop 队列延迟 | 暂不修改 | 未修改 |
| BUG-30 | work_mode 注释不一致 | 注释有误 | ✅ 已修复注释 |
| BUG-31 | tracking_point/引导跟踪空实现 | 注释明确 | ✅ 已加注释 |
| BUG-32 | 凝聚内层未跳过已用点 | 按建议修改 | ✅ 已修复 |
| BUG-33 | 起批 delta_T 未校验 | 暂不修改 | 未修改 |
| BUG-34 | tmp_track_die 空向量越界 | 按建议修改 | ✅ 已修复 |
| BUG-35 | 航迹号 500 不复用 | 按建议修改 | ✅ 已修复 |
| BUG-36 | TAS 波束关闭字段未清 | 暂不修改 | 未修改 |
| BUG-37 | 局部结构体未完整初始化 | 按建议修改 | ✅ 已修复 |
---
## 已修复项明细
### BUG-04
- 文件:`data_process.cpp`
- 修改:TAS 分支 `data_num = min(max(Point_Sum,0), 150)`,避免 `Point_Sum > 150` 时越界读取输入数组。
### BUG-05
- 文件:`track_init.cpp`
- 修改:重复航迹去重循环改为 `for (size_t i = 0; i + 1 < Track_to_start.size(); ++i)`,避免空容器时 `size()-1` 下溢。
### BUG-06
- 文件:`data_process.cpp``track_init.cpp``track_init_direct_tracking.cpp`
- 修改:
- `track_process_parameters_initial/modify` 校验 `3 <= track_start_point_num <= 9`,非法参数返回 `-1`
- 起批转可靠航迹前增加 `Track_to_start.empty()` 和每条航迹 `size() >= 3` 防御。
- 直接跟踪的 `tmp_track_to_trust_track` 也增加 `L >= 3` 保护。
### BUG-09
- 文件:`tas_ctrl.cpp`
- 修改:
- `tas_ctrl_process` 开始时校验 `Trust_track_num_Output` 非空并清零。
- `tas_target_add` 写入输出数组前检查 `*Trust_track_num_Output < MAX_TRACK_NUM`
### BUG-10
- 文件:`track_index_mangement.cpp`
- 修改:写入 `List[]` 前校验 `Track_Index``[1, MAX_TRACK_INDEX]`
### BUG-11
- 文件:`track_asso_tas.cpp`
- 修改:`model_filter` 增加 `found_tas_track` 标记;找不到目标时直接返回,局部变量均初始化。
### BUG-12
- 文件:`tas_ctrl.cpp`
- 修改:`tas_beam_output` 初始化 `H_track/X_now/CPI_time`,找不到目标时 `open_flag=0` 并返回。
### BUG-14
- 文件:`track_index_mangement.h`
- 修改:`lastest_index` 声明时初始化为 `0`
### BUG-15
- 文件:`track_asso.cpp`
- 修改:TWS 关联中 `delta_T <= 0` 时从候选列表移除该无效配对并 `continue`,不再标记点迹已使用、不刷新航迹状态。
### BUG-16
- 文件:`track_asso_tas.cpp`
- 修改:TAS 关联点循环中 `delta_T <= 0` 时跳过该点。
### BUG-17
- 文件:`track_asso_tas.cpp`
- 修改:TAS 外推时 `delta_T <= 0` 直接跳过,避免航迹时间回退和负时间预测。
### BUG-19
- 文件:`kalman.cpp``data_process_class_dll.h`
- 修改:`Bind_speed``prt <= 0``freq <= 0` 返回安全非零值;接口注释改为“PRI 不允许为 0”。
### BUG-21
- 文件:`track_asso.cpp`
- 修改:近程门限中 `/1000``/100` 改为浮点除法,避免整数除零恒不成立;保留 `d*d` 比较方式(未修改 BUG-20)。
### BUG-22
- 文件:`kalman.cpp``dot_coh.cpp``dot_coh_tas.cpp`
- 修改:
- 新增 `wrapAnglePi()`EKF 各残差计算后对方位角分量做 `[-π,π]` 环绕。
- 点迹凝聚 `work_mode==0` 分支和 TAS 凝聚统一使用最小角度差 `delta_F`
### BUG-23
- 文件:`track_asso.cpp``track_asso_tas.cpp``track_asso_direct_tracking.cpp`
- 修改:
- IMM 交互中 `c[0..2]` 为 0/负时钳位到 `1e-12`
- 模型概率更新增加分母保护,分母异常时保持上一拍概率。
- 似然计算对 `det_S <= 0` 返回 0,避免 NaN。
### BUG-24
- 文件:`kalman.h``kalman.cpp``track_asso.cpp``track_asso_tas.cpp``track_asso_direct_tracking.cpp`
- 修改:
- `kalman_filter_EKF``S_filter``[2][2]` 改为 `[3][3]`
- 调用侧使用 `Matrix3f` 和 3x3 行列式,似然归一化改为 `1/sqrt(pow(2*PI,3)*detS)`
### BUG-26
- 文件:`track_asso.cpp``track_asso_tas.cpp``track_asso_direct_tracking.cpp`
- 修改:航向角改用 `atan2(X[4], X[1])` 并归一化到 `[0,2π)`
### BUG-27
- 文件:`track_asso_tas.cpp``track_asso_direct_tracking.cpp``track_init.cpp`
- 修改:计算 `asin` 前对 `height/range` 做定义域钳位,`range <= 0` 时按 0 处理。
### BUG-28
- 文件:`data_process.cpp``dot_coh.h/cpp``track_asso.h/cpp``track_asso_tas.h/cpp``track_init.h/cpp``tas_ctrl.h/cpp``track_index_mangement.h/cpp`
- 修改:
-`Dot_Coh``Track_Asso``Track_Asso_Tas``Track_Init``TAS_Ctrl``Track_Ind_Mangement` 增加 `reset()`
- `track_clear_all()` 调用上述 reset,并恢复 `last_beam_num = INT_MAX`
- 直接跟踪相关类也补充了 `reset()`
### BUG-30
- 文件:`data_process_class_dll.h`
- 修改:`work_mode` 注释由“0进程 1中程 3远程”改为“0进程 1中程 2远程”。
### BUG-31
- 文件:`data_process_class_dll.h``data_process.cpp``track_init_direct_tracking.cpp`
- 修改:在 `direct_tracking_process``tracking_point`、直接跟踪入口处注释明确“当前接口未启用,保留空实现”。
### BUG-32
- 文件:`dot_coh.cpp``dot_coh_tas.cpp`
- 修改:内层凝聚比较增加对 `i``Use_Flag` 的检查,已使用点不再参与凝聚。
### BUG-34
- 文件:`track_init.cpp``track_init_direct_tracking.cpp`
- 修改:`tmp_track_die` 先判断 `n <= 0`,空向量直接删除。
### BUG-35
- 文件:`track_index_mangement.cpp`
- 修改:两处回绕循环由 `i < MAX_TRACK_INDEX` 改为 `i <= MAX_TRACK_INDEX`,使 500 号可复用。
### BUG-37
- 文件:`track_init.cpp``track_init_direct_tracking.cpp`
- 修改:`Temp_track``Trust_Track` 局部变量改为 `= {}` 值初始化,避免未初始化字段。
---
## 编译与运行验证
使用 **MSVC 2013 (Visual Studio 12) x86** 实际编译:
| 配置 | 结果 |
|---|---|
| X256_PS Release | ✅ 编译链接通过 |
| X256_MS Release | ✅ 编译链接通过 |
| X256_PS Debug | ✅ 编译链接通过 |
| MSVC `/W4` Release | ✅ 编译通过,未再出现 C4700/C4701 未初始化变量告警 |
另编写临时宿主程序验证 DLL
- 初始化 `RadarPara`,调用 `track_process_parameters_initial` 成功。
- 调用 `track_process`,返回 `1`,输出计数正常。
- 工厂创建/销毁流程正常。
> 说明:当前构建仍会输出原有代码的 C4244 转换告警、C4018 有符号/无符号比较告警、C4819 编码告警,均非本次修复引入,不影响链接和运行。
+276
View File
@@ -0,0 +1,276 @@
# 雷达数据处理 DLL 逻辑 BUG 分析报告
分析范围:`data_process_class_dll/` 下全部源码(不含 `Eigen/`),以迁移后的当前代码行号为准。
严重级别定义:
- **P0**:可能导致崩溃、越界读写、内存破坏或长时间运行内存泄漏,建议优先修复。
- **P1**:在常见异常时序/边界输入下会出错,或属于明显算法逻辑错误。
- **P2**:健壮性、数值稳定性、状态一致性、功能缺失等问题。
- **P3**:代码质量/可维护性问题。
---
## 1. 内存与生命周期
### BUG-01 [P0] 基类没有虚析构函数,工厂按基类指针 delete 派生对象
- 位置:`data_process_class_dll.h:168``data_process_class_dll.cpp:25-32`
- 说明:`Data_process_class_dll` 没有声明虚析构函数,而 `Data_Process` 内部包含多个 `std::vector` 和若干成员对象。`Data_Process_Factory::Destroy()` 执行 `delete p` 时静态类型是基类指针,只会调用基类析构函数,派生类成员(`Data_buffer``trust_track``temp_track`、Eigen 相关对象等)的析构不会执行,属于未定义行为并造成内存泄漏。
- 建议:在基类中增加 `virtual ~Data_process_class_dll() {}`;同时让工厂支持重复销毁、销毁后返回 nullptr。
- 暂不修复
### BUG-02 [P1] `Hight_smooth` 高度平滑缓存只增不减,长时间运行内存持续增长
- 位置:`track_asso.cpp:890``track_asso_tas.cpp:722``track_asso_direct_tracking.cpp:639`
- 说明:每次高度更新都执行 `Hight_smooth.push_back(...)`,从未裁剪或清空。航迹存活时间越长,该 vector 越大;500 条航迹长时间运行时内存会持续增长。
- 建议:仅保留最近 `height_win_length` 个高度值(如 `resize`/`erase(begin)` 后再 push),或改用固定长度 `std::deque`;航迹消亡时随结构体释放。
- 暂不修复
### BUG-03 [P2] 工厂单例创建/销毁非线程安全
- 位置:`data_process_class_dll.cpp:15-32`
- 说明:`GetB()``Destroy()` 对静态指针 `p` 无任何同步。若宿主在多线程环境调用,可能创建两个实例(泄漏一个)或对同一对象重复销毁。
- 建议:用 C++11 `static Data_Process instance;` 返回地址,或对工厂方法加锁;明确 DLL 接口的线程模型。
- 暂不修复
---
## 2. 数组/向量越界
### BUG-04 [P0] TAS 输入点迹未限制 `Point_Sum <= 150`
- 位置:`data_process.cpp:66`
- 说明:TWS 分支使用 `min(Point_Sum, 150)`,但 TAS 分支直接 `data_num = Data_Input[0].Point_Sum` 并循环读取 `Data_Input[i]`。当协议传入 `Point_Sum > 150` 时,会越界读取 `Data_Input[150]`
- 建议:与 TWS 分支一致,使用 `data_num = min(max(Point_Sum,0), 150)`,并校验 `Point_Sum >= 0`
- 按建议修复
### BUG-05 [P0] `Track_to_start.size()-1` 在空容器时下溢导致越界
- 位置:`track_init.cpp:534`
- 说明:与已发现示例一致。`size()` 返回 `size_t`,空容器减 1 得到极大值,随后 `Track_to_start[i]` 越界。
- 建议:`if (Track_to_start.empty()) return;`,或改为 `for (size_t i = 0; i + 1 < Track_to_start.size(); ++i)`
- 按建议修复,改为 `for (size_t i = 0; i + 1 < Track_to_start.size(); ++i)`
### BUG-06 [P0] `track_start_point_num` 未校验,取值 0/1/2 或大于 9 时多处越界
- 位置:`track_init.cpp:533,544-545,588-594``track_init_direct_tracking.cpp:316-322`
- 说明:重复航迹比较固定访问 `Track_to_start[i][1]``[2]`,三点初始化访问 `[L-3]/[L-2]/[L-1]`。该参数由外部 `RadarPara` 传入,若未初始化或配置为 0/1/2,会出现负下标或越界;若大于 9,`tmp_track_die` 会在 `n>=10` 时删除临时航迹,逻辑也无法起批。
- 建议:在 `track_process_parameters_initial/modify` 中校验 `3 <= track_start_point_num <= 9`;使用 `Track_to_start[i].size()` 作为实际长度并在访问前检查。
- 按建议修复
### BUG-07 [P0] 禁止区域个数未限制在 30 以内,外部配置过大时数组越界
- 位置:`track_init.cpp:711``track_prohibite_area_num`)、`tas_ctrl.cpp:123``TAS_prohibite_area_num`
- 说明:循环上界直接使用外部传入的计数,而对应数组固定为 `[30]`。配置大于 30 时越界读。
- 建议:循环上界改为 `min(count, 30)`,并在参数初始化/修改时拒绝非法计数或截断。
- 暂不修复
### BUG-08 [P1] 消亡航迹号输出无数组容量检查
- 位置:`track_die.cpp:24``track_die_tas.cpp:26`
- 说明:`Track_die_Index_Output[*Track_die_num_Output-1] = ...` 不检查数组容量。正常流量下最多 500 条航迹,与 `MAX_TRACK_NUM` 一致,但接口没有把容量传入,一旦宿主传入较小数组、或计数被异常修改,就会越界写。
- 建议:接口增加 `die_array_capacity` 参数,或内部保证 `*Track_die_num_Output < MAX_TRACK_NUM` 后再写。
- 暂不修改
### BUG-09 [P1] `Beam_Ctrl` 路径中输出计数未初始化/无上界,可能越界写航迹输出数组
- 位置:`data_process.cpp:193-198``tas_ctrl.cpp:74-78`
- 说明:`Beam_Ctrl()` 直接使用宿主传入的 `Trust_track_num_Output`,而 `tas_ctrl_process` 不会先清零,`tas_target_add` 会基于旧值自增并写 `Trust_Track_Output[*Trust_track_num_Output-1]`。若调用方未清零或旧值接近 `MAX_TRACK_NUM`,会越界写。
- 建议:`tas_ctrl_process` 内部保存 `*count = 0` 或在每次写入前检查 `*count < MAX_TRACK_NUM`;同时校验指针非空。
- 按建议修改
### BUG-10 [P1] 航迹号直接作为数组下标,未校验范围
- 位置:`track_index_mangement.cpp:29`
- 说明:`List[(*trust_track)[i].Track_Index-1] = 1`,若航迹号不在 `[1, MAX_TRACK_INDEX]` 内(异常数据、内存损坏、外部修改),立即越界。
- 建议:写前检查 `Track_Index >= 1 && Track_Index <= MAX_TRACK_INDEX`,异常航迹号返回错误或跳过。
- 按建议修改
---
## 3. 未初始化变量
### BUG-11 [P1] `Track_Asso_Tas::model_filter` 在找不到 TAS 目标时使用未初始化变量
- 位置:`track_asso_tas.cpp:228-232`,随后在 `271/276/280/282` 等使用
- 说明:`X1/X2/X3/P1/P2/P3/T_track/v_track/r_track/h_track` 只在 `Track_Index == tas_track_idx` 时赋值。若 `tas_track_idx` 不存在(例如目标已被消亡、主程序传入失效批号),后续仍用这些未初始化值计算 IMM、距离门限和外推,结果不可预测。MSVC `/W4` 已报 C4701。
- 建议:函数开头初始化这些变量,并在找不到目标时直接 return;上层也应处理“TAS 目标不存在”的返回值。
- 按建议修改
### BUG-12 [P1] `tas_beam_output` 在队列目标不在航迹表中时使用未初始化变量
- 位置:`tas_ctrl.cpp:242-271`
- 说明:`H_track``X_now[]` 只在找到匹配航迹时赋值;若 `track_clear_all()` 后队列未清空、或目标已被删除而队列未同步,循环找不到目标,随后 `asin(H_track/range)``X_now[...]` 使用未初始化数据。Cppcheck 和 MSVC `/W4` 均报 C4701。
- 建议:找不到目标时立即 `open_flag=0` 并 return;变量声明时初始化。
- 按建议修改
### BUG-13 [P2] `Data_Process::Work_Parameter` 及若干成员在构造后未初始化
- 位置:`data_process.h:28-31,78-95`
- 说明:构造函数为空,`Work_Parameter``Beam_num``data_num``TAS_track_idx` 等未初始化。若宿主在调用 `track_process_parameters_initial` 前就调用 `data_preprocess/track_process/Beam_Ctrl``Work_Parameter.track_start_point_num``Sys_delay``V_MIN/V_MAX` 等是垃圾值,可能导致起批越界、除零或异常门限。
- 建议:构造函数中对 `Work_Parameter` 进行 `memset`/值初始化并设置安全默认参数;在处理函数入口检查“参数是否已初始化”。
- 暂不修复
### BUG-14 [P3] `Track_Ind_Mangement::lastest_index` 未初始化
- 位置:`track_index_mangement.h:17``track_index_mangement.cpp:33`
- 说明:只有空航迹表分支会赋值为 1;如果首次调用时航迹表非空,就会读取未初始化的 `lastest_index`
- 建议:声明为 `int lastest_index = 0;` 或增加构造函数初始化。
- 按建议修改
---
## 4. 时间戳/时序处理
### BUG-15 [P1] TWS 关联在 `delta_T <= 0` 时仍把点迹标记为已关联并刷新航迹状态
- 位置:`track_asso.cpp:610-691`
- 说明:滤波和航迹信息更新在 `if (delta_T > 0)` 内,但 `Extrapolate_round=0``point_flag=1``associate_point_number++`、点迹 `Use_Flag=1` 都在 if 之外。重复/乱序时间戳的点仍会“占用”点迹、让航迹看起来已更新,实际状态未更新。
- 建议:`delta_T <= 0` 时直接跳过该关联候选(或作为无效量测处理),不要标记点迹已使用、不要刷新航迹新鲜度。
- 按建议修改
### BUG-16 [P1] TAS 关联完全没有 `delta_T > 0` 检查
- 位置:`track_asso_tas.cpp:271-335,385-452`
- 说明:TAS 路径计算 `delta_T` 后直接进入统计距离和滤波,即使 `delta_T <= 0` 也会生成 F/Q 并更新航迹,可能把航迹时间更新到过去。
- 建议:与 TWS 一致,只有 `delta_T > 0` 才允许关联;否则跳过该点。
- 按建议修改
### BUG-17 [P1] TAS 外推使用未校验的 `latest_timestamp - T_track`,负时间差导致反向预测
- 位置:`track_asso_tas.cpp:483-506`
- 说明:若 `latest_timestamp < T_track`(乱序/重复时间戳),`delta_T` 为负,`T_track += delta_T*1000` 会回退航迹时间,IMM F/Q 也按负时间生成。
- 建议:`delta_T = max(0, latest_timestamp - T_track)/1000.0`;若为 0 则直接返回或保持原状态。
- 按建议修改
### BUG-18 [P1] 卡尔曼初始化及统计距离函数对零/负时间差没有保护
- 位置:`kalman.cpp:13-46,126-130,158-168`;调用点 `track_init.cpp:275,450,593-594``track_init_direct_tracking.cpp:135,271,321-322`
- 说明:两点/三点初始化直接除以 `T/T1/T2`。同一 CPI 重复点、时间戳相等或乱序会产生除零、inf/NaN,随后污染航迹协方差和模型概率。
- 建议:调用前统一校验时间差大于最小阈值(如 >0 或 >1 ms);`kalman_filter_init_2dots/3dots` 内部对非法时间返回错误。
- 暂不修改
### BUG-19 [P1] `Bind_speed` 对 `prt == 0` 无保护,而接口说明 PRI 可给 0
- 位置:`kalman.cpp:766-770``data_process_class_dll.h:29`
- 说明:`return 150000.0/(freq*prt)`,当 `PRI=0` 时除零;结果传给 `Round()` 会把 inf/NaN 转换为未定义整型。
- 建议:`prt <= 0` 时返回固定安全值或直接返回无效距离;统一约定 PRI 单位与默认值。
- 按建议修改,同时修改接口说明:PRI不可为0
---
## 5. 关联门限与滤波算法逻辑
### BUG-20 [P1] 统计距离 d 已经是平方形式,门限中又平方了一次
- 位置:`track_asso.cpp:544-546``track_asso_tas.cpp:335``track_asso_direct_tracking.cpp:286``track_init.cpp:221`
- 说明:`d_cal_EKF` 返回的是 `delta_z^T S^{-1} delta_z`(马氏距离平方),后续门限却写成 `d*d < THRESHOLD*THRESHOLD`。例如阈值 3 时本意是 `d < 9`,实际变成 `d < 3`,波门明显偏小。
- 建议:统一改为 `d < TRACK_START_THRESHOLD*TRACK_START_THRESHOLD` / `d < ASSO_THORD*ASSO_THORD`
- 暂不修改
### BUG-21 [P1] 近程模型 3 门限因整数除法恒为 0
- 位置:`track_asso.cpp:544-545`
- 说明:`ASSO_THORD` 是 int 宏,`ASSO_THORD*ASSO_THORD/1000``/100` 按整数计算,结果均为 0,导致 `d3*d3 < 0` 永远不成立;近距离下模型 3 实际被禁用。
- 建议:写为 `ASSO_THORD*ASSO_THORD/1000.0``/100.0`,同时按 BUG-20 修正平方关系。
- 按建议修改,但不修改BUG-20
### BUG-22 [P1] EKF 方位角残差未按 0/2π 环绕处理
- 位置:`kalman.cpp:265-298,457-492,642-680`;凝聚 `dot_coh.cpp:35,44``work_mode==0` 分支)、`dot_coh_tas.cpp:33,42`
- 说明:预测方位被归一化到 `[0,2π)`,但量测方位未归一化,`delta_z = Z_mea - Z_pred` 未做 ±π 环绕。目标跨正北时残差会接近 2π,导致错误拒绝/错误滤波。凝聚中 `work_mode==0` 和 TAS 凝聚也直接 `fabs(angle)`,未处理 360° 环绕。
- 建议:方位差统一按 `wrapToPi()` 处理;`work_mode==0` 与 TAS 凝聚复用同一环绕角差函数。
- 按建议修改
### BUG-23 [P1] IMM 模型概率计算缺少零分母/奇异矩阵保护
- 位置:`track_asso.cpp:157-165,627-647``track_asso_tas.cpp:122-130,406-431``track_asso_direct_tracking.cpp:95-103,352-374`
- 说明:`c[0..2]``Possibility1*c[0]+...``det_S` 都可能为 0 或负;`1/sqrt(2*PI*det_S)` 对负/零行列式产生 NaN。一旦概率变 NaN,后续 `model_output` 会把整条航迹状态污染。
- 建议:计算前检查 `det_S > eps`、分母 > eps;异常时保持上一拍模型概率或回退为等概率 `{1/3,1/3,1/3}`
- 按建议修改
### BUG-24 [P2] EKF 似然只取 3x3 新息协方差左上角 2x2 的行列式
- 位置:`kalman.cpp:515-519`(S 为 3x3,但输出只保存 2x2);调用处 `track_asso.cpp:627-633``track_asso_tas.cpp:406-412``track_asso_direct_tracking.cpp:352-358`
- 说明:EKF 量测为距离/方位/径向速度三维,新息协方差 S 是 3x3,但接口 `S_filter[2][2]` 和似然计算只使用二维子块,模型似然不完整。
- 建议:将接口改为 3x3,并采用完整 3 维高斯归一化因子 `1/sqrt(pow(2*PI,3)*detS)`(若只比较相对大小,也至少应保持三个模型使用相同维数)。
- 按建议修改
### BUG-25 [P1] TWS 航迹关联/输出没有排除 TAS 航迹
- 位置:`track_asso.cpp:65-133`(输出)、`141-228`(交互
)、`414-570`(滤波)
- 说明:原代码中有 `// if manual_tracking_flag==0` 的过滤逻辑但被注释掉。当前 TWS 处理会遍历并更新所有航迹,包括 `Track_Mode==1` 的 TAS 航迹;TWS 输出循环也会把 TAS 航迹当作 `point_type=0` 输出,造成 TAS 航迹被 TWS 点迹错误更新和重复输出。
- 建议:TWS 的交互、关联、输出统一跳过 `Track_Mode == 1`(或 `manual_tracking_flag == 1`)的航迹;TAS 目标只在 TAS 流程中处理。
- 暂不处理
### BUG-26 [P2] 输出航向角使用 `atan(y/x)` 而不是 `atan2`
- 位置:`track_asso.cpp:100``track_asso_tas.cpp:66``track_asso_direct_tracking.cpp:59`
- 说明:当 `vx == 0` 时除法结果接近 ±inf,现有象限修正逻辑不完整,某些象限会输出负角度或 90° 偏差。
- 建议:统一使用 `atan2(X[4], X[1])` 并归一化到 `[0,2π)`
- 按建议修改
### BUG-27 [P2] `asin(height/range)` 缺少定义域和零距离保护
- 位置:`track_asso_tas.cpp:54``track_asso_direct_tracking.cpp:48``track_init.cpp:646,673`
- 说明:`range` 为 0 或 `height > range` 时,`asin` 参数超出 `[-1,1]` 产生 NaN,并输出到 `Track.Elevation`
- 建议:计算前钳位 `h/r``[-1,1]`,并对 `r <= eps` 特殊处理。
- 按建议修改
---
## 6. 状态清理与接口一致性
### BUG-28 [P1] `track_clear_all` 清理不彻底,重连后可能输出幽灵航迹/幽灵波束
- 位置:`data_process.cpp:219-229`
- 说明:只清空 6 个顶层 vector,未清理:
- `Dot_Coh::data_input_buff`(滑窗凝聚缓存);
- `TAS_Ctrl::tas_target_queue``tas_target_num`
- `last_beam_num`(扫描圈判断);
- `Track_Ind_Mangement::lastest_index`
- 各关联类的 `point_process` 成员。
清空后若立即调用 `Beam_Ctrl`TAS 队列仍认为有目标,但 `trust_track` 已空,会触发 BUG-12 的未初始化路径并输出错误波束;下一次 TWS 处理也可能输出清空前的缓存点迹。
- 建议:为 `Dot_Coh``TAS_Ctrl``Track_Ind_Mangement` 增加 `reset()``track_clear_all` 调用所有 reset,并恢复 `last_beam_num=INT_MAX`
- 按建议修改
### BUG-29 [P2] `tracking_stop` 后 TAS 队列要到下一次 `Beam_Ctrl` 才移除
- 位置:`data_process.cpp:260-270``tas_ctrl.cpp:138-162`
- 说明:`tracking_stop` 只清标志位和 `Track_Mode`,不会立即清 `tas_target_queue`。在调用 `Beam_Ctrl` 前,队列仍会输出该目标的跟踪波束。
- 建议:`tracking_stop` 内同步删除 TAS 队列项并更新 `tas_target_num`,或明确接口时序并文档化。
- 暂不修改
### BUG-30 [P2] 工作模式枚举与代码分支不一致
- 位置:`data_process_class_dll.h:140`(注释:0 进程、1 中程、3 远程)、`track_asso.cpp:729-744`(按 0/1/2/else 分支)
- 说明:注释定义远程模式为 3,但代码按 `work_mode==2` 使用远距数据率;当外部按注释传 3 时,会落入 else 使用近程数据率 `DATA_RATE_SHORT`
- 建议:统一枚举定义,或代码改为 `work_mode==3` 使用 `DATA_RATE_FAR`
- 注释有误,修改注释为:0 进程、1 中程、2 远程
### BUG-31 [P2] `tracking_point` 和引导跟踪处理是空实现
- 位置:`data_process.cpp:282-286``data_process_class_dll.h:200-213``track_init_direct_tracking.cpp:11-21`
- 说明:`tracking_point` 直接返回 0`Data_Process` 没有重写 `direct_tracking_process`,基类默认返回 0`Track_Init_Direct_Tracking::track_init_process_logic` 也是空函数。若接口已被主程序调用,则相关功能实际未生效。
- 建议:确认这两个接口是否已废弃;若仍需要,补齐实现或至少在文档中明确为未实现并返回错误码。
- 在注释中明确接口未启用,保留空实现
---
## 7. 其他逻辑与健壮性
### BUG-32 [P2] 凝聚内层循环没有跳过已标记使用的点
- 位置:`dot_coh.cpp:25,148``dot_coh_tas.cpp:25`
- 说明:内层只检查当前基准点 `loop_of_point``Use_Flag`,没有检查被比较点 `i``Use_Flag`。已被凝聚掉的点仍可参与后续比较,甚至反过来把高幅度基准点标记掉。
- 建议:内层同样判断 `(*data_input)[i].Use_Flag != 1`(以及 `data_tmp[i]`)。
- 按建议修改
### BUG-33 [P2] 起批/临时航迹关联未校验 `delta_T > 0`,重复时间戳可能产生非法卡尔曼初始化
- 位置:`track_init.cpp:189,381,450``track_init_direct_tracking.cpp:67,221,271`
- 说明:点迹与临时航迹、点迹与航迹头的关联均使用 `T_point - T_track_head`,未要求正时间差。`kalman_filter_init_2dots` 遇到 0/负 T 会产生除零。
- 建议:在关联条件中显式要求 `T_point > T_track_head`,且时间差需大于最小步长。
- 暂不修改
### BUG-34 [P2] 临时航迹消亡函数在空向量时直接取 `[n-1]`
- 位置:`track_init.cpp:694-695``track_init_direct_tracking.cpp:417-418`
- 说明:`int n = (*Iter).size();` 后立即 `(*Iter)[n-1]`。正常流程每条临时航迹至少 1 个点,但没有防御;一旦出现空内层向量,`n-1` 为负并越界。
- 建议:先判断 `n > 0`,空向量直接删除。
- 按建议修改
### BUG-35 [P3] 航迹号复用逻辑漏掉 `MAX_TRACK_INDEX`
- 位置:`track_index_mangement.cpp:44,56`
- 说明:回绕查找循环写作 `i < MAX_TRACK_INDEX`,因此 500 号航迹永远不会被复用;与第一段 `i <= MAX_TRACK_INDEX` 不一致。
- 建议:两处回绕循环改为 `i <= MAX_TRACK_INDEX`
- 按建议修改
### BUG-36 [P3] TAS 波束关闭时只清 `open_flag`,其他字段保留旧值
- 位置:`tas_ctrl.cpp:277-284`
- 说明:当 `tas_target_queue[0].empty_flag==0` 时,仅设置 `Tracking_beam->open_flag=0``Range/Azi/Elev/type/TAS_track_index` 保留上一拍内容。主程序若只按 `open_flag` 判断则无问题,但字段语义不清晰。
- 建议:关闭时同时清零 `type/Range/Azi/Elev/TAS_track_index`
- 暂不修改
### BUG-37 [P3] 部分结构体局部变量未完整初始化
- 位置:`track_init.cpp:80,598``track_init_direct_tracking.cpp:325`
- 说明:`Temp_track temp_track_tmp``Trust_Track trust_track_tmp``P` 矩阵等字段未显式初始化。当前流程部分字段未被读取,但依赖调用顺序;后续维护容易读到垃圾值。
- 建议:使用值初始化 `Temp_track tmp = {};` 或为结构体提供构造函数/`init()` 统一初始化所有字段。
- 按建议修改
---
## 建议修复顺序
1. 先修 P0BUG-01、BUG-04、BUG-05、BUG-06、BUG-07、BUG-11、BUG-12。
2. 再修 P1 时间与关联逻辑:BUG-15~BUG-23、BUG-25、BUG-28。
3. 最后处理数值稳定性、状态一致性和未启用功能:BUG-24、BUG-26~BUG-37。
> 说明:`track_asso_direct_tracking.cpp` 和 `track_init_direct_tracking.cpp` 当前未加入 CMake 构建(与旧 .pro 一致),其中问题与主流程同类问题重复,修复主流程时可同步修改或暂缓。
+42
View File
@@ -0,0 +1,42 @@
# 雷达数据处理项目修改说明
## 概述
增加日志文件输出功能,具体需求如下:
- 将标准输出std::cout重定向到日志文件,考虑使用 rdbuf() 方法,见[参考1](#参考1)
- 在parameters.h中添加一个日志输出开关的宏定义,开关关闭时,不重定向输出到文件
- 日志文件输出路径为“.\\rdp_logs\\”,日志文件名按当前日期+时间命名
- 增加宏定义,在输出日志时添加时间戳、代码文件、代码行数等关键信息再输出到标准输出
## 参考
### 参考1
使用 rdbuf() 方法重定向标准输出,更符合C++的流式风格,通过替换 std::cout 的底层流缓冲区(streambuf),将其指向一个文件输出流(std::ofstream)。
```cpp
#include <iostream>
#include <fstream>
int main() {
std::ofstream file("output.txt");
if (!file.is_open()) {
return 1;
}
// 保存原始的 cout 缓冲区,以便之后恢复
auto original_buf = std::cout.rdbuf();
// 将 cout 的缓冲区替换为 file 的缓冲区
std::cout.rdbuf(file.rdbuf());
// 此后的输出都会写入文件
std::cout << "这条信息会写入文件。" << std::endl;
// 恢复 cout 的原始缓冲区,让输出回到控制台
std::cout.rdbuf(original_buf);
// file 对象会在析构时自动关闭
std::cout << "这条信息会回到控制台。" << std::endl;
return 0;
}
```