学习 / 实践
具身智能实践(七):搬运规则,为什么会误停正常下降?
具身智能 · 工程案例
21回合MuJoCo对照:下降需要自己的抓取契约。用正常误停、旧包报警与晚下降残留接触,拆开监测范围、停止动作和最终放置。
浏览统计暂不可用
本文目录 10
搬运方块时,要求“方块中心高于12厘米”很合理:它用来确认方块仍被抬着。但任务进入下降阶段后,方块本来就应该越来越低。把同一条规则继续打开,会发生什么?
这轮21回合给出了一个直接反例:方块仍被双指夹持、与夹爪中心只差7.874毫米,却在正常下降到6.002秒时被判为抓取异常。 去掉下降阶段的搬运高度条件后,正常轨迹能完成放置;但故障后的保持动作仍有缺口,晚下降松爪条件最终留下了手指接触。
因此这篇不把“覆盖更多阶段”直接写成“系统更安全”。我们分别检查三个问题:规则在当前阶段是否合适,报警是否发生在真实故障之后,最后的物理状态是否满足任务要求。
1. 上一轮留下的不是“多加一个判断”
E6恢复消融发现,旧门控只在搬运阶段工作。路径重新定时后,控制器停留在被监测阶段的时间也发生变化,反复恢复次数因而不能只归因于路径几何。
直接把 phase == "transfer" 改成 phase in ("transfer", "lower"),看似补上了下降监测,其实同时带来了新的问题:原判断中的每个条件,到了下降阶段还成立吗?
这里把“阶段契约”理解为一组当前阶段应满足的条件。它是本实验中的明确判据,不是经过形式化证明的机器人安全契约。
| 条件 | 搬运时的作用 | 下降时是否沿用 |
|---|---|---|
| 双指接触方块 | 支持仍在夹持的判断 | 是,主动释放前仍要求夹持 |
| 方块距夹爪中心小于5cm | 排除已明显脱离的状态 | 是 |
| 方块中心高于12cm | 确认抬升后的搬运状态 | 否,下降必然经过这个高度 |
| 最新接纳采样年龄小于60ms | 防止拿旧证据当当前状态 | 是 |
去掉高度条件只改变下降判据,搬运判据保持不变。主动释放后,失去手指接触反而是预期动作,不能继续把它当作同一种抓取故障。
2. 先把恢复关闭,隔离这一个问题
本轮不叠加E6的恢复与重规划。三种策略使用同一固定时间表、同一初始状态和同一报警后动作:锁存停止,保持报警时的执行器目标,后续不恢复。
这样可以检查监测范围与判据,而不让不同恢复路径重新改变阶段时长。它是一轮独立消融,不是声称完整E6控制器已经升级并通过回归。
| 策略 | 搬运监测 | 下降监测 |
|---|---|---|
仅搬运 transfer-only |
完整搬运判据 | 不监测 |
照搬 reuse-transfer |
完整搬运判据 | 完整搬运判据,包括高度 |
分阶段 phase-aware |
完整搬运判据 | 双指接触、距离、年龄;不要求搬运高度 |
三者都在计划的主动释放阶段结束抓取监测。释放后的状态仍由最终放置验收检查,但没有实现独立的释放安全监测。
核心差异在代码里很短:
contact = {"left_pad", "right_pad"} <= set(packet["contacts"].split("|"))
retained = contact and packet["grasp_error"] < self.error
height_required = phase == "transfer" or self.policy == "reuse-transfer"
return retained and (not height_required or packet["cube_z"] > self.height)判据只读取传入的观测包,不直接访问物理引擎。观测来自MuJoCo真值,这与相机识别、触觉估计或真机传感器不同。
3. 21个回合具体怎么跑?
七个条件各跑三种策略,每格一次确定性执行,无随机种子。这不是用21个独立随机样本估计泛化成功率。
| 项目 | 本轮设置 |
|---|---|
| 环境 | Windows 11、Python 3.12.14、MuJoCo 3.3.7、NumPy 2.2.6 |
| 物理/控制步长 | 2ms |
| 观测采样周期 | 20ms |
| 搬运 / 下降 / 主动释放 | 4.0–5.5s / 5.5–6.5s / 6.5–7.2s |
| 回合终点 | 9.2s,包含撤离和稳定阶段 |
| 抓取异常确认 | 连续坏采样的捕获跨度至少40ms |
| 新鲜度门槛 | 最新接纳采样年龄达到60ms即报警 |
| 报警后的动作 | 从下一控制步开始保持目标;没有恢复 |
七条件分别是:无故障;4.8s搬运松爪;5.6s下降早期松爪;6.2s下降后期松爪;5.6s起下降丢包;同一时段重送故障前旧包;5.6s的一次空接触报告。松爪、丢包和重送持续240ms,空报告窗口20ms,只影响一个采样。
松爪故障只把夹爪执行器目标改为打开,不改写方块位置。故障窗口结束后,恢复该策略当时的夹爪目标。因此即使已停住平移,原来的闭爪目标仍可能重新施加。这一点会解释后面的失败。
MuJoCo的控制向量与物理状态是不同层次;改变执行器目标后,接触与运动仍由仿真推进。可对照官方仿真循环说明及位置执行器定义。保持目标不等于把物体冻结在空间中。
4. 正常下降:规则本身制造了误报
正常条件下,照搬策略在5.962s出现第一份不满足高度条件的采样,40ms后,于6.002s停止。此刻实际记录是:
| 物理量 | 记录 |
|---|---|
| 方块中心高度 | 110.687mm |
| 方块与夹爪中心距离 | 7.874mm |
| 手指接触 | 左、右两指都有 |
| 观测年龄 | 0ms,刚捕获的新包 |
不是通信过期,也不是接触丢失。它正确执行了一条放错阶段的规则。 最后方块仍悬在夹爪中,未进入主动释放,也未通过放置验收。
分阶段策略和仅搬运策略没有报警,正常回合的状态与控制轨迹完全一致。这里支持的结论是:在本场景的正常下降中,移除搬运高度条件避免了这次误停;不是所有高度约束都应该删除。
图来自实际控制日志。部分曲线重合;右图方块下降并不等于按计划完成了主动释放。
5. 方块进了托盘,为什么仍不能说过程正确?
早下降松爪条件中,三种策略的最终放置都通过。但仅搬运策略完全没有监测下降,不曾报警;另外两种策略在5.642s检出接触异常,随后保持目标,方块仍因重力落进了下方托盘。
若只汇总“成功次数”,这三种明显不同的过程会被记成一样。最终放置验收只能回答:末尾0.5s是否在目标范围、静止、没有手指接触,而且此前曾抬升;它没有要求方块必须以计划动作落地,也没有衡量碰撞冲击。
这不是应该偷偷调整验收规则、让结果更漂亮的理由。原规则和原结果都保留,再把缺失的过程要求写出来,才知道下一轮要验证什么。
6. 晚下降:报警正确,停止动作仍有问题
6.2s强制松爪时,分阶段策略在6.242s停止。到9.2s末尾,方块已经接触托盘底部,但仍同时接触左右两指,不满足“无手指接触”的放置条件。
日志显示,夹爪停止在较低位置;240ms松爪故障结束后,保持的闭爪目标重新施加,留下残余手指接触。这不是经过设计的重新抓取,也不能写成“系统成功救回了物体”。本轮记录的接触和目标支持这个解释,但没有额外测量接触力或证明所有碰撞过程。
反过来看照搬策略,它在6.002s就因为高度条件误停,早于6.2s故障,之后方块反而落入托盘并通过验收。不能把这个更早的停止算成“更快检出松爪”。
同一张结果表里,一个策略误报后最终通过,另一个策略正确报警后最终未通过。所以监测判断与退出动作必须分别评估,不能只用终点结果替它们排序。
7. 丢包和重送:到达时间不能替代捕获时间
下降丢包与重送旧包时,分阶段策略都在5.642s报警。最新接纳采样来自5.582s,年龄恰好60ms。重送条件中的12份旧包虽然到达了,却不满足序号和捕获时间同时递增的要求,因此没有刷新年龄。
这里有两个不同的时间量:坏采样确认跨度是40ms,年龄门槛是60ms。丢包从5.600s的命令步开始,第一份故障后步末采样原应在5.602s;5.642s报警距该步末时刻40ms,却距最新好采样60ms。报告延迟时必须说明起点。
在一次空报告条件中,分阶段策略下一次就收到正常采样,坏跨度被清除,没有停机。照搬策略后来仍在6.002s误停,原因是高度,不是那份已经恢复的空报告。
8. 完整矩阵:不要只看最后一列
单元格分别记录“首次停止 / 最终放置”。“不停止”表示没有报警,不等于已验证过程安全。
| 条件 | 仅搬运 | 照搬 | 分阶段 |
|---|---|---|---|
| 正常 | 不停止 / 通过 | 6.002s抓取 / 未通过 | 不停止 / 通过 |
| 搬运松爪 | 4.842s抓取 / 未通过 | 4.842s抓取 / 未通过 | 4.842s抓取 / 未通过 |
| 下降早松爪 | 不停止 / 通过 | 5.642s抓取 / 通过 | 5.642s抓取 / 通过 |
| 下降晚松爪 | 不停止 / 通过 | 6.002s误停 / 通过 | 6.242s抓取 / 未通过 |
| 下降丢包 | 不停止 / 通过 | 5.642s过期 / 未通过 | 5.642s过期 / 未通过 |
| 下降旧包重送 | 不停止 / 通过 | 5.642s过期 / 未通过 | 5.642s过期 / 未通过 |
| 一次空报告 | 不停止 / 通过 | 6.002s误停 / 未通过 | 不停止 / 通过 |
两个下降松爪条件中,分阶段策略从首个故障后采样到停止均为40ms。本矩阵没有证明增加监测提高了放置成功率;它暴露的是旧监测范围的空缺、机械复制判据的误报,以及保持动作的不足。
9. 怎样核验与复现?
执行代码与协议先提交,再运行21格;manifest记录干净工作区、版本和来源指纹。独立审计器不导入监测器或MuJoCo,从记录重算:
- 105份逐回合文件与10份源码/协议指纹。
- 故障窗口、实际接收包、旧包丢弃、采样年龄与坏采样跨度。
- 停止时刻、下一步保持目标、最终放置和主动释放是否进入。
- 七条件各三对策略,共21组首次决策分歧前的状态/控制前缀。
13项监测测试与8项证据审计、篡改检出测试通过。篡改测试只修改临时副本中的目标、观测、事件、状态或结果,确认审计会报错;不改变原始证据。审计检查记录一致性,不重算全部接触力,也不替代对模拟器的验证。
从工程根目录审计已归档数据:
python experiments/vl01_phase_contracts/audit.py evidence/phase-contracts-20261001
python -m unittest discover -s experiments/vl01_phase_contracts -p test_monitor.py -v重跑时使用没有存在过的目录,避免覆盖历史;运行前提交源码和协议,使manifest记录可复现版本。虚拟环境需使用上述MuJoCo版本。
python experiments/vl01_phase_contracts/run.py --out runs/e7-my-run
python experiments/vl01_phase_contracts/audit.py runs/e7-my-run --out runs/e7-my-run/audit.json
python experiments/vl01_phase_contracts/plot.py runs/e7-my-run --out runs/e7-my-run/figurescontrol.csv保留每2ms的决策依据,states.jsonl与trajectory.csv每20ms保留物理采样。events.json查首次停止,summary.json查逐格验收。完整测试的 E7_EVIDENCE 设置方法见工程说明。
10. 下一步:先定义停止之后做什么
接下来最值得做的不是增加更多监测阈值,而是分别定义:下降故障后的退出动作、主动释放后的状态要求,以及恢复次数或冷却约束。保持、受控释放、撤离可能产生不同后果,应冻结各自前提,再用同样故障时刻对照。
本轮仍使用固定时间表决定阶段、单一时钟与仿真真值,没有视觉、ROS2、学习策略、真机或全任务安全证明。完整VL01及M4/M5继续保持未完成。已有证据支持的改进很具体:规则要随阶段解释;报警、动作和终点验收,要各自留下证据。
写给未来的自己合上文章前,留下一点自己的理解。
你的私人学习便签,只存在当前浏览器,不会上传或公开。清理浏览器数据会丢失,请导出留存。三种语言共用这篇文章的便签。
继续探索
继续探索
- 工程案例
具身智能实践(六):恢复门控与路径重规划,各自解决了什么?
30回合消融对照:重规划把首次目标跳变从50–97毫米降至约0.25毫米,却没有提高本矩阵的放置成功率。用原始日志拆开恢复证据、动作连续性与任务结果。
接下来,走哪条路?
- 具身实践(四):消息还在到,观测已经过期了 →
45回合MuJoCo对照,分离采样间隔、异常计数与观测年龄;理解旧消息为何会掩盖真实松爪,以及时间阈值仍有什么局限。
- 具身智能实践(六):恢复门控与路径重规划,各自解决了什么? →
30回合消融对照:重规划把首次目标跳变从50–97毫米降至约0.25毫米,却没有提高本矩阵的放置成功率。用原始日志拆开恢复证据、动作连续性与任务结果。
依据文章关联与同主题已发布内容整理,不使用随机推荐。