跳到正文
APPLICATIONS · ROBOTICS PROJECT

学会正常抓取,不等于学会从掉落中恢复

让机器人把方块放进盒子,是一项小而完整的系统实验:物体必须真的被抓起,经过接触物理搬运,松手后稳定留在容器内。我们用同一个任务连接身体、动作、数据、学习和评测,并故意制造一次掉落,看正常场景里的好成绩在哪里失效。

机械臂把橙色方块放进蓝色盒子,旁边的示范轨迹与回转箭头象征学习和恢复
生成的直觉总览:示范、学习、执行和恢复需要分别验证。插画及其中曲线不是实验结果;下文另附实际仿真截图和逐回合报告。 查看原图 ↗
01 · 先写下什么才算成功

到达目标点,只完成了入盒的一部分

想象把杯子交给别人:手到了对方附近,不代表已经交接;松手后杯子掉在地上,更不能算成功。机器人同样需要检查物体,而不是只检查夹爪或命令。

我们复用 Fetch 机械臂,并加入有底板和四壁的碰撞容器。方块边长 5 cm,容器内部水平尺寸为 17 × 15 cm;方块初始位置在 x∈[1.16,1.43] m、y∈[0.59,0.77] m 内随机采样。容器、机器人、物体形状和物理参数保持固定。执行期间不把方块绑到夹爪,也不改写方块位置,抓取与掉落都由 MuJoCo 接触物理计算。

  1. 完整进入

    旋转后的方块八个顶点均在盒内水平范围;允许 1 mm 数值容差。

  2. 处于底部高度

    物体中心高度在 0.435–0.45 m,不把悬在盒上方算成功。

  3. 已经释放

    夹爪打开、与物体无接触,且夹爪距物体大于 8 cm。

  4. 持续低速

    线速度 < 0.02 m/s,角速度 < 0.1 rad/s;所有条件连续满足 10 步。

每个控制步为 0.04 秒,连续 10 步对应 0.4 秒的检查窗口。最多 250 步;超时计失败,不从分母中删除。

底部高度与低速是这个固定场景的教学判据,不是接触支撑力证明,也不是安全认证。默认 Fetch 的目标距离奖励不要求这套入盒合同,因此这里的成功率不能当作官方 Fetch 基准成绩。

02 · 让训练与执行使用同一接口

学到的是观察到动作的映射,不是示范器阶段

示范器是手写的阶段控制程序:靠近、下降、闭合、提起、搬运、降低、松开、撤离。它负责提供训练标签,不是模型内部的隐藏答案。学习策略看不到阶段编号,也不调用示范器来补出正常动作。

  1. 物理示范

    采集 80 条完整训练轨迹,保存观察、专家动作和回合 ID。

  2. 构造历史

    当前及过去共四帧观察,拼接上一动作;每回合独立清空历史。

  3. 监督回归

    64 棵极端随机树共同预测四维动作;固定随机种子与依赖。

  4. 闭环执行

    预测动作改变环境,下一次读取新状态;不是回放训练轨迹。

行为克隆(Behavior Cloning,BC)是一种训练方式。本项目用树集成实现,既不是神经网络,也不是视觉—语言—动作模型。
xt=[ot−3,g; ot−2,g; ot−1,g; ot,g; at−1]∈R116x_t=[o_{t-3},g;\ o_{t-2},g;\ o_{t-1},g;\ o_t,g;\ a_{t-1}]\in\mathbb R^{116}
每帧仿真观察 o 为 25 维,目标 g 为 3 维,前一动作 a 为 4 维:4×(25+3)+4=116。回合开头用初始观察补齐历史,前一动作为零;没有使用未来帧。

观察包含夹爪和物体位置、相对位置、夹爪开度、物体姿态及速度等。它们由仿真器直接提供,属于特权状态。真实相机不会自动吐出这些精确数值;替换为视觉输入需要增加感知、标定、遮挡处理与误差评估,不能只把输入名称改成“图像”。

动作的前三维是归一化末端位移命令,Fetch 内部再乘以 0.05;第四维控制夹爪。底层采用 mocap 约束接口,不是直接电机电流,也不是通用真机驱动。ExtraTreesRegressor(极端随机树集成回归器)以多棵树预测的平均值输出连续动作,适合在这个小型状态任务中展示完整学习链路;这不构成它优于机器人神经策略的结论。

03 · 从源码重建实验

数据可以重采,模型可以重训,结果可以逐回合核对

下载完整源码、依赖锁与实验报告 ZIP。解压后进入 robot-pick-place 目录,用 Python 3.11 或 3.12 和 uv 运行以下命令。不需要 API Key,也不连接真实机械臂。

uv sync --frozen
uv run --frozen python -m unittest test_project -v
uv run --frozen python pipeline.py collect
uv run --frozen python pipeline.py train
uv run --frozen python pipeline.py evaluate --split validation
# 冻结模型与规则后,再运行独立测试
uv run --frozen python pipeline.py evaluate --split test --policy expert
uv run --frozen python pipeline.py evaluate --split test
uv run --frozen python pipeline.py evaluate --split test --stress grip-release
uv run --frozen python pipeline.py evaluate --split test --policy bc-recovery --stress grip-release

