学习 / 实践

具身智能实践(十一):已经放好了,为什么还要撤销“完成”?

具身智能 / 探索 · 工程案例

七条 MuJoCo 轨迹与双画面回放,将历史完成事件和当前有效状态分开,保留传感误报与过期边界。

进阶 · 11 分钟 · 更新于 2026-10-07 · 步骤 11 / 22

这篇之后,已经有了哪些结果?

保留本文发表时的结论与下一步设想;以下是已发表的后续内容,不代表所有局限都已解决。

继续探索

继续探索

  1. 工程案例

    具身智能实践(十二):恢复预算耗尽之后,夹爪应该做什么?

    12 个 MuJoCo 回合与三画面回放,对比保持、松爪、松爪后退,区分终止决定与实际退出后果。

    12 分钟已发布

浏览统计暂不可用

本文目录 9
跳到正文 ↓
从干净环境复现 · 本篇固定版本

以下为 Windows PowerShell,Python 3.12。使用新的目录;不要在有未保存改动的工程里切换版本。每篇固定提交不同,首篇的旧提交不包含后续实验。

git clone https://github.com/VirtualSelect/hohoo-embodied-agent.git hohoo-embodied-agent-study
cd hohoo-embodied-agent-study
git checkout cd26180e8560155d18c45d34a33dc9ef25bbcdf6
python -m venv .venv
$py = '.\.venv\Scripts\python.exe'
& $py -m pip install -r requirements-lock.txt
& $py experiments/vl01_completion_lifecycle/run.py --out outputs/my-run
& $py experiments/vl01_completion_lifecycle/audit.py outputs/my-run

预期得到原始轨迹、摘要和审计结果。请使用新的输出目录,避免覆盖旧结果;不同实验对已存在目录的处理并不相同。E8–E10 共用一组实验入口。以上命令不调用模型;先运行数值部分,视频回放按正文单独执行。

排错:找不到实验目录先核对提交;导入失败检查解释器与安装环境;OpenGL 报错仅影响需要渲染的步骤。Linux/macOS 将解释器替换为 .venv/bin/python,尚未在这些平台复测。

查看本篇固定代码 ↗

固定版本代码 · 原始记录与审计 · 实验档案

上一轮释放验收有一个很具体的反例:物体先在托盘目标区域稳定了足够久,程序报告完成;随后外力把它推离合格区域,最终放置失败,但已经锁存的完成标志仍然为真。

这个标志没有记录错历史。错误在于上层把“曾经通过验收”当成“现在仍然可用”。本篇将两者拆开:completed_at 保留第一次完成事件,state 根据持续观测更新。新增七条真实 MuJoCo 轨迹,直接检查推力、静默、旧包重送和单帧错误报告。

1. 先看同一动作的两种结局

左侧正常运行,右侧在 8.0 到 8.08 秒向方块施加 x 方向 1N 外力。两者此前使用同一个场景、动作序列与验收条件。

回放直接读取归档的 qpos、qvel 和状态事件,再用 mj_forward 更新渲染,不重新推进动力学,不算新增实验回合。画面中的 historical=True 只表示曾经完成,current=VALID/INVALID 表示当前验收状态。视频没有声音,关键结果也完整列在下面。

两条轨迹都在 7.102 秒首次完成。右侧在 8.022 秒撤销当前有效性,历史完成时刻仍然保留。完整轨迹到 12 秒结束;最后 0.5 秒的放置验收,正常条件通过,外力条件失败。

2. 为什么一个布尔值不够

本轮用五个互斥状态表达当前观察结果:

状态 含义 上层不能误解成什么
NOT_READY 尚未满足抬升与释放阶段前提 已经开始验收
UNKNOWN 缺乏足够新鲜或有效的观测 已知物体掉落
INVALID 新鲜观测违反放置条件 永久不可恢复
VERIFYING 有合格观测,正在积累持续窗口 已完成
VALID 连续窗口满足要求且观测仍新鲜 此后永远成功

completed_at 则是一个独立、只记录一次的历史字段。失败后的重新验收不会改写这个首次时刻。这样既能回答“任务曾在何时完成”,也能回答“现在能不能把结果交给下一阶段”。

注意,本例只观察,不自动执行重新抓取或恢复动作;状态撤销与动作决策是两层不同的职责。

