精简仓库结构并增强任务链路:归档双目可选后端、新增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:
+38
-12
@@ -1,8 +1,11 @@
|
||||
# L1 航向伺服落地方案(无距离,树莓派 / Python)
|
||||
# L1 航向伺服落地方案(无距离,树莓派 / Python)
|
||||
|
||||
> 目标:**先把"只修正飞行方向、不需要距离"的部分落地**,速度-距离闭环(L2)滞后。
|
||||
> 基于结论:本吊舱无激光 → 表4 永不出,且不允许二次开发(部署文档 §10.0 / §10)。
|
||||
> 日期:2026-10-09 状态:**S0 已实现(路线 A1 + L1 胶水层),全量 396 passed;符号待台架 S1 标定**
|
||||
> 日期:2026-10-09 起,**2026-10-19 更新** 状态:
|
||||
> **S0/S1/S2 + SITL + 真吊舱在环已验证**(全量 621 passed)。
|
||||
> 后续变更:第二判据 `require_vision` → **LOS 运动学一致性**(§2.3/§6);
|
||||
> 距离源由「双目」改为规划中的「激光雷达」(§7)。
|
||||
|
||||
---
|
||||
|
||||
@@ -114,7 +117,20 @@ L1 的 `tracked` 判据按阶段递进:
|
||||
| 阶段 | 判据 |
|
||||
|---|---|
|
||||
| 台架(S1~S2) | bit2 锁定 **且** 遥测未超龄(现有 `_pod_locked()`)+ **人工在旁观察**,随时按键 `u` 解锁 |
|
||||
| 接入视觉后(S3+) | bit2 **且** 我方 `stereo_yolo`/`target_tracker` 有目标(**第二判据**,必做) |
|
||||
| ~~接入视觉后(S3+)~~ | ~~bit2 **且** 我方 `stereo_yolo`/`target_tracker` 有目标~~ |
|
||||
| **现行(2026-10-19 起)** | bit2 **且** 遥测未超龄 **且 LOS 运动学一致性**(`pod_bridge/los_consistency.py`) |
|
||||
|
||||
> ⚠ **2026-10-19 架构变更**:后续决定**吊舱取代双目 + YOLO 作为唯一目标源**,
|
||||
> 因此原「我方视觉第二判据」(`require_vision` / `vision_target_fn`) 已**删除** ——
|
||||
> 它要么恒 False(链路永远进不了 TRACK),要么指向吊舱自身(自证,零信息量)。
|
||||
>
|
||||
> 替代判据:本吊舱无电机、相机刚性固连机体,机头转 Δψ 时真实目标的脱靶量必变
|
||||
> ≈−Δψ。故用 `residual = Δβ + Δψ`(3s 窗口,激励门槛 20°、残差上限 8°)判断
|
||||
> 「角度是活的还是冻住的」。超限 → `tracked=False` 且 `pod_locked()` 也返回 False
|
||||
> (状态机会退出 TRACK 重新搜索,而不是只让控制律单方面刹车)。
|
||||
>
|
||||
> **局限**:它只能证明「角度是活的」,不能证明「是那个目标」。若吊舱锁错了物体
|
||||
> 但角度正常变化,本判据无法识别 —— 那属于识别问题,需另接独立传感器。
|
||||
|
||||
---
|
||||
|
||||
@@ -149,7 +165,12 @@ L1 的 `tracked` 判据按阶段递进:
|
||||
"alpha_from_frame": false,
|
||||
"alpha_from_off_target": true,
|
||||
"vertical_enabled": true, // 决策3:无人机 L1 开垂直(vz 由 tracking.vertical 压低)
|
||||
"require_vision": false // true = 需我方视觉第二判据(S3 起开,§2.3)
|
||||
|
||||
// 第二判据:LOS 运动学一致性(2026-10-19 取代 require_vision,见 §2.3)
|
||||
"los_consistency_enabled": true, // false → 退回"只信 bit2"
|
||||
"los_window_ms": 3000, // 比较窗口
|
||||
"los_min_yaw_change_deg": 20.0, // 窗口内机头至少转这么多才判定(激励门槛)
|
||||
"los_max_residual_deg": 8.0 // |Δβ+Δψ| 上限,超过判不一致
|
||||
}
|
||||
```
|
||||
|
||||
@@ -187,10 +208,10 @@ L1 的 `tracked` 判据按阶段递进:
|
||||
| 风险 | 判据 / 对策 |
|
||||
|---|---|
|
||||
| **符号反了** → 反向转 | S1 标定 + S2 干跑必验;配置化而非硬编码 |
|
||||
| bit2 粘滞 → 丢失后仍转 | 第二判据(我方视觉);台架期人工值守 |
|
||||
| bit2 粘滞 → 丢失后仍转 | **LOS 运动学一致性**(`pod_bridge/los_consistency.py`,2026-10-19 取代旧「我方视觉」方案):机头转 Δψ 而脱靶量不动 → 判丢;台架期仍人工值守 |
|
||||
| 框架角定义不符(绝对而非相对机体) | S1 实测确认,不符则改用脱靶量积分等替代 |
|
||||
| 云台归中/搜索态框架角乱转 | 仅锁定态启用;非锁定 → `tracked=False` → BRAKE_HOVER |
|
||||
| 垂直通道撞地 | L1 强制 `vz_gain=0` |
|
||||
| 垂直通道撞地 | L1 强制 `vz_gain=0`(本机实际按决策3 开垂直但压低限速) |
|
||||
| 测距噪声(L2 才有) | L2 滞后,且**不用连续 PID**,改分段限速 |
|
||||
|
||||
---
|
||||
@@ -200,7 +221,8 @@ L1 的 `tracked` 判据按阶段递进:
|
||||
L1 落地时就留好口子,将来 L2 只是"换个输入源",不动结构:
|
||||
|
||||
- `ControlSnapshot.distance_valid` / `target_distance_m` / `distance_time_ms` 字段
|
||||
**现在就按 `False` 填全**,L2 时换成 `stereo_ranger` 的 `forward_distance_m`;
|
||||
**现在就按 `False` 填全**;将来接**激光雷达**距离源后填入(原计划的
|
||||
`stereo_ranger.forward_distance_m` 已随"吊舱取代双目"一并搁置);
|
||||
- `bridge.step()` 按配置在 `TrackingControlLaw`(L1)与 `GuidanceLaw`(L2)间切换;
|
||||
- `guidance.py` 的输入接口保持不变,等有标定过的距离源再启用。
|
||||
|
||||
@@ -224,18 +246,22 @@ L1 落地时就留好口子,将来 L2 只是"换个输入源",不动结构
|
||||
| 2 | `visual_track_control/tracking_control_law.py` | ✅ 第④步角度直入优先,否则回退像素 |
|
||||
| 3 | `visual_track_control/config.py` | ✅ 拆出 `load_from_dict()` 供 bridge 内嵌复用 |
|
||||
| 4 | `pod_bridge/config.py` | ✅ 加 `HeadingServoConfig` + 内嵌 `TrackingConfig`,严格校验符号(±1) |
|
||||
| 5 | `pod_bridge/bridge.py` | ✅ `_build_snapshot()`;`step()` 按 enabled 切 L1/L2;`_dispatch` 对 DEGRADED_HOLD 补发刹车保心跳;`vision_target_fn` 注入点(§2.3 第二判据) |
|
||||
| 5 | `pod_bridge/bridge.py` | ✅ `_build_snapshot()`;`step()` 按 enabled 切 L1/L2;`_dispatch` 对 DEGRADED_HOLD 补发刹车保心跳;~~`vision_target_fn` 注入点~~ → **已删除,改为 LOS 一致性判据**(`los_consistency.py`,§2.3) |
|
||||
| 6 | `config/pod_bridge.json` | ✅ 落 L1 首飞值(slow_approach/0.2、垂直压低、无电机 → 仅脱靶量) |
|
||||
| 7 | `tests/` | ✅ 新增 24 条(vtc 5 + config 9 + bridge L1 10);全量 **396 passed** |
|
||||
| 8 | `pod_bridge/run_bridge.py` | ✅ 闭环 CLI 入口:`--dry-run`(S2 只接吊舱/不发 offboard/打印 β→yaw_rate) 与实飞(S3+,`PodBridge.connect`+信号优雅停机);配套 `run_bridge_test.py` 5 条,全量 **401 passed** |
|
||||
| 9 | `pod_bridge/bridge.py:run()` | ✅ 循环周期改按生效律取频率(L1=tracking.control,L2=guidance),修 L1 live 频率错配 |
|
||||
| 10 | `pod_bridge/virtual_pod.py` | ✅ 模拟吊舱(SITL/台架工具):按无电机语义合成表2-2(框架角恒0、无激光、不可见→bit2=0+脱靶量归0),符号与 S1 标定一致 |
|
||||
| 11 | `pod_sitl_test.py`(根目录) | ✅ L1 SITL 全流程(test.py 吊舱版):解锁→起飞→锚点→offboard→L1 闭环(VirtualPod→PodBridge→控制律)→丢目标→刹车→RTL→落地→上锁,轨迹落 CSV;飞行编排不塞进 run_bridge(保持其纯 offboard 闭环入口) |
|
||||
| 11 | `l1_sitl_test.py`(根目录,原 `pod_sitl_test.py`) | ✅ L1 SITL 全流程:解锁→起飞→锚点→offboard→L1 闭环(VirtualPod→PodBridge→控制律)→丢目标→刹车→RTL→落地→上锁,轨迹落 CSV;飞行编排不塞进 run_bridge(保持其纯 offboard 闭环入口) |
|
||||
| 12 | `tests/pod_bridge/virtual_pod*_test.py` | ✅ 15 条:S1 符号回归 + VirtualPod×PodBridge×控制律集成(右转/下降/慢速前近/丢目标刹车);全量 **417 passed** |
|
||||
| 13 | `pod_bridge/los_consistency.py`(2026-10-19) | ✅ 目标有效性第二判据:LOS 运动学一致性(Δβ+Δψ,3s 窗口/20° 激励/8° 残差);`pod_locked()` 叠加该判据;配套 `los_consistency_test.py` 12 条 + 桥接层 3 条 |
|
||||
|
||||
**待办(非代码,台架)**:~~S1 标定~~ **已完成(2026-10-09)**:目标在左下时 `off_target_x/y`
|
||||
均为负 → 吊舱 X 轴右正(与 β 同向)`beta_sign=+1`;Y 轴上正(与 α 下正相反)
|
||||
`alpha_sign=-1`(已回填 `pod_bridge.json`,并加标定回归测试守住)。厂商确认本版
|
||||
**电机无用** → `beta_from_frame/alpha_from_frame` 恒 false。剩 **S2 干跑**
|
||||
`run_bridge.py --dry-run` 复核方向与量级(目标偏左→yaw_rate 负、居中→趋 0),并标定 `heading.gain`;
|
||||
之后 **SITL 全流程** `python pod_sitl_test.py`(需 PX4 SITL,本机尚未实跑)→ S3 不装桨接飞控。
|
||||
**电机无用** → `beta_from_frame/alpha_from_frame` 恒 false。
|
||||
|
||||
**已完成的后续验证(2026-10-19)**:S2 干跑(`run_bridge.py --dry-run`,真吊舱 COM5,20Hz
|
||||
闭环无异常)、SITL 全流程(`l1_sitl_test.py` 与 `task_runner_sitl.py` 均实跑)、
|
||||
真吊舱在环全流程(`task_runner_real.py --port COM5`,无目标时走"搜索超时→返航"安全路径)。
|
||||
剩:**`heading.gain` 标定**、**吊舱真实目标识别(bit2 0→1)**、S3 不装桨接飞控。
|
||||
|
||||
Reference in New Issue
Block a user