精简仓库结构并增强任务链路:归档双目可选后端、新增LOS判据与自定义返航
归档 legacy/:stereo_yolo/stereo_ranger/target_tracker 三包 + 175 条测试 + demo/配置/权重/三份规格;运行链路不再依赖,默认 pytest 446 条,归档测试按需运行。 目标有效性第二判据改为 LOS 运动学一致性(pod_bridge/los_consistency.py),删除 require_vision;pod_locked() 叠加该判据,状态机随之后退重搜。 自定义返航(task_runner/return_home.py):保持转场高度回起飞点 → 恢复初始航向 → 垂直降落,不再爬 RTL_RETURN_ALT;未起飞/无起飞点/超时/异常仍退回 PX4 原生 RTL。 任务链安全兜底:主循环异常→紧急返航、stop 幂等、landing_stop 保留遥测、in_air 流复用+超时、解锁/起飞与吊舱识别仅执行一次、rtl_timeout 上限。 入口共享件拆到 utils/sitl_support.py;pod_sitl_test.py→l1_sitl_test.py;删除旧架构 test.py;相机脚本移入 tools/。 新增 .gitignore 并剔除历史误跟踪的 59 个 .pyc;requirements 按实际依赖重写;文档全面对齐,新增 legacy/README.md 与 tools/README.md。
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
# 双目相机模组到位作业指导
|
||||
|
||||
> **定位**:`docs/` 下三份规格(《双目测距技术路线》《双目YOLO目标识别需求说明》
|
||||
> 《视觉跟踪控制律技术路线》)回答"应该怎样、判据是什么";本文回答"相机模组到货
|
||||
> 之后按什么顺序做什么、每步怎么判通过、结果回填到哪里"。**本文不新立判据**——
|
||||
> 所有通过标准一律引用规格原文并注明章节。
|
||||
>
|
||||
> **适用范围**:双目相机模组(含厂商标定数据)到货起,至《测距路线》§12.3 四条
|
||||
> 红线解除为止。飞控/机载平台到位后的工作属《视觉跟踪控制律技术路线》§8 阶段 4~6,
|
||||
> 本文只在阶段 6 交接。
|
||||
>
|
||||
> **编写状态(2026-09-14)**:仓库内几何参数全部为占位值
|
||||
> (`utils/config/stereo_ranger.json`)、demo 素材为 AI 合成图,本文判据**尚未在
|
||||
> 任何真实设备上执行过**。首次执行后请把实测偏差与踩坑回填本文,并去掉本行。
|
||||
|
||||
---
|
||||
|
||||
## 0. 一页速览
|
||||
|
||||
| 阶段 | 内容 | 出口判据(出处) | 解除的阻塞 |
|
||||
|------|------|-----------------|-----------|
|
||||
| P0 | 开箱登记与数据清点 | 登记表(附录 A.1)填满;缺失项有替代方案 | 厂商数据可用性未知 |
|
||||
| P1 | 几何参数回填 | fail-fast 校验通过 + 新有效域覆盖任务包线(§9.1/§11.2) | 几何参数为占位 |
|
||||
| P2 | 校正质量核验 | 静态场景 \|Δy\| P95 ≤ 1 px(§12.1) | 极线对齐不可信 |
|
||||
| P3 | 真实素材采集入库 | 覆盖 5/10/15/20/25 m 档、元数据齐(§2.3) | 素材只有合成图 |
|
||||
| P4 | 测距真值验证 | 有效域内 δZ ≤ 2 m、趋势 ∝ Z²(§12.1) | 数值从未对过真值 |
|
||||
| P5 | 阈值整定 | §9 各表 ⚠ 全部替换为实测值(§12.2) | 阈值全部占位 |
|
||||
| P6 | 台架/SITL 联动 → 解禁评审 | 控制联动场景全覆盖(§12.1);§12.3 四条逐条勾选 | 红线未解除 |
|
||||
|
||||
依赖顺序:P0 → P1 → P2 → P3 → P4 → P5 → P6。P2 必须在 P1 之后(校正质量要在
|
||||
正确内参下判读),P4 必须在 P3 之后(没有真实素材就没有真值比对)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 阶段 0:开箱登记与数据清点
|
||||
|
||||
### 1.1 向厂商索取的清单
|
||||
|
||||
| 数据 | 用途 | 缺失时的替代方案 | 落位 |
|
||||
|------|------|-----------------|------|
|
||||
| 校正后内参 `fx_px`/`fy_px`/`cx_px`/`cy_px` | §9.1 几何组,`Z = F·B/D` 的分母来源 | 自标定(张正友);**P2 判据不达标时本就要提前做** | `utils/config/stereo_ranger.json` |
|
||||
| 基线 `baseline_m`(标称 + 实测公差) | §9.1;`F·B` 常量 | 卡尺/塞规实测,记录不确定度 | 同上 |
|
||||
| 畸变系数与校正映射(remap maps)或"已做校正"的书面确认 | §2.2 第 4 条:前端输出的是校正后图上的框 | 自标定 + 自建 remap 表 | 采集预处理(不在本仓) |
|
||||
| 出厂标定报告与不确定度 | P1/P2 的判据依据,**要存档** | 无报告 = 按未标定处理,走自标定 | 本文附录 A.1 |
|
||||
| 分辨率 / 帧率 / 像素格式 / 位深 | 原生坐标系与算力预算(《需求说明》§5) | — | 附录 A.1 + `stereo_yolo.json` 复核 |
|
||||
| 同步方式与触发接口(sbs / 双流 / 硬触发) | §2.3 同帧契约的形态选择 | sbs 优先(天然同曝光,§2.3) | 采集端设计 |
|
||||
| 机械图纸(安装接口、两目光轴平行度要求) | 安装外参、换机型(P6) | — | 附录 A.1 |
|
||||
|
||||
### 1.2 到货当天建议实测
|
||||
|
||||
1. **基线复核**:卡尺/图纸比对标称值,偏差 >1% 时以实测为准并记录(`F·B` 直接决定距离标定);
|
||||
2. **同帧性验证**:拍快速横向移动的手/笔,sbs 形态应为同一时刻;双流形态量化两路时间窗抖动并记录(§2.3 要求"残余时序抖动应记录供误差评估");
|
||||
3. **分辨率与帧率实测**:跑满声称帧率,记录实际值与丢帧情况(供 P5/P6 的算力预算);
|
||||
4. **图像质量目测**:左右目曝光/增益是否一致(不一致会让同一目标两目置信度与框边缘不对称,污染视差取点)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 阶段 1:几何参数回填
|
||||
|
||||
### 2.1 改哪些字段
|
||||
|
||||
只动 `utils/config/stereo_ranger.json` 的 **5 个几何项**:
|
||||
|
||||
```
|
||||
fx_px, fy_px, cx_px, cy_px ← 厂商校正后内参(注意:fx=fy=F 是校正后口径)
|
||||
baseline_m ← 实测基线
|
||||
```
|
||||
|
||||
`utils/config/stereo_yolo.json` **不含几何参数**(输出框天然位于输入图的原生
|
||||
坐标系,§4 配置一致性要求)——前端无需回填,只需复核 `imgsz` 与真实分辨率匹配。
|
||||
|
||||
**视差域 `disparity_min_px` / `disparity_max_px` 不是标定数据**,是任务决策项:
|
||||
按任务近界 `Z_near` 反推 `disparity_max_px = F·B / Z_near`,按可测远界定
|
||||
`disparity_min_px`。回填内参后 `F·B` 变化,两者的距离语义会平移,**必须重算**。
|
||||
|
||||
### 2.2 回填后必算的派生量(写进记录表)
|
||||
|
||||
| 派生量 | 公式(代码属性) | 用途 |
|
||||
|--------|-----------------|------|
|
||||
| `F·B` | `fx_px × baseline_m`(`focal_baseline_px_m`) | 距离解算常量 |
|
||||
| `z_min_m` | `F·B / disparity_max_px` | 近界(只读派生) |
|
||||
| `z_max_m` | `F·B / disparity_min_px` | 远界(只读派生) |
|
||||
| `z_error_budget_max_m` | `sqrt(max_delta_z_m × F·B)` | 误差预算门对应的最远距离(§7.2,δD 基准固定 1 px) |
|
||||
|
||||
以上四项**不是配置项**,由 `StereoConfig` 只读派生(v1.0 冻结:视差域权威,
|
||||
距离域派生,避免两处冗余互推舍入不一致,§6.4)。回填后手算一遍与程序输出比对,
|
||||
作为回填正确性的一次交叉验证。
|
||||
|
||||
### 2.3 判据
|
||||
|
||||
1. **fail-fast 校验通过**:JSON 必须含全部 17 个键、无未知键、类型正确
|
||||
(`consistency_N_frames` / `consistency_M_frames` / `filter_reset_frames`
|
||||
必须是整数,`3.5` 或 `true` 会被拒);取值约束:`0 < disparity_min_px < disparity_max_px`、
|
||||
`consistency_M_frames ≥ consistency_N_frames`、`0 < smooth_alpha ≤ 1`、
|
||||
`cx_px`/`cy_px` 非负、其余数值项一律为正(以 `stereo_ranger/config.py` 为准);
|
||||
2. **有效域覆盖任务包线**:新的 `z_min_m` / `z_max_m` / `z_error_budget_max_m`
|
||||
与任务的距离区间逐项比对,**不达标时先改视差域/基线/机型(P6),不要迁就旧数值**;
|
||||
3. 记录回填前后的 diff 与批准人(附录 A.2)。
|
||||
|
||||
### 2.4 连带修改清单(容易漏,会导致测试变红)
|
||||
|
||||
| 受影响处 | 现象 | 处置 |
|
||||
|---------|------|------|
|
||||
| `utils/tests/stereo_ranger/config_test.py::test_load_from_json_matches_defaults` | **必失败**:该用例断言 JSON 内容与 `StereoConfig()` 占位默认值逐字段相等 | 改为"语义一致性"断言(域关系、派生恒等式、取值约束),或维护一份"当前标定值"副本单独比对;**不要**为了过测试而改 dataclass 默认值——默认值是单测的占位基准 |
|
||||
| `utils/tests/stereo_yolo/config_test.py::test_load_from_json_matches_defaults` | 同上(仅当改动 `stereo_yolo.json` 时) | 同上 |
|
||||
| `docs/双目测距技术路线.md` §9 各表的 ⚠ 标记 | 表格仍写占位值 | 回填为实测值并标注日期与来源(保持"以规格为准") |
|
||||
| `utils/stereo_ranger/README.md`、`utils/stereo_yolo/README.md` 的占位值表 | 同上 | 同步,并撤掉"占位红线"字样(或改为"已标定") |
|
||||
| `utils/demo_stereo_ranger.py` 的注释(`F·B=57.6 px·m`) | 注释过时 | 同步数值 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 阶段 2:校正质量核验
|
||||
|
||||
**判据(§12.1 校正质量)**:静态场景下,左右匹配框的 \|Δy\| 分布 **P95 ≤ 1 px**(⚠占位)。
|
||||
不达标 → **触发自标定提前**(§7 风险表第 7 项、《需求说明》§6)。
|
||||
|
||||
### 3.1 建议方法
|
||||
|
||||
1. 静态标靶(棋盘格或随机纹理板)摆在近/中/远 3 档(如 3 / 8 / 15 m),每档在画面
|
||||
中心与四角共 5 个区域成像;
|
||||
2. 每处采 ≥50 帧,用**检测链路本身**(前端 → 两目框)统计 `|y1_L − y1_R|` 与
|
||||
`|cy_L − cy_R|` 双口径的 P95;
|
||||
3. 交叉验证:若统计值接近 1 px,改用角点/纹理匹配口径(不依赖检测框边缘)复核,
|
||||
避免把"检测边缘抖动"误判成"校正误差"。参考量级:本仓合成对(已知零校正误差)
|
||||
在 1080p 下实测 \|Δy\| ≈ 0.2 px,即**检测链路自身就贡献约 0.2 px 噪声**。
|
||||
|
||||
### 3.2 不达标时的排查顺序
|
||||
|
||||
1. 内参/remap 是否张冠李戴(最常见:用原始图内参解释校正图);
|
||||
2. 校正映射是否按原生分辨率生成(缩放过的 map 会引入亚像素偏置);
|
||||
3. 两目光轴平行度/安装(机械问题,需厂商介入);
|
||||
4. 仍不达标 → 自标定(P2 不达标即 v1.1 自标定提前,§7 风险表)。
|
||||
|
||||
⚠ **工具缺口**:仓库目前**没有**该统计脚本,需新增(建议 `utils/tools/calib_check.py`,
|
||||
输入左右目图像目录,输出 \|Δy\| 直方图与 P95)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 阶段 3:真实素材采集与入库
|
||||
|
||||
### 4.1 采集清单
|
||||
|
||||
| 档位 | 内容 | 用途 |
|
||||
|------|------|------|
|
||||
| 5 / 10 / 15 / 20 m | 静态标靶(或无人机目标静置),每档 ≥50 帧,手持激光测距仪同步记录真值 | P4 测距精度(§12.1) |
|
||||
| ≥25 m(域外档) | 同上 | 验证"域外不撒谎":`valid=false` 且方位照常发布(§12.3 第 3 条) |
|
||||
| 横向快速移动 | 目标在画面内快速平移 | 帧同步核验(§12.1:无系统性虚假视差) |
|
||||
| 多目标 | 同画面 2 个同类目标 + 1 个非目标干扰 | P5 的 `isolation_gate_px` 整定 |
|
||||
| 丢失-恢复 | 目标被遮挡 ≥ `filter_reset_frames` 帧后重现 | P5 的 `filter_reset_frames` / `smooth_alpha` 整定 |
|
||||
|
||||
### 4.2 命名与落位(建议)
|
||||
|
||||
```
|
||||
utils/assets/stereo_yolo/<YYYYMMDD>/z05m_01_L.png
|
||||
z05m_01_R.png # 双流形态
|
||||
z05m_01_sbs.png # sbs 形态(推荐,§2.3)
|
||||
z05m_01.json # 元数据
|
||||
```
|
||||
|
||||
元数据必填字段:拍摄时间、距离真值 + 测距仪型号、目标类型、光照/天气、曝光与增益、
|
||||
同步形态、分辨率、帧号范围、操作人。
|
||||
|
||||
### 4.3 注意
|
||||
|
||||
- **素材必须是校正后的图**(或同时保存原始图 + 本次使用的 remap 表)——否则 P4 的
|
||||
误差里混进校正误差,无法归因(§2.2 第 4 条);
|
||||
- 替换 `utils/assets/stereo_yolo/drone_sky.png` 只能换"单图冒烟"的输入;上面这套
|
||||
目录结构需要配回放脚本(见 P4 工具缺口)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 阶段 4:测距真值验证
|
||||
|
||||
**判据(§12.1 测距精度)**:以**地面手持激光测距仪**为真值(D8:测距方向与 `Z`
|
||||
一致,不是斜距 `R`);有效域内 **δZ ≤ 2 m**(⚠占位);误差趋势符合 `δZ ∝ Z²`(§7.1)。
|
||||
|
||||
### 5.1 方法与产物
|
||||
|
||||
1. 每档 ≥50 组"前端 → `StereoRanger.update()`"输出,与真值比对,输出**误差-距离曲线**;
|
||||
2. 由曲线拟合实测 δD(视差噪声基准,当前固定 1 px 是占位,§12.2),
|
||||
并用 `Z_budget = sqrt(max_delta_z_m × F·B / δD_meas)` 反推"预算门"应落在哪;
|
||||
3. 单独跑域外档,确认 `valid=false` 且 `center_mid_px` 仍发布(§7.3 域外不撒谎,
|
||||
也不丢方位);
|
||||
4. 结果记入附录 A.4。
|
||||
|
||||
### 5.2 不通过时的归因顺序
|
||||
|
||||
| 现象 | 首先怀疑 | 处置 |
|
||||
|------|---------|------|
|
||||
| 全档系统性偏置 | 内参/基线错、取点规则 | 复核 P1 回填值;复核 `x1` 取点(§6.1 同侧边缘) |
|
||||
| 误差随 Z² 放大且系数偏大 | 实测 δD 大于既定基准 | 收紧 `max_delta_z_m` 或缩小有效域;把实测 δD 写回规格(§12.2) |
|
||||
| 远场随机跳变 | 检测边缘抖动 + 小视差放大 | 属预期(§7.2),确认降级/门限按 §6.4 生效即可 |
|
||||
| 横向移动时出现虚假视差 | 帧同步 | 回到 P3 复核同步形态(§2.3) |
|
||||
|
||||
⚠ **工具缺口**:仓库目前**没有**"真实素材回放"脚本(现 demo 的合成对是解析构造的),
|
||||
需新增(建议 `utils/tools/replay_stereo.py`,输入 4.2 的目录结构,输出逐帧记录
|
||||
与误差表)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 阶段 5:阈值整定清单
|
||||
|
||||
§9 表中每个 ⚠ 都要在本阶段被实测值替换。整定依据与建议方法:
|
||||
|
||||
| 参数 | 占位值 | 整定输入 | 建议方法 |
|
||||
|------|-------|---------|---------|
|
||||
| `tau_y_px` | 2.0 | P2 的 \|Δy\| 分布 | 取 P95 的 1.5~2 倍留余量 |
|
||||
| `tau_h_ratio` | 0.25 | 真实框高相对差分布 | 同上口径 |
|
||||
| `disparity_min_px` | 3.0 | 可测远界需求 | 由任务远界反推(P1 已重算) |
|
||||
| `disparity_max_px` | 57.6 | 任务近界 | 由 `Z_near` 反推(P1 已重算) |
|
||||
| `max_delta_z_m` | 2.0 | P4 的误差曲线 | 由可接受的最大距离误差定;与 δD 实测联动(P4 第 2 步) |
|
||||
| `consistency_jump_px` | 3.0 | 静态场景视差噪声 P95 | 取噪声峰值的数倍:太小误判、太大漏检(§6.7) |
|
||||
| `consistency_N_frames` | 3 | 安全需求 + 误报率 | N/M 决定"异常后多久降级/判无效"(3/5 ≈ 0.17 s @30 fps),与消费侧的降级时延一起定 |
|
||||
| `consistency_M_frames` | 5 | 同上 | 必须 ≥ N |
|
||||
| `smooth_alpha` | 0.3 | P4 数据离线拟合 | 在"噪声抑制"与"群延迟"间取平衡(0.3 ≈ 3.3 帧群延迟) |
|
||||
| `jump_reset_m` | 5.0 | 真实跳变幅度观测 | 用目标切换/大机动场景标定 |
|
||||
| `filter_reset_frames` | 5 | 丢失-恢复场景 | 与消费侧 coast 策略配合(§6.5) |
|
||||
| `isolation_gate_px` | 50.0 | 多目标场景 | 由"同帧不同目标的最小像素间距"定,取小于该值的门限 |
|
||||
|
||||
前端侧同步复核:`conf_threshold` / `iou_threshold` 与真实素材上的漏检/误检权衡;
|
||||
`imgsz` 与平台算力(P7)——**这两项不随标定变化,但要与检测质量一起整定**。
|
||||
|
||||
---
|
||||
|
||||
## 7. 阶段 6:台架/SITL 联动与解禁评审
|
||||
|
||||
### 7.1 台架联动(判据见 §12.1 控制联动)
|
||||
|
||||
回放/SITL 下跑通:距离闭环 ↔ 定速接近切换、`invalid` 持续降级路径、
|
||||
远场"方位闭环 + 定速接近"(D4)——场景覆盖要求见《视觉跟踪控制律技术路线》第 7 章。
|
||||
|
||||
### 7.2 解禁检查表(§12.3 四条逐条勾选)
|
||||
|
||||
- [ ] **红线 1**:§7/§9 中所有 ⚠ 数值已由实测/厂商数据确认,替换记录已归档(附录 A.2/A.3/A.4);
|
||||
- [ ] **红线 2**:相机参数与阈值全部在配置文件中,代码内无写死(含 demo/工具脚本复核);
|
||||
- [ ] **红线 3**:域外/失配确实输出 `valid = false`——合成回归(`pytest -q`)+ 真实素材(P4 域外档)两轮都有证据;
|
||||
- [ ] **红线 4**:地面真值验证完成并归档(P4 全档通过)。
|
||||
|
||||
### 7.3 解禁之后仍未解禁的
|
||||
|
||||
本文解除的是**测距/检测链路**的红线。实飞还要求控制律侧完成
|
||||
《视觉跟踪控制律技术路线》§8 阶段 6 的增益与限幅整定——两者都满足才可实飞。
|
||||
|
||||
---
|
||||
|
||||
## 附录 A:记录表模板
|
||||
|
||||
### A.1 开箱登记
|
||||
|
||||
| 项 | 值 |
|
||||
|----|----|
|
||||
| 型号 / 序列号 | |
|
||||
| 分辨率 / 帧率 / 像素格式 | |
|
||||
| 标称基线 / 实测基线(工具、公差) | |
|
||||
| 校正后内参(fx, fy, cx, cy) | |
|
||||
| 畸变系数 / remap 表版本 | |
|
||||
| 出厂标定报告编号与日期 | |
|
||||
| 同步形态(sbs / 双流 / 硬触发) | |
|
||||
| 到货日期 / 登记人 | |
|
||||
|
||||
### A.2 参数回填记录
|
||||
|
||||
| 字段 | 回填前 | 回填后 | 来源 | 日期 / 批准 |
|
||||
|------|-------|-------|------|------------|
|
||||
|
||||
派生量复核(手算 vs 程序):`F·B` = ___,`z_min_m` = ___,`z_max_m` = ___,
|
||||
`z_error_budget_max_m` = ___。
|
||||
|
||||
### A.3 校正质量核验
|
||||
|
||||
| 档位 | 区域 | 样本数 | \|Δy\| P95 | 判据 ≤1 px | 备注 |
|
||||
|------|------|-------|-----------|-----------|------|
|
||||
|
||||
### A.4 测距真值验证
|
||||
|
||||
| 距离真值 | 样本数 | Z 均值 | δZ | 判据 ≤2 m | valid 率 | 备注 |
|
||||
|---------|-------|-------|----|----------|---------|------|
|
||||
|
||||
---
|
||||
|
||||
## 附录 B:判据来源索引
|
||||
|
||||
| 本文阶段 | 规格出处 |
|
||||
|---------|---------|
|
||||
| P1 回填与派生量 | 《测距路线》§9.1、§6.4、§11.2 |
|
||||
| P1 连带修改 | `utils/stereo_ranger/config.py`(fail-fast 规则)、两份 `config_test.py` |
|
||||
| P2 校正质量 | 《测距路线》§12.1、§7 风险表第 7 项;《需求说明》§6 |
|
||||
| P3 采集与同步 | 《需求说明》§2.3;《测距路线》§12.1 帧同步 |
|
||||
| P4 真值验证 | 《测距路线》§12.1、§7.1、§7.2、§7.3(D8 真值方向) |
|
||||
| P5 阈值整定 | 《测距路线》§9 全表、§12.2;《需求说明》§4 |
|
||||
| P6 联动与解禁 | 《测距路线》§12.1、§12.3;《视觉跟踪控制律技术路线》§7/§8 |
|
||||
|
||||
## 附录 C:已知缺口(执行前需补齐)
|
||||
|
||||
1. **工具脚本缺三件**(本文标注 ⚠):校正质量统计(P2)、真实素材回放(P4)、
|
||||
真值-误差曲线拟合(P4)。在它们就位前,P2/P4 只能手工抽样,判据不可复现;
|
||||
2. **外部参考文档缺档**:《测距路线》§12.2 把开放问题(P1 焦距规格、P2 出厂标定、
|
||||
P3 帧同步形态、P6 换机型、P7 性能实测、P8 避障激光去留)的**权威清单**指向
|
||||
《双目深度估计思路》第 15 章,该文档当前不在仓库中——需要它才能核对问题编号与
|
||||
结论,请补回或改引他处;
|
||||
3. **P7(性能实测)不在本文范围**:它依赖机载/边缘平台,属平台工程文档。
|
||||
Reference in New Issue
Block a user