学习 / 实践
具身智能实践(五):通信恢复了,为什么还不能立刻继续搬运?
具身智能 · 工程案例
18回合 MuJoCo 对照:旧正常包让基线反复启停却最终成功;用连续新证据与剩余路径规划重新定义恢复。
浏览统计暂不可用
本文目录 10
上一轮已经能识别过期观测,并停止搬运。问题随之改变:通信恢复了,原来的动作是否就可以继续?
这轮最值得看的不是“又成功了几次”,而是一个反例:收到消息就恢复的策略,在旧正常包重送时恢复了9次,其中8次没有满足新鲜抓取证据,最后却仍完成了放置。只看终点,会把中间的反复启停全部藏起来。
1. 从“应该停”到“何时能继续”
一次通信间断可能对应两种完全不同的现实:方块仍夹在手里,只是消息暂时没有送达;也可能夹爪已经松开,新的状态还没有被接收。
因此,恢复连接只是传输层事件,不能直接满足搬运的前置条件。本轮把恢复拆成三个问题:
- 收到的是新的观测,还是旧消息的再次投递?
- 新观测是否持续支持“还抓着方块”?
- 即使可以继续,旧轨迹对应的时刻是否已经过去?
前两项决定是否允许恢复,第三项决定恢复后发出什么目标。
2. 场景与冻结协议
复用同一 MuJoCo 笛卡尔夹爪、方块、托盘和原始动作。Python 3.12.14、MuJoCo 3.3.7、NumPy 2.2.6;协议在正式运行前冻结于提交 8142cdb。
| 项目 | 本轮设定 |
|---|---|
| 物理与控制步长 | 2ms |
| 观测采样 | 20ms |
| 故障开始 | 4.8s,搬运阶段 |
| 消息间断 | [4.8, 5.04),240ms |
| 过期阈值 | 观测年龄达到60ms |
| 持续异常阈值 | 坏观测跨度达到40ms |
| 恢复确认 | 至少100ms连续有效的新观测 |
| 最长等待 | 停止后600ms |
| 所有回合终点 | 10.8s |
| 对照规模 | 6条件 × 3策略 = 18回合,每格一次 |
这是固定条件的确定性仿真,不是18次独立随机试验,也不估计部署成功率。观测来自仿真真值,不包含相机识别。
3. 六种条件分别改变什么?
| 条件 | 对消息或物理的处理 |
|---|---|
| clean | 无扰动 |
| delay-40ms | 每份观测固定延迟40ms送达 |
| reordered | 故障开始后每第三包延迟80ms,允许新包先到 |
| gap | 间断期间不投递,恢复后投递新观测,不追发积压包 |
| stale-replay | 间断后重送最后一个正常旧包,直到5.2s |
| gap-and-drop | 通信间断,同时在该区间实际打开夹爪 |
“掉落”由执行器松爪造成,方块仍通过接触与重力运动,没有直接改写方块位置。固定延迟与乱序条件不强制制造停机:没有停机同样是需要记录的结果。
4. 三种策略的差异
锁存停止(latched):一旦触发停止,保持目标,600ms后中止,不恢复。这是保守参照。
收到即恢复(receipt):只要有合法消息投递就恢复,不检查它是否重复、过期或仍支持抓取,并继续按墙钟时间读取原轨迹。这是刻意保留的反例基线。
重新验收(revalidate):恢复窗口中的捕获必须同时满足:
- 序号/捕获顺序严格递增,且捕获晚于此次停止;
- 每份观测的年龄小于60ms;
- 双侧接触成立,方块高度大于0.12m,与夹爪中心距离小于0.05m;
- 连续跨度至少100ms,相邻捕获间隔不超过20ms。
条件失效会清空确认窗口。600ms截止时,先执行中止判定,不能在同一个tick“压线恢复”。这些数值是教学场景的协议,不是通用机器人安全阈值。
5. 旧包为何会让系统反复启停?
下面是 stale-replay 的实际记录,而不是示意时间:
| 时刻 | 发生的事情 |
|---|---|
| 4.782s | 最后一个间断前的正常观测被捕获 |
| 4.842s | 该观测年龄达到60ms,触发停止 |
| 5.042s | 旧包再次送达,收到即恢复策略立即放行;捕获年龄已260ms |
| 5.042s之后 | 旧证据再次触发停止,又被后续重复投递放行 |
| 5.302s | 重新验收策略取得100ms连续新证据,第一次恢复 |
收到即恢复累计9次恢复,其中8次对应过期证据。事件日志里的恢复次数与最终任务成功必须同时看。

