# utils —— Python 实现(运行链路) > **架构现状(2026-10-20)**:运行链路是「光电吊舱 → `pod_bridge` → `task_runner` → PX4」。 > 双目 + YOLO 那套可选感知后端(`stereo_yolo` / `target_tracker` / `stereo_ranger`) > **已整体归档到仓库根的 `legacy/`**,默认不参与 pytest 收集;接回方式见 `legacy/README.md`。 本目录包含: - **运行链路**:`pod_bridge`(吊舱桥接)+ `task_runner`(任务编排)+ `visual_track_control` (控制律原语,被前两者复用) - **入口共享件**:`sitl_support.py`(时钟/遥测订阅/连接准备/`RATE_*`) - **测试**:`tests/`(446 条)、`conftest.py`、`pytest.ini` `visual_track_control` 是 `reference-c++/visual_track_control` 的逐构件 Python 移植 (语义对齐、含行为修复);`target_tracker` 的移植版已随归档移入 `legacy/utils/`。 ## 目录结构 ``` utils/ ├── pod_bridge/ # 吊舱 ↔ PX4 桥接(**运行链路核心**) │ ├── bridge.py # PodBridge:L1/L2 切换、目标门控、链路维持 │ ├── los_consistency.py # 目标有效性第二判据(LOS 运动学一致性) │ ├── ground_link.py # 地面站 UDP 坐标注入 + 命令队列 │ ├── guidance.py # L2 地理引导律 │ ├── protocol.py # 表2-1/2-2/3/4 帧编解码 │ ├── pod_serial.py # 串口链路(115200 8N1) │ ├── px4_gateway.py # MAVSDK 遥测 + offboard 网关 │ ├── virtual_pod.py # 虚拟吊舱(SITL/台架) │ └── {run_bridge,listen_pod,pod_console,sim_fc,verify_px4}.py # 台架工具 ├── task_runner/ # 任务级编排 │ ├── state_machine.py # WAIT→ARM_TAKEOFF→GOTO→SEARCH→TRACK→RTL │ ├── runner.py # 编排器(快照采集/动作/异常兜底) │ ├── return_home.py # 自定义返航(回起飞点→恢复航向→垂直降落) │ ├── pod_control.py # 吊舱识别/锁定指令 │ └── log.py # 事件 JSONL + 遥测 CSV + 简报 ├── visual_track_control/ # 控制律 + MAVSDK 网关(运行链路复用) │ └── README.md # 接口清单 + C++ 差异 ├── config/ # 配置 JSON(pod_bridge.json 为主线) ├── tests/ # pytest(446 条) │ ├── pod_bridge/ # 208 条(协议/桥接/引导/注入/节流/LOS) │ ├── task_runner/ # 122 条(状态机/编排器/返航/日志/吊舱控制) │ ├── visual_track_control/ # 86 条(对应 C++ gtest + L1 增量) │ └── ground_station/ # 30 条(页面与日志解读) ├── conftest.py # 把 utils/ 插进 sys.path + fake_mavsdk fixture ├── pytest.ini # 收集 *_test.py + importlib 导入模式 └── sitl_support.py # 入口共用:时钟/遥测订阅/连接准备/速率常量 ``` ## 环境 conda env `pytorch`(`D:\program file\conda\envs\pytorch`),Python 3.12, 依赖:numpy、mavsdk(<4)、pytest、flask、pyserial (`opencv-python` 仅供 `tools/` 下的相机脚本;`ultralytics` 仅供已归档的双目链路)。 ## 运行测试 ```bash cd utils "D:/program file/conda/envs/pytorch/python.exe" -m pytest -q ``` **运行链路 446 条全部通过(2026-10-20)**: | 组 | 条数 | |---|---| | `pod_bridge` | 208 | | `task_runner` | 122 | | `visual_track_control`(含 §9.4 硬验收、A1/A2/A4、C1、C4、S6、L1 角度直入) | 86 | | `ground_station` | 30 | 归档的可选后端 175 条(stereo_ranger 111 / stereo_yolo 36 / target_tracker 28) 在 `legacy/` 下,按需运行: ```bash cd legacy/utils && PYTHONPATH="../../utils" "D:/program file/conda/envs/pytorch/python.exe" -m pytest -q ``` 运行链路测试不需要硬件(FakePod / VirtualPod / FakePx4 注入)。 ## 运行入口 入口脚本在仓库根(不在 utils 内): ```bash PY="D:/program file/conda/envs/pytorch/python.exe" "$PY" task_runner_sitl.py --conn udpin://0.0.0.0:14540 # 任务全流程 SITL "$PY" task_runner_real.py --port COM5 --conn udpin://0.0.0.0:14540 --target-type 1 "$PY" l1_sitl_test.py --conn udpin://0.0.0.0:14540 # 仅 L1 控制律闭环 "$PY" utils/pod_bridge/run_bridge.py --port COM5 --dry-run # S2 台架干跑 ``` ## 移植约定 - MAVLink 部分改为 **MAVSDK 语义映射**(offboard API,非字节透传),三分支映射保留 C++ A2 回归语义,详见 `visual_track_control/README.md`。 - 测试逐条移植 C++ gtest 断言(`EXPECT_DOUBLE_EQ` → 精确 `==`, `EXPECT_NEAR` → `pytest.approx`)。 - 行为修复项(C1/C2/C4、A1/A2/A4、S6)在测试文件头注释中标注对应章节。 - ⚠ 全部数值为占位值,标定完成前不得作为飞行控制决策依据。 ## 已归档内容 `legacy/utils/` 下保留了原 `stereo_yolo` / `stereo_ranger` / `target_tracker` 三包、 175 条测试、三个 demo、`stereo_*.json`、素材与 YOLO 权重;说明见 `legacy/README.md`。