3. 把空间、接触与时间条件写进契约

物理步长为 2ms,每 20ms 产生一次观测,持续窗口至少 250ms,观测年龄达到 60ms 即过期。使用整数 tick 计算边界,避免依赖浮点秒数是否恰好相等。

合格观测要求方块 x/y 距离目标中心 (0.24, 0.12) 分别小于 0.045m,z 距离 0.026m 小于 0.006m,速度小于 0.02m/s,接触 bin_floor,并且不接触左右手指。之前还必须曾抬高到 0.1m 以上,并进入释放阶段。

连续观测的捕获时刻间距不能超过 20ms;重复或乱序包不能刷新新鲜度。窗口至少 250ms,而采样以 20ms 为单位,因此本轮实际需要跨越 260ms。VALID 是这些具体条件下的观察状态,不是通用机器人安全认证。

旧版最终放置验收复用 VL01 的最后 0.5 秒位置、速度、抬升和无手指接触要求;当前观察器额外要求 bin_floor 接触。两者分别保存,不能把末端验收结果当作持续状态的别名。

4. 在新包到达之前先检查证据是否过期

更新顺序影响边界行为。先检查上一份可信捕获是否已过期,再处理新到达的包:

if self.last is None or now - self.last >= self.age:
    self.start = None
    self.transition('UNKNOWN', now, 'no-fresh-evidence')
if packet is None:
    return
# 在这里验证包格式,并忽略重复、乱序或过期的捕获。
if not placed(packet):
    self.start = None
    self.transition('INVALID', now, 'fresh-violation')
    return

为什么不能“只要本次有新包,就认为没有断过”?因为包刚好在 60ms 截止时到达时,旧证据已经不能继续支持原来的稳定窗口。新包可以开启新的验证,不能把空档擦掉。

这种顺序在 boundary-gap 中产生两个同 tick 的事件:8.042 秒先 UNKNOWN,再 VERIFYING。汇总曲线每个物理 tick 只画最后状态,因此看不到宽度为零的 UNKNOWN 段;逐事件列表保留了这次重置。不要只看图而忽略日志粒度。

5. 七种条件的实际结果

两种观察器处理同一物理轨迹,因此是七个回合,不是十四个。所有条件第一次完成都是 7.102 秒,旧版完成标志此后不再变化。

七种条件下当前验收状态的时间条:外力触发无效,静默和旧包触发未知,恢复后重新验证;历史首次完成均为7.102秒
条件 关键变化时刻(秒) 最后放置验收
正常 7.102 VALID,此后保持 通过
外力推移 8.022 INVALID 失败
8.0–8.4 秒静默 8.042 UNKNOWN → 8.402 VERIFYING → 8.662 VALID 通过
同期重复旧正常包 与静默相同 通过
单帧错误坏观测 8.002 INVALID → 8.022 VERIFYING → 8.282 VALID 通过
推移后插入单帧假正常包 8.202 VERIFYING → 8.222 INVALID,未重新有效 失败
截止边界恢复收包 8.042 UNKNOWN/VERIFYING → 8.302 VALID 通过

静默与重送旧包具有相同结果,说明“持续收到网络包”不能替代“持续获得新观测”。推移后的单帧假正常包只能启动验证,不能凭一帧重建有效状态。

6. 最重要的负结果:坏观测也会触发撤销

false-bad 没有改变物理世界,只把 8.002 秒那一份收到的 x 坐标改成 0.4m。真实方块仍稳定,但立即撤销策略仍然进入 INVALID,并花到 8.282 秒才重新有效。

这是保守撤销的代价,不能只展示推力案例就称为“误报问题已解决”。本实现对重新建立有效性使用持续窗口,对撤销却采用单帧触发;它容忍孤立的假正常报告,却不容忍孤立的假异常报告。

下一步可以比较撤销滞回或连续异常确认,但必须同时衡量真实偏移的检测延迟。此前搬运实验已展示过这类权衡,本轮没有顺手选择一个“看起来更好”的阈值来隐藏误报。

7. 哪些是物理证据,哪些是传感故障

每个回合分别保存三类文件:2ms 控制与物理记录、20ms 的完整 qpos/qvel 状态,以及状态事件汇总。收到的 packet 与真实 cube 位置、速度、接触分别记录。

