1、更新文档;

Signed-off-by: waiwaylee <waiwaylee@foxmail.com>
This commit is contained in:
2026-10-20 11:22:33 +08:00
parent 3a9b1c4924
commit 332f270b46
5 changed files with 218 additions and 71 deletions
+102 -35
View File
@@ -1,9 +1,9 @@
# 雷达数据处理 DLL(data_process_class_dll)
> X256 雷达数据处理动态链接库:将雷达输出的原始点迹(TWS/TAS)处理为稳定可靠的目标航迹,并给出 TAS 跟踪波束控制指令。
> 仓库 simianzhen256-v1.5.5-ms-vscode(目录名沿用旧版本,当前代码版本为 **V1.5.6**;已由 Qt/qmake 工程迁移为 VS Code + CMake 工程,编译器为 MSVC 2022 / v143,C++17,x64 目标)。
> 仓库 simianzhen256-v1.5.5-ms-vscode(目录名沿用旧版本,当前代码版本为 **V1.5.8**;已由 Qt/qmake 工程迁移为 VS Code + CMake 工程,编译器为 MSVC 2022 / v143,C++17,x64 目标)。
>
> 版本号由 `parameters.h` 的 `MAJOR_VERSION` / `MINOR_VERSION` / `PATCH_VERSION`(当前 1.5.6)与体制后缀拼装为 `VERSION_STRING`(相扫 `V1.5.6.PS` / 机扫 `V1.5.6.MS`),实例创建后可从 `Data_Process_Factory::GetB()` 返回对象的公开成员 `version_info`(`const char*`)读取。
> 版本号由 `parameters.h` 的 `MAJOR_VERSION` / `MINOR_VERSION` / `PATCH_VERSION`(当前 1.5.8)与体制后缀拼装为 `VERSION_STRING`(相扫 `V1.5.8.PS` / 机扫 `V1.5.8.MS`),实例创建后可从 `Data_Process_Factory::GetB()` 返回对象的公开成员 `version_info`(`const char*`)读取。
---
@@ -53,20 +53,21 @@
## 2. 功能特性
- **双模式处理管线**:data_preprocess 按输入类型与扫描圈完成标志返回 0/1/2/3(TWS 以方位波位号 == 0 判为一圈完成,机扫转台反转不再误判),track_process 据此调度 TWS 凝聚/关联/起始或 TAS 凝聚/关联。
- **双模式处理管线**:data_preprocess 按输入类型与扫描圈完成标志返回 0/1/2/3,track_process 据此调度 TWS 凝聚/关联/起始或 TAS 凝聚/关联。判圈条件按扫描体制区分(3e6763c,编译期 `#ifdef PHASE_SCANNING` 隔离):**相扫**比较前后两帧方位波位号(当前波位号 ≤ 上一帧波位号即判满圈),**机扫**以「方位波位号 == 0」判满圈(规避转台反转导致的误判),详见 7.2。
- **两帧滑窗点迹凝聚**:TWS 点迹先与上一帧缓存合并凝聚,再进入关联,兼顾跨波位(CPI)相邻点迹的分裂问题;近程模式增加速度维约束。
- **逻辑法航迹起始**:每圈按固定顺序推进——① 未关联点迹先与 ≥2 点临时航迹做 EKF 波门 + 折角约束关联(延长临时航迹),② 再与 1 点航迹头做速度法关联(两点卡尔曼初始化出 2 点临时航迹),③ 两步都做完后删除被消费的点迹、剩余点迹转成新航迹头,④ 长度达标的临时航迹经三点卡尔曼初始化转可靠航迹;带起批屏蔽区与重复航迹去重。
- **3 模型 IMM 滤波**:三个 Singer 模型(低/中/高过程噪声),量测为「距离-方位-径向速度」三维的 EKF,多普勒残差按盲速折叠,似然用 3×3 新息协方差。
- **最近邻数据关联**:三模型统计距离波门 `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 航迹。关联输出的航迹同时给出**靠近/远离方向标志**:按航迹 IMM 融合速度矢量与「雷达→目标」位置矢量的夹角判定——`acos((-x·cos(Direction_Angle) − y·sin(Direction_Angle)) / r) < π/2` 置 1(靠近),否则 0(远离),等价于「滤波速度的径向分量指向雷达」,不再使用受多普勒模糊影响的实测径向速度 `vr_point`;TWS、TAS 两通道一致(见 9.6)。
- **重点目标与外推上限**:`primary_target_add` / `primary_target_cancel` 可按批号手动标记/取消重点目标,重点航迹的消亡轮数放宽到 `TRACK_DIE_ROUND_PRIMARY`(10,普通航迹 6);未关联航迹的外推圈数受限(TWS ≤ `MAX_EXTRAPOLATE_NUM`=3,TAS 相扫 5 / 机扫 48),超限后停止外推。**输出航迹只包含本圈有更新的航迹**(`Track_Update_Flag` 门控),宿主不能再用输出行数推断航迹总数(见 9.9)。
- **重点目标与外推上限**:`primary_target_add` / `primary_target_cancel` 可按批号手动标记/取消重点目标,重点航迹的消亡轮数放宽到 `TRACK_DIE_ROUND_PRIMARY`(10);未关联航迹的外推圈数受限(TWS ≤ `MAX_EXTRAPOLATE_NUM`=3,TAS 相扫 5 / 机扫 48),超限后停止外推。**输出航迹只包含本圈有更新的航迹**(`Track_Update_Flag` 门控),宿主不能再用输出行数推断航迹总数(见 9.9)。
- **航迹质量(V1.5.8)**:归一化航迹质量(0~1,内部)贯穿起始→关联→外推三阶段——临时航迹每延长一点按「统计距离 + SNR」重算,关联实点后按「统计距离 + SNR + 有效点占比」加权并指数平滑,未关联期间按未更新时长二次衰减;起批需达到**按长度分级**的最低质量,输出航迹给 0~100 的 `Quality` 字段;**普通 TWS 航迹的消亡改由质量决定**(`Quality < 0.3`),重点航迹与 TAS 航迹仍按外推圈数(见 9.11)。
- **点迹附加信息字段扩展(需同步重编译宿主)**:`DataRev` 新增 `amp_asv` / `prn_fftn`,`Track` 新增 `amp_asv_point` / `prn_fftn_point`,结构体布局随之变化,宿主必须使用同一版本头文件重新编译对接;输入侧已打通(TWS 输出有效,TAS 输出仍未写回),详见 11.2。
- **高度维独立平滑**:按距离分段选择滑动平均窗长(5/6/7/9 点),抑制俯仰测量跳变。
- **TAS 波束控制**:手动转 TAS 目标入队(队列长度与容量随扫描体制切换),按最新时间戳外推输出跟踪波束(距离/方位/俯仰/批号)。
- **航迹生命周期管理**:外推轮数计数、超时消亡、手动删除、全清空(含各模块 reset,防重连后幽灵航迹)。
- **航迹生命周期管理**:外推轮数计数、超时消亡与质量消亡(普通 TWS 航迹)、手动删除、全清空(含各模块 reset,防重连后幽灵航迹)。
- **防御性加固**:见 archived_docs/BUG_FIX_REPORT.md——越界防护、时间戳正序校验、方位角 ±π 环绕、asin 定义域钳位、IMM 概率奇异保护等已修复项。
- **日志文件输出**:`RDP_LOG_ENABLE` 定义时,首次 `Data_Process_Factory::GetB()` 自动用 `rdbuf()` 将 `std::cout` 重定向到 `RDP_LOG_DIR`(`.\rdp_logs\`)下按日期+时间命名的日志文件,`Destroy()` 时恢复控制台并关闭文件;`RDP_LOG` 日志宏在每条日志前附加 `[时间戳][文件:行号]`。该宏在 `parameters.h` 中**当前为注释状态(默认不启用)**,即默认不做重定向、日志输出到控制台(见 10.1)。
- **版本号输出**:`parameters.h` 的 `MAJOR_VERSION`/`MINOR_VERSION`/`PATCH_VERSION`(当前 1.5.6)经两级 `STRINGIFY` 宏拼成 `VERSION_STRING`(`V1.5.6.PS` / `V1.5.6.MS`);`Data_process_class_dll` 基类公开成员 `const char* version_info` 由 `Data_Process_Factory::GetB()` 在创建实例时赋值,宿主可直接读取以核对/上报 DLL 版本(b227ae1)。
- **数据记录调试功能(可选编译)**:`rdp_record` 模块把结构体按「一个记录实体一张表」写入 SQLite(一次运行一个 db 文件、多张表),结构体到表的映射由内置的 ormpp(`third_party/ormpp`,含 iguana、frozen 与 SQLite 3.49.1 amalgamation)完成;由 CMake 选项 `RDP_DATA_RECORD`(`AUTO`/`ON`/`OFF`)控制,**AUTO 时 Debug 构建启用、Release(交付)构建完全不编译**——记录模块源码不参与编译、`RDP_RECORD`/`RDP_RECORD_BATCH` 宏展开为 `((void)0)`(实参不求值),DLL 不新增依赖与导出符号、无性能损失。启用时 `GetB()` 建目录并开库(`.\rdp_records\rdp_record_YYYYMMDD_HHMMSS.db`),首次写入某实体时自动 `CREATE TABLE IF NOT EXISTS`,同步写入、失败降级(不抛出、不影响雷达处理)。当前内置 **6 张在用记录表**(输入点迹、TWS/TAS 凝聚后点迹、临时航迹、可靠航迹、点航关联信息,共 7 个实体定义、其中 1 个已停用),并新增 `point_id`/`frame_id`/`circle_id`/`temp_track_id`/`track_id` 等关联标识,可把一次处理的点迹→凝聚→临时航迹→可靠航迹→关联信息串成完整链路;新增记录数据只需「加结构体 + 注册 + 一行记录点」,详见 docs/data_record_debug.md(见 4.3、10.1、11.3)。
- **版本号输出**:`parameters.h` 的 `MAJOR_VERSION`/`MINOR_VERSION`/`PATCH_VERSION`(当前 1.5.8)经两级 `STRINGIFY` 宏拼成 `VERSION_STRING`(`V1.5.8.PS` / `V1.5.8.MS`);`Data_process_class_dll` 基类公开成员 `const char* version_info` 由 `Data_Process_Factory::GetB()` 在创建实例时赋值,宿主可直接读取以核对/上报 DLL 版本(b227ae1)。
- **数据记录调试功能(可选编译)**:`rdp_record` 模块把结构体按「一个记录实体一张表」写入 SQLite(一次运行一个 db 文件、多张表),结构体到表的映射由内置的 ormpp(`third_party/ormpp`,含 iguana、frozen 与 SQLite 3.49.1 amalgamation)完成;由 CMake 选项 `RDP_DATA_RECORD`(`AUTO`/`ON`/`OFF`)控制,**AUTO 时 Debug 构建启用、Release(交付)构建完全不编译**——记录模块源码不参与编译、`RDP_RECORD`/`RDP_RECORD_BATCH` 宏展开为 `((void)0)`(实参不求值),DLL 不新增依赖与导出符号、无性能损失。启用时 `GetB()` 建目录并开库(`.\rdp_records\rdp_record_YYYYMMDD_HHMMSS.db`),首次写入某实体时自动 `CREATE TABLE IF NOT EXISTS`,同步写入、失败降级(不抛出、不影响雷达处理)。当前内置 **6 张在用记录表**(输入点迹、TWS/TAS 凝聚后点迹、临时航迹、可靠航迹、点航关联信息,共 7 个实体定义、其中 1 个已停用),**可靠航迹与关联信息两通道均覆盖 TWS 与 TAS**(TAS 侧由 5cb67cc 补齐,关联信息以 `tas_flag` 区分来源),并新增 `point_id`/`frame_id`/`circle_id`/`temp_track_id`/`track_id` 等关联标识,可把一次处理的点迹→凝聚→临时航迹→可靠航迹→关联信息串成完整链路;新增记录数据只需「加结构体 + 注册 + 一行记录点」,详见 docs/data_record_debug.md(见 4.3、10.1、11.3)。
---
@@ -311,13 +312,13 @@ classDiagram
| Track_Asso | TWS 点航关联 + IMM 滤波:模型交互 → 门限筛选(NN)→ 各模型 EKF → 概率更新 → 模型输出(只输出 `Track_Update_Flag==1` 的航迹);未关联航迹按上限外推;高度平滑;按滤波速度矢量写 `Flag_Direction`;ΔT≤0(乱序/重复时间戳)的候选取出后不更新滤波、不刷新航迹,仅消费该点迹 |
| Track_Asso_Tas | TAS 航迹关联(只处理指定批号 tas_track_idx,门限与 TWS 略有差异;输出同样受 `Track_Update_Flag` 门控,外推上限 `MAX_EXTRAPOLATE_NUM_TAS` 的判定方向与 TWS 相反) |
| Track_Init | 逻辑法航迹起始,每圈顺序固定:点-临时航迹关联(延长 ≥2 点临时航迹)→ 点-航迹头关联(两点起始)→ 剩余点转新航迹头 → 长度达标者起批(三点卡尔曼初始化);另含起批屏蔽区判断与临时航迹消亡 |
| Track_Die / Track_Die_Tas | 可靠航迹消亡:未关联轮数超限(普通 TWS 6 圈 / 重点航迹 10 圈 / TAS 相扫 10、机扫 96)或手动删除标志置位时输出消亡批号并删除 |
| Track_Die / Track_Die_Tas | 可靠航迹消亡:**TWS 普通航迹按航迹质量**(V1.5.8:`Quality < 0.3`)、TWS 重点航迹按未关联轮数(10)、TAS 按未关联轮数(相扫 10、机扫 96),或手动删除标志置位时输出消亡批号并删除 |
| TAS_Ctrl | TAS 波束控制:手动目标入队(tas_target_add)、失效目标出队(tas_target_del)、跟踪波束预测输出(tas_beam_output:数据率门控 + 队内选择最早 CPI 目标)、调度时刻记录(last_track_time) |
| Track_Ind_Mangement | 航迹号 1~500 的顺序分配与回绕复用 |
| kalman | 两点/三点滤波初始化、线性卡尔曼预测/滤波、EKF(3 维量测含多普勒)、马氏统计距离 d、盲速 Bind_speed |
| coor_trans | 极坐标 ↔ 直角坐标转换 |
| rdp_log(rdp_log.h/.cpp) | 日志输出:按 parameters.h 的 `RDP_LOG_ENABLE` 开关,在 `Init()` 中用 `rdbuf()` 将 `std::cout` 重定向到日期+时间命名的日志文件、`Shutdown()` 恢复控制台并关闭;提供 `RDP_LOG` 宏自动附加 `[时间戳][文件:行号]` 前缀 |
| rdp_record(rdp_record.h/.cpp、rdp_record_entity.h) | 数据记录调试(可选编译):由 CMake 选项 `RDP_DATA_RECORD` 决定是否参与编译;开启时把「记录实体」(结构体)经内置 ormpp 映射写入 SQLite 表(一实体一表,首次写入自动 `CREATE TABLE IF NOT EXISTS`,一次运行一个 db 文件),`RDP_RECORD`/`RDP_RECORD_BATCH` 记录点宏在关闭时展开为空操作;`Init()`/`Shutdown()` 由工厂的 `GetB()`/`Destroy()` 调用;建表/插入失败一律降级(每个实体只提示一次),不影响雷达处理。**当前 7 个实体定义、6 张在用表**:`RdpRecPoint`(输入点迹,TWS/TAS 共用)、`RdpRecPointCohesionTWS`、`RdpRecPointCohesionTAS`、`RdpRecTempTrack`、`RdpRecTrustTrack`、`RdpRecAssoInfo`(另有已停用的 `RdpRecTrackOut`),并有数组转字符串辅助 `arrayToString()`(用于把 `X`/`P` 等状态数组存为文本列) |
| rdp_record(rdp_record.h/.cpp、rdp_record_entity.h) | 数据记录调试(可选编译):由 CMake 选项 `RDP_DATA_RECORD` 决定是否参与编译;开启时把「记录实体」(结构体)经内置 ormpp 映射写入 SQLite 表(一实体一表,首次写入自动 `CREATE TABLE IF NOT EXISTS`,一次运行一个 db 文件),`RDP_RECORD`/`RDP_RECORD_BATCH` 记录点宏在关闭时展开为空操作;`Init()`/`Shutdown()` 由工厂的 `GetB()`/`Destroy()` 调用;建表/插入失败一律降级(每个实体只提示一次),不影响雷达处理。**当前 7 个实体定义、6 张在用表**:`RdpRecPoint`(输入点迹,TWS/TAS 共用)、`RdpRecPointCohesionTWS`、`RdpRecPointCohesionTAS`、`RdpRecTempTrack`、`RdpRecTrustTrack`、`RdpRecAssoInfo`(后两者 **TWS 与 TAS 两通道均写入**,关联信息以 `tas_flag` 区分来源;另有已停用的 `RdpRecTrackOut`),并有数组转字符串辅助 `arrayToString()`(用于把 `X`/`P` 等状态数组存为文本列) |
| Track_Init_Direct_Tracking / Track_Asso_Direct_Tracking | 引导跟踪(direct tracking)专用起批/关联。**当前入口为空实现、未启用**;track_asso_direct_tracking.cpp 未加入 CMake 源列表 |
---
@@ -329,7 +330,7 @@ classDiagram
| 结构体 | 用途 | 要点 |
|---|---|---|
| DataRev | 输入点迹 | 距离(m)、方位/俯仰(°)、速度(m/s)、幅度/门限/SNR/RCS、码盘值、CPI/GNSS 时间(ms, long long)、方位波位(0-24)/俯仰波位(0-13)、PRI(µs,**不允许为 0**)、频点号、点数、点迹号、使用标记、TAS 批号、点迹类型、归一化幅度 `amp_asv`(dB)、速度维 FFT 点数 `prn_fftn`、十字星数据 speed_dim[129]/range_dim[8] |
| Track | 输出航迹 | 位置/速度、极坐标量、航迹号、更新点数、方向标志 Flag_Direction(仅关联/外推输出路径赋值:按滤波速度矢量判定,1 靠近 / 0 远离,见 9.6;起批输出不写该字段)、实虚点标志 Flag_Point、一步预测、跟踪模式、航向角 Direction_Angle、目标类型、关联点信息、归一化幅度 `amp_asv_point` / 速度维 FFT 点数 `prn_fftn_point`、航迹时间(s)/GNSS、SNR/RCS、十字星数据透传 |
| Track | 输出航迹 | 位置/速度、极坐标量、**航迹质量 `Quality`(0~100,V1.5.8 新增;插在 `Amplitude` 之后,宿主需同步重编译)**、航迹号、更新点数、方向标志 Flag_Direction(仅关联/外推输出路径赋值:按滤波速度矢量判定,1 靠近 / 0 远离,见 9.6;起批输出不写该字段)、实虚点标志 Flag_Point、一步预测、跟踪模式、航向角 Direction_Angle、目标类型、关联点信息、归一化幅度 `amp_asv_point` / 速度维 FFT 点数 `prn_fftn_point`、航迹时间(s)/GNSS、SNR/RCS、十字星数据透传 |
| TrackingBeam | TAS 跟踪波束指令 | open_flag、type、Range、Azi、Elev、TAS_track_index |
| Target_direct_tracking | 引导跟踪信息 | 批号、距离/方位/俯仰、开关(接口未启用) |
| RadarPara | 工作参数 | 见 [参数说明](#10-参数说明) |
@@ -339,15 +340,15 @@ classDiagram
| 结构体 | 用途 | 关键字段 |
|---|---|---|
| PointRecv | 内部点迹 | 距离/方位(弧度)/速度/幅度/高度/SNR/RCS/CPI/GNSS 时间、点迹号 `point_id` / 帧号 `frame_id` / 圈号 `circle_id`(记录链路用,c3c7e66 新增)、使用标志、波位/PRF/频点、跟踪模式、点迹区号、归一化幅度 `amp_asv_point` / 速度维 FFT 点数 `prn_fftn_point`、十字星数据 |
| Trust_Track | 可靠航迹(IMM 全状态) | 航迹号、标识字段 `track_id` / `point_id` / `circle_id`(b227ae1 新增,起批时取临时航迹末点的 `temp_track_id`/`point_id`/`circle_id`,关联成功时刷新为被关联点迹的 ID)、高度、极坐标量快照 `Range` / `Azimuth` / `Elevation` / `Velocity`(b227ae1 新增,仅在本圈有输出时回填)、航迹时间、更新标志 Track_Update_Flag(**输出门控**:仅置 1 的航迹当圈被输出,输出后清零)、外推轮数 Extrapolate_round、实虚点标志、手动删除/手动 TAS/重点目标(primary_target_flag,决定消亡用 6 还是 10 圈)标志、关联点数、高度平滑缓冲 Hight_smooth、关联点信息、归一化幅度 `amp_asv_point` / 速度维 FFT 点数 `prn_fftn_point`、融合状态 X[6]/P[6][6]、三个子模型 X1/X2/X3、P1/P2/P3、模型概率 u[3] |
| Temp_track | 临时航迹(航迹起始阶段) | 4 维状态 X[4]/P[4][4]、极坐标点信息(`r`/`azi`/`vr`/`height`/`SNR`/`RCS`/`amplitude`)、时间戳 `CPI_time` / `GNSS_time`、`buff_round`(已缓存圈数)、标识字段 `temp_track_id` / `point_id` / `circle_id`、区号 `temp_track_section_idx`、俯仰波位号 `pitch_num`、关联标志(c3c7e66 起字段统一更名,如原 `snr`/`Amp`/`T`) |
| Asso_Info | 点航关联候选(track_asso.cpp 使用) | `point_id` / `track_id` / `circle_id`、三模型统计距离 `d1`/`d2`/`d3` 与最小值 `d_min`、点迹/航迹下标、`delta_T`/`delta_h`/`R`/`VT`、门限判定结果 `thd_d`/`thd_h`/`thd_r`、是否被最近邻取中 `min_d_flag`(b227ae1 由局部结构体提升到 struct.h,用于记录 `RdpRecAssoInfo`) |
| Trust_Track | 可靠航迹(IMM 全状态) | 航迹号、标识字段 `track_id` / `point_id` / `circle_id`(b227ae1 新增,起批时取临时航迹末点的 `temp_track_id`/`point_id`/`circle_id`,关联成功时刷新为被关联点迹的 ID)、高度、极坐标量快照 `Range` / `Azimuth` / `Elevation` / `Velocity`(b227ae1 新增,仅在本圈有输出时回填)、**航迹质量相关状态(V1.5.8 新增)`Quality`(0~1)/ `Point_sum`(累计点数,含外推)/ `Valid_point_sum`(累计实点关联次数)/ `Unupdated_time`(连续未关联实点的累计毫秒)**、航迹时间 `T_track`(CPI 时间)/ `GNSS_time`、更新标志 Track_Update_Flag(**输出门控**:仅置 1 的航迹当圈被输出,输出后清零)、外推轮数 Extrapolate_round、实虚点标志、手动删除/手动 TAS/重点目标(primary_target_flag,决定消亡走质量还是 10 圈轮数)标志、关联点数、高度平滑缓冲 Hight_smooth、关联点信息、归一化幅度 `amp_asv_point` / 速度维 FFT 点数 `prn_fftn_point`、融合状态 X[6]/P[6][6]、三个子模型 X1/X2/X3、P1/P2/P3、模型概率 u[3] |
| Temp_track | 临时航迹(航迹起始阶段) | 4 维状态 X[4]/P[4][4]、极坐标点信息(`r`/`azi`/`vr`/`height`/`SNR`/`RCS`/`amplitude`)、**航迹质量 `quality`(0~1,V1.5.8 新增,起批时带给 Trust_Track)**、时间戳 `CPI_time` / `GNSS_time`、`buff_round`(已缓存圈数)、标识字段 `temp_track_id` / `point_id` / `circle_id`、区号 `temp_track_section_idx`、俯仰波位号 `pitch_num`、关联标志(c3c7e66 起字段统一更名,如原 `snr`/`Amp`/`T`) |
| Asso_Info | 点航关联候选(track_asso.cpp / track_asso_tas.cpp 共用) | `point_id` / `track_id` / `circle_id`、三模型统计距离 `d1`/`d2`/`d3` 与最小值 `d_min`、点迹/航迹下标、`delta_T`/`delta_h`/`R`/`VT`、来源标志 `tas_flag`(1 TAS / 0 TWS,5cb67cc 新增)、门限判定结果 `thd_d`/`thd_h`/`thd_r`、是否被最近邻取中 `min_d_flag`(b227ae1 提升到 struct.h;TAS 侧 5cb67cc 起改用同一结构) |
| Tracking_Target | TAS 队列元素 | 批号 Index、空标志 empty_flag、最近波束输出时间 last_track_time |
| Direct_Tracking_Target | 引导跟踪目标 | ID、方位/俯仰/距离、空标志 |
> 说明:Trust_Track 的状态布局为 [x, vx, ax, y, vy, ay],x/y 两轴解耦,每轴为「位置-速度-加速度」。
>
> ⚠ **结构体布局变更**:`DataRev` 新增 `amp_asv` / `prn_fftn`,`Track` 新增 `amp_asv_point` / `prn_fftn_point`,内部 `PointRecv` / `Trust_Track` / `Temp_track` 亦有新增与更名字段。宿主与 DLL 必须使用同一版本头文件并**同步重新编译**,否则字段错位。对外结构体(`data_process_class_dll.h`)在本版中仅新增了基类成员 `version_info`,`DataRev` / `Track` / `RadarPara` 布局自 1.5.5 起未再变化。
> ⚠ **结构体布局变更**:`DataRev` 新增 `amp_asv` / `prn_fftn`,`Track` 新增 `amp_asv_point` / `prn_fftn_point`;**V1.5.8 起 `Track` 又在 `Amplitude` 之后插入 `Quality`(之后字段整体后移)**,内部 `Trust_Track` / `Temp_track` 新增质量相关字段。宿主与 DLL 必须使用同一版本头文件并**同步重新编译**,否则字段错位。对外结构体中 `DataRev` / `RadarPara` 布局自 1.5.5 起未变化。
---
@@ -359,7 +360,7 @@ classDiagram
|---|---|---|
| Data_Process_Factory::GetB() | 实例指针 | 获取单例(首次调用时创建,并写入 `version_info`) |
| Data_Process_Factory::Destroy() | — | 销毁实例并将指针置空 |
| version_info(基类公开成员) | `const char*` | DLL 版本字符串,由 `GetB()` 赋值为 `VERSION_STRING`(相扫 `V1.5.6.PS` / 机扫 `V1.5.6.MS`);只读使用,不要释放(b227ae1) |
| version_info(基类公开成员) | `const char*` | DLL 版本字符串,由 `GetB()` 赋值为 `VERSION_STRING`(相扫 `V1.5.8.PS` / 机扫 `V1.5.8.MS`);只读使用,不要释放(b227ae1) |
| track_process_parameters_initial(RadarPara) | 0 成功 / -1 失败 | 初始化工作参数;校验 3 ≤ track_start_point_num ≤ 9 |
| track_process_parameters_modify(RadarPara) | 0 / -1 | 运行时修改参数(校验同上) |
| data_preprocess(DataRev[150]) | 0/1/2/3 | 输入一帧点迹并缓存,返回处理模式(见下表) |
@@ -370,7 +371,7 @@ classDiagram
| tracking_start(track_index) | 0 | 手动转 TAS 跟踪(置 manual_tracking_flag,由 Beam_Ctrl 入队) |
| tracking_stop(track_index) | 0 | 手动取消 TAS(清标志并 Track_Mode=0;队列项延至下一次 Beam_Ctrl 移除) |
| primary_target_add(track_index) | 0 | 手动将指定批号标为**重点目标**(置 `primary_target_flag=1`,消亡轮数放宽到 10 圈;批号不存在时不报错、无副作用) |
| primary_target_cancel(track_index) | 0 | 取消指定批号的重点目标标记(置 `primary_target_flag=0`,恢复普通消亡轮数) |
| primary_target_cancel(track_index) | 0 | 取消指定批号的重点目标标记(置 `primary_target_flag=0`,恢复普通航迹的消亡判据——V1.5.8 起为 `Quality < 0.3`) |
| tracking_point(azimuth) | 0 | 手动打跟踪波束——**未实现(保留空实现)** |
| direct_tracking_process(...) | 0 | 引导跟踪——**未实现(保留空实现)** |
@@ -385,11 +386,11 @@ classDiagram
| 返回值 | 含义 | 触发条件 |
|---|---|---|
| 0 | 无效数据 | point_type 既非 0 也非 1 |
| 1 | **TWS 满一圈,执行航迹处理** | point_type==0 且当前帧方位波位号 == 0(7d5a56f 起改用波位号为 0 判满圈:机扫转台反转时波位号会变小但并未扫完一圈,原「波位号变小」判据会误判) |
| 2 | **TWS 未满一圈,继续蓄数据** | point_type==0 且方位波位号 != 0;调用 track_process(model=2) 做滑窗凝聚 |
| 1 | **TWS 满一圈,执行航迹处理** | point_type==0 且判圈条件成立:**相扫**(`PHASE_SCANNING`)当前帧方位波位号 ≤ 上一帧波位号 `last_beam_num`;**机扫**(`MECHANICAL_SCANNING`)当前帧方位波位号 == 0 |
| 2 | **TWS 未满一圈,继续蓄数据** | point_type==0 且上述判圈条件不成立;调用 track_process(model=2) 做滑窗凝聚 |
| 3 | **TAS 处理** | point_type==1;同时记录 TAS_track_idx 与最新时间戳 |
> 7d5a56f 起满圈判据不再依赖上一帧波位号:`last_beam_num` 仍被赋值(`track_clear_all()` 复位为 INT_MAX),但不参与判断;因此首帧是否返回 1 取决于该帧方位波位号是否为 0。调用方需保证方位波位号按 0~Beam_num-1 编号且每圈均出现 0,否则 TWS 通道将持续返回 2(不满圈)。
> **判圈条件按体制区分(3e6763c)**:源码用 `#ifdef PHASE_SCANNING` 把两条判据编译期隔离——相扫走「波位号不变大(当前 ≤ 上一帧)即为新一圈」的判据(`last_beam_num` 参与判断,`track_clear_all()` 复位为 INT_MAX,故**相扫首帧即返回 1**);机扫保持 7d5a56f 的「方位波位号 == 0」判据(机扫转台反转时波位号会变小但并未扫完一圈,用波位号比较会误判),此分支下 `last_beam_num` 仍被赋值但不参与判断。因此同一份源码按体制构建出的判圈行为不同,调用方需按实际体制提供对应的波位号序列:相扫要求每圈波位号先增后回到起点、机扫要求每圈均出现 0。
### 7.3 典型调用序列
@@ -421,7 +422,7 @@ flowchart TD
```mermaid
flowchart TD
A["data_preprocess: 点迹入 Data_buffer(度→弧度、高度=Range·sin(Elev)、时间戳缓存)"] --> B["方位波位号 == 0(一圈完成)→ model=1"]
A["data_preprocess: 点迹入 Data_buffer(度→弧度、高度=Range·sin(Elev)、时间戳缓存)"] --> B["判圈成立(相扫: 波位号 ≤ 上一帧 / 机扫: 波位号 == 0)→ model=1"]
B --> C["track_process(1)"]
C --> D["dot_coh 两帧滑窗凝聚 → point_recv"]
D --> E["track_asso: IMM 交互 → 点航波门筛选(NN)→ EKF 滤波 → 模型输出"]
@@ -547,7 +548,7 @@ $$
\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)重新得到。
关联成功后**复制原临时航迹并追加该点迹**,新航迹的 4 维状态用最近两点做**两点卡尔曼初始化**(见 9.5.2)重新得到。同一处(V1.5.8 起)随即重算该临时航迹的**航迹质量**:长度恰为 3 时对三点写入同一质量值,长度 >3 时只更新末点(指数平滑),详见 9.11。
#### (2) 点-航迹头关联(两点起始)
@@ -572,11 +573,12 @@ $$
#### (4) 转可靠航迹(起批)
临时航迹长度 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 个)**且航迹质量达到该长度对应的门限**(V1.5.8 新增,见 9.11)时进入起批队列;同源(前三点时间/距离相同)的重复航迹只保留 d 较小者(比较下标 `track_start_point_num-1` 处的 d)。起批时令 L = track_start_point_num,用航迹中下标 L-3、L-2、L-1 的三个点做 **三点卡尔曼初始化** 得到 6 维状态(航迹长度恰为 L 时即最近三点),构造 Trust_Track:
- 三个 IMM 子模型用同一状态/协方差初始化,模型概率 u = [1/3, 1/3, 1/3];
- 质量状态初始化:`Quality` = 临时航迹末点质量,`Point_sum` = `Valid_point_sum` = L,`Unupdated_time` = 0;
- 分配航迹号(1~500,见 9.8);
- 输出仅写入前 L 个历史点(`Trust_Track_Output[i][0..L-1]`,`Point_Sum = L`),航迹长度大于 L 时其余点不输出;
- 输出仅写入前 L 个历史点(`Trust_Track_Output[i][0..L-1]`,`Point_Sum = L`),每点写入 `Quality = 该点临时航迹质量 × 100`;航迹长度大于 L 时其余点不输出;
- 起批输出不写 `Flag_Direction`、`x_Predict/y_Predict/z_Predict`、`Range_Predict/Azimuth_Predict/Elevation_Predict`、`Target_Type`、`prf_point`、`v_z` 等字段,且 DLL 不清零输出数组,宿主读到的是自身缓存的旧值(详见 docs/track_init_readme.md 第 14 节)。
### 9.4 IMM 框架(3 个 Singer 模型)
@@ -841,24 +843,26 @@ $$
#### 外推
- **TWS**:未关联到实点的航迹(`manual_tracking_flag==0`)按工作模式数据率 DATA_RATE_SHORT/MIDDLE/FAR 预测一帧(ΔT≤0 的候选虽被消费但未刷新航迹状态,其 `point_flag` 仍为 0,故同样在本环节外推,见 9.6)。预测用各子模型 Singer F/Qj 推进,`Extrapolate_round+1`,`point_flag=0`(虚点/补点),航迹时间同步推进,并置 `Track_Update_Flag=1`(本圈输出)。
> **时间差取值(56b5449 → b4aed8a)**:56b5449 曾把 TWS 外推的 ΔT 改为按最新时间戳实时计算(`(latest_timestamp − T_track)/1000`,并对 `ΔT ≤ 0` 跳过),b4aed8a 已**回调**为按 `work_mode` 取固定数据率(原因:按最新时间戳推进会在 TAS 工作时同步外推出 TWS 航迹)。因此 `track_asso_process()` 与 `model_filter()` 虽接收 `latest_timestamp` 形参,但当前不参与 ΔT 计算(实时计算的两行代码以注释保留在源码中)。
- **TWS 外推上限(50e0b5c)**:仅当 `Extrapolate_round <= MAX_EXTRAPOLATE_NUM`(=3)时才做上述预测;超过上限后不再推进位置与航迹时间,只执行 `Extrapolate_round+1`、`point_flag=0`、`Track_Update_Flag=0`——该航迹当圈不输出、位置冻结在最后一次预测处,直到重新关联到实点(`Extrapolate_round` 清零)才恢复。目的是避免长时间未关联的航迹被反复外推到远处。
- **TAS**:按 `latest_timestamp − T_track` 预测(ΔT ≤ 0 跳过),航迹时间推进到最新时间戳。上限判定为 `Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS`(相扫 5 / 机扫 48)时才预测并输出,未达该轮数时只累加 `Extrapolate_round` 且不输出(位置与航迹时间停在最后一次关联处)。⚠ 判定方向与 TWS 的 `<=` 相反,见 11.2。
- **质量衰减(V1.5.8)**:本环节对每条未关联航迹(不论是否已超外推上限)按未更新时长降低 `Quality`,`Unupdated_time` 同步累加,因此**超限后航迹虽不再输出,质量仍在下降**,直到触发质量消亡(见下)。因为 ΔT 已移到上限判断之外计算,这一衰减在上限内/外都按 `work_mode` 的数据率推进。
- **TAS**:按 `latest_timestamp − T_track` 预测(ΔT ≤ 0 跳过),航迹时间推进到最新时间戳。上限判定为 `Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS`(相扫 5 / 机扫 48)时才预测并输出,未达该轮数时只累加 `Extrapolate_round` 且不输出(位置与航迹时间停在最后一次关联处)。⚠ 判定方向与 TWS 的 `<=` 相反,见 11.2。TAS 通道**不维护航迹质量**(`track_asso_tas.cpp` 未更新 `Quality`),消亡仍按外推圈数。
- **输出门控**:`track_asso_process()` / `track_asso_process_tas()` 的输出循环只写 `Track_Update_Flag==1` 的航迹,写完即清零;因此「本圈未更新」的航迹(外推超限等)不会出现在 `Trust_Track_Output` 中。
#### 消亡(track_die.cpp / track_die_tas.cpp)
判据为 `Extrapolate_round > 阈值`(50e0b5c 起由 `>=` 改为 `>`),满足其一即消亡:
**TWS 普通航迹自 V1.5.8 起改为按航迹质量消亡**(`Quality < TRACK_DIE_QUALITY` = 0.3),其余通道仍按外推圈数(判据 `Extrapolate_round > 阈值`,50e0b5c 起由 `>=` 改为 `>`),满足其一即消亡:
| 通道 | 条件 |
|---|---|
| TWS 普通航迹 | Track_Mode==0 且 primary_target_flag==0 且 Extrapolate_round > TRACK_DIE_ROUND(=6) |
| TWS 普通航迹 | Track_Mode==0 且 primary_target_flag==0 且 **Quality < TRACK_DIE_QUALITY(=0.3)**(V1.5.8,782bff5) |
| TWS 重点航迹 | Track_Mode==0 且 primary_target_flag==1 且 Extrapolate_round > TRACK_DIE_ROUND_PRIMARY(=10) |
| TAS 航迹 | Track_Mode==1 且 Extrapolate_round > TRACK_DIE_ROUND_TAS(相扫 10 / 机扫 96) |
| 任意航迹 | manual_delete_flag==1(手动删除标记,不区分通道) |
消亡批号写入 Track_die_Index_Output 并删除本地航迹。由于 `Extrapolate_round` 每圈未关联只自增 1,普通 TWS 航迹实际连续 7 圈无实点关联才消亡(重点航迹 11 圈;TAS 相扫 11 圈 / 机扫 97 圈)。`track_process()` 中的调用顺序为 `track_asso → track_die → track_init`(data_process.cpp),即消亡先于航迹起始执行。
消亡批号写入 Track_die_Index_Output 并删除本地航迹。重点航迹实际连续 11 圈无实点关联才消亡(TAS 相扫 11 圈 / 机扫 97 圈,因 `Extrapolate_round` 每圈未关联只自增 1);普通 TWS 航迹的存活时长改为由质量衰减速度决定——未关联时间越长衰减越快,`Quality` 降到 0.3 以下即消亡,不再有固定圈数上限(`TRACK_DIE_ROUND` 仍定义但已不被引用,见 10.1)。`track_process()` 中的调用顺序为 `track_asso → track_die → track_init`(data_process.cpp),即消亡先于航迹起始执行。
> 重点目标标记(`primary_target_add` / `primary_target_cancel`)只影响消亡轮数,不改变关联、滤波、波束控制等其他环节,也不体现在输出航迹字段中。
> 重点目标标记(`primary_target_add` / `primary_target_cancel`)在 TWS 上决定「按质量消亡(普通)」还是「按 10 圈轮数消亡(重点)」,不改变关联、滤波、波束控制等其他环节,也不体现在输出航迹字段中。
### 9.10 TAS 波束控制(tas_ctrl.cpp)
@@ -878,11 +882,54 @@ $$
- tas_ctrl_process 入口强制 *Trust_track_num_Output=0 并在写入前检查容量,防止输出数组越界(BUG-09 修复)。
### 9.11 航迹质量(V1.5.8,1ae0cf2 / d9a7bd0 / 4b70b24 / 782bff5)
内部质量 `Quality` 为 **0~1** 的归一化值(`Temp_track::quality`、`Trust_Track::Quality`),输出时乘 `TRACK_QUALITY_MAX`(100)折算为 **0~100** 写入 `Track.Quality`。它贯穿「临时航迹 → 起批 → 关联 → 外推 → 消亡」全过程,是普通 TWS 航迹**自动**消亡的唯一依据。
**三个公共分量**
| 分量 | 公式 | 说明 |
|---|---|---|
| 统计距离项 `d_tmp` | `exp(−d)` | `d` 为所选点迹的最近邻统计距离(TWS 为三模型 `d_min`;临时航迹为末点 `d`) |
| SNR 项 `snr_tmp` | `1/(1+exp(−(SNR−16)/1.2))` | 以 16 为中心、尺度参数 1.2 的 Sigmoid,SNR 越高越接近 1 |
| 长度项 `len_tmp` | `sigmoid((Valid_point_sum−4)/1.2)×0.5 + (1 − Valid_point_sum/Point_sum)×0.5` | 仅在关联更新时使用;两项各占 0.5,衡量「已积累实点数」与「实点占比」 |
**① 临时航迹阶段(`track_init.cpp::point_temp_track_asso()`)**:每成功延长一个点后重算——`quality_tmp = (0.5·d_tmp + 0.3·snr_tmp)/(0.5+0.3)`(只用距离与 SNR 两项,不含长度项)。
- 长度 L = 3:SNR 取三点平均,`quality_tmp` **写满三个点**;
- 长度 L > 3:SNR 只取末点,末点质量 = `前一点质量×0.8 + quality_tmp×0.2`(指数平滑,`TRACK_QUALITY_ITER_COEFF`)。
**② 关联更新(`track_asso.cpp::model_filter()`)**:关联到实点并完成 IMM/EKF 更新后,用 `tq = 0.5·d_tmp + 0.3·snr_tmp + 0.2·len_tmp` 求即时质量,再 `Quality = Quality×0.8 + tq×0.2`;随后 `Point_sum++`、`Valid_point_sum++`(**质量用的是自增前的计数**),`Unupdated_time` 清零。注意 `Valid_point_sum/Point_sum` 为**整数除法**(先截断再乘 0.5)。
**③ 外推衰减(`track_asso.cpp::model_filter()` 外推环节)**:按累计未更新时长做二次衰减。记 `t = Unupdated_time/1000`(秒),每次先 `Quality -= f(t_old)`、执行 `Unupdated_time += ΔT`、再 `Quality += f(t_new)`,净效果为 `Quality += [f(t_new) − f(t_old)]`(即 `Quality -= [f(t_old) − f(t_new)]`),其中
$$
f(t)=O_2\,t^2+O_1\,t,\qquad O_2=-0.0008,\; O_1=-0.0025
$$
因两系数为负,`f` 单调递减,故每圈质量下降 `0.0008\,(t_{new}^2-t_{old}^2)+0.0025\,(t_{new}-t_{old})`——**未关联越久、衰减越快**;结果钳位到 ≥0。该衰减在上限内/外都会执行(见 9.9)。
**④ 起批门限(`tmp_track_to_trust_track()`)**:除长度 3~10 与屏蔽区判断外,按长度取最低质量:
| 航迹长度 L | 3 | 4 | 5 | 6 | ≥7 |
|---|---|---|---|---|---|
| 最低质量 | 0.7 | 0.6 | 0.5 | 0.4 | 0.3 |
不达标的本圈不起批,临时航迹继续留在表中积累(受 `buff_round`/长度 10 的临时航迹消亡约束)。
**⑤ 消亡(`track_die.cpp`)**:普通 TWS 航迹 `Quality < TRACK_DIE_QUALITY`(0.3)即消亡;重点航迹与 TAS 航迹仍按外推圈数(见 9.9)。
> 参数全部集中在 `parameters.h` 的「通用数据处理参数」段(两种扫描体制共用):`TRACK_QUALITY_MAX/MIN`、`TRACK_QUALITY_D_WEIGHT`(0.5) / `SNR_WEIGHT`(0.3) / `LEN_WEIGHT`(0.2)、`TRACK_QUALITY_ITER_COEFF`(0.8)、`TRACK_QUALITY_DECREASE_COEFF_O2/O1`、`TRACK_START_QUALITY_L3~L7`、`TRACK_DIE_QUALITY(_PRAMARY)`。
>
> 已知局限(详见 11.2):TAS 通道不维护质量;`TRACK_QUALITY_MIN`、`TRACK_DIE_QUALITY_PRAMARY`、`TRACK_DIE_ROUND` 当前定义但未参与计算;起批质量门限按**临时航迹长度**取值,而实际起批只用末点质量。
---
## 10. 参数说明
### 10.1 编译期宏(parameters.h,随扫描体制切换)
### 10.1 编译期宏(parameters.h)
`parameters.h` 分为「通用数据处理参数」段(两种体制共用,V1.5.8 的航迹质量参数即在此段)与 `#ifdef MECHANICAL_SCANNING` / `#ifdef PHASE_SCANNING` 两段(随体制取不同值)。下表「同左」表示两体制取值相同。
| 宏 | 相扫 PHASE_SCANNING | 机扫 MECHANICAL_SCANNING | 含义 |
|---|---|---|---|
@@ -898,7 +945,13 @@ $$
| R_MIN / R_MAX | 100 / 100000 | 同左 | 有效量程(m) |
| TRACK_START_THRESHOLD | 8 | 同左 | 起批波门(d² 门限 64;越大越容易起批) |
| ALPHA_START | 60 | 同左 | 起批折角(°) |
| TRACK_DIE_ROUND | 6 | 6 | TWS **普通**航迹消亡圈数(判据 Extrapolate_round > 6;50e0b5c 起由 4 调整为 6,判据由 ≥ 改为 >) |
| TRACK_DIE_ROUND | 6 | 6 | **已不被引用**:V1.5.8 起 TWS 普通航迹改按质量消亡(见下行),该宏仍定义但代码中无使用 |
| TRACK_DIE_QUALITY | 0.3 | 0.3 | TWS **普通**航迹消亡质量门限(`Quality < 0.3` 即消亡;V1.5.8 新增,与体制无关) |
| TRACK_START_QUALITY_L3 / L4 / L5 / L6 / L7 | 0.7 / 0.6 / 0.5 / 0.4 / 0.3 | 同左 | 起批最低质量(按临时航迹长度 3/4/5/6/≥7 取值;V1.5.8 新增) |
| TRACK_QUALITY_MAX / MIN | 100 / 0 | 同左 | 质量折算上限(输出 `Track.Quality` = 内部质量×100)/ 下限(**当前未使用**) |
| TRACK_QUALITY_D_WEIGHT / SNR_WEIGHT / LEN_WEIGHT | 0.5 / 0.3 / 0.2 | 同左 | 质量三要素权重:统计距离 / SNR / 有效点占比(V1.5.8 新增) |
| TRACK_QUALITY_ITER_COEFF | 0.8 | 同左 | 质量指数平滑系数(`新 = 旧×0.8 + 即时×0.2`) |
| TRACK_QUALITY_DECREASE_COEFF_O2 / O1 | −0.0008 / −0.0025 | 同左 | 质量衰减二次项 / 一次项系数(负值;随未更新时间 `t` 累计,见 9.11) |
| TRACK_DIE_ROUND_PRIMARY | 10 | 10 | TWS **重点航迹**消亡圈数(primary_target_flag==1 时套用;50e0b5c 新增) |
| TRACK_DIE_ROUND_TAS | 10 | 96 | TAS 航迹消亡圈数(判据 Extrapolate_round > 阈值;相扫 50e0b5c 起由 5 调整为 10,机扫保持 96) |
| MAX_EXTRAPOLATE_NUM | 3 | 3 | TWS 未关联航迹最大外推圈数(Extrapolate_round ≤ 3 才继续外推;50e0b5c 新增) |
@@ -939,8 +992,8 @@ $$
- **越界/防御**: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)。
- **数值稳定性**:方位残差 ±π 环绕(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)。
- **后修订(50e0b5c、fc49707、42b598e、e8c56f9,BUG_FIX_REPORT.md 成文之后)**:输出航迹增加 `Track_Update_Flag` 门控(只输出本圈有更新的航迹);未关联航迹外推增加圈数上限;消亡判据改为 `>`,正常/重点航迹分别定为 6 / 10 圈(TAS 相扫 10、机扫 96);`Flag_Direction` 改用滤波速度矢量判定,修复速度模糊时的向站/背站误判;手动操作接口补 `break`;`DataRev`/`Track` 新增归一化幅度与速度维 FFT 点数字段(输入侧其后已打通,TAS 输出仍未写回,见 11.2)。
- **后修订(e0bf227,BUG_FIX_REPORT.md 成文之后)**:TWS 关联高度门限由注释状态改为实际生效(`track_asso.cpp`),统计距离/高度/距离三类判据拆为独立布尔量,`ASSO_THORD` 由 3 调大至 4;TAS 关联高度门限 2000~3000 m 段放宽至 250 m;修复 `tas_beam_output()` 数据率门控误判(详见 CHANGELOG 的 [1.5.8] 与 9.6、9.10)。
- **后修订(50e0b5c、fc49707、42b598e、e8c56f9,BUG_FIX_REPORT.md 成文之后)**:输出航迹增加 `Track_Update_Flag` 门控(只输出本圈有更新的航迹);未关联航迹外推增加圈数上限;消亡判据改为 `>`,正常/重点航迹分别定为 6 / 10 圈(TAS 相扫 10、机扫 96;**普通 TWS 航迹的 6 圈判据已于 V1.5.8 改为质量消亡,见 11.2**);`Flag_Direction` 改用滤波速度矢量判定,修复速度模糊时的向站/背站误判;手动操作接口补 `break`;`DataRev`/`Track` 新增归一化幅度与速度维 FFT 点数字段(输入侧其后已打通,TAS 输出仍未写回,见 11.2)。
### 11.2 有意保留 / 未修复(archived_docs/BUG_REPORT.md 标注项 + 后续源码观察)
@@ -959,6 +1012,10 @@ $$
- **归一化幅度 / 速度维 FFT 点数(e8c56f9 新增,输入侧已打通)**:`data_preprocess()` 现已在 TWS、TAS 两条分支都把 `DataRev.amp_asv` / `DataRev.prn_fftn` 拷入内部 `PointRecv`(`data_process.cpp`,并随 `RdpRecPoint` 落库),因此 TWS 关联路径(`track_asso.cpp` 写航迹、输出时写回 `Track`)取到的是有效数据。**TAS 通道仍未打通**:`track_asso_tas.cpp` 的关联与输出路径没有涉及这两个字段,TAS 输出航迹中 `amp_asv_point` / `prn_fftn_point` 仍保持宿主原值,宿主暂不应依赖 TAS 侧的这两个字段。
- **TAS 外推上限判据方向与 TWS 相反(50e0b5c)**:TWS 用 `Extrapolate_round <= MAX_EXTRAPOLATE_NUM` 外推,TAS 用 `Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS`,实际效果是 TAS 航迹在未达上限的若干圈内既不外推也不输出(位置与航迹时间停在最后一次关联处),达到上限后才恢复逐帧外推输出;如属笔误,宜与 TWS 侧统一。
- **Flag_Direction 判据的 acos 无定义域钳位(fc49707/42b598e)**:对 `(-x·cos D − y·sin D)/r` 直接取 `acos`(与 BUG-27 同类问题),浮点舍入使参数略微越过 ±1 时返回 NaN,比较为假、按「远离 0」输出;`r` 为 0 时还存在除零。
- **航迹质量仅覆盖 TWS 通道(V1.5.8)**:`track_asso_tas.cpp` 既不更新 `Quality` 也不在 `model_output()` 写 `Track.Quality`,因此 TAS 航迹的 `Quality` 停留在起批时的初值(手动转 TAS 后不再变化),TAS 消亡仍按外推圈数。宿主若要按质量过滤,需自行区分 `Track_Mode`。
- **质量相关宏存在未使用项(V1.5.8)**:`TRACK_QUALITY_MIN`、`TRACK_DIE_QUALITY_PRAMARY` 定义但未参与任何计算;`TRACK_DIE_ROUND` 在 TWS 普通航迹改为质量消亡后也不再被引用(保留备用)。调参时不要误以为三者生效。
- **起批质量门限取的是临时航迹「末点」质量**:`tmp_track_to_trust_track()` 用 `(*Iter)[L-1].quality` 与按长度取的门限比较,而临时航迹质量只在 L=3 时写过所有点、L>3 时只更新末点,因此门限表实际是针对「最新一点的质量」,不是整条航迹的平均质量。
- **质量长度项含整数除法**:`1 − Valid_point_sum/Point_sum` 中两操作数均为 `int`,先做整数除法截断再乘 0.5,`Valid_point_sum/Point_sum` 的精度损失最大约 1/Point_sum;对点数很多的航迹影响可忽略,但精确复现公式时需注意。
### 11.3 未启用功能
@@ -968,7 +1025,7 @@ $$
- RadarPara 中的起批/关联波门字段未被实现读取(见 10.2)。
- build/output/ 下为早期打包导出物,其 data_process_class_dll.h 时间戳仍为 32 位 int,与当前 64 位接口不一致,勿作为对接依据。
- **数据记录调试功能默认只在 Debug 启用**:CMake 选项 `RDP_DATA_RECORD` 的 AUTO 默认值为「Debug 启用、Release 关闭」,交付/Release 构建下记录模块(`rdp_record.cpp`、`sqlite3.c`)不参与编译、`RDP_RECORD` 为空操作(导出符号与依赖均无变化);如需在 Release 构建中临时排查可显式 `-DRDP_DATA_RECORD=ON`,但正式交付应保持 AUTO/OFF(见 docs/data_record_debug.md)。记录点中的字段错误只在启用记录功能的构建中才会被检查(关闭时宏丢弃实参)。
- **记录表的两个观察**:① 可靠航迹表 `RdpRecTrustTrack` 在输出循环内写库,而该循环入口已把 `Track_Update_Flag` 清零(`track_asso.cpp` 先置 0 再输出),因此表中的 `Track_Update_Flag` 恒为 0,判断「本圈是否更新」应改用该表是否出现对应 `track_id`/`circle_id` 的记录;② `Trust_Track` 的极坐标量快照 `Range`/`Azimuth`/`Elevation`/`Velocity` 只在航迹当圈有输出时回填,长期未输出(外推超限)的航迹在表中该项为 0 或旧值。
- **记录表的三个观察**:① 可靠航迹表 `RdpRecTrustTrack` 在输出分支内写库,而该分支入口已把 `Track_Update_Flag` 清零(`track_asso.cpp` / `track_asso_tas.cpp` 均先置 0 再输出),因此表中的 `Track_Update_Flag` 恒为 0,判断「本圈是否更新」应改用该表是否出现对应 `track_id`/`circle_id` 的记录;② `Trust_Track` 的极坐标量快照 `Range`/`Azimuth`/`Elevation`/`Velocity` 只在航迹当圈有输出时回填,长期未输出(外推超限)的航迹在表中该项为 0 或旧值;③ TAS 关联信息行中 `R`/`VT` 为占位 0、`thd_r` 恒为 true、`track_index` 存的是 TAS 目标批号(TWS 行才是航迹表下标),跨通道分析时不要按 TWS 语义解读。
### 11.4 航迹起始相关的未修复观察(详见 docs/track_init_readme.md 第 15 节)
@@ -984,12 +1041,22 @@ $$
## 12. 版本历史
当前代码版本:**V1.5.6**(`parameters.h` 的 `PATCH_VERSION`;对应最近一次提交 b227ae1,2026-10-08)。版本号自本版起可运行时读取(`version_info`,见 7.1)。
当前代码版本:**V1.5.8**(`parameters.h` 的 `PATCH_VERSION`;对应最近一次代码提交 3088ce4,2026-10-20)。版本号自 1.5.6 起可运行时读取(`version_info`,见 7.1)。中间状态 b4aed8a 曾把版本号置为 7,但未单独发布/记录,本文档按 1.5.8 汇总。
近期提交(git log --oneline,新→旧):
近期提交(git log --oneline,新→旧;仅列代码改动,纯文档提交略):
| 提交 | 内容 |
|---|---|
| 3088ce4(**V1.5.8** 版本号来源) | 更新版本号至 V1.5.8(`PATCH_VERSION` 7→8) |
| 782bff5 | 调整航迹质量下降逻辑(改为按未更新时长的二次函数衰减,系数 −0.0008 / −0.0025);**普通 TWS 航迹消亡条件改为由航迹质量确定**(`Quality < TRACK_DIE_QUALITY` = 0.3),重点航迹与 TAS 仍按外推圈数 |
| 4b70b24 | 航迹质量下降策略改为按点迹未更新时间计算:`Trust_Track` 新增 `Unupdated_time`,外推 ΔT 计算移到外推上限判断之外,超限后质量继续下降 |
| d9a7bd0 | 优化临时航迹质量评估(L=3 时取三点平均 SNR 并写满三点,L>3 只对末点指数平滑);航迹起始增加**按长度分级的质量门限**(L3~L7:0.7/0.6/0.5/0.4/0.3) |
| 1ae0cf2 | 增加航迹质量:`Track` 新增 `Quality`(×100 输出 0~100)、`Trust_Track` 新增 `Quality`/`Point_sum`/`Valid_point_sum`、`Temp_track` 新增 `quality`;起批时初始化质量,关联实点时按「距离+SNR+有效点占比」加权更新 |
| 3e6763c | 扫描一圈完成判据按体制区分:相扫比较前后两帧方位波位号(`Beam_index_aiz <= last_beam_num` 判满圈、`last_beam_num` 重新参与判断),机扫保持「方位波位号 == 0」(避免转台反转误判) |
| b4aed8a | 回调 TWS 外推时间差计算方法:ΔT 由「按最新时间戳实时计算」恢复为按 `work_mode` 取 `DATA_RATE_SHORT/MIDDLE/FAR` 固定值,避免 TAS 工作时同步外推出 TWS 航迹;同时把版本号置为 1.5.7(未单独发布);实时计算代码与 `latest_timestamp` 形参保留但不再参与计算 |
| e982804 | 调整临时航迹记录时机:`RdpRecTempTrack` 的写入由 `track_init_process_logic()` 末尾移到**转为可靠航迹之前**,避免本圈起批的临时航迹转走后在记录中丢失当前帧数据 |
| 56b5449 | (已被 b4aed8a 回调)TWS 外推 ΔT 改为按最新时间戳计算:`track_asso_process()`/`model_filter()` 新增 `latest_timestamp` 形参,ΔT 取 `(latest_timestamp − T_track)/1000` 且 `ΔT ≤ 0` 时跳过 |
| 5cb67cc | 增加 TAS 航迹信息与 TAS 关联信息记录:`track_asso_tas.cpp` 的输出环节记录 `RdpRecTrustTrack`、关联环节改用全局 `Asso_Info` 并记录 `RdpRecAssoInfo`;`Asso_Info`/`RdpRecAssoInfo` 新增 `tas_flag` 区分 TWS/TAS 来源 |
| b227ae1(**V1.5.6** 版本号来源) | 数据处理增加版本号输出:`parameters.h` 新增版本宏(`MAJOR_VERSION`/`MINOR_VERSION`/`PATCH_VERSION` = 1.5.6、体制后缀 `VERSION_INFO`、拼装宏 `VERSION_STRING`),基类新增公开成员 `const char* version_info` 并由 `GetB()` 赋值;Debug 下记录可靠航迹与关联信息:`struct.h` 新增全局 `Asso_Info`(含 `min_d_flag` 与门限量)、`Trust_Track` 新增 `track_id`/`point_id`/`circle_id` 与极坐标量快照 `Range`/`Azimuth`/`Elevation`/`Velocity`,新增 `RdpRecTrustTrack`/`RdpRecAssoInfo` 两张表并在 `track_asso.cpp` 输出循环与关联三处埋点,移除 `data_process.cpp` 中按输出数组批量记录的旧示例(`RdpRecTrackOut` 实体注释停用);`track_asso.cpp` 的 ΔT 分支改写为 `if (delta_T > 0)`(行为等价) |
| c3c7e66 | 增加临时航迹录入数据库(新增 `RdpRecTempTrack` 表与 `track_init.cpp` 记录点)、输入点迹增加圈 ID(`PointRecv::circle_id`、`Data_Process::circle_id` 在满圈/TAS 帧末自增);`Temp_track` 字段更名(`snr`→`SNR`、`Amp`→`amplitude`、`T`→`CPI_time`、`Temp_track_section_idx`→`temp_track_section_idx`)并新增 `temp_track_id`/`point_id`/`circle_id`/`pitch_num`;临时航迹起批时把 ID 透传给 `Trust_Track` |
| a4f32e4 | 新增数据记录功能:把过程数据录入数据库(凝聚后点迹 `RdpRecPointCohesionTWS/TAS`,输入点迹改为 `RdpRecPoint`)、`data_process.h` 新增 `point_id`/`frame_id`/`circle_id` 计数、`dot_coh`/`dot_coh_tas` 埋记录点;<br>(该提交同时把上一轮的 CMake/工具链与记录框架改动一并提交,内容见下方「工作区(未提交…)」两条) |