实测记录: 无激光时吊舱不输出表4(目标经纬度)
20Hz喂伪造表3(lat39.9042/lon116.4074/rel_alt50m),只收到约60Hz表2-2, 表4一帧都没有。判读: 吊舱目标地理解算依赖激光测距,无斜距即不解算。 架构影响: - guidance.py 引导律在本设备上永久刹车(bridge.py:169 target_valid 依赖表4), 安全方向正确但吊舱侧不再提供目标坐标 - 目标距离/坐标必须改由自有链路 stereo_yolo -> stereo_ranger 提供 - --auto-unlock 实测禁用: pod_console.py:232 把 last_tgt_s is None 当超时, 会一锁定就误解锁并与 0x0F 常驻自动重锁循环震荡 - 阶段2/阶段3 精度实验取消(前提不成立) 保留两种待排除可能: 未真锁定、表3时戳/有效性要求,给出复测命令。
This commit is contained in:
@@ -1,8 +1,50 @@
|
|||||||
# 用「模拟飞控」喂表3 验证吊舱目标解算能力的实验方案
|
# 用「模拟飞控」喂表3 验证吊舱目标解算能力的实验方案
|
||||||
|
|
||||||
> 状态:**代码已实现**(`sim_fc.py` 已落地,配套 21 个纯软单测),
|
> 状态:**Q1 已有实测答案 —— 无激光时吊舱不输出 表4**(2026-10-08,见 §0.1)。
|
||||||
> 参数已敲定见 §7,**待上机实跑**得到 Q1/Q2/Q3 的实测答案。
|
> 工具 `sim_fc.py` 已落地并配套 21 个纯软单测,参数已敲定见 §7。
|
||||||
> 日期:2026-09-29 关联:`docs/树莓派4B部署注意事项.md` §10 / §10.1
|
> 日期:2026-09-29 立项 / 2026-10-08 实测收敛 关联:`docs/树莓派4B部署注意事项.md` §10.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0.1 🔴 实测结论(2026-10-08):Q1 = 否,无激光 → 表4 不输出
|
||||||
|
|
||||||
|
**实验**:`sim_fc.py` 以 20Hz 持续喂伪造 表3(lat 39.9042 / lon 116.4074 /
|
||||||
|
rel_alt 50m,真实 UTC 递增时戳),同时观测下行。
|
||||||
|
|
||||||
|
**结果**:只收到 表2-2 遥测(≈60Hz),**表4 一帧都没有**(退出码 1)。
|
||||||
|
|
||||||
|
**判读**:吊舱的目标地理解算**依赖激光测距**——没有斜距就无法把视场角换算成
|
||||||
|
地面坐标,于是它**根本不发 表4**(不是发 0,也不是吐旧值)。原先设想的
|
||||||
|
"是否假设目标贴地"随之作废:**它压根没解算**。
|
||||||
|
|
||||||
|
**三个问题的答案**:
|
||||||
|
|
||||||
|
| 问题 | 实测答案 |
|
||||||
|
|---|---|
|
||||||
|
| **Q1** 无激光时是否输出表4 | ❌ **否**。表4 路径在本设备上不存在 |
|
||||||
|
| **Q2** 表4 频率 | ❌ 无从谈起(无输出)。`target_stale_ms` 对表4 无意义 |
|
||||||
|
| **Q3** 目标丢失后表4 行为 | ❌ 无法观测。目标丢失判据**不能**依赖表4(这与 §10.1 的预判一致) |
|
||||||
|
|
||||||
|
**架构影响(分叉已选边)**:
|
||||||
|
|
||||||
|
1. `guidance.py` 地理位置引导律在本设备上**永久刹车**——`bridge.py:169` 的
|
||||||
|
`target_valid` 依赖表4,表4 恒缺则每周期走 `_brake()`。安全方向正确(不会乱飞),
|
||||||
|
但**功能上等于吊舱侧不提供目标坐标**;
|
||||||
|
2. 目标距离与坐标**必须改由我方自有链路提供**:`stereo_yolo` 检测 →
|
||||||
|
`stereo_ranger` 双目视距。吊舱退化为"伺服稳定指向 + 表2-2 脱靶量"传感器;
|
||||||
|
3. 若要保留吊舱侧目标定位,只能换**带激光测距的吊舱型号**或外挂测距模块;
|
||||||
|
4. `--auto-unlock` **已实测禁用**(`pod_console.py:232` 把 `last_tgt_s is None`
|
||||||
|
当成超时,会一锁定就误解锁并循环震荡)。
|
||||||
|
|
||||||
|
**尚未完全排除的两种可能**(值得再花 10 分钟钉死,钉死前不要把结论当成绝对):
|
||||||
|
|
||||||
|
1. 本次测试**未必真的锁定成功**(bit2 未置位)→ 吊舱可能要求先锁定才解算。
|
||||||
|
复测加 `--detect person --auto-lock`,看汇总里"首次锁定"是否有值;
|
||||||
|
若**锁定后仍无表4**,结论才完全坐实。
|
||||||
|
2. 吊舱可能对 表3 的**时戳/位置有效性**有额外要求 → 用 `--freeze-time` 做一次对照。
|
||||||
|
|
||||||
|
**阶段2 / 阶段3 处置**:**取消**(精度比对与高度敏感性扫描都以表4 存在为前提)。
|
||||||
|
除非上面第 1 条复测翻盘,否则不要再往这条路上投时间。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+42
-12
@@ -171,17 +171,15 @@ WantedBy=multi-user.target
|
|||||||
`journalctl -u pod-bridge -f`。
|
`journalctl -u pod-bridge -f`。
|
||||||
- 代码热路径按 10Hz 引导 + 20Hz 姿态下发,Pi 4B 单核占用可忽略,无需实时内核。
|
- 代码热路径按 10Hz 引导 + 20Hz 姿态下发,Pi 4B 单核占用可忽略,无需实时内核。
|
||||||
|
|
||||||
## 10. 本设备实测特性(2026-09-28,厂商确认)
|
## 10. 本设备实测特性(2026-09-28 厂商确认 + 2026-10-08 实测)
|
||||||
|
|
||||||
- **本吊舱不含激光测距模块**。后果:
|
- **本吊舱不含激光测距模块**。后果:
|
||||||
- 表2-2 激光测距字段恒为 0(无效),不可作为判据;
|
- 表2-2 激光测距字段恒为 0(无效),不可作为判据;
|
||||||
- `pod_bridge.json` 的 `link.require_laser_valid` **必须为 false**,否则引导
|
- `pod_bridge.json` 的 `link.require_laser_valid` **必须为 false**,否则引导
|
||||||
永久刹车(该闸门是为"有激光且锁定位置位粘滞"的机型准备的);
|
永久刹车(该闸门是为"有激光且锁定位置位粘滞"的机型准备的);
|
||||||
- ⚠ 需向厂商确认:无激光时吊舱如何解算表4 的目标绝对/相对高度
|
- 🔴 **无激光时吊舱不输出 表4(目标经纬度)** —— **实测确认,2026-10-08**。
|
||||||
(是否假设目标在地面),这直接决定引导用的坐标精度。
|
详见 §10.0,这是本项目迄今最重要的架构性结论。
|
||||||
→ 已给出**不依赖厂商答复的自测方案**:用树莓派伪造飞控数据喂 表3,
|
|
||||||
逼吊舱吐 表4,见 `docs/吊舱解算验证方案-模拟飞控喂表3.md`。
|
|
||||||
该实验还顺带回答 §10.1 悬着的两个前置问题(表4 是否存在、实际频率)。
|
|
||||||
- **锁定位置位(表2-2 状态字节1 bit2)在目标丢失后不复位**——实测观察;
|
- **锁定位置位(表2-2 状态字节1 bit2)在目标丢失后不复位**——实测观察;
|
||||||
表2-2 脱靶量是定长字段且协议**没有无效标志位**,丢失时表现为 0,
|
表2-2 脱靶量是定长字段且协议**没有无效标志位**,丢失时表现为 0,
|
||||||
无法区分"不输出"与"输出 0"。
|
无法区分"不输出"与"输出 0"。
|
||||||
@@ -193,16 +191,48 @@ WantedBy=multi-user.target
|
|||||||
0x07 / 0x0F / 0x10(实测结论,2026-09-28 纠正)。只有发了 `0x08 目标识别关`
|
0x07 / 0x0F / 0x10(实测结论,2026-09-28 纠正)。只有发了 `0x08 目标识别关`
|
||||||
才真正退出识别,此时才需要按 `d` / `a` 重新开启。
|
才真正退出识别,此时才需要按 `d` / `a` 重新开启。
|
||||||
|
|
||||||
### 10.1 自动解锁机制(待定,勿贸然启用)
|
### 10.0 实测结论:无激光 → 表4 不输出(2026-10-08)
|
||||||
|
|
||||||
|
**实验**:用 `sim_fc.py` 以 20Hz 持续喂伪造 表3(lat 39.9042 / lon 116.4074 /
|
||||||
|
rel_alt 50m,真实 UTC 递增时戳),同时观测下行。
|
||||||
|
|
||||||
|
**结果**:只收到 表2-2 遥测(约 60Hz),**表4 一帧都没有**。
|
||||||
|
|
||||||
|
**判读**:吊舱的目标地理解算**依赖激光测距**。没有距离输入时,它拿不到目标的
|
||||||
|
斜距,无法把视场角换算成地面坐标,于是**根本不发 表4**(不是发 0、不是发旧值)。
|
||||||
|
此前"无激光时如何解算高度/是否假设目标贴地"的问题随之作废——**根本没解算**。
|
||||||
|
|
||||||
|
**直接后果(务必读完再决定下一步)**:
|
||||||
|
|
||||||
|
| 受影响项 | 后果 |
|
||||||
|
|---|---|
|
||||||
|
| `guidance.py` 地理位置引导律 | **永久刹车**。桥接层 `bridge.py:169` 的 `target_valid` 依赖表4;表4 恒缺 → `_latest_target` 恒 None → `GuidanceLaw.update()` 每周期走 `_brake("载机位置或目标不可用/超龄")`。安全方向正确(降级刹车、不会乱飞),但**吊舱表4 这条引导路径在本设备上等于不存在** |
|
||||||
|
| 目标距离/坐标来源 | 必须改由**我方自有链路**提供:`stereo_yolo` 检测 → `stereo_ranger` 双目视距。吊舱只当作"稳定指向 + 表2-2 脱靶量"的伺服/传感器用 |
|
||||||
|
| `--auto-unlock`(§10.1) | **必然误触发,已实测禁用**。见 §10.1 |
|
||||||
|
| 后续选型 | 若要保留吊舱侧目标定位,只能换**带激光测距的吊舱型号**,或外挂测距模块 |
|
||||||
|
|
||||||
|
**尚未排除的两种可能(值得再花 10 分钟钉死)**:
|
||||||
|
1. 吊舱需要**先真正锁定**才解算,而本次测试未必锁定成功(bit2 未置位)。
|
||||||
|
→ 复测时加 `--detect person --auto-lock`,并在汇总里确认"首次锁定"有值;
|
||||||
|
若锁定后仍无表4,结论才完全坐实。
|
||||||
|
2. 吊舱要求 表3 的**时戳/位置有效性**满足某种条件(例如 GPS 有效标志)。
|
||||||
|
→ 可用 `--freeze-time` 做一次对照。
|
||||||
|
|
||||||
|
> 复测命令:`python -m pod_bridge.sim_fc /dev/ttyAMA0 --detect person --auto-lock
|
||||||
|
> --seconds 60 --json phase1.json`,退出码 1 = 仍无表4。
|
||||||
|
### 10.1 自动解锁机制(🔴 本设备实测禁用,2026-10-08)
|
||||||
|
|
||||||
`pod_console.py --auto-unlock SEC` 现按「锁定中 + 表4 超过 SEC 秒未更新」触发 0x0E。
|
`pod_console.py --auto-unlock SEC` 现按「锁定中 + 表4 超过 SEC 秒未更新」触发 0x0E。
|
||||||
**该判据对本设备存疑**,开箱前需确认:
|
**该判据在本设备上 100% 误触发,不要用**:因为 §10.0 实测确认表4 根本不发,
|
||||||
|
`last_tgt_s` 恒为 None,而 `pod_console.py:232` 的条件把
|
||||||
|
`last_tgt_s is None` **直接当成超时** → 一旦锁定满 SEC 秒就发 0x0E,并且每
|
||||||
|
SEC 秒重复一次(与"假锁定"形成持续震荡:解锁 → 自动锁定 → 解锁 → …)。
|
||||||
|
|
||||||
| 待确认项 | 影响 |
|
| 待确认项 | 现状(2026-10-08 更新) |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 本设备无激光,锁定后**到底发不发 表4** | 若表4 根本不发,`last_tgt_s` 恒空 → 一锁定就被误解锁,机制不可用 |
|
| 本设备无激光,锁定后到底发不发 表4 | ✅ **已实测:不发**。判据前提不成立 |
|
||||||
| 表4 的实际发送频率(规格 1~60Hz) | SEC 必须远大于实际周期(建议 ≥5s 且 ≥3 倍周期),否则误杀 |
|
| 表4 的实际发送频率 | ❌ 无从谈起(无输出) |
|
||||||
| 解锁后是否自动重发 0x0F/0x10 重新捕获 | **不需要**:0x0F 是常驻模式,0x0E 后目标重新入画会自动锁定;自动重发反而可能与"假锁定"形成震荡 |
|
| 解锁后是否自动重发 0x0F/0x10 重新捕获 | 不需要(0x0F 常驻),但**这反而让误解锁的震荡可以一直循环**,所以更不能用 |
|
||||||
|
|
||||||
候选替代判据(按可靠性排序):
|
候选替代判据(按可靠性排序):
|
||||||
1. **操作员按键 `u`**(台架阶段推荐,零误杀);
|
1. **操作员按键 `u`**(台架阶段推荐,零误杀);
|
||||||
|
|||||||
@@ -224,9 +224,10 @@ def main() -> int:
|
|||||||
latest_tgt = frame
|
latest_tgt = frame
|
||||||
|
|
||||||
# ---- 自动解除锁定:锁定中但表4 长时间不更新 ----
|
# ---- 自动解除锁定:锁定中但表4 长时间不更新 ----
|
||||||
# ⚠ 本设备无激光测距,表4(目标经纬度)可能始终不发 → last_tgt_s 恒为
|
# 🔴 本设备已实测(2026-10-08):无激光测距时吊舱**根本不发表4** →
|
||||||
# None,此判据会一锁定就误解锁。启用前先用控制台观察「目标帧 距今」,
|
# last_tgt_s 恒为 None,而下方条件把 None 当成超时,故本设备上
|
||||||
# 确认锁定后表4 真的在发。触发判据的替代方案见部署文档 §10。
|
# --auto-unlock 会一锁定就误解锁,并每 SEC 秒与「0x0F 常驻自动重锁」
|
||||||
|
# 循环震荡。**不要再启用**,判据改用按键 u。详见部署文档 §10.0/§10.1。
|
||||||
if (args.auto_unlock > 0 and latest is not None
|
if (args.auto_unlock > 0 and latest is not None
|
||||||
and latest.is_target_locked
|
and latest.is_target_locked
|
||||||
and (last_tgt_s is None or now_s - last_tgt_s > args.auto_unlock)
|
and (last_tgt_s is None or now_s - last_tgt_s > args.auto_unlock)
|
||||||
|
|||||||
Reference in New Issue
Block a user