很多团队以为“通用操作”靠一个更大的模型就能突然出现,但真到人形机器人落地时,决定成败的通常不是模型参数,而是任务拆解是否清楚、示教数据是否可复现、行为编排是否可回放,以及人工接管链路是否足够稳定。这篇文章想解决的,就是怎么把“会抓几个 demo”升级成“能持续扩技能、能排错、能上线验证”的人形机器人操作能力栈。适合已经在做双臂、人形上肢、灵巧操作或 teleop 数据采集的团队。最关键的工程判断是:先把通用操作拆成可编排的技能家族,再决定哪些部分交给策略学习,哪些部分必须保留显式约束和人工兜底。
这篇适合谁
- 正在做人形机器人上肢操作、双臂协作、工位取放、整理、插接、折叠这类任务的团队
- 已经有遥操作或示教系统,但数据质量、复现性、策略上线成功率不稳定的团队
- 想把“技能演示”升级成“技能库 + 调度层 + 回放验证”的工程化体系,而不是继续堆单点 demo 的团队
先纠正几个很常见的误区
- 误区 1:通用操作 = 端到端大模型直接控全身。
真实工程里,越接近执行器、接触、夹持和安全边界的层,越不该全部交给黑箱策略。任务层可以学,底层约束和接管边界要写清楚。 - 误区 2:示教越多越好。
没有统一 episode 结构、时序对齐、失败标签和回放工具,再多示教也只是堆垃圾数据。 - 误区 3:抓取成功率高,就说明操作系统搭好了。
真正要看的是跨物体、跨工位、跨视角、跨延迟扰动时,系统还能不能稳定恢复。 - 误区 4:行为编排只是“业务逻辑”,晚点再补。
如果没有清晰的任务图、前置条件、失败出口和人工接管点,你后面几乎没法做可靠排错。
关键实现判断
如果你想让人形机器人持续学会新的操作任务,不要先追求“一个大脑统治全部动作”,而要先把系统分成四层:
- 任务层:负责任务目标、工位上下文、前置条件、异常出口。
- 技能层:负责到达、对齐、抓取、插入、放置、整理、开关门、双臂配合等可复用技能。
- 执行层:负责轨迹、接触、力限、速度限、碰撞边界、控制模式切换。
- 监督层:负责人工接管、日志回放、失败归因、版本冻结和回滚。
这四层没分清楚,所谓“通用操作”大概率只是一个很脆的长脚本。分清楚了,你才能知道哪些问题该补数据,哪些问题该改规划,哪些问题其实是控制或夹具设计问题。
分步实践指南
第 1 步,先定义“任务家族”,不要空谈通用
建议先把目标限制在 3 到 5 个共享操作原语的任务家族里,比如:
- 抓取 + 搬运 + 放置
- 双手整理 + 定位 + 插接
- 开门 / 抽屉 + 取物 + 复位
- 料箱分拣 + 朝向调整 + 上料
每个任务家族都要写清楚:
- 开始条件是什么
- 成功结束条件是什么
- 允许哪些姿态误差和接触误差
- 哪些情况必须停机或请求接管
这一步做不好,后面很容易出现“训练集里看起来像一个任务,现场其实是十种不同问题”的混乱。
第 2 步,把技能接口冻结,而不是把 demo 录满
先给每个技能定义稳定接口,再去录数据。一个可用的技能接口至少要有:
- 输入:目标位姿、目标区域、目标物体类别、当前工位上下文、手爪状态
- 输出:成功 / 失败、失败原因、末端位姿误差、接触状态、耗时、是否需要人工介入
- 前置条件:例如相机外参已校准、目标已分配 ID、夹爪已打开、腰部姿态在允许范围内
- 终止条件:超时、力矩异常、对象丢失、视觉置信度过低、路径不可达
MoveIt Task Constructor 的价值就很适合拿来做这里的工程参照。它把复杂操作拆成可串联的 stage,不同 stage 之间明确传递状态,适合把“靠近目标、生成抓取位姿、闭合夹爪、撤离、放置”这类过程拆开,而不是全写成一个不可调试的大节点。对于人形机器人来说,这种“先拆清阶段,再给每阶段选 planner 或策略”的思路,比直接堆端到端动作更稳。
第 3 步,先把遥操作链路做成“高质量示教工具”,不是表演工具
很多团队做遥操作时太在意“操作者看起来酷不酷”,却忽略三个更重要的指标:
- 示教动作是否能稳定复现到机器人坐标系
- 操作者能不能及时感知遮挡、深度和接触前状态
- 整条链路的延迟、抖动和丢包会不会污染数据
Open-TeleVision 的做法值得参考,它强调沉浸式主动视觉反馈,并把操作者上肢动作直接映射到机器人,目标不是做炫技遥操作,而是提升长时程、精细任务的数据质量。对人形平台来说,这给了一个很实际的提醒:示教系统首先是数据生产设备,其次才是远程操控界面。
我更建议你在示教链路里强制记录这些字段:
- 双臂 / 末端 / 头部 / 腰部目标与实际状态
- 视觉帧时间戳、控制指令时间戳、执行确认时间戳
- 接触或夹持相关事件
- 操作员脚踏开关 / 模式切换 / 接管触发事件
- 任务阶段标签和失败标签
如果没有这些,后续你几乎没法判断策略失败到底是学得不行,还是示教本身就不稳定。
第 4 步,把“会做动作”与“知道何时做”分开
行为编排层不要偷懒。真正上线时,最常见的问题不是技能本身做不出来,而是做的时机不对、重试顺序不对、异常出口不对。
BehaviorTree.CPP 是一个很好的工程参照,因为它把反应式行为、非阻塞动作、逻辑与实现分离、状态记录和回放都当成一等公民。对人形机器人操作来说,这意味着:
- 技能节点可以单独调试和替换
- 视觉丢失、抓取失败、插入未对齐可以走不同恢复分支
- 人工接管可以作为树上的显式节点,而不是临时补丁
- 可以回看每次任务到底卡在哪个条件判断上
一个务实的原则是:策略负责“怎么做得更柔顺、更泛化”,行为树负责“现在该不该做、失败后退到哪一步、何时请求人工接管”。
第 5 步,让策略学习只吃它真正该吃的问题
如果你在做人形操作策略,最容易犯的错误是把所有不稳定都推给训练。其实很多问题应该先在系统层剥离:
- 目标定位飘,是感知和标定问题
- 接触瞬间震荡,是控制和顺应性问题
- 双臂打架,是时序和约束问题
- 阶段切换混乱,是编排问题
真正适合交给策略的,是局部接触细节、视觉到动作的泛化映射,以及在小范围扰动下的动作修正。Humanoid Manipulation / iDP3 的项目页很有参考价值,它明确把系统分为机器人平台、数据采集、学习方法、真实部署四部分,而不是假装一套模型能独自解决全部问题。它还特别指出,移动平台上的 3D 视觉动作策略很容易受相机标定和点云分割质量限制,这正是很多人形项目会踩的坑。
第 6 步,把失败样本当成主资产,而不是副产品
建议你从第一天起就建立失败桶,而不是只记成功率。至少分成这几类:
- 目标没看见
- 目标看见了但抓空
- 抓住了但姿态不对
- 接触太猛导致目标偏移
- 双臂或手-环境发生几何冲突
- 阶段切换错误
- 超时或人工接管
每周回看失败桶时,不要只看视频,要同时看任务阶段、控制模式、延迟曲线、感知置信度、末端误差和 operator intervention 事件。这样你才能知道下一轮该补哪种数据,还是该先改技能边界。
第 7 步,先做“可验证的技能升级”,不要直接追求无边界泛化
每次升级一个技能版本,至少要做四组验证:
- 基准组:原工位、原物体、原光照
- 扰动组:轻微位姿变化、轻微遮挡、轻微延迟
- 跨实例组:同类不同尺寸或材质物体
- 恢复组:故意制造抓偏、碰撞前停、目标短时丢失、临时接管
验证不该只给一个总成功率,而要给:
- 任务成功率
- 每个阶段成功率
- 平均重试次数
- 人工接管率
- 平均恢复耗时
- 严重失败率(可能伤物、伤夹具、伤环境)
如果这些指标没有变好,就不要急着让新策略上主线。
现场 first-look 决策表:通用操作一乱,先压回哪一层
通用操作系统出问题时,第一反应不要是“模型还不够通用”。很多现场失败,其实先坏在任务家族定义、示教质量、技能接口、接触约束、部署对齐或回放证据上。先用这张表把问题压回第一责任层,再决定要不要继续训练、扩数据或改策略。
| 现场先看到什么症状 | 第一怀疑层 | 先拉哪几类信号 / 证据 | 今天先不要继续做什么 |
|---|---|---|---|
| 单个物体或单次 demo 能过,换同类物、工位角度或起始姿态就失败 | 任务家族 / 成功判据层 | 任务脚本、对象集合、起止状态、允许扰动、阶段成功率、失败桶分布 | 不要先宣布“通用操作能力成立”,也不要继续扩更多任务家族 |
| 遥操作数据很多,但训练后策略学到犹豫、绕路、硬拽或临时修正 | 示教质量 / episode 合同层 | 操作者 ID、控制模式、时延、阶段标签、接管点、失败标签、成功样本筛选规则 | 不要把所有最终成功片段都当正样本,也不要靠再采一批数据掩盖脏示教 |
| 技能库和行为树越来越长,但任务一失败就卡在中间收不回来 | 技能接口 / 编排恢复层 | 技能前置条件、后置条件、超时、取消事件、fallback 节点、人工接管入口 | 不要继续把任务链写长,也不要让策略学习去补技能接口的空洞 |
| 抓取成功率看着更高,但夹具、物体、桌面或人机边界的代价变大 | 执行约束 / 接触包线层 | 力矩、接触力、滑移、物体损伤、碰撞前停、急停 / 接管次数、恢复耗时 | 不要只报平均成功率,也不要用放宽接触阈值换一个更好看的结果 |
| 离线回放或仿真里很好,真机上线后动作总是慢半拍或偏一点 | 观测-动作对齐 / 部署边界层 | 相机与末端坐标、时间戳、控制延迟、策略版本、仿真参数、真实工位配置差异 | 不要先怪模型泛化差,也不要在时序和坐标没对齐前继续加数据 |
| 失败后只剩现场视频,没人说清是哪一版策略、哪个节点、哪次接管出了问题 | 回放证据 / 版本归因层 | episode ID、模型版本、行为树节点、日志包、接管事件、失败标签和统一时间线 | 不要靠会议印象决定版本晋级,也不要在证据链断掉时合并新策略 |
如果第一轮证据还不能把问题压到其中一层,就先把这次运行记成 scouting。不要急着把它归因成“大模型不够强”或“数据还不够多”。通用操作最怕的不是慢一点,而是在错误层上越修越像进展。
最容易翻车的地方
- 把“单任务学会”误判成“任务家族可迁移”。 只在一个桌面、一个光照、一个操作员数据上有效,不能算系统能力。
- 示教坐标系不稳。 头显、手部、机器人本体、相机坐标一旦有漂移,后续训练和回放都会被污染。
- 跳过中间表示。 没有阶段标签、事件标签、失败标签,后面根本无法精确补数据。
- 把人工接管当例外。 真正可落地的人形操作系统,一开始就应该把接管、回退和任务中止设计进去。
- 忽略操作员负担。 如果一个示教系统 20 分钟就让操作员疲劳,数据质量通常也会很快下滑。
怎么验证你真的搭对了
我会看下面这张“最小可用判据表”是否成立:
- 同一技能在 3 个以上工位或场景变体中能复现
- 失败能稳定落入已有失败桶,而不是出现大量“说不清为什么”的坏例
- 能从一次线上失败追溯到对应 episode、对应模型版本、对应行为树节点和对应接管事件
- 升级后的成功率提升,不是靠放宽人工接管或缩小测试条件换来的
- 操作员、算法、控制、集成四类问题能被分开归因
如果你现在还做不到最后两条,那系统大概率还停留在“能演示”,还没有进入“能工程迭代”。
下一步怎么做
- 先挑一个任务家族,写出技能接口表和失败桶定义
- 把现有 teleop 数据链路补齐时间戳、阶段标签和接管事件
- 给任务流加上显式行为编排层,不再让脚本和策略互相缠在一起
- 只选 1 到 2 个最值得学的技能做策略升级,别一口气全学
- 建立固定的回放评审节奏,每周复盘失败样本,而不是只看成功 demo
延伸阅读 / Sources
- MoveIt Task Constructor 官方文档
- BehaviorTree.CPP 官方文档
- Open-TeleVision 项目页
- Generalizable Humanoid Manipulation with 3D Diffusion Policies 项目页