独立审计不用控制器或 MuJoCo,读取 21 份逐回合文件,重算状态、完成时刻、最终放置和故障时间表,并核对源码/原始文件哈希。它还验证五组物理轨迹一致:正常对四种纯传感故障,推移对推移后假正常包。这样才能说明传感故障组没有暗中改变控制结果。

九个状态边界测试加三个证据测试通过;后者包含“修改状态并重算文件哈希仍被发现”和“漏掉一个实验条件被发现”。哈希只说明文件一致,独立重算才检查部分内容是否自洽。这仍不是对物理接触力、所有故障或真实硬件的形式证明。

8. 从代码重跑与复核

使用具身仓库现有环境:Python 3.12、MuJoCo 3.3.7、NumPy 2.2.6。从 hohoo-embodied-agent 根目录执行:

python experiments/vl01_completion_lifecycle/run.py --out evidence/MY-E11
python experiments/vl01_completion_lifecycle/audit.py evidence/MY-E11
$env:E11_EVIDENCE = (Resolve-Path evidence/MY-E11).Path
python -m unittest discover -s experiments/vl01_completion_lifecycle -p "test_*.py"
python experiments/vl01_completion_lifecycle/replay.py --evidence evidence/MY-E11

以上是 PowerShell 命令;其他终端用对应方式设置 E11_EVIDENCE。回放额外使用已有的 imageio/FFmpeg 和 Pillow;数字实验不依赖渲染。不设置该环境变量时,三个证据测试会跳过,九个状态测试仍运行。也可以将变量指向现有归档单独复核。输出目录必须不存在,保留旧结果。

关于推进物理与仅更新派生量的区别,见 MuJoCo 官方 simulation 文档。本轮回放使用后者展示存档状态,没有重新模拟一条“更好看”的轨迹。

这次完成的是验收状态生命周期,完整 VL01、真机安全、退出动作与恢复预算的组合仍未完成。可以把下一阶段的接收条件写得更清楚了:既读取历史事件,也验证交接时刻的当前证据;不能只读取一个永不清零的 success。

修复进展 · 2026-10-07

2026-10-07 修正:先处理同一时刻的新观测再判断过期;E14 记录释放意图时刻,排除释放前采样的迟到包。20 项判定器检查及原 E11/E14 协议的 7/8 回合复跑通过独立审计。旧证据仍对应原固定版本,不据此扩大到真机或完整里程碑。

修正版代码与回归命令。

写给未来的自己合上文章前,留下一点自己的理解。

你的私人学习便签,只存在当前浏览器,不会上传或公开。清理浏览器数据会丢失,请导出留存。三种语言共用这篇文章的便签。

下一篇已发布内容:具身智能实践(十二):恢复预算耗尽之后,夹爪应该做什么? →

当前学习位置

探索 / 具身智能

  1. ○ 具身智能实践(十):恢复次数受控了,为什么任务反而没完成?
  2. ○ 具身智能实践(十一):已经放好了,为什么还要撤销“完成”?
  3. ○ 具身智能实践(十二):恢复预算耗尽之后,夹爪应该做什么?

继续探索

继续探索

  1. 实验 / 020

    E11 / 完成事件与当前有效性

    七条 MuJoCo 轨迹与双画面回放,将历史完成事件和当前有效状态分开,保留传感误报与过期边界。

    已完成
  2. 项目 / 003

    Hohoo 具身实验

    MuJoCo 抓取放置与二维力控两个教学场景,记录阶段契约、调参、绕障和延迟反馈的实际结果与失败。

    实验中
  3. 工程案例

    具身智能实践(九):松爪命令成功,不等于放置完成

    五条真实轨迹同时检查单帧与持续窗口:错误观测、延迟松爪和完成后的外力揭示验收范围。

    9 分钟已发布
  4. 工程案例

    具身智能实践(十):恢复次数受控了,为什么任务反而没完成?

    12回合对照无限恢复、两次预算与400ms冷却:分别记录启停、验收窗口、终止原因和最终任务结果。

    9 分钟已发布

接下来,走哪条路?

依据文章关联与同主题已发布内容整理,不使用随机推荐。

← 全部文章