精简仓库结构并增强任务链路:归档双目可选后端、新增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,170 @@
|
||||
# 双目 YOLO 目标识别模块需求说明(检测前端)
|
||||
|
||||
> **定位**:双目链路中的"检测前端",服务于已实现的 `utils/stereo_ranger`。本模块负责在左右目图像上独立运行 YOLO 类检测器,并输出**符合 stereo_ranger 输入契约**的检测框列表;**不承担**测距、左右目关联与立体校正。
|
||||
>
|
||||
> **版本**:0.2(2026-09-11;按 `utils/stereo_ranger` v1.0 实现接口对齐,文档引用随《双目测距方案》更名为《双目测距技术路线》同步更新)。
|
||||
>
|
||||
> **语义权威**:`docs/双目测距技术路线.md`(下称《测距路线》)——几何、取点、匹配、有效性、退化语义一律以其为准;**字段级接口以 `utils/stereo_ranger/types.py` 为准**(本文只做需求描述,不重复定义)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 目的与定位
|
||||
|
||||
单目检测给出像素框,stereo_ranger 需要"同一逻辑帧、左右目各自"的检测结果来完成视差测距。本模块把"图像 → 原生坐标系检测框"的整段处理收敛为对测距端透明的单一输入源:
|
||||
|
||||
```
|
||||
采集/同步 → 预处理(校正+letterbox)→ 左右目并行 YOLO 推理 → NMS
|
||||
→ 框映射回原生分辨率 → 输出 DetectionFrame(左右各一)→ stereo_ranger.update(...)
|
||||
```
|
||||
|
||||
### 1.1 明确不做的事
|
||||
|
||||
- 不做视差计算、左右目关联、距离/方位估计(均属 stereo_ranger);
|
||||
- 不做立体校正本身(校正映射属于采集预处理,契约见《测距路线》§2.1"校正契约"与本文 §2.2 第 4 条);
|
||||
- 不做跨帧跟踪(`track_id` 可由外部追踪器注入;无追踪器时留空,见 §2.1)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 与 stereo_ranger 的接口契约(硬性要求)
|
||||
|
||||
接口对齐 `utils/stereo_ranger/types.py` 与 `utils/stereo_ranger/stereo_ranger.py` 的实现,任何偏离都会破坏测距正确性。
|
||||
|
||||
### 2.1 输出数据定义
|
||||
|
||||
输出即 stereo_ranger 的输入:**每目一个 `DetectionFrame`**。字段名与语义以
|
||||
`utils/stereo_ranger/types.py` 为准(下例仅为语义说明,不重复定义):
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Detection:
|
||||
x1: float # 框左上角 x(已校正图像坐标,原生分辨率 px)
|
||||
y1: float # 框左上角 y
|
||||
x2: float # 框右下角 x
|
||||
y2: float # 框右下角 y
|
||||
confidence: float = 1.0 # 检测置信度 [0,1]
|
||||
class_id: int = 0 # 类别 id(左右目同一目标必须一致,§2.2 第 5 条)
|
||||
track_id: int | None = None # 检测侧轨道关联;无追踪器时留空(0/负数一律视为"无轨道")
|
||||
|
||||
@dataclass
|
||||
class DetectionFrame:
|
||||
frame_id: int # 帧标识;左右两帧必须一致(同帧契约,§2.3)
|
||||
detections: Sequence[Detection] = () # 该目本帧检测框
|
||||
```
|
||||
|
||||
- **推荐直接复用** `utils/stereo_ranger/types.py` 的 `Detection` / `DetectionFrame`
|
||||
(纯值语义、无第三方依赖;只共享数据约定、不引入解算逻辑,不违反前端/测距解耦);
|
||||
若因部署边界另建类型,字段名与语义必须逐字一致——两处定义漂移会静默破坏视差取点;
|
||||
- `track_id` **仅供测距端做目标隔离键**(左右一致且为正时优先),不参与匹配与解算(§2.5);
|
||||
- 每目一帧内多目标的排列顺序无要求,按检测器输出自然顺序即可。
|
||||
|
||||
### 2.2 坐标与几何硬约束
|
||||
|
||||
1. **原生分辨率坐标系**:输出框必须位于校正后图像的原生分辨率(如 1920×1080)下;视差在原生坐标计算,才能保留传感器全部像素精度(《测距路线》§2.1"坐标基准一致")。检测器输入尺寸(如 640×640)上的框必须经 letter-box 逆变换精确映射回原生坐标。
|
||||
2. **左右目预处理几何位级一致**:同一缩放、同一填充。禁止左右图各自自适应缩放/填充——那会破坏校正后的极线对齐性质。
|
||||
3. **框边语义**:`(x1, y1)` 为左上角、`x1` 即框"左边缘"(测距端主方案直接取 `x1_L − x1_R` 作视差,《测距路线》§6.1)。实现方不得把框定义改为中心点+宽高而不转换。
|
||||
4. **立体校正前提**:本模块输出的是"校正后图像"上的框。若输入为原始图,采集端须先做与测距端内参一致的重映射(校准映射、内参由标定给出)。
|
||||
5. **同一物理目标在左右目必然同时可见时**,其两框 `y` 坐标应接近(垂直残差验收见 §6);`x1` 有系统偏移(`≈ F·B/Z` 视差)属正常,不得在识别端"对齐"掉。**同一目标的类别在两目必须一致**——类别一致是测距端匹配的硬约束(《测距路线》§6.2),不一致会退化为两条"仅方位"记录。
|
||||
6. **输出前自检**:所有框坐标必须为有限值且满足 `x2 > x1`、`y2 > y1`。非有限值框会被测距端丢弃(不参与匹配、不发布记录),畸变框会污染框高约束与匹配代价——自检应在识别端出口完成,而不是依赖下游兜底。
|
||||
|
||||
### 2.3 帧配对要求
|
||||
|
||||
- 每帧必须携带**单调递增的帧标识**(`DetectionFrame.frame_id`,int),左右两个容器共用同一值;
|
||||
- `frame_id` 不一致时测距端**拒收整帧、返回空列表**(《测距路线》§2.1 同帧契约、§5 第 ① 步)——下游兜底不等于可以松懈,正确配对是采集端的责任;
|
||||
- 无硬件同步的双独立流形态下,采集端按接收时间窗配对并输出帧标识,残余时序抖动应记录供误差评估(两种同步形态的取舍见《双目深度估计思路》§3.2,该文档为链路外部参考);
|
||||
- 同帧拼接(side-by-side)单流形态:解码一次、裁切为左右图,天然同曝光,推荐优先支持;
|
||||
- 帧标识由采集端按真实曝光顺序分配,**禁止为凑成"同帧"而重编号**(§2.5 第 5 条)。
|
||||
|
||||
### 2.4 与测距端的对接方式(示例)
|
||||
|
||||
```python
|
||||
from utils.stereo_ranger import StereoRanger
|
||||
from utils.stereo_ranger.types import DetectionFrame # 纯值类型,可安全复用
|
||||
|
||||
frontend = StereoYoloFrontend(cfg) # 本模块主类
|
||||
ranger = StereoRanger(stereo_cfg) # 配置见 §4,实测值见 utils/config/stereo_ranger.json
|
||||
|
||||
left_frame, right_frame = frontend.detect(left_img, right_img, frame_id=n) # 各一个 DetectionFrame
|
||||
records = ranger.update(left_frame, right_frame, now_ms=monotonic_ms())
|
||||
```
|
||||
|
||||
- **第三个参数是 `now_ms`(平台单调时钟毫秒,仅用于输出打戳,默认 0),不是帧序号**——按位置把 `n` 传进去会被静默当作时间戳,污染 `timestamp_ms`;
|
||||
- 返回 `list[RangeRecord]`,顺序:先按左目框顺序(配对→完整记录 / 未配对→仅方位记录),再补未配对的右目框的"仅方位"记录;左目非空时记录数与左目框数一致;
|
||||
- **没有 `matched` 字段**。单目检出的记录为 `degradation = BEARING_ONLY`、`valid = False`、`forward_distance_m = None`,方位取该目框中心;
|
||||
- 配对成功但域外/一致性异常时仍发布 `degradation = COMPLETE` 的记录(`disparity_px`、`center_mid_px` 可用),但 `valid = False`、`forward_distance_m = None`——**域外不撒谎,也不丢方位**(《测距路线》§7.3);
|
||||
- **测距端不消费检测置信度**:完整记录的 `confidence` 是匹配质量 `clamp(1 − 匹配代价)`(连续跳变时乘降级系数,判 invalid 时置 0);仅方位记录的 `confidence` 才直接取检测置信度。故 conf 阈值/NMS 必须由识别端自行完成后再输出;
|
||||
- 两目检测均为空 → 返回空列表(正常空帧,不告警)。
|
||||
|
||||
### 2.5 输入纯净性硬约束(v0.2 新增,飞行安全相关)
|
||||
|
||||
1. **只送本帧原生实测框**:`update()` 的输入必须是**本帧、在原生校正图上检测得到的框**。跨帧外推框(追踪器预测/Coast 补帧)、平滑后的框、按上一帧位移推算的"虚拟框"**一律不得送入**;
|
||||
2. **外推框会伪装成合法测量**:框的 `x1` 偏差直接进入视差 `D = x1_L − x1_R`,`Z = F·B/D` 没有任何机制识别"这不是本帧观测",误差随 `Z²` 放大且不触发 `valid` 门(《测距路线》§7.1);测距端的时序一致性监控最多把它降级,不能纠偏(《测距路线》§6.7);
|
||||
3. **目标丢失就该没有距离**:本帧未检出 → 不发布该目标检测框;测距端对其记失效、连续 `filter_reset_frames` 帧后清空滤波状态(《测距路线》§6.5)。距离中断(coast)属于**消费侧**策略,且必须与 `valid` 语义分开标注;
|
||||
4. **`track_id` 仅作隔离键**:由外部追踪器注入时只用于目标状态隔离(《测距路线》§4);**不得用追踪框充当检测框**;左右目同一目标的 `track_id` 必须一致,否则隔离退化为最近邻兜底(§2.1);
|
||||
5. **两目同源**:左右框必须来自同一次曝光(同帧契约);左右取自不同帧、仅凭"时间接近"拼成一对,即使 `frame_id` 相同也属违约——`frame_id` 由采集端保证真实(§2.3);
|
||||
6. **前端不做左右匹配、不做对齐**:左右匹配、视差取点、方位解算全部在 stereo_ranger;识别端只需保证"每目各自把该目可见目标检测出来",不得为便于后端匹配而调整框位置(《测距路线》§1.4)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 模块内部建议构成(实现参考)
|
||||
|
||||
| 子模块 | 职责 | 说明 |
|
||||
|---|---|---|
|
||||
| 采集/同步(可选) | 双流按帧标识+时间窗配对,或 sbs 裁切 | 无硬同步时量化残余抖动;帧标识不得重编号(§2.3) |
|
||||
| 几何预处理 | 校正 remap → 左右完全一致的 letterbox | letterbox 参数(缩放 s、填充)必须左右共用一份配置 |
|
||||
| 推理调度 | 左右目各一次检测 | **必须并发**:单设备双流或双实例双线程;串行使时延翻倍(《测距路线》§10.1:检测单核 20~30ms,NPU 预算成立) |
|
||||
| YOLO 推理 + NMS | 输出 640×640(或配置尺寸)坐标系下的框 | 类别表、conf/NMS 阈值外置 |
|
||||
| 坐标回映 | 逆 letterbox 映射到原生分辨率 | 与预处理使用同一套变换参数,禁止各写一份 |
|
||||
| 输出适配 | 出口自检(有限值、`x2>x1`、`y2>y1`)→ 每目封装 `DetectionFrame(frame_id, detections)` | 字段严格按 §2.1;`frame_id` 左右共用 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 配置项需求(全部外置,禁止硬编码)
|
||||
|
||||
| 配置 | 说明 |
|
||||
|---|---|
|
||||
| 模型权重 / 类别表 | 检测器选择(YOLOv5/v8/…)不设限 |
|
||||
| 输入尺寸 | 如 640×640;左右共用 |
|
||||
| conf / NMS IoU 阈值 | 识别端自身过滤口径(测距端不消费检测置信度,§2.4) |
|
||||
| 输出类别过滤 | 可选白名单;同一目标左右目类别必须一致(§2.2 第 5 条) |
|
||||
| 原分辨率与内参 | 逆映射/校验用;`fx_px`/`fy_px`/`cx_px`/`cy_px` 必须与测距端配置**同源同值**(当前占位值见 `utils/config/stereo_ranger.json`,标定回填后同步) |
|
||||
| 并发策略 | 单实例多线程 or 双实例 |
|
||||
| 帧同步方式 | sbs / 双流 + 时间窗 |
|
||||
|
||||
配置一致性要求(§5"一致性"项的落地):letterbox 缩放与填充参数、内参、原分辨率
|
||||
均由**同一配置源**驱动左右两目与两个模块;任何一处单独调整都会造成视差系统性偏差
|
||||
(《测距路线》§9 全部参数外置、启动期校验的语义同样适用于本模块)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 非功能需求(大致)
|
||||
|
||||
| 项目 | 要求 |
|
||||
|---|---|
|
||||
| 帧率 | 满足测距流水线帧周期(如 30 fps → ≤33 ms/帧) |
|
||||
| 左右推理 | 必须并发执行(《测距路线》§10.1:检测单核 20~30ms,串行会吃掉全部预算) |
|
||||
| 端到端时延 | 实测并留出余量:识别之外,匹配+测距在少量目标时 <1 ms(测距端为纯计算单元、无 IO 无阻塞,《测距路线》§11.3) |
|
||||
| 一致性 | 左右目预处理/回映参数由同一配置源驱动,杜绝两路漂移(§4 配置一致性要求) |
|
||||
| 失败处理 | 单目推理失败等异常不阻塞整体,该目输出空帧列表(测距端退化为另一目的仅方位记录);错误日志节流(《测距路线》§5:第 1 次 + 每满 100 次,带累计计数) |
|
||||
|
||||
---
|
||||
|
||||
## 6. 验证与验收(大致)
|
||||
|
||||
| 项目 | 方法 | 通过标准(示意) |
|
||||
|---|---|---|
|
||||
| 坐标回映 | 已知缩放/填充的合成图,比对回映框与真值 | 误差 <0.5 px(像素取整前) |
|
||||
| 垂直对齐 | 静态场景,左右匹配框 \|Δy\| 直方图 | P95 ≤1 px(《测距路线》§12.1 校正质量;不达标触发自标定提前) |
|
||||
| 类别一致性 | 静态场景统计同一目标两目类别 | 不一致率 ≈0(不一致会被测距端匹配硬约束拦截,退化为两条仅方位记录) |
|
||||
| 输出合法性 | 出口自检单测(含非有限值、退化框构造用例) | 无 `x2 ≤ x1` / `y2 ≤ y1` / 非有限值框输出(§2.2 第 6 条) |
|
||||
| 输入纯净性 | 代码审查 + 单测:断言送入 `update()` 的框集合恰为本帧检测输出 | 无预测/Coast/平滑框进入(§2.5) |
|
||||
| 下游对接 | 用本模块输出喂 `StereoRanger.update()` | 与 `utils/demo_stereo_ranger.py` 真值投影法结果同量级;误差随距离趋势符合 `δZ ∝ Z²`(《测距路线》§7.1) |
|
||||
| 帧周期 | 双流满负荷计时 | 满足所选帧率预算 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 依赖与边界
|
||||
|
||||
- 依赖:YOLO 推理栈(如 onnxruntime/torch)、opencv(解码/预处理/校正 remap,若选用 numpy 实现 letterbox 亦可);**不 import `stereo_ranger` 的测距逻辑**(保持前端/测距解耦),仅可复用 `stereo_ranger/types.py` 的纯值类型(可选,见 §2.1)与同一份配置数值(§4);
|
||||
- 本模块不实现:跨帧跟踪(无追踪器时 `track_id` 留 `None` 可接受)、距离 coast/外推(属消费侧,§2.5 第 3 条)、自标定与立体校正本身、主测距传感器融合;
|
||||
- 若部署平台算力不足(如边缘设备),允许降低输入分辨率或帧率,但左右一致性与原生回映两条约束不可妥协(§2.2 第 1、2 条);
|
||||
- **红线同源**:本模块输出同样受《测距路线》§12.3 约束——标定完成前内参等数值均为占位值,仅限台架/回放验证,不得接入实飞控制回路。
|
||||
@@ -0,0 +1,754 @@
|
||||
# 双目测距技术路线
|
||||
|
||||
> 本文档把双目测距(立体目标测距)抽象为**与编程语言、硬件平台无关**的技术路线:
|
||||
> 只讲几何模型、数据结构、算法流程与质量语义,不依赖任何语言特性、加速器
|
||||
> 型号或操作系统。可作为任意语言(C++/Rust/Python 仿真/嵌入式 C)在任意
|
||||
> 算力平台上重新实现或移植的规格说明。
|
||||
>
|
||||
> **文档分工**(各司其职,不重复抄录):
|
||||
>
|
||||
> | 文档 | 定位 | 与本文的分工 |
|
||||
> |------|------|--------------|
|
||||
> | `docs/双目深度估计思路.md` | 平台工程路线 + 原稿对照 | **平台与工程细节权威**:采集/解码链路、加速器预算、线程与文件落点、原稿缺陷对照;本文一律不涉及 |
|
||||
> | 本文 | **算法路线** | **算法与语义权威**:几何、取点、匹配、有效性、滤波、方位源、误差模型、职责与缺点 |
|
||||
> | `docs/视觉跟踪控制律技术路线.md` | 距离/方位的消费者 | 其距离通道与方位源如何消费本文输出,见其 §1.2/§2/§6.4 |
|
||||
> | `docs/双目测距方案讨论纪要.md` | 决策索引 | D2/D4/D5/S1~S3 等拍板结论的唯一索引,本文只落实、不重新讨论 |
|
||||
>
|
||||
> 三份技术路线若出现表述分歧:拍板结论以《双目测距方案讨论纪要》为准,
|
||||
> 算法语义以本文为准,平台工程以《双目深度估计思路》为准。
|
||||
>
|
||||
> **参考实现**:`utils/stereo_ranger/`(Python,构件划分与本文逐条对应)。
|
||||
> 实现时冻结的补充决策与发现的原文矛盾已回填本文(§4/§6.1/§6.2/§6.4/
|
||||
> §6.7/§9/§11),两文档以本文为准。
|
||||
>
|
||||
> ⚠️ **全部数值均为占位值**:焦距/标定参数待厂商数据(P1/P2),各阈值未整定。
|
||||
> 标定与地面真值验证完成前,本模块输出**仅限静态标靶/回放/台架验证,
|
||||
> 不得作为飞行控制决策依据**(见 §12.3 红线)。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [概述与系统定位](#1-概述与系统定位)
|
||||
2. [输入输出接口定义](#2-输入输出接口定义)
|
||||
3. [坐标系与符号约定](#3-坐标系与符号约定)
|
||||
4. [核心构件与状态清单](#4-核心构件与状态清单)
|
||||
5. [单周期处理流程(主流程伪代码)](#5-单周期处理流程主流程伪代码)
|
||||
6. [各环节算法细节](#6-各环节算法细节)
|
||||
7. [误差模型与有效距离域](#7-误差模型与有效距离域)
|
||||
8. [职责、边界与已知缺点](#8-职责边界与已知缺点)
|
||||
9. [配置参数全量表](#9-配置参数全量表)
|
||||
10. [设计取舍记录(为什么不是别的做法)](#10-设计取舍记录为什么不是别的做法)
|
||||
11. [实现与重写指引](#11-实现与重写指引)
|
||||
12. [验证路线与待定项](#12-验证路线与待定项)
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述与系统定位
|
||||
|
||||
### 1.1 模块职责
|
||||
|
||||
本模块是**目标距离与方位的机载唯一来源**(决策 D2:双目替代激光雷达,
|
||||
与提交 b96111e 一致)。它对**同一时刻**左右两幅已立体校正图像上的目标
|
||||
检测框做立体几何解算,输出**少量目标的**距离与方位(不是稠密深度图)。
|
||||
职责四件事:
|
||||
|
||||
1. **匹配**:把左右两目的检测框按"同一物理目标"配对(硬约束筛选 +
|
||||
贪心代价排序);
|
||||
2. **测距**:同侧边缘视差 D → `Z = F·B / D` 前向距离(斜距 R 仅参考输出);
|
||||
3. **方位源**:输出**虚拟双目中心**像素 `c_mid`(两目框中心等权平均,
|
||||
消除单目近场视差偏差,§6.6);
|
||||
4. **质量语义**:输出有效性标志与置信度(有效域内 + 匹配成功 + 一致性
|
||||
正常),对距离做轻量时间滤波;域外/失配/异常时**明确输出无效**,
|
||||
不得强行估计。
|
||||
|
||||
### 1.2 在系统中的位置
|
||||
|
||||
```text
|
||||
平台采集/解码/立体校正(平台相关,见《双目深度估计思路》第 3/8 章)
|
||||
→ 校正后左/右图像(同帧)
|
||||
→ 左/右目标检测(外部模块,输出原图坐标系的检测框)
|
||||
→ 本模块:匹配 + 测距 + 方位源 + 有效性 + 滤波 → 目标距离记录
|
||||
├─ 距离 Z(valid)──▶ 控制律距离通道(Δd → PID → 前向速度,域内闭环)
|
||||
├─ 方位 c_mid ──────▶ 接入层填入控制律目标中心(虚拟中心相机像素)
|
||||
└─ valid / 置信度 ──▶ 接入层降级语义:
|
||||
域外/失配 → "无距离"策略(方位闭环 + 定速接近,D4)
|
||||
持续无距离 → exit 档降级(S1 门限,消费侧实现)
|
||||
```
|
||||
|
||||
**上游**:同帧校正图像对与左右检测框(检测、采集、解码、校正均为外部
|
||||
模块);**下游**:跟踪控制律与接入层。"域外定速接近"的远场补偿策略
|
||||
属消费侧行为,本文只负责提供诚实的有效性标志与持续的方位。
|
||||
|
||||
### 1.3 设计特点
|
||||
|
||||
| 特点 | 含义 | 带来的约束 |
|
||||
|------|------|-----------|
|
||||
| **稀疏输出** | 只算检测到的目标,不做逐像素匹配 | 无检测即无输出;距离精度受框质量制约(§8) |
|
||||
| **纯值输入/输出** | 每帧传入同帧框对 + 参数,输出纯值记录列表 | 无隐藏输入、可离线回放 |
|
||||
| **纯函数构件** | 取点、测距、域判定均为无状态纯函数 | 可独立单元测试(合成框对即可,无需真实图像) |
|
||||
| **有状态部分极小** | 仅滤波器、一致性监控与目标隔离状态,且按目标隔离 | 重写时状态清单见 §11.1,漏一个就变行为 |
|
||||
| **参数全外置** | 几何、阈值、滤波参数全部来自配置 | 代码内不得写死任何相机参数或阈值 |
|
||||
| **诚实降级** | 域外/失配输出 `valid = false` 而非勉强给值 | 消费侧的远场策略建立在"不撒谎"的有效性上 |
|
||||
|
||||
### 1.4 明确不做的事(边界)
|
||||
|
||||
- **不做采集/解码/立体校正**:消费校正后的图像与框;校正与自标定属
|
||||
平台工程(v1.1 备选),不在本文范围;
|
||||
- **不做稠密匹配**:不做 SGBM 类逐像素立体匹配,不输出深度图;
|
||||
- **不做环境感知/避障**:环境深度由避障侧深度模型负责,与本模块并存
|
||||
互不替代;
|
||||
- **不做目标跟踪**:不维护轨道与运动滤波;上游 track_id 只用作目标
|
||||
状态隔离键(§4),不参与匹配打分与连续性先验(后者留 v1.1);
|
||||
- **不做运动/IMU 补偿**:帧间运动引起的虚假视差靠帧同步契约与一致性
|
||||
监控兜底,不做解算级补偿;
|
||||
- **不做多传感器融合**:双目是目标距离机载唯一来源(D2),无交叉校验
|
||||
基准;数据质量靠内部一致性监控自检(§6.7);
|
||||
- **不在域外强行估计**:超出有效距离域一律输出 `valid = false`。
|
||||
|
||||
---
|
||||
|
||||
## 2. 输入输出接口定义
|
||||
|
||||
### 2.1 输入(每帧一次,由平台层供给)
|
||||
|
||||
| 分组 | 项 | 语义与约束 |
|
||||
|------|----|-----------|
|
||||
| 帧对 | 左帧、右帧 | 各含**帧标识**;两帧标识必须一致(同帧契约,见下) |
|
||||
| 检测 | 检测框数组 ×2 | 每框含:类别、置信度、框(左上/右下角像素);**已映射回校正图像坐标系** |
|
||||
| 几何 | 基线 `B`、焦距 `F`、主点 `cx, cy` | 校正后内参(`fx = fy = F`);来自标定配置,禁止写死 |
|
||||
| 参数 | 匹配/有效性/滤波阈值 | 配置外置(§9),启动期加载并校验 |
|
||||
| 时钟 | 当前单调时刻 | 用于输出打戳 |
|
||||
|
||||
**契约要点**:
|
||||
|
||||
- **同帧契约**:左右帧必须来自同一曝光时刻(同步与配对由平台层保证,
|
||||
形态差异见《双目深度估计思路》§3.2)。本文把"左右帧标识一致"作为
|
||||
输入违约检查:不一致直接拒收本帧、输出空、告警节流——**不同帧的
|
||||
框配对解算没有物理意义**;
|
||||
- **校正契约**:检测框位于**已立体校正**的图像上("两目 y 对齐"是校正
|
||||
的结果而非假设,§3);未校正图像上的框不得进入本模块;
|
||||
- **坐标基准一致**:检测若在缩放/裁剪图上运行,框必须先映射回校正图像
|
||||
基准,且几何参数 `F/cx/cy` 使用同一基准的内参——否则视差与几何失配,
|
||||
距离系统性错误;
|
||||
- **时间戳纪律**:输出取样时刻以**平台接收时刻的单调时钟**为准,
|
||||
不伪造采集时刻。
|
||||
|
||||
### 2.2 输出:目标距离记录(每帧每目标一条,纯值)
|
||||
|
||||
| 字段 | 单位/类型 | 语义 |
|
||||
|------|-----------|------|
|
||||
| 帧标识 | — | 继承自输入帧对 |
|
||||
| 类别 | 枚举 | 目标类别 |
|
||||
| 轨道关联 | 整数或"无" | 检测侧 track 关联(如有;v1.0 可无) |
|
||||
| `Z` | m | 前向距离(沿光轴分量,**距离通道唯一消费量**) |
|
||||
| `R` | m | 斜距(参考值,不进控制回路;与已发布的 `Z` **同基准**——按滤波后 Z 换算,保证 `R ≥ Z`) |
|
||||
| `D` | px | 本次视差(调试与交叉校验用) |
|
||||
| `c_mid` | 像素 (x, y) | **虚拟双目中心**框中心:方位控制源(§6.6) |
|
||||
| 参考目框 | 像素框 | 左目(参考目)检测框,供交叉校验与调试 |
|
||||
| `confidence` | [0,1] | 匹配质量与一致性综合置信度 |
|
||||
| `valid` | 布尔 | 是否落在有效距离域且匹配成功且一致性正常(§6.4) |
|
||||
| 退化标记 | 枚举 | `完整`(距离+方位)/ `仅方位`(单目检出,§5 第 ⑤ 步) |
|
||||
| 取样时刻 | 单调时钟 | 平台接收时刻打戳(§2.1 时间戳纪律) |
|
||||
|
||||
**记录两态**:
|
||||
|
||||
- **完整记录**(匹配成功):距离 + 方位 + 有效性;
|
||||
- **仅方位记录**(仅一目检出,v1.0 允许):发布该目框中心作方位,
|
||||
`valid = false`,无距离;单目方位存在近场视差偏差(§6.6,v1.0 接受)。
|
||||
|
||||
### 2.3 输出语义与消费侧衔接
|
||||
|
||||
- `valid == true` 的 `Z` 才可作为控制律距离通道输入;消费侧另有自己的
|
||||
"有效性 + 正值 + 未超龄"三重门(见《视觉跟踪控制律技术路线》§6.4);
|
||||
- `valid == false`(域外/失配/一致性异常)→ 消费侧进入"无距离"策略
|
||||
(方位闭环 + 定速接近,默认档),持续无距离达门限才退出近距操作
|
||||
(消费侧 exit 门限,S1);
|
||||
- **`c_mid` 始终随检测发布**(域外仍有方位)——这是远场"方位闭环 +
|
||||
定速接近"策略得以成立的输入基础;
|
||||
- 消费侧以 `track_id` 一致性校验本记录与追踪主目标对应(调用方约定
|
||||
S3,库内不实现)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 坐标系与符号约定
|
||||
|
||||
### 3.1 符号表
|
||||
|
||||
| 符号 | 含义 | 单位 |
|
||||
|------|------|------|
|
||||
| `B` | 基线长度(左右光心间距) | m |
|
||||
| `F` | 像素焦距(校正后 `fx = fy`) | px |
|
||||
| `cx, cy` | x/y 方向主点 | px |
|
||||
| `xL, yL` | 目标点在**左目(参考目)**图像中的像素坐标 | px |
|
||||
| `xR` | 同一目标点在右目图像中的像素坐标 | px |
|
||||
| `D` | 视差 = `xL − xR` | px |
|
||||
| `Z` | 前向距离(沿光轴分量) | m |
|
||||
| `X, Y` | 相机(左目)坐标系横向/纵向偏移 | m |
|
||||
| `X_C` | 目标在**模组中心系**的横向偏移 | m |
|
||||
| `R` | 斜距 | m |
|
||||
| `cL, cR` | 同一目标在左/右目中的**检测框中心** | px |
|
||||
| `c_mid` | 虚拟双目中心框中心(方位源) | px |
|
||||
|
||||
**统一约定**:校正后**以左目为参考系**,视差 `D = xL − xR > 0`
|
||||
(正视差是物理前提;`D ≤ 0` 视为违例,§6.3)。
|
||||
|
||||
### 3.2 公式(校正后坐标系)
|
||||
|
||||
```text
|
||||
D = xL − xR (同一物理特征点的 x 坐标差)
|
||||
Z = F × B / D
|
||||
X = (xL − cx) × Z / F (左目系)
|
||||
Y = (yL − cy) × Z / F
|
||||
R = sqrt(X² + Y² + Z²)
|
||||
```
|
||||
|
||||
- **距离通道使用 Z(前向分量)而非 R**:与机头前向的期望射程语义对齐,
|
||||
也与地面真值仪(手持激光测距仪)的测量方向一致(决策 D8);
|
||||
小角度下 `Z ≈ R`,大偏航角目标时二者差异增大,地面验证解读数据须注意;
|
||||
- **X/Y 以左目系表达**;模组中心系下 `X_C = X − B/2`(左目光心在模组中线
|
||||
−B/2 侧,符号与 §6.6 一致;原文 `+B/2` 为笔误),`B/2` 对 `Z`、`R` 的
|
||||
影响可忽略(本机型 3cm)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心构件与状态清单
|
||||
|
||||
| 构件 | 职责 | 运行期持久状态 | 备注 |
|
||||
|------|------|---------------|------|
|
||||
| 流程编排 | 单周期五步流程(§5) | 无 | 每帧一次 |
|
||||
| 视差取点器 | 框 → 取点 x(同侧边缘,回退中心) | 无(纯函数) | §6.1 |
|
||||
| 匹配器 | 左右框配对 | 无(纯函数) | **接口注入**,默认贪心;可替换为匈牙利等而不动调用方 |
|
||||
| 测距计算 | `(D, 框)` → `(Z, X, Y, R, c_mid)` | 无(纯函数) | §3.2/§6.6 |
|
||||
| 有效性判定 | 域内 + 误差预算判定 | 无(纯函数) | §6.4 |
|
||||
| 一致性监控 | 时序层面质量自检 | **每目标**:上次视差 + 连续异常计数 | §6.7 |
|
||||
| 时间滤波器 | 距离低通 + 跳变重置 | **每目标**:上次滤波值、初始化标志、连续失效计数 | §6.5 |
|
||||
| 目标状态容器 | 隔离键解析 + 帧末老化清理 | **每目标**:最近框中心、最近出现帧 | 隔离键见下;连续 `filter_reset_frames` 帧未出现则整体清理 |
|
||||
| 告警节流器 | 异常日志限频 | 每类异常:首见标记 + 累计计数 | 第 1 次 + 每满 100 次 |
|
||||
|
||||
**目标隔离键(v1.0 冻结)**:`track_id` 优先——左右目的 track_id 一致且
|
||||
为正时,用 `(轨道, 类别, id)` 作键(v1.1 语义提前启用,上游追踪库已在
|
||||
链路中);否则回退**框位置最近邻**(同类别、门限 `isolation_gate_px` 内、
|
||||
本帧尚未被占用的最近状态,一一归属)。
|
||||
|
||||
重写/移植时最容易漏的是**每目标隔离**的一致性计数与滤波状态——按
|
||||
"全局单份"实现会在多目标下互相污染。
|
||||
|
||||
---
|
||||
|
||||
## 5. 单周期处理流程(主流程伪代码)
|
||||
|
||||
```text
|
||||
函数 单周期处理(左帧, 右帧, 参数, now_ms) -> 目标距离记录列表:
|
||||
|
||||
# ---- ① 输入违约检查 ----
|
||||
若 左帧.帧标识 ≠ 右帧.帧标识:
|
||||
告警节流("左右帧非同帧,拒收")
|
||||
返回 空列表
|
||||
|
||||
# ---- ② 取点(每目每框一次,纯函数) ----
|
||||
左点表 ← 对 左帧.框列表 逐框取点(同侧边缘 x) # §6.1
|
||||
右点表 ← 对 右帧.框列表 逐框取点(同侧边缘 x)
|
||||
丢弃 坐标非有限值 的框(不参与匹配,也不发布记录;告警节流)
|
||||
|
||||
# ---- ③ 左右匹配(接口注入,默认贪心) ----
|
||||
配对表 ← 匹配器.匹配(左点表, 右点表, 参数.匹配) # §6.2
|
||||
|
||||
# ---- ④ 配对成功的目标:测距 + 方位源 + 有效性 + 滤波 ----
|
||||
对 配对表 中每个 (左框, 右框, 代价):
|
||||
D ← 视差选择(左框, 右框) # 同侧边缘;越窗且中心在域内→回退中心(§6.1)
|
||||
(Z, R) ← 测距(D, 参数.几何) # §3.2
|
||||
c_mid ← (左框.中心 + 右框.中心) / 2 # §6.6
|
||||
域内 ← 有效性判定(D, Z, 代价, 参数.有效性) # §6.4 门①②
|
||||
一致性 ← 一致性监控(目标键).推进(D) # §6.7
|
||||
置信度 ← 置信度映射(代价, 一致性) # §6.4 映射
|
||||
有效 ← 域内 且 一致性 正常
|
||||
|
||||
若 有效:
|
||||
Z_out ← 滤波器(目标键).推进(Z, 参数.滤波) # §6.5
|
||||
否则:
|
||||
滤波器(目标键).记失效() # §6.5 失效策略
|
||||
Z_out ← 无
|
||||
|
||||
发布 记录(帧标识, 类别, Z_out, R, D, c_mid, 左框,
|
||||
置信度, 有效, 完整, 取样时刻 = now_ms)
|
||||
|
||||
# ---- ⑤ 单目退化(仅一目检出) ----
|
||||
对 未匹配的左框:
|
||||
发布 记录(仅方位 = 左框.中心, valid = false, 退化 = 单目)
|
||||
对 未匹配的右框:
|
||||
发布 记录(仅方位 = 右框.中心, valid = false, 退化 = 单目)
|
||||
|
||||
# ---- ⑥ 空输入 ----
|
||||
若 两目框列表均为空:
|
||||
发布 无目标记录(或空列表);不告警(正常空帧)
|
||||
```
|
||||
|
||||
**失败路径语义**:
|
||||
|
||||
| 情形 | 行为 | 日志 |
|
||||
|------|------|------|
|
||||
| 左右帧标识不一致 | 拒收本帧,输出空 | WARN 节流 |
|
||||
| 单目检测为空 | 另一目发布仅方位记录 | 不告警(正常退化) |
|
||||
| 匹配全部失败 | 全部按仅方位发布 | 不告警 |
|
||||
| 视差违例(`D ≤ 0` 或超界) | 该目标 `valid = false`,仍配对并发布 `D`/`c_mid` | WARN 节流 |
|
||||
| 边缘视差越窗、中心回退 | 该目标用中心视差解算(框宽差可能混入,§6.1) | WARN 节流 |
|
||||
| 框坐标非法(非有限值) | 丢弃该框,不参与匹配也不发布 | WARN 节流 |
|
||||
| 两目均无检测 | 无目标记录 | 不告警 |
|
||||
|
||||
高频热路径(每帧执行的数学)不打日志;所有异常日志按节流规范
|
||||
(第 1 次 + 每满 100 次,带累计计数)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 各环节算法细节
|
||||
|
||||
### 6.1 视差取点:同侧边缘(v1.0 主方案)
|
||||
|
||||
同一物理目标在两目中的检测框宽并不严格相等(检测抖动、外观差异),
|
||||
**框中心**视差会混入框宽差的一半,**同一侧边缘**视差可抵消框宽项:
|
||||
|
||||
| 取点方式 | 误差来源 | 结论 |
|
||||
|----------|----------|------|
|
||||
| 框中心 | 两目框宽差直接进入视差 | 作对照/回退 |
|
||||
| **同侧边缘(v1.0)** | 边缘定位噪声 | **v1.0 主方案** |
|
||||
| 多边缘 + 亚像素精化(灰度重心/抛物线拟合) | 实现复杂度 | v1.1 |
|
||||
|
||||
```text
|
||||
取法: D = 左框.左上角x − 右框.左上角x (同取左侧边缘)
|
||||
回退: 边缘视差越窗 且 中心视差在域内 → 回退框中心并告警节流
|
||||
两者均越窗 → 保留边缘值(供诊断与违例告警),由 §6.4 门 ① 判无效
|
||||
```
|
||||
|
||||
> **不做"左右两边缘各算一次取中值"(v1.0 冻结)**:两边缘视差的中值恒
|
||||
> 等于二者均值,即 `(cL.x − cR.x)`——**框中心视差**,与本表"同侧边缘
|
||||
> 抵消框宽差"的理由自相矛盾(早期原文笔误),故不实现;亚像素精化留
|
||||
> v1.1(§8.3)。
|
||||
|
||||
### 6.2 左右匹配:硬约束 + 贪心代价
|
||||
|
||||
**硬约束**(任一不满足直接拒绝配对,不进代价排序):
|
||||
|
||||
- 类别一致;
|
||||
- `|yL − yR| ≤ τ_y`(校正后 y 应对齐;这是校正质量的运行期体现);
|
||||
- 框高相近:`|hL − hR| / max(hL, hR) ≤ τ_h`。
|
||||
|
||||
**视差域不是配对硬约束(v1.0 冻结)**:越界目标仍应配对、仍发布 `D` 与
|
||||
`c_mid`(远场"方位闭环 + 定速接近"的输入基础),仅由 §6.4 门 ① 判
|
||||
`valid = false`。若把域并入硬约束,越界目标会退化为无方位的失配记录,
|
||||
与 §2.3/§5 失败路径表的语义冲突。
|
||||
|
||||
**代价与贪心**:
|
||||
|
||||
```text
|
||||
cost = |Δy| / τ_y + |Δh| / (τ_h × max(hL, hR))
|
||||
按 cost 升序逐一配对,cost < 1 才接受,一一配对(一个左框至多配一个右框)
|
||||
```
|
||||
|
||||
- 本场景目标数极少(1~2 个),O(n²) 贪心足够(§10.3);
|
||||
- 失败处理:任一目未匹配 → 该目标本帧无距离(仅方位发布),
|
||||
不阻塞其他目标。
|
||||
|
||||
### 6.3 测距计算与违例处理
|
||||
|
||||
```text
|
||||
Z = F × B / D (D ≤ 0:物理违例 → valid = false,告警节流)
|
||||
R = sqrt(X² + Y² + Z²) (参考输出)
|
||||
```
|
||||
|
||||
- `D ≤ 0` 在校正正确的正视差几何下不应出现;出现说明匹配错误或校正
|
||||
残差过大,宁可无效不可给值;
|
||||
- `D ≤ 0` 时**不出解算结果**(无 `Z`、无 `R`);超界(`0 < D < D_min`
|
||||
或 `> D_max`)仍解算 `Z`/`R` 供诊断与告警,同样 `valid = false`;
|
||||
- 边缘取点为像素级整数(取整/插值规则由实现自定,但**左右目必须一致**);
|
||||
- 所有除法分母(`D`)在使用前校验为正。
|
||||
|
||||
### 6.4 有效性判定:三道门(缺一不可)
|
||||
|
||||
| 门 | 判据 | 拦截什么 |
|
||||
|----|------|---------|
|
||||
| ① 域内 | `D ∈ [D_min, D_max]`(含边界);距离域由 `Z = F·B/D` 派生 | 远场小视差病态 + 近场大视差盲区 |
|
||||
| ② 误差预算 | `δZ(δD=1px) = Z²/(F·B) ≤ δZ_max` | 有效域边界处的精度下限 |
|
||||
| ③ 一致性正常 | §6.7 监控未判异常 | 持续视差跳变(标定漂移/同步故障/匹配错误) |
|
||||
|
||||
```text
|
||||
valid = 域内 且 误差预算内 且 匹配成功 且 一致性正常
|
||||
```
|
||||
|
||||
匹配成功由第 ③ 步保证(只有配对目标才进入本节判定)。
|
||||
|
||||
**门 ① 以视差域为唯一真源(v1.0 冻结)**:配置只存
|
||||
`disparity_min_px / disparity_max_px`,`Z_min / Z_max` 由 `Z = F·B/D`
|
||||
派生为只读量——`D` 是直接观测量,`Z` 是导出量,用 `D` 判域可避免
|
||||
"距离阈值反推视差阈值"的舍入不一致;两处冗余存储正是该不一致的根源
|
||||
(原文 §9.2 占位值即不自洽:`D_min = 3px` ⇔ 19.2m ≠ 20m),故不再
|
||||
"互推并校验自洽"。
|
||||
|
||||
**门 ② 的 δD 基准固定为 1px(⚠占位,v1.0 冻结)**:δD 的真实构成
|
||||
(边缘定位噪声 + 校正残差 + 帧不同步 + 压缩伪影,§7.1)留待地面真值
|
||||
拟合(§12.2),当前不做估计、不随目标状态变化。
|
||||
|
||||
**置信度映射(⚠占位,v1.0 冻结)**:基值 = `clamp(1 − 匹配代价, 0, 1)`;
|
||||
连续跳变 ≥ N 帧(§6.7)时乘降级系数(⚠0.5);判 invalid(≥ M 帧)时置 0。
|
||||
|
||||
### 6.5 时间滤波与跳变重置(每目标独立)
|
||||
|
||||
```text
|
||||
推进(Z_new):
|
||||
若 未初始化: 状态 ← Z_new; 返回 Z_new
|
||||
若 |Z_new − 上次| > 跳变门限:
|
||||
状态 ← Z_new # 直接重置而非滤波,防止拖尾
|
||||
否则:
|
||||
状态 ← 上次 + α × (Z_new − 上次) # 一阶低通,α ∈ (0,1]
|
||||
返回 状态
|
||||
|
||||
记失效(): # 无效帧与"目标本帧缺席"均记失效(§6.5 失效策略)
|
||||
连续失效计数 +1
|
||||
若 连续失效 ≥ filter_reset_frames: 清空滤波状态(下次有效帧重新初始化)
|
||||
```
|
||||
|
||||
- **单帧毛刺由跳变重置处理,持续性异常由 §6.7 一致性监控处理**,
|
||||
两者职责不同不得合并;
|
||||
- `α = 1` 等效不滤波;滤波只在**有效帧**之间进行,无效帧不参与平滑;
|
||||
- 清理门限 `filter_reset_frames` **独立配置**(不复用 §6.7 的 M,⚠占位
|
||||
5 帧),防"陈旧状态平滑新测量";
|
||||
- 参考斜距 `R` 与**滤波后**的 `Z_out` 同基准(`X/Y/Z ∝ Z`,按
|
||||
`Z_out/Z_raw` 精确换基,保证 `R ≥ Z`,§2.2);
|
||||
- 滤波引入的群延迟约 `1/α` 帧(⚠占位 α=0.3 → 约 3 帧 ≈ 0.1s),
|
||||
接近阶段的距离滞后由消费侧 PID 与限幅吸收。
|
||||
|
||||
### 6.6 方位源:虚拟双目中心 `c_mid`
|
||||
|
||||
**问题**:双目模组两枚相机分列模组中线两侧(各偏 ±B/2),都不在机身
|
||||
中轴上。校正后严格成立的只有 **y 对齐**(垂直方向不受两目差异影响);
|
||||
水平方向上直接以某一目(如左目)的像素做方位控制,收敛后对准的是
|
||||
**该相机的光轴**,相对模组中线存在恒定视差偏差:
|
||||
|
||||
```text
|
||||
β_bias ≈ atan( (B/2) / Z )
|
||||
```
|
||||
|
||||
| 距离 Z | 角度偏差 | 像素等效(F≈960px,⚠占位) |
|
||||
|-------:|-------:|-------:|
|
||||
| 3 m | 0.57° | ≈10 px |
|
||||
| 10 m | 0.17° | ≈2.9 px |
|
||||
|
||||
远距离可忽略,**近场不可忽略**;偏差方向恒定、随距离减小。
|
||||
|
||||
**精确修正(零额外成本)**:校正后几何下,位于基线中点的**虚拟相机**
|
||||
对任一物理点 P 的投影恰为该点在两目投影的**等权平均**:
|
||||
|
||||
```text
|
||||
xL = cx + F·(X_C + B/2)/Z (左目光心在模组中线 −B/2 侧)
|
||||
xR = cx + F·(X_C − B/2)/Z (右目光心在模组中线 +B/2 侧)
|
||||
(xL + xR) / 2 = cx + F·X_C/Z (= 虚拟相机投影,逐点精确,无近似)
|
||||
```
|
||||
|
||||
检测框的每条边缘都是物理点、逐点满足上式,因此:
|
||||
|
||||
```text
|
||||
虚拟框 = 两目框逐边平均 ⇒ 虚拟框中心 c_mid = (cL + cR) / 2
|
||||
c_mid.y = (cL.y + cR.y) / 2 (校正后两目 y 天然相等,取平均兼得降噪)
|
||||
```
|
||||
|
||||
即**等权平均等价于把相机搬到模组中线**,方位控制对标的是虚拟中心相机,
|
||||
与机体中轴的安装偏移(如有)属安装外参,按安装标定处理。
|
||||
|
||||
**方位源与视差取点是两个不同的取点,不得混用**:
|
||||
|
||||
| 用途 | 取点 | 原因 |
|
||||
|------|------|------|
|
||||
| 视差 D(测距) | **同侧边缘** | 抵消两目框宽差(§6.1) |
|
||||
| 方位 c_mid(控制) | **框中心等权平均** | 瞄点语义 = 虚拟框中心;误用边缘点平均会把瞄点偏到目标边缘(约半个框宽) |
|
||||
|
||||
**单目退化**(仅一目检出,v1.0):退化为该目框中心,接受上表偏差;
|
||||
v1.1 可用最近一次有效 Z 做定值修正 `Δx = F·(B/2)/Z` px。
|
||||
|
||||
### 6.7 内部一致性监控(替代原激光交叉校验)
|
||||
|
||||
机载激光移除后无外部距离基准,飞行中只能靠自身时序一致性监控数据
|
||||
质量(**只能降级、不能纠偏**,绝对精度靠地面静态验证,§12.1):
|
||||
|
||||
```text
|
||||
逐目标推进(D):
|
||||
视差跳变 = |D − 上次 D|(或等效 Z 跳变量;门限 consistency_jump_px)
|
||||
连续 N 帧跳变超门限 → confidence 降级(⚠×0.5)
|
||||
连续 M 帧异常 → valid 置 false 并 WARN(节流)
|
||||
任一正常帧 → 清零连续计数
|
||||
```
|
||||
|
||||
- 匹配层面质量(|Δy| 残差、框高一致性、代价门限)已由 §6.2 硬约束
|
||||
承担;本节只管**时序层面**;
|
||||
- 跳变门限 `consistency_jump_px`(⚠占位 3px)、N / M(⚠ 3 / 5 帧)均
|
||||
为占位,实测后整定(§9.3);
|
||||
- **推进时机(v1.0 冻结)**:只在配对成功帧推进——仅方位帧没有 `D`
|
||||
观测量,不推进 D 序列、也不清零;目标缺席/无效帧的**滤波失效**由
|
||||
§6.5 记,两条状态机职责不混;
|
||||
- 监控判 invalid 是"质量语义"而非"错误":输出仍正常发布(仅方位),
|
||||
由消费侧按无距离策略接管。
|
||||
|
||||
---
|
||||
|
||||
## 7. 误差模型与有效距离域
|
||||
|
||||
### 7.1 误差模型
|
||||
|
||||
由 `D = F·B/Z` 微分得:
|
||||
|
||||
```text
|
||||
δZ ≈ Z² · δD / (F·B) (绝对误差,随距离平方增长)
|
||||
δZ / Z ≈ Z · δD / (F·B) (相对误差,随距离线性增长)
|
||||
```
|
||||
|
||||
`δD` 的构成:检测框边缘定位噪声 + 校正残差(|Δy| 失配混入)+ 帧不同步
|
||||
引入的运动虚假视差 + 有损压缩伪影(平台相关,抽象计入边缘噪声)。
|
||||
基线与焦距误差(δB/B、δF/F)线性传递、量级小,出厂标定后可忽略。
|
||||
|
||||
**这是"双目只能作近场距离源"的定量依据**,也是第 8 章多数缺点的根源。
|
||||
|
||||
### 7.2 有效距离域判据
|
||||
|
||||
```text
|
||||
valid 域 ⇔ D ∈ [D_min, D_max](⚠占位 3 ~ 57.6px)
|
||||
且 δZ(δD = 1px) ≤ δZ_max(⚠占位 2m)
|
||||
```
|
||||
|
||||
- 按占位焦距计算:宽角档(HFOV≈90°)有效域约 **≤15m**、窄角档
|
||||
(HFOV≈60°)约 **≤20m**(**⚠占位,待厂商实焦距回填后重算**;
|
||||
数值回填的权威位置在《双目深度估计思路》§5.3 误差表);
|
||||
- 近界:`D_max`(或 `Z_min`)限定最近可测距离——目标过近时视差超上限、
|
||||
框占满画面、边缘取点失效(§8 第 3 条);
|
||||
- 敏感性:误差 ∝ 1/B。更换大基线机型误差按比例缩小、有效域等比扩大
|
||||
——**换机型(P6)是扩大远场能力的唯一杠杆**。
|
||||
|
||||
### 7.3 远场空洞(如实声明)
|
||||
|
||||
双目有效域之外(预计 >15~20m,待焦距回填),系统**不存在任何机载
|
||||
目标距离源**。补偿方式是消费侧的远场策略(方位闭环 + 定速接近,D4),
|
||||
而非强行使用不可靠的远场估计。本模块的职责边界是:把"测不了"诚实
|
||||
地表达为 `valid = false` + 持续发布方位。
|
||||
|
||||
---
|
||||
|
||||
## 8. 职责、边界与已知缺点
|
||||
|
||||
### 8.1 职责(一句话版)
|
||||
|
||||
> 对同帧左右检测框做立体几何解算:**有效域内给出目标前向距离,
|
||||
> 全程给出虚拟中心方位,测不了时诚实输出无效**——供控制律做
|
||||
> 近场距离闭环与远场方位闭环 + 定速接近。
|
||||
|
||||
边界(不做什么)见 §1.4;与避障深度模型的分工见《双目深度估计思路》§1.3。
|
||||
|
||||
### 8.2 已知缺点与局限(如实声明,不得因文档目的删减)
|
||||
|
||||
| # | 缺点 | 根因 | 影响 | 现行对策 / 接受理由 |
|
||||
|---|------|------|------|---------------------|
|
||||
| 1 | **误差随距离平方增长** | `δZ ∝ Z²`(§7.1) | 远距离距离值不可用 | 有效域判据硬性拦截(§6.4);域外交给定速接近 |
|
||||
| 2 | **远场空洞** | 有效域 >15~20m 外无任何机载距离源 | 远场无法距离闭环 | 消费侧 D4 策略(方位闭环 + 定速接近);扩域唯一杠杆是换机型(P6) |
|
||||
| 3 | **近场盲区** | 视差超 `D_max`、框占满画面、边缘取点失效 | 反制逼近的最后阶段恰是最需要距离时失效 | 消费侧判丢刹车/定速接近兜底;`Z_min` 如实设界 |
|
||||
| 4 | **检测框是单点依赖** | 全部几何量从框导出 | 无检测即无距离也无方位;框抖动直接进入 δD | 检测置信度门槛在检测侧;追踪库 Coast 补帧兜底 |
|
||||
| 5 | **框级精度上限** | 取点在框边缘/中心,非特征级匹配 | 精度天花板高于特征级方案 | 接受(几何换算换实时性,§10.1);v1.1 亚像素精化 |
|
||||
| 6 | **小视差病态** | 远距 D → 1px,量化误差主导 | 远场 δD=1px 假设过于乐观 | 同上由有效域拦截 |
|
||||
| 7 | **标定与校正依赖** | y 对齐、无畸变是解算前提 | 未标定则系统性偏差,甚至全盘不成立 | P2 出厂标定为 v1.0 首要前置;不达标则 v1.1 自标定提前 |
|
||||
| 8 | **帧不同步敏感** | 非同瞬曝光 → 运动目标虚假视差 | 快速横移目标距离失真 | 同帧契约(§2.1)+ 13 章快速横移验证;同步形态待 P3 |
|
||||
| 9 | **固定基线/焦距** | 单一几何配置 | 近盲远废的区间固定 | 参数化配置;换机型只改配置(红线 2) |
|
||||
| 10 | **贪心匹配局限** | O(n²) 局部最优 | 目标多/邻近/遮挡时错配风险 | 目标数极少(1~2)可接受;匹配器接口注入保留替换空间 |
|
||||
| 11 | **无飞行中绝对基准** | 激光移除后无外部真值(D2/D8) | 一致性监控只能降级、不能纠偏 | 绝对精度靠地面手持激光测距仪静态验证(§12.1) |
|
||||
| 12 | **单目退化有瞄偏** | 单目光轴偏离模组中线(§6.6) | 仅方位记录时方位存在 0.5° 量级近场偏差 | v1.0 接受并如实标注退化;v1.1 定值修正 |
|
||||
|
||||
**阅读提示**:1/2/3/6/9 是几何固有,只能拦截或换硬件,不能修好;
|
||||
4/5/8/10/12 是工程折中,有 v1.1/v2.0 改进路径;7/11 是流程前提,
|
||||
靠标定与地面验证闭环。
|
||||
|
||||
### 8.3 缺点对策索引
|
||||
|
||||
| 路径 | 覆盖的缺点 |
|
||||
|------|-----------|
|
||||
| v1.1(算法) | 亚像素边缘(5)、真值拟合误差修正项(1/6)、track_id 辅助匹配(10)、单目定值修正(12)、自标定(7,视 P2 结论提前) |
|
||||
| v2.0(远期) | 实例分割替代框(4/5)、端到端立体评估(5)、更大基线/长焦机型(1/2/3/6/9,P6) |
|
||||
| 消费侧兜底 | 定速接近 + 判丢刹车 + exit 门限(2/3 的安全网) |
|
||||
| 地面验证 | 7/8/11 的唯一闭环手段 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 配置参数全量表
|
||||
|
||||
全部参数**配置外置、启动期一次加载并校验**:缺项、类型错误、非法取值
|
||||
一律拒绝进入运行期(fail-fast,语义要求,不绑定具体配置格式)。
|
||||
所有数值均为占位(⚠),整定后回填。
|
||||
|
||||
### 9.1 几何组(来自标定,P1/P2)
|
||||
|
||||
| 键 | 单位 | 占位值 | 作用 |
|
||||
|----|------|-------|------|
|
||||
| `baseline_m` | m | 0.06 | 基线 B;更换机型只改此项 |
|
||||
| `fx_px` / `fy_px` | px | 960.0(⚠占位,待 P1) | 像素焦距(校正后 `fx = fy = F`) |
|
||||
| `cx_px` / `cy_px` | px | 960.0 / 540.0(⚠占位,待 P2) | 主点 |
|
||||
|
||||
### 9.2 匹配组
|
||||
|
||||
| 键 | 单位 | 占位值 | 作用 |
|
||||
|----|------|-------|------|
|
||||
| `tau_y_px` | px | 2.0 | \|Δy\| 硬约束(同时是校正质量的运行期体现) |
|
||||
| `tau_h_ratio` | — | 0.25 | 框高相对差硬约束 |
|
||||
| `disparity_min_px` | px | 3.0 | 最小可测视差(远界);**域唯一真源**(§6.4) |
|
||||
| `disparity_max_px` | px | 57.6 | 最大可测视差(近界);⚠占位:按 F=960/B=0.06 反推 ⇔ 1.0 m |
|
||||
| `distance_min_m` / `distance_max_m` | m | **不再配置** | v1.0 冻结:距离域由 `Z = F·B/D` 从视差域派生为只读量(§6.4) |
|
||||
|
||||
### 9.3 有效性组
|
||||
|
||||
| 键 | 单位 | 占位值 | 作用 |
|
||||
|----|------|-------|------|
|
||||
| `max_delta_z_m` | m | 2.0 | 误差预算 `δZ(δD=1px)` 上限(δD 基准固定 1px,§6.4) |
|
||||
| `consistency_N_frames` | 帧 | 3 | 连续跳变降置信度的帧数 |
|
||||
| `consistency_M_frames` | 帧 | 5 | 连续异常判 invalid 的帧数 |
|
||||
| `consistency_jump_px` | px | 3.0 | 单帧视差跳变门限(§6.7);**v1.0 补充项**(原文缺项) |
|
||||
|
||||
### 9.4 滤波组
|
||||
|
||||
| 键 | 单位 | 占位值 | 作用 |
|
||||
|----|------|-------|------|
|
||||
| `smooth_alpha` | — | 0.3 | 一阶低通系数(§6.5 定义,1 = 不滤波) |
|
||||
| `jump_reset_m` | m | 5.0 | 单帧跳变直接重置的门限 |
|
||||
| `filter_reset_frames` | 帧 | 5(⚠独立配置,不复用 M) | 连续失效多久后清空滤波状态(§6.5) |
|
||||
|
||||
### 9.5 目标隔离组
|
||||
|
||||
| 键 | 单位 | 占位值 | 作用 |
|
||||
|----|------|-------|------|
|
||||
| `isolation_gate_px` | px | 50.0 | 最近邻兜底的匹配门限(§4);**v1.0 补充项**(原文缺项) |
|
||||
|
||||
---
|
||||
|
||||
## 10. 设计取舍记录(为什么不是别的做法)
|
||||
|
||||
### 10.1 两次目标检测代替稠密像素匹配
|
||||
|
||||
双目深度最难的是逐像素匹配:稠密立体匹配(SGBM 类)在该分辨率与
|
||||
嵌入式 CPU 预算下不可行,而系统需求只是**少量目标的距离**。用左右
|
||||
各一次轻量检测 + 框级几何换算绕开逐像素匹配,以"检测框天然给出 ROI"
|
||||
换"精度天花板"(§8 第 5 条)。检测算力实测单核 20~30ms,NPU 预算
|
||||
成立(平台侧见《双目深度估计思路》第 9 章)。
|
||||
|
||||
### 10.2 不先上端到端深度网络
|
||||
|
||||
需采集标注数据集、可解释性差、误差行为不可解析;先以几何法建立
|
||||
**可验证的真值基线**,端到端立体/深度网络留 v2.0 评估。
|
||||
|
||||
### 10.3 贪心匹配而非匈牙利
|
||||
|
||||
目标数 1~2 个,贪心与全局最优几乎必然同解;O(n²) 足够。匹配器做
|
||||
**接口注入**,保留替换为匈牙利/带连续性先验算法的空间而不动调用方。
|
||||
|
||||
### 10.4 同侧边缘而非框中心取视差
|
||||
|
||||
框宽差直接污染中心视差;同侧边缘可抵消框宽项(§6.1,原稿缺陷 2 的修正)。
|
||||
|
||||
### 10.5 距离通道用 Z 不用 R
|
||||
|
||||
与机头前向期望射程语义对齐,也与地面真值仪测量方向一致(决策 D8);
|
||||
R 仅作参考输出。
|
||||
|
||||
### 10.6 方位源取两目框中心等权平均(虚拟中心像素)
|
||||
|
||||
两目均偏于模组中线 ±B/2,单目存在近场视差偏差(3m 处约 0.57°);
|
||||
等权平均是投影几何**精确解**(§6.6,原稿"offset 加权"构想的正确形式,
|
||||
决策 D5)。注意与视差取点(同侧边缘)分工不同、不可混用。
|
||||
|
||||
### 10.7 双目为机载唯一距离源、域外定速接近
|
||||
|
||||
替代激光(b96111e / D2);远场误差平方发散,强行估计不可靠——以
|
||||
"诚实 invalid + 持续方位"支撑消费侧的方位闭环 + 定速接近(D4),
|
||||
而不是在算法侧掩盖远场空洞。
|
||||
|
||||
---
|
||||
|
||||
## 11. 实现与重写指引
|
||||
|
||||
### 11.1 必须持久化的状态(漏一个就变行为)
|
||||
|
||||
| 状态 | 所属 | 初值 | 何时改变 |
|
||||
|------|------|------|---------|
|
||||
| 上次视差 + 连续异常计数 ×目标 | 一致性监控 | 无 / 0 | 配对帧写入上次视差;异常 +1 / 正常清零 |
|
||||
| 上次滤波值 ×目标 | 时间滤波器 | 无(未初始化) | 每有效帧写入 |
|
||||
| 滤波初始化标志 ×目标 | 时间滤波器 | false | 首个有效帧置 true;清空时回 false |
|
||||
| 连续失效计数 ×目标 | 时间滤波器 | 0 | 每无效/缺席帧 +1 / 有效帧清零 |
|
||||
| 最近框中心、最近出现帧 ×目标 | 目标状态容器 | 首帧写入 | 每次解析隔离键时刷新;连续 `filter_reset_frames` 帧未出现则整体清理 |
|
||||
| 帧序号 | 流程编排 | 0 | 每帧 +1(被拒收的违约帧不加) |
|
||||
| 告警节流状态 ×异常类 | 节流器 | 首见未打印 + 计数 0 | 每次异常更新 |
|
||||
|
||||
构造期预计算量:针孔系数与常量(如 `F·B`)一次算好,热路径只做乘除。
|
||||
|
||||
### 11.2 数值与精度注意
|
||||
|
||||
| 事项 | 处理方式 | 理由 |
|
||||
|------|---------|------|
|
||||
| 除零 | `D ≤ 0` 先判违例再除 | 正视差是物理前提(§6.3) |
|
||||
| 视差取整 | 左右目规则必须一致 | 不一致会引入系统性 δD |
|
||||
| 域判定基准 | 用 `D` 判域而非 `Z` | 直接观测量,避免往返舍入(§6.4) |
|
||||
| 域配置单一来源 | 只配视差域,距离域派生 | 两处冗余存储是互推舍入不一致的根源(§6.4/§9.2) |
|
||||
| 误差预算基准 | δD 固定 1px(⚠占位),不做在线估计 | 真实 δD 留待地面真值拟合(§12.2) |
|
||||
| 浮点比较 | 阈值比较用 `≥/≤` 含边界语义 | 边界帧的归类必须确定 |
|
||||
|
||||
### 11.3 并发与生命周期
|
||||
|
||||
- 本模块是**纯计算单元**:驱动方式(独立线程 / 订阅回调 / 同步调用)
|
||||
由平台层决定,本文只约定数据契约;
|
||||
- 同一实例**不得并发调用**单周期处理(含滤波/一致性状态的无锁前提);
|
||||
- 输出记录为**值拷贝**语义:多消费者各自持有快照,不得共享可变状态;
|
||||
- 单周期处理应当无阻塞、无 IO(日志走节流通道,不落在数学热路径上)。
|
||||
|
||||
### 11.4 可测试性设计(构件边界即测试边界)
|
||||
|
||||
| 构件 | 是否纯函数 | 测试要点 |
|
||||
|------|-----------|---------|
|
||||
| 取点器 | 是 | 同侧边缘取值;框宽差不进入视差(构造两目等框不同宽断言 D 相同);越窗回退中心;边界含等号 |
|
||||
| 匹配器 | 是 | 硬约束拦截各一例;贪心排序;一一配对;cost ≥ 1 拒绝 |
|
||||
| 测距计算 | 是 | 已知 Z 反推 D 构造框对,断言 `Z = F·B/D` 回收;`D ≤ 0` 违例;`c_mid` 等权平均精确性(§6.6 恒等式);`R` 与发布 Z 同基准(`R ≥ Z`) |
|
||||
| 有效性判定 | 是 | 三道门各一例;边界帧(恰在域界)归类确定;预算门通过/拦截两侧 |
|
||||
| 时间滤波器 | 否 | 低通收敛;跳变重置不拖尾;失效清理 |
|
||||
| 一致性监控 | 否 | N 帧降级、M 帧判 invalid、正常帧清零 |
|
||||
| 目标隔离 | 否 | track_id 一致跨大位移保持状态;最近邻越门限新建;老化清理 |
|
||||
| 全流程 | 否 | 合成帧对端到端:单目标/多目标/单目退化/非同帧拒收/记录顺序/非有限框/reset |
|
||||
|
||||
**无需真实图像**:全部测试用合成框对驱动,几何是解析可断言的。参考实现
|
||||
的构件级用例已全部通过(§12.1)。
|
||||
|
||||
---
|
||||
|
||||
## 12. 验证路线与待定项
|
||||
|
||||
### 12.1 验证项
|
||||
|
||||
| 项 | 方法 | 通过标准 |
|
||||
|----|------|----------|
|
||||
| 构件级 | §11.4 合成框对单测 | 全部通过(无硬件依赖);Python 参考实现 `utils/stereo_ranger/` 用例已跑通 |
|
||||
| 校正质量 | 静态场景统计匹配框 \|Δy\| 分布 | P95 ≤ 1px(⚠占位);不达标触发自标定提前 |
|
||||
| 测距精度 | 5/10/15/20m 静态标靶,以**地面手持激光测距仪**为真值(非机载,D8),记录误差曲线 | 趋势与 §7 一致;有效域内 δZ ≤ 2m(⚠占位) |
|
||||
| 帧同步 | 目标横向快速移动,观察视差时序抖动 | 无系统性虚假视差 |
|
||||
| 控制联动 | 回放/SITL:距离闭环 ↔ 定速接近切换、invalid 持续降级路径 | 《视觉跟踪控制律技术路线》第 7 章场景全覆盖 |
|
||||
| 日志纪律 | 检查异常路径日志 | 节流规范(第 1 次 + 每 100 次,带累计计数) |
|
||||
|
||||
### 12.2 待定项
|
||||
|
||||
开放问题(P1 焦距规格、P2 出厂标定、P3 帧同步形态、P6 换机型、
|
||||
P7 性能实测、P8 避障激光去留)以《双目深度估计思路》第 15 章为权威
|
||||
清单,本文不另立编号;其中:
|
||||
|
||||
- **P1/P2 直接决定本文 §7 结论与 §9 几何组能否从占位变实值**;
|
||||
- **v1.0 实现补充的占位量**:`consistency_jump_px`(3px)、
|
||||
`isolation_gate_px`(50px)、置信度降级系数(0.5)、误差预算基准 δD
|
||||
(固定 1px)——随 P1/P2 回填与实测一并整定(§9.3/§9.5);
|
||||
- **P6 是扩大有效域的唯一杠杆**(§7.2);
|
||||
- P8(避障单点激光去留)不影响本链路——目标测距职责已由本模块承担。
|
||||
|
||||
### 12.3 红线
|
||||
|
||||
1. **占位数值不得用于飞行决策**:§7/§9 中所有 ⚠ 数值未经厂商数据与
|
||||
整定确认前,本模块输出仅限静态标靶/回放/台架验证;
|
||||
2. **相机参数与阈值一律配置外置**,禁止写死(后续可能更换机型);
|
||||
3. **域外/失配必须输出 `valid = false`**,不得强行估计距离(远场策略
|
||||
的正确性建立在有效性不撒谎之上);
|
||||
4. **标定与地面真值验证完成前不得接入实飞控制回路**(与消费侧控制律
|
||||
红线一致,见《视觉跟踪控制律技术路线》§12.3)。
|
||||
@@ -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