@@ -20,7 +20,7 @@
|
||||
|
||||
1. **时间主线**:所有时间戳为 64 位毫秒(CPI/GNSS),参与运算时除 1000 转秒;ΔT = 点迹时间 − 航迹时间,ΔT 的正负决定"有效更新 / 只消费不更新 / 跳过"。
|
||||
2. **状态主线**:每条可靠航迹维护一套 IMM(3 个 Singer 模型)状态 [x, vx, ax, y, vy, ay],x/y 两轴解耦,量测为「距离-方位-径向速度」三维 EKF。
|
||||
3. **生命周期主线**:可靠航迹靠"外推轮数"消亡(判据为 `>`:TWS 普通航迹 6 圈、重点目标 10 圈,TAS 相扫 10 / 机扫 96 圈);临时航迹靠"缓存圈数 buff_round"消亡。
|
||||
3. **生命周期主线**:可靠航迹的消亡分两种判据——**TWS 普通航迹自 V1.5.8 起按航迹质量**(`Quality < TRACK_DIE_QUALITY` = 0.3),**重点目标按外推轮数**(判据 `> 10`)、**TAS 按外推轮数**(判据 `> 阈值`:相扫 10 / 机扫 96 圈);临时航迹靠"缓存圈数 buff_round"消亡。
|
||||
|
||||
---
|
||||
|
||||
@@ -74,7 +74,7 @@ flowchart TD
|
||||
flowchart TD
|
||||
A["收到一帧点迹"] --> B{"point_type ?"}
|
||||
B -->|"0 = TWS"| C["写入 TWS 缓存"]
|
||||
C --> D{"方位波位号 Beam_index_aiz == 0 ?"}
|
||||
C --> D{"判圈条件成立 ?<br/>相扫: Beam_index_aiz <= last_beam_num<br/>机扫: Beam_index_aiz == 0"}
|
||||
D -->|"是"| E["return 1:满一圈,执行 TWS 航迹处理"]
|
||||
D -->|"否"| F["return 2:未满圈,仅做滑窗凝聚"]
|
||||
B -->|"1 = TAS"| G["写入 TAS 缓存<br/>记录 TAS 批号与本帧时间戳"]
|
||||
@@ -84,9 +84,10 @@ flowchart TD
|
||||
|
||||
**要点**
|
||||
|
||||
- 判圈条件由"波位号由大变小"改为 **波位号为 0**(7d5a56f),避免机扫转台反转时误判一圈完成(代码中保留了旧判断的注释)。
|
||||
- 波位号 0 是每圈的起始波位,因此**每圈恰好触发一次 model=1**。
|
||||
- 清空(`track_clear_all`)后圈状态复位,下一次调用必然判为"满一圈"。
|
||||
- 判圈条件按扫描体制区分(3e6763c,源码用 `#ifdef PHASE_SCANNING` 编译期隔离):
|
||||
- **相扫**:比较前后两帧方位波位号,当前帧 `Beam_index_aiz <= last_beam_num` 判为满一圈;`last_beam_num` 参与判断,`track_clear_all()` 复位为 INT_MAX,故**清空后/首帧即判满一圈**;
|
||||
- **机扫**:判 **波位号为 0**(7d5a56f 起),避免转台反转时波位号变小导致误判一圈完成(代码中保留了旧判断的注释);该分支下 `last_beam_num` 仍被赋值但不参与判断。
|
||||
- 机扫下波位号 0 是每圈的起始波位,因此**每圈恰好触发一次 model=1**。
|
||||
- TAS 数据不参与判圈,**每来一帧就处理一次**(TAS 是调度的跟踪波位,本身就是单目标 CPI)。
|
||||
|
||||
### 2.3 调度:model 与动作的对应
|
||||
@@ -277,9 +278,11 @@ VT > 300 且 R > 1200 → 拒绝(高速目标给固定 1200 m 上限)
|
||||
|
||||
**输出门控(50e0b5c)**:TWS 输出航迹的循环改为「`Track_Update_Flag == 1` 才输出,输出后清零」,即每圈只输出**本圈关联到实点或成功外推**的航迹;此前是每圈把航迹表中全部可靠航迹各输出一行。门控只判更新标志、不判 `manual_tracking_flag`,因此手动转 TAS 的航迹若本圈在 TWS 侧关联到实点,仍会经 TWS 通道输出。
|
||||
|
||||
> 由于外推上限(3)小于 TWS 消亡轮数(6),普通航迹在停止预测后还会**连续 3 圈不向宿主输出**任何航迹行(`Extrapolate_round` 依次走到 5、6、7,第 7 圈在 `track_die` 中消亡),只在最后输出一次消亡批号。
|
||||
> **普通 TWS 航迹的消亡改由质量决定(V1.5.8)**:`track_die.cpp` 对 `Track_Mode==0 && primary_target_flag==0` 的航迹改用 `Quality < TRACK_DIE_QUALITY`(0.3)判消亡,因此外推超限后航迹仍会驻留,直到质量衰减到门限以下;`Extrapolate_round` 继续每圈 +1 但不再决定普通 TWS 航迹的存活。重点航迹(10 圈)与 TAS(相扫 10 / 机扫 96)不变。
|
||||
>
|
||||
> **TAS 通道的判据方向相反**(`track_asso_tas.cpp` L484):`Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS` 时才做预测、推进航迹时间并置 `Track_Update_Flag = 1`;未达该轮数时只累加圈数(不预测、不输出)。即 TWS 是"先外推、到上限后停",TAS 是"先不预测、到轮数后才开始外推",详见 7.2 与第 10 节。
|
||||
> 质量在外推环节按未更新时长二次衰减(`Unupdated_time` 累计,ΔT 由 `work_mode` 数据率决定),且该计算位于外推上限判断之外,故上限内、外都会衰减。
|
||||
>
|
||||
> **TAS 通道的判据方向相反**(`track_asso_tas.cpp`):`Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS` 时才做预测、推进航迹时间并置 `Track_Update_Flag = 1`;未达该轮数时只累加圈数(不预测、不输出)。即 TWS 是"先外推、到上限后停",TAS 是"先不预测、到轮数后才开始外推",详见 7.2 与第 10 节;TAS 不维护航迹质量。
|
||||
|
||||
---
|
||||
|
||||
@@ -390,14 +393,16 @@ dis ≥ |v_r,head| · ΔT 同上,用航迹头的多普勒约
|
||||
|
||||
| 通道 | 条件(满足其一即消亡) |
|
||||
|---|---|
|
||||
| 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_delete` 置位) |
|
||||
|
||||
三个判据都改为 `die_flag` 组合("或"关系),且比较符由 `>=` 改为 `>`(50e0b5c):即允许的外推圈数比旧版各多 1 圈,且**重点航迹与普通航迹走不同门限**。由于每圈未关联只自增 1,判据为 `>` 时实际是"连续 N+1 圈没有实点关联"才消亡:普通 TWS 航迹 7 圈、重点航迹 11 圈、TAS 相扫 11 圈 / 机扫 97 圈。
|
||||
轮数类判据都改为 `die_flag` 组合("或"关系),且比较符由 `>=` 改为 `>`(50e0b5c):即允许的外推圈数比旧版各多 1 圈,且**重点航迹与普通航迹走不同门限**。由于每圈未关联只自增 1,判据为 `>` 时实际是"连续 N+1 圈没有实点关联"才消亡:重点航迹 11 圈、TAS 相扫 11 圈 / 机扫 97 圈。
|
||||
|
||||
> `primary_target_flag`(重点目标标记)由外部接口 `Data_Process::primary_target_add / primary_target_cancel` 按批号置 1 / 清 0(`data_process.cpp` L268-297);新起批航迹在 `track_init.cpp` 中以 `Trust_Track trust_track_tmp = {}` 零初始化,故恒为 0。该标记目前只影响上表的 TWS 消亡轮数。
|
||||
> **普通 TWS 航迹的消亡时长(V1.5.8)**:改按质量后不再有固定圈数,存活时长由质量衰减速度决定——未关联期间按 `Unupdated_time` 的二次函数加速衰减(见 9.9 / README 9.11),`Quality` 跌破 0.3 即消亡;`TRACK_DIE_ROUND`(6)已不再被引用。
|
||||
|
||||
> `primary_target_flag`(重点目标标记)由外部接口 `Data_Process::primary_target_add / primary_target_cancel` 按批号置 1 / 清 0(`data_process.cpp`);新起批航迹在 `track_init.cpp` 中以 `Trust_Track trust_track_tmp = {}` 零初始化,故恒为 0。该标记在 TWS 上决定走「质量消亡(普通)」还是「10 圈消亡(重点)」。
|
||||
|
||||
消亡时把批号写入消亡输出数组并从航迹表删除;**临时航迹消亡不对外输出**(起批失败的中间态对宿主不可见)。
|
||||
|
||||
@@ -538,9 +543,12 @@ flowchart TD
|
||||
| `ASSO_THORD` | 4 | 同左 | 关联波门(判据 d*d < ASSO_THORD²,d 已是马氏距离平方,等效 d < 4) |
|
||||
| `MAX_EXTRAPOLATE_NUM` | 3 | 同左 | TWS 未关联航迹最大外推轮数(`Extrapolate_round <= 该值` 才预测并输出) |
|
||||
| `MAX_EXTRAPOLATE_NUM_TAS` | 5 | 48 | TAS 未关联航迹开始外推的轮数(判据 `>=`,方向与 TWS 相反) |
|
||||
| `TRACK_DIE_ROUND` | 6 | 6 | TWS 普通航迹消亡轮数(判据 `Extrapolate_round > 该值`) |
|
||||
| `TRACK_DIE_ROUND` | 6 | 6 | **已不被引用**:V1.5.8 起 TWS 普通航迹改按质量消亡(宏保留备用) |
|
||||
| `TRACK_DIE_ROUND_PRIMARY` | 10 | 10 | TWS 重点航迹(`primary_target_flag==1`)消亡轮数 |
|
||||
| `TRACK_DIE_ROUND_TAS` | 10 | 96 | TAS 航迹消亡轮数(判据 `Extrapolate_round > 该值`) |
|
||||
| `TRACK_DIE_QUALITY` | 0.3 | 0.3 | TWS 普通航迹质量消亡门限(`Quality < 该值`;V1.5.8 新增) |
|
||||
| `TRACK_START_QUALITY_L3~L7` | 0.7 / 0.6 / 0.5 / 0.4 / 0.3 | 同左 | 起批最低质量(按临时航迹长度 3/4/5/6/≥7;V1.5.8 新增) |
|
||||
| `TRACK_QUALITY_*` | 见 README 10.1 | 同左 | 质量权重(D/SNR/LEN:0.5/0.3/0.2)、平滑系数 0.8、衰减系数 O2/O1 = −0.0008/−0.0025、折算上限 100(V1.5.8 新增) |
|
||||
| `MAX_TRACK_NUM / MAX_TRACK_INDEX` | 500 / 500 | 同左 | 航迹数上限 / 航迹号上限 |
|
||||
| `TAS_QUEUE_LENGTH / MAX_TAS_NUM` | 4 / 4 | 1 / 1 | TAS 队列长度 / 最大 TAS 目标数 |
|
||||
| `H_F_WIN_LEN` | 3 | 同左 | 高度平滑窗长基数(实际 +2/+3/+4/+6) |
|
||||
@@ -593,14 +601,15 @@ flowchart TD
|
||||
- 屏蔽区/禁止区的组数按 30 组数组定义,配置数量未做上限校验;
|
||||
- 高度平滑缓存只增不减,长时运行下每条航迹的内存占用会持续增长。
|
||||
|
||||
**外推、消亡与输出门控(50e0b5c / fc49707 / 42b598e / e8c56f9)**
|
||||
**外推、消亡与输出门控(50e0b5c / fc49707 / 42b598e / e8c56f9 / V1.5.8)**
|
||||
|
||||
- **外推圈数上限**:TWS 只在 `Extrapolate_round <= MAX_EXTRAPOLATE_NUM`(3)时预测并输出;TAS 相反,`Extrapolate_round >= MAX_EXTRAPOLATE_NUM_TAS`(相扫 5 / 机扫 48)时才预测并输出。两处比较方向不一致,此处仅如实记录,**不判定为缺陷**;
|
||||
- **消亡判据**由 `>=` 改为 `>`,并区分重点目标:普通 TWS 航迹 `> TRACK_DIE_ROUND`(6)、重点航迹(`primary_target_flag==1`)`> TRACK_DIE_ROUND_PRIMARY`(10)、TAS 航迹 `> TRACK_DIE_ROUND_TAS`(相扫 10 / 机扫 96);`manual_delete_flag == 1` 单独判为消亡;因外推上限(3)小于消亡轮数(6),普通 TWS 航迹停止预测后还会连续 3 圈不向宿主输出;
|
||||
- **普通 TWS 航迹消亡改按质量(V1.5.8)**:`Quality < TRACK_DIE_QUALITY`(0.3)即消亡,`TRACK_DIE_ROUND`(6)不再被引用;重点航迹仍按 `> TRACK_DIE_ROUND_PRIMARY`(10)、TAS 仍按 `> TRACK_DIE_ROUND_TAS`(相扫 10 / 机扫 96);`manual_delete_flag == 1` 单独判为消亡;
|
||||
- **航迹质量(V1.5.8)**:内部 0~1,临时航迹每延长一点按「距离+SNR」更新、关联实点按「距离+SNR+有效点占比」平滑更新、未关联期间按 `Unupdated_time` 二次衰减;起批需达按长度分级的最低质量;输出 `Track.Quality` 为 0~100(×100)。TAS 通道不维护质量;
|
||||
- **输出门控**:TWS 与 TAS 的输出航迹循环都新增 `Track_Update_Flag == 1` 判定并在输出后清零,只输出**本圈关联到实点或成功外推**的航迹(此前 TWS 每圈把航迹表中全部可靠航迹各输出一行);
|
||||
- **接近/远离判据**(fc49707 + 42b598e):`Flag_Direction` 不再用实测径向速度 `vr_point > 0`(受多普勒速度模糊影响符号可能取反),改为用 IMM 融合速度方向角判定——`Direction_Angle = atan2(X[4], X[1])`(弧度转度后输出到 `Track.Direction_Angle`),`x`、`y` 为经 `Work_Parameter.Sys_delay` 补偿后的位置、`r` 为其模,`acos((-x·cosθ - y·sinθ)/r) < π/2` 判为靠近(1)、否则远离(0),等价于"速度方向与雷达→目标位置方向夹角 > 90°"。中间版本 fc49707 曾写为 `acos((-x·vx - y·vy)/r/Range_V) < π/4`(按合速度归一化、门限 45°),42b598e 改为上式;
|
||||
- **归一化幅度 / 速度维 FFT 点数(e8c56f9 新增,输入侧已打通)**:`DataRev` 新增 `amp_asv`(归一化幅度 dB)、`prn_fftn`(速度维 FFT 点数),`Track`/内部 `PointRecv`/`Trust_Track` 也新增同名成对字段;`data_preprocess()` 现已在 TWS 与 TAS 两条分支都把这两个字段搬入 `PointRecv`(并随 `RdpRecPoint` 落库),因此 `track_asso.cpp` 写入航迹并在 TWS 输出行写回的 `amp_asv_point` / `prn_fftn_point` 有有效数据来源;**TAS 的关联与输出路径(`track_asso_tas.cpp`)仍未涉及这两个字段**,TAS 输出行中它们保持宿主原值。
|
||||
- **版本号与记录标识(b227ae1 / c3c7e66)**:`parameters.h` 新增版本宏并拼装为 `VERSION_STRING`(当前 `V1.5.6.PS` / `V1.5.6.MS`),实例创建后可由基类公开成员 `version_info` 读取;`Data_Process` 新增 `point_id` / `frame_id` / `circle_id` 自增计数(`circle_id` 在 TWS 满一圈、TAS 每帧末自增),`PointRecv`/`Temp_track`/`Trust_Track` 新增对应的标识字段,记录功能据此把「输入点迹 → 凝聚点迹 → 临时航迹 → 可靠航迹 → 关联信息」串成同一条链路。
|
||||
- **版本号与记录标识(b227ae1 / c3c7e66 / 5cb67cc)**:`parameters.h` 新增版本宏并拼装为 `VERSION_STRING`(当前 `V1.5.8.PS` / `V1.5.8.MS`),实例创建后可由基类公开成员 `version_info` 读取;`Data_Process` 新增 `point_id` / `frame_id` / `circle_id` 自增计数(`circle_id` 在 TWS 每判满一圈、TAS 每帧末自增),`PointRecv`/`Temp_track`/`Trust_Track` 新增对应的标识字段,记录功能据此把「输入点迹 → 凝聚点迹 → 临时航迹 → 可靠航迹 → 关联信息」串成同一条链路;可靠航迹与关联信息的记录点为 TWS/TAS 双通道(关联信息以 `Asso_Info::tas_flag` 区分来源)。
|
||||
|
||||
**未启用**
|
||||
|
||||
@@ -616,13 +625,13 @@ flowchart TD
|
||||
|
||||
| 项 | README 描述(更新前) | 当前源码 |
|
||||
|---|---|---|
|
||||
| 满圈判据 | 当前方位波位号 < 上一帧波位号 | **方位波位号 == 0**(7d5a56f,适应机扫转台反转) |
|
||||
| 满圈判据 | 当前方位波位号 < 上一帧波位号 | 按体制区分(3e6763c):**相扫**当前波位号 ≤ 上一帧波位号(等价于原判据)、**机扫**方位波位号 == 0(7d5a56f,适应机扫转台反转) |
|
||||
| 点-航迹头判据 | 按距离分段收紧速度门限(半速、1/2~1/3 速) | 该分支注释停用;改为统一速度区间 **+ 两条多普勒-几何一致性约束**(7d5a56f) |
|
||||
| 起始输出历史点 | "临时航迹的全部 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` 的点,两道处理叠加,效果一致 |
|
||||
| 日志开关 | "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 对应版本的记录);流程落地实现仍以本文为准。
|
||||
>
|
||||
> 补充修订(本次):起始流程的**步骤顺序**原先在本文档(第 0、6 节)与 README(第 2、5.2、8.3、9.3 节)中都写作「航迹头 → 2 点 → ≥3 点 → 起批」,与源码每圈「点 × 临时航迹关联 → 点 × 航迹头关联 → 剩余点转航迹头 → 达标者起批」的顺序相反,现已按源码修正,并补充说明两个关联阶段互不排斥、均不做一对一分配。
|
||||
|
||||
+18
-11
@@ -129,28 +129,29 @@ RDP_RECORD(RdpRecTrackHeight{0, trust_track[i].Track_Index, trust_track[i].Heigh
|
||||
| ① | 输入点迹(TWS + TAS) | `data_process.cpp::data_preprocess()`,TWS 分支(`point_type == 0`)与 TAS 分支(`point_type == 1`)的逐点循环内 | `RdpRecPoint` | TWS/TAS **共用一张表**,用 `point_type` 区分;每个输入点迹一行,含 `point_id` / `frame_id` / `circle_id` 三个链路标识 |
|
||||
| ② | TWS 凝聚后点迹 | `dot_coh.cpp::dot_coh_process_buff()`,输出到 `point_recv` 的循环内 | `RdpRecPointCohesionTWS` | 两帧滑窗凝聚后进入关联的点迹 |
|
||||
| ③ | TAS 凝聚后点迹 | `dot_coh_tas.cpp::dot_coh_tas_process()`,输出到 `point_recv_tas` 的循环内 | `RdpRecPointCohesionTAS` | 单帧凝聚后的 TAS 点迹 |
|
||||
| ④ | 临时航迹 | `track_init.cpp::track_init_process_logic()` 末尾(**消亡临时航迹之后**),双层遍历 `temp_track` | `RdpRecTempTrack` | 每条临时航迹的每个点一行,含 `temp_track_id` / `point_id` / `circle_id`;因在消亡之后记录,表中是「本圈存活下来 + 本圈新建」的临时航迹 |
|
||||
| ⑤ | 可靠航迹 | `track_asso.cpp::track_asso_process()` 的**输出循环内**(`Track_Update_Flag==1` 的分支末尾) | `RdpRecTrustTrack` | 内部 `Trust_Track` 全量落库(含 IMM 的 `X`/`P`/`X1`~`X3`/`P2`/`P3`/`u`,数组经 `arrayToString()` 存为文本列)。**只记录本圈有输出的航迹,且仅 TWS 通道**——`track_asso_tas.cpp`(TAS)与 `track_init.cpp`(起批)均未埋此点 |
|
||||
| ⑥ | 点航关联信息 | `track_asso.cpp::model_filter()` 三处:未通过门限的候选、被最近邻取中的候选、因航迹/点迹已被消费而删表的候选 | `RdpRecAssoInfo` | 每个候选一行(`d1`/`d2`/`d3`/`d_min`、`delta_T`/`delta_h`/`R`/`VT`、`thd_d`/`thd_h`/`thd_r`),并以 `min_d_flag` 标记是否被最近邻取中,可用于复现关联决策 |
|
||||
| ④ | 临时航迹 | `track_init.cpp::track_init_process_logic()`,TWS 圈内**转为可靠航迹之前**(清空点迹之后、`tmp_track_to_trust_track()` 之前),双层遍历 `temp_track` | `RdpRecTempTrack` | 每条临时航迹的每个点一行,含 `temp_track_id` / `point_id` / `circle_id`;记录时机于 e982804 前移,因此表中包含**本圈参与起始判定但可能随即起批转走**的临时航迹(原先在消亡之后记录会丢失这部分数据) |
|
||||
| ⑤ | 可靠航迹 | TWS:`track_asso.cpp::track_asso_process()` 的输出分支内(`Track_Update_Flag==1`);TAS:`track_asso_tas.cpp::model_output()` 写出航迹之后(5cb67cc 补齐) | `RdpRecTrustTrack` | 按实体字段定义落库内部 `Trust_Track`(含 IMM 的 `X`/`P`/`X1`~`X3`/`P2`/`P3`/`u`,数组经 `arrayToString()` 存为文本列)。**两通道共用一张表**,用 `Track_Mode`(TWS 0 / TAS 1)区分;均只记录**本圈有输出**的航迹,`track_init.cpp` 起批路径未埋此点;V1.5.8 新增的 `Quality` / `Point_sum` / `Valid_point_sum` / `Unupdated_time` **尚未加入该实体**,如需分析质量请按第 5 节配方自行补字段 |
|
||||
| ⑥ | 点航关联信息 | TWS:`track_asso.cpp::model_filter()` 三处(未通过门限的候选、被最近邻取中的候选、因航迹/点迹已被消费而删表的候选);TAS:`track_asso_tas.cpp::model_filter()` 两处(未通过门限的候选、被取中候选及其余候选,5cb67cc 补齐) | `RdpRecAssoInfo` | 每个候选一行(`d1`/`d2`/`d3`/`d_min`、`delta_T`/`delta_h`/`R`/`VT`、`thd_d`/`thd_h`/`thd_r`),以 `min_d_flag` 标记是否被最近邻取中、以 `tas_flag`(点迹 `point_type`,1 TAS / 0 TWS)区分来源通道,可用于复现关联决策 |
|
||||
| ⑦ | (已停用)本圈输出航迹 | 原 `data_process.cpp::track_process()` 的 `model == 1/3` 分支 | ~~`RdpRecTrackOut`~~ | 该实体与记录点已在 b227ae1 中整体注释停用,改由 ⑤ 记录内部航迹;`rdp_record.cpp` 与 `rdp_record_entity.h` 中保留注释代码以备参考 |
|
||||
|
||||
> 表清单即上表 ①②③④⑤⑥ 六张在用表(`rdp_record_entity.h` 中共 7 个实体定义,其中第 ⑦ 项已停用)。
|
||||
|
||||
**链路串联**:①→②/③(点迹 → 凝聚后点迹)按 `point_id` 关联;②/③→④/⑤ 按 `point_id` 与 `circle_id` 关联;④→⑤ 通过起批时透传的 `track_id`(取自临时航迹末点的 `temp_track_id`)关联;⑤→⑥ 按 `track_id` 与 `point_id` 关联。`circle_id` 在 TWS 满一圈(`Beam_index_aiz == 0`)、TAS 每帧处理结束时自增,可用来划分「第几圈/第几帧」。
|
||||
**链路串联**:①→②/③(点迹 → 凝聚后点迹)按 `point_id` 关联;②/③→④/⑤ 按 `point_id` 与 `circle_id` 关联;④→⑤ 通过起批时透传的 `track_id`(取自临时航迹末点的 `temp_track_id`)关联;⑤→⑥ 按 `track_id` 与 `point_id` 关联。TWS 与 TAS 可先用 `RdpRecPoint.point_type`、`RdpRecTrustTrack.Track_Mode`、`RdpRecAssoInfo.tas_flag` 三处之一区分通道。`circle_id` 在 TWS 每判满一圈(相扫为波位号不再增大、机扫为波位号 0,见 README 7.2)、TAS 每帧处理结束时自增,可用来划分「第几圈/第几帧」。
|
||||
|
||||
**字段速查**(字段顺序即建表列顺序;首列均为 `int64_t id` 自增主键):
|
||||
|
||||
- `RdpRecPoint` / `RdpRecPointCohesionTWS` / `RdpRecPointCohesionTAS`(三者字段一致):`point_id`、`frame_id`、`circle_id`、`range`、`azimuth`(弧度)、`velocity`、`amplitude`、`height`、`SNR`、`RCS`、`encoder_value`、`amp_asv_point`、`prn_fftn_point`、`CPI_time`、`GNSS_time`、`use_flag`、`azimuth_beam_index`、`pitch_beam_index`、`PRF_index`、`freq_index`、`point_type`、`point_section_asso`;
|
||||
- `RdpRecTempTrack`:`temp_track_id`、`point_id`、`circle_id`、`X`、`P`(文本)、`r`、`azi`、`vr`、`height`、`SNR`、`RCS`、`amplitude`、`CPI_time`、`GNSS_time`、`d`、`buff_round`、`temp_track_section_idx`、`asso_flag`、`pitch_num`;
|
||||
- `RdpRecTrustTrack`:`track_id`、`point_id`、`circle_id`、`Track_Index`、`Range`、`Azimuth`、`Elevation`、`Velocity`、`Amplitude`、`Height`、`T_track`、`GNSS_time`、`Track_Sum`、`Point_Index`、`Track_Mode`、`Track_Update_Flag`、`Extrapolate_round`、`point_flag`、`approach_flag`、`manual_delete_flag`、`manual_tracking_flag`、`associate_point_number`、`primary_target_flag`、`Target_Type`、`Track_section_idx`、`range_point`、`azi_point`、`elev_point`、`vr_point`、`prf_point`、`point_type`、`snr_point`、`amp_asv_point`、`prn_fftn_point`、`RCS`、`pitch_num`、`X`、`P`、`X1`、`X2`、`X3`、`P2`、`P3`、`u`(后 8 项为文本);
|
||||
- `RdpRecAssoInfo`:`point_id`、`track_id`、`circle_id`、`d1`、`d2`、`d3`、`d_min`、`point_index`、`track_index`、`delta_T`、`delta_h`、`R`、`VT`、`thd_d`、`thd_h`、`thd_r`、`min_d_flag`。
|
||||
- `RdpRecAssoInfo`:`point_id`、`track_id`、`circle_id`、`d1`、`d2`、`d3`、`d_min`、`point_index`、`track_index`、`delta_T`、`delta_h`、`R`、`VT`、`tas_flag`、`thd_d`、`thd_h`、`thd_r`、`min_d_flag`。
|
||||
|
||||
各表的字段为**调试用途**,按第 5 节增删即可,不影响框架。注意记录点中的字段错误只在启用记录功能的构建中才会被检查(关闭时宏丢弃实参)。
|
||||
|
||||
**两点使用提醒**:
|
||||
**三点使用提醒**:
|
||||
|
||||
- `RdpRecTrustTrack::Track_Update_Flag` **恒为 0**:写库发生在输出循环内,而该循环入口已先把标志清零(`track_asso.cpp` 先置 0、再输出、最后记录)。判断「某航迹本圈是否更新」应改用该表是否出现对应 `track_id` / `circle_id` 的记录,或改用 `RdpRecAssoInfo::min_d_flag`。
|
||||
- `Range` / `Azimuth` / `Elevation` / `Velocity` 四个内部快照**只在航迹当圈有输出时被回填**,长期未输出(外推超限)的航迹在表中为 0 或旧值。
|
||||
- `RdpRecTrustTrack::Track_Update_Flag` **恒为 0**(TWS 与 TAS 两处记录点相同):写库发生在输出分支内,而该分支入口已先把标志清零(`track_asso.cpp` / `track_asso_tas.cpp` 均先置 0、再输出、最后记录)。判断「某航迹本圈是否更新」应改用该表是否出现对应 `track_id` / `circle_id` 的记录,或改用 `RdpRecAssoInfo::min_d_flag`。
|
||||
- `Range` / `Azimuth` / `Elevation` / `Velocity` 四个内部快照**只在航迹当圈有输出时被回填**(两通道均在记录前回填),长期未输出(外推超限)的航迹在表中为 0 或旧值。
|
||||
- **TAS 关联信息的三个字段为占位值**:`track_asso_tas.cpp` 写入的候选把 `R` / `VT` 置 0(TAS 关联只用统计距离与高度两个门限),并把 `thd_r` 恒置 true;`track_index` 取 TAS 目标批号 `tas_track_idx`(不是航迹表下标,TWS 行才是下标)。分析 TAS 行时不要按 TWS 的语义解读这三项。
|
||||
|
||||
## 7. 查询与分析
|
||||
|
||||
@@ -175,11 +176,17 @@ print(con.execute("""
|
||||
order by p.id desc limit 10
|
||||
""").fetchall())
|
||||
|
||||
# 查看某圈的关联决策(min_d_flag=1 为最终取中的候选)
|
||||
# 查看某圈的关联决策(min_d_flag=1 为最终取中的候选;tas_flag 区分通道)
|
||||
print(con.execute("""
|
||||
select track_id, point_id, d_min, delta_T, thd_d, thd_h, thd_r, min_d_flag
|
||||
select track_id, point_id, d_min, delta_T, tas_flag, thd_d, thd_h, thd_r, min_d_flag
|
||||
from RdpRecAssoInfo where circle_id = (select max(circle_id) from RdpRecAssoInfo)
|
||||
order by min_d_flag desc, d_min asc limit 20
|
||||
order by tas_flag, min_d_flag desc, d_min asc limit 20
|
||||
""").fetchall())
|
||||
|
||||
# TAS 航迹与 TWS 航迹共表,用 Track_Mode 区分(0 TWS / 1 TAS)
|
||||
print(con.execute("""
|
||||
select track_id, circle_id, Track_Index, Track_Mode, Range, Velocity, Extrapolate_round
|
||||
from RdpRecTrustTrack where Track_Mode = 1 order by id desc limit 10
|
||||
""").fetchall())
|
||||
```
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ track_init.track_init_process_logic(&point_recv, &trust_track, &temp_track,
|
||||
|
||||
### 1.2 调用频率 = 扫描圈
|
||||
|
||||
`data_preprocess` 在 `Data_Input[0].Beam_index_aiz == 0` 时返回 1(`data_process.cpp` L51),宿主据此调用 `track_process(model=1)`。
|
||||
`data_preprocess` 判为一圈完成时返回 1(`data_process.cpp`),宿主据此调用 `track_process(model=1)`。判据按扫描体制区分(3e6763c):**相扫**比较前后两帧方位波位号(当前 ≤ 上一帧即满圈,`last_beam_num` 参与判断,清空后/首帧即满圈),**机扫**判 `Data_Input[0].Beam_index_aiz == 0`(详见 README 7.2 与 `docs/data_process_flow_report.md` 2.2 节)。
|
||||
因此 **`track_init_process_logic()` 每次调用对应 TWS 一圈**,`Temp_track::buff_round`(已缓存圈数)正是以「调用次数」为单位累加的。
|
||||
|
||||
### 1.3 类接口
|
||||
@@ -90,6 +90,7 @@ track_init.track_init_process_logic(&point_recv, &trust_track, &temp_track,
|
||||
| `asso_flag` | 0 未关联 / 1 已关联(待删除)/ 2 去重淘汰 | 临时状态标记 |
|
||||
| `pitch_num`、`speed_dim[129]`、`range_dim[8]` | 俯仰波位、十字星数据 | 纯透传 |
|
||||
| `temp_track_id` / `point_id` / `circle_id` | 临时航迹 ID / 末关联点迹 ID / 处理圈 ID(c3c7e66 新增) | 数据记录链路标识;起批时透传给 `Trust_Track` |
|
||||
| `quality` | **航迹质量(0~1,V1.5.8 新增)** | 每延长一点即重算(见 8.6);起批时取末点值作为初始质量,并参与起批质量门限判断 |
|
||||
| `temp_track_section_idx` | 临时航迹区号 | 相关赋值已被注释停用,当前不参与逻辑 |
|
||||
|
||||
> 字段更名提示(c3c7e66):`snr`→`SNR`、`Amp`→`amplitude`、`T`→`CPI_time`、`Temp_track_section_idx`→`temp_track_section_idx`。阅读早期提交或旧文档时注意对应关系。
|
||||
@@ -379,8 +380,11 @@ for (...) (*point_recv).push_back(point_process[i]); // 回写未被使用的
|
||||
int L = (*Iter).size();
|
||||
double range = (*Iter)[L-1].r;
|
||||
double azi = (*Iter)[L-1].azi/PI*180; // 转度,供屏蔽区比较
|
||||
double quality = (*Iter)[L-1].quality; // V1.5.8:末点航迹质量
|
||||
|
||||
if( (L <= 10 && L >= Work_Parameter.track_start_point_num) && track_init_prohibit(range, azi, Work_Parameter)==0 )
|
||||
if( L <= 10 && L >= Work_Parameter.track_start_point_num
|
||||
&& track_init_prohibit(range, azi, Work_Parameter) == 0
|
||||
&& quality >= 按长度取的质量门限 ) // V1.5.8 新增
|
||||
{ 复制到 Track_to_start; 从 temp_track 中 erase; }
|
||||
else
|
||||
Iter++;
|
||||
@@ -388,12 +392,13 @@ else
|
||||
|
||||
**入选条件**:
|
||||
|
||||
1. **长度**:`track_start_point_num ≤ L ≤ 10`(`track_start_point_num` 由宿主经 `track_process_parameters_initial` 传入,接口层校验范围 **3~9**,`data_process.cpp` L208);
|
||||
2. **不在起批屏蔽区**内(用**末点**的距离/方位判断,见 8.5)。
|
||||
1. **长度**:`track_start_point_num ≤ L ≤ 10`(`track_start_point_num` 由宿主经 `track_process_parameters_initial` 传入,接口层校验范围 **3~9**,`data_process.cpp`);
|
||||
2. **不在起批屏蔽区**内(用**末点**的距离/方位判断,见 8.5);
|
||||
3. **航迹质量达标(V1.5.8,d9a7bd0)**:按长度取门限 `TRACK_START_QUALITY_L3~L7`——L=3 →0.7、L=4 →0.6、L=5 →0.5、L=6 →0.4、L≥7 →0.3;比较对象是**末点** `quality`,不达标则本圈不起批、留在 `temp_track` 继续积累。
|
||||
|
||||
命中即从 `temp_track` 摘出(先复制后删除,`Track_to_start` 成为候选表)。
|
||||
|
||||
> 结果:**一旦长度达到阈值且不落在屏蔽区,当圈即起批**(没有"连续 M 圈满足才起批"的确认期)。若因屏蔽区被拦住,航迹会继续在 `temp_track` 中增长,直到离开屏蔽区(此时 `L > track_start_point_num`,见 8.3 的副作用)或达到 `L=10` 被判消亡。
|
||||
> 结果:**一旦长度达到阈值、不落在屏蔽区且末点质量达标,当圈即起批**(没有"连续 M 圈满足才起批"的确认期)。若因屏蔽区被拦住,航迹会继续在 `temp_track` 中增长,直到离开屏蔽区(此时 `L > track_start_point_num`,见 8.3 的副作用)或达到 `L=10` 被判消亡;若因质量门限被拦住,则继续积累直到质量回升或临时航迹消亡。
|
||||
|
||||
### 8.2 步骤 2:同源去重(L504-550)
|
||||
|
||||
@@ -478,6 +483,27 @@ return 0;
|
||||
- 采用**严格不等号**:恰好落在边界上的点不算屏蔽;
|
||||
- 判断用**末点**极坐标,不使用高度。
|
||||
|
||||
### 8.6 临时航迹质量评估与起批门限(V1.5.8,1ae0cf2 / d9a7bd0)
|
||||
|
||||
在阶段二(点-临时航迹关联)每成功延长一个点后,`point_temp_track_asso()` 立即重算该临时航迹末点的质量:
|
||||
|
||||
```cpp
|
||||
L = temp_track_ref.size();
|
||||
d_tmp = exp(-temp_track_ref[L-1].d); // 末点统计距离项(d 已是马氏距离平方)
|
||||
// L == 3:取三个点 SNR 的平均;L > 3:只取末点 SNR
|
||||
snr_tmp = 1 / (1 + exp(-(SNR - 16) / 1.2)); // 以 16 dB 为界的 Sigmoid
|
||||
quality_tmp = (0.5 * d_tmp + 0.3 * snr_tmp) / (0.5 + 0.3); // 只用距离 + SNR 两项(不含长度项)
|
||||
|
||||
if (L == 3) 三点全部写 quality_tmp; // 质量起点
|
||||
else 末点 quality = 前一点 quality * 0.8 + quality_tmp * 0.2; // 指数平滑
|
||||
```
|
||||
|
||||
- `Temp_track::quality` 是 **0~1** 的归一化值;起批时 `Trust_Track.Quality = 末点 quality`,`Point_sum = Valid_point_sum = L`;
|
||||
- 起批门限按**临时航迹长度 L** 取(比较对象是**末点**质量):L=3 → 0.7、L=4 → 0.6、L=5 → 0.5、L=6 → 0.4、L≥7 → 0.3;
|
||||
- 质量不达标时该临时航迹**不进入 `Track_to_start`**,继续留在 `temp_track` 中参与下一圈关联(受 `buff_round`/长度 10 的消亡约束)。
|
||||
|
||||
> 注意:质量只在「点-临时航迹关联」路径更新,阶段三(点 × 1 点航迹头 → 2 点临时航迹)不写 `quality`;2 点航迹要到下一圈被延长成 3 点时才会首次获得质量值,这与其本来也不能起批(长度不足)是一致的。
|
||||
|
||||
---
|
||||
|
||||
## 9. 阶段六:临时航迹消亡
|
||||
@@ -509,7 +535,7 @@ if ((*Iter)[n-1].buff_round > 2 || n >= 10) erase;
|
||||
| **1. 生成航迹头** | 未被阶段二/三消费(`Use_Flag==0`);创建时 `buff_round=1`(L77-114) |
|
||||
| **2. 航迹头 → 2 点**(L325, L368-372) | 航迹头 `size==1` 且 `buff_round ≥ 2`;`dis ≤ V_MAX·ΔT`;`dis ≥ V_MIN·ΔT`;`dis ≥ abs(vr_p)·ΔT`;`dis ≥ abs(vr_h)·ΔT`;`vr_p·vr_h > 0`(隐含 `ΔT > 0`) |
|
||||
| **3. 2 点 → 3 点及以上**(L164, L191, L221) | 临时航迹 `size > 1` 且末点 `buff_round ≥ 2`;`abs(r_p − r_末点) ≥ 5 m`;`d ≤ 8`(代码写 `d² ≤ 64`);`α < 60°`;`vr_p·vr_末点 > 0` |
|
||||
| **4. 转可靠航迹**(L484, L556) | `track_start_point_num ≤ L ≤ 10`;末点不在起批屏蔽区;同源去重后保留;`trust_track.size() < 500` 且成功分配航迹号 |
|
||||
| **4. 转可靠航迹**(L484, L556) | `track_start_point_num ≤ L ≤ 10`;末点不在起批屏蔽区;**末点质量 ≥ 按 L 取的门限(V1.5.8)**;同源去重后保留;`trust_track.size() < 500` 且成功分配航迹号 |
|
||||
| **5. 消亡**(L686) | `末点.buff_round > 2`(连续 2 圈无新点)或 `长度 ≥ 10` |
|
||||
|
||||
### 10.2 门限汇总
|
||||
@@ -526,6 +552,8 @@ if ((*Iter)[n-1].buff_round > 2 || n >= 10) erase;
|
||||
| 允许丢圈数 | 1 圈(`buff_round > 2` 消亡) | L686 | ❌ |
|
||||
| 航迹头上限等待 | 2 圈 | L686(1 点航迹同判据) | ❌ |
|
||||
| 起批屏蔽区 | ≤30 个矩形 | `RadarPara.track_prohibite_area_*` | ✅ |
|
||||
| 起批最低质量(V1.5.8) | L3→0.7 / L4→0.6 / L5→0.5 / L6→0.4 / L≥7→0.3 | `TRACK_START_QUALITY_L3~L7` | 编译期 |
|
||||
| 质量权重(V1.5.8) | 距离 0.5 / SNR 0.3 / 长度 0.2 | `TRACK_QUALITY_*_WEIGHT` | 编译期 |
|
||||
| 航迹数上限 | 500 | `MAX_TRACK_INDEX` | 编译期 |
|
||||
|
||||
---
|
||||
@@ -675,7 +703,8 @@ $$
|
||||
| `GNSS_time` | 点透传 | |
|
||||
| `Flag_Point` | 恒为 **1**(实点) | |
|
||||
| `Track_Mode` | 恒为 **0**(TWS) | |
|
||||
| **未赋值** | `Flag_Direction`、`x_Predict/y_Predict/z_Predict`、`Range_Predict/Azimuth_Predict/Elevation_Predict`、`Target_Type`、`prf_point`、`v_z`、`amp_asv_point`、`prn_fftn_point` | DLL 不清零该数组,宿主读到的是其自身缓存的旧值/未初始化值。注意 `Flag_Direction` 只在关联输出路径赋值(`track_asso.cpp` L129 / `track_asso_tas.cpp` L93),起批输出不写该字段。该字段的判据已由 f249fdc 的 `vr_point > 0 ? 1 : 0`(实测径向速度,受多普勒速度模糊影响符号可能取反)改为 fc49707 + 42b598e 的**航向-位置夹角法**:`Direction_Angle = atan2(X[4], X[1])`(弧度转度后同时输出到 `Direction_Angle`),`x`、`y` 为经 `Work_Parameter.Sys_delay` 补偿后的位置、`r` 为其模,`acos((-x·cos(Direction_Angle) - y·sin(Direction_Angle))/r) < π/2` 判为靠近(1)、否则远离(0),即滤波速度方向与"雷达→目标"位置方向夹角超 90° 判为接近。另 `amp_asv_point` / `prn_fftn_point` 属 e8c56f9 新增,`data_preprocess()` **现已**把 `DataRev.amp_asv / prn_fftn` 搬入 `PointRecv`(TWS 与 TAS 分支均赋值,并随 `RdpRecPoint` 落库),因此 TWS 关联/输出路径的该字段已有有效来源;TAS 关联与输出路径(`track_asso_tas.cpp`)仍未涉及这两个字段,TAS 输出行中它们保持宿主原值 |
|
||||
| `Quality` | **该历史点的临时航迹质量 × 100**(V1.5.8) | 内部 `quality` 为 0~1,输出折算为 0~100;同一条航迹的各个历史点可能取值不同(L=3 时三点相同,之后只有末点更新) |
|
||||
| **未赋值** | `Flag_Direction`、`x_Predict/y_Predict/z_Predict`、`Range_Predict/Azimuth_Predict/Elevation_Predict`、`Target_Type`、`prf_point`、`v_z`、`amp_asv_point`、`prn_fftn_point` | DLL 不清零该数组,宿主读到的是其自身缓存的旧值/未初始化值。注意 `Flag_Direction` 只在关联输出路径赋值(`track_asso.cpp` / `track_asso_tas.cpp`),起批输出不写该字段。该字段的判据已由 f249fdc 的 `vr_point > 0 ? 1 : 0`(实测径向速度,受多普勒速度模糊影响符号可能取反)改为 fc49707 + 42b598e 的**航向-位置夹角法**:`Direction_Angle = atan2(X[4], X[1])`(弧度转度后同时输出到 `Direction_Angle`),`x`、`y` 为经 `Work_Parameter.Sys_delay` 补偿后的位置、`r` 为其模,`acos((-x·cos(Direction_Angle) - y·sin(Direction_Angle))/r) < π/2` 判为靠近(1)、否则远离(0),即滤波速度方向与"雷达→目标"位置方向夹角超 90° 判为接近。另 `amp_asv_point` / `prn_fftn_point` 属 e8c56f9 新增,`data_preprocess()` **现已**把 `DataRev.amp_asv / prn_fftn` 搬入 `PointRecv`(TWS 与 TAS 分支均赋值,并随 `RdpRecPoint` 落库),因此 TWS 关联/输出路径的该字段已有有效来源;TAS 关联与输出路径(`track_asso_tas.cpp`)仍未涉及这两个字段,TAS 输出行中它们保持宿主原值 |
|
||||
|
||||
---
|
||||
|
||||
@@ -697,6 +726,8 @@ $$
|
||||
12. **`PI` 为 float 常量**(3.1415926f)参与双精度运算,角度换算存在约 1e-7 量级偏差,属既有实现风格。
|
||||
13. **精度/量纲提醒**:`Temp_track::vr` 直接取点的 `Velocity`(多普勒)作为径向速度,EKF 关联时用于残差折叠(盲速 `v_bind`)与符号判据;若宿主的 `Velocity` 存在模糊,符号判据 `vr_p·vr_末点 > 0` 可能失效。
|
||||
14. **输出数组行号可能越界(极端场景)**:容量判据用 `trust_track->size() < 500`,而 `Trust_Track_Output` 的行计数已在 `track_asso` 阶段按「消亡前」的航迹数推进,中间的 `track_die` 删除 D 条后腾出的配额会让起始流程多写 D 行;当 D ≥ 2 且当圈起批数占满配额时,写入行号可超过 `MAX_TRACK_NUM=500`(详见 2.3)。建议把判据改为同时校验 `*Trust_track_num_Output < MAX_TRACK_NUM` 与 `trust_track->size() < MAX_TRACK_INDEX`。
|
||||
15. **起批质量门限比较的是「末点」质量而非整条航迹质量(V1.5.8)**:`tmp_track_to_trust_track()` 取 `(*Iter)[L-1].quality` 与按长度取的门限比较,而该质量在 L>3 时只是末点的指数平滑值(L=3 时三点同值),并不代表整条临时航迹的平均质量;长度越大门限越低,实际是「用更宽松的门限校验最新一点」。
|
||||
16. **起批质量来源依赖阶段二**:`quality` 只在「点-临时航迹关联」成功后更新,阶段三产生的 2 点临时航迹不带质量值;长度 3 的临时航迹在第三次延长时写入三点同值,因此其起批质量有定义。若将来把起批点数放宽到 3 以下(当前接口校验 3~9),则会出现质量恒为 0、永远无法通过质量门限的情况。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user