Learning a Unified Policy for Position and Force Control in Legged Loco-Manipulation
这篇文章的一作是 Peiyuan Zhi作者团队主要来自 北京通用人工智能研究院BIGAI、北邮以及 BIGAI Unitree Robotics 联合实验室。该工作后续收录在 CoRL 2025是CoRL的best paper方向上属于腿式机器人的 loco-manipulation也就是移动和操作一体化重点解决机器人在接触丰富场景下如何同时处理位置控制和力控制的问题。这篇文章的核心是指出现有很多具身智能或者机器人操作策略尤其是视觉模仿学习策略通常只关注位置——比如机械臂末端应该移动到哪里、base 应该怎么走、关节轨迹应该怎么跟踪。但在真实接触任务中只知道位置是不够的。比如擦黑板、开柜门、拉抽屉这些任务机器人不仅要知道“手往哪里动”还要知道“该用多大力”“什么时候保持接触”“什么时候顺着环境让步”。如果没有力的信息机器人很容易出现看起来轨迹对了但实际任务失败的情况擦黑板没有压住、推柜门力度不够、拉抽屉时因为遮挡或者接触变化导致动作偏掉。而传统的力控制通常依赖力传感器但对于腿式机器人来说额外的力传感器成本高、集成复杂也不一定在所有接触点都能布置。因此这篇文章想解决的问题就是能不能不依赖力传感器只根据机器人自身历史状态学出一个同时支持位置控制和力控制的统一低层策略基于此文章提出了 UNIFP / Unified Force-Position Policy1、任务场景腿式机器人 loco-manipulation包含四足机械臂和人形机器人。2、核心目标用一个统一策略同时处理 position command 和 force command。3、训练方式在 Isaac Gym 中通过强化学习训练低层策略小脑部分通过模拟不同位置命令、力命令和外部扰动力让策略学会从历史机器人状态中估计外力并通过位置和速度调整进行补偿。4、关键特点不依赖真实力传感器但可以实现位置跟踪、力施加、力跟踪以及合规交互等多种行为。个人觉得这篇文章的重点不是单纯做了一个 force estimator而是把 force 和 position 统一到一个可学习的低层控制策略里使它能够作为后续模仿学习或者高层策略的大脑-小脑接口。核心贡献 1提出了面向腿式机器人的统一力-位置控制策略这篇文章最核心的部分是小脑也就是低层 force-position policy。传统方法往往把位置控制和力控制分开处理位置控制就是跟踪末端轨迹力控制就是单独设计力调节模块。但问题是在真实接触任务中力和位置不是独立的。你压黑板压得越紧末端位置就会被环境限制你推柜门时手的位置变化和接触力大小也是相互耦合的。文章采用了阻抗控制的思想把机器人和环境的交互建模成类似弹簧-阻尼系统的形式。简单理解就是位置命令决定机器人“想去哪里”力命令决定机器人“想施加多大力”外部环境反作用力会阻止机器人完全到达目标位置策略需要根据历史状态估计这种力并调整自己的位置和速度。在论文小脑部分作者主要分了两块进行建模第一块是 end-effector也就是末端执行器的位置和力控制。这里对应机器狗右上角的那个“拳头”末端文章里主要让它完成推、拉、擦、接触等动作。第二块是 base也就是机器人本体的多接触建模。这里不是只考虑机械臂末端而是考虑机器人整个身体受到外力时base 该如何通过速度调整来补偿。我理解这里的差异是对于末端执行器位置变化和接触力变化更直接所以文章主要用刚度系数去建模位置-力关系对于 base精确位姿变化和接触情况更复杂因此文章更多通过速度和阻尼项来处理外力补偿。也就是说这篇文章并没有把 base 和末端之间的相互作用力完全统一建模而是采用了一种相对解耦的方式末端负责 manipulation contactbase 负责多接触和整体稳定。文章最后也提到多点力估计和全身多接触交互仍然是未来工作。核心贡献 2不依赖力传感器而是通过历史状态估计外力这篇文章一个比较重要的点是它不是用真实力传感器做力控而是让策略从机器人历史状态里估计力。输入给低层策略的信息包括机器人 base 姿态base 角速度关节位置W关节速度上一时刻动作命令信息步态相位信息。命令信息里又包括base velocity commandend-effector position commandend-effector force commandbase force command。然后策略通过这些信息去推断机器人当前受到什么样的外力以及应该如何调整动作。这里可以理解为机器人并没有直接“摸到力传感器数值”但它可以从自己的运动偏差中反推出力。比如命令末端往前 5cm但实际被环境挡住了关节状态和目标位置之间出现偏移base 被人踢了一脚速度和姿态发生变化这些历史状态都隐含了外力信息。策略通过强化学习学会把这些偏差解释成“外部力”再进行补偿。这也是本文和普通 position-control policy 最大的区别普通位置策略只知道“我要去哪里”UNIFP 还会估计“为什么我没有到那里”以及“是不是因为环境给了我一个反作用力”。核心贡献 3Force-aware Imitation Learning把估计力引入高层模仿学习如果只是低层控制机器人还需要人或者高层策略给它 position command 和 force command。但在完全自动执行任务时高层通常事先并不知道精确力值。这也是论文后半部分加入 imitation learning 的原因。文章训练了一个高层 diffusion policy它的输入包括RGB 图像机器人状态低层 force estimator 估计出来的力信息。它的输出是end-effector position commandforce command。然后这些命令再交给低层 UNIFP 策略执行。所以整体可以理解成一个大脑-小脑结构高层 diffusion policy 是大脑负责根据视觉、状态和估计力判断下一步应该去哪里、用多大力低层 UNIFP policy 是小脑负责把 position command 和 force command 稳定执行出来同时根据历史状态继续估计外力并补偿。我觉得这里比较关键的一点是作者不是直接让 diffusion policy 输出关节动作而是让它输出更抽象的 position command 和 force command。这样做的好处是高层不用直接处理复杂的机器人动力学而低层策略已经学会了如何在接触中稳定执行。举例擦黑板任务中高层看到黑板和末端位置输出“末端沿着黑板横向移动同时保持一定压力”低层 UNIFP 负责真正让机器人压住黑板并在黑板反作用力下保持稳定接触。开柜门任务中高层输出“手往柜门方向推并施加一定向前力”低层策略负责根据柜门的反作用力和机器人状态调整姿态保证动作不会因为接触变化而失稳。核心贡献 4在真实机器人上验证了统一力-位置策略的有效性文章实验主要分为几类1、位置跟踪实验验证在有外力干扰的情况下策略能否仍然完成 position tracking。实验结果显示即使加入外力位置跟踪误差也能保持在较小范围内说明策略确实学到了一定的力补偿能力。2、力控制实验作者在真实机器人上输入 0N 到 60N 的 force command并用测力计测量末端实际施加的力。结果显示不同末端位置下平均误差大致在 10N 以内。虽然这个精度不能说非常高但对于擦黑板、推柜门、开抽屉这类接触任务已经足够有用。3、接触丰富的 imitation learning 任务文章测试了几个典型任务wipe-blackboard擦黑板需要持续接触和稳定压力open-cabinet打开按压式柜门close-cabinet关闭柜门open-drawer-occlusion打开抽屉并且过程中视觉会逐渐被遮挡。这些任务的共同点是仅靠轨迹模仿很容易失败因为任务成功依赖接触力和环境反馈。实验结果显示引入 force estimation 和 force command 后force-aware imitation learning 相比普通 position-control policy 在接触丰富任务上有明显提升整体成功率提升约 39.5%。这说明 estimated force 虽然不是来自真实传感器但仍然能给高层策略提供关键的接触信息。4、跨本体验证文章还在 Unitree B2-Z1 四足机械臂和 Unitree G1 人形机器人上进行了实验。对于四足机械臂主要验证末端操作和力控对于人形机器人则主要验证 base force compensation也就是外力作用下机器人如何通过速度调整和身体姿态保持稳定。这说明该方法不是只针对单一机器人结构而是在四足和人形两种 embodiment 上都有一定泛化能力。附页细节补充对于 Contact number它的意思不是简单鼓励脚多接触地面而是鼓励“该落地的脚真的接触地面”。更准确地看代码实际实现不是简单相乘而是contact contact_forces[:, feet_indices, 2] 5.stance_mask self._get_gait_phase()reward torch.where(contact stance_mask, 1, -0.3)return torch.mean(reward, dim1)也就是说如果当前脚的 contact 状态和 stance_mask 一致就给 1如果不一致就给 -0.3。所以这个 reward 本质上是在约束步态相位和真实接触状态保持一致而不是单纯让所有脚都落地。对于 Reference motion如果只看公式可能会误以为误差越大奖励越大误差 0 - reward 0误差 0.5 - reward 0.25误差 1.0 - reward 1.0这样确实是不合理的。但实际代码里不是这样。代码中的 ref_dof_leg 是dof_error torch.sum(torch.abs(joint_pos - pos_target), dim1)rew torch.exp(-dof_error * 0.1)return rew也就是说误差越小reward 越接近 1误差越大reward 越小。这才符合 reference motion tracking 的目标。