图由控制日志生成。横轴为仿真时间;它不是摄像头画面,也不是物理机器人运行录像。
6. 恢复时为什么重新规划剩余路径?
停止期间,程序时间和物理状态还在变化。直接查询“当前墙钟时刻的旧轨迹目标”,可能跳过尚未执行的路径段。
本实现从恢复时实测夹爪位置生成通向原搬运终点的1.5s轨迹,再进入原来的下降、松爪、撤离与稳定阶段。hold只是保持执行器目标,物理仍然推进;并不把状态冻结在停止瞬间。

重新验收同时改变了恢复条件和后续轨迹,因此本轮比较的是策略组合。不能把全部差异都归功于100ms窗口;要分离原因,需要下一轮分别开关门控和重规划。
7. 18回合的完整结果
| 条件 | 锁存停止 | 收到即恢复 | 重新验收 |
|---|---|---|---|
| 无扰动 | 放置成功 | 放置成功 | 放置成功 |
| 固定40ms延迟 | 放置成功 | 放置成功 | 放置成功 |
| 每第三包延迟80ms | 放置成功 | 放置成功 | 放置成功 |
| 240ms通信间断 | 中止,未放置 | 1次恢复,成功 | 1次恢复,成功 |
| 旧正常包重送 | 中止,未放置 | 9次恢复,8次证据不足;最终成功 | 1次恢复,成功 |
| 间断并松爪 | 中止,未放置 | 6次恢复,均证据不足;未放置 | 不恢复,中止 |
这里“证据不足”精确定义为:恢复时观测年龄达到60ms,或抓取状态谓词不成立。不把它直接翻译成“真实机器人必定发生危险”。
纯通信间断时,重新验收在5.142s恢复;旧包重送时是5.302s;真正松爪条件则在5.442s到达等待期限后中止。后者的放置失败并不等于门控失败,它正确地拒绝了证据不成立的继续动作。
8. 怎样确认差异来自停止之后?
审计不调用 Gate 的决策实现,而是读取CSV和保存的状态:
- 18回合的终点条件从轨迹重新计算;
- 12组策略间的决策前状态前缀一致,qpos、qvel、ctrl最大绝对差为0;
- 两个重新验收恢复窗口均满足捕获顺序、时间跨度、年龄与抓取谓词;
- 108份原始文件记录SHA-256,包接收、忽略旧包与中止时限另外核验;
- 新增18项边界测试,与此前41项测试均通过。
这能发现记录不一致或逻辑边界错误,但不构成另一套物理引擎的交叉验证。
9. 复现与阅读原始产物
在具身工程根目录执行,使用新的输出目录保留旧记录:
.venv/Scripts/python experiments/vl01_recovery_gate/test_gate.py
.venv/Scripts/python experiments/vl01_recovery_gate/run.py --out evidence/my-recovery-run
.venv/Scripts/python experiments/vl01_recovery_gate/audit.py evidence/my-recovery-run
.venv/Scripts/python experiments/vl01_recovery_gate/render.py evidence/my-recovery-run每回合 control.csv 是2ms决策记录;states.jsonl 与 trajectory.csv 是20ms状态采样;events.json 记录停止、恢复和中止;replans.json 保存重新规划起点。
跨平台检出历史证据时可运行 portable-audit.py evidence/recovery-20260930。它只在临时目录恢复能够匹配原哈希的LF/CRLF换行,再运行冻结审计,不修改原始证据。
10. 结论边界与下一个问题
本轮证明的是:在这组固定场景中,持续收到消息不足以作为恢复条件;新的连续抓取证据配合剩余路径规划,能区分通信间断与抓取丢失。
尚未验证真实网络、时钟偏差、视觉估计误差、不同物体或不同故障相位。没有重抓取,也没有完成ROS2桥接或完整M4/M5。下一步最有价值的是门控与重规划的消融对照,而不是马上增加更复杂的机器人模型。
关于步进和仿真状态的基础行为,可对照 MuJoCo 3.3.7 仿真文档。本站代码、协议和原始数据共同限定了本文的结论。
写给未来的自己合上文章前,留下一点自己的理解。
你的私人学习便签,只存在当前浏览器,不会上传或公开。清理浏览器数据会丢失,请导出留存。三种语言共用这篇文章的便签。
继续探索
继续探索
接下来,走哪条路?
- 具身实践(四):消息还在到,观测已经过期了 →
45回合MuJoCo对照,分离采样间隔、异常计数与观测年龄;理解旧消息为何会掩盖真实松爪,以及时间阈值仍有什么局限。
- 具身实践(三):抓住之后,还要一直确认吗? →
27回合MuJoCo对照:用单次观测缺失与受控松爪,检验持续监测、误停和40毫秒确认延迟,并公开代码、轨迹与重放。
依据文章关联与同主题已发布内容整理,不使用随机推荐。