Compare commits
6
Commits
a76da34756
...
ed7d6d7902
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed7d6d7902 | ||
|
|
e8c56f914b | ||
|
|
42b598e2e5 | ||
|
|
fc49707b08 | ||
|
|
50e0b5cb74 | ||
|
|
e0bf227be3 |
@@ -4,4 +4,5 @@ debug/
|
|||||||
release/
|
release/
|
||||||
build/
|
build/
|
||||||
rdp_logs/
|
rdp_logs/
|
||||||
|
design_docs/
|
||||||
.mnemon/
|
.mnemon/
|
||||||
@@ -17,6 +17,10 @@
|
|||||||
- 新增日志文件输出功能:`parameters.h` 增加 `RDP_LOG_ENABLE` 开关(定义时启用;**当前源码中该宏为注释状态,即默认不重定向、日志输出到控制台**)与 `RDP_LOG_DIR` 目录宏(`.\\rdp_logs\\`);新增 `rdp_log.h/.cpp` 日志模块,首次 `Data_Process_Factory::GetB()` 时按 `RDP_LOG_ENABLE` 决定是否用 `rdbuf()` 将 `std::cout` 重定向到 `.\rdp_logs\` 下按日期+时间命名的日志文件(`rdp_YYYYMMDD_HHMMSS.log`,目录不存在自动创建),`Destroy()` 销毁实例时恢复 `std::cout` 并关闭文件;开关注释关闭时不重定向、日志仍输出到标准输出;日志文件在 `CMakeLists.txt` 的 SOURCES 中注册。
|
- 新增日志文件输出功能:`parameters.h` 增加 `RDP_LOG_ENABLE` 开关(定义时启用;**当前源码中该宏为注释状态,即默认不重定向、日志输出到控制台**)与 `RDP_LOG_DIR` 目录宏(`.\\rdp_logs\\`);新增 `rdp_log.h/.cpp` 日志模块,首次 `Data_Process_Factory::GetB()` 时按 `RDP_LOG_ENABLE` 决定是否用 `rdbuf()` 将 `std::cout` 重定向到 `.\rdp_logs\` 下按日期+时间命名的日志文件(`rdp_YYYYMMDD_HHMMSS.log`,目录不存在自动创建),`Destroy()` 销毁实例时恢复 `std::cout` 并关闭文件;开关注释关闭时不重定向、日志仍输出到标准输出;日志文件在 `CMakeLists.txt` 的 SOURCES 中注册。
|
||||||
- 新增 `RDP_LOG` 日志输出宏(`rdp_log.h`):自动在每条日志前附加 `[时间戳][代码文件:行号]` 信息后再输出到标准输出(重定向开启时随之写入日志文件),供后续新增日志统一使用。
|
- 新增 `RDP_LOG` 日志输出宏(`rdp_log.h`):自动在每条日志前附加 `[时间戳][代码文件:行号]` 信息后再输出到标准输出(重定向开启时随之写入日志文件),供后续新增日志统一使用。
|
||||||
- 更新 README.md(604f158、d6cdbc0):目录结构补充 `archived_docs/` 归档目录;9.6 节改写 TWS 关联 ΔT≤0 的处理说明;功能特性、模块职责、已知问题与参考文档的文档引用路径同步指向 `archived_docs/`;版本历史表补充 604f158、d6cdbc0 提交记录。
|
- 更新 README.md(604f158、d6cdbc0):目录结构补充 `archived_docs/` 归档目录;9.6 节改写 TWS 关联 ΔT≤0 的处理说明;功能特性、模块职责、已知问题与参考文档的文档引用路径同步指向 `archived_docs/`;版本历史表补充 604f158、d6cdbc0 提交记录。
|
||||||
|
- TWS 关联新增**高度门限**(e0bf227,`track_asso.cpp`):原实现中分距离段的高度门限代码块整体为注释状态、`d_h` 恒为 1(等于不生效),现改为独立判定 `thd_h = |h_track − h_point|` 与航迹距离分段比较后再参与关联(分段值见 Changed),与 TAS 通道的高度门限取值一致。
|
||||||
|
- 关联门限判定重构为三个显式布尔量(e0bf227):`track_asso.cpp` 与 `track_asso_tas.cpp` 的 `model_filter()` 原先把统计距离、高度、距离三类判据混写在一个长 `if` 条件里(高度门限在 TWS 侧整体被注释),现分别计算 `thd_d`(统计距离门限,按距离分段)、`thd_h`(高度门限)、`thd_r`(TWS 距离门限)后再以 `thd_d && thd_h && thd_r`(TAS 为 `thd_d && thd_h`)判定候选,逻辑等价性更易核对;TWS 侧同时移除了 `manual_tracking_flag==0` 的注释残留代码块与其缩进。
|
||||||
|
- 更新 README.md(e0bf227):目录结构(第 3 节)删除已移除的 `docs/data_process_flow_report.html` 并补充 `design_docs/` 留档目录(被 .gitignore 忽略);2、9.6、9.10、10.1、11.1、12、13 节按源码同步 `ASSO_THORD = 4`(关联波门等效 d < 4、TWS 分段比例门限 16/1000 与 16/100)、TWS/TAS 高度门限的分段取值、`thd_d/thd_h/thd_r` 三类门限判定结构、TAS 波束数据率门控与 e0bf227 提交记录;13 节参考文档表删除已不存在的 HTML 行。
|
||||||
|
- 同步 `docs/data_process_flow_report.md`(e0bf227):4.2 节波门由「统计距离 + 距离 + 恒通过的俯仰门限」改为「统计距离 thd_d + 高度 thd_h + 距离 thd_r」并给出 TWS 高度门限分段表,7 节 TAS 高度门限 2000~3000 m 段由 200 m 更正为 250 m;7.2 节判据与 9.1 节参数表按源码更新(`ASSO_THORD = 4`、`d² < 16`);8.2 节改为单条件数据率门控并在选中目标后按 CPI 时间计算外推步长。
|
||||||
- 输出航迹补充「靠近/远离」方向标志 `Flag_Direction`(f249fdc):TWS 关联输出(`track_asso.cpp`)与 TAS 关联输出(`track_asso_tas.cpp`)在写入 `vr_point` 后追加 `Flag_Direction = vr_point > 0 ? 1 : 0`,即径向速度为正判为靠近(1)、为零或负判为远离(0)。该字段此前已在 `data_process_class_dll.h` 的 `Track` 结构体中声明(注释「方向标志 1 靠近/0 远离」)但从未被赋值,宿主读到的是未初始化/旧值。
|
- 输出航迹补充「靠近/远离」方向标志 `Flag_Direction`(f249fdc):TWS 关联输出(`track_asso.cpp`)与 TAS 关联输出(`track_asso_tas.cpp`)在写入 `vr_point` 后追加 `Flag_Direction = vr_point > 0 ? 1 : 0`,即径向速度为正判为靠近(1)、为零或负判为远离(0)。该字段此前已在 `data_process_class_dll.h` 的 `Track` 结构体中声明(注释「方向标志 1 靠近/0 远离」)但从未被赋值,宿主读到的是未初始化/旧值。
|
||||||
- 新增三份流程与专项文档(f249fdc):`docs/data_process_flow_report.md`(数据处理流程与关键逻辑说明:总体数据流、前处理与判圈、凝聚、TWS/TAS 关联与滤波、航迹起始、外推消亡与航迹号管理、TAS 波束控制、参数脉络与关键约定)、`docs/data_process_flow_report.html`(同内容的 HTML 渲染版)、`docs/track_init_readme.md`(航迹起始 Track Init 详细逻辑说明:分阶段流程、起始条件汇总、参数调参、输出字段映射、已知风险与代码索引)。
|
- 新增三份流程与专项文档(f249fdc):`docs/data_process_flow_report.md`(数据处理流程与关键逻辑说明:总体数据流、前处理与判圈、凝聚、TWS/TAS 关联与滤波、航迹起始、外推消亡与航迹号管理、TAS 波束控制、参数脉络与关键约定)、`docs/data_process_flow_report.html`(同内容的 HTML 渲染版)、`docs/track_init_readme.md`(航迹起始 Track Init 详细逻辑说明:分阶段流程、起始条件汇总、参数调参、输出字段映射、已知风险与代码索引)。
|
||||||
- 更新 README.md(7d5a56f、f249fdc):目录结构新增 `docs/` 目录;2、7.2、8.1 节满圈判据改为「方位波位号 == 0」并说明 `last_beam_num` 不再参与判断;8.3、9.3 节改写点-航迹头关联判据与起批输出历史点数;9.6 节补充方向标志输出与点迹消费说明;2、10.1 节 `RDP_LOG_ENABLE` 说明改为当前实际状态(注释停用、默认不重定向);11.4 节新增航迹起始未修复观察;版本历史表补充 7d5a56f、f249fdc,参考文档表补充 `docs/` 三份文档。
|
- 更新 README.md(7d5a56f、f249fdc):目录结构新增 `docs/` 目录;2、7.2、8.1 节满圈判据改为「方位波位号 == 0」并说明 `last_beam_num` 不再参与判断;8.3、9.3 节改写点-航迹头关联判据与起批输出历史点数;9.6 节补充方向标志输出与点迹消费说明;2、10.1 节 `RDP_LOG_ENABLE` 说明改为当前实际状态(注释停用、默认不重定向);11.4 节新增航迹起始未修复观察;版本历史表补充 7d5a56f、f249fdc,参考文档表补充 `docs/` 三份文档。
|
||||||
@@ -37,15 +41,20 @@
|
|||||||
- 扫描一圈完成判据改为「方位波位号 == 0」(7d5a56f):原判据「当前方位波位号 < 上一帧波位号」在机扫模式下遇到转台反转时波位号会变小但并未扫完一圈,造成误判;现 `data_preprocess()` 仅在 `Data_Input[0].Beam_index_aiz == 0` 时返回 1(TWS 满一圈,执行航迹处理),否则返回 2(继续蓄数据,只做滑窗凝聚)。原判据代码注释保留,`last_beam_num` 仍被赋值但不再参与判断。调用方需保证点迹的方位波位号按 0~Beam_num-1 编号且每圈必然出现 0。
|
- 扫描一圈完成判据改为「方位波位号 == 0」(7d5a56f):原判据「当前方位波位号 < 上一帧波位号」在机扫模式下遇到转台反转时波位号会变小但并未扫完一圈,造成误判;现 `data_preprocess()` 仅在 `Data_Input[0].Beam_index_aiz == 0` 时返回 1(TWS 满一圈,执行航迹处理),否则返回 2(继续蓄数据,只做滑窗凝聚)。原判据代码注释保留,`last_beam_num` 仍被赋值但不再参与判断。调用方需保证点迹的方位波位号按 0~Beam_num-1 编号且每圈必然出现 0。
|
||||||
- 点迹-航迹头关联判据改为统一速度区间并增加多普勒-几何一致性约束(7d5a56f,`track_init.cpp`):原先按扫描体制与距离分段收紧速度门限的分支(近程 `r≥1000` 全速 / `r<1000` 半速,中远程 `r≥2000` 全速 / `r<2000` 取 1/2~1/3 速)整体注释停用,改为 `dis ≤ V_MAX·ΔT` 且 `dis ≥ V_MIN·ΔT`,同时要求 `vr_point·v_track_head > 0`,并新增 `dis ≥ |vr_point|·ΔT` 与 `dis ≥ |v_track_head|·ΔT` 两条约束——切向高速目标在 ΔT 内的实际位移远小于 `|vr|·ΔT`,据此被排除,用于限制由切向高速点迹起批出的短航迹。其中 `vmax` 的近程/中远程分支取值相同,均取 `Work_Parameter.V_MAX`。
|
- 点迹-航迹头关联判据改为统一速度区间并增加多普勒-几何一致性约束(7d5a56f,`track_init.cpp`):原先按扫描体制与距离分段收紧速度门限的分支(近程 `r≥1000` 全速 / `r<1000` 半速,中远程 `r≥2000` 全速 / `r<2000` 取 1/2~1/3 速)整体注释停用,改为 `dis ≤ V_MAX·ΔT` 且 `dis ≥ V_MIN·ΔT`,同时要求 `vr_point·v_track_head > 0`,并新增 `dis ≥ |vr_point|·ΔT` 与 `dis ≥ |v_track_head|·ΔT` 两条约束——切向高速目标在 ΔT 内的实际位移远小于 `|vr|·ΔT`,据此被排除,用于限制由切向高速点迹起批出的短航迹。其中 `vmax` 的近程/中远程分支取值相同,均取 `Work_Parameter.V_MAX`。
|
||||||
- 同步 `docs/` 内两份专项文档(本次文档更新):`docs/data_process_flow_report.md` 附录与 `docs/track_init_readme.md` 第 12.1 节的「与 README 的差异」说明改为「差异已按结论同步到 README」并保留更新前的旧表述作为改动缘由;其中「起始输入过滤」一行更正为「上游 `track_asso_process()` 已删除 `Use_Flag==1` 的点迹 + `track_init` 入口再次剔除」,「初始化用点」一行更正为「取下标 `track_start_point_num-3 ~ -1`,航迹更长时不是真正的末三点」;`docs/track_init_readme.md` 第 15 节第 2 条相应更正(`track_init.cpp` L505 的 `L` 覆盖为 `track_start_point_num`,第 L 个点之后的尾部点既不参与初始化也不输出),第 14 节补充说明 `Flag_Direction` 仅由关联输出路径赋值、起批输出不写该字段。
|
- 同步 `docs/` 内两份专项文档(本次文档更新):`docs/data_process_flow_report.md` 附录与 `docs/track_init_readme.md` 第 12.1 节的「与 README 的差异」说明改为「差异已按结论同步到 README」并保留更新前的旧表述作为改动缘由;其中「起始输入过滤」一行更正为「上游 `track_asso_process()` 已删除 `Use_Flag==1` 的点迹 + `track_init` 入口再次剔除」,「初始化用点」一行更正为「取下标 `track_start_point_num-3 ~ -1`,航迹更长时不是真正的末三点」;`docs/track_init_readme.md` 第 15 节第 2 条相应更正(`track_init.cpp` L505 的 `L` 覆盖为 `track_start_point_num`,第 L 个点之后的尾部点既不参与初始化也不输出),第 14 节补充说明 `Flag_Direction` 仅由关联输出路径赋值、起批输出不写该字段。
|
||||||
|
- 关联波门 `ASSO_THORD` 由 3 调大至 4(e0bf227,`parameters.h` 相扫/机扫两组宏同步):判据写作 `d*d < ASSO_THORD*ASSO_THORD`,而 `d` 本身已是马氏距离平方,等效门限由 `d < 3` 放宽为 `d < 4`(TWS 分距离段的比例门限随之由 9/1000、9/100 变为 16/1000、16/100),配合高度门限判定提高机动目标的关联概率;调参时仍需注意这一层「二次方」语义(BUG-20 有意保留)。
|
||||||
|
- TWS 与 TAS 关联的高度门限统一为同一组按航迹距离分段的取值(e0bf227):`r_track ≤ 1000 m` 时 `|h_track − h_point| ≤ 150 m`、`1000~2000 m` 时 ≤ 200 m、`2000~3000 m` 时 ≤ 250 m、`3000~5000 m` 时 ≤ 300 m、`> 5000 m` 不约束。其中 TWS 侧为该门限首次生效(原代码块被注释),TAS 侧 `2000~3000 m` 段由 200 m 放宽到 250 m。
|
||||||
|
- TAS 波束输出的数据率门控条件修正(e0bf227,`tas_ctrl.cpp::tas_beam_output()`):原判据同时要求「距上次波束输出超过 DATA_RATE_TAS」与「航迹时间 T_track 与最新时间戳之差超过 DATA_RATE_TAS」,后者与「选取 CPI 时间最早目标」的语义冲突,会额外抑制本可输出的目标;现仅保留 `delta_T_last_track = (latest_timestamp − last_track_time)/1000 > DATA_RATE_TAS` 一条门控,`delta_T` 改为在选中该目标后按 `(latest_timestamp − CPI_time)/1000` 计算并用于外推,使 TAS 目标输出间隔严格跟随数据率。
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- 修复 MSVC `/W3` 下全部 C4819 / C4018 / C4244 编译警告:源码文件改为带 BOM 的 UTF-8 编码;signed/unsigned 不匹配处改用 `size_t` 循环变量或显式 `static_cast<int>` 比较;double/float、__int64/double 等窄化转换改为 `static_cast` 显式转换,保持原有计算逻辑不变(涉及 `data_process.cpp`、`dot_coh.cpp`、`dot_coh_tas.cpp`、`tas_ctrl.cpp`、`track_asso.cpp`、`track_asso_tas.cpp`、`track_init.cpp`、`track_init_direct_tracking.cpp`、`track_index_mangement.cpp` 等)。
|
- 修复 MSVC `/W3` 下全部 C4819 / C4018 / C4244 编译警告:源码文件改为带 BOM 的 UTF-8 编码;signed/unsigned 不匹配处改用 `size_t` 循环变量或显式 `static_cast<int>` 比较;double/float、__int64/double 等窄化转换改为 `static_cast` 显式转换,保持原有计算逻辑不变(涉及 `data_process.cpp`、`dot_coh.cpp`、`dot_coh_tas.cpp`、`tas_ctrl.cpp`、`track_asso.cpp`、`track_asso_tas.cpp`、`track_init.cpp`、`track_init_direct_tracking.cpp`、`track_index_mangement.cpp` 等)。
|
||||||
- 修复 `TAS_Ctrl::tas_beam_output()` 把航迹向量下标 `earliest_track_idx` 误赋给 `Tracking_beam->TAS_track_index` 的问题(1521592):现输出实际航迹号 `(*trust_track)[earliest_track_idx].Track_Index`,避免跟踪波束批号与目标不符。
|
- 修复 `TAS_Ctrl::tas_beam_output()` 把航迹向量下标 `earliest_track_idx` 误赋给 `Tracking_beam->TAS_track_index` 的问题(1521592):现输出实际航迹号 `(*trust_track)[earliest_track_idx].Track_Index`,避免跟踪波束批号与目标不符。
|
||||||
|
- 修正 README.md(第 2、5.2、8.1、8.3、9.3、13 节)与 `docs/data_process_flow_report.md`(第 0、1、6.1~6.4 节、附录)中航迹起始的步骤顺序描述(纯文档勘误,无代码改动):两份文档原写作「航迹头(1 点)→ 点-航迹头关联(2 点)→ 点-临时航迹关联(≥3 点)→ 起批」,与 `track_init.cpp`(L49-126)每圈的实际执行顺序相反;现更正为「① 点迹先与 ≥2 点临时航迹关联(延长已有临时航迹)→ ② 再与 1 点航迹头关联(两点卡尔曼初始化出 2 点临时航迹)→ ③ 两个阶段都结束后统一删除被消费(`Use_Flag==1`)的点迹、剩余点迹逐条转为新航迹头 → ④ 长度达标的临时航迹经三点卡尔曼初始化转为可靠航迹」,并同步修正流程图与状态机;另补充两点此前的描述缺失:两个关联阶段互不排斥(航迹头阶段不检查临时航迹阶段留下的 `Use_Flag`,同一点迹可同时延长一条临时航迹并开启一条 2 点临时航迹)、两类关联都不做一对一分配(同一条临时航迹可被同圈多个点延长)。
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
- 删除已注释停用的无用代码残留(d6cdbc0):`data_process.cpp` 中 TWS/TAS 分支的 `std::cout` 调试输出注释块,以及 `dot_coh.cpp` 中早期「1 km 以内 SNR < 20 dB 点迹过滤」的注释代码块。仅清理注释,不改变任何运行逻辑。
|
- 删除已注释停用的无用代码残留(d6cdbc0):`data_process.cpp` 中 TWS/TAS 分支的 `std::cout` 调试输出注释块,以及 `dot_coh.cpp` 中早期「1 km 以内 SNR < 20 dB 点迹过滤」的注释代码块。仅清理注释,不改变任何运行逻辑。
|
||||||
|
- 删除 `docs/data_process_flow_report.html`(e0bf227):该 HTML 渲染版与 `docs/data_process_flow_report.md` 内容重复且已明显滞后,保留价值不足;同内容的 HTML 已在 git 忽略的 `design_docs/` 内另行留档。README 目录结构、参考文档表与版本历史表中指向该文件的条目同步移除。
|
||||||
|
|
||||||
## [1.5.5] - 2026-08-27
|
## [1.5.5] - 2026-08-27
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,9 @@
|
|||||||
|
|
||||||
- **双模式处理管线**:data_preprocess 按输入类型与扫描圈完成标志返回 0/1/2/3(TWS 以方位波位号 == 0 判为一圈完成,机扫转台反转不再误判),track_process 据此调度 TWS 凝聚/关联/起始或 TAS 凝聚/关联。
|
- **双模式处理管线**:data_preprocess 按输入类型与扫描圈完成标志返回 0/1/2/3(TWS 以方位波位号 == 0 判为一圈完成,机扫转台反转不再误判),track_process 据此调度 TWS 凝聚/关联/起始或 TAS 凝聚/关联。
|
||||||
- **两帧滑窗点迹凝聚**:TWS 点迹先与上一帧缓存合并凝聚,再进入关联,兼顾跨波位(CPI)相邻点迹的分裂问题;近程模式增加速度维约束。
|
- **两帧滑窗点迹凝聚**:TWS 点迹先与上一帧缓存合并凝聚,再进入关联,兼顾跨波位(CPI)相邻点迹的分裂问题;近程模式增加速度维约束。
|
||||||
- **逻辑法航迹起始**:航迹头(单点)→ 点-头速度法关联(两点)→ 点-临时航迹 EKF 波门 + 折角约束关联(三点及以上)→ 三点卡尔曼初始化转可靠航迹;带起批屏蔽区与重复航迹去重。
|
- **逻辑法航迹起始**:每圈按固定顺序推进——① 未关联点迹先与 ≥2 点临时航迹做 EKF 波门 + 折角约束关联(延长临时航迹),② 再与 1 点航迹头做速度法关联(两点卡尔曼初始化出 2 点临时航迹),③ 两步都做完后删除被消费的点迹、剩余点迹转成新航迹头,④ 长度达标的临时航迹经三点卡尔曼初始化转可靠航迹;带起批屏蔽区与重复航迹去重。
|
||||||
- **3 模型 IMM 滤波**:三个 Singer 模型(低/中/高过程噪声),量测为「距离-方位-径向速度」三维的 EKF,多普勒残差按盲速折叠,似然用 3×3 新息协方差。
|
- **3 模型 IMM 滤波**:三个 Singer 模型(低/中/高过程噪声),量测为「距离-方位-径向速度」三维的 EKF,多普勒残差按盲速折叠,似然用 3×3 新息协方差。
|
||||||
- **最近邻数据关联**:TWS 按航迹距离分段收紧模型 3 波门并附加距离门限;TAS 附加按距离分段的高度门限。ΔT ≤ 0(点迹时间戳不晚于航迹时间)的候选不更新航迹状态、仅消费该点迹(标记已使用),避免其继续起批而生成虚假 TWS 航迹。关联输出的航迹同时给出**靠近/远离方向标志**:`Flag_Direction = vr_point > 0 ? 1 : 0`(1 靠近 / 0 远离),TWS、TAS 两通道一致。
|
- **最近邻数据关联**:三模型统计距离波门 `ASSO_THORD = 4`(等效 d < 4,TWS 另按航迹距离分段收紧模型 3 波门),再叠加高度门限(≤1000 m 150 m / 2000 m 200 m / 3000 m 250 m / 5000 m 300 m,更远不约束)与 TWS 弦距-位移距离门限。ΔT ≤ 0(点迹时间戳不晚于航迹时间)的候选不更新航迹状态、仅消费该点迹(标记已使用),避免其继续起批而生成虚假 TWS 航迹。关联输出的航迹同时给出**靠近/远离方向标志**:`Flag_Direction = vr_point > 0 ? 1 : 0`(1 靠近 / 0 远离),TWS、TAS 两通道一致。
|
||||||
- **高度维独立平滑**:按距离分段选择滑动平均窗长(5/6/7/9 点),抑制俯仰测量跳变。
|
- **高度维独立平滑**:按距离分段选择滑动平均窗长(5/6/7/9 点),抑制俯仰测量跳变。
|
||||||
- **TAS 波束控制**:手动转 TAS 目标入队(队列长度与容量随扫描体制切换),按最新时间戳外推输出跟踪波束(距离/方位/俯仰/批号)。
|
- **TAS 波束控制**:手动转 TAS 目标入队(队列长度与容量随扫描体制切换),按最新时间戳外推输出跟踪波束(距离/方位/俯仰/批号)。
|
||||||
- **航迹生命周期管理**:外推轮数计数、超时消亡、手动删除、全清空(含各模块 reset,防重连后幽灵航迹)。
|
- **航迹生命周期管理**:外推轮数计数、超时消亡、手动删除、全清空(含各模块 reset,防重连后幽灵航迹)。
|
||||||
@@ -77,8 +77,8 @@
|
|||||||
│ └── requirements.md # 需求说明:日志文件输出功能修改要求(含 rdbuf() 重定向参考示例)
|
│ └── requirements.md # 需求说明:日志文件输出功能修改要求(含 rdbuf() 重定向参考示例)
|
||||||
├── docs/ # 专项说明文档(按当前源码整理,与 README 互补)
|
├── docs/ # 专项说明文档(按当前源码整理,与 README 互补)
|
||||||
│ ├── data_process_flow_report.md # 数据处理流程与关键逻辑说明(前处理/判圈、凝聚、关联与滤波、起始、外推消亡、TAS 波束、参数脉络)
|
│ ├── data_process_flow_report.md # 数据处理流程与关键逻辑说明(前处理/判圈、凝聚、关联与滤波、起始、外推消亡、TAS 波束、参数脉络)
|
||||||
│ ├── data_process_flow_report.html # 上文的 HTML 渲染版(浏览器直接打开)
|
|
||||||
│ └── track_init_readme.md # 航迹起始(Track Init)详细逻辑说明(阶段流程、条件汇总、输出字段映射、风险点、代码索引)
|
│ └── track_init_readme.md # 航迹起始(Track Init)详细逻辑说明(阶段流程、条件汇总、输出字段映射、风险点、代码索引)
|
||||||
|
├── design_docs/ # 设计与讨论资料留档(被 .gitignore 忽略、不入库;含设计讨论、产品介绍与 README/流程报告的导出、渲染版本)
|
||||||
├── .vscode/ # VS Code 工程配置
|
├── .vscode/ # VS Code 工程配置
|
||||||
│ ├── settings.json # cmake.generator=NMake、MSVC2013 x86 环境变量、compile_commands
|
│ ├── settings.json # cmake.generator=NMake、MSVC2013 x86 环境变量、compile_commands
|
||||||
│ ├── cmake-variants.yaml # X256_PS / X256_MS × Release / Debug 变体
|
│ ├── cmake-variants.yaml # X256_PS / X256_MS × Release / Debug 变体
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
│ ├── dot_coh_tas.h / .cpp # TAS 点迹凝聚
|
│ ├── dot_coh_tas.h / .cpp # TAS 点迹凝聚
|
||||||
│ ├── coor_trans.h / .cpp # 极坐标 ↔ 直角坐标转换
|
│ ├── coor_trans.h / .cpp # 极坐标 ↔ 直角坐标转换
|
||||||
│ ├── kalman.h / .cpp # 卡尔曼滤波:两点/三点初始化、线性 KF、EKF(含多普勒)、统计距离、盲速计算
|
│ ├── kalman.h / .cpp # 卡尔曼滤波:两点/三点初始化、线性 KF、EKF(含多普勒)、统计距离、盲速计算
|
||||||
│ ├── track_asso.h / .cpp # TWS 航迹关联:IMM 交互 → 滤波 → 输出、距离/俯仰门限、高度平滑
|
│ ├── track_asso.h / .cpp # TWS 航迹关联:IMM 交互 → 滤波 → 输出、统计距离/高度/距离门限、高度平滑
|
||||||
│ ├── track_asso_tas.h / .cpp # TAS 航迹关联(独立实现,量测门限与数据率不同)
|
│ ├── track_asso_tas.h / .cpp # TAS 航迹关联(独立实现,量测门限与数据率不同)
|
||||||
│ ├── track_init.h / .cpp # 逻辑法航迹起始:点-临时航迹关联、点-航迹头关联、转可靠航迹、屏蔽区
|
│ ├── track_init.h / .cpp # 逻辑法航迹起始:点-临时航迹关联、点-航迹头关联、转可靠航迹、屏蔽区
|
||||||
│ ├── track_init_direct_tracking.h/.cpp# 引导跟踪航迹起始(当前入口为空实现,未启用)
|
│ ├── track_init_direct_tracking.h/.cpp# 引导跟踪航迹起始(当前入口为空实现,未启用)
|
||||||
@@ -253,7 +253,7 @@ classDiagram
|
|||||||
| Dot_Coh_TAS | TAS 点迹凝聚(单帧,距离/方位/速度三维门限) |
|
| Dot_Coh_TAS | TAS 点迹凝聚(单帧,距离/方位/速度三维门限) |
|
||||||
| Track_Asso | TWS 点航关联 + IMM 滤波:模型交互 → 门限筛选(NN)→ 各模型 EKF → 概率更新 → 模型输出;未关联航迹外推;高度平滑;ΔT≤0(乱序/重复时间戳)的候选取出后不更新滤波、不刷新航迹,仅消费该点迹 |
|
| Track_Asso | TWS 点航关联 + IMM 滤波:模型交互 → 门限筛选(NN)→ 各模型 EKF → 概率更新 → 模型输出;未关联航迹外推;高度平滑;ΔT≤0(乱序/重复时间戳)的候选取出后不更新滤波、不刷新航迹,仅消费该点迹 |
|
||||||
| Track_Asso_Tas | TAS 航迹关联(只处理指定批号 tas_track_idx,门限与 TWS 略有差异) |
|
| Track_Asso_Tas | TAS 航迹关联(只处理指定批号 tas_track_idx,门限与 TWS 略有差异) |
|
||||||
| Track_Init | 逻辑法航迹起始:航迹头维护、点-头关联(两点)、点-临时航迹关联(三点及以上)、起批(三点卡尔曼初始化)、屏蔽区判断、临时航迹消亡 |
|
| Track_Init | 逻辑法航迹起始,每圈顺序固定:点-临时航迹关联(延长 ≥2 点临时航迹)→ 点-航迹头关联(两点起始)→ 剩余点转新航迹头 → 长度达标者起批(三点卡尔曼初始化);另含起批屏蔽区判断与临时航迹消亡 |
|
||||||
| Track_Die / Track_Die_Tas | 可靠航迹消亡:外推轮数超限或手动删除标志置位时输出消亡批号并删除 |
|
| Track_Die / Track_Die_Tas | 可靠航迹消亡:外推轮数超限或手动删除标志置位时输出消亡批号并删除 |
|
||||||
| TAS_Ctrl | TAS 波束控制:手动目标入队(tas_target_add)、失效目标出队(tas_target_del)、跟踪波束预测输出(tas_beam_output:数据率门控 + 队内选择最早 CPI 目标)、调度时刻记录(last_track_time) |
|
| TAS_Ctrl | TAS 波束控制:手动目标入队(tas_target_add)、失效目标出队(tas_target_del)、跟踪波束预测输出(tas_beam_output:数据率门控 + 队内选择最早 CPI 目标)、调度时刻记录(last_track_time) |
|
||||||
| Track_Ind_Mangement | 航迹号 1~500 的顺序分配与回绕复用 |
|
| Track_Ind_Mangement | 航迹号 1~500 的顺序分配与回绕复用 |
|
||||||
@@ -358,7 +358,7 @@ flowchart TD
|
|||||||
C --> D["dot_coh 两帧滑窗凝聚 → point_recv"]
|
C --> D["dot_coh 两帧滑窗凝聚 → point_recv"]
|
||||||
D --> E["track_asso: IMM 交互 → 点航波门筛选(NN)→ EKF 滤波 → 模型输出"]
|
D --> E["track_asso: IMM 交互 → 点航波门筛选(NN)→ EKF 滤波 → 模型输出"]
|
||||||
E --> F["track_die: 外推超限/手动删除 → 输出消亡批号"]
|
E --> F["track_die: 外推超限/手动删除 → 输出消亡批号"]
|
||||||
F --> G["track_init: 点-临时航迹关联 → 点-航迹头关联 → 起批转可靠航迹"]
|
F --> G["track_init: 点-临时航迹关联 → 点-航迹头关联 → 剩余点转新航迹头 → 起批转可靠航迹"]
|
||||||
G --> H["输出 Trust_Track_Output(含起批历史点)"]
|
G --> H["输出 Trust_Track_Output(含起批历史点)"]
|
||||||
H --> I["Beam_Ctrl: 手动 TAS 目标入队 / 波束输出"]
|
H --> I["Beam_Ctrl: 手动 TAS 目标入队 / 波束输出"]
|
||||||
```
|
```
|
||||||
@@ -382,20 +382,23 @@ flowchart TD
|
|||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
A["未关联点迹"] --> B["转航迹头 Temp_track(1点) buff_round=1"]
|
A["本圈未关联点迹(point_recv → point_process)"] --> A1["临时航迹所有点的 buff_round +1"]
|
||||||
B --> C{"下一帧点迹"}
|
A1 --> B["① 点-临时航迹关联(≥2 点临时航迹、末点 buff_round≥2):EKF 统计距离波门 d²≤64、折角<60°、径向速度同号、|Δr|≥5m → 复制原航迹并追加新点"]
|
||||||
C --> D["点-航迹头关联:V_MIN·ΔT ≤ dis ≤ V_MAX·ΔT、径向速度同号、dis ≥ |vr_point|·ΔT 且 dis ≥ |v_track_head|·ΔT → 两点卡尔曼初始化(航迹头→2 点临时航迹)"]
|
B --> C["② 点-航迹头关联(1 点航迹头、buff_round≥2):V_MIN·ΔT ≤ dis ≤ V_MAX·ΔT、径向速度同号、dis ≥ |vr_point|·ΔT 且 dis ≥ |v_track_head|·ΔT → 两点卡尔曼初始化(航迹头 + 新点 → 2 点临时航迹)"]
|
||||||
D --> E{"后续点迹"}
|
C --> D["③ 删除 Use_Flag==1 的点迹,剩余点全部转为新航迹头 Temp_track(1 点、buff_round=1)"]
|
||||||
E --> F["点-临时航迹关联:EKF 统计距离波门 d²≤64、折角<60°、径向速度同号、|Δr|≥5m"]
|
D --> E{"④ 长度 ≥ track_start_point_num(3~9) 且 ≤10 且不在起批屏蔽区 ?"}
|
||||||
F --> G{"长度 ≥ track_start_point_num(3~9) 且 ≤10"}
|
E -- 是 --> F["重复航迹去重(保留末点 d 更小者)→ 三点卡尔曼初始化"]
|
||||||
G -- 是 --> H["屏蔽区判断 → 重复航迹去重(保留末点 d 更小者)→ 三点卡尔曼初始化"]
|
F --> G["转可靠航迹:分配航迹号 1~500,IMM 三模型同状态初始化 u=1/3"]
|
||||||
H --> I["转可靠航迹:分配航迹号 1~500,IMM 三模型同状态初始化 u=1/3"]
|
G --> H["输出前 track_start_point_num 个历史点 Trust_Track_Output[i][0..L-1]"]
|
||||||
I --> J["输出前 track_start_point_num 个历史点 Trust_Track_Output[i][0..L-1]"]
|
E -- 否 --> I["留在临时航迹表,下一圈继续关联"]
|
||||||
G -- 否 --> K{"buff_round>2 或 长度≥10 ?"}
|
H --> J["⑤ 临时航迹消亡:末点 buff_round>2 或 长度≥10"]
|
||||||
K -- 是 --> L["临时航迹消亡"]
|
I --> J
|
||||||
K -- 否 --> E
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> 顺序说明:`track_init_process_logic()` 中四步的先后顺序固定、不可颠倒——先延长已有临时航迹,再与航迹头配对,两步都走完才生成新航迹头,最后才把长度达标的临时航迹转为可靠航迹(因此当圈新建的 2 点临时航迹不可能当圈起批,长度刚达标的临时航迹则可以当圈起批);临时航迹消亡在第 ⑤ 步、即全部起始动作之后执行。
|
||||||
|
>
|
||||||
|
> 第 ① ② 步**互不排斥**:两者都只把命中的点迹标记 `Use_Flag=1`,航迹头关联并不检查临时航迹关联留下的标记,因此同一点迹可能既延长一条临时航迹、又开启一条新的两点临时航迹;两类关联也都不做一对一分配(同一条临时航迹可被本圈多个点延长,同一个航迹头也可与本圈多个点配对)。只有走完两步后才统一删除 `Use_Flag==1` 的点迹,其余点迹成为新航迹头。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. 算法实现详解
|
## 9. 算法实现详解
|
||||||
@@ -447,7 +450,34 @@ $$
|
|||||||
|
|
||||||
### 9.3 航迹起始(逻辑法)
|
### 9.3 航迹起始(逻辑法)
|
||||||
|
|
||||||
#### (1) 点-航迹头关联(两点起始)
|
每圈(model=1)在 `track_init_process_logic()` 中按**固定顺序**执行下列四步,顺序不可颠倒:
|
||||||
|
|
||||||
|
1. **点-临时航迹关联**:本圈未关联点迹优先延长已有的 ≥2 点临时航迹(判据见 (1));
|
||||||
|
2. **点-航迹头关联**:随后点迹与 1 点航迹头配对,产生新的 2 点临时航迹(判据见 (2));
|
||||||
|
3. **剩余点迹转航迹头**:前两步只把命中的点迹标记为已使用(`Use_Flag=1`),两步都做完后才统一删除这些点迹,其余点迹逐条转为新航迹头(见 (3));
|
||||||
|
4. **转可靠航迹(起批)**:长度达标的临时航迹经三点卡尔曼初始化转为可靠航迹(见 (4));起批动作完成后才消亡不满足条件的临时航迹。
|
||||||
|
|
||||||
|
> 两点补充:① 第 1、2 步**互不排斥**——航迹头关联不检查临时航迹关联留下的 `Use_Flag`,因此同一点迹可能既延长一条临时航迹、又开启一条新的两点临时航迹;两类关联也都不做一对一分配(同一条临时航迹可被本圈多个点延长,同一个航迹头也可与本圈多个点配对)。② 每圈入口先把**所有**临时航迹所有点的 `buff_round` 加 1 再做关联,新建点(航迹头或被关联上的新点)`buff_round = 1`,因此当圈新建的 2 点临时航迹要到下一圈末点 `buff_round` 变为 2 之后才参与第 1 步。
|
||||||
|
|
||||||
|
#### (1) 点-临时航迹关联(延长 ≥2 点临时航迹)
|
||||||
|
|
||||||
|
对 ≥ 2 点的临时航迹(末点 buff_round ≥ 2),用航迹末点状态做 EKF 一步预测,计算三维(距离-方位-径向速度)马氏统计距离 d(见 9.5.3),并要求 |r_point − r_temp| ≥ 5 m,同时满足:
|
||||||
|
|
||||||
|
$$
|
||||||
|
d^2 \le TRACK\_START\_THRESHOLD^2 = 64,\qquad
|
||||||
|
\alpha < ALPHA\_START = 60°,\qquad
|
||||||
|
v_{r,point}\cdot v_{r,track}>0
|
||||||
|
$$
|
||||||
|
|
||||||
|
折角 α 为最近三点连线夹角(度):
|
||||||
|
|
||||||
|
$$
|
||||||
|
\alpha=\arccos\left(\frac{\vec{D_{12}}\cdot\vec{D_{23}}}{\|\vec{D_{12}}\|\,\|\vec{D_{23}}\|}\right)\cdot\frac{180}{\pi}
|
||||||
|
$$
|
||||||
|
|
||||||
|
关联成功后**复制原临时航迹并追加该点迹**,新航迹的 4 维状态用最近两点做**两点卡尔曼初始化**(见 9.5.2)重新得到。
|
||||||
|
|
||||||
|
#### (2) 点-航迹头关联(两点起始)
|
||||||
|
|
||||||
对单点航迹头(buff_round ≥ 2),量测点需同时满足以下四个条件(7d5a56f 起的判据):
|
对单点航迹头(buff_round ≥ 2),量测点需同时满足以下四个条件(7d5a56f 起的判据):
|
||||||
|
|
||||||
@@ -462,25 +492,13 @@ $$
|
|||||||
|
|
||||||
> 历史行为(已注释停用):原先按扫描体制与距离分段收紧速度门限——近程 r≥1000 用全速、r<1000 用半速;中远程 r≥2000 用全速、r<2000 取下限 1/2·V_min·ΔT / 上限 1/3·V_max·ΔT。
|
> 历史行为(已注释停用):原先按扫描体制与距离分段收紧速度门限——近程 r≥1000 用全速、r<1000 用半速;中远程 r≥2000 用全速、r<2000 取下限 1/2·V_min·ΔT / 上限 1/3·V_max·ΔT。
|
||||||
|
|
||||||
关联成功用 **两点卡尔曼初始化**(见 9.5.2)。
|
关联成功用 **两点卡尔曼初始化**(见 9.5.2)生成 2 点临时航迹:第 1 点为原航迹头,第 2 点为该点迹。
|
||||||
|
|
||||||
#### (2) 点-临时航迹关联(三点及以上)
|
#### (3) 剩余点迹转航迹头
|
||||||
|
|
||||||
对 ≥ 2 点的临时航迹,用航迹末点状态做 EKF 一步预测,计算三维(距离-方位-径向速度)马氏统计距离 d(见 9.5.3),并要求 |r_point − r_head| ≥ 5 m,同时满足:
|
第 (1)(2) 步结束后统一删除 `Use_Flag==1` 的点迹;剩余点迹回写 `point_recv`(随后被整体清空),并**逐条新建 1 点临时航迹(航迹头)**:位置直接取点迹的直角坐标、速度置 0、`buff_round = 1`。新航迹头当圈不再参与任何关联,只能从下一圈开始按第 (2) 步配对。
|
||||||
|
|
||||||
$$
|
#### (4) 转可靠航迹(起批)
|
||||||
d^2 \le TRACK\_START\_THRESHOLD^2 = 64,\qquad
|
|
||||||
\alpha < ALPHA\_START = 60°,\qquad
|
|
||||||
v_{r,point}\cdot v_{r,track}>0
|
|
||||||
$$
|
|
||||||
|
|
||||||
折角 α 为最近三点连线夹角(度):
|
|
||||||
|
|
||||||
$$
|
|
||||||
\alpha=\arccos\left(\frac{\vec{D_{12}}\cdot\vec{D_{23}}}{\|\vec{D_{12}}\|\,\|\vec{D_{23}}\|}\right)\cdot\frac{180}{\pi}
|
|
||||||
$$
|
|
||||||
|
|
||||||
#### (3) 转可靠航迹(起批)
|
|
||||||
|
|
||||||
临时航迹长度 N 满足 track_start_point_num ≤ N ≤ 10(起批点数由参数给定,典型 3~4,接口层校验 3~9)且不在起批屏蔽区内(屏蔽区为距离-方位矩形区域,最多 30 个)时进入起批队列;同源(前三点时间/距离相同)的重复航迹只保留 d 较小者(比较下标 `track_start_point_num-1` 处的 d)。起批时令 L = track_start_point_num,用航迹中下标 L-3、L-2、L-1 的三个点做 **三点卡尔曼初始化** 得到 6 维状态(航迹长度恰为 L 时即最近三点),构造 Trust_Track:
|
临时航迹长度 N 满足 track_start_point_num ≤ N ≤ 10(起批点数由参数给定,典型 3~4,接口层校验 3~9)且不在起批屏蔽区内(屏蔽区为距离-方位矩形区域,最多 30 个)时进入起批队列;同源(前三点时间/距离相同)的重复航迹只保留 d 较小者(比较下标 `track_start_point_num-1` 处的 d)。起批时令 L = track_start_point_num,用航迹中下标 L-3、L-2、L-1 的三个点做 **三点卡尔曼初始化** 得到 6 维状态(航迹长度恰为 L 时即最近三点),构造 Trust_Track:
|
||||||
|
|
||||||
@@ -675,18 +693,19 @@ $$
|
|||||||
|
|
||||||
#### TWS(track_asso.cpp)
|
#### TWS(track_asso.cpp)
|
||||||
|
|
||||||
对每条航迹 × 每个点计算三模型 d1, d2, d3,波门按航迹距离分段:
|
对每条航迹 × 每个点计算三模型 d1, d2, d3,波门按航迹距离分段(`ASSO_THORD = 4`,判据写作 `d*d < ASSO_THORD*ASSO_THORD`,而 d 本身已是马氏距离平方,故下表的等价门限为 d < 4):
|
||||||
|
|
||||||
| 航迹距离 | 模型 1/2 门限 | 模型 3 门限 |
|
| 航迹距离 | 模型 1/2 门限 | 模型 3 门限 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| r_track ≤ 500 m | d_i² < 9 | d_3² < 9/1000(≈关闭) |
|
| r_track ≤ 500 m | d_i² < 16 | d_3² < 16/1000(≈关闭) |
|
||||||
| 500 < r_track < 1000 m | d_i² < 9 | d_3² < 9/100(收紧) |
|
| 500 < r_track < 1000 m | d_i² < 16 | d_3² < 16/100(收紧) |
|
||||||
| r_track ≥ 1000 m | d_i² < 9 | d_3² < 9 |
|
| r_track ≥ 1000 m | d_i² < 16 | d_3² < 16 |
|
||||||
|
|
||||||
同时满足两个附加门限:
|
关联判据在 `model_filter()` 中拆为三个布尔量,三者同时通过才记为候选:`thd_d`(上表统计距离门限)、`thd_h`(高度门限)、`thd_r`(距离门限)。
|
||||||
|
|
||||||
- **俯仰门限 d_p**:当前恒为 true(分距离段 7°/5°/10° 的逻辑在源码中被注释停用);
|
- **高度门限 thd_h**(e0bf227 起生效):以 |h_track − h_point| 与航迹距离分段比较,取值与 TAS 通道一致——≤ 1000 m 时 ≤ 150 m、1000~2000 m 时 ≤ 200 m、2000~3000 m 时 ≤ 250 m、3000~5000 m 时 ≤ 300 m、> 5000 m 时不约束。该项原为注释停用的代码块(等价于恒通过),现正式参与关联判定,用于压制俯仰测量跳变引起的错误关联;
|
||||||
- **距离门限 d_r**:以航迹-点迹弦距 R = √(r_t² + r_p² − 2·r_t·r_p·cos Δθ)(Δθ 为环绕方位差)与航迹速度位移 VT = v_track·ΔT 判断:
|
- **俯仰门限 d_p**:分距离段 7°/5°/10° 的逻辑仍在源码中注释停用,不参与判定(其作用已由高度门限覆盖);
|
||||||
|
- **距离门限 thd_r**:以航迹-点迹弦距 R = √(r_t² + r_p² − 2·r_t·r_p·cos Δθ)(Δθ 为环绕方位差)与航迹速度位移 VT = v_track·ΔT 判断:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
VT<100\ \text{且}\ R>300\ \Rightarrow 拒绝;\qquad
|
VT<100\ \text{且}\ R>300\ \Rightarrow 拒绝;\qquad
|
||||||
@@ -708,17 +727,17 @@ $$
|
|||||||
|
|
||||||
#### TAS(track_asso_tas.cpp)
|
#### TAS(track_asso_tas.cpp)
|
||||||
|
|
||||||
只处理 tas_track_idx 指定的航迹,门限:
|
只处理 tas_track_idx 指定的航迹,只有统计距离与高度两个门限,两者同时通过(`thd_d && thd_h`)才记为候选:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
d_i^2 < ASSO\_THORD^2 = 9\ \ \text{且高度门限}\ d_h=1
|
thd\_d:\ d_i^2 < ASSO\_THORD^2 = 16 \qquad\text{且}\qquad thd\_h:\ \text{高度门限通过}
|
||||||
$$
|
$$
|
||||||
|
|
||||||
高度门限按航迹距离分段:≤1000 m:|h_t−h_p| ≤ 150 m;1000~2000 m:≤ 200 m;2000~3000 m:≤ 200 m;3000~5000 m:≤ 300 m;>5000 m:不约束。
|
高度门限按航迹距离分段:≤1000 m:|h_t−h_p| ≤ 150 m;1000~2000 m:≤ 200 m;2000~3000 m:≤ 250 m;3000~5000 m:≤ 300 m;>5000 m:不约束(与 TWS 通道 9.6 的取值相同)。
|
||||||
|
|
||||||
输出航迹同样写入**方向标志** `Flag_Direction`(由 `vr_point` 符号决定,f249fdc),规则与 TWS 通道一致。
|
输出航迹同样写入**方向标志** `Flag_Direction`(由 `vr_point` 符号决定,f249fdc),规则与 TWS 通道一致。
|
||||||
|
|
||||||
> ⚠ **波门语义提示**:代码中 d 本身已是马氏距离平方,但门限写作 d*d < ASSO_THORD*ASSO_THORD,等效于 d < 3(而非 √d < 3)。该行为在 BUG-20 中被识别,**有意保留未改**;ASSO_THORD/1000、/100 已改为浮点除法(BUG-21 修复)。
|
> ⚠ **波门语义提示**:代码中 d 本身已是马氏距离平方,但门限写作 d*d < ASSO_THORD*ASSO_THORD,等效于 d < 4(而非 √d < 4)。该行为在 BUG-20 中被识别,**有意保留未改**;ASSO_THORD/1000、/100 已改为浮点除法(BUG-21 修复)。TAS 不区分距离段,`ASSO_THORD` 原值直接作为门限。
|
||||||
|
|
||||||
### 9.7 高度平滑
|
### 9.7 高度平滑
|
||||||
|
|
||||||
@@ -753,14 +772,18 @@ $$
|
|||||||
|
|
||||||
- **入队条件**(仅手动):manual_tracking_flag==1 且 Track_Mode==0 且队列未满(MAX_TAS_NUM,相扫 4 / 机扫 1)且不在 TAS 禁止区内。入队即置 Track_Mode=1、以航迹时间初始化 last_track_time,并输出一次航迹更新。
|
- **入队条件**(仅手动):manual_tracking_flag==1 且 Track_Mode==0 且队列未满(MAX_TAS_NUM,相扫 4 / 机扫 1)且不在 TAS 禁止区内。入队即置 Track_Mode=1、以航迹时间初始化 last_track_time,并输出一次航迹更新。
|
||||||
- **出队**:队列中目标在航迹表中不存在、或不再处于手动 TAS 状态时清除。(自动转 TAS / 自动退出的 tas_auto_start/tas_auto_end 逻辑全部注释停用——只支持手动。)
|
- **出队**:队列中目标在航迹表中不存在、或不再处于手动 TAS 状态时清除。(自动转 TAS / 自动退出的 tas_auto_start/tas_auto_end 逻辑全部注释停用——只支持手动。)
|
||||||
- **波束输出**:在 TAS 队列内遍历,选择满足**数据率门控**的目标——目标距上次波束输出(`last_track_time`)的时间、以及航迹时间 T_track 与最新时间戳 latest_timestamp 的差值,均须大于运行时参数 `Work_Parameter.DATA_RATE_TAS` 秒(单位 s,1521592 起由 Hz 改为 s,需为 >0 的有效值),保证 TAS 目标输出间隔不随波束时间(Beam_Ctrl 调用频率)变化;多个候选中取 CPI 时间最早者,用其状态外推到 latest_timestamp:
|
- **波束输出**:在 TAS 队列内遍历,逐个目标先按**数据率门控**筛选——仅要求目标距上次波束输出(`last_track_time`)的时间 `delta_T_last_track = (latest_timestamp − last_track_time)/1000` 大于运行时参数 `Work_Parameter.DATA_RATE_TAS` 秒(单位 s,1521592 起由 Hz 改为 s,需为 >0 的有效值),保证 TAS 目标输出间隔不随波束时间(Beam_Ctrl 调用频率)变化;对通过门控的目标再比较航迹时间 `T_track`,取 CPI 时间最早者,选中后按其 CPI 时间与最新时间戳之差外推到 latest_timestamp:
|
||||||
|
|
||||||
$$
|
$$
|
||||||
|
\Delta T=(latest\_timestamp-CPI\_time)/1000,\qquad
|
||||||
x_p=x+v_x\Delta T,\quad y_p=y+v_y\Delta T,\quad
|
x_p=x+v_x\Delta T,\quad y_p=y+v_y\Delta T,\quad
|
||||||
r_p=\sqrt{x_p^2+y_p^2},\quad \theta_p=\operatorname{atan2}(y_p,x_p)
|
r_p=\sqrt{x_p^2+y_p^2},\quad \theta_p=\operatorname{atan2}(y_p,x_p)
|
||||||
$$
|
$$
|
||||||
|
|
||||||
输出 TrackingBeam{open_flag=1, type=1, Range=rp, Azi=θp(°), Elev=asin(h/rp)(°), TAS_track_index};队空、目标不在航迹表或数据率门控未通过时 open_flag=0。输出后更新该目标队列项的 last_track_time;原每次 Beam_Ctrl 末尾的整队循环移位(队列轮转)已停用,改为按数据率门控在队列内轮换目标。
|
输出 TrackingBeam{open_flag=1, type=1, Range=rp, Azi=θp(°), Elev=asin(h/rp)(°), TAS_track_index};队空、目标不在航迹表或数据率门控未通过时 open_flag=0。输出后更新该目标队列项的 last_track_time;原每次 Beam_Ctrl 末尾的整队循环移位(队列轮转)已停用,改为按数据率门控在队列内轮换目标。
|
||||||
|
|
||||||
|
> e0bf227 修正:数据率门控原先同时要求「距上次波束输出」与「航迹时间 T_track 距最新时间戳」都超过 DATA_RATE_TAS,第二个条件与「选 CPI 最早目标」的语义冲突(航迹时间越早反倒越容易被抑制),会漏掉本应输出的波束;现已只保留前者。
|
||||||
|
|
||||||
- tas_ctrl_process 入口强制 *Trust_track_num_Output=0 并在写入前检查容量,防止输出数组越界(BUG-09 修复)。
|
- tas_ctrl_process 入口强制 *Trust_track_num_Output=0 并在写入前检查容量,防止输出数组越界(BUG-09 修复)。
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -783,7 +806,7 @@ $$
|
|||||||
| ALPHA_START | 60 | 同左 | 起批折角(°) |
|
| ALPHA_START | 60 | 同左 | 起批折角(°) |
|
||||||
| TRACK_DIE_ROUND | 4 | 4 | TWS 航迹消亡外推轮数 |
|
| TRACK_DIE_ROUND | 4 | 4 | TWS 航迹消亡外推轮数 |
|
||||||
| TRACK_DIE_ROUND_TAS | 5 | 96 | TAS 航迹消亡外推轮数 |
|
| TRACK_DIE_ROUND_TAS | 5 | 96 | TAS 航迹消亡外推轮数 |
|
||||||
| ASSO_THORD | 3 | 同左 | 关联波门 |
|
| ASSO_THORD | 4 | 同左 | 关联波门(判据 d*d < ASSO_THORD²,d 已是马氏距离平方,等效 d < 4;e0bf227 起由 3 调大至 4) |
|
||||||
| H_F_WIN_LEN | 3 | 同左 | 高度平滑窗长基数(实际 +2/+3/+4/+6) |
|
| H_F_WIN_LEN | 3 | 同左 | 高度平滑窗长基数(实际 +2/+3/+4/+6) |
|
||||||
| TAS_QUEUE_LENGTH / MAX_TAS_NUM | 4 / 4 | 1 / 1 | TAS 队列长度 / 最大 TAS 目标数 |
|
| TAS_QUEUE_LENGTH / MAX_TAS_NUM | 4 / 4 | 1 / 1 | TAS 队列长度 / 最大 TAS 目标数 |
|
||||||
| FREQ0 | 9.2 GHz | 同左 | 载波频点(原 FREQ0~FREQ20 一组宏已精简为单个 FREQ0,e729c5b 起由 16.8 GHz 改为 9.2 GHz) |
|
| FREQ0 | 9.2 GHz | 同左 | 载波频点(原 FREQ0~FREQ20 一组宏已精简为单个 FREQ0,e729c5b 起由 16.8 GHz 改为 9.2 GHz) |
|
||||||
@@ -819,6 +842,7 @@ $$
|
|||||||
- **越界/防御**:TAS Point_Sum 限幅 150(BUG-04);size()-1 下溢(BUG-05);起批点数校验(BUG-06);航迹号下标校验(BUG-10);Beam_Ctrl 输出计数清零+容量检查(BUG-09);消亡空向量保护(BUG-34);航迹号 500 可复用(BUG-35);局部结构体值初始化(BUG-37)。
|
- **越界/防御**:TAS Point_Sum 限幅 150(BUG-04);size()-1 下溢(BUG-05);起批点数校验(BUG-06);航迹号下标校验(BUG-10);Beam_Ctrl 输出计数清零+容量检查(BUG-09);消亡空向量保护(BUG-34);航迹号 500 可复用(BUG-35);局部结构体值初始化(BUG-37)。
|
||||||
- **时间戳/时序**:TWS 关联 ΔT≤0 的候选不参与滤波更新、不刷新航迹状态并消费该点迹(604f158 起由「剔除候选、点迹保持未使用」改为当前行为,仍属 BUG-15 处置范围);TAS 关联 ΔT≤0 拒绝(BUG-16);TAS 外推负时间差跳过(BUG-17);Bind_speed 除零保护(BUG-19)。
|
- **时间戳/时序**:TWS 关联 ΔT≤0 的候选不参与滤波更新、不刷新航迹状态并消费该点迹(604f158 起由「剔除候选、点迹保持未使用」改为当前行为,仍属 BUG-15 处置范围);TAS 关联 ΔT≤0 拒绝(BUG-16);TAS 外推负时间差跳过(BUG-17);Bind_speed 除零保护(BUG-19)。
|
||||||
- **数值稳定性**:方位残差 ±π 环绕(BUG-22);IMM 概率零分母/奇异保护(BUG-23);EKF 似然 3×3 新息协方差(BUG-24);航向角 atan2(BUG-26);asin 定义域钳位(BUG-27);近程模型 3 门限浮点除法(BUG-21);track_clear_all 全模块 reset(BUG-28);未初始化变量修复(BUG-11/12/14)。
|
- **数值稳定性**:方位残差 ±π 环绕(BUG-22);IMM 概率零分母/奇异保护(BUG-23);EKF 似然 3×3 新息协方差(BUG-24);航向角 atan2(BUG-26);asin 定义域钳位(BUG-27);近程模型 3 门限浮点除法(BUG-21);track_clear_all 全模块 reset(BUG-28);未初始化变量修复(BUG-11/12/14)。
|
||||||
|
- **后修订(e0bf227,BUG_FIX_REPORT.md 成文之后)**:TWS 关联高度门限由注释状态改为实际生效(`track_asso.cpp`),统计距离/高度/距离三类判据拆为独立布尔量,`ASSO_THORD` 由 3 调大至 4;TAS 关联高度门限 2000~3000 m 段放宽至 250 m;修复 `tas_beam_output()` 数据率门控误判(详见 CHANGELOG 的 Unreleased 与 9.6、9.10)。
|
||||||
|
|
||||||
### 11.2 有意保留 / 未修复(标注于 archived_docs/BUG_REPORT.md)
|
### 11.2 有意保留 / 未修复(标注于 archived_docs/BUG_REPORT.md)
|
||||||
|
|
||||||
@@ -851,7 +875,7 @@ $$
|
|||||||
- 起批判据对马氏距离平方再次平方(`d*d ≤ TRACK_START_THRESHOLD²`),实际门限为 `d ≤ 8`,按字面 `d² ≤ 64` 理解会严重放宽;调 `TRACK_START_THRESHOLD` 时需注意这一层。
|
- 起批判据对马氏距离平方再次平方(`d*d ≤ TRACK_START_THRESHOLD²`),实际门限为 `d ≤ 8`,按字面 `d² ≤ 64` 理解会严重放宽;调 `TRACK_START_THRESHOLD` 时需注意这一层。
|
||||||
- 折角计算 `acos` 无定义域钳位,浮点越界产生 NaN 时条件恒假(静默丢弃该关联)。
|
- 折角计算 `acos` 无定义域钳位,浮点越界产生 NaN 时条件恒假(静默丢弃该关联)。
|
||||||
- 起批输出数组行号可能越过容量:容量判据用 `trust_track->size() < MAX_TRACK_INDEX`,而输出行计数在 track_asso 阶段(track_die 删除航迹之前)已推进,极端场景(当圈消亡 ≥ 2 条且起批占满配额)可写到 `MAX_TRACK_NUM` 之外。
|
- 起批输出数组行号可能越过容量:容量判据用 `trust_track->size() < MAX_TRACK_INDEX`,而输出行计数在 track_asso 阶段(track_die 删除航迹之前)已推进,极端场景(当圈消亡 ≥ 2 条且起批占满配额)可写到 `MAX_TRACK_NUM` 之外。
|
||||||
- 起批输出有多个字段未赋值(见 9.3(3) 与 docs/track_init_readme.md 第 14 节),宿主不应依赖这些字段。
|
- 起批输出有多个字段未赋值(见 9.3(4) 与 docs/track_init_readme.md 第 14 节),宿主不应依赖这些字段。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -861,7 +885,8 @@ $$
|
|||||||
|
|
||||||
| 提交 | 内容 |
|
| 提交 | 内容 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| f249fdc | 输出航迹新增「靠近/远离」方向标志:`track_asso.cpp`(TWS)与 `track_asso_tas.cpp`(TAS)在写入 `vr_point` 后补 `Flag_Direction = vr_point > 0 ? 1 : 0`;新增 `docs/data_process_flow_report.md`、`docs/data_process_flow_report.html`、`docs/track_init_readme.md` 三份流程与专项文档 |
|
| e0bf227 | 关联判定重构并加强:TWS `track_asso.cpp` 新增按航迹距离分段的高度门限(原高度门限代码块为注释状态)、统计距离/高度/距离三类判据拆为 `thd_d`/`thd_h`/`thd_r` 布尔量;`parameters.h` 的 `ASSO_THORD` 由 3 调大至 4(等效门限 d < 4,提高机动目标关联概率);TAS `track_asso_tas.cpp` 高度门限 2000~3000 m 段由 200 m 放宽至 250 m;修复 `tas_beam_output()` 的数据率门控条件(去掉与「取最早 CPI 目标」冲突的 T_track 判据);删除 `docs/data_process_flow_report.html`;`.gitignore` 增加 `design_docs/`;同步更新 README/CHANGELOG/docs |
|
||||||
|
| f249fdc | 输出航迹新增「靠近/远离」方向标志:`track_asso.cpp`(TWS)与 `track_asso_tas.cpp`(TAS)在写入 `vr_point` 后补 `Flag_Direction = vr_point > 0 ? 1 : 0`;新增 `docs/data_process_flow_report.md`、`docs/data_process_flow_report.html`、`docs/track_init_readme.md` 三份流程与专项文档(其中 HTML 版已于 e0bf227 删除) |
|
||||||
| 7d5a56f | 满圈判据由「波位号变小」改为「方位波位号 == 0」(避免机扫转台反转误判,`data_process.cpp`);点-航迹头关联改为统一速度区间 `V_MIN·ΔT ≤ dis ≤ V_MAX·ΔT` 并新增 `dis ≥ |vr_point|·ΔT`、`dis ≥ |v_track_head|·ΔT` 两条多普勒-几何一致性约束,限制切向高速短航迹(`track_init.cpp`);同步更新 README/CHANGELOG |
|
| 7d5a56f | 满圈判据由「波位号变小」改为「方位波位号 == 0」(避免机扫转台反转误判,`data_process.cpp`);点-航迹头关联改为统一速度区间 `V_MIN·ΔT ≤ dis ≤ V_MAX·ΔT` 并新增 `dis ≥ |vr_point|·ΔT`、`dis ≥ |v_track_head|·ΔT` 两条多普勒-几何一致性约束,限制切向高速短航迹(`track_init.cpp`);同步更新 README/CHANGELOG |
|
||||||
| 604f158 | TWS 关联中 ΔT≤0(点迹时间戳不晚于航迹时间)的候选不再剔除:仍参与最近邻选取但不更新 IMM/EKF、不刷新航迹时间与新鲜度,并标记该点迹已使用(`Use_Flag=1`)消费掉,避免其继续参与航迹起始生成虚假 TWS 航迹;`track_asso.cpp` 的 ΔT≤0 告警日志注释停用;过期文档(BUG_REPORT.md、BUG_FIX_REPORT.md、requirements.md)移入 archived_docs/ 留档 |
|
| 604f158 | TWS 关联中 ΔT≤0(点迹时间戳不晚于航迹时间)的候选不再剔除:仍参与最近邻选取但不更新 IMM/EKF、不刷新航迹时间与新鲜度,并标记该点迹已使用(`Use_Flag=1`)消费掉,避免其继续参与航迹起始生成虚假 TWS 航迹;`track_asso.cpp` 的 ΔT≤0 告警日志注释停用;过期文档(BUG_REPORT.md、BUG_FIX_REPORT.md、requirements.md)移入 archived_docs/ 留档 |
|
||||||
| d6cdbc0 | 删除 `data_process.cpp`、`dot_coh.cpp` 中已注释停用的调试输出与早期 1 km SNR 过滤代码残留(不改变运行逻辑);同步更新 README/CHANGELOG |
|
| d6cdbc0 | 删除 `data_process.cpp`、`dot_coh.cpp` 中已注释停用的调试输出与早期 1 km SNR 过滤代码残留(不改变运行逻辑);同步更新 README/CHANGELOG |
|
||||||
@@ -894,8 +919,7 @@ $$
|
|||||||
| 文档 | 内容 |
|
| 文档 | 内容 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| CHANGELOG.md | 变更日志(Keep a Changelog 格式,按 git 提交记录维护) |
|
| CHANGELOG.md | 变更日志(Keep a Changelog 格式,按 git 提交记录维护) |
|
||||||
| docs/data_process_flow_report.md | 数据处理流程与关键逻辑说明(按当前源码整理:前处理与判圈、凝聚、TWS/TAS 关联与滤波、航迹起始、外推消亡、TAS 波束控制、参数脉络;含与本文档的历史差异提示) |
|
| docs/data_process_flow_report.md | 数据处理流程与关键逻辑说明(按当前源码整理:前处理与判圈、凝聚、TWS/TAS 关联与滤波、航迹起始、外推消亡、TAS 波束控制、参数脉络;含与本文档的历史差异提示)——原同内容 HTML 渲染版(`data_process_flow_report.html`)已于 e0bf227 删除,HTML 版本在 git 忽略的 `design_docs/` 内留档 |
|
||||||
| docs/data_process_flow_report.html | 上文同内容的 HTML 渲染版 |
|
|
||||||
| docs/track_init_readme.md | 航迹起始(Track Init)专项说明:分阶段流程、起始条件汇总、调参直觉、输出字段映射(含未赋值字段)、已知风险与代码索引 |
|
| docs/track_init_readme.md | 航迹起始(Track Init)专项说明:分阶段流程、起始条件汇总、调参直觉、输出字段映射(含未赋值字段)、已知风险与代码索引 |
|
||||||
| archived_docs/BUG_REPORT.md | 全量逻辑 BUG 分析(P0~P3 共 37 项,含位置、说明、建议、处置结论)——过期留档,仅作历史参考 |
|
| archived_docs/BUG_REPORT.md | 全量逻辑 BUG 分析(P0~P3 共 37 项,含位置、说明、建议、处置结论)——过期留档,仅作历史参考 |
|
||||||
| archived_docs/BUG_FIX_REPORT.md | 修复明细、修复状态汇总表与 MSVC 2013 x86 编译验证记录——过期留档(对应 01d28e0 时期) |
|
| archived_docs/BUG_FIX_REPORT.md | 修复明细、修复状态汇总表与 MSVC 2013 x86 编译验证记录——过期留档(对应 01d28e0 时期) |
|
||||||
|
|||||||
@@ -264,15 +264,49 @@ int Data_Process:: track_delete(int delete_track_num, //手动
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//手动添加重点目标
|
||||||
|
int Data_Process::primary_target_add(int track_index)
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( size_t i=0; i<trust_track.size();i++){
|
||||||
|
if(trust_track[i].Track_Index==track_index)
|
||||||
|
{
|
||||||
|
trust_track[i].primary_target_flag = 1;
|
||||||
|
//std::cout<< "Add primary target :" << trust_track[i].Track_Index << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//手动取消重点目标
|
||||||
|
int Data_Process::primary_target_cancel(int track_index)
|
||||||
|
{
|
||||||
|
|
||||||
|
for ( size_t i=0; i<trust_track.size();i++){
|
||||||
|
if(trust_track[i].Track_Index==track_index)
|
||||||
|
{
|
||||||
|
trust_track[i].primary_target_flag = 0;
|
||||||
|
//std::cout<< "Cancel primary target :" << trust_track[i].Track_Index << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//手动转TAS跟踪函数
|
//手动转TAS跟踪函数
|
||||||
int Data_Process:: tracking_start(int track_index) //需要手动转入TAS跟踪的航迹号
|
int Data_Process:: tracking_start(int track_index) //需要手动转入TAS跟踪的航迹号
|
||||||
{
|
{
|
||||||
|
|
||||||
for ( size_t i=0; i<trust_track.size();i++)
|
for ( size_t i=0; i<trust_track.size();i++){
|
||||||
if(trust_track[i].Track_Index==track_index)
|
if(trust_track[i].Track_Index==track_index)
|
||||||
{
|
{
|
||||||
trust_track[i].manual_tracking_flag = 1;
|
trust_track[i].manual_tracking_flag = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -286,6 +320,7 @@ int Data_Process:: tracking_stop(int track_index) //需要手动转
|
|||||||
{
|
{
|
||||||
trust_track[i].manual_tracking_flag = 0;
|
trust_track[i].manual_tracking_flag = 0;
|
||||||
trust_track[i].Track_Mode = 0;
|
trust_track[i].Track_Mode = 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,12 @@ public:
|
|||||||
//手动取消TAS跟踪函数
|
//手动取消TAS跟踪函数
|
||||||
int tracking_stop(int track_index); //需要取消TAS跟踪的航迹号
|
int tracking_stop(int track_index); //需要取消TAS跟踪的航迹号
|
||||||
|
|
||||||
|
//手动添加重点目标
|
||||||
|
int primary_target_add(int track_index); //将指定目标转为重点目标
|
||||||
|
|
||||||
|
//手动取消重点目标
|
||||||
|
int primary_target_cancel(int track_index); //将指定重点目标取消
|
||||||
|
|
||||||
//手动打跟踪波束
|
//手动打跟踪波束
|
||||||
int tracking_point(float Azimuth); //方位角
|
int tracking_point(float Azimuth); //方位角
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ struct DATA_PROCESS_CLASS_DLLSHARED_EXPORT DataRev
|
|||||||
int Point_Num; //点迹号(1,2,3,4...)
|
int Point_Num; //点迹号(1,2,3,4...)
|
||||||
int UseFlag; //点迹使用标记 使用1/未使用0 主程序存入数据时置为0
|
int UseFlag; //点迹使用标记 使用1/未使用0 主程序存入数据时置为0
|
||||||
int TAS_track_index; //TAS的航迹号
|
int TAS_track_index; //TAS的航迹号
|
||||||
int point_type; //点迹类型 TAS 1/TWS 0
|
int point_type; //点迹类型 TAS 1/TWS 0
|
||||||
int pitch_num; // 俯仰波位号
|
int pitch_num; // 俯仰波位号
|
||||||
|
float amp_asv; //目标归一化幅度(dB)
|
||||||
|
float prn_fftn; //速度维FFT点数
|
||||||
float speed_dim[129]; // 目标的十字星数据,目标点速度维129个点
|
float speed_dim[129]; // 目标的十字星数据,目标点速度维129个点
|
||||||
float range_dim[8]; // 目标的十字星数据,目标点距离维8个点
|
float range_dim[8]; // 目标的十字星数据,目标点距离维8个点
|
||||||
};
|
};
|
||||||
@@ -69,6 +71,8 @@ struct DATA_PROCESS_CLASS_DLLSHARED_EXPORT Track
|
|||||||
float elev_point;
|
float elev_point;
|
||||||
float vr_point;
|
float vr_point;
|
||||||
float prf_point;
|
float prf_point;
|
||||||
|
float amp_asv_point; //关联上的点迹信息(归一化幅度)
|
||||||
|
float prn_fftn_point; //点迹速度维FFT点数
|
||||||
|
|
||||||
float track_time; //航迹时间 (单位 s)
|
float track_time; //航迹时间 (单位 s)
|
||||||
float track_snr; //信噪比
|
float track_snr; //信噪比
|
||||||
@@ -236,6 +240,18 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//手动添加重点目标
|
||||||
|
virtual int primary_target_add(int track_index) //将指定目标转为重点目标
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//手动取消重点目标
|
||||||
|
virtual int primary_target_cancel(int track_index) //将指定重点目标取消
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//手动打跟踪波束
|
//手动打跟踪波束
|
||||||
virtual int tracking_point(float Azimuth) //方位角(当前接口未启用,保留空实现)
|
virtual int tracking_point(float Azimuth) //方位角(当前接口未启用,保留空实现)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -49,10 +49,14 @@
|
|||||||
#define TRACK_START_THRESHOLD 8 //起航波门 3 越大越容易起批
|
#define TRACK_START_THRESHOLD 8 //起航波门 3 越大越容易起批
|
||||||
#define ALPHA_START 60 //起航夹角 120 越大越容易起批
|
#define ALPHA_START 60 //起航夹角 120 越大越容易起批
|
||||||
|
|
||||||
#define TRACK_DIE_ROUND 4 // 航迹消亡时间
|
#define MAX_EXTRAPOLATE_NUM 3 //最大外推点数
|
||||||
#define TRACK_DIE_ROUND_TAS 96 //
|
#define MAX_EXTRAPOLATE_NUM_TAS 48 //TAS最大外推点数
|
||||||
|
|
||||||
#define ASSO_THORD 3
|
#define TRACK_DIE_ROUND 6 // 航迹消亡圈数
|
||||||
|
#define TRACK_DIE_ROUND_PRIMARY 10 // 重点航迹消亡圈数
|
||||||
|
#define TRACK_DIE_ROUND_TAS 96 //TAS航迹消亡圈数
|
||||||
|
|
||||||
|
#define ASSO_THORD 4
|
||||||
|
|
||||||
#define H_F_WIN_LEN 3
|
#define H_F_WIN_LEN 3
|
||||||
|
|
||||||
@@ -98,10 +102,14 @@
|
|||||||
#define TRACK_START_THRESHOLD 8 //起航波门 3 越大越容易起批
|
#define TRACK_START_THRESHOLD 8 //起航波门 3 越大越容易起批
|
||||||
#define ALPHA_START 60 //起航夹角 120 越大越容易起批
|
#define ALPHA_START 60 //起航夹角 120 越大越容易起批
|
||||||
|
|
||||||
#define TRACK_DIE_ROUND 4 // 航迹消亡时间
|
#define MAX_EXTRAPOLATE_NUM 3 //最大外推点数
|
||||||
#define TRACK_DIE_ROUND_TAS 5
|
#define MAX_EXTRAPOLATE_NUM_TAS 5 //TAS最大外推点数
|
||||||
|
|
||||||
#define ASSO_THORD 3
|
#define TRACK_DIE_ROUND 6 // 航迹消亡圈数
|
||||||
|
#define TRACK_DIE_ROUND_PRIMARY 10 // 重点航迹消亡圈数
|
||||||
|
#define TRACK_DIE_ROUND_TAS 10 //TAS航迹消亡圈数
|
||||||
|
|
||||||
|
#define ASSO_THORD 4
|
||||||
|
|
||||||
#define H_F_WIN_LEN 3
|
#define H_F_WIN_LEN 3
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ struct PointRecv
|
|||||||
double Height; //高度
|
double Height; //高度
|
||||||
double snr; //信噪比
|
double snr; //信噪比
|
||||||
double RCS; //目标RCS
|
double RCS; //目标RCS
|
||||||
|
float amp_asv_point; //归一化幅度dB
|
||||||
|
float prn_fftn_point; //点迹速度维FFT点数
|
||||||
long long CPI_Time; //CPI时间
|
long long CPI_Time; //CPI时间
|
||||||
long long GNSS_time; //GNSS时间
|
long long GNSS_time; //GNSS时间
|
||||||
int Point_index; //点迹号 1~50
|
int Point_index; //点迹号 1~50
|
||||||
@@ -57,6 +59,8 @@ struct Trust_Track
|
|||||||
int manual_tracking_flag; //手动TAS
|
int manual_tracking_flag; //手动TAS
|
||||||
int associate_point_number; //关联的点数
|
int associate_point_number; //关联的点数
|
||||||
|
|
||||||
|
int primary_target_flag; //重点目标标记
|
||||||
|
|
||||||
int Target_Type; //目标类型 搜索目标 低空目标 地面目标
|
int Target_Type; //目标类型 搜索目标 低空目标 地面目标
|
||||||
|
|
||||||
int Track_section_idx; //航迹区号
|
int Track_section_idx; //航迹区号
|
||||||
@@ -70,6 +74,8 @@ struct Trust_Track
|
|||||||
double prf_point;
|
double prf_point;
|
||||||
int point_type; //TWS TAS
|
int point_type; //TWS TAS
|
||||||
double snr_point; //信噪比
|
double snr_point; //信噪比
|
||||||
|
float amp_asv_point; //关联上的点迹信息(归一化幅度)
|
||||||
|
float prn_fftn_point; //点迹速度维FFT点数
|
||||||
|
|
||||||
double RCS;
|
double RCS;
|
||||||
|
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ void TAS_Ctrl::tas_beam_output(std::vector<Trust_Track> *trust_track
|
|||||||
long long CPI_time = 0;
|
long long CPI_time = 0;
|
||||||
long long earliest_CPI_time = LLONG_MAX;
|
long long earliest_CPI_time = LLONG_MAX;
|
||||||
float delta_T = 0;
|
float delta_T = 0;
|
||||||
|
float delta_T_last_track = 0;
|
||||||
double H_track = 0;
|
double H_track = 0;
|
||||||
int earliest_track_idx=-1;
|
int earliest_track_idx=-1;
|
||||||
int earliest_tas_queue_idx=-1;
|
int earliest_tas_queue_idx=-1;
|
||||||
@@ -281,13 +282,14 @@ void TAS_Ctrl::tas_beam_output(std::vector<Trust_Track> *trust_track
|
|||||||
if((*trust_track)[track_idx].Track_Index == tas_target_queue[tas_idx].Index)
|
if((*trust_track)[track_idx].Track_Index == tas_target_queue[tas_idx].Index)
|
||||||
{
|
{
|
||||||
CPI_time = (*trust_track)[track_idx].T_track;
|
CPI_time = (*trust_track)[track_idx].T_track;
|
||||||
delta_T = (latest_timestamp - CPI_time) / 1000.0f;
|
delta_T_last_track = (latest_timestamp - tas_target_queue[tas_idx].last_track_time) / 1000.0f;
|
||||||
|
|
||||||
//查找最早的CPI时间, 航迹时间与当前最新时间戳的差值大于 DATA_RATE_TAS 时才输出TAS跟踪波束
|
//查找CPI时间最早,且满足TAS数据率的目标
|
||||||
if(CPI_time < earliest_CPI_time && (latest_timestamp - tas_target_queue[tas_idx].last_track_time) / 1000.0f > Work_Parameter.DATA_RATE_TAS && delta_T > Work_Parameter.DATA_RATE_TAS)
|
if(CPI_time < earliest_CPI_time && (delta_T_last_track > Work_Parameter.DATA_RATE_TAS))
|
||||||
{
|
{
|
||||||
earliest_CPI_time = CPI_time;
|
earliest_CPI_time = CPI_time;
|
||||||
H_track = (*trust_track)[track_idx].Height;
|
H_track = (*trust_track)[track_idx].Height;
|
||||||
|
delta_T = (latest_timestamp - CPI_time) / 1000.0f;
|
||||||
|
|
||||||
earliest_track_idx = track_idx;
|
earliest_track_idx = track_idx;
|
||||||
earliest_tas_queue_idx = tas_idx;
|
earliest_tas_queue_idx = tas_idx;
|
||||||
@@ -295,7 +297,6 @@ void TAS_Ctrl::tas_beam_output(std::vector<Trust_Track> *trust_track
|
|||||||
for(int ii=0;ii<6;ii++){
|
for(int ii=0;ii<6;ii++){
|
||||||
X_now[ii]=(*trust_track)[track_idx].X[ii];
|
X_now[ii]=(*trust_track)[track_idx].X[ii];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -65,9 +65,8 @@ int Track_Asso:: track_asso_process(std::vector<PointRecv> *point_
|
|||||||
//输出航迹
|
//输出航迹
|
||||||
for (size_t i=0;i<trust_track->size();i++)
|
for (size_t i=0;i<trust_track->size();i++)
|
||||||
{ // 输出更新航迹条件:
|
{ // 输出更新航迹条件:
|
||||||
// if((*trust_track)[i].manual_tracking_flag==0)
|
if((*trust_track)[i].Track_Update_Flag==1){
|
||||||
// {
|
(*trust_track)[i].Track_Update_Flag=0;
|
||||||
|
|
||||||
*Trust_track_num_Output= *Trust_track_num_Output+1;
|
*Trust_track_num_Output= *Trust_track_num_Output+1;
|
||||||
|
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].Point_Sum=1;
|
Trust_Track_Output[*Trust_track_num_Output-1][0].Point_Sum=1;
|
||||||
@@ -110,7 +109,8 @@ int Track_Asso:: track_asso_process(std::vector<PointRecv> *point_
|
|||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].point_type=0;
|
Trust_Track_Output[*Trust_track_num_Output-1][0].point_type=0;
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].prf_point = static_cast<float>((*trust_track)[i].prf_point);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].prf_point = static_cast<float>((*trust_track)[i].prf_point);
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].track_snr = static_cast<float>((*trust_track)[i].snr_point);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].track_snr = static_cast<float>((*trust_track)[i].snr_point);
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=Trust_Track_Output[*Trust_track_num_Output-1][0].vr_point>0?1:0;
|
Trust_Track_Output[*Trust_track_num_Output-1][0].amp_asv_point = static_cast<float>((*trust_track)[i].amp_asv_point);
|
||||||
|
Trust_Track_Output[*Trust_track_num_Output-1][0].prn_fftn_point = static_cast<float>((*trust_track)[i].prn_fftn_point);
|
||||||
|
|
||||||
//直接输出点迹高度-20260605
|
//直接输出点迹高度-20260605
|
||||||
//Trust_Track_Output[*Trust_track_num_Output-1][0].z = (*trust_track)[i].range_point * sin((*trust_track)[i].elev_point/180.0*PI);
|
//Trust_Track_Output[*Trust_track_num_Output-1][0].z = (*trust_track)[i].range_point * sin((*trust_track)[i].elev_point/180.0*PI);
|
||||||
@@ -124,12 +124,32 @@ int Track_Asso:: track_asso_process(std::vector<PointRecv> *point_
|
|||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].v_x=static_cast<float>((*trust_track)[i].X[1]);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].v_x=static_cast<float>((*trust_track)[i].X[1]);
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].v_y=static_cast<float>((*trust_track)[i].X[4]);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].v_y=static_cast<float>((*trust_track)[i].X[4]);
|
||||||
|
|
||||||
|
// Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=Trust_Track_Output[*Trust_track_num_Output-1][0].vr_point>0?1:0;
|
||||||
|
|
||||||
|
if(acos((-x * cos(Direction_Angle) - y * sin(Direction_Angle)) / r ) < PI / 2)
|
||||||
|
{
|
||||||
|
Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=1;
|
||||||
|
// if(r*abs(sin(azi - Direction_Angle))<500)
|
||||||
|
// {
|
||||||
|
// Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=1;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=0;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].track_rcs = static_cast<float>((*trust_track)[i].RCS);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].track_rcs = static_cast<float>((*trust_track)[i].RCS);
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].pitch_num = (*trust_track)[i].pitch_num;
|
Trust_Track_Output[*Trust_track_num_Output-1][0].pitch_num = (*trust_track)[i].pitch_num;
|
||||||
|
|
||||||
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim, (*trust_track)[i].speed_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim));
|
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim, (*trust_track)[i].speed_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim));
|
||||||
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim, (*trust_track)[i].range_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim));
|
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim, (*trust_track)[i].range_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim));
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -417,157 +437,108 @@ void Track_Asso:: model_filter(std::vector <Trust_Track> *trust_track,struct Ra
|
|||||||
//遍历所有点迹航迹 计算点迹和航迹的统计距离
|
//遍历所有点迹航迹 计算点迹和航迹的统计距离
|
||||||
for (size_t loop_of_track = 0; loop_of_track<trust_track->size();loop_of_track++)
|
for (size_t loop_of_track = 0; loop_of_track<trust_track->size();loop_of_track++)
|
||||||
{
|
{
|
||||||
// if((*trust_track)[loop_of_track].manual_tracking_flag==0)
|
(*trust_track)[loop_of_track].point_flag = 0; //航迹的point_flag置为0 关联上点后再置为1
|
||||||
// {
|
|
||||||
(*trust_track)[loop_of_track].point_flag = 0; //航迹的point_flag置为0 关联上点后再置为1
|
|
||||||
|
|
||||||
for (size_t loop_of_point = 0; loop_of_point<point_process.size();loop_of_point++)
|
for (size_t loop_of_point = 0; loop_of_point<point_process.size();loop_of_point++)
|
||||||
{
|
{
|
||||||
|
|
||||||
//时间差
|
//时间差
|
||||||
double delta_T = (point_process[loop_of_point].CPI_Time - (*trust_track)[loop_of_track].T_track)/1000.0;
|
double delta_T = (point_process[loop_of_point].CPI_Time - (*trust_track)[loop_of_track].T_track)/1000.0;
|
||||||
//航迹X P
|
//航迹X P
|
||||||
double X1[6],X2[6],X3[6],P1[6][6],P2[6][6],P3[6][6];
|
double X1[6],X2[6],X3[6],P1[6][6],P2[6][6],P3[6][6];
|
||||||
memcpy(X1,(*trust_track)[loop_of_track].X1,6*sizeof(double));
|
memcpy(X1,(*trust_track)[loop_of_track].X1,6*sizeof(double));
|
||||||
memcpy(X2,(*trust_track)[loop_of_track].X2,6*sizeof(double));
|
memcpy(X2,(*trust_track)[loop_of_track].X2,6*sizeof(double));
|
||||||
memcpy(X3,(*trust_track)[loop_of_track].X3,6*sizeof(double));
|
memcpy(X3,(*trust_track)[loop_of_track].X3,6*sizeof(double));
|
||||||
memcpy(P1,(*trust_track)[loop_of_track].P1,6*6*sizeof(double));
|
memcpy(P1,(*trust_track)[loop_of_track].P1,6*6*sizeof(double));
|
||||||
memcpy(P2,(*trust_track)[loop_of_track].P2,6*6*sizeof(double));
|
memcpy(P2,(*trust_track)[loop_of_track].P2,6*6*sizeof(double));
|
||||||
memcpy(P3,(*trust_track)[loop_of_track].P3,6*6*sizeof(double));
|
memcpy(P3,(*trust_track)[loop_of_track].P3,6*6*sizeof(double));
|
||||||
double v_track = sqrt(pow((*trust_track)[loop_of_track].X[1],2)+pow((*trust_track)[loop_of_track].X[4],2));
|
double v_track = sqrt(pow((*trust_track)[loop_of_track].X[1],2)+pow((*trust_track)[loop_of_track].X[4],2));
|
||||||
double h_track = (*trust_track)[loop_of_track].Height;
|
double h_track = (*trust_track)[loop_of_track].Height;
|
||||||
double r_track = sqrt(pow((*trust_track)[loop_of_track].X[0],2)+pow((*trust_track)[loop_of_track].X[3],2));
|
double r_track = sqrt(pow((*trust_track)[loop_of_track].X[0],2)+pow((*trust_track)[loop_of_track].X[3],2));
|
||||||
|
|
||||||
//量测信息
|
//量测信息
|
||||||
double Z[3] = {point_process[loop_of_point].Range,
|
double Z[3] = {point_process[loop_of_point].Range,
|
||||||
point_process[loop_of_point].Azimuth,
|
point_process[loop_of_point].Azimuth,
|
||||||
point_process[loop_of_point].Velocity};
|
point_process[loop_of_point].Velocity};
|
||||||
double prt = point_process[loop_of_point].PRF_index;
|
double prt = point_process[loop_of_point].PRF_index;
|
||||||
double freq_ind = point_process[loop_of_point].Freq_index;
|
double freq_ind = point_process[loop_of_point].Freq_index;
|
||||||
double h_point = point_process[loop_of_point].Height;
|
double h_point = point_process[loop_of_point].Height;
|
||||||
|
|
||||||
//计算统计距离d
|
//计算统计距离d
|
||||||
double d1,d2,d3;
|
double d1,d2,d3;
|
||||||
IMM_d_cal(v_track,X1,P1,X2,P2, X3,P3,Z,prt,freq_ind,delta_T,&d1,&d2,&d3,Work_Parameter);
|
IMM_d_cal(v_track,X1,P1,X2,P2, X3,P3,Z,prt,freq_ind,delta_T,&d1,&d2,&d3,Work_Parameter);
|
||||||
|
|
||||||
//计算高度门限
|
//判定统计距离门限,thd_d
|
||||||
// double d_h;
|
bool thd_d = false;
|
||||||
// if (r_track<1000)
|
|
||||||
// {
|
|
||||||
// if(abs(h_track-h_point)<=150)
|
|
||||||
// {
|
|
||||||
// d_h = 1;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// d_h = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
if( (r_track <= 500 && \
|
||||||
// else if (r_track<2000 && r_track>=1000)
|
(d1*d1 < ASSO_THORD*ASSO_THORD || d2*d2 < ASSO_THORD*ASSO_THORD || d3*d3 < ASSO_THORD*ASSO_THORD / 1000.0)) || \
|
||||||
// {
|
((r_track > 500 && r_track < 1000) && \
|
||||||
// if(abs(h_track-h_point)<=200)
|
(d1*d1 < ASSO_THORD*ASSO_THORD || d2*d2 < ASSO_THORD*ASSO_THORD || d3*d3 < ASSO_THORD*ASSO_THORD / 100.0)) || \
|
||||||
// {
|
(r_track >= 1000 && \
|
||||||
// d_h = 1;
|
(d1*d1 < ASSO_THORD*ASSO_THORD || d2*d2 < ASSO_THORD*ASSO_THORD || d3*d3 < ASSO_THORD*ASSO_THORD))\
|
||||||
// }
|
){
|
||||||
// else
|
thd_d = true;
|
||||||
// {
|
|
||||||
// d_h = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// else if(r_track>=2000 && r_track<3000 )
|
|
||||||
// {
|
|
||||||
// if(abs(h_track-h_point)<=200)
|
|
||||||
// {
|
|
||||||
// d_h = 1;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// d_h = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else if(r_track>=3000 && r_track<5000)
|
|
||||||
// {
|
|
||||||
// if(abs(h_track-h_point)<=300)
|
|
||||||
// {
|
|
||||||
// d_h = 1;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// d_h = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// d_h = 1;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// std::cout << delta_T<<" "<<d1<<" "<<d2<<" "<<d3;
|
|
||||||
// std::cout << h_track<<" "<<h_point<<" "<<d_h;
|
|
||||||
// d_h = 1;
|
|
||||||
|
|
||||||
//计算俯仰门限
|
|
||||||
bool d_p = true;
|
|
||||||
|
|
||||||
// double p_track = atan2(h_track, r_track); //航迹俯仰
|
|
||||||
// double p_point = asin(h_point/point_process[loop_of_point].Range); //点迹俯仰
|
|
||||||
|
|
||||||
// if( (r_track > 3000 && abs(p_track - p_point)*180/PI <= 7) || \
|
|
||||||
// (r_track > 1000 && r_track <= 3000 && abs(p_track - p_point)*180/PI <= 5) || \
|
|
||||||
// (r_track <= 1000 && abs(p_track - p_point)*180/PI <= 10)){
|
|
||||||
// d_p = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
//计算距离门限,R=航迹点与量测点的距离,VT=航向速度乘以扫描时间差
|
|
||||||
double& t_x0 = (*trust_track)[loop_of_track].X[0];
|
|
||||||
double& t_y0 = (*trust_track)[loop_of_track].X[3];
|
|
||||||
double a_track = atan2(t_y0, t_x0); //航迹方位角
|
|
||||||
double& r_point = point_process[loop_of_point].Range; //点迹距离
|
|
||||||
double a_delta = abs(a_track - point_process[loop_of_point].Azimuth); //方位差
|
|
||||||
if(a_delta > PI){
|
|
||||||
a_delta = 2*PI - a_delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
double R = sqrt(r_track * r_track + r_point*r_point - 2*r_track*r_point*cos(a_delta));
|
|
||||||
double VT = v_track*delta_T;
|
|
||||||
|
|
||||||
bool d_r = true;
|
|
||||||
|
|
||||||
if(VT < 100 && R > 300){
|
|
||||||
//VT<100m,使用固定门限300m
|
|
||||||
d_r = false;
|
|
||||||
}else if((VT>=100 && VT<=300 && R/VT>3)){
|
|
||||||
d_r = false;
|
|
||||||
}else if(VT>300 && R > 1200){
|
|
||||||
d_r = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//小于关联门限 保存关联信息
|
|
||||||
if(
|
|
||||||
( r_track<=500 && (d1*d1<ASSO_THORD*ASSO_THORD || d2*d2<ASSO_THORD*ASSO_THORD || d3*d3<ASSO_THORD*ASSO_THORD/1000.0) && d_p && d_r)//
|
|
||||||
||( (r_track>500&&r_track<1000) && (d1*d1<ASSO_THORD*ASSO_THORD || d2*d2<ASSO_THORD*ASSO_THORD || d3*d3<ASSO_THORD*ASSO_THORD/100.0) && d_p && d_r)//
|
|
||||||
||( r_track>=1000 && (d1*d1<ASSO_THORD*ASSO_THORD || d2*d2<ASSO_THORD*ASSO_THORD || d3*d3<ASSO_THORD*ASSO_THORD) && d_p && d_r)//
|
|
||||||
)
|
|
||||||
{
|
|
||||||
//std::cout << "asooooooooooo";
|
|
||||||
|
|
||||||
struct asso_info associated_info_tmp;
|
|
||||||
associated_info_tmp.d1=d1;
|
|
||||||
associated_info_tmp.d2=d2;
|
|
||||||
associated_info_tmp.d3=d3;
|
|
||||||
associated_info_tmp.point_index=static_cast<int>(loop_of_point)+1;
|
|
||||||
associated_info_tmp.track_index=static_cast<int>(loop_of_track)+1;
|
|
||||||
if(d1<=d2&&d1<=d3)
|
|
||||||
associated_info_tmp.d_min=d1;
|
|
||||||
else if(d2<=d1&& d2<=d3)
|
|
||||||
associated_info_tmp.d_min=d2;
|
|
||||||
else
|
|
||||||
associated_info_tmp.d_min=d3;
|
|
||||||
|
|
||||||
associated_info.push_back(associated_info_tmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//判定高度门限,thd_h
|
||||||
|
bool thd_h = false;
|
||||||
|
double delta_h = abs(h_track-h_point);
|
||||||
|
|
||||||
|
if( (r_track <= 1000 && delta_h <= 150) || \
|
||||||
|
((r_track > 1000 && r_track <= 2000) && delta_h <= 200) || \
|
||||||
|
((r_track > 2000 && r_track <= 3000) && delta_h <= 250) || \
|
||||||
|
((r_track > 3000 && r_track <= 5000) && delta_h <= 300) || \
|
||||||
|
r_track > 5000
|
||||||
|
){
|
||||||
|
thd_h = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//判定距离门限,R=航迹点与量测点的距离,VT=航向速度乘以扫描时间差
|
||||||
|
double& t_x0 = (*trust_track)[loop_of_track].X[0];
|
||||||
|
double& t_y0 = (*trust_track)[loop_of_track].X[3];
|
||||||
|
double a_track = atan2(t_y0, t_x0); //航迹方位角
|
||||||
|
double& r_point = point_process[loop_of_point].Range; //点迹距离
|
||||||
|
double a_delta = abs(a_track - point_process[loop_of_point].Azimuth); //方位差
|
||||||
|
if(a_delta > PI){
|
||||||
|
a_delta = 2*PI - a_delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
double R = sqrt(r_track * r_track + r_point*r_point - 2*r_track*r_point*cos(a_delta));
|
||||||
|
double VT = v_track*delta_T;
|
||||||
|
|
||||||
|
bool thd_r = true;
|
||||||
|
|
||||||
|
if(VT < 100 && R > 300){
|
||||||
|
//VT<100m,使用固定门限300m
|
||||||
|
thd_r = false;
|
||||||
|
}else if((VT>=100 && VT<=300 && R/VT>3)){
|
||||||
|
thd_r = false;
|
||||||
|
}else if(VT>300 && R > 1200){
|
||||||
|
thd_r = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//小于关联门限 保存关联信息
|
||||||
|
if(thd_d && thd_h && thd_r)
|
||||||
|
{
|
||||||
|
//std::cout << "asooooooooooo";
|
||||||
|
|
||||||
|
struct asso_info associated_info_tmp;
|
||||||
|
associated_info_tmp.d1=d1;
|
||||||
|
associated_info_tmp.d2=d2;
|
||||||
|
associated_info_tmp.d3=d3;
|
||||||
|
associated_info_tmp.point_index=static_cast<int>(loop_of_point)+1;
|
||||||
|
associated_info_tmp.track_index=static_cast<int>(loop_of_track)+1;
|
||||||
|
if(d1<=d2&&d1<=d3)
|
||||||
|
associated_info_tmp.d_min=d1;
|
||||||
|
else if(d2<=d1&& d2<=d3)
|
||||||
|
associated_info_tmp.d_min=d2;
|
||||||
|
else
|
||||||
|
associated_info_tmp.d_min=d3;
|
||||||
|
|
||||||
|
associated_info.push_back(associated_info_tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,6 +659,8 @@ void Track_Asso:: model_filter(std::vector <Trust_Track> *trust_track,struct Ra
|
|||||||
(*trust_track)[track_index-1].Amplitude= point_process[point_index-1].Amplitude; //幅度
|
(*trust_track)[track_index-1].Amplitude= point_process[point_index-1].Amplitude; //幅度
|
||||||
|
|
||||||
(*trust_track)[track_index-1].RCS = point_process[point_index-1].RCS;
|
(*trust_track)[track_index-1].RCS = point_process[point_index-1].RCS;
|
||||||
|
(*trust_track)[track_index-1].amp_asv_point = point_process[point_index-1].amp_asv_point;
|
||||||
|
(*trust_track)[track_index-1].prn_fftn_point = point_process[point_index-1].prn_fftn_point;
|
||||||
|
|
||||||
(*trust_track)[track_index-1].pitch_num = point_process[point_index-1].pitch_num;
|
(*trust_track)[track_index-1].pitch_num = point_process[point_index-1].pitch_num;
|
||||||
|
|
||||||
@@ -700,6 +673,7 @@ void Track_Asso:: model_filter(std::vector <Trust_Track> *trust_track,struct Ra
|
|||||||
(*trust_track)[track_index-1].Extrapolate_round = 0; //连续未用实点更新时间
|
(*trust_track)[track_index-1].Extrapolate_round = 0; //连续未用实点更新时间
|
||||||
(*trust_track)[track_index-1].point_flag=1; //实点
|
(*trust_track)[track_index-1].point_flag=1; //实点
|
||||||
(*trust_track)[track_index-1].associate_point_number = (*trust_track)[track_index-1].associate_point_number+1; //关联点数+1
|
(*trust_track)[track_index-1].associate_point_number = (*trust_track)[track_index-1].associate_point_number+1; //关联点数+1
|
||||||
|
(*trust_track)[track_index-1].Track_Update_Flag = 1; //航迹更新标志
|
||||||
}
|
}
|
||||||
|
|
||||||
//删除associated_info中关联上的航迹 点迹信息
|
//删除associated_info中关联上的航迹 点迹信息
|
||||||
@@ -734,57 +708,66 @@ void Track_Asso:: model_filter(std::vector <Trust_Track> *trust_track,struct Ra
|
|||||||
//未关联上的航迹 进行外推 tws
|
//未关联上的航迹 进行外推 tws
|
||||||
for (size_t i =0; i<(*trust_track).size();i++ )
|
for (size_t i =0; i<(*trust_track).size();i++ )
|
||||||
{
|
{
|
||||||
if((*trust_track)[i].point_flag == 0 && (*trust_track)[i].manual_tracking_flag == 0)
|
if((*trust_track)[i].point_flag == 0 && (*trust_track)[i].manual_tracking_flag == 0) //未关联上点迹的航迹进行外推
|
||||||
{
|
{
|
||||||
double v_track = sqrt(pow((*trust_track)[i].X[1],2)+pow((*trust_track)[i].X[4],2));
|
//外推点数未到上限,则继续外推,否则不外推
|
||||||
double delta_T;
|
if((*trust_track)[i].Extrapolate_round <= MAX_EXTRAPOLATE_NUM)
|
||||||
if(Work_Parameter.work_mode == 0)
|
|
||||||
{
|
|
||||||
delta_T = Work_Parameter.DATA_RATE_SHORT;
|
|
||||||
}
|
|
||||||
else if(Work_Parameter.work_mode == 1)
|
|
||||||
{
|
|
||||||
delta_T = Work_Parameter.DATA_RATE_MIDDLE;
|
|
||||||
}
|
|
||||||
else if(Work_Parameter.work_mode == 2)
|
|
||||||
{
|
|
||||||
delta_T = Work_Parameter.DATA_RATE_FAR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
double v_track = sqrt(pow((*trust_track)[i].X[1],2)+pow((*trust_track)[i].X[4],2));
|
||||||
|
double delta_T;
|
||||||
|
if(Work_Parameter.work_mode == 0)
|
||||||
|
{
|
||||||
delta_T = Work_Parameter.DATA_RATE_SHORT;
|
delta_T = Work_Parameter.DATA_RATE_SHORT;
|
||||||
|
}
|
||||||
|
else if(Work_Parameter.work_mode == 1)
|
||||||
|
{
|
||||||
|
delta_T = Work_Parameter.DATA_RATE_MIDDLE;
|
||||||
|
}
|
||||||
|
else if(Work_Parameter.work_mode == 2)
|
||||||
|
{
|
||||||
|
delta_T = Work_Parameter.DATA_RATE_FAR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delta_T = Work_Parameter.DATA_RATE_SHORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
double F[6][6], Q1[6][6], Q2[6][6], Q3[6][6];
|
||||||
|
IMM_F_Q_gen( v_track, delta_T, F, Q1, Q2, Q3,Work_Parameter);
|
||||||
|
|
||||||
|
//航迹X P
|
||||||
|
double X1[6],X2[6],X3[6],P1[6][6],P2[6][6],P3[6][6];
|
||||||
|
memcpy(X1,(*trust_track)[i].X1,6*sizeof(double));
|
||||||
|
memcpy(X2,(*trust_track)[i].X2,6*sizeof(double));
|
||||||
|
memcpy(X3,(*trust_track)[i].X3,6*sizeof(double));
|
||||||
|
memcpy(P1,(*trust_track)[i].P1,6*6*sizeof(double));
|
||||||
|
memcpy(P2,(*trust_track)[i].P2,6*6*sizeof(double));
|
||||||
|
memcpy(P3,(*trust_track)[i].P3,6*6*sizeof(double));
|
||||||
|
|
||||||
|
//外推
|
||||||
|
|
||||||
|
double X1_pred[6],X2_pred[6],X3_pred[6],P1_pred[6][6],P2_pred[6][6],P3_pred[6][6];
|
||||||
|
kalman Kalman;
|
||||||
|
Kalman.kalman_pred(F, Q1, X1, P1, X1_pred, P1_pred);
|
||||||
|
Kalman.kalman_pred(F, Q2, X2, P2, X2_pred, P2_pred);
|
||||||
|
Kalman.kalman_pred(F, Q3, X3, P3, X3_pred, P3_pred);
|
||||||
|
memcpy((*trust_track)[i].X1,X1_pred,6*sizeof(double));
|
||||||
|
memcpy((*trust_track)[i].X2,X2_pred,6*sizeof(double));
|
||||||
|
memcpy((*trust_track)[i].X3,X3_pred,6*sizeof(double));
|
||||||
|
memcpy((*trust_track)[i].P1,P1_pred,6*6*sizeof(double));
|
||||||
|
memcpy((*trust_track)[i].P2,P2_pred,6*6*sizeof(double));
|
||||||
|
memcpy((*trust_track)[i].P3,P3_pred,6*6*sizeof(double));
|
||||||
|
|
||||||
|
(*trust_track)[i].T_track = static_cast<long long>((*trust_track)[i].T_track+delta_T*1000.0); //更新航迹时间
|
||||||
|
(*trust_track)[i].GNSS_time = static_cast<long long>((*trust_track)[i].GNSS_time+delta_T*1000.0); //更新航迹时间
|
||||||
|
(*trust_track)[i].Extrapolate_round =(*trust_track)[i].Extrapolate_round+1; //连续未用实点更新时间
|
||||||
|
(*trust_track)[i].point_flag=0; //虚点
|
||||||
|
(*trust_track)[i].Track_Update_Flag = 1; //航迹更新标志
|
||||||
|
}else{
|
||||||
|
(*trust_track)[i].Extrapolate_round =(*trust_track)[i].Extrapolate_round+1; //连续未用实点更新时间
|
||||||
|
(*trust_track)[i].point_flag=0; //虚点
|
||||||
|
(*trust_track)[i].Track_Update_Flag = 0; //航迹更新标志
|
||||||
}
|
}
|
||||||
|
|
||||||
double F[6][6], Q1[6][6], Q2[6][6], Q3[6][6];
|
|
||||||
IMM_F_Q_gen( v_track, delta_T, F, Q1, Q2, Q3,Work_Parameter);
|
|
||||||
|
|
||||||
//航迹X P
|
|
||||||
double X1[6],X2[6],X3[6],P1[6][6],P2[6][6],P3[6][6];
|
|
||||||
memcpy(X1,(*trust_track)[i].X1,6*sizeof(double));
|
|
||||||
memcpy(X2,(*trust_track)[i].X2,6*sizeof(double));
|
|
||||||
memcpy(X3,(*trust_track)[i].X3,6*sizeof(double));
|
|
||||||
memcpy(P1,(*trust_track)[i].P1,6*6*sizeof(double));
|
|
||||||
memcpy(P2,(*trust_track)[i].P2,6*6*sizeof(double));
|
|
||||||
memcpy(P3,(*trust_track)[i].P3,6*6*sizeof(double));
|
|
||||||
|
|
||||||
//外推
|
|
||||||
|
|
||||||
double X1_pred[6],X2_pred[6],X3_pred[6],P1_pred[6][6],P2_pred[6][6],P3_pred[6][6];
|
|
||||||
kalman Kalman;
|
|
||||||
Kalman.kalman_pred(F, Q1, X1, P1, X1_pred, P1_pred);
|
|
||||||
Kalman.kalman_pred(F, Q2, X2, P2, X2_pred, P2_pred);
|
|
||||||
Kalman.kalman_pred(F, Q3, X3, P3, X3_pred, P3_pred);
|
|
||||||
memcpy((*trust_track)[i].X1,X1_pred,6*sizeof(double));
|
|
||||||
memcpy((*trust_track)[i].X2,X2_pred,6*sizeof(double));
|
|
||||||
memcpy((*trust_track)[i].X3,X3_pred,6*sizeof(double));
|
|
||||||
memcpy((*trust_track)[i].P1,P1_pred,6*6*sizeof(double));
|
|
||||||
memcpy((*trust_track)[i].P2,P2_pred,6*6*sizeof(double));
|
|
||||||
memcpy((*trust_track)[i].P3,P3_pred,6*6*sizeof(double));
|
|
||||||
|
|
||||||
(*trust_track)[i].T_track = static_cast<long long>((*trust_track)[i].T_track+delta_T*1000.0); //更新航迹时间
|
|
||||||
(*trust_track)[i].GNSS_time = static_cast<long long>((*trust_track)[i].GNSS_time+delta_T*1000.0); //更新航迹时间
|
|
||||||
(*trust_track)[i].Extrapolate_round =(*trust_track)[i].Extrapolate_round+1; //连续未用实点更新时间
|
|
||||||
(*trust_track)[i].point_flag=0; //虚点
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,9 @@ long long latest_timestamp //最新时间戳
|
|||||||
//输出航迹
|
//输出航迹
|
||||||
for (size_t i=0;i<trust_track->size();i++)
|
for (size_t i=0;i<trust_track->size();i++)
|
||||||
{ // 输出更新航迹条件:
|
{ // 输出更新航迹条件:
|
||||||
if((*trust_track)[i].Track_Index == tas_track_idx)
|
if((*trust_track)[i].Track_Index == tas_track_idx && (*trust_track)[i].Track_Update_Flag == 1)
|
||||||
{
|
{
|
||||||
|
(*trust_track)[i].Track_Update_Flag = 0; //航迹更新标志
|
||||||
*Trust_track_num_Output= *Trust_track_num_Output+1;
|
*Trust_track_num_Output= *Trust_track_num_Output+1;
|
||||||
|
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].Point_Sum=1;
|
Trust_Track_Output[*Trust_track_num_Output-1][0].Point_Sum=1;
|
||||||
@@ -87,7 +88,24 @@ long long latest_timestamp //最新时间戳
|
|||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].v_y=static_cast<float>((*trust_track)[i].X[4]);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].v_y=static_cast<float>((*trust_track)[i].X[4]);
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].track_rcs = static_cast<float>((*trust_track)[i].RCS);
|
Trust_Track_Output[*Trust_track_num_Output-1][0].track_rcs = static_cast<float>((*trust_track)[i].RCS);
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].pitch_num = (*trust_track)[i].pitch_num;
|
Trust_Track_Output[*Trust_track_num_Output-1][0].pitch_num = (*trust_track)[i].pitch_num;
|
||||||
Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=Trust_Track_Output[*Trust_track_num_Output-1][0].vr_point>0?1:0;
|
// Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=Trust_Track_Output[*Trust_track_num_Output-1][0].vr_point>0?1:0;
|
||||||
|
|
||||||
|
if(acos((-x * cos(Direction_Angle) - y * sin(Direction_Angle)) / r ) < PI / 2)
|
||||||
|
{
|
||||||
|
Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=1;
|
||||||
|
// if(r*abs(sin(azi - Direction_Angle))<500)
|
||||||
|
// {
|
||||||
|
// Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=1;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=0;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Trust_Track_Output[*Trust_track_num_Output-1][0].Flag_Direction=0;
|
||||||
|
}
|
||||||
|
|
||||||
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim, (*trust_track)[i].speed_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim));
|
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim, (*trust_track)[i].speed_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].speed_dim));
|
||||||
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim, (*trust_track)[i].range_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim));
|
std::memcpy(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim, (*trust_track)[i].range_dim, sizeof(Trust_Track_Output[*Trust_track_num_Output-1][0].range_dim));
|
||||||
@@ -289,65 +307,28 @@ void Track_Asso_Tas::model_filter( std::vector<Trust_Track> *t
|
|||||||
double d1,d2,d3;
|
double d1,d2,d3;
|
||||||
IMM_d_cal(v_track,X1,P1,X2,P2, X3,P3,Z,prt,freq_ind,delta_T,&d1,&d2,&d3,Work_Parameter);
|
IMM_d_cal(v_track,X1,P1,X2,P2, X3,P3,Z,prt,freq_ind,delta_T,&d1,&d2,&d3,Work_Parameter);
|
||||||
|
|
||||||
//计算高度门限
|
//判定统计距离门限,thd_d
|
||||||
double d_h;
|
bool thd_d = false;
|
||||||
if (r_track<1000)
|
|
||||||
{
|
|
||||||
if(abs(h_track-h_point)<=150)
|
|
||||||
{
|
|
||||||
d_h = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d_h = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
if(d1*d1<ASSO_THORD*ASSO_THORD || d2*d2<ASSO_THORD*ASSO_THORD || d3*d3<ASSO_THORD*ASSO_THORD){
|
||||||
else if (r_track<2000 && r_track>=1000)
|
thd_d = true;
|
||||||
{
|
|
||||||
if(abs(h_track-h_point)<=200)
|
|
||||||
{
|
|
||||||
d_h = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d_h = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(r_track>=2000 && r_track<3000 )
|
|
||||||
{
|
|
||||||
if(abs(h_track-h_point)<=200)
|
|
||||||
{
|
|
||||||
d_h = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d_h = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(r_track>=3000 && r_track<5000)
|
|
||||||
{
|
|
||||||
if(abs(h_track-h_point)<=300)
|
|
||||||
{
|
|
||||||
d_h = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d_h = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d_h = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cout << "T d" <<point_process[loop_of_point].CPI_Time/1000<<" "<<T_track/1000<<" "<<delta_T<<" "<<d1<<" "<<d2<<" "<<d3;
|
//判定高度门限,thd_h
|
||||||
// std::cout << "h_track" <<h_track<<" h_point"<<h_point<<" d_h"<<d_h;
|
bool thd_h = false;
|
||||||
|
double delta_h = abs(h_track-h_point);
|
||||||
|
|
||||||
|
if( (r_track <= 1000 && delta_h <= 150) || \
|
||||||
|
((r_track > 1000 && r_track <= 2000) && delta_h <= 200) || \
|
||||||
|
((r_track > 2000 && r_track <= 3000) && delta_h <= 250) || \
|
||||||
|
((r_track > 3000 && r_track <= 5000) && delta_h <= 300) || \
|
||||||
|
r_track > 5000
|
||||||
|
){
|
||||||
|
thd_h = true;
|
||||||
|
}
|
||||||
|
|
||||||
//小于关联门限 保存关联信息
|
//小于关联门限 保存关联信息
|
||||||
if((d1*d1<ASSO_THORD*ASSO_THORD || d2*d2<ASSO_THORD*ASSO_THORD || d3*d3<ASSO_THORD*ASSO_THORD)
|
if(thd_d && thd_h)
|
||||||
&& d_h == 1)//
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// std::cout << "TAS asoooooo111" ;
|
// std::cout << "TAS asoooooo111" ;
|
||||||
@@ -481,6 +462,7 @@ void Track_Asso_Tas::model_filter( std::vector<Trust_Track> *t
|
|||||||
(*trust_track)[i].Amplitude= point_process[point_index-1].Amplitude; //幅度
|
(*trust_track)[i].Amplitude= point_process[point_index-1].Amplitude; //幅度
|
||||||
(*trust_track)[i].associate_point_number = (*trust_track)[i].associate_point_number+1; //关联点数+1
|
(*trust_track)[i].associate_point_number = (*trust_track)[i].associate_point_number+1; //关联点数+1
|
||||||
(*trust_track)[i].RCS = point_process[point_index-1].RCS;
|
(*trust_track)[i].RCS = point_process[point_index-1].RCS;
|
||||||
|
(*trust_track)[i].Track_Update_Flag = 1; //航迹更新标志
|
||||||
|
|
||||||
(*trust_track)[i].pitch_num = point_process[point_index-1].pitch_num;
|
(*trust_track)[i].pitch_num = point_process[point_index-1].pitch_num;
|
||||||
|
|
||||||
@@ -496,33 +478,41 @@ void Track_Asso_Tas::model_filter( std::vector<Trust_Track> *t
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//RDP_LOG << "unassociated point for track index " << tas_track_idx << std::endl;
|
//RDP_LOG << "unassociated point for track index " << tas_track_idx << std::endl;
|
||||||
for(size_t i=0;i<trust_track->size();i++)
|
for(size_t i=0;i<trust_track->size();i++){
|
||||||
if((*trust_track)[i].Track_Index == tas_track_idx)
|
if((*trust_track)[i].Track_Index == tas_track_idx)
|
||||||
{
|
{
|
||||||
double delta_T = (latest_timestamp - T_track)/1000.0;
|
if((*trust_track)[i].Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS)
|
||||||
if (delta_T <= 0)
|
{
|
||||||
continue;
|
double delta_T = (latest_timestamp - T_track)/1000.0;
|
||||||
double F[6][6], Q1[6][6], Q2[6][6], Q3[6][6];
|
if (delta_T <= 0)
|
||||||
IMM_F_Q_gen( v_track, delta_T, F, Q1, Q2, Q3,Work_Parameter);
|
continue;
|
||||||
|
double F[6][6], Q1[6][6], Q2[6][6], Q3[6][6];
|
||||||
|
IMM_F_Q_gen( v_track, delta_T, F, Q1, Q2, Q3,Work_Parameter);
|
||||||
|
|
||||||
double X1_pred[6],X2_pred[6],X3_pred[6],P1_pred[6][6],P2_pred[6][6],P3_pred[6][6];
|
double X1_pred[6],X2_pred[6],X3_pred[6],P1_pred[6][6],P2_pred[6][6],P3_pred[6][6];
|
||||||
kalman Kalman;
|
kalman Kalman;
|
||||||
Kalman.kalman_pred(F, Q1, X1, P1, X1_pred, P1_pred);
|
Kalman.kalman_pred(F, Q1, X1, P1, X1_pred, P1_pred);
|
||||||
Kalman.kalman_pred(F, Q2, X2, P2, X2_pred, P2_pred);
|
Kalman.kalman_pred(F, Q2, X2, P2, X2_pred, P2_pred);
|
||||||
Kalman.kalman_pred(F, Q3, X3, P3, X3_pred, P3_pred);
|
Kalman.kalman_pred(F, Q3, X3, P3, X3_pred, P3_pred);
|
||||||
memcpy((*trust_track)[i].X1,X1_pred,6*sizeof(double));
|
memcpy((*trust_track)[i].X1,X1_pred,6*sizeof(double));
|
||||||
memcpy((*trust_track)[i].X2,X2_pred,6*sizeof(double));
|
memcpy((*trust_track)[i].X2,X2_pred,6*sizeof(double));
|
||||||
memcpy((*trust_track)[i].X3,X3_pred,6*sizeof(double));
|
memcpy((*trust_track)[i].X3,X3_pred,6*sizeof(double));
|
||||||
memcpy((*trust_track)[i].P1,P1_pred,6*6*sizeof(double));
|
memcpy((*trust_track)[i].P1,P1_pred,6*6*sizeof(double));
|
||||||
memcpy((*trust_track)[i].P2,P2_pred,6*6*sizeof(double));
|
memcpy((*trust_track)[i].P2,P2_pred,6*6*sizeof(double));
|
||||||
memcpy((*trust_track)[i].P3,P3_pred,6*6*sizeof(double));
|
memcpy((*trust_track)[i].P3,P3_pred,6*6*sizeof(double));
|
||||||
|
|
||||||
(*trust_track)[i].T_track = static_cast<long long>((*trust_track)[i].T_track+delta_T*1000.0); //更新航迹时间
|
(*trust_track)[i].T_track = static_cast<long long>((*trust_track)[i].T_track+delta_T*1000.0); //更新航迹时间
|
||||||
(*trust_track)[i].GNSS_time = static_cast<long long>((*trust_track)[i].GNSS_time+delta_T*1000.0); //更新航迹时间
|
(*trust_track)[i].GNSS_time = static_cast<long long>((*trust_track)[i].GNSS_time+delta_T*1000.0); //更新航迹时间
|
||||||
(*trust_track)[i].point_flag=0; //虚点
|
(*trust_track)[i].point_flag=0; //虚点
|
||||||
(*trust_track)[i].Extrapolate_round =(*trust_track)[i].Extrapolate_round+1;
|
(*trust_track)[i].Extrapolate_round =(*trust_track)[i].Extrapolate_round+1;
|
||||||
|
(*trust_track)[i].Track_Update_Flag = 1; //航迹更新标志
|
||||||
|
}else{
|
||||||
|
(*trust_track)[i].point_flag=0; //虚点
|
||||||
|
(*trust_track)[i].Extrapolate_round =(*trust_track)[i].Extrapolate_round+1;
|
||||||
|
(*trust_track)[i].Track_Update_Flag = 0; //航迹更新标志
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,24 @@ void Track_Die::track_die_process( std::vector <Trust_Track> *trust_track,
|
|||||||
std::vector <Trust_Track>::iterator Iter;
|
std::vector <Trust_Track>::iterator Iter;
|
||||||
for (Iter=trust_track->begin(); Iter!=trust_track->end();)
|
for (Iter=trust_track->begin(); Iter!=trust_track->end();)
|
||||||
{
|
{
|
||||||
if( ((*Iter).Track_Mode == 0 && (*Iter).Extrapolate_round >= TRACK_DIE_ROUND)
|
bool die_flag = false;
|
||||||
// ||((*Iter).Track_Mode == 1 && (*Iter).Extrapolate_round >= TRACK_DIE_ROUND_TAS)
|
|
||||||
||(*Iter).manual_delete_flag == 1)
|
|
||||||
|
|
||||||
|
if((*Iter).manual_delete_flag == 1)
|
||||||
|
{
|
||||||
|
die_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*Iter).Track_Mode == 0 && (*Iter).primary_target_flag == 0 && (*Iter).Extrapolate_round > TRACK_DIE_ROUND)
|
||||||
|
{
|
||||||
|
die_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*Iter).Track_Mode == 0 && (*Iter).primary_target_flag == 1 && (*Iter).Extrapolate_round > TRACK_DIE_ROUND_PRIMARY)
|
||||||
|
{
|
||||||
|
die_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(die_flag)
|
||||||
{
|
{
|
||||||
//输出消亡信息
|
//输出消亡信息
|
||||||
*Track_die_num_Output=*Track_die_num_Output+1;
|
*Track_die_num_Output=*Track_die_num_Output+1;
|
||||||
|
|||||||
@@ -17,9 +17,19 @@ void Track_Die_Tas::track_die_process_tas( std::vector <Trust_Track> *trust_trac
|
|||||||
std::vector <Trust_Track>::iterator Iter;
|
std::vector <Trust_Track>::iterator Iter;
|
||||||
for (Iter=trust_track->begin(); Iter!=trust_track->end();)
|
for (Iter=trust_track->begin(); Iter!=trust_track->end();)
|
||||||
{
|
{
|
||||||
if( ((*Iter).Track_Mode == 1 && (*Iter).Extrapolate_round >= TRACK_DIE_ROUND_TAS)
|
bool die_flag = false;
|
||||||
||(*Iter).manual_delete_flag == 1)
|
|
||||||
|
|
||||||
|
if((*Iter).manual_delete_flag == 1)
|
||||||
|
{
|
||||||
|
die_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((*Iter).Track_Mode == 1 && (*Iter).Extrapolate_round > TRACK_DIE_ROUND_TAS)
|
||||||
|
{
|
||||||
|
die_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(die_flag)
|
||||||
{
|
{
|
||||||
// RDP_LOG << "remove tas target :" << (*Iter).Track_Index << std::endl;
|
// RDP_LOG << "remove tas target :" << (*Iter).Track_Index << std::endl;
|
||||||
//输出消亡信息
|
//输出消亡信息
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@
|
|||||||
| ② 调度 | 模式码 | 分流到 TWS / TAS 通道 | — |
|
| ② 调度 | 模式码 | 分流到 TWS / TAS 通道 | — |
|
||||||
| ③ 凝聚 | 单 CPI 或相邻两 CPI 点迹 | 同类点合并(保幅度大者) | 凝聚点迹表 |
|
| ③ 凝聚 | 单 CPI 或相邻两 CPI 点迹 | 同类点合并(保幅度大者) | 凝聚点迹表 |
|
||||||
| ④ 关联 | 凝聚点迹 + 已有航迹 | IMM 交互 → 波门筛选 → 最近邻一对一 → EKF 更新 | 更新航迹 + 剩余点迹 |
|
| ④ 关联 | 凝聚点迹 + 已有航迹 | IMM 交互 → 波门筛选 → 最近邻一对一 → EKF 更新 | 更新航迹 + 剩余点迹 |
|
||||||
| ⑤ 起始 | 剩余(未关联)点迹 | 逻辑法:航迹头 → 2 点 → ≥3 点 → 起批 | 新可靠航迹 |
|
| ⑤ 起始 | 剩余(未关联)点迹 | 逻辑法(每圈顺序固定):点 × ≥2 点临时航迹关联 → 点 × 1 点航迹头关联 → 剩余点转新航迹头 → 达标临时航迹起批 | 新可靠航迹 + 更新后的临时航迹表 |
|
||||||
| ⑥ 外推/消亡 | 未关联航迹 | 按数据率预测一帧;超限则消亡 | 补点航迹 / 消亡批号 |
|
| ⑥ 外推/消亡 | 未关联航迹 | 按数据率预测一帧;超限则消亡 | 补点航迹 / 消亡批号 |
|
||||||
| ⑦ 波束控制 | TAS 队列 + 航迹 | 数据率门控 + 队列调度 → 位置外推 | 跟踪波束指令 |
|
| ⑦ 波束控制 | TAS 队列 + 航迹 | 数据率门控 + 队列调度 → 位置外推 | 跟踪波束指令 |
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ flowchart TD
|
|||||||
|
|
||||||
M1 --> A1["IMM 交互 + 波门筛选 + 最近邻关联 + EKF 更新"]
|
M1 --> A1["IMM 交互 + 波门筛选 + 最近邻关联 + EKF 更新"]
|
||||||
A1 --> A2["未关联航迹外推 / 超限消亡"]
|
A1 --> A2["未关联航迹外推 / 超限消亡"]
|
||||||
A2 --> A3["剩余点迹 → 逻辑法航迹起始"]
|
A2 --> A3["剩余点迹 → 逻辑法起始:点×临时航迹 → 点×航迹头 → 剩余点转航迹头 → 起批"]
|
||||||
A3 --> OUT1["输出更新航迹 + 起批航迹历史点 + 消亡批号"]
|
A3 --> OUT1["输出更新航迹 + 起批航迹历史点 + 消亡批号"]
|
||||||
|
|
||||||
M3 --> B1["TAS 凝聚(单帧)"]
|
M3 --> B1["TAS 凝聚(单帧)"]
|
||||||
@@ -165,7 +165,7 @@ flowchart TD
|
|||||||
A["全部可靠航迹"] --> A1["IMM 交互(mix)"]
|
A["全部可靠航迹"] --> A1["IMM 交互(mix)"]
|
||||||
A1 --> B["滤波前先统一置 point_flag=0(本圈默认未关联实点)"]
|
A1 --> B["滤波前先统一置 point_flag=0(本圈默认未关联实点)"]
|
||||||
B --> C["逐航迹 × 逐点:算 ΔT、三个模型马氏距离 d1/d2/d3"]
|
B --> C["逐航迹 × 逐点:算 ΔT、三个模型马氏距离 d1/d2/d3"]
|
||||||
C --> D{"波门判定<br/>距离分段 + 距离门限 d_r + 俯仰门限 d_p"}
|
C --> D{"波门判定<br/>统计距离波门 thd_d + 高度门限 thd_h + 距离门限 thd_r"}
|
||||||
D -- 通过 --> E["记入候选表(含 d_min = min(d1,d2,d3))"]
|
D -- 通过 --> E["记入候选表(含 d_min = min(d1,d2,d3))"]
|
||||||
D -- 不通过 --> F["丢弃该候选对"]
|
D -- 不通过 --> F["丢弃该候选对"]
|
||||||
E --> G["最近邻:反复取全表 d_min 最小者"]
|
E --> G["最近邻:反复取全表 d_min 最小者"]
|
||||||
@@ -180,19 +180,31 @@ flowchart TD
|
|||||||
M --> N["输出全部航迹(更新行 + 补点行)"]
|
M --> N["输出全部航迹(更新行 + 补点行)"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 波门(三步都通过才算候选)
|
### 4.2 波门(统计距离、高度、距离三类都通过才算候选)
|
||||||
|
|
||||||
**(1)统计距离波门**——按航迹距离分段收紧高机动模型:
|
**(1)统计距离波门 thd_d**——按航迹距离分段收紧高机动模型(`ASSO_THORD = 4`):
|
||||||
|
|
||||||
| 航迹距离 r_track | 模型 1 / 2 | 模型 3 |
|
| 航迹距离 r_track | 模型 1 / 2 | 模型 3 |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| ≤ 500 m | d² < 9 | d² < 9/1000(≈ 关闭,抑制近程高机动模型的乱关联) |
|
| ≤ 500 m | d² < 16 | d² < 16/1000(≈ 关闭,抑制近程高机动模型的乱关联) |
|
||||||
| 500 ~ 1000 m | d² < 9 | d² < 9/100(收紧) |
|
| 500 ~ 1000 m | d² < 16 | d² < 16/100(收紧) |
|
||||||
| ≥ 1000 m | d² < 9 | d² < 9 |
|
| ≥ 1000 m | d² < 16 | d² < 16 |
|
||||||
|
|
||||||
> ⚠ **门限语义**:代码里 d 已经是马氏距离平方,判据又写作 `d*d < 9`,等效于 **d < 3**(约对应 3 自由度卡方分布 95% 分位的量级)。调整 ASSO_THORD 时务必记住这一层"二次方"。
|
> ⚠ **门限语义**:代码里 d 已经是马氏距离平方,判据又写作 `d*d < ASSO_THORD*ASSO_THORD`,`ASSO_THORD = 4` 时等效于 **d < 4**(而非 √d < 4)。调整 ASSO_THORD 时务必记住这一层"二次方"(该行为在 BUG-20 中被识别,有意保留)。
|
||||||
|
|
||||||
**(2)距离门限 d_r**——抑制远距离突跳。用航迹-点迹弦距 R 与航迹位移 VT = v_track·ΔT 判断:
|
**(2)高度门限 thd_h**(e0bf227 起在 TWS 侧生效)——|h_track − h_point| 按航迹距离分段:
|
||||||
|
|
||||||
|
| 航迹距离 r_track | 高度差门限 |
|
||||||
|
|---|---|
|
||||||
|
| ≤ 1000 m | 150 m |
|
||||||
|
| 1000 ~ 2000 m | 200 m |
|
||||||
|
| 2000 ~ 3000 m | 250 m |
|
||||||
|
| 3000 ~ 5000 m | 300 m |
|
||||||
|
| > 5000 m | 不约束 |
|
||||||
|
|
||||||
|
> 该门限此前在 `track_asso.cpp` 中整块被注释、`d_h` 恒为 1(等于不生效),现改为独立布尔量 `thd_h` 参与判定,取值与 TAS 通道一致,用于压制俯仰测量跳变引起的错误关联。
|
||||||
|
|
||||||
|
**(3)距离门限 thd_r**——抑制远距离突跳。用航迹-点迹弦距 R 与航迹位移 VT = v_track·ΔT 判断:
|
||||||
|
|
||||||
```
|
```
|
||||||
VT < 100 且 R > 300 → 拒绝(慢速目标不允许 300 m 以上的跳变)
|
VT < 100 且 R > 300 → 拒绝(慢速目标不允许 300 m 以上的跳变)
|
||||||
@@ -200,7 +212,9 @@ VT < 100 且 R > 300 → 拒绝(慢速目标不允许 300 m 以上的跳
|
|||||||
VT > 300 且 R > 1200 → 拒绝(高速目标给固定 1200 m 上限)
|
VT > 300 且 R > 1200 → 拒绝(高速目标给固定 1200 m 上限)
|
||||||
```
|
```
|
||||||
|
|
||||||
**(3)俯仰门限 d_p**:分距离段 7°/5°/10° 的逻辑当前被注释停用,**恒为通过**。
|
**(4)俯仰门限 d_p**:分距离段 7°/5°/10° 的逻辑仍被注释停用,不参与判定(其作用已由高度门限覆盖)。
|
||||||
|
|
||||||
|
> 实现要点:三类判据分别算成 `thd_d` / `thd_h` / `thd_r` 三个布尔量,最后以 `thd_d && thd_h && thd_r` 决定是否记入候选表(e0bf227 起;此前三者混写在一个长 `if` 条件里)。
|
||||||
|
|
||||||
### 4.3 最近邻(NN)选取规则
|
### 4.3 最近邻(NN)选取规则
|
||||||
|
|
||||||
@@ -254,106 +268,51 @@ VT > 300 且 R > 1200 → 拒绝(高速目标给固定 1200 m 上限)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. IMM + EKF 关键逻辑
|
## 5. 航迹起始(逻辑法)
|
||||||
|
|
||||||
### 5.1 IMM 框架
|
### 5.1 状态机(每圈按 ①→⑤ 的固定顺序执行)
|
||||||
|
|
||||||
```mermaid
|
|
||||||
flowchart LR
|
|
||||||
A["上一拍三模型状态/协方差 + 模型概率 u"] --> B["交互 mix:算归一化常数 c̄j 与混合概率"]
|
|
||||||
B --> C["得到三个混合初值 X0j / P0j"]
|
|
||||||
C --> D["各子模型独立预测(Singer F 和 Qj)"]
|
|
||||||
D --> E["各子模型 EKF 量测更新 → 新息协方差 Sj、马氏距离 dj"]
|
|
||||||
E --> F["似然 Λj = N(dj; 0, Sj),模型概率 μj' ∝ Λj·c̄j"]
|
|
||||||
F --> G["融合输出:X̂ = Σμj'X̂j<br/>P = Σμj'[Pj + (X̂j−X̂)(X̂j−X̂)ᵀ]"]
|
|
||||||
```
|
|
||||||
|
|
||||||
- 状态布局 `[x, vx, ax, y, vy, ay]`,x/y 两轴解耦;
|
|
||||||
- 模型转移概率矩阵固定:
|
|
||||||
```
|
|
||||||
Pt = [ 0.8 0.15 0.05
|
|
||||||
0.3 0.4 0.3
|
|
||||||
0.05 0.15 0.8 ]
|
|
||||||
```
|
|
||||||
- 机动相关时间常数 α = 0.2;
|
|
||||||
- 数值保护:归一化常数 c̄j ≤ 1e-12 时钳位;似然分母(det S)≤ 1e-12 时该模型似然置 0;概率分母异常时**保持上一拍模型概率**;EKF 似然用 3×3 新息协方差(保证与量测维数一致)。
|
|
||||||
|
|
||||||
### 5.2 三个 Singer 模型的过程噪声强度分档
|
|
||||||
|
|
||||||
按航迹速度 v_track 切换 q 值(模型 1 恒用 slow):
|
|
||||||
|
|
||||||
| 模型 | TWS 通道 | TAS 通道 |
|
|
||||||
|---|---|---|
|
|
||||||
| 模型 1(低机动) | `Model1_Q_slow`(恒定) | 同左 |
|
|
||||||
| 模型 2(中机动) | v≤5:slow/20;5<v≤30:slow;v>30:fast | v≤5:slow/20;50<v≤100:10·fast;其余:fast |
|
|
||||||
| 模型 3(高机动) | v≤5:slow/20;5<v≤20:slow;20<v≤50:fast;50<v≤100:2·fast;v>100:10·fast | v≤5:slow/20;50<v≤100:10·fast;其余:fast |
|
|
||||||
|
|
||||||
> 语义:低速目标按"低机动"处理(把中/高机动模型噪声压到极小,避免噪声被当成机动),速度越高逐步放大高机动模型的过程噪声。`Model1_Q_fast` 字段不参与计算。
|
|
||||||
|
|
||||||
### 5.3 量测与残差修正(EKF)
|
|
||||||
|
|
||||||
量测向量 Z = [r, θ, v_r],量测函数由预测状态给出:
|
|
||||||
|
|
||||||
```
|
|
||||||
h(X) = [ √(x²+y²), atan2(y,x) 归一化到 [0,2π), −(x·vx + y·vy)/√(x²+y²) ]
|
|
||||||
```
|
|
||||||
|
|
||||||
在预测点处线性化得到雅可比 H(3×6),量测噪声 R = diag(σr², σa², σv²)(10 m / 0.02 rad / 2 m/s),S = H·P·Hᵀ + R。
|
|
||||||
|
|
||||||
**两处残差修正(关键)**
|
|
||||||
|
|
||||||
1. **方位环绕**:νθ 归一到 [−π, π),避免 0°/360° 附近的假大残差;
|
|
||||||
2. **多普勒盲速折叠**:`νv ← νv − round(νv / v_bind) · v_bind`,其中
|
|
||||||
|
|
||||||
```
|
|
||||||
v_bind = 150000 / (f_GHz · PRI_µs), f_GHz = 9.2 + 0.02 · 频点号
|
|
||||||
```
|
|
||||||
|
|
||||||
PRI ≤ 0 或频率非法时返回安全值 1.0(接口约定 PRI 单位 µs 且不允许为 0)。
|
|
||||||
|
|
||||||
判据(关联)与模型似然共用同一个 `d = νᵀS⁻¹ν`,且滤波函数把 3×3 新息协方差 S 一并回传给似然使用。
|
|
||||||
|
|
||||||
### 5.4 航迹初始化
|
|
||||||
|
|
||||||
| 场景 | 维数 | 做法 |
|
|
||||||
|---|---|---|
|
|
||||||
| 两点(航迹头 + 1 点,临时航迹) | 4 维 [x, vx, y, vy] | 位置取末点,速度取两点差分;协方差按 Z1 处的**转换量测协方差** R 填充,速度项按 R/T、2R/T² 传播 |
|
|
||||||
| 三点(起批,可靠航迹) | 6 维 | 位置取末点、速度取末两点差分、加速度取两段速度差分;协方差按 R0/R1/R2 误差传播构造 |
|
|
||||||
| 起批时 IMM 初始化 | — | 三个子模型用同一状态/协方差,模型概率 u = [1/3, 1/3, 1/3] |
|
|
||||||
|
|
||||||
**转换量测协方差**(极坐标量测转直角坐标时的等效噪声,含方位非线性引起的附加项,由 σr=10 m、σa=0.02 rad 决定)用于上述初始化与临时航迹统计距离计算。
|
|
||||||
|
|
||||||
> 约束:两点/三点初始化对时间差 T 无除零保护,因此**起批路径要求时间戳严格递增、不允许重复**。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. 航迹起始(逻辑法)
|
|
||||||
|
|
||||||
### 6.1 状态机
|
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
A["本圈未被可靠航迹关联的点迹"] --> B["全部转成'航迹头'(1 点,buff_round=1)"]
|
A["本圈未被可靠航迹关联的点迹"] --> A0["临时航迹所有点的 buff_round +1"]
|
||||||
B --> C{"下一圈的点迹"}
|
A0 --> B["① 点 × ≥2 点临时航迹关联(三点及以上)<br/>EKF 统计距离 + 折角 + 多普勒同号<br/>命中 → 复制原航迹 + 追加新点"]
|
||||||
C --> D["点-航迹头关联(两点起始)<br/>速度区间 + 多普勒一致性"]
|
B --> C["② 点 × 1 点航迹头关联(两点起始)<br/>速度区间 + 多普勒一致性<br/>命中 → 两点卡尔曼初始化 → 2 点临时航迹"]
|
||||||
D -->|命中| E["两点卡尔曼初始化 → 2 点临时航迹"]
|
C --> D["③ 删除 Use_Flag==1 的点迹<br/>剩余点全部转成新航迹头(1 点,buff_round=1)<br/>当圈不再参与关联"]
|
||||||
D -->|未命中| B
|
D --> E{"④ 长度 ≥ 起批点数<br/>且 ≤10 且不在起批屏蔽区?"}
|
||||||
E --> F{"后续圈的点迹"}
|
E -- 是 --> F["同源去重(保留末点 d 更小者)"]
|
||||||
F --> G["点-临时航迹关联(三点及以上)<br/>EKF 统计距离 + 折角 + 多普勒同号"]
|
F --> G["三点卡尔曼初始化 → 分配航迹号 1~500<br/>IMM 三模型同状态,u=1/3"]
|
||||||
G -->|命中| H["航迹延长(复制原航迹 + 追加新点)"]
|
G --> H["输出该航迹的历史点(前 N 个点)"]
|
||||||
G -->|未命中| F
|
E -- 否 --> I["留在临时航迹表,下一圈继续关联"]
|
||||||
H --> I{"长度 ≥ 起批点数<br/>且不在起批屏蔽区?"}
|
H --> J["⑤ 临时航迹消亡(不对外输出)<br/>末点 buff_round > 2 或 长度 ≥ 10"]
|
||||||
I -- 是 --> J["同源去重(保留末点 d 更小者)"]
|
I --> J
|
||||||
J --> K["三点卡尔曼初始化 → 分配航迹号 1~500<br/>IMM 三模型同状态,u=1/3"]
|
|
||||||
K --> L["输出该航迹的历史点(前 N 个点)"]
|
|
||||||
I -- 否 --> F
|
|
||||||
F --> M{"末点 buff_round > 2<br/>或长度 ≥ 10 ?"}
|
|
||||||
M -- 是 --> N["临时航迹消亡(不对外输出)"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 关联判据汇总
|
**每圈顺序不可颠倒(`track_init.cpp` L49-126)**:点迹**先**做点-临时航迹关联(延长已有 ≥2 点临时航迹),**再**做点-航迹头关联(产生新的 2 点临时航迹),两阶段都结束后才把未被消费的点迹转成新航迹头,最后才把长度达标的临时航迹转可靠航迹,消亡放在最末。由此可得:
|
||||||
|
|
||||||
**阶段一:点 ↔ 航迹头(两点起始)**
|
- 当圈新建的 2 点临时航迹**不可能当圈起批**——长度不足,且新点 `buff_round=1` 要到下一圈才具备关联资格;
|
||||||
|
- 当圈刚被延长到达标长度的临时航迹**可以当圈起批**(第 ④ 步在第 ① 步之后执行);
|
||||||
|
- 两个关联阶段**互不排斥**:都只把命中的点迹标记 `Use_Flag=1`,航迹头阶段不检查临时航迹阶段留下的标记,因此同一点迹可同时延长一条临时航迹、又开启一条 2 点临时航迹,只有走完两阶段后才统一删除被标记的点迹。
|
||||||
|
|
||||||
|
> 第 ⑤ 步的消亡判据对**未起批**的临时航迹生效;已起批的航迹在第 ④ 步中已从临时航迹表移除。
|
||||||
|
|
||||||
|
### 5.2 关联判据汇总
|
||||||
|
|
||||||
|
每圈按 **① 点-临时航迹关联 → ② 点-航迹头关联** 的顺序依次执行,两阶段的关联判据如下。
|
||||||
|
|
||||||
|
**阶段①:点 ↔ ≥2 点临时航迹(三点及以上)**
|
||||||
|
|
||||||
|
```
|
||||||
|
|r_point − r_末点| ≥ 5 m 距离差硬门限(近距点不参与)
|
||||||
|
d ≤ 8(代码写作 d² ≤ TRACK_START_THRESHOLD²=64) 3 维 EKF 统计距离波门
|
||||||
|
α < ALPHA_START = 60° 折角:最近三点连线夹角
|
||||||
|
v_r,point · v_r,末点 > 0 多普勒同号
|
||||||
|
```
|
||||||
|
|
||||||
|
- d 由 4 维 CV 状态一步预测 + 「距离-方位-径向速度」EKF 得到(过程噪声 0.03²、同样做方位环绕与盲速折叠);
|
||||||
|
- 折角 α 为向量 D12(前一点→末点)与 D23(末点→新点)的夹角;α 越小越接近直线;
|
||||||
|
- 门限同样写作 `d² ≤ TRACK_START_THRESHOLD²`,而 d 本身已是马氏距离平方,实际生效为 d ≤ 8(与可靠航迹关联门限的语义一致)。
|
||||||
|
|
||||||
|
**阶段②:点 ↔ 航迹头(两点起始)**
|
||||||
|
|
||||||
用航迹头位置与点迹的平面距离 `dis` 与 ΔT(秒):
|
用航迹头位置与点迹的平面距离 `dis` 与 ΔT(秒):
|
||||||
|
|
||||||
@@ -369,27 +328,14 @@ dis ≥ |v_r,head| · ΔT 同上,用航迹头的多普勒约
|
|||||||
- 判据隐含要求 ΔT > 0(ΔT ≤ 0 时 `dis ≤ V_MAX·ΔT` 必然不成立);
|
- 判据隐含要求 ΔT > 0(ΔT ≤ 0 时 `dis ≤ V_MAX·ΔT` 必然不成立);
|
||||||
- 近程/中远程分支当前取值相同(都是 V_MAX),**实际不做距离分段**。
|
- 近程/中远程分支当前取值相同(都是 V_MAX),**实际不做距离分段**。
|
||||||
|
|
||||||
**阶段二:点 ↔ ≥2 点临时航迹(三点及以上)**
|
### 5.3 临时航迹的"圈数"生命周期
|
||||||
|
|
||||||
```
|
`buff_round` 只在起始流程里自增,并且**每次调用(= 每圈)先把所有临时航迹所有点的 buff_round +1,再做关联**;因此关联判据看到的是自增后的圈数,当圈刚建立/刚追加的点(buff_round=1)当圈不可能再被关联:
|
||||||
|r_point − r_末点| ≥ 5 m 距离差硬门限(近距点不参与)
|
|
||||||
d ≤ 8(代码写作 d² ≤ TRACK_START_THRESHOLD²=64) 3 维 EKF 统计距离波门
|
|
||||||
α < ALPHA_START = 60° 折角:最近三点连线夹角
|
|
||||||
v_r,point · v_r,末点 > 0 多普勒同号
|
|
||||||
```
|
|
||||||
|
|
||||||
- d 由 4 维 CV 状态一步预测 + 「距离-方位-径向速度」EKF 得到(过程噪声 0.03²、同样做方位环绕与盲速折叠);
|
|
||||||
- 折角 α 为向量 D12(前一点→末点)与 D23(末点→新点)的夹角;α 越小越接近直线;
|
|
||||||
- 同样存在"门限对马氏距离平方再平方"的语义,实际生效为 d ≤ 8。
|
|
||||||
|
|
||||||
### 6.3 临时航迹的"圈数"生命周期
|
|
||||||
|
|
||||||
`buff_round` 只在起始流程里自增,并且**每次调用(= 每圈)先把所有临时航迹所有点的 buff_round +1,再做关联**:
|
|
||||||
|
|
||||||
| 动作 | 效果 |
|
| 动作 | 效果 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 新点加入 | buff_round = 1 |
|
| 新点加入 | buff_round = 1 |
|
||||||
| 关联资格 | 只看**末点**,要求 buff_round ≥ 2 → **上一圈加入的点本圈才能被延续**,同一航迹每圈最多吸收一个点 |
|
| 关联资格 | 只看**末点**,要求 buff_round ≥ 2 → **上一圈加入的点本圈才能被延续**;同一圈内一条临时航迹可被多个点同时延续(每个点各复制出一条新航迹,见 6.4),并非一对一 |
|
||||||
| 消亡条件 | 末点 buff_round > 2(连续 2 圈无新点)或长度 ≥ 10 |
|
| 消亡条件 | 末点 buff_round > 2(连续 2 圈无新点)或长度 ≥ 10 |
|
||||||
|
|
||||||
**时间轴示例(以第 k 圈加入新点为起点)**
|
**时间轴示例(以第 k 圈加入新点为起点)**
|
||||||
@@ -402,13 +348,14 @@ v_r,point · v_r,末点 > 0 多普勒同号
|
|||||||
|
|
||||||
即:**允许中间空 1 圈**,最大关联间隔 2 圈;生命周期完全由"圈数"驱动,与绝对时间无关。
|
即:**允许中间空 1 圈**,最大关联间隔 2 圈;生命周期完全由"圈数"驱动,与绝对时间无关。
|
||||||
|
|
||||||
### 6.4 航迹分裂与去重
|
### 5.4 航迹分裂与去重
|
||||||
|
|
||||||
- 关联阶段**不做一对一分配**:一个点满足多条临时航迹条件时,每条都各自复制出一条新航迹;多条点命中同一条航迹时也各自复制 → 同一圈会产生大量同源临时航迹;
|
- 关联阶段**不做一对一分配**:一个点满足多条临时航迹条件时,每条都各自复制出一条新航迹;多个点命中同一条临时航迹时也各自复制;点-航迹头阶段同理(一个航迹头可与多个点各生成一条 2 点临时航迹)→ 同一圈会产生大量同源临时航迹;
|
||||||
|
- 两个关联阶段也**互不排斥**:点-航迹头阶段不检查点-临时航迹阶段留下的 `Use_Flag`,同一点迹可同时参与两边的分裂试探;
|
||||||
- 起批前做**同源去重**:比较两条候选航迹的**前三个点**,只要有任一点的"时间 T + 距离 r"完全相同即判为同源,保留末点统计距离 d 更小者;
|
- 起批前做**同源去重**:比较两条候选航迹的**前三个点**,只要有任一点的"时间 T + 距离 r"完全相同即判为同源,保留末点统计距离 d 更小者;
|
||||||
- 这样既保证不漏关联(允许分裂试探),又不会让同一批点重复起批。
|
- 这样既保证不漏关联(允许分裂试探),又不会让同一批点重复起批。
|
||||||
|
|
||||||
### 6.5 起批与输出
|
### 5.5 起批与输出
|
||||||
|
|
||||||
| 条件 | 说明 |
|
| 条件 | 说明 |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -422,9 +369,9 @@ v_r,point · v_r,末点 > 0 多普勒同号
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. 外推、消亡与航迹号管理
|
## 6. 外推、消亡与航迹号管理
|
||||||
|
|
||||||
### 7.1 消亡条件
|
### 6.1 消亡条件
|
||||||
|
|
||||||
| 通道 | 条件(满足其一即消亡) |
|
| 通道 | 条件(满足其一即消亡) |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -434,7 +381,7 @@ v_r,point · v_r,末点 > 0 多普勒同号
|
|||||||
|
|
||||||
消亡时把批号写入消亡输出数组并从航迹表删除;**临时航迹消亡不对外输出**(起批失败的中间态对宿主不可见)。
|
消亡时把批号写入消亡输出数组并从航迹表删除;**临时航迹消亡不对外输出**(起批失败的中间态对宿主不可见)。
|
||||||
|
|
||||||
### 7.2 航迹号分配
|
### 6.2 航迹号分配
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
@@ -454,20 +401,20 @@ flowchart TD
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. TAS 通道(model=3)
|
## 7. TAS 通道(model=3)
|
||||||
|
|
||||||
### 8.1 与 TWS 通道的差异
|
### 7.1 与 TWS 通道的差异
|
||||||
|
|
||||||
| 项 | TWS | TAS |
|
| 项 | TWS | TAS |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| 凝聚 | 相邻两帧滑窗,近程多速度维约束 | 单帧,恒有速度维约束 |
|
| 凝聚 | 相邻两帧滑窗,近程多速度维约束 | 单帧,恒有速度维约束 |
|
||||||
| 处理对象 | 全部可靠航迹 × 全部点 | **仅指定批号**的这一条航迹 × 全部点 |
|
| 处理对象 | 全部可靠航迹 × 全部点 | **仅指定批号**的这一条航迹 × 全部点 |
|
||||||
| 俯仰/高度门限 | 俯仰门限当前恒通过 | **高度门限生效**(按距离分段) |
|
| 俯仰/高度门限 | 俯仰门限已注释停用;**高度门限生效**(按距离分段,e0bf227 起) | **高度门限生效**(按距离分段,取值与 TWS 相同) |
|
||||||
| ΔT ≤ 0 | 参与选取但只消费点迹、不更新 | **直接跳过该点**(并记告警日志) |
|
| ΔT ≤ 0 | 参与选取但只消费点迹、不更新 | **直接跳过该点**(并记告警日志) |
|
||||||
| 外推时间 | 按 work_mode 数据率固定步长 | 按 `最新时间戳 − 航迹时间` |
|
| 外推时间 | 按 work_mode 数据率固定步长 | 按 `最新时间戳 − 航迹时间` |
|
||||||
| 输出 | 全部航迹 | 仅该批号航迹 |
|
| 输出 | 全部航迹 | 仅该批号航迹 |
|
||||||
|
|
||||||
### 8.2 TAS 关联与更新
|
### 7.2 TAS 关联与更新
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
@@ -476,7 +423,7 @@ flowchart TD
|
|||||||
B -- 是 --> C["IMM 交互;航迹 point_flag 置 0"]
|
B -- 是 --> C["IMM 交互;航迹 point_flag 置 0"]
|
||||||
C --> D["逐点:ΔT ≤ 0 → 记告警并跳过"]
|
C --> D["逐点:ΔT ≤ 0 → 记告警并跳过"]
|
||||||
D --> E["逐点:三模型统计距离 d1/d2/d3 + 高度门限"]
|
D --> E["逐点:三模型统计距离 d1/d2/d3 + 高度门限"]
|
||||||
E --> F{"d² < 9(任一模型)且高度门限通过?"}
|
E --> F{"d² < 16(任一模型)且高度门限通过?"}
|
||||||
F -- 是 --> G["记入候选表"]
|
F -- 是 --> G["记入候选表"]
|
||||||
F -- 否 --> H["丢弃"]
|
F -- 否 --> H["丢弃"]
|
||||||
G --> I["取 d_min 最小的一点"]
|
G --> I["取 d_min 最小的一点"]
|
||||||
@@ -493,7 +440,7 @@ flowchart TD
|
|||||||
|---|---|
|
|---|---|
|
||||||
| ≤ 1000 m | 150 m |
|
| ≤ 1000 m | 150 m |
|
||||||
| 1000 ~ 2000 m | 200 m |
|
| 1000 ~ 2000 m | 200 m |
|
||||||
| 2000 ~ 3000 m | 200 m |
|
| 2000 ~ 3000 m | 250 m |
|
||||||
| 3000 ~ 5000 m | 300 m |
|
| 3000 ~ 5000 m | 300 m |
|
||||||
| > 5000 m | 不约束 |
|
| > 5000 m | 不约束 |
|
||||||
|
|
||||||
@@ -501,9 +448,9 @@ flowchart TD
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9. TAS 波束控制(外部接口 Beam_Ctrl)
|
## 8. TAS 波束控制(外部接口 Beam_Ctrl)
|
||||||
|
|
||||||
### 9.1 队列管理
|
### 8.1 队列管理
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
@@ -527,15 +474,15 @@ flowchart TD
|
|||||||
|
|
||||||
> 自动开启/退出 TAS 的逻辑(按距离/速度/高度阈值)已全部注释停用,**只支持手动**。
|
> 自动开启/退出 TAS 的逻辑(按距离/速度/高度阈值)已全部注释停用,**只支持手动**。
|
||||||
|
|
||||||
### 9.2 波束输出调度(关键)
|
### 8.2 波束输出调度(关键)
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
flowchart TD
|
flowchart TD
|
||||||
A["遍历 TAS 队列"] --> B["按批号在航迹表中找到该航迹"]
|
A["遍历 TAS 队列"] --> B["按批号在航迹表中找到该航迹"]
|
||||||
B --> C{"距上次波束输出 > DATA_RATE_TAS 秒<br/>且 最新时间戳 − 航迹时间 > DATA_RATE_TAS 秒?"}
|
B --> C{"距上次波束输出 > DATA_RATE_TAS 秒<br/>且 CPI 时间早于已选中的最早 CPI?"}
|
||||||
C -- 否 --> A
|
C -- 否 --> A
|
||||||
C -- 是 --> D["在合格目标中选 CPI 时间最早者"]
|
C -- 是 --> D["选中该目标(CPI 时间最早者)"]
|
||||||
D --> E["位置外推:x + vx·ΔT, y + vy·ΔT"]
|
D --> E["位置外推:ΔT = (最新时间戳 − CPI 时间)/1000<br/>x + vx·ΔT, y + vy·ΔT"]
|
||||||
E --> F["Range = √(xp²+yp²),Azi = atan2(yp,xp)<br/>Elev = asin(Height / Range)"]
|
E --> F["Range = √(xp²+yp²),Azi = atan2(yp,xp)<br/>Elev = asin(Height / Range)"]
|
||||||
F --> G["open_flag=1, type=1, 批号=真实航迹号<br/>更新该目标 last_track_time = 最新时间戳"]
|
F --> G["open_flag=1, type=1, 批号=真实航迹号<br/>更新该目标 last_track_time = 最新时间戳"]
|
||||||
C -.->|"无任何合格目标"| H["open_flag = 0(其余字段保持旧值)"]
|
C -.->|"无任何合格目标"| H["open_flag = 0(其余字段保持旧值)"]
|
||||||
@@ -543,16 +490,17 @@ flowchart TD
|
|||||||
|
|
||||||
**要点**
|
**要点**
|
||||||
|
|
||||||
- 门控用**两个条件**:距上次输出的时间、航迹时间与最新时间戳之差都要大于 `DATA_RATE_TAS` 秒(单位是秒,由宿主经参数初始化传入,须为 > 0 的有效值)→ 保证 TAS 目标的数据率**不随 Beam_Ctrl 的调用频率变化**;
|
- 门控只用一个条件(e0bf227 修正):目标「距上次波束输出的时间」(`latest_timestamp − last_track_time`)要大于 `DATA_RATE_TAS` 秒(单位是秒,由宿主经参数初始化传入,须为 > 0 的有效值)→ 保证 TAS 目标的数据率**不随 Beam_Ctrl 的调用频率变化**;修正前还要求「航迹时间与最新时间戳之差」也大于该门限,与"取最早 CPI 目标"的语义冲突,会漏掉本应输出的波束;
|
||||||
- 多目标时选**队列中 CPI 时间最早**的目标,等价于"按最久未更新者优先"的轮转;
|
- 多目标时选**队列中 CPI 时间最早**的目标(同时要求其 CPI 时间早于当前已选者),等价于"按最久未更新者优先"的轮转;
|
||||||
|
- 选中后才按该目标的 CPI 时间算外推步长 `ΔT = (最新时间戳 − CPI 时间)/1000`;
|
||||||
- 原来的"每次调用整队循环移位"已停用;
|
- 原来的"每次调用整队循环移位"已停用;
|
||||||
- 俯仰用航迹高度直接算(叠加雷达平台高度的处理只影响对外输出的 z,不参与波束俯仰)。
|
- 俯仰用航迹高度直接算(叠加雷达平台高度的处理只影响对外输出的 z,不参与波束俯仰)。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10. 参数脉络(决定行为的旋钮)
|
## 9. 参数脉络(决定行为的旋钮)
|
||||||
|
|
||||||
### 10.1 编译期宏(随扫描体制切换)
|
### 9.1 编译期宏(随扫描体制切换)
|
||||||
|
|
||||||
| 宏 | 相扫 | 机扫 | 作用点 |
|
| 宏 | 相扫 | 机扫 | 作用点 |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
@@ -561,7 +509,7 @@ flowchart TD
|
|||||||
| `R_MIN / R_MAX` | 100 / 100000 | 同左 | 有效量程(凝聚后过滤) |
|
| `R_MIN / R_MAX` | 100 / 100000 | 同左 | 有效量程(凝聚后过滤) |
|
||||||
| `TRACK_START_THRESHOLD` | 8 | 同左 | 起始统计距离波门(d ≤ 8) |
|
| `TRACK_START_THRESHOLD` | 8 | 同左 | 起始统计距离波门(d ≤ 8) |
|
||||||
| `ALPHA_START` | 60 | 同左 | 起始折角上限(°) |
|
| `ALPHA_START` | 60 | 同左 | 起始折角上限(°) |
|
||||||
| `ASSO_THORD` | 3 | 同左 | 关联波门(d² < 9,等效 d < 3) |
|
| `ASSO_THORD` | 4 | 同左 | 关联波门(判据 d*d < ASSO_THORD²,d 已是马氏距离平方,等效 d < 4) |
|
||||||
| `TRACK_DIE_ROUND` | 4 | 4 | TWS 消亡外推轮数 |
|
| `TRACK_DIE_ROUND` | 4 | 4 | TWS 消亡外推轮数 |
|
||||||
| `TRACK_DIE_ROUND_TAS` | 5 | 96 | TAS 消亡外推轮数 |
|
| `TRACK_DIE_ROUND_TAS` | 5 | 96 | TAS 消亡外推轮数 |
|
||||||
| `MAX_TRACK_NUM / MAX_TRACK_INDEX` | 500 / 500 | 同左 | 航迹数上限 / 航迹号上限 |
|
| `MAX_TRACK_NUM / MAX_TRACK_INDEX` | 500 / 500 | 同左 | 航迹数上限 / 航迹号上限 |
|
||||||
@@ -570,7 +518,7 @@ flowchart TD
|
|||||||
| `FREQ0` | 9.2 GHz | 同左 | 盲速计算的基准频率 |
|
| `FREQ0` | 9.2 GHz | 同左 | 盲速计算的基准频率 |
|
||||||
| `RDP_LOG_ENABLE / RDP_LOG_DIR` | — | — | 日志落盘开关与目录 |
|
| `RDP_LOG_ENABLE / RDP_LOG_DIR` | — | — | 日志落盘开关与目录 |
|
||||||
|
|
||||||
### 10.2 运行时参数(宿主传入,随任务变化)
|
### 9.2 运行时参数(宿主传入,随任务变化)
|
||||||
|
|
||||||
| 参数 | 影响环节 |
|
| 参数 | 影响环节 |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -589,7 +537,7 @@ flowchart TD
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. 关键约定与注意事项
|
## 10. 关键约定与注意事项
|
||||||
|
|
||||||
**时序与时间戳**
|
**时序与时间戳**
|
||||||
|
|
||||||
@@ -635,5 +583,8 @@ flowchart TD
|
|||||||
| 起始输出历史点 | "临时航迹的全部 L 个点" | 实际输出**前 `track_start_point_num` 个点** |
|
| 起始输出历史点 | "临时航迹的全部 L 个点" | 实际输出**前 `track_start_point_num` 个点** |
|
||||||
| 起始输入过滤 | "track_init 跳过 Use_Flag==1 的点" | 上游 `track_asso_process()` 结束前已把 `Use_Flag==1` 的点迹从 `point_recv` 删除;`track_init` 入口(L59-70)也会再剔除一次 `Use_Flag==1` 的点,两道处理叠加,效果一致 |
|
| 起始输入过滤 | "track_init 跳过 Use_Flag==1 的点" | 上游 `track_asso_process()` 结束前已把 `Use_Flag==1` 的点迹从 `point_recv` 删除;`track_init` 入口(L59-70)也会再剔除一次 `Use_Flag==1` 的点,两道处理叠加,效果一致 |
|
||||||
| 日志开关 | "RDP_LOG_ENABLE 默认开启" | `parameters.h` 中该宏当前为**注释状态**(不落盘,日志进控制台) |
|
| 日志开关 | "RDP_LOG_ENABLE 默认开启" | `parameters.h` 中该宏当前为**注释状态**(不落盘,日志进控制台) |
|
||||||
|
| 起始步骤顺序 | "航迹头(1 点)→ 点-航迹头关联(2 点)→ 点-临时航迹关联(≥3 点)→ 起批" | 每圈实际顺序为**点 × ≥2 点临时航迹关联 → 点 × 1 点航迹头关联 → 剩余点转新航迹头 → 长度达标的临时航迹起批**,消亡最后执行(`track_init.cpp` L49-126,见第 6 节) |
|
||||||
|
|
||||||
> 后续:README 与 `track_init_readme.md`(航迹起始专项说明)已按上表结论同步(见 CHANGELOG 的 Unreleased 记录);流程落地实现仍以本文为准。
|
> 后续:README 与 `track_init_readme.md`(航迹起始专项说明)已按上表结论同步(见 CHANGELOG 的 Unreleased 记录);流程落地实现仍以本文为准。
|
||||||
|
>
|
||||||
|
> 补充修订(本次):起始流程的**步骤顺序**原先在本文档(第 0、6 节)与 README(第 2、5.2、8.3、9.3 节)中都写作「航迹头 → 2 点 → ≥3 点 → 起批」,与源码每圈「点 × 临时航迹关联 → 点 × 航迹头关联 → 剩余点转航迹头 → 达标者起批」的顺序相反,现已按源码修正,并补充说明两个关联阶段互不排斥、均不做一对一分配。
|
||||||
|
|||||||
Reference in New Issue
Block a user