environment.py 定义物理环境与成功判据;pipeline.py 负责采集、训练和评测;test_project.py 检查回合隔离、历史特征、碰撞几何和成功边界。生成的数据与模型保存在 runs/,下载包内 evidence/ 是本次留存报告,不会被当作新运行结果。

训练集使用种子 100–179,验证集为 1000–1019,测试集为 2000–2049;按整条轨迹划分,不把相邻帧随机分进训练和测试。验证用于开发,冻结策略后才测试。报告记录模型与源码哈希,防止把旧结果与新代码拼在一起。

版本与运行边界

本次实际运行环境为 macOS Apple Silicon、Python 3.11.14、Gymnasium-Robotics 1.4.2、MuJoCo 3.3.7;其余版本见 uv.lock。最初解析到 MuJoCo 3.16.0 时原版 Fetch 也出现初始化失败,因此固定已验证版本。其他操作系统尚未实测。训练不要求显示窗口;添加 --render 可输出首个回合的实际画面,但需要可用的 OpenGL 上下文。只加载自己训练或信任的 Joblib 模型文件。

04 · 2026-10-20 本地实验

正常场景里的满分,挡不住一次没练过的掉落

80 条训练示范共 6,550 步,20 条验证示范共 1,638 步。验证动作均方误差约 0.000528,度量的是归一化动作标签误差,不是米制位置误差,也不是成功概率。下面是独立 50 个测试种子上的闭环结果;四组使用同一组初始位置种子。

控制方案条件成功 / 全部回合干扰回合脚本恢复回合
脚本示范器正常50 / 5000(全程脚本)
学习策略 BC正常50 / 5000
学习策略 BC提起后强制松手0 / 50500
BC + 一次脚本恢复提起后强制松手50 / 505050

验证集三种对应设置分别为 20/20、0/20、20/20。测试使用新的回合种子,但仍来自相同的位置分布;不是新物体、新光照、新容器或新机器人上的泛化。50 次全部成功也不等于真实成功概率为 100%:在独立同分布的二项假设下,95% Wilson 区间约为 92.9%–100%;0/50 对应约 0%–7.1%。这些区间不覆盖未测试的分布变化。

查看汇总及哈希;逐回合判据、物体位置和恢复步数在下载包 evidence/ 内。不要只截取成功演示而隐藏失败组。

05 · 明确谁在恢复

补上系统恢复,不等于模型自己学会恢复

干扰在物体首次提起、尚未移到盒子上方时触发:连续 12 步暂停平移并张开夹爪,共 0.48 秒。我们只覆盖控制命令,不修改物体状态。学习策略随后仍根据自己的观察运行,但测试中未能在时限内完成入盒。

仿真中方块仍在盒外,机械臂停留在方块附近
实际仿真:验证种子 1000,BC 遭遇松手干扰后,第 250 步超时。方块未入盒。
仿真中方块已落在蓝色容器内,夹爪张开并撤离
同一验证种子与干扰:加入一次脚本恢复,第 122 步满足入盒条件。不是生成图,也不是真机照片。
  1. 记住已提起

    观察到物体高度超过 0.55 m,记录曾进入搬运阶段。

  2. 检测掉落迹象

    物体回到低位、位于容器前方且远离夹爪;不声称已证明落稳。

  3. 一次脚本接管

    重新执行接近、抓取、搬运和释放;不重置环境或物体位置。

  4. 同一判据验收

    仍检查完整入盒、释放与持续低速;第二次失败不无限重试。

恢复分支使用特权状态与人工规则,最多切换一次。报告中 50 次恢复都应计入脚本接管,不能把这组成绩归到纯学习策略名下。

这个对比说明:成功示范覆盖了正常路径,却没有充分覆盖掉落后的状态;一个边界明确的恢复模块能改善整个系统,但不会自动改变模型本身。若要研究“学会恢复”,应另行采集纠正示范、训练新策略,并保留新的独立测试集,不能用本轮测试继续调参后还称完全未见。

06 · 把小实验放回大系统

跑通这一盒,不代表具备通用操作能力

本实验不包含视觉感知、自然语言指令、动态避障、跨物体迁移或真机安全控制。盒子宽、物体规则、状态精确、任务固定,都是范围限定,不应该藏在“自主完成”的标题后面。仿真接触参数也不等于真实材质;未来接入硬件前,需要独立标定、时延测量、限位限力与停止机制。

当前只支持这里的行为克隆流程。继承的 GoalEnv 目标奖励重算仍遵循原 Fetch 语义,不能直接拿来做 HER(Hindsight Experience Replay,事后经验回放)训练:本文终止条件依赖接触、速度和连续历史,不是目标坐标一项就能重算。

继续实验时,每次只改变一个因素并重新定义证据:先改变初始位置范围,再研究物体质量与摩擦;然后加入带误差的感知,最后才讨论真实机器人。不能把新增场景失败简单归因于“模型不够大”。

回到六个专栏:坐标与运动学解释动作空间;标定解释视觉接口缺口;模仿学习解释分布偏移;物理仿真解释接触;失败恢复解释状态与接管;机器人评测解释分母与不确定性。也可以返回具身智能总览。

RESEARCH LEDGER

一手来源与证据边界

优先使用论文、官方文档、官方模型卡和代码仓库。页面中的数字只代表来源所述设置,不自动外推到其他模型与数据。