1032 lines
86 KiB
Markdown
1032 lines
86 KiB
Markdown
# 雷达数据处理 DLL(data_process_class_dll)
|
||
|
||
> X256 雷达数据处理动态链接库:将雷达输出的原始点迹(TWS/TAS)处理为稳定可靠的目标航迹,并给出 TAS 跟踪波束控制指令。
|
||
> 仓库 simianzhen256-v1.5.5-ms-vscode(上游 simianzhen256,v1.5.5;已由 Qt/qmake 工程迁移为 VS Code + CMake 工程,编译器为 MSVC 2022 / v143,C++17,x64 目标)。
|
||
|
||
---
|
||
|
||
## 目录
|
||
|
||
1. [项目简介](#1-项目简介)
|
||
2. [功能特性](#2-功能特性)
|
||
3. [目录结构](#3-目录结构)
|
||
4. [构建与环境](#4-构建与环境)
|
||
5. [总体架构](#5-总体架构)
|
||
6. [关键数据结构](#6-关键数据结构)
|
||
7. [外部接口与调用流程](#7-外部接口与调用流程)
|
||
8. [处理流程总览](#8-处理流程总览)
|
||
9. [算法实现详解](#9-算法实现详解)
|
||
10. [参数说明](#10-参数说明)
|
||
11. [已知问题与限制](#11-已知问题与限制)
|
||
12. [版本历史](#12-版本历史)
|
||
13. [参考文档](#13-参考文档)
|
||
|
||
---
|
||
|
||
## 1. 项目简介
|
||
|
||
本仓库是一个 **Windows 动态链接库**,实现某型雷达(内部代号 X256,按扫描体制分为 **相扫 X256_PS** 与 **机扫 X256_MS** 两种构建)的 **航迹数据处理** 功能,包括:
|
||
|
||
- 输入点迹预处理与点迹凝聚(滑窗凝聚)
|
||
- 边扫描边跟踪(TWS)与边跟踪边扫描(TAS)双通道处理
|
||
- 逻辑法航迹起始(3~9 点起批,含屏蔽区、角度/波门约束)
|
||
- IMM + 扩展卡尔曼滤波(EKF,含多普勒速度)航迹维持
|
||
- 最近邻(NN)点航关联
|
||
- 航迹外推、消亡与航迹号管理
|
||
- TAS 手动转跟踪与跟踪波束调度输出
|
||
|
||
**技术栈**:C++(MSVC 2022 / v143 工具集,C++17)、Eigen 3(随仓库内置,仅用 Eigen/Dense)、CMake ≥ 3.21。
|
||
|
||
**处理约定**:
|
||
|
||
| 项目 | 约定 |
|
||
|---|---|
|
||
| 时间戳 | CPI 时间 / GNSS 时间均为 long long 毫秒(64 位);航迹时间 T_track 同样为毫秒,参与运算时除以 1000 转秒 |
|
||
| 角度 | 外部接口用度(°),内部统一弧度;输出航向角/方位/俯仰为度 |
|
||
| 坐标 | 直角坐标系 x/y 为水平面投影,z = 目标高度 + 雷达平台高度 |
|
||
| 点迹类型 | point_type = 0 为 TWS,point_type = 1 为 TAS |
|
||
| 跟踪模式 | Track_Mode = 0 为 TWS,Track_Mode = 1 为 TAS |
|
||
|
||
---
|
||
|
||
## 2. 功能特性
|
||
|
||
- **双模式处理管线**:data_preprocess 按输入类型与扫描圈完成标志返回 0/1/2/3(TWS 以方位波位号 == 0 判为一圈完成,机扫转台反转不再误判),track_process 据此调度 TWS 凝聚/关联/起始或 TAS 凝聚/关联。
|
||
- **两帧滑窗点迹凝聚**: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)。
|
||
- **点迹附加信息字段扩展(需同步重编译宿主)**:`DataRev` 新增 `amp_asv` / `prn_fftn`,`Track` 新增 `amp_asv_point` / `prn_fftn_point`,结构体布局随之变化,宿主必须使用同一版本头文件重新编译对接;当前输入侧尚未打通,详见 11.2。
|
||
- **高度维独立平滑**:按距离分段选择滑动平均窗长(5/6/7/9 点),抑制俯仰测量跳变。
|
||
- **TAS 波束控制**:手动转 TAS 目标入队(队列长度与容量随扫描体制切换),按最新时间戳外推输出跟踪波束(距离/方位/俯仰/批号)。
|
||
- **航迹生命周期管理**:外推轮数计数、超时消亡、手动删除、全清空(含各模块 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)。
|
||
- **数据记录调试功能(可选编译)**:`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`,同步写入、失败降级(不抛出、不影响雷达处理)。当前内置 2 个示例记录点(TWS 输入点迹 → `RdpRecPointTws`;输出航迹 → `RdpRecTrackOut`),新增记录数据只需「加结构体 + 注册 + 一行记录点」,详见 docs/data_record_debug.md(见 4.3、10.1、11.3)。
|
||
|
||
---
|
||
|
||
## 3. 目录结构
|
||
|
||
```text
|
||
.
|
||
├── CMakeLists.txt # CMake 构建脚本(扫描模式切换、导出宏、输出目录)
|
||
├── CHANGELOG.md # 变更日志(Keep a Changelog 格式,按 git 提交记录维护)
|
||
├── README.md # 本文件:项目说明(架构、接口、流程、算法、参数)
|
||
├── requirements.md # 需求说明:数据记录调试功能修改要求(结构体经 ormpp 写入 SQLite、Release 可屏蔽、数据分类入不同表、宏记录点;原日志文件输出需求已实现)
|
||
├── archived_docs/ # 过期文档留档(仅作历史参考;接口与流程以本 README 与 docs/ 专项说明为准)
|
||
│ ├── BUG_REPORT.md # 全量逻辑 BUG 分析报告(P0~P3,37 项)
|
||
│ └── BUG_FIX_REPORT.md # BUG 修复报告(修复明细 + 编译验证结果)
|
||
├── docs/ # 专项说明文档(按当前源码整理,与 README 互补)
|
||
│ ├── data_process_flow_report.md # 数据处理流程与关键逻辑说明(前处理/判圈、凝聚、关联与滤波、起始、外推消亡、TAS 波束、参数脉络)
|
||
│ ├── track_init_readme.md # 航迹起始(Track Init)详细逻辑说明(阶段流程、条件汇总、输出字段映射、风险点、代码索引)
|
||
│ └── data_record_debug.md # 数据记录调试功能说明(开关与构建、运行期行为、表结构约定、新增记录点四步配方、示例记录点、查询示例)
|
||
├── design_docs/ # 设计与讨论资料留档(被 .gitignore 忽略、不入库;含设计讨论、产品介绍与 README/流程报告的导出、渲染版本)
|
||
├── .vscode/ # VS Code 工程配置
|
||
│ ├── settings.json # cmake.generator=NMake、MSVC2022 x64 环境变量、compile_commands
|
||
│ ├── cmake-variants.yaml # X256_PS / X256_MS × Release / Debug 变体
|
||
│ ├── tasks.json # 配置/构建/清理任务(MSVC2022 x64)
|
||
│ └── scripts/ # 构建脚本(纯 ASCII,避免 cmd 代码页问题)
|
||
│ ├── msvc_env.bat # 共享环境设置:定位 VS2022/cl.exe 并调用 vcvarsall.bat(x64)
|
||
│ ├── configure.bat # CMake 配置(含旧工具集构建树自动清理)
|
||
│ ├── build.bat # CMake 构建
|
||
│ └── clean.bat # CMake 清理
|
||
├── backup/
|
||
│ └── data_process_class_dll/
|
||
│ ├── data_process_class_dll.pro # 迁移前的 Qt/qmake 工程文件(备份)
|
||
│ └── data_process_class_dll.pro.user
|
||
├── third_party/ # 内置第三方源码(按上游原样保存,来源/版本/升级方式见其 UPSTREAM.md)
|
||
│ └── ormpp/ # ormpp 0.2.0 + iguana 1.0.5 + frozen + SQLite 3.49.1 amalgamation(Apache-2.0 / 公有领域)
|
||
├── data_process_class_dll/ # 源码目录
|
||
│ ├── data_process_class_dll.h # 对外接口:DataRev/Track/TrackingBeam/RadarPara 结构体、抽象基类、工厂类
|
||
│ ├── data_process_class_dll_global.h # DLL 导入导出宏
|
||
│ ├── data_process_class_dll.cpp # 工厂实现(GetB/Destroy 单例)
|
||
│ ├── rdp_log.h / .cpp # 日志输出模块:rdbuf() 重定向 std::cout、RDP_LOG 宏(开关宏在 parameters.h)
|
||
│ ├── rdp_record.h / .cpp # 数据记录调试模块:结构体→SQLite 表(内置 ormpp)、RDP_RECORD/RDP_RECORD_BATCH 宏、按实体自动建表、失败降级(开关由 CMake 选项 RDP_DATA_RECORD 控制;实现以 C++20 独立编译)
|
||
│ ├── rdp_record_entity.h # 记录实体(=数据表)定义区:新增需要记录的数据在此加结构体并写 RDP_RECORD_DECLARE
|
||
│ ├── data_process.h / .cpp # Data_Process 实现:接口分发、TWS/TAS 主流程、参数管理、清空/删除/转跟踪
|
||
│ ├── struct.h # 内部结构体:PointRecv / Trust_Track / Temp_track / Tracking_Target
|
||
│ ├── parameters.h # 编译期宏参数(按 MECHANICAL_SCANNING / PHASE_SCANNING 分两组)
|
||
│ ├── dot_coh.h / .cpp # TWS 点迹凝聚(含两帧滑窗缓冲)
|
||
│ ├── dot_coh_tas.h / .cpp # TAS 点迹凝聚
|
||
│ ├── coor_trans.h / .cpp # 极坐标 ↔ 直角坐标转换
|
||
│ ├── kalman.h / .cpp # 卡尔曼滤波:两点/三点初始化、线性 KF、EKF(含多普勒)、统计距离、盲速计算
|
||
│ ├── track_asso.h / .cpp # TWS 航迹关联:IMM 交互 → 滤波 → 输出、统计距离/高度/距离门限、高度平滑
|
||
│ ├── track_asso_tas.h / .cpp # TAS 航迹关联(独立实现,量测门限与数据率不同)
|
||
│ ├── track_init.h / .cpp # 逻辑法航迹起始:点-临时航迹关联、点-航迹头关联、转可靠航迹、屏蔽区
|
||
│ ├── track_init_direct_tracking.h/.cpp# 引导跟踪航迹起始(当前入口为空实现,未启用)
|
||
│ ├── track_asso_direct_tracking.h/.cpp# 引导跟踪航迹关联(未加入 CMake 构建)
|
||
│ ├── track_die.h / .cpp # TWS 航迹消亡
|
||
│ ├── track_die_tas.h / .cpp # TAS 航迹消亡
|
||
│ ├── tas_ctrl.h / .cpp # TAS 波束控制:目标队列增删、波束输出、禁止区判断
|
||
│ ├── track_index_mangement.h / .cpp # 航迹号 1~500 分配/复用
|
||
│ └── Eigen/ # 内置 Eigen 3 头文件库(仅用 Eigen/Dense)
|
||
├── build/ # 构建产物(被 .gitignore 忽略)
|
||
│ ├── X256_PS/ # 相扫构建目录(含 bin/data_process_class_dll.dll、rdp_playback.exe 等)
|
||
│ ├── X256_MS/ # 机扫构建目录
|
||
│ └── output/ # 早期打包导出(其中 data_process_class_dll.h 为旧版 32 位时间戳接口,勿作为当前 API 依据)
|
||
├── rdp_logs/ # 日志输出目录(运行时自动创建于宿主进程当前工作目录下,被 .gitignore 忽略)
|
||
├── rdp_records/ # 数据记录库输出目录(运行时自动创建于宿主进程当前工作目录下,被 .gitignore 忽略;仅记录功能启用时产生)
|
||
└── .gitignore
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 构建与环境
|
||
|
||
### 4.1 环境要求
|
||
|
||
| 组件 | 要求 |
|
||
|---|---|
|
||
| 操作系统 | Windows(构建脚本默认按 D:\APP\VisualStudio2022 与 Windows SDK 10.0.26100.0 配置,可用环境变量覆盖) |
|
||
| 编译器 | Microsoft Visual C++ 2022(v143 工具集,`_MSC_VER` 19.44)**x64**(`D:\APP\VisualStudio2022\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x64\cl.exe`) |
|
||
| C++ 标准 | C++17(`/std:c++17`;由 `CMAKE_CXX_STANDARD 17` + `CMAKE_CXX_STANDARD_REQUIRED ON` 强制) |
|
||
| CMake | ≥ 3.21(VS2022 生成器自 3.21 起支持;本工程实际在 CMake 4.x 上验证) |
|
||
| 生成器 | NMake Makefiles(VS Code 配置与脚本均使用该生成器) |
|
||
| 线性代数 | 无需安装——Eigen 头文件已内置在源码目录 |
|
||
| 数据记录(可选调试功能) | 无需安装——ormpp / iguana / frozen / SQLite amalgamation 已内置在 `third_party/ormpp`(版本与升级方式见该目录 UPSTREAM.md);启用时记录模块以 C++20 独立编译,所需的 C 编译器由同一 VS 2022 工具集提供 |
|
||
|
||
### 4.2 扫描体制
|
||
|
||
通过 CMake 缓存变量 RADAR_SCAN_MODE 切换,对应 parameters.h 中的两组宏:
|
||
|
||
| 变量值 | 对应宏 | 构建目录 |
|
||
|---|---|---|
|
||
| PHASE_SCANNING | 相扫(X256_PS,默认) | build/X256_PS |
|
||
| MECHANICAL_SCANNING | 机扫(X256_MS) | build/X256_MS |
|
||
|
||
### 4.3 命令行构建
|
||
|
||
```bat
|
||
:: 需在 MSVC 2022 x64 环境中执行(先运行 vcvarsall.bat x64)
|
||
cmake -S . -B build/X256_PS -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DRADAR_SCAN_MODE=PHASE_SCANNING ^
|
||
-DCMAKE_CXX_COMPILER="D:/APP/VisualStudio2022/VC/Tools/MSVC/14.44.35207/bin/Hostx64/x64/cl.exe"
|
||
cmake --build build/X256_PS
|
||
```
|
||
|
||
或直接使用仓库提供的脚本(内部已通过 msvc_env.bat 调用 vcvarsall.bat x64 并校验 cl.exe):
|
||
|
||
```bat
|
||
.vscode\scripts\configure.bat build/X256_PS PHASE_SCANNING Release
|
||
.vscode\scripts\build.bat build/X256_PS
|
||
.vscode\scripts\clean.bat build/X256_PS
|
||
```
|
||
|
||
configure.bat 会在构建目录中写入 `.msvc_toolset` 标记;若该目录是用其它工具集(例如旧的 MSVC 2013 缓存)配置的,脚本会先整体删除该目录再重新配置,避免新旧目标文件混链。用 `set VS2022_DIR=...`、`set MSVC_TOOLSET_VERSION=...`、`set MSVC_TARGET_ARCH=x86` 可覆盖默认的 VS 安装路径、工具集版本与目标架构。
|
||
|
||
数据记录调试功能由缓存变量 `RDP_DATA_RECORD` 控制,`configure.bat` 的第 4 个参数即该变量(取值 `AUTO`/`ON`/`OFF`,缺省 `AUTO`):
|
||
|
||
```bat
|
||
:: AUTO(默认):Debug 构建启用、Release 构建关闭——交付构建不做任何记录
|
||
.vscode\scripts\configure.bat build/X256_PS PHASE_SCANNING Debug AUTO
|
||
:: 显式关闭(Release 交付推荐)或显式开启(临时在 Release 中排查)
|
||
.vscode\scripts\configure.bat build/X256_PS PHASE_SCANNING Release OFF
|
||
.vscode\scripts\configure.bat build/X256_PS PHASE_SCANNING Debug ON
|
||
```
|
||
|
||
启用时配置阶段打印 `数据记录调试功能:启用(C++20 静态库 rdp_record + 内置 SQLite)`,并额外构建静态库 `rdp_record`(记录模块 + SQLite,链接进 DLL);关闭时打印 `...:关闭(不编译记录模块,RDP_RECORD 为空操作)`,记录模块源码完全不参与编译。开关语义、表结构约定与新增记录点配方见 docs/data_record_debug.md。
|
||
|
||
在 VS Code 中可直接运行任务(tasks.json):「CMake: 配置并构建 X256_PS (Release)」等,默认任务为 X256_PS Release。
|
||
|
||
### 4.4 产物
|
||
|
||
| 产物 | 位置 |
|
||
|---|---|
|
||
| data_process_class_dll.dll(+ .pdb) | build/<X256_XX>/bin/ |
|
||
| 导入库 data_process_class_dll.lib | build/<X256_XX>/lib/ |
|
||
| 安装(cmake --install) | DLL/导入库 → bin、lib,公开头文件 → include |
|
||
| compile_commands.json | 构建根目录(供 VS Code IntelliSense 使用) |
|
||
| rdp_record.lib(仅记录功能启用时) | build/<X256_XX>/lib/ —— 记录模块静态库(含 SQLite),已链接进 DLL,**无需随 DLL 分发** |
|
||
|
||
产物为 **x64(AMD64)** 目标。宿主程序必须是 64 位、且使用与本 DLL 同一版本头文件重新编译——MSVC 2013 → MSVC 2022 同时伴随 x86 → x64 的 ABI 变化,旧的 32 位宿主无法加载该 DLL。
|
||
|
||
仓库 build/X256_PS/bin/ 内原附带 **rdp_playback.exe**(回放测试工具,依赖 Qt5Core.dll、sqlite3.dll,配置样例 RadarConfigParam.ini,可回放 .db 记录的点迹数据验证 DLL 输出),该工具不在本仓库源码范围内、当前构建目录中亦不存在,需自行放置;由于 DLL 已改为 x64,配套的 rdp_playback.exe 必须是 **x64 版本**(同时其自带 Qt5Core.dll / sqlite3.dll 也需为 x64),32 位版本无法加载新版 DLL。
|
||
|
||
### 4.5 编译警告处理
|
||
|
||
- 源码文件统一使用 **带 BOM 的 UTF-8** 编码保存;`CMakeLists.txt` 对 MSVC 统一追加 `/utf-8`,中文字符串与注释不再受系统代码页影响(消除 C4819),BOM 仅作为编辑器/旧工具的兼容保留。
|
||
- `CMakeLists.txt` 显式指定 `/W3`:CMake 3.15(策略 CMP0092)起不再把 `/W3` 放进 `CMAKE_CXX_FLAGS`,本工程此前一直以 `/W3` 构建,故显式恢复以保持警告级别不变。
|
||
- 修复了 `/W3` 下全部 C4819(源文件字符集)、C4018(signed/unsigned 不匹配)、C4244(类型转换可能丢失数据)警告:循环变量按需改为 `size_t`,窄化转换改为 `static_cast` 显式转换,不改变原有计算逻辑。
|
||
- MSVC 2022 在 `/W3` 下新增报出的 C4267(`size_t` → `int` 窄化)共 17 处已按同一约定修复(`track_asso.cpp`、`track_asso_tas.cpp`、`track_init.cpp`、`track_init_direct_tracking.cpp`、`tas_ctrl.cpp` 中改为 `static_cast<int>(...)`),同样不改变计算逻辑。
|
||
- 当前四种配置(X256_PS / X256_MS × Release / Debug)均以 **0 warning、0 error** 通过编译。
|
||
- cl.exe 的诊断信息为中文(跟随 VS 安装语言,`VSLANG=1033` 对 VS2022 的 cl.exe 无效),构建日志中偶见 `注意: 包含文件:` 行泄漏,属 CMake 依赖扫描的显示噪声,头文件依赖(`CMakeFiles/*.dir/**/*.obj.d`)记录完整,不影响增量编译。
|
||
- **第三方库告警例外(仅记录功能启用时)**:数据记录模块的第三方依赖按上游原样内置在 `third_party/ormpp`(保留上游字节,含换行符,不转 BOM/编码),其中 `third_party/ormpp/thirdparty/sqlite3/sqlite3.c` 以源文件级 `/w` 单独编译,`data_process_class_dll/rdp_record.cpp` 用 `#pragma warning(push, 0)` / `(pop)` 包裹第三方头;除此之外本工程源码仍按上一条的 `/W3` 零告警标准编译(X256_PS/X256_MS × Release/Debug 四种配置实测 0 warning、0 error)。
|
||
|
||
### 4.6 编译器升级说明(MSVC 2013 → MSVC 2022)
|
||
|
||
| 项目 | 升级前 | 升级后 |
|
||
|---|---|---|
|
||
| 编译器 | Microsoft Visual C++ 2013(VS 12.0,`_MSC_VER` 1800) | Microsoft Visual C++ 2022(v143,`_MSC_VER` 1944,cl 19.44.35228) |
|
||
| 目标架构 | x86(32 位) | x64(AMD64) |
|
||
| C++ 标准 | C++11(编译器默认) | C++17(`/std:c++17`) |
|
||
| CMake 最低版本 | 3.10 | 3.21 |
|
||
| 新增/调整编译选项 | — | `/utf-8`(改为无条件)、`/Zc:__cplusplus`、`/W3`(显式恢复) |
|
||
|
||
- **`/Zc:__cplusplus`**:MSVC 默认把 `__cplusplus` 报为 `199711L`,加该选项后正确报 `201703L`,使依赖 `__cplusplus` 判断的第三方库(内置 Eigen 3.3.7)走标准分支。已验证 Eigen 3.3.7 在此组合下编译通过。
|
||
- **`/Zc:strictStrings` 仍仅在 Release 启用**:原限制(MSVC 2013 Debug 运行库与该选项冲突)已不存在,此处保持与原 qmake 工程一致的行为。
|
||
- **旧构建目录需清理**:MSVC 2013 的 CMake 缓存与目标文件不能跨编译器复用(nmake 会因目标文件时间戳较新而跳过重编译,导致新旧目标文件混链)。`configure.bat` 已内置自动清理:构建目录中无 `.msvc_toolset` 标记或标记与当前工具集不一致时,先删除整个构建目录再配置。
|
||
- **源码改动**:仅补齐 17 处 `static_cast<int>(...)` 显式窄化转换以消除 MSVC 2022 新增的 C4267 告警,未改动任何计算逻辑、接口与结构体布局;DLL 导出符号与升级前一致(差异仅为 x86 → x64 的名称修饰,如 `QAE` → `QEAA`、`PAV` → `PEAV`)。
|
||
- **兼容性风险点已核查**:C++17 移除的 `std::auto_ptr`、`std::random_shuffle`、`std::unary_function`/`binary_function`、`std::binder1st/2nd` 等在本工程源码与内置 Eigen 3.3.7 中均未被使用(Eigen 的相应特化本身带有 `__cplusplus`/`EIGEN_COMP_MSVC` 版本保护)。
|
||
|
||
---
|
||
|
||
## 5. 总体架构
|
||
|
||
### 5.1 设计模式
|
||
|
||
- **接口 + 工厂(单例)**:Data_process_class_dll(抽象基类,声明全部虚接口)→ Data_Process(具体实现)。宿主仅通过 Data_Process_Factory::GetB() / Destroy() 获取与销毁唯一实例。
|
||
- **模块化流水线**:Data_Process 按职责组合 Dot_Coh、Dot_Coh_TAS、Track_Asso、Track_Asso_Tas、Track_Init、Track_Die、Track_Die_Tas、TAS_Ctrl、Track_Ind_Mangement 等模块,各模块持有自身处理缓存并支持 reset()。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class Data_process_class_dll {
|
||
<<abstract, exported API>>
|
||
+data_preprocess(DataRev[150]) int
|
||
+track_process(Track[][10], int*, int[], int*, int) int
|
||
+Beam_Ctrl(TrackingBeam*, Track[][10], int*)
|
||
+direct_tracking_process(...) int
|
||
+track_clear_all() int
|
||
+track_delete(int, int[]) int
|
||
+tracking_start(int) int
|
||
+tracking_stop(int) int
|
||
+tracking_point(float) int
|
||
+track_process_parameters_initial(RadarPara) int
|
||
+track_process_parameters_modify(RadarPara) int
|
||
}
|
||
class Data_Process {
|
||
-Data_buffer / Data_buffer_tas : vector PointRecv
|
||
-point_recv / point_recv_tas : vector PointRecv
|
||
-trust_track : vector Trust_Track
|
||
-temp_track : vector Temp_track
|
||
-Work_Parameter : RadarPara
|
||
-dot_coh / dot_coh_tas / track_asso / track_asso_tas
|
||
-track_init / track_die / track_die_tas / tas_ctrl
|
||
}
|
||
class Data_Process_Factory {
|
||
-static p : Data_process_class_dll*
|
||
+static GetB() Data_process_class_dll*
|
||
+static Destroy()
|
||
}
|
||
class Dot_Coh
|
||
class Dot_Coh_TAS
|
||
class Track_Asso
|
||
class Track_Asso_Tas
|
||
class Track_Init
|
||
class Track_Die
|
||
class Track_Die_Tas
|
||
class TAS_Ctrl
|
||
class Track_Ind_Mangement
|
||
class kalman
|
||
class coor_trans
|
||
|
||
Data_process_class_dll <|-- Data_Process
|
||
Data_Process_Factory ..> Data_Process : creates
|
||
Data_Process *-- Dot_Coh
|
||
Data_Process *-- Dot_Coh_TAS
|
||
Data_Process *-- Track_Asso
|
||
Data_Process *-- Track_Asso_Tas
|
||
Data_Process *-- Track_Init
|
||
Data_Process *-- Track_Die
|
||
Data_Process *-- Track_Die_Tas
|
||
Data_Process *-- TAS_Ctrl
|
||
Track_Init *-- Track_Ind_Mangement
|
||
Track_Asso ..> kalman
|
||
Track_Asso_Tas ..> kalman
|
||
Track_Init ..> kalman
|
||
kalman ..> coor_trans
|
||
```
|
||
|
||
### 5.2 模块职责
|
||
|
||
| 类 / 文件 | 职责 |
|
||
|---|---|
|
||
| Data_Process(data_process.cpp) | 对外接口实现与流程编排:输入缓存、按 model 分发 TWS/TAS 流水线、参数管理、航迹清空/删除、手动转/停 TAS、手动标记/取消重点目标(primary_target_add/cancel)、波束控制转发 |
|
||
| Dot_Coh | TWS 点迹凝聚:两帧滑窗合并凝聚(dot_coh_process_buff) |
|
||
| Dot_Coh_TAS | TAS 点迹凝聚(单帧,距离/方位/速度三维门限) |
|
||
| 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)或手动删除标志置位时输出消亡批号并删除 |
|
||
| 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()` 调用;建表/插入失败一律降级(每个实体只提示一次),不影响雷达处理 |
|
||
| Track_Init_Direct_Tracking / Track_Asso_Direct_Tracking | 引导跟踪(direct tracking)专用起批/关联。**当前入口为空实现、未启用**;track_asso_direct_tracking.cpp 未加入 CMake 源列表 |
|
||
|
||
---
|
||
|
||
## 6. 关键数据结构
|
||
|
||
### 6.1 对外结构体(data_process_class_dll.h)
|
||
|
||
| 结构体 | 用途 | 要点 |
|
||
|---|---|---|
|
||
| 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、十字星数据透传 |
|
||
| TrackingBeam | TAS 跟踪波束指令 | open_flag、type、Range、Azi、Elev、TAS_track_index |
|
||
| Target_direct_tracking | 引导跟踪信息 | 批号、距离/方位/俯仰、开关(接口未启用) |
|
||
| RadarPara | 工作参数 | 见 [参数说明](#10-参数说明) |
|
||
|
||
### 6.2 内部结构体(struct.h)
|
||
|
||
| 结构体 | 用途 | 关键字段 |
|
||
|---|---|---|
|
||
| PointRecv | 内部点迹 | 距离/方位(弧度)/速度/幅度/高度/SNR/RCS/CPI/GNSS 时间、点迹号、使用标志、波位/PRF/频点、跟踪模式、点迹区号、归一化幅度 `amp_asv_point` / 速度维 FFT 点数 `prn_fftn_point`、十字星数据 |
|
||
| Trust_Track | 可靠航迹(IMM 全状态) | 航迹号、高度、航迹时间、更新标志 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]、极坐标点信息、时间戳、buff_round(已缓存圈数)、区号、关联标志 |
|
||
| 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` 新增 `primary_target_flag` 与 `amp_asv_point` / `prn_fftn_point`。宿主与 DLL 必须使用同一版本头文件并**同步重新编译**,否则字段错位。
|
||
|
||
---
|
||
|
||
## 7. 外部接口与调用流程
|
||
|
||
### 7.1 接口一览
|
||
|
||
| 接口 | 返回值 | 说明 |
|
||
|---|---|---|
|
||
| Data_Process_Factory::GetB() | 实例指针 | 获取单例(首次调用时创建) |
|
||
| Data_Process_Factory::Destroy() | — | 销毁实例并将指针置空 |
|
||
| 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 | 输入一帧点迹并缓存,返回处理模式(见下表) |
|
||
| track_process(Track[][10], &num, dieIdx[], &dieNum, model) | 1 | 按 data_preprocess 的返回值执行 TWS/TAS 处理 |
|
||
| Beam_Ctrl(TrackingBeam*, Track[][10], &num) | — | TAS 波束控制(内部清零并重填航迹输出计数) |
|
||
| track_clear_all() | 0 | 清空全部航迹/缓存并复位各模块状态 |
|
||
| track_delete(n, idx[]) | 0 | 按批号标记手动删除(下一轮消亡输出) |
|
||
| 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`,恢复普通消亡轮数) |
|
||
| tracking_point(azimuth) | 0 | 手动打跟踪波束——**未实现(保留空实现)** |
|
||
| direct_tracking_process(...) | 0 | 引导跟踪——**未实现(保留空实现)** |
|
||
|
||
> **输出语义(50e0b5c 起)**:`track_process(model=1/3)` 只把本圈**有更新**的航迹写入 `Trust_Track_Output`(关联到实点、外推成功,或 TAS 指定批号被更新),行数由 `Trust_track_num_Output` 给出;未更新(含外推超限)的航迹当圈不出现在输出中,宿主不能据输出行数推断航迹总数。输出数组内容由 DLL 覆盖写入指定行,其余行保持宿主原值(DLL 不清零整块数组)。
|
||
|
||
> 日志输出为 DLL 内部功能(不对外导出,接口见 10.1 的宏开关):首次 `GetB()` 创建实例时自动初始化(`RDP_LOG_ENABLE` 定义则将 `std::cout` 重定向到 `.\rdp_logs\` 下按日期+时间命名的日志文件,该宏当前为注释状态,见 10.1),`Destroy()` 销毁实例时恢复 `std::cout` 并关闭日志文件。
|
||
|
||
### 7.2 data_preprocess 返回值的含义
|
||
|
||
| 返回值 | 含义 | 触发条件 |
|
||
|---|---|---|
|
||
| 0 | 无效数据 | point_type 既非 0 也非 1 |
|
||
| 1 | **TWS 满一圈,执行航迹处理** | point_type==0 且当前帧方位波位号 == 0(7d5a56f 起改用波位号为 0 判满圈:机扫转台反转时波位号会变小但并未扫完一圈,原「波位号变小」判据会误判) |
|
||
| 2 | **TWS 未满一圈,继续蓄数据** | point_type==0 且方位波位号 != 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(不满圈)。
|
||
|
||
### 7.3 典型调用序列
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["Data_Process_Factory::GetB()"] --> B["track_process_parameters_initial(RadarPara)"]
|
||
B --> C{"接收一帧点迹"}
|
||
C --> D["model = data_preprocess(DataRev[150])"]
|
||
D --> E{"model ?"}
|
||
E -- "2 (TWS 蓄数据)" --> F["track_process(model=2) 滑窗凝聚"]
|
||
E -- "1 (TWS 一圈)" --> G["track_process(model=1) 关联/起批/消亡"]
|
||
E -- "3 (TAS)" --> H["track_process(model=3) TAS 关联/消亡"]
|
||
E -- "0" --> C
|
||
F --> C
|
||
G --> I["Beam_Ctrl() 输出跟踪波束"]
|
||
H --> I
|
||
I --> J{"手动操作?"}
|
||
J -- 是 --> K["tracking_start / tracking_stop / track_delete"]
|
||
K --> C
|
||
J -- 否 --> C
|
||
C -. "结束/重连" .-> L["track_clear_all() / Factory::Destroy()"]
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 处理流程总览
|
||
|
||
### 8.1 TWS 流程(model=1)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
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 滤波 → 模型输出"]
|
||
E --> F["track_die: 连续未关联超限 / 手动删除 → 输出消亡批号"]
|
||
F --> G["track_init: 点-临时航迹关联 → 点-航迹头关联 → 剩余点转新航迹头 → 起批转可靠航迹"]
|
||
G --> H["输出 Trust_Track_Output(含起批历史点)"]
|
||
H --> I["Beam_Ctrl: 手动 TAS 目标入队 / 波束输出"]
|
||
```
|
||
|
||
其中 model=2(未满一圈)只执行滑窗凝聚 dot_coh_process_buff,把上一帧凝聚完成的点输出到 point_recv 供下一圈的关联/起批使用,当前帧未凝聚点作为下一次的缓存——即「凝聚在前、关联在后、缓存一帧」的两帧滑窗结构。
|
||
|
||
输出环节(`track_asso_process()` 末尾)只写 `Track_Update_Flag==1` 的航迹:关联到实点、或外推成功(`Extrapolate_round <= MAX_EXTRAPOLATE_NUM` = 3)时置 1;外推超限的航迹不再推进位置与航迹时间,当圈也不输出,直到重新关联上实点才恢复(详见 9.9)。
|
||
|
||
### 8.2 TAS 流程(model=3)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["data_preprocess: 点迹入 Data_buffer_tas,记录 TAS_track_idx/latest_timestamp → model=3"] --> B["track_process(3)"]
|
||
B --> C["dot_coh_tas 单帧凝聚 → point_recv_tas"]
|
||
C --> D["track_asso_tas: 仅对 tas_track_idx 批号做 IMM+EKF 关联(含高度门限)"]
|
||
D --> E["未关联 → 按 latest_timestamp 外推(ΔT≤0 跳过)"]
|
||
E --> F["track_die_tas: TAS 连续未关联超上限 / 手动删除 → 消亡输出"]
|
||
F --> G["输出该批号航迹(point_type=1)"]
|
||
G --> H["Beam_Ctrl: 数据率门控 + 队内最早 CPI 目标 + 预测波束输出"]
|
||
```
|
||
|
||
TAS 输出同样受 `Track_Update_Flag` 门控:只有 `Track_Index == tas_track_idx` 且本圈有更新(关联到实点、或外推成功)时才向 `Trust_Track_Output` 写一行(`point_type=1`)。TAS 外推上限为 `MAX_EXTRAPOLATE_NUM_TAS`(相扫 5 / 机扫 48),判定方向与 TWS 相反(`Extrapolate_round >= 上限` 时才外推并输出),详见 9.9 与 11.2。
|
||
|
||
### 8.3 航迹起始流程(逻辑法)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A["本圈未关联点迹(point_recv → point_process)"] --> A1["临时航迹所有点的 buff_round +1"]
|
||
A1 --> B["① 点-临时航迹关联(≥2 点临时航迹、末点 buff_round≥2):EKF 统计距离波门 d²≤64、折角<60°、径向速度同号、|Δr|≥5m → 复制原航迹并追加新点"]
|
||
B --> C["② 点-航迹头关联(1 点航迹头、buff_round≥2):V_MIN·ΔT ≤ dis ≤ V_MAX·ΔT、径向速度同号、dis ≥ |vr_point|·ΔT 且 dis ≥ |v_track_head|·ΔT → 两点卡尔曼初始化(航迹头 + 新点 → 2 点临时航迹)"]
|
||
C --> D["③ 删除 Use_Flag==1 的点迹,剩余点全部转为新航迹头 Temp_track(1 点、buff_round=1)"]
|
||
D --> E{"④ 长度 ≥ track_start_point_num(3~9) 且 ≤10 且不在起批屏蔽区 ?"}
|
||
E -- 是 --> F["重复航迹去重(保留末点 d 更小者)→ 三点卡尔曼初始化"]
|
||
F --> G["转可靠航迹:分配航迹号 1~500,IMM 三模型同状态初始化 u=1/3"]
|
||
G --> H["输出前 track_start_point_num 个历史点 Trust_Track_Output[i][0..L-1]"]
|
||
E -- 否 --> I["留在临时航迹表,下一圈继续关联"]
|
||
H --> J["⑤ 临时航迹消亡:末点 buff_round>2 或 长度≥10"]
|
||
I --> J
|
||
```
|
||
|
||
> 顺序说明:`track_init_process_logic()` 中四步的先后顺序固定、不可颠倒——先延长已有临时航迹,再与航迹头配对,两步都走完才生成新航迹头,最后才把长度达标的临时航迹转为可靠航迹(因此当圈新建的 2 点临时航迹不可能当圈起批,长度刚达标的临时航迹则可以当圈起批);临时航迹消亡在第 ⑤ 步、即全部起始动作之后执行。
|
||
>
|
||
> 第 ① ② 步**互不排斥**:两者都只把命中的点迹标记 `Use_Flag=1`,航迹头关联并不检查临时航迹关联留下的标记,因此同一点迹可能既延长一条临时航迹、又开启一条新的两点临时航迹;两类关联也都不做一对一分配(同一条临时航迹可被本圈多个点延长,同一个航迹头也可与本圈多个点配对)。只有走完两步后才统一删除 `Use_Flag==1` 的点迹,其余点迹成为新航迹头。
|
||
|
||
---
|
||
|
||
## 9. 算法实现详解
|
||
|
||
### 9.1 坐标与量测转换
|
||
|
||
极坐标(距离 r、方位 θ,弧度)与直角坐标互转(coor_trans.cpp):
|
||
|
||
$$
|
||
x=r\cos\theta,\qquad y=r\sin\theta
|
||
\qquad\qquad
|
||
r=\sqrt{x^2+y^2},\qquad \theta=\operatorname{atan2}(y,x)\ \bmod 2\pi
|
||
$$
|
||
|
||
输入点高度由量测俯仰直接折算:h = R·sin(ε)(data_preprocess 中完成)。输出时航迹高度加雷达平台高度:z = h + H_radar。
|
||
|
||
**转换量测协方差**(用于以直角坐标为量测的线性滤波,kalman.cpp 中多处使用)。设 λθ = exp(-σa²/2)、λθ' = exp(-2σa²),则在量测 (r,θ) 处转换后的直角坐标量测噪声协方差为:
|
||
|
||
$$
|
||
R_{xx}=\left(\lambda_\theta^{-2}-2\right)r^2\cos^2\theta+\tfrac12\left(r^2+\sigma_r^2\right)\left(1+\lambda'_\theta\cos 2\theta\right)
|
||
$$
|
||
|
||
$$
|
||
R_{yy}=\left(\lambda_\theta^{-2}-2\right)r^2\sin^2\theta+\tfrac12\left(r^2+\sigma_r^2\right)\left(1-\lambda'_\theta\cos 2\theta\right)
|
||
$$
|
||
|
||
$$
|
||
R_{xy}=\left(\lambda_\theta^{-2}-2\right)r^2\sin\theta\cos\theta+\tfrac12\left(r^2+\sigma_r^2\right)\lambda'_\theta\sin 2\theta
|
||
$$
|
||
|
||
其中 σr、σa 由 SIGMA_R / SIGMA_A 宏给定(10 m / 0.02 rad)。
|
||
|
||
### 9.2 点迹凝聚
|
||
|
||
对同一 CPI(TWS 为相邻两 CPI 合并后)内所有点迹两两比较,门限满足且幅度较小者被标记删除(Use_Flag=1):
|
||
|
||
| 模式 | 距离门限 | 方位门限(环绕最小角差) | 速度门限 |
|
||
|---|---|---|---|
|
||
| work_mode==0(近程) | ≤ 80 m(DOT_COH_RANGE) | ≤ 6°(DOT_COH_AZI) | ≤ 2 m/s(DOT_COH_V) |
|
||
| work_mode!=0(中/远程) | ≤ 80 m | ≤ 6° | 不约束 |
|
||
|
||
方位差按环绕角处理:
|
||
|
||
$$
|
||
\Delta\theta = \min\left(|\theta_0-\theta_1|,\ 2\pi-|\theta_0-\theta_1|\right)
|
||
$$
|
||
|
||
凝聚后删除 r<100 m 或 r>100000 m 的量程外点。TWS 的 dot_coh_process_buff 将上一帧缓存点标记区号 1、当前帧点标记区号 2,合并凝聚后:区号 1 的点输出到 point_recv(进入关联),区号 2 的点存入 data_input_buff 供下一帧凝聚——形成两帧滑窗。
|
||
|
||
### 9.3 航迹起始(逻辑法)
|
||
|
||
每圈(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 起的判据):
|
||
|
||
$$
|
||
V_{min}\Delta T \le d_{12} \le V_{max}\Delta T,\qquad
|
||
v_{r,point}\cdot v_{r,head}>0,\qquad
|
||
d_{12} \ge \left|v_{r,point}\right|\Delta T,\qquad
|
||
d_{12} \ge \left|v_{r,head}\right|\Delta T
|
||
$$
|
||
|
||
其中 d12 为两点间平面距离,ΔT 为时间差(秒),V_min/V_max 取 `RadarPara.V_MIN / V_MAX`(代码中 vmax 的近程/中远程分支取值相同,均为 V_MAX)。后两条为**多普勒-几何一致性约束**:切向飞行目标在 ΔT 内的实际位移远小于 |vr|·ΔT,据此被排除,用于限制切向高速点迹起批出的短航迹。
|
||
|
||
> 历史行为(已注释停用):原先按扫描体制与距离分段收紧速度门限——近程 r≥1000 用全速、r<1000 用半速;中远程 r≥2000 用全速、r<2000 取下限 1/2·V_min·ΔT / 上限 1/3·V_max·ΔT。
|
||
|
||
关联成功用 **两点卡尔曼初始化**(见 9.5.2)生成 2 点临时航迹:第 1 点为原航迹头,第 2 点为该点迹。
|
||
|
||
#### (3) 剩余点迹转航迹头
|
||
|
||
第 (1)(2) 步结束后统一删除 `Use_Flag==1` 的点迹;剩余点迹回写 `point_recv`(随后被整体清空),并**逐条新建 1 点临时航迹(航迹头)**:位置直接取点迹的直角坐标、速度置 0、`buff_round = 1`。新航迹头当圈不再参与任何关联,只能从下一圈开始按第 (2) 步配对。
|
||
|
||
#### (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:
|
||
|
||
- 三个 IMM 子模型用同一状态/协方差初始化,模型概率 u = [1/3, 1/3, 1/3];
|
||
- 分配航迹号(1~500,见 9.8);
|
||
- 输出仅写入前 L 个历史点(`Trust_Track_Output[i][0..L-1]`,`Point_Sum = L`),航迹长度大于 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 模型)
|
||
|
||
TWS/TAS 关联共用同一套 IMM 结构(代码各自实现一份)。状态 [x, vx, ax, y, vy, ay],x/y 两轴解耦,机动相关时间常数固定 α = 0.2。
|
||
|
||
**模型转移概率矩阵**:
|
||
|
||
$$
|
||
P_t=\begin{bmatrix}0.8&0.15&0.05\\0.3&0.4&0.3\\0.05&0.15&0.8\end{bmatrix}
|
||
$$
|
||
|
||
**交互(mix)**:归一化常数与混合概率
|
||
|
||
$$
|
||
\bar c_j=\sum_{i}p_{ij}\,\mu_i,\qquad
|
||
\mu_{i|j}=\frac{p_{ij}\,\mu_i}{\bar c_j}
|
||
$$
|
||
|
||
混合状态 X0j = Σ μ(i|j) Xi,混合协方差 P0j = Σ μ(i|j) [Pi + (Xi − X0j)(Xi − X0j)ᵀ](实现中对 c̄j 做了 ≥ 1e-12 钳位防除零)。
|
||
|
||
**子模型滤波**:每个模型以各自的 F、Qj 做 EKF 预测/更新(9.5)。
|
||
|
||
**模型概率更新**:以新息协方差行列式归一化的高斯似然
|
||
|
||
$$
|
||
\Lambda_j=\frac{1}{\sqrt{(2\pi)^3\det S_j}}\exp\left(-\tfrac12 d_j\right),\qquad
|
||
\mu_j'=\frac{\Lambda_j\,\bar c_j}{\sum_k \Lambda_k\,\bar c_k}
|
||
$$
|
||
|
||
其中 dj 为该模型的马氏距离平方。实现中 det Sj ≤ 1e-12 时 Λj = 0,分母 ≤ 1e-12 时保持上一拍概率。
|
||
|
||
**输出融合**:
|
||
|
||
$$
|
||
\hat X=\sum_j\mu_j'\hat X_j,\qquad
|
||
P=\sum_j\mu_j'\left[P_j+\left(\hat X_j-\hat X\right)\left(\hat X_j-\hat X\right)^T\right]
|
||
$$
|
||
|
||
### 9.5 卡尔曼滤波
|
||
|
||
#### 9.5.1 Singer 模型状态转移与过程噪声
|
||
|
||
每轴状态转移矩阵(α = 0.2,T = ΔT 为时间差,秒):
|
||
|
||
$$
|
||
F_{axis}=\begin{bmatrix}
|
||
1 & T & \dfrac{\alpha T-1+e^{-\alpha T}}{\alpha^2}\\[2mm]
|
||
0 & 1 & \dfrac{1-e^{-\alpha T}}{\alpha}\\[2mm]
|
||
0 & 0 & e^{-\alpha T}
|
||
\end{bmatrix}
|
||
,\qquad
|
||
F=\begin{bmatrix}F_{axis}&0\\0&F_{axis}\end{bmatrix}
|
||
$$
|
||
|
||
过程噪声 Qj = qj · Q̄,Q̄ 每轴为对称矩阵,元素为 Singer 模型离散化的标准结果:
|
||
|
||
$$
|
||
\bar q_{11}=\frac{1}{2\alpha^5}\left[1-e^{-2\alpha T}+2\alpha T+\frac{2\alpha^3T^3}{3}-2\alpha^2T^2-4\alpha T e^{-\alpha T}\right]
|
||
$$
|
||
|
||
$$
|
||
\bar q_{12}=\frac{1}{2\alpha^4}\left[e^{-2\alpha T}+1-2e^{-\alpha T}+2\alpha T e^{-\alpha T}-2\alpha T+\alpha^2T^2\right]
|
||
$$
|
||
|
||
$$
|
||
\bar q_{13}=\frac{1}{2\alpha^3}\left[1-e^{-2\alpha T}-2\alpha T e^{-\alpha T}\right]
|
||
$$
|
||
|
||
$$
|
||
\bar q_{22}=\frac{1}{2\alpha^3}\left[4e^{-\alpha T}-3-e^{-2\alpha T}+2\alpha T\right]
|
||
$$
|
||
|
||
$$
|
||
\bar q_{23}=\frac{1}{2\alpha^2}\left[e^{-2\alpha T}+1-2e^{-\alpha T}\right],
|
||
\qquad
|
||
\bar q_{33}=\frac{1}{2\alpha}\left[1-e^{-2\alpha T}\right]
|
||
$$
|
||
|
||
过程噪声强度 qj 按航迹速度分档(对应三个机动等级):
|
||
|
||
| 模型 | TWS 版(track_asso.cpp) | TAS 版(track_asso_tas.cpp) |
|
||
|---|---|---|
|
||
| 模型 1(低机动) | q1 = 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 字段当前未参与计算(模型 1 只用 slow);各档系数以源码为准。
|
||
|
||
#### 9.5.2 两点初始化(临时航迹,4 维)
|
||
|
||
两直角量测 Z0=(x0,y0)、Z1=(x1,y1),时间差 T:
|
||
|
||
$$
|
||
X=[x_1,\ (x_1-x_0)/T,\ y_1,\ (y_1-y_0)/T]^T,\qquad
|
||
P_{axis}=\begin{bmatrix}R&R/T\\R/T&2R/T^2\end{bmatrix}
|
||
$$
|
||
|
||
其中 R 为 Z1 处的转换量测协方差(9.1)。x/y 轴独立填充 P[4][4]。
|
||
|
||
#### 9.5.3 三点初始化(可靠航迹,6 维)
|
||
|
||
三点 Z0, Z1, Z2,时间差 T1, T2,取末点与差分近似速度/加速度:
|
||
|
||
$$
|
||
X=\left[x_2,\ \frac{x_2-x_1}{T_2},\ \frac{(x_2-x_1)/T_2-(x_1-x_0)/T_1}{(T_2+T_1)/2},\
|
||
y_2,\ \frac{y_2-y_1}{T_2},\ \frac{(y_2-y_1)/T_2-(y_1-y_0)/T_1}{(T_2+T_1)/2}\right]^T
|
||
$$
|
||
|
||
协方差按误差传播由 R0, R1, R2(各点转换量测协方差)构造,x 轴块 P11 形式为:
|
||
|
||
$$
|
||
P_{11}=\begin{bmatrix}
|
||
R_2^{xx} & R_2^{xx}/T_2 & \dfrac{R_2^{xx}/T_2}{(T_2+T_1)/2}\\[1mm]
|
||
R_2^{xx}/T_2 & \dfrac{R_2^{xx}+R_1^{xx}}{T_2^2} & \dfrac{(R_2^{xx}+R_1^{xx})/T_2^2+R_1^{xx}/(T_1T_2)}{(T_1+T_2)/2}\\[1mm]
|
||
\dfrac{R_2^{xx}/T_2}{(T_2+T_1)/2} & \dfrac{(R_2^{xx}+R_1^{xx})/T_2^2+R_1^{xx}/(T_1T_2)}{(T_1+T_2)/2} & \dfrac{4\left[(R_2^{xx}+R_1^{xx})/T_2^2+(R_1^{xx}+R_0^{xx})/T_1^2+2R_1^{xx}/(T_1T_2)\right]}{(T_1+T_2)^2}
|
||
\end{bmatrix}
|
||
$$
|
||
|
||
P12(x-y 交叉块)、P22(y 轴块)同构,把 Rxx 换成 Rxy、Ryy。
|
||
|
||
> ⚠ 当前实现未对 T=0 的重复时间戳做除零保护(BUG-18,暂不修复),调用方需保证点迹时间严格递增。
|
||
|
||
#### 9.5.4 线性卡尔曼滤波(二维直角量测)
|
||
|
||
标准预测/更新:
|
||
|
||
$$
|
||
\hat X_{k|k-1}=F\hat X_{k-1},\qquad
|
||
P_{k|k-1}=FP_{k-1}F^T+Q
|
||
$$
|
||
|
||
$$
|
||
S=HP_{k|k-1}H^T+R,\qquad
|
||
K=P_{k|k-1}H^TS^{-1}
|
||
$$
|
||
|
||
$$
|
||
\hat X_k=\hat X_{k|k-1}+K\left(Z-H\hat X_{k|k-1}\right),\qquad
|
||
P_k=\left(I-KH\right)P_{k|k-1}
|
||
$$
|
||
|
||
H 为位置选择矩阵(6 维状态取 x/y)。统计距离(马氏距离平方):
|
||
|
||
$$
|
||
d=\nu^T S^{-1}\nu,\qquad \nu=Z-H\hat X_{k|k-1}
|
||
$$
|
||
|
||
此形式用于两点临时航迹的门限 d_cal_track_init(CV 模型 FCV、Q=(0.03)²I)。
|
||
|
||
#### 9.5.5 扩展卡尔曼滤波(距离-方位-径向速度量测)
|
||
|
||
量测向量 Z = [r, θ, vr],非线性量测函数(由预测状态计算):
|
||
|
||
$$
|
||
h(\hat X)=\begin{bmatrix}r\\\theta\\v_r\end{bmatrix}=
|
||
\begin{bmatrix}\sqrt{x^2+y^2}\\ \operatorname{atan2}(y,x)\bmod 2\pi\\ -\dfrac{x\,v_x+y\,v_y}{\sqrt{x^2+y^2}}\end{bmatrix}
|
||
$$
|
||
|
||
雅可比(在预测点处线性化):
|
||
|
||
$$
|
||
H=\frac{\partial h}{\partial X}=
|
||
\begin{bmatrix}
|
||
\dfrac{x}{r}&0&0&\dfrac{y}{r}&0&0\\[2mm]
|
||
-\dfrac{y}{r^2}&0&0&\dfrac{x}{r^2}&0&0\\[2mm]
|
||
-\dfrac{y(v_xy-v_yx)}{r^3}&-\dfrac{x}{r}&0&-\dfrac{x(v_yx-v_xy)}{r^3}&-\dfrac{y}{r}&0
|
||
\end{bmatrix}
|
||
$$
|
||
|
||
量测噪声 R = diag(σr², σa², σv²)。新息与增益/更新同 9.5.4,并做两项残差修正:
|
||
|
||
- **方位环绕**:νθ = wrapToPi(θ_mea − θ_pred),归一到 [-π, π);
|
||
- **多普勒盲速折叠**:νv = νv − Round(νv / v_bind)·v_bind,其中盲速
|
||
|
||
$$
|
||
v_{bind}=\frac{150000}{f_{GHz}\cdot PRI_{µs}}\quad(\mathrm{m/s}),\qquad
|
||
f_{GHz}=9.2+0.02\cdot f_{ind}
|
||
$$
|
||
|
||
(PRI ≤ 0 或 f ≤ 0 时返回安全值 1.0,接口约定 PRI 不允许为 0。)
|
||
|
||
关联判定与模型似然共用 d = νᵀS⁻¹ν,滤波后输出完整 3×3 新息协方差 S 供似然归一化使用(BUG-24 已修复)。
|
||
|
||
### 9.6 点航关联(最近邻)
|
||
|
||
#### TWS(track_asso.cpp)
|
||
|
||
对每条航迹 × 每个点计算三模型 d1, d2, d3,波门按航迹距离分段(`ASSO_THORD = 4`,判据写作 `d*d < ASSO_THORD*ASSO_THORD`,而 d 本身已是马氏距离平方,故下表的等价门限为 d < 4):
|
||
|
||
| 航迹距离 | 模型 1/2 门限 | 模型 3 门限 |
|
||
|---|---|---|
|
||
| r_track ≤ 500 m | d_i² < 16 | d_3² < 16/1000(≈关闭) |
|
||
| 500 < r_track < 1000 m | d_i² < 16 | d_3² < 16/100(收紧) |
|
||
| r_track ≥ 1000 m | d_i² < 16 | d_3² < 16 |
|
||
|
||
关联判据在 `model_filter()` 中拆为三个布尔量,三者同时通过才记为候选:`thd_d`(上表统计距离门限)、`thd_h`(高度门限)、`thd_r`(距离门限)。
|
||
|
||
- **高度门限 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_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
|
||
100\le VT\le300\ \text{且}\ R/VT>3\ \Rightarrow 拒绝;\qquad
|
||
VT>300\ \text{且}\ R>1200\ \Rightarrow 拒绝
|
||
$$
|
||
|
||
候选对按 d_min = min(d1,d2,d3) 全局排序,**最近邻**原则逐个取点:每条航迹每圈最多关联一个点、每个点只属于一条航迹。关联成功后:三模型分别 EKF 更新 → 模型概率更新 → 更新航迹时间/幅度/SNR/RCS/十字星数据 → 高度平滑。
|
||
|
||
**靠近/远离方向标志 Flag_Direction(fc49707 起、42b598e 调整,TWS/TAS 同步)**:不再使用实测径向速度(原 `Flag_Direction = vr_point > 0 ? 1 : 0`,实测多普勒在速度模糊时符号可能取反),改为按航迹 IMM 融合状态的速度矢量与位置矢量判定:
|
||
|
||
$$
|
||
D=\operatorname{atan2}(X[4],X[1])\ \text{(速度方向角)},\qquad
|
||
Flag\_Direction=\begin{cases}1,& \arccos\!\left(\dfrac{-x\cos D-y\sin D}{r}\right)<\dfrac{\pi}{2}\\[2mm]0,&\text{否则}\end{cases}
|
||
$$
|
||
|
||
其中 x、y 为经 `Sys_delay` 补偿后的航迹位置,r = √(x²+y²),`Direction_Angle` 输出字段即 D 的度数形式。该判据等价于「目标速度方向与『雷达→目标』位置方向的夹角大于 90°」,即**滤波速度矢量的径向分量指向雷达(径向接近)时判为靠近(1)**,否则远离(0);中间版本曾按合速度归一化并把门限取为 π/4(45° 锥角),42b598e 去掉归一化并放宽到 π/2。外推(虚点)输出同样按该判据写 `Flag_Direction`。
|
||
|
||
**ΔT ≤ 0 的候选(604f158 起的行为)**:ΔT = (点迹 CPI 时间 − 航迹 T_track)/1000,ΔT ≤ 0 表示该点迹时间戳不晚于航迹时间(典型场景:航迹已按 TAS 点迹更新过,本圈 TWS 点迹的时间戳更早,或存在重复时间戳)。这种候选**不再被剔除**,仍参与最近邻最小 d 的比较与选取,但选中后:
|
||
|
||
- 不执行 IMM/EKF 更新,不写回 X1/X2/X3、P1/P2/P3 与模型概率;
|
||
- 不刷新航迹时间 T_track / GNSS_time 与点迹信息;
|
||
- 不置实点标志:`Extrapolate_round`、`point_flag`、`associate_point_number` 均保持原值,因此该航迹仍按「未关联航迹」在后续外推环节推进一帧(见 9.9);
|
||
- 该候选对连同该航迹本圈的其余候选对被一并移出候选表,因此该航迹本圈不会再关联其他点迹;由于时间戳更早的候选仍参与最小 d 比较,它可能先于有效候选(ΔT>0)被取中;
|
||
- 该点迹的 `Use_Flag` 被置 1 消费掉:`track_asso_process()` 在关联结束后会把 `Use_Flag==1` 的点迹从 `point_recv` 中删除(track_init 入口也会再剔除一次 `Use_Flag==1` 的点),因此该点迹不会进入航迹起始、不会再参与起批,避免生成虚假 TWS 航迹。
|
||
|
||
> 历史行为:604f158 之前,ΔT ≤ 0 的候选在选取时被直接剔除并 `continue`,点迹保持未被使用,可能被后续用于航迹起始。该分支原有的 `RDP_LOG` 告警日志现已注释停用;TAS 关联(track_asso_tas.cpp,见下)中同类告警日志仍启用。
|
||
|
||
#### TAS(track_asso_tas.cpp)
|
||
|
||
只处理 tas_track_idx 指定的航迹,只有统计距离与高度两个门限,两者同时通过(`thd_d && thd_h`)才记为候选:
|
||
|
||
$$
|
||
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:≤ 250 m;3000~5000 m:≤ 300 m;>5000 m:不约束(与 TWS 通道 9.6 的取值相同)。
|
||
|
||
输出航迹同样写入**方向标志** `Flag_Direction`,判据与 TWS 通道完全一致(fc49707/42b598e:按 IMM 融合速度矢量与位置矢量的夹角判定,见上文 TWS 小节)。
|
||
|
||
> ⚠ **波门语义提示**:代码中 d 本身已是马氏距离平方,但门限写作 d*d < ASSO_THORD*ASSO_THORD,等效于 d < 4(而非 √d < 4)。该行为在 BUG-20 中被识别,**有意保留未改**;ASSO_THORD/1000、/100 已改为浮点除法(BUG-21 修复)。TAS 不区分距离段,`ASSO_THORD` 原值直接作为门限。
|
||
|
||
### 9.7 高度平滑
|
||
|
||
关联实点后,点迹高度入滑窗 Hight_smooth,输出高度取最近 w 个值的平均(不足 w 个则全平均):
|
||
|
||
$$
|
||
\hat h=\frac{1}{w}\sum_{i=N-w+1}^{N} h_i,\qquad
|
||
w=\begin{cases}5,&r\le1000\\6,&1000<r\le2000\\7,&2000<r\le4000\\9,&r>4000\end{cases}
|
||
$$
|
||
|
||
> 已知问题(BUG-02):缓存只增不减,航迹存活越久内存占用越大,当前有意保留。
|
||
|
||
### 9.8 航迹号管理(track_index_mangement.cpp)
|
||
|
||
- 空航迹表时从 1 开始;否则从 lastest_index+1 向上找第一个未占用号(含 500,BUG-35 已修复),找不到则从 1 回绕;全满(500 条)返回 0(不起批)。
|
||
- 写占用表前校验 1 ≤ Track_Index ≤ 500,防御异常批号越界(BUG-10 修复)。
|
||
|
||
### 9.9 航迹外推与消亡
|
||
|
||
#### 外推
|
||
|
||
- **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`(本圈输出)。
|
||
- **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。
|
||
- **输出门控**:`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 普通航迹 | Track_Mode==0 且 primary_target_flag==0 且 Extrapolate_round > TRACK_DIE_ROUND(=6) |
|
||
| 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),即消亡先于航迹起始执行。
|
||
|
||
> 重点目标标记(`primary_target_add` / `primary_target_cancel`)只影响消亡轮数,不改变关联、滤波、波束控制等其他环节,也不体现在输出航迹字段中。
|
||
|
||
### 9.10 TAS 波束控制(tas_ctrl.cpp)
|
||
|
||
- **入队条件**(仅手动):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 队列内遍历,逐个目标先按**数据率门控**筛选——仅要求目标距上次波束输出(`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
|
||
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 末尾的整队循环移位(队列轮转)已停用,改为按数据率门控在队列内轮换目标。
|
||
|
||
> e0bf227 修正:数据率门控原先同时要求「距上次波束输出」与「航迹时间 T_track 距最新时间戳」都超过 DATA_RATE_TAS,第二个条件与「选 CPI 最早目标」的语义冲突(航迹时间越早反倒越容易被抑制),会漏掉本应输出的波束;现已只保留前者。
|
||
|
||
- tas_ctrl_process 入口强制 *Trust_track_num_Output=0 并在写入前检查容量,防止输出数组越界(BUG-09 修复)。
|
||
|
||
---
|
||
|
||
## 10. 参数说明
|
||
|
||
### 10.1 编译期宏(parameters.h,随扫描体制切换)
|
||
|
||
| 宏 | 相扫 PHASE_SCANNING | 机扫 MECHANICAL_SCANNING | 含义 |
|
||
|---|---|---|---|
|
||
| RDP_LOG_ENABLE | 注释停用(默认不启用) | 同左 | 日志文件输出开关:定义时将 `std::cout` 重定向到日志文件;**当前源码中该宏为注释状态**(parameters.h 的注释文字仍写「定义(默认)」,以代码实际状态为准),不重定向、日志输出到标准输出/控制台 |
|
||
| RDP_LOG_DIR | `.\rdp_logs\` | 同左 | 日志文件输出目录(相对宿主进程当前工作目录,目录不存在时自动创建) |
|
||
| RDP_RECORD_ENABLE | 由 CMake 选项 `RDP_DATA_RECORD` 定义(AUTO 时 Debug 定义) | 同左 | 数据记录调试开关:**不要在 parameters.h 中手工定义**(由构建系统传入);定义时记录模块参与编译,未定义时 `RDP_RECORD`/`RDP_RECORD_BATCH` 展开为空操作,见 4.3 与 11.3 |
|
||
| RDP_RECORD_DB_DIR | `.\rdp_records\` | 同左 | 数据记录库输出目录(相对宿主进程当前工作目录,目录不存在时自动创建;仅记录功能启用时产生) |
|
||
| DATA_RATE_TAS | 已停用(原 0.3) | 已停用(原 0.0625) | 编译期宏已注释停用;TAS 数据率统一由运行时参数 RadarPara.DATA_RATE_TAS 提供(见 10.2) |
|
||
| SIGMA_R / SIGMA_A / SIGMA_E / SIGMA_V | 10.0 / 0.02 / 0.2 / 2.0(两体制相同) | 同左 | 量测误差:距离 m / 方位 rad / 俯仰 rad / 速度 m/s |
|
||
| DOT_COH_RANGE / DOT_COH_V / DOT_COH_AZI | 80 / 2 / 6 | 同左 | 凝聚门限:距离 m / 速度 m/s / 方位 ° |
|
||
| MAX_BEAM_NUM | 100 | 同左 | 最大波位数 |
|
||
| MAX_TRACK_NUM / MAX_TRACK_INDEX | 500 / 500 | 同左 | 航迹数上限 / 航迹号上限 |
|
||
| 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_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 新增) |
|
||
| MAX_EXTRAPOLATE_NUM_TAS | 5 | 48 | TAS 最大外推圈数(判据为 Extrapolate_round ≥ 该值时才外推,方向与 TWS 相反,见 9.9 与 11.2;50e0b5c 新增) |
|
||
| ASSO_THORD | 4 | 同左 | 关联波门(判据 d*d < ASSO_THORD²,d 已是马氏距离平方,等效 d < 4;e0bf227 起由 3 调大至 4) |
|
||
| H_F_WIN_LEN | 3 | 同左 | 高度平滑窗长基数(实际 +2/+3/+4/+6) |
|
||
| 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) |
|
||
|
||
### 10.2 运行时参数(RadarPara)
|
||
|
||
| 字段 | 含义 | 备注 |
|
||
|---|---|---|
|
||
| Beam_num | 波位数 | |
|
||
| Height | 雷达平台高度(m) | 输出 z 叠加 |
|
||
| Sys_delay | 系统延迟(s) | 输出航迹位置做 x + vx·Sys_delay 补偿 |
|
||
| R_TAS_max/min、V_TAS_max/min、TAS_Height_1~5 | TAS 自动开启/退出条件 | 自动逻辑已停用,字段保留 |
|
||
| track_prohibite_area_num + 4×30 数组 | 起批屏蔽区(最多 30 个) | 数量未做上限校验(BUG-07) |
|
||
| TAS_prohibite_area_num + 4×30 数组 | TAS 禁止区(最多 30 个) | 同上 |
|
||
| cfar_th | CFAR 门限 | 当前未参与处理 |
|
||
| work_mode | 0 近程 / 1 中程 / 2 远程 | 决定数据率与门限分支 |
|
||
| north_angle | 北偏角 | 保留 |
|
||
| V_MAX / V_MIN | 目标速度上下限(m/s) | 航迹头关联速度区间门限 |
|
||
| DATA_RATE_SHORT / MIDDLE / FAR | 三模式数据率(s) | TWS 外推步长 |
|
||
| DATA_RATE_TAS | TAS 波束输出间隔(s) | 由调用者经 track_process_parameters_initial 输入(须为 >0 的有效值);`tas_beam_output()` 门控阈值为 DATA_RATE_TAS 秒(1521592 起单位由 Hz 改为 s),引导跟踪外推同样使用该运行时参数 |
|
||
| track_start_point_num | 起批点数 | 校验范围 3~9 |
|
||
| track_start_threshold / track_asso_threshold / track_asso_threshold_tas | 起批/关联波门 | **⚠ 声明但当前实现未使用**,实际门限为宏 TRACK_START_THRESHOLD / ASSO_THORD |
|
||
| Model1/2/3_Q_fast/slow | 三个 Singer 模型过程噪声强度 | Model1_Q_fast 未使用;分档规则见 9.5.1 |
|
||
|
||
---
|
||
|
||
## 11. 已知问题与限制
|
||
|
||
详见 archived_docs/BUG_REPORT.md(37 项分析)与 archived_docs/BUG_FIX_REPORT.md(修复明细)。要点:
|
||
|
||
### 11.1 已修复(archived_docs/BUG_FIX_REPORT.md)
|
||
|
||
- **越界/防御**: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 点数字段(输入侧未打通,见 11.2)。
|
||
|
||
### 11.2 有意保留 / 未修复(archived_docs/BUG_REPORT.md 标注项 + 后续源码观察)
|
||
|
||
- **BUG-01**:基类无虚析构,Destroy() 按基类指针 delete。
|
||
- **BUG-02**:Hight_smooth 只增不减,长时运行内存持续增长。
|
||
- **BUG-03**:工厂 GetB/Destroy 非线程安全,接口线程模型未定义(宿主应单线程调用)。
|
||
- **BUG-07**:禁止区个数未限制在 30 内,配置过大越界读。
|
||
- **BUG-08**:消亡航迹输出数组容量未传入,仅约定 ≤500。
|
||
- **BUG-13**:Work_Parameter 等成员构造后未初始化,必须先调 track_process_parameters_initial 再处理。
|
||
- **BUG-18**:卡尔曼两点/三点初始化对零/负时间差无保护(起批时间戳必须严格递增)。
|
||
- **BUG-20**:门限对马氏距离平方再次平方(e0bf227 把 `ASSO_THORD` 调为 4 后等效 d < 4),有意保留。
|
||
- **BUG-25**:TWS 关联/输出未排除 Track_Mode==1 的 TAS 航迹(原 `manual_tracking_flag==0` 过滤代码块已于 fc49707 删除,未恢复过滤)。
|
||
- **BUG-29**:tracking_stop 后 TAS 队列项延迟到下一次 Beam_Ctrl 才移除。
|
||
- **BUG-33**:起批关联未显式校验 ΔT>0。
|
||
- **BUG-36**:TAS 波束关闭时只清 open_flag,其余字段保留旧值。
|
||
- **新字段未打通(e8c56f9)**:`data_preprocess()` 未把 `DataRev.amp_asv` / `DataRev.prn_fftn` 拷入内部 `PointRecv`(该局部对象本身也未初始化),而 `track_asso.cpp` 会把点迹的这两个字段写进航迹并输出,因此 TWS 输出航迹的 `amp_asv_point` / `prn_fftn_point` 当前取到的是未初始化值;TAS 通道(`track_asso_tas.cpp`)的关联与输出路径完全没有涉及这两个字段,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 时还存在除零。
|
||
|
||
### 11.3 未启用功能
|
||
|
||
- direct_tracking_process(引导跟踪)、tracking_point(手动打波束)为**空实现**;Track_Init_Direct_Tracking::track_init_process_logic 同样为空。
|
||
- track_asso_direct_tracking.cpp **未加入 CMake 源列表**(与旧 .pro 一致)。
|
||
- TAS **自动**开启/退出逻辑(tas_auto_start/tas_auto_end)注释停用,仅支持手动 tracking_start/tracking_stop。
|
||
- 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)。记录点中的字段错误只在启用记录功能的构建中才会被检查(关闭时宏丢弃实参)。
|
||
|
||
### 11.4 航迹起始相关的未修复观察(详见 docs/track_init_readme.md 第 15 节)
|
||
|
||
以下为阅读源码得到的观察,**未在本轮文档更新中改动代码**;修改前请结合实测数据评估:
|
||
|
||
- 点-临时航迹关联硬编码 `|Δr| ≥ 5 m` 门限,切向/远距离慢速目标可能漏关联导致起批失败。
|
||
- 起批判据对马氏距离平方再次平方(`d*d ≤ TRACK_START_THRESHOLD²`),实际门限为 `d ≤ 8`,按字面 `d² ≤ 64` 理解会严重放宽;调 `TRACK_START_THRESHOLD` 时需注意这一层。
|
||
- 折角计算 `acos` 无定义域钳位,浮点越界产生 NaN 时条件恒假(静默丢弃该关联)。
|
||
- 起批输出数组行号可能越过容量:容量判据用 `trust_track->size() < MAX_TRACK_INDEX`,而输出行计数在 track_asso 阶段(track_die 删除航迹之前)已推进,极端场景(当圈消亡 ≥ 2 条且起批占满配额)可写到 `MAX_TRACK_NUM` 之外。
|
||
- 起批输出有多个字段未赋值(见 9.3(4) 与 docs/track_init_readme.md 第 14 节),宿主不应依赖这些字段。
|
||
|
||
---
|
||
|
||
## 12. 版本历史
|
||
|
||
近期提交(git log --oneline,新→旧):
|
||
|
||
| 提交 | 内容 |
|
||
|---|---|
|
||
| 工作区(未提交,数据记录调试功能) | 新增可选编译的数据记录调试功能:CMake 缓存变量 `RDP_DATA_RECORD`(AUTO/ON/OFF,AUTO = Debug 启用 / Release 关闭)与独立静态库 `rdp_record`(**以 C++20 编译**,雷达代码保持 C++17);内置第三方源码 `third_party/ormpp`(ormpp 0.2.0 + iguana 1.0.5 + frozen + SQLite 3.49.1 amalgamation,附 UPSTREAM.md);新增 `rdp_record.h`(`Init`/`Shutdown`/`db_path` + `RDP_RECORD`/`RDP_RECORD_BATCH` 宏,关闭时展开为空操作)、`rdp_record_entity.h`(记录实体定义区)与 `rdp_record.cpp`(实体注册区、按实体自动建表、单条/批量写入、失败降级);`Data_Process_Factory::GetB()/Destroy()` 调用 `rdp_record::Init()/Shutdown()`;`parameters.h` 新增 `RDP_RECORD_DB_DIR`(`.\rdp_records\`);`data_process.cpp` 新增 2 个示例记录点(TWS 输入点迹 → `RdpRecPointTws`、输出航迹 → `RdpRecTrackOut`);`configure.bat` 新增第 4 个参数(AUTO/ON/OFF);`.gitignore` 增加 `rdp_records/`;新增 `docs/data_record_debug.md`。验证:Release(PS/MS)导出表与依赖表与改动前逐行一致、DLL 体积不变(178,688 / 178,176 字节)、构建树无记录模块目标文件;Debug(PS/MS,AUTO→启用)0 warning 0 error;运行时校验(临时程序 + Python sqlite3)确认建库、一实体一表、批量事务写入、`id` 自增、取值一致、`integrity_check` = ok,且记录目录不可创建时接口照常返回、仅提示一次 |
|
||
| 工作区(未提交) | 编译器由 MSVC 2013(Visual Studio 12,x86)升级为 **MSVC 2022(v143,x64)**、C++ 标准提升至 **C++17**:`CMakeLists.txt` 重写(`CMAKE_CXX_STANDARD 17`、`_MSC_VER >= 1930` 强校验、`/utf-8` `/Zc:__cplusplus` `/W3`)、`.vscode/scripts/` 全部构建脚本改为 MSVC 2022(新增共享的 `msvc_env.bat`,`configure.bat` 自动清理旧工具集构建树)、VS Code 配置同步(settings / c_cpp_properties / cmake-variants / tasks 改为 MSVC2022 x64 + C++17)、修复 MSVC 2022 新增的 17 处 C4267 窄化告警;X256_PS/X256_MS × Release/Debug 四种配置均 0 warning 0 error 通过,产物为 x64 DLL(导出符号与升级前一致,仅名称修饰随架构变化) |
|
||
| e8c56f9 | 输入/输出结构适配「归一化幅度」与「速度维 FFT 点数」:`DataRev` 新增 `amp_asv`/`prn_fftn`,`Track` 新增 `amp_asv_point`/`prn_fftn_point`,内部 `PointRecv`/`Trust_Track` 同步新增字段;`track_asso.cpp` 关联实点时写入航迹、TWS 输出时写回输出结构(输入侧未打通,见 11.2) |
|
||
| 42b598e | 调整「向站/背站」判断条件:判据由 `acos((-x·vx − y·vy)/r/Range_V) < π/4` 改为 `acos((-x·cos(Direction_Angle) − y·sin(Direction_Angle))/r) < π/2`(去掉按合速度归一化,锥角门限由 45° 放宽到 90°),TWS/TAS 同步 |
|
||
| fc49707 | 「向站/背站」判断改用滤波速度矢量:`Flag_Direction` 不再取 `vr_point > 0`(实测径向速度受多普勒模糊影响、符号可能取反),改按航迹 IMM 速度方向与位置矢量的夹角判定(TWS/TAS 同步);`primary_target_add/cancel`、`tracking_start/stop` 命中目标后 `break`;删除 TWS 输出循环中的注释残留代码块 |
|
||
| 50e0b5c | 新增手动重点目标接口(`primary_target_add`/`primary_target_cancel` + `Trust_Track::primary_target_flag`)与重点航迹消亡圈数 `TRACK_DIE_ROUND_PRIMARY`(10);输出航迹改为只输出 `Track_Update_Flag==1` 的本圈更新航迹;未关联航迹外推限制在 `MAX_EXTRAPOLATE_NUM`(3)圈内,TAS 侧新增 `MAX_EXTRAPOLATE_NUM_TAS`(相扫 5 / 机扫 48);`TRACK_DIE_ROUND` 由 4 调整为 6、`TRACK_DIE_ROUND_TAS` 相扫由 5 调整为 10,消亡判据改为 `>`;同步更新 README/CHANGELOG/docs |
|
||
| 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 |
|
||
| 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 |
|
||
| 1521592 | 新增日志模块(`rdp_log.h/.cpp`,CMake SOURCES 注册、.gitignore 忽略 `rdp_logs/`):`RDP_LOG_ENABLE` / `RDP_LOG_DIR` 宏(parameters.h)、std::cout 经 `rdbuf()` 重定向到 `.\rdp_logs\` 下日期+时间命名日志、`RDP_LOG` 前缀宏、ΔT≤0 告警日志;`RadarPara.DATA_RATE_TAS` 单位由 Hz 改为 s;修复 `tas_beam_output()` 将向量下标误赋给 `Tracking_beam->TAS_track_index` 的问题;更新 README/CHANGELOG |
|
||
| 5f82098 | 修复 MSVC `/W3` 下全部 C4819 / C4018 / C4244 警告(UTF-8 with BOM、size_t / static_cast 等);更新项目文档 |
|
||
| f438ac5 | 优化 TAS 调度:波束输出改为在队列内选择满足数据率门控且 CPI 时间最早的目标,停用整队循环移位;DATA_RATE_TAS 编译期宏停用、统一使用运行时参数;#pragma message 提示扫描体制 |
|
||
| e729c5b | 频点宏精简为 FREQ0 = 9.2 GHz(原 FREQ0~FREQ20 均为 16.8 GHz) |
|
||
| b3e2f52 | TAS 波束控制改为按固定数据率调度,RadarPara 新增 DATA_RATE_TAS 运行时参数;新增 CHANGELOG.md、requirements.md,README 补充相应说明 |
|
||
| 93d3924 | 新增 README.md(本文档);移除 requirements.md;调整 .gitignore |
|
||
| 3500652 | 去掉 1 km 以内航迹起批的 20 dB 信噪比门限 |
|
||
| 01d28e0 | 改用 VS Code + CMake 重新编译(编译器不变);修复若干逻辑 BUG(见 archived_docs/BUG_FIX_REPORT.md) |
|
||
| 0cb31b4 | 删除不必要文件;输入点迹/输出航迹的 CPI 与 GNSS 时间改为 64 位整型;修复 TAS 外推时间差可能无效的问题 |
|
||
| d101fe9 | 增加航迹清空功能(解决重连乱窜);TAS 外推时间间隔按波束时间计算;增加 1 km 内 SNR<20 dB 不起批限制(后于 3500652 移除) |
|
||
| 8636179 | 机扫/相扫程序合并,宏定义配置切换 |
|
||
| 06d45f5 | 机扫跟踪增加高度门限判断 |
|
||
| 8b1896d | 适配四面阵机扫跟踪模式 |
|
||
| ae3ef84 | 扫描一圈完成判断改为「波位号变小」 |
|
||
| e9b8a32 | 修复 R 矩阵赋值、波位号判断、点数上限、空容器、雅可比取值、起批负索引、容器 push_back 后修改失效、机扫参数等 8 项 |
|
||
| 28fcf06 | 统一代码缩进格式 |
|
||
| 7c10ae9 / 958ff6b | TWS 关联增加俯仰门限 / 点航距离门限(限制远距离突跳关联) |
|
||
| 2b1293a / 167fa79 | 去掉自动转 TAS,只保留手动转 TAS;起批时手动转跟踪标志清零 |
|
||
| 6008959 | 添加「航迹点迹区分区说明.vsdx」(后随 0cb31b4 删除不必要文件而移除) |
|
||
| d6e43d6 / 199ae34 | 点迹凝聚角度约束调整;凝聚条件按模式区分(近程:距离/速度/方位;中远程:距离/方位) |
|
||
| 06938b2 | 航迹起始增加屏蔽区域 |
|
||
|
||
---
|
||
|
||
## 13. 参考文档
|
||
|
||
| 文档 | 内容 |
|
||
|---|---|
|
||
| CHANGELOG.md | 变更日志(Keep a Changelog 格式,按 git 提交记录维护) |
|
||
| docs/data_process_flow_report.md | 数据处理流程与关键逻辑说明(按当前源码整理:前处理与判圈、凝聚、TWS/TAS 关联与滤波、航迹起始、外推消亡、TAS 波束控制、参数脉络;含与本文档的历史差异提示)——原同内容 HTML 渲染版(`data_process_flow_report.html`)已于 e0bf227 删除,HTML 版本在 git 忽略的 `design_docs/` 内留档 |
|
||
| docs/track_init_readme.md | 航迹起始(Track Init)专项说明:分阶段流程、起始条件汇总、调参直觉、输出字段映射(含未赋值字段)、已知风险与代码索引 |
|
||
| docs/data_record_debug.md | 数据记录调试功能说明:开关与构建(`RDP_DATA_RECORD`、C++20 隔离与 C 编译器要求)、运行期行为(目录/文件名、PRAGMA、失败降级、线程模型)、表结构约定、**新增记录点四步配方**、现有 2 个示例记录点、查询示例与已知限制 |
|
||
| third_party/ormpp/UPSTREAM.md | 内置第三方源码的来源说明:ormpp / iguana / frozen / SQLite 版本、许可证、复现与升级步骤(含 blob 校验值) |
|
||
| archived_docs/BUG_REPORT.md | 全量逻辑 BUG 分析(P0~P3 共 37 项,含位置、说明、建议、处置结论)——过期留档,仅作历史参考 |
|
||
| archived_docs/BUG_FIX_REPORT.md | 修复明细、修复状态汇总表与 MSVC 2013 x86 编译验证记录——过期留档(对应 01d28e0 时期) |
|
||
| requirements.md | 修改需求说明:数据记录调试功能(结构体经 ormpp 映射写入 SQLite、Release 版可屏蔽、数据分类入不同表、宏记录点、便于快速新增结构体、不使用异步写入)——已按该说明实现框架与 2 个示例记录点,详见 docs/data_record_debug.md(此前同名的日志文件输出需求亦已实现) |
|
||
| backup/data_process_class_dll/data_process_class_dll.pro | 迁移前的 Qt/qmake 工程文件(源文件清单参考) |
|
||
| .vscode/tasks.json、.vscode/cmake-variants.yaml | VS Code 构建任务与变体定义 |
|
||
| build/X256_PS/bin/RadarConfigParam.ini | 回放测试工具(rdp_playback.exe)配置样例 |
|