yaml
论文: HYPERmotion: Learning Hybrid Behavior Planning for Autonomous Loco-manipulation
作者: Jin Wang, Rui Dai, Weijie Wang, Luca Rossini, Francesco Ruscelli, Nikos Tsagarakis
机构: 意大利技术研究院 (IIT) + 热那亚大学
arXiv: 2406.14655 [cs.RO], 2024-06-20
项目主页: https://hy-motion.github.io/
关键词: 人形机器人、Loco-manipulation、LLM 任务规划、VLM 形态选择、强化学习、全身轨迹优化、行为树
一、介绍:人形机器人的"会走"和"会干活"之间,隔着一整个工程学
先说人话版的一句话总结:这篇论文给一台半人马造型的四足轮腿人形机器人(38 个自由度)装上了一整套"大脑---小脑---脊髓"分层系统------LLM 负责想(把一句自然语言拆成任务图)、VLM 负责选(单臂还是双臂、轮子还是腿)、强化学习负责练(把每个技能练成肌肉记忆存进动作库)、全身优化负责兜底(保证练出来的动作物理上真能做)------最终让机器人听懂一句"把抽屉打开、拿起电钻、放进盒子、交给那位同学",然后零样本在线规划、真实世界里把它干完。
搞视频编码的人对这个分层结构应该有天然的亲切感。你想想 x265 的码控体系:顶层 EncGOP 做 GOP 级和帧级的码率分配与场景切换决策,中层做 CTU 级的 RDO,底层还有 SAO/ALF 这类"保证画质不崩"的修复模块------每一层只做自己尺度上的事,靠明确的接口往下传约束。HYPERmotion 的架构几乎是同构的:LLM 是 GOP 级决策器(决定这一段"序列"怎么组织),技能库里的 RL 策略是帧级编码器(每个原子动作各司其职),全身优化器则像环路滤波一样,把上游输出"投影"回物理可行的流形上。下面这张对应表你可以先留着,读完全文再回来看,会发现严丝合缝:
| 视频编码器 | HYPERmotion | 职责 |
|---|---|---|
| GOP 级决策(EncGOP) | LLM 任务规划器 | 长时程分解、场景判断、调度 |
| 帧级编码(RDO) | RL 技能策略 | 单个原子任务的"最优执行" |
| 环路滤波(ALF/SAO) | 全身轨迹优化 | 把理想输出投影回"可行域" |
| 码率/失真约束 | 动力学等式/不等式约束 | 硬性物理边界,谁也不能越 |
| 参考帧管理 | 动作库(Motion Library) | 存储可复用的"已编码知识" |
1.1 问题定义:为什么这事难
论文要解决的任务叫 loco-manipulation(移动操作)------一边挪窝一边干活。固定基座的机械臂做操作已经卷了十几年,但人形机器人加上一个会漂移的浮动基座(floating base),问题复杂度是指数级上涨的:
- 自由度爆炸:38 个可驱动关节。直接对全身做端到端 RL,训练成本和 sim-to-real 难度都会失控。这就像你不可能对 8K 全帧直接做全搜索运动估计------必须分层、必须降维。
- 技能泛化困境:现有的学习型控制器大多是"一任务一策略",学会开门就不会开抽屉,组织不起来长时程技能序列。相当于你只有 I 帧没有 P/B 帧------每个画面都从头编,效率低到没法看。
- LLM 落地的"最后一公里":用 LLM 做机器人规划的工作不少(Code as Policies、SayCan 等),但几乎都停在固定机械臂或纯仿真。放到有复杂动力学约束的人形机器人上,LLM 压根不懂"这个动作我的膝盖够不够得着、会不会摔"。
1.2 论文的三个核心贡献
- 分解式训练 + 统一运动生成器 :RL 只训上半身相关的低维动作空间(单臂 14 维 / 双臂 19 维),再用基于全身动力学约束的轨迹优化把低维轨迹"投影"回 93 维全身空间------学的东西简单了,做出来的动作还是全身协调的。
- 动作库(Motion Library):把训练好的技能连同属性/功能描述一起存档,LLM 不需要任何额外训练或示教就能检索、编排这些技能,生成层级任务图(task graph),再翻译成行为树(Behavior Tree)执行。
- 具身形态选择器(Morphology Selector):用 VLM 融合 2D 图像 + 深度蒸馏出来的空间几何特征 + 机器人自身能力描述(affordance),零样本决定操作用单臂还是双臂、移动用轮子还是腿。
二、原理:四大模块如何"接力干活"
整个系统按论文 Figure 2 的画法分为四个相互咬合的扇区。我们一个一个拆。
2.1 运动生成扇区:RL 练"小肌肉",优化器管"大身体"
这是全篇工程上最扎实的部分。核心洞察是一句话:直接在仿真里训全身轨迹输出,既低效又不现实------那就只训有用的部分,剩下的交给优化器。
具体做法是把机器人"拆"开训:
- 单臂任务 (开抽屉、开门、单臂抓取):动作空间 A 1 ⊆ R 14 \mathcal{A}_1 \subseteq \mathbb{R}^{14} A1⊆R14------右臂 6 关节角 + 浮动基座的 6 维平移/欧拉角 + 1 个躯干 yaw + 1 个夹爪开合。左臂全程固定。
- 双臂抓取 :动作空间 A 2 ⊆ R 19 \mathcal{A}_2 \subseteq \mathbb{R}^{19} A2⊆R19,加上左臂 6 关节,夹爪关节闭合(抱箱子嘛,夹爪张着没意义)。
这里有个非常"编码器思维"的细节:浮动基座的运动被启发式地限死了 (heuristically limited)。为什么?因为如果你让 RL 随便浪,它可能学出一个下半身根本接不住的动作------就像运动估计里如果搜索范围不设限,MV 会指向参考帧外一样,你必须用约束把搜索空间框在"可补偿"的范围内。RL 输出的只是上半身 20 维关节位置轨迹 q ∗ ∈ R 20 q^* \in \mathbb{R}^{20} q∗∈R20,这是一个参考轨迹(reference),不是最终指令。
然后轮到全身轨迹生成器出场。论文用的是 IIT 自家的 Horizon 轨迹优化框架,把参考轨迹作为代价函数里的跟踪目标,在完整全身动力学约束下重新求解一条物理可行的全身轨迹。这一步在编码里的对应物太形象了:RL 策略像码率控制给出的"理想 QP",而全身优化是真正执行量化决策的模块------理想 QP 可能要求超过带宽(超过关节力矩/速度极限),最终都要被约束"打回原形"。
训练全部用 PPO (毕竟是腿足 RL 的事实标准),在 Isaac Gym 里大规模并行训练,再用 Gazebo 验证规划出的全身运动。
2.2 动作库:给每个技能写一份"API 文档"
技能练完了不能散装堆着。动作库里每个技能单元包含两部分:
- 学习型全身策略本身(网络权重 + 执行代码);
- 属性与功能描述("我能开抽屉""我需要目标物 6D 位姿""我输出的是单臂动作")。
第二部分才是灵魂------它是喂给 LLM 的"函数签名 + docstring"。LLM 做规划时,本质上是在对这些技能做一次受限的函数调用编排。这也是为什么论文反复强调"LLM 不再需要考虑自碰撞或平衡约束":那些脏活累活全被封装进技能内部了,LLM 只管语义层面的调度。这个设计哲学和好的编码器抽象一模一样------上层模块不需要知道熵编码内部怎么 context modeling 的。
2.3 形态选择器:VLM 当"现场指挥官"
人伸手开一扇门之前,脑子里已经完成了"这扇门往哪开、我该用哪只手、要不要侧身"的几何推理。论文想复刻的就是这个决策过程,用 VLM 实现,分操作和移动两条通路:
操作形态选择 :头部 D435i 深度相机拍 2D 图像 + 深度 → 调用目标检测与 6D 位姿估计(FoundationPose / DOPE)拿到目标物体位姿 v c ∈ R 6 v_c \in \mathbb{R}^6 vc∈R6 → 变换到机器人坐标系 v R ∈ R 6 v_R \in \mathbb{R}^6 vR∈R6 → VLM 综合(任务状态 s s s、头部场景图 I s c e n e h I^h_{scene} Isceneh、目标 6D 位姿、机器人能力描述 prompt p V p_V pV)输出操作形态 x m x_m xm:
x m = V ( s , I s c e n e h , v R , p V ) x_m = V(s, I^h_{scene}, v_R, p_V) xm=V(s,Isceneh,vR,pV)
比如"捡起那块饼干"------饼干很轻很小,VLM 应该输出单臂;"把箱子搬到桌上"------箱子太大,输出双臂。
移动形态选择 :骨盆深度相机生成点云 P c P_c Pc → 下采样成体素网格 V g V_g Vg(这一步就是"蒸馏空间几何")→ 和路面场景图 I s c e n e p I^p_{scene} Iscenep、任务状态一起喂给 VLM,输出移动形态 x l x_l xl:
x l = V ( s , I s c e n e p , V g , p V ) x_l = V(s, I^p_{scene}, V_g, p_V) xl=V(s,Iscenep,Vg,pV)
比如平地就走轮式(快、稳),遇到有台阶/障碍的复杂地形就切腿式。
这里的关键设计是"具身知识接地"(grounding) :prompt p V p_V pV 里写了机器人自己的结构描述------"半人马造型、四条腿、每条腿底下一个轮子、右臂有夹爪、默认形态是单臂+轮式"。VLM 不是在真空里做选择题,它是拿着这台机器人的"体检报告"在做决策。
2.4 任务规划扇区:LLM + 行为树 = 语义到动作的翻译器
整个链路是:自然语言指令 → LLM 生成层级任务图(XML)→ 构建成行为树(BT)→ BT 节点调度技能执行。
用户输入(User Input)模块由三块组成,这是 prompt 工程的教科书式架构:
- Basic Prompts:机器人背景设定 + 输出格式约束。原文直接要求"输出一个 XML 文件用于构建行为树",并交代机器人身体结构。
- Motion Library:技能目录及其功能描述,相当于 API 清单。
- Function Options :可选功能开关,默认全关 。包括:
manipulation_mode_selector:往行为树里插<WhetherSingleArm>条件节点;locomotion_mode_selector:插<WhetherWheelMove>条件节点;detection_recovery:插<IsActionSuccess>条件节点,动作失败就重试。
这个"功能开关"设计很妙:任务简单时 prompt 短、规划错误率低;任务复杂时手动把对应功能打开。这是在用规划成功率换系统能力上限,旋钮握在用户手里------和你编码时"要不要开 CTU 级 RDO 精搜"是同一种取舍。
行为树作为中间桥接层的选择也很务实:BT 天然支持条件分支、失败回退、循环重试,LLM 生成的任务图挂载到 BT 节点上,执行层就不需要理解任何语义了。BT 是机器人领域验证了几十年的执行框架,比让 LLM 直接逐步发号施令稳健得多------LLM 负责"一次性把计划想好",BT 负责"逐步执行时不出幺蛾子",职责分离干净利落。
2.5 系统硬件一览(后面拆解要用)
- 本体:半人马造型,人形上半身 + 四条轮腿。全身 38 个可驱动关节。躯干通过 yaw 关节装在骨盆上(上半身可水平转)。每臂 6 DoF,右臂夹爪额外 1 DoF。每条腿 6 DoF,全向轮式 + 关节腿式双模。
- 感知:两个 RealSense D435i 深度相机------头部一个(看物体),骨盆一个(看路)。
- 计算 :两个车载计算单元负责实时控制(XBot2 中间件 + CartesI/O 优先级 QP 运动控制器),外接一台 i9-13900HX + RTX 4090 的引导 PC 负责 LLM/VLM 推理和感知处理。
- LLM/VLM:GPT-4o 做规划器,GPT-4V 做形态选择器(OpenAI API)。
注意最后一条------大脑在体外。这个细节踩坑点部分会回来鞭尸。
三、公式:把论文的数学骨架一根根抽出来
3.1 RL 奖励函数(公式 1)
所有技能共用一个通用奖励骨架:
r = α 1 r l _ r e a c h + α 2 r r _ r e a c h + α 3 r r o t + α 4 r f i n g e r + α 5 r t a s k + α 6 r p e n a l t y r = \alpha_1 r_{l\reach} + \alpha_2 r{r\reach} + \alpha_3 r{rot} + \alpha_4 r_{finger} + \alpha_5 r_{task} + \alpha_6 r_{penalty} r=α1rl_reach+α2rr_reach+α3rrot+α4rfinger+α5rtask+α6rpenalty
逐项拆:
(1)末端到达奖励。左右手各自的"够到目标"奖励:
r l _ r e a c h = ( 1 1 + d l 2 ) 2 , r r _ r e a c h = ( 1 1 + d r 2 ) 2 r_{l\reach} = \left(\frac{1}{1 + d_l^2}\right)^2, \quad r{r\_reach} = \left(\frac{1}{1 + d_r^2}\right)^2 rl_reach=(1+dl21)2,rr_reach=(1+dr21)2
其中 d l , d r d_l, d_r dl,dr 是操作目标到左/右末端执行器的距离。这个形式值得品一下: 1 / ( 1 + d 2 ) 1/(1+d^2) 1/(1+d2) 本身是平滑单调递减的"距离场",外面再套平方,等于在近距离区间的梯度被进一步拉伸------离目标越近,奖励梯度越陡,策略被"吸"向目标的力越强 。做过 reward shaping 的都知道,这比朴素的 − d -d −d 好在:远处梯度太平会学不动,近处不加密会来回震荡。这个设计是"远松近紧"的经典形态,跟运动估计里分级搜索(先粗后精)的思路暗合。
(2)夹爪姿态对齐奖励:
r r o t = sign ( d x ) ⋅ d x 2 + sign ( d z ) ⋅ d z 2 r_{rot} = \text{sign}(d_x) \cdot d_x^2 + \text{sign}(d_z) \cdot d_z^2 rrot=sign(dx)⋅dx2+sign(dz)⋅dz2
d x d_x dx、 d z d_z dz 分别是夹爪 forward 轴与物体内向轴、夹爪 up 轴与物体 up 轴的点积。点积衡量轴对齐程度:对齐时点积接近 ±1。带符号的平方意味着------轴完全反了(点积 -1)惩罚最大,完全对齐(+1)奖励为零代价。直观理解:它逼着夹爪"手心对着把手、手背朝天",不同任务的物体坐标系在附录里定义得明明白白(抽屉把手 x 轴指向机器人、z 轴朝上;抓取任务的物体"向上方向沿 -x 轴"------这是逼夹爪从上往下抓)。
(3)夹爪包络奖励:
r f i n g e r = β − ( d t + d b ) r_{finger} = \beta - (d_t + d_b) rfinger=β−(dt+db)
d t , d b d_t, d_b dt,db 是夹爪上/下指连杆到物体的距离, β \beta β 是与操作物体尺寸相关的微调参数(附录里各任务 β \beta β 从 0.02 到 0.1 不等)。这个奖励的语义是"两张手指把物体夹在中间"------只有 d t d_t dt 和 d b d_b db 同时小,物体才真的在夹爪中间。抓取任务里还有一个配套条件奖励 r a r o u n d r_{around} raround:只有当夹爪上指节在把手之上、下指节在把手之下时才给 0.5 分,否则 0------典型的稀疏条件奖励,防止策略学会"贴着物体蹭"的作弊解。
(4)动作惩罚:
r p e n a l t y = − ∥ a ∥ 2 r_{penalty} = -\|a\|^2 rpenalty=−∥a∥2
L2 惩罚抑制过大动作,保证运动平滑。经典操作,不多解释------但注意权重 α 6 \alpha_6 α6 只有 0.01,作者非常克制:惩罚太重会让机器人变得畏手畏脚(学过"奖励 hacking 反面教材"的都懂)。
(5)任务特定奖励 r t a s k r_{task} rtask,附录里每个任务都不一样:
- 开抽屉 (式 A1): r t a s k = α 7 r a r o u n d + l d r a w e r ⋅ r a r o u n d + l d r a w e r r_{task} = \alpha_7 r_{around} + l_{drawer} \cdot r_{around} + l_{drawer} rtask=α7raround+ldrawer⋅raround+ldrawer。 l d r a w e r l_{drawer} ldrawer 是抽屉被拉出的长度。妙在乘法项: r a r o u n d = 0 r_{around} = 0 raround=0 时(没夹对位置)拉动抽屉只有基础分,夹对了拉动才有加倍分------先把姿势摆对,再谈绩效。
- 开门 (式 A2): r t a s k = α 7 r a r o u n d + a n g l e h a n d l e ⋅ r a r o u n d + a n g l e h a n d l e + a n g l e d o o r r_{task} = \alpha_7 r_{around} + angle_{handle} \cdot r_{around} + angle_{handle} + angle_{door} rtask=α7raround+anglehandle⋅raround+anglehandle+angledoor。两级进度:先压把手( a n g l e h a n d l e angle_{handle} anglehandle),再开门( a n g l e d o o r angle_{door} angledoor),天然形成课程学习。
- 单臂抓取 (式 A3): r t a s k = α 7 r a r o u n d + h r_{task} = \alpha_7 r_{around} + h rtask=α7raround+h, h h h 是物体被拿起的 0/1 指示。
- 双臂抓取 (式 A4): r t a s k = h r_{task} = h rtask=h,极简。此时 d l , d r d_l, d_r dl,dr 分别定义为左右末端到物体左右侧的距离, r r o t r_{rot} rrot、 r f i n g e r r_{finger} rfinger 权重直接置零(抱箱子不需要手指精细对齐)。
各任务奖励权重的完整对比(从附录 Table 2/4/6/8 提取):
| 参数 | 开抽屉 | 开门 | 单臂抓取 | 双臂抓取 |
|---|---|---|---|---|
| α 1 \alpha_1 α1(左reach) | 2.0 | 2.0 | 7.5 | 2.0 |
| α 2 \alpha_2 α2(右reach) | 0.0 | 0.0 | 0.0 | 2.0 |
| α 3 \alpha_3 α3(姿态对齐) | 0.5 | 1.5 | 5.0 | 0.0 |
| α 4 \alpha_4 α4(手指包络) | 7.5 | 7.5 | 2.5 | 0.0 |
| α 5 \alpha_5 α5(任务奖励) | 7.5 | 2.0 | 7.5 | 7.5 |
| α 6 \alpha_6 α6(动作惩罚) | 0.01 | 0.01 | 0.01 | 0.01 |
| α 7 \alpha_7 α7(around 条件) | 0.7 | 0.125 | 0.7 | 0.0 |
| β \beta β | 0.04 | 0.02 | 0.1 | 0.0 |
注意 α 2 = 0 \alpha_2 = 0 α2=0 的分布------单臂任务根本不奖励左手,让策略明确"左手别乱动"。而开门任务 α 7 \alpha_7 α7 只有 0.125、 α 3 = 1.5 \alpha_3 = 1.5 α3=1.5:压门把手这个动作姿态对齐比包络更重要。每个任务的权重表就是一份"这个任务的难点在哪"的诊断书,这是 reward engineering 最值得学的部分。
3.2 全身轨迹优化(公式 2 + 附录 A3)
RL 输出的低维轨迹 q ∗ q^* q∗ 怎么变成 38 关节都能执行的全身动作?论文将其建模为非线性最优控制问题(OCP):
min x ( ⋅ ) , u ( ⋅ ) ∫ 0 T L ( x ( t ) , u ( t ) , t ) d t s.t. x ˙ ( t ) = f ( x ( t ) , u ( t ) , t ) g 1 ( x ( t ) , u ( t ) , t ) = 0 g 2 ( x ( t ) , u ( t ) , t ) ≤ 0 \begin{aligned} \min_{x(\cdot), u(\cdot)} \quad & \int_0^T L(x(t), u(t), t)\, dt \\ \text{s.t.} \quad & \dot{x}(t) = f(x(t), u(t), t) \\ & g_1(x(t), u(t), t) = 0 \\ & g_2(x(t), u(t), t) \le 0 \end{aligned} x(⋅),u(⋅)mins.t.∫0TL(x(t),u(t),t)dtx˙(t)=f(x(t),u(t),t)g1(x(t),u(t),t)=0g2(x(t),u(t),t)≤0
变量定义:
- 状态 x ( t ) = q , v ∈ R 93 x(t) = q, v \in \mathbb{R}^{93} x(t)=q,v∈R93:广义坐标 + 广义速度,一共 93 维(38 关节 + 浮动基座 6 DoF + 各自的速度)。
- 输入 u ( t ) = v ˙ , f c ∈ R 58 u(t) = \\dot{v}, f_c \in \mathbb{R}^{58} u(t)=v˙,fc∈R58:广义加速度 + 足端接触力。
- 等式约束 g 1 g_1 g1:全身动力学方程------这是硬约束,保证解出来的轨迹在物理上成立。
- 不等式约束 g 2 g_2 g2:关节极限、速度极限、接触力的单边性(脚只能推地不能拉地)。
中间代价:
L ( x , u , t ) = ∥ q u − q ∗ ∥ 2 + ∥ u ∥ 2 L(x, u, t) = \|q_u - q^*\|^2 + \|u\|^2 L(x,u,t)=∥qu−q∗∥2+∥u∥2
第一项让全身解尽量贴着 RL 给的上半身参考轨迹 q ∗ q^* q∗,第二项是能量正则。这个结构和视频编码里的"率失真优化"完全同构 : ∥ q u − q ∗ ∥ 2 \|q_u - q^*\|^2 ∥qu−q∗∥2 是失真项 D(你偏离参考要付出画质代价), ∥ u ∥ 2 \|u\|^2 ∥u∥2 是码率项 R(你消耗的能量要付出代价), λ \lambda λ 加权折中------只不过这里 λ 隐含在量纲归一里。
附录 A3 给了数值求解的离散化:把连续问题转成 N 节点的 NLP:
J = ∑ i = 0 N L i ( x i , u i ) x ˙ i = f ( x i , u i ) , i = 0 , ⋯ , N C m i n ≤ C ( x i , u i ) ≤ C m a x , i = 0 , ⋯ , N \begin{aligned} J &= \sum_{i=0}^{N} L_i(x_i, u_i) \\ \dot{x}i &= f(x_i, u_i), \quad i = 0, \cdots, N \\ C{min} &\le C(x_i, u_i) \le C_{max}, \quad i = 0, \cdots, N \end{aligned} Jx˙iCmin=i=0∑NLi(xi,ui)=f(xi,ui),i=0,⋯,N≤C(xi,ui)≤Cmax,i=0,⋯,N
具体约束包括(式 A8,这是全篇工程含金量最高的约束清单):
- 初始条件: q 0 = q i n i t q_0 = q_{init} q0=qinit, v 0 = 0 v_0 = 0 v0=0(从静止的当前姿态出发);
- 位置/速度/加速度边界: q m i n k ≤ q k ≤ q m a x k q_{min}^k \le q^k \le q_{max}^k qmink≤qk≤qmaxk 等三组, ∀ k ∈ 1 , N − 1 \forall k \in 1, N-1 ∀k∈1,N−1;
- 足端接触力约束 : f c , i z , k ⋅ n i > 0 f^{z,k}{c,i} \cdot n_i > 0 fc,iz,k⋅ni>0(法向力必须为正------脚踩地只能压不能吸)+ 摩擦锥约束 ∥ ( f c , i x , k , f c , i y , k ) ∥ 2 ≤ μ i 2 ( f c , i z , k ⋅ n i ) 2 \|(f^{x,k}{c,i}, f^{y,k}{c,i})\|^2 \le \mu_i^2 (f^{z,k}{c,i} \cdot n_i)^2 ∥(fc,ix,k,fc,iy,k)∥2≤μi2(fc,iz,k⋅ni)2(切向力不能超过摩擦系数乘以法向力)。
摩擦锥约束是腿足运动不可协商的底线:违反它=脚打滑=摔倒。RL 训练时不管自碰撞(作者明说了,训练期需要上半身和腿之间的碰撞余量,所以让手臂快点伸出去),自碰撞规避完全靠这一步全身优化在约束内投影解决。整个"RL 出参考、优化器保可行"的分工在这里画上了句号。
3.3 形态选择的形式化(公式 3/4)
前面原理部分已经给出: x m = V ( s , I s c e n e h , v R , p V ) x_m = V(s, I^h_{scene}, v_R, p_V) xm=V(s,Isceneh,vR,pV) 和 x l = V ( s , I s c e n e p , V g , p V ) x_l = V(s, I^p_{scene}, V_g, p_V) xl=V(s,Iscenep,Vg,pV)。这里值得强调的是信息形态的选择本身就是一种特征工程:
- 操作决策喂的是6D 位姿向量 v R ∈ R 6 v_R \in \mathbb{R}^6 vR∈R6------紧凑、精确、低带宽。VLM 判断"单臂还是双臂"需要的是物体尺寸和可达性,一个位姿加上 2D 图像的上下文就够了。
- 移动决策喂的是体素网格 V g V_g Vg------保留空间占用结构。判断"走轮子还是走腿"需要的是地形起伏和障碍物几何,纯 2D 图像会被视觉歧义骗(一张地毯的照片和一片台阶的照片对 VLM 来说可能差不多),深度蒸馏出的体素才是地形判断的硬证据。
实验也证实了这个判断:加空间数据(SD)后移动场景的提升比操作场景更明显(详见效果对比部分)。
四、图示:整个系统一图流
4.1 全局架构(对应论文 Figure 2)
┌─────────────────────────────────────┐
│ 用户输入扇区 │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ Basic │ │ Motion Library │ │
│ │ Prompts │ │ (技能+功能描述) │ │
│ └──────────┘ └──────────────────┘ │
│ ┌──────────────────────────────┐ │
│ │ Function Options (默认全 off)│ │
│ │ · 形态选择器(操作/移动) │ │
│ │ · 失败检测与恢复 │ │
│ └──────────────────────────────┘ │
└──────────────┬──────────────────────┘
│ 自然语言指令 + prompt 组合
▼
┌──────────────────────┐ ┌─────────────────────┐
│ 运动生成扇区 (离线) │ │ 任务规划扇区 (在线) │
│ │ │ │
│ Isaac Gym 并行 RL │ │ LLM (GPT-4o) │
│ (PPO, 分解动作空间) │ │ 层级任务图 (XML) │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ 上半身参考轨迹 q* │ 存入 │ Behavior Tree │
│ │ ├───────▶ │ (调度+条件分支) │
│ ▼ │ 动作库 │ │ │
│ 全身轨迹优化(Horizon) │ │ ▼ │
│ 动力学约束内投影 │ │ 低层执行 (XBot2) │
└──────────────────────┘ └─────────────────────┘
▲ │
│ 需要选形态时 ▼
┌───────┴──────────────────────────────────────────────┐
│ 形态选择扇区 (VLM, GPT-4V) │
│ 头部相机: 2D图 + 6D位姿 ──▶ 操作形态 (单臂/双臂) │
│ 骨盆相机: 深度→点云→体素 ──▶ 移动形态 (轮式/腿式) │
│ prompt: 机器人自身能力描述 (affordance grounding) │
└──────────────────────────────────────────────────────┘
4.2 一条指令的完整生命周期(对应论文 Figure 1 的 5 步)
指令: "打开抽屉,拿起电钻,放进箱子,交给那位同学"
│
├─ ① LLM 解析语义,生成任务图:
│ [语义导航(AprilTag)] → [物体检测+位姿估计]
│ → [开抽屉技能] → <IsActionSuccess?> ──否──▶ [重试]
│ → [形态选择] → [单臂抓取技能] → ...
│
├─ ② 语义导航: 骨盆相机找 AprilTag,移动中不断校正
│ <WhetherWheelMove?> 平地 → 轮式
│
├─ ③ 到达后: 头部相机 2D+深度 → FoundationPose 估计
│ 抽屉把手 6D 位姿 → 机器人坐标系
│
├─ ④ 技能执行: RL 策略输出 q* → 全身优化 → 关节指令
│ XBot2 实时中间件 → 38 个执行器
│
└─ ⑤ 每个技能完成后 BT 检查条件节点,决定继续/重试/回退
4.3 技能库节点一览(对应附录 Figure A2/A3)
| 节点类型 | 节点 | 来源 |
|---|---|---|
| 动作节点(学习型) | 开抽屉、开门、单臂抓取、双臂抓取 | RL + 全身优化 |
| 动作节点(预定义) | 语义导航、物体检测、位姿估计等 | 常规机器人模块 |
| 条件节点 | <WhetherSingleArm>、<WhetherWheelMove>、<IsActionSuccess> |
VLM 形态选择 / 失败恢复 |
五、踩坑点:论文承认的,和它没明说的
这部分按老规矩分"范式级"(方法论固有缺陷)和"工程级"(工程实现上的坑)。
范式级
1. 技能库的"穷举悖论"。 论文在结论里老实承认:motion library 的规模限制了可执行任务指令的范围,新技能需要单独训练优化,无法从已有动作泛化 。这是"技能单元 + 上层编排"这一整个范式(SayCan、ProgPrompt 都在此列)的原罪:库里的技能是离散的原语,用户命令一超出库的覆盖范围,系统就抓瞎。就像你的编码器只预置了 I/P/B 三种帧类型,突然来了个需要 GOP 结构之外灵活性的场景------抽象层救不了能力缺失。长时程任务的多样性上限 = 动作库的笛卡尔积覆盖度,而这个覆盖度是靠 GPU 时数一格一格烧出来的。
2. 开环规划,不抗干扰。 结论原话:系统难以处理外部扰动和碰撞,任务中缺乏实时语言交互,应对意外任务的重新规划能力有限 。翻译一下:LLM 把计划一次性生成完,之后 BT 就是"照章办事"------相当于编码一个 GOP 前不做任何场景切换检测,中途画面切了还按旧参考帧编 。中途你踹机器人一脚、把电钻挪个位置,它都不会(或者只会机械地)重试,更不会重新理解任务。detection_recovery 那个 <IsActionSuccess> 节点只是"失败就重复上一个动作",离真正的闭环重规划差着一个数量级。
3. LLM 的"非具身"本质没有改变。 GPT-4o 不懂这台机器人的动力学,它只是读了一份文字版的能力说明书。prompt 里"默认单臂+轮式"这类先验,本质是把机器人学家的调参工作转写成了自然语言------写 prompt 的人必须非常懂这台机器人。说明书写错一个字,行为树就系统性跑偏。这和给编码器传错误的 level/tier 参数,后面所有 RDO 决策全盘皆错,是一个道理。
工程级
4. "大脑在体外"的延迟与依赖。 硬件配置里写得很清楚:LLM/VLM 跑在外接的 RTX 4090 引导 PC 上,机器人本体只带两块负责实时控制的计算单元。这意味着这套系统目前离了网线/无线链路就不是自主系统,而室外部署时引导 PC 与机器人之间的感知数据回传(2D 图像、点云)本身就是延迟大户。论文没有给 LLM 推理延迟的具体数字,但按 GPT-4o API 的典型延迟(秒级),每个形态选择/规划调用都会在行为树里插一个"卡顿"。对比人形机器人动辄 1kHz 的底层控制频率,这个时间尺度断层非常刺眼。
5. 感知-执行的标定错位是最大失败源。 实验(Figure 8)里执行错误的占比普遍高于感知错误,但作者在正文里点出的根因值得划重点:"execution errors mainly stem from intricate dynamical constraints on the actions and misalignment of the floating sensing with robot execution" ------浮动基座上相机的世界坐标会跟着基座漂移。固定基座机械臂上"眼在手上/眼在手外"的标定是一次性的,人形机器人上每走一步标定就在变。这是所有 mobile manipulation 系统共同的坑,这篇论文没有(也没法)根治。
6. 训练期关闭自碰撞的双刃剑。 3.1 节提过:RL 训练时为了留出上半身与腿的碰撞余量、让手臂快速伸出去,刻意关掉了自碰撞检测 ,把碰撞规避全权交给下游全身优化。这个设计成立的前提是:全身优化器一定能找到无碰撞的投影解。如果 RL 策略学出的动作太"浪"(比如手伸进了腿的工作空间深处),OCP 可能无可行解,或者解出来的动作和参考轨迹面目全非( L 2 L_2 L2 代价巨大),技能执行效果就会大打折扣。论文的 Figure 5 显示轨迹跟踪得不错,但那是在精心设计的任务里;任务空间一扩,这个假设就可能崩。
7. AprilTag 依赖的"作弊感"。 长时程任务里目标定位靠 AprilTag 视觉基准标记:门上贴一个推把手位置、抽屉的定位也靠 tag。这是实验室里的标准操作,但真实家庭里不会给你贴满 AprilTag。物体级 6D 位姿估计(FoundationPose)虽然号称支持 novel objects,但在杂乱真实场景里的鲁棒性和 tag 没法比。这一层其实是整个 demo 里最"脆"的环节。
8. 每个技能的奖励权重都要人肉调。 看看 3.1 节那张权重表:8 个参数 × 4 个任务,每一个数字背后都是若干轮失败的训练。开门任务 α 7 = 0.125 \alpha_7 = 0.125 α7=0.125 和抓取任务 α 7 = 0.7 \alpha_7 = 0.7 α7=0.7 差了 6 倍------这种敏感度意味着每加一个新技能就是一次完整的 reward engineering 周期,和"范式级第 1 条"互为表里。
六、源码拆解:论文没放码,我们用伪代码把系统"重写"一遍
论文官方仓库未开源(项目主页只有 prompt 文件:hy-motion.github.io/prompt/ 下的 user_input.ini、motion_library.ini、basic_prompt.ini、Function_options.ini),但附录把算法细节给得很足,足以重构核心流程。以下伪代码均标注了论文出处。
6.1 技能训练主循环(对应 Sec 3.2 + 附录 A2)
python
# 对应论文 Sec 3.2 与附录 A2:PPO 训练任务技能(以开抽屉为例)
# 网络: MLP [256, 128, 64], ELU 激活, actor-critic 架构
TASK_CONFIG = {
"action_space": 14, # A1 ⊆ R^14: 右臂6 + 基座6 + 躯干yaw 1 + 夹爪 1
"left_arm": "FIXED", # 单臂任务左臂固定
"obs": [
"upper_body_joint_pos_normalized",
"upper_body_joint_vel * 0.1",
"drawer_pulled_length", # 任务进度观测量------RL 能看到自己拉了多远
"gripper_to_handle_vec", # 末端的引导向量
],
"reward_weights": dict(a1=2.0, a2=0.0, a3=0.5, a4=7.5,
a5=7.5, a6=0.01, a7=0.7, beta=0.04),
}
def compute_reward(state, action, cfg):
# 通用骨架 (Eq.1)
r_l_reach = (1 / (1 + dl**2))**2 # dl: 目标到左末端的距离
r_r_reach = (1 / (1 + dr**2))**2
# dx: 夹爪forward轴·物体内向轴; dz: 夹爪up轴·物体up轴 (点积)
r_rot = sign(dx)*dx**2 + sign(dz)*dz**2
r_finger = cfg.beta - (d_top + d_bottom) # 双指包络
r_penalty = -norm(action)**2
# 任务奖励 (附录 Eq.A1, 开抽屉)
r_around = 0.5 if (finger_top_above_handle and finger_bottom_below_handle) else 0
r_task = cfg.a7 * r_around + drawer_len * r_around + drawer_len
# ^^^ 夹对了位置, 拉动才有加倍分------先摆姿势, 再谈绩效
return (cfg.a1*r_l_reach + cfg.a2*r_r_reach + cfg.a3*r_rot
+ cfg.a4*r_finger + cfg.a5*r_task + cfg.a6*r_penalty)
注意观测列表里同时有 drawer_pulled_length(进度)和 gripper_to_handle_vec(引导),这是"任务进度可观测"的设计------策略在任意时刻都知道自己处于任务的哪个阶段,等价于给 P/B 帧编码时显式传入参考帧信息,不用它自己猜。
6.2 全身轨迹生成(对应 Eq.2 + 附录 A3 的 Horizon 求解流程)
python
# 对应论文 Eq.2 与附录 Eq.A5-A9: 把 RL 上半身参考轨迹投影到全身可行空间
def whole_body_motion_generation(q_star, T, N_nodes):
# 状态 x = [q, v] ∈ R^93 (广义坐标+速度)
# 输入 u = [v_dot, f_c] ∈ R^58 (加速度+足端接触力)
X, U = discretize(N_nodes) # Eq.A6: N 节点离散化
def cost(x_i, u_i): # Eq.A9
return norm(x_i.q_upper - q_star_i)**2 + norm(u_i)**2
# ^失真项: 贴住 RL 参考 ^能量正则
constraints = [
("dyn", lambda x,u: x_dot - f(x, u)), # 全身动力学 (等式)
("init", lambda: (q_0 == q_init, v_0 == 0)), # 从当前姿态静止出发
("q_bound", lambda x: (q_min <= x.q <= q_max)), # 关节位置极限
("v_bound", lambda x: (v_min <= x.v <= v_max)), # 速度极限
("a_bound", lambda u: (a_min <= u.v_dot <= a_max)),
("unilateral", lambda f_c: f_c.z * n > 0), # 接触力单边性: 只推不拉
("friction_cone", lambda f_c: fx**2+fy**2 <= (mu*f_c.z)**2), # 摩擦锥
]
# 注: RL 训练期无自碰撞约束, 全身优化在 g2 内自然规避自碰撞 (Sec 4.1)
return solve_nlp(cost, constraints, X, U) # Horizon 框架求解
工程要点:RL 输出的 q ∗ q^* q∗ 是 20 维(上半身),优化目标里只跟踪 q u q_u qu(上半身关节),腿和基座完全由动力学约束和代价泛函自己"长"出来------这就是"低维轨迹投影到全身空间"的具体含义。
6.3 LLM 规划与行为树生成(对应 Sec 3.3 + 附录 A6/A7)
python
# 对应 Sec 3.3 与附录 A6: 模块化 prompt 组装 → LLM 生成 BT XML
def plan_task(user_command, function_options):
prompt = compose(
BASIC_PROMPTS, # "你是机器人控制器, 输出 XML 行为树..." + 本体描述
MOTION_LIBRARY, # 技能目录: 名称 + 属性/功能描述 (LLM 的 API 手册)
FUNCTION_OPTIONS, # 各功能默认 off; on 了才允许往 BT 里插对应条件节点
user_command,
)
# Function Options 开关注入规则 (附录 A6.2):
# manipulation_mode_selector=on → BT 里允许 <WhetherSingleArm> 节点
# locomotion_mode_selector=on → BT 里允许 <WhetherWheelMove> 节点
# detection_recovery=on → BT 里允许 <IsActionSuccess> 节点(失败重试)
task_graph_xml = LLM_gpt4o(prompt) # 层级任务图, XML 格式
return build_behavior_tree(task_graph_xml) # 构建完整 BT, 交给执行层
# BT 执行示意 (长时程任务, 对应 Figure 7):
# [导航到门] → [检测门把手] → <WhetherSingleArm?> → [开抽屉技能]
# → <IsActionSuccess?> 否→重试 / 是→[抓电钻] → [放箱子] → [交给同学]
6.4 形态选择器(对应 Eq.3/4 + 附录 A5)
python
# 对应 Eq.3/4: VLM 形态选择 (GPT-4V)
def select_manipulation_morphism(task_state, p_V):
img_2d, depth = head_camera.capture() # 头部 D435i
v_c = FoundationPose(img_2d, depth) # 目标 6D 位姿 (Sec 3.3)
v_R = T_world_to_robot @ v_c # 转到机器人坐标系
return VLM_gpt4v(s=task_state, I=img_2d, v_6d=v_R, prompt=p_V)
# 输出: 'single_arm' | 'dual_arm'
def select_locomotion_morphism(task_state, p_V):
point_cloud = pelvis_camera.depth_to_pointcloud() # 骨盆 D435i
voxel_grid = downsample(point_cloud) # 体素化 = 空间几何蒸馏
img_path = pelvis_camera.capture_2d()
return VLM_gpt4v(s=task_state, I=img_path, Vg=voxel_grid, prompt=p_V)
# 输出: 'wheel' | 'leg'
6.5 关键超参数汇总
| 项目 | 配置(论文附录) |
|---|---|
| RL 算法 | PPO,actor-critic MLP |
| 网络结构 | 256, 128, 64,ELU 激活 |
| 训练环境 | Isaac Gym(GPU 并行) |
| 动作空间 | 单臂 R 14 \mathbb{R}^{14} R14 / 双臂 R 19 \mathbb{R}^{19} R19 |
| RL 输出 | 上半身关节位置轨迹 q ∗ ∈ R 20 q^* \in \mathbb{R}^{20} q∗∈R20 |
| 全身状态/输入维度 | n x = 93 n_x = 93 nx=93, n u = 58 n_u = 58 nu=58 |
| 优化框架 | Horizon 轨迹优化(NLP 离散化,N 节点) |
| 规划 LLM / 形态 VLM | GPT-4o / GPT-4V(OpenAI API) |
| 实时中间件 | XBot2 + CartesI/O(优先级 QP) |
| 相机 | 2 × RealSense D435i(头部/骨盆) |
| 位姿估计 | FoundationPose / DOPE |
七、效果对比:数字说话
7.1 轨迹跟踪质量(Figure 5,定性)
开抽屉/开门任务的末端位置轨迹在 Isaac Gym、Gazebo、真机三环境对比:三条曲线高度重合,且经全身控制器"过滤"后的轨迹更平滑(RL 原始轨迹因关掉自碰撞而偏快,优化器在约束内把速度抹平)。这是 sim-to-real 成功部署的直接证据。
7.2 形态选择成功率(Figure 6,箱线图)
10 个操作场景 + 10 个移动场景(6 仿真 + 4 真实),每场景 10 次测试,对比纯 2D 图像输入 vs 图像+空间数据(SD)输入。从图上读到的分布(纵轴为成功率 0-100,数值为从图中目测的近似值):
| 场景类型 | 输入 | 成功率分布(中位数 ≈) |
|---|---|---|
| 移动场景 Mob-Scene | 仅 2D | ~55%,且离散度大(下须低至 ~45%,离群点 ~25%) |
| 移动场景 Mob-Scene | 2D + SD | **80%**,箱体收紧(75-90%),整体显著上移 |
| 操作场景 Manip-Scene | 仅 2D | ~68%,跨度大(离群点低至 ~30%) |
| 操作场景 Manip-Scene | 2D + SD | ~72%,略有提升、稳健性变好 |
核心结论:空间几何蒸馏对移动决策的提升远大于操作决策------这正是 3.3 节预测的:地形判断吃"体素证据",操作判断吃"位姿 + 2D 上下文"。作者的原话是:加入空间信息后选择器"在判断移动模式和适应复杂场景(不同类型与高度的障碍路径)时准确率显著提升"。
7.3 LLM 规划任务成功率(Figure 8,精确数值)
4 个代表性任务在真机上的成功率与失败归因(每次失败的类型分为规划错误 / 感知错误 / 执行错误):
| 任务 | 成功率 | 规划错误 | 感知错误 | 执行错误 |
|---|---|---|---|---|
| 接近并开门 | 76% | 8% | --- | 16% |
| 开抽屉并拿电钻 | 60% | 12% | 8% | 20% |
| 抓取和放置(Pick and Place) | 72% | 4% | 12% | 12% |
| 双臂抓放 | 68% | 16% | 4% | 12% |
三个值得咀嚼的观察:
- 最难的任务不是成功率最低的 。"开抽屉并拿电钻"是两段式复合任务(开抽屉 + 抓取 + 感知衔接),60% 垫底,符合预期。但双臂抓放的规划错误率(16%)反而是全场最高 ------双臂任务触发了
manipulation_mode_selector功能开关,prompt 变长、任务图分支变多,LLM 出错的概率自然上升。作者自己也说了:"adding task complexity and selecting multiple functional modules as input increases the difficulty of planning"。功能开关是把双刃剑的实锤。 - 执行错误 > 规划错误 > 感知错误是普遍规律。物理世界执行(动力学约束 + 浮动感知错位)始终是最薄弱环节------这是 5 号坑的定量注脚。
- 真机 ≥60% 的成功率在这个体级的 loco-manipulation 系统里是能看的数据。对比很多停在仿真里的 LLM+人形工作,这篇的工程完成度是真金白银的。
7.4 长时程任务(Figure 1/7,定性)
一句口头指令驱动完整流程:AprilTag 语义导航 → 检测 + 位姿估计 → 操作/移动形态自主选择 → 多技能串联执行(开抽屉 → 拿电钻 → 放入箱子 → 交给实验员)。行为树正确表达了条件分支与失败重试逻辑。这是"零样本在线规划"的核心演示------没有任何一个环节的技能序列是预先编程的,全部由 LLM 现场编排。
7.5 横向对比(与相关工作定位)
| 工作 | 平台 | LLM 规划 | 真机 | 技能来源 |
|---|---|---|---|---|
| SayCan (CoRL'22) | 固定基座移动机械臂 | ✓ | ✓ | 技能库(值函数接地) |
| Code as Policies | 固定机械臂 | ✓ | ✓ | 代码生成 |
| DoReMi / RoboGen | 人形/通用,仅仿真 | ✓ | ✗ | LLM 决策 |
| 端到端 VLA(RT-2 等) | 固定机械臂 | 隐式 | ✓ | 大规模模仿学习 |
| HYPERmotion | 38 DoF 轮腿人形 | ✓ | ✓ | RL 技能库 + 全身优化 |
HYPERmotion 的卡位很清晰:它是把"LLM 规划 + 技能库"范式搬到高自由度人形平台、并跑通真机长时程任务的少数工作之一。代价是技能全靠逐个训练,泛化上限被库的规模锁死。
八、总结:一套"分层兜底"的工程哲学,和一个尚未闭合的环
回过头看,HYPERmotion 的核心思想可以用一句话压缩:把不可解的全身自主问题,切解成"语义层(LLM)---决策层(VLM 形态选择)---技能层(RL 策略)---可行性层(全身优化)"四级流水线,每一层只在自己擅长的尺度上做决策,用明确的接口把约束逐层下传。
这套哲学对我们这些搞编码器的人来说毫不陌生------码控分层、模块级 RDO、环路滤波兜底,本质都是"分层 + 各司其职 + 约束下传"。它有效,可解释,工程上可控。但它也有同样古老的宿命:层与层之间的信息损耗,以及底层能力缺失时上层无法弥补。
- 亮点:分解式训练让 38 DoF 的训练成本可控;动作库 + 功能开关的模块化 prompt 设计是 LLM 机器人系统里少见的干净抽象;摩擦锥/单边性等硬约束保住了真机安全底线;真机 60-76% 的成功率证明了工程完成度。
- 边界:技能库规模决定能力上限、新技能无法从旧技能泛化、开环规划不抗扰动、LLM/VLM 在体外且延迟秒级、感知标定随基座漂移------这五条在结论里被作者承认或可从实验数据直接读出。
- 未来:作者给出的方向是扩充技能、增强 LLM 动态规划能力、改进导航感知,走向"闭环人形运动与人机协作安全"。
一个开放问题留给你:当 VLA 端到端模型(RT-2、π0 这类)持续吃数据变大变强,这种"LLM 编排离散技能"的分层架构,是像 H.264 的分层工具集一样长盛不衰,还是像所有中间件一样,最终被端到端浪潮拍在沙滩上?我个人的判断是:分层架构的价值在安全可验证------摩擦锥约束和"LLM 只能调用白名单技能"这两道闸门,在机器人进入人类生活空间的早期,比端到端的优雅重要得多。至少在真机上,能兜住底的系统才有资格谈上限。
论文链接: arXiv:2406.14655 | 项目主页: hy-motion.github.io