Files
code-test-drone/utils
keita dbce0a862f pod_console: 支持主动解除锁定 + 控制台不再刷屏
解除锁定: 按键u发0x0E停止跟踪, s=0x0E+0x08关识别, d开识别, a自动锁定, c归中,
q退出; --auto-unlock SEC 在锁定中表4超时SEC秒自动发0x0E(针对本吊舱锁定位置位
丢失后不复位); --unlock-on-exit 退出前解锁。
显示: 新增Renderer原地重绘(光标上移+清行, 不再清屏刷屏), 刷新默认0.5s,
事件行追加在面板下方; 非TTY输出改为每周期一行紧凑记录。
打桩验证: 自动解锁与退出解锁均正确发出0x0E
2026-09-28 15:39:09 +08:00
..
2026-09-02 15:13:13 +08:00
2026-09-14 15:05:03 +08:00
2026-09-14 15:05:03 +08:00

utils —— reference-c++ 的 Python 移植 + 双目链路新实现

将 reference-c++/ 下的 target_tracker(多目标追踪过滤器)与 visual_track_control(视觉跟踪控制律)移植为 Python,两包互不依赖 (唯一的数据转换点在胶水层 demo)。

另有双目链路新实现(非 C++ 移植、按规格实现):

  • stereo_ranger(双目稀疏目标测距),规格 docs/双目测距技术路线.md;
  • stereo_yolo(双目 YOLO 检测前端),规格 docs/双目YOLO目标识别需求说明.md, 输出直接作为 stereo_ranger 的输入(仅复用其 types.py 纯值类型)。

Python 侧定位为 C++ 实现的先验验证:构件划分与语义按规格冻结,便于逐构件 移植对照;stereo_yolo 的 C++ 移植注记见其包 README。

目录结构

utils/
├── target_tracker/            # 包 1:卡尔曼滤波多目标追踪(无第三方硬依赖,仅 numpy)
│   └── README.md              # 接口清单 + C++ 差异
├── visual_track_control/      # 包 2:三通道控制律 + MAVSDK offboard 网关
│   └── README.md              # 接口清单 + C++ 差异
├── stereo_ranger/             # 包 3:双目稀疏目标测距(纯标准库,无第三方依赖)
│   └── README.md              # 接口清单 + 与规格的偏差
├── stereo_yolo/               # 包 4:双目 YOLO 检测前端(真模型需 ultralytics)
│   └── README.md              # 接口清单 + C++ 移植注记
├── demo_track_control.py      # 胶水层集成演示(模拟检测 → 追踪 → 控制律 → 发送)
├── demo_stereo_ranger.py      # 双目测距演示(合成框对,六场景,无硬件)
├── demo_stereo_yolo.py        # 检测前端演示(真模型 + 合成素材 → 测距联调)
├── assets/stereo_yolo/        # demo 占位素材(AI 合成图,可整体替换为真实素材)
├── config/track_control.json  # 控制律配置(拷贝自 reference-c++)
├── config/stereo_ranger.json  # 双目测距配置(占位值,待标定回填)
├── config/stereo_yolo.json    # 检测前端配置(不存内参,几何参数唯一来源见上)
├── tests/                     # pytest 测试
│   ├── target_tracker/        # 28 条(对应 C++ 测试文件)
│   ├── visual_track_control/  # 81 条(对应 C++ 测试文件)
│   ├── stereo_ranger/         # 111 条(规格 §11.4 构件级 + 全流程)
│   └── stereo_yolo/           # 36 条(假检测器驱动,无模型/素材/硬件)
├── conftest.py                # 保证可从任意工作目录导入各包
└── pytest.ini                 # 收集 *_test.py 命名(与 C++ 测试文件名对齐);
                               # importlib 导入模式避免跨包同名测试文件冲突

环境

conda env pytorch(D:\program file\conda\envs\pytorch),Python 3.12, 依赖:numpy、mavsdk、pytest;stereo_ranger 仅标准库;stereo_yolo 只有真模型 推理路径需要 ultralytics(在检测器内部延迟导入,测试与假检测器路径不受影响)。

运行测试

cd utils
"D:/program file/conda/envs/pytorch/python.exe" -m pytest -q

256 条测试全部通过:109 条 C++ 移植用例(含 §9.4 六条硬验收、A1/A2/A4 回归、PID anti-windup C1、超龄 C4、首拍限幅 S6)+ 111 条 stereo_ranger (合成框对驱动)+ 36 条 stereo_yolo(假检测器驱动)。 stereo_ranger / stereo_yolo 测试均不需要真实图像、模型权重或硬件。

运行演示

# mock 传输(本地记录指令,无实机)
python utils/demo_track_control.py --speedup 10

# MAVSDK 实发(需飞控/SITL 在 udp://:14540)
python utils/demo_track_control.py --transport mavsdk

# 双目测距(合成框对,离线,无相机/飞控)
python utils/demo_stereo_ranger.py

# 双目检测前端(真模型推理;需 ultralytics + models/yolo26n-drone.pt)
python utils/demo_stereo_yolo.py

控制链路时间线 13 s(20 Hz):正常跟踪 6 s(vx 从零渐变 → 逼近限速 3 m/s)→ 目标消失 4 s(Coast 预测,60 帧后轨道判亡)→ 判零速刹车 3 s。

双目测距演示六场景:逼近(三道有效性门 + 滤波)→ 远场域外(方位仍发布)→ 单目退化 → 非同帧拒收 → 一致性降级/判无效 → 多目标贪心配对。

检测前端演示五场景:单图冒烟 → 合成双目对联调(真检测框喂 stereo_ranger, 与解析式 D=F·B/Z 对照)→ 空场景 → 左右形状不一致拒收 → 帧周期计时。 合成对用 AI 占位素材 assets/stereo_yolo/drone_sky.png(可整体替换为真实 素材),本机实测 |ΔD|≈0.3 px、|Δy|≈0.2 px;帧周期 25~34 ms(640 输入, 双实例并发,随机器负载波动),与 30 fps 预算 33.3 ms 同量级,结论不可外推 到机载平台(§5 的算力预算另见平台工程文档)。

移植约定

  • MAVLink 部分改为 MAVSDK 语义映射(offboard API,非字节透传),三分支 映射保留 C++ A2 回归语义,详见包 2 README。
  • 测试逐条移植 C++ gtest 断言(EXPECT_DOUBLE_EQ → 精确 ==, EXPECT_NEAR → pytest.approx);MAVSDK 部分因无 SITL/实机,仅 mock 验证。
  • 行为修复项(C1/C2/C4、A1/A2/A4、S6)在测试文件头注释中标注对应章节。
  • stereo_ranger 不是移植:按规格五步流程新实现,与规格的偏差(越界=有效性门、 视差域权威、补充 consistency_jump_px/isolation_gate_px 等)见其包 README; ⚠ 全部数值为占位值,标定完成前不得作为飞行控制决策依据。
  • stereo_yolo 不是移植:推理口径为 ultralytics 直跑 .pt,letterbox、解码、 NMS、坐标回映均在库内完成;C++ 侧复现要点与接口契约硬约束(原生分辨率坐标、 左右预处理位级一致、x1 即框左边缘、无跨帧状态)见其包 README 的移植注记表。 ⚠ 占位素材 assets/stereo_yolo/ 为 AI 合成图,真实双目素材到位后需重跑联调。