1. 为什么全身跟踪是人形机器人落地的第一道坎
人形机器人这两年热度很高,但真正动手做过全身控制的人都知道,硬件本体只是入场券,真正决定它能不能干活、能不能稳住、能不能在真实环境里连续跑上几个小时的,是底层那套全身跟踪算法。所谓 General Whole-Body Tracking,直译过来就是“通用全身跟踪”,它要解决的核心问题是:给定一个参考动作序列(可能来自动捕、视频重定向、遥操作或者生成模型),让机器人在物理仿真或真实硬件上,尽可能忠实地复现这套动作,同时保持平衡、不摔倒、不抖动、不烧电机。
这件事听起来像是“让机器人学人跳舞”,但实际难度远超外行想象。人形机器人是一个高维、欠驱动、强耦合、带接触切换的非线性系统,光是自由度就动辄二三十个,再加上浮动基座,状态空间维度直接翻倍。更麻烦的是,双足行走本身就是一种“受控跌倒”,每一步都在失衡与恢复之间走钢丝。你要让它在跟踪动作的同时还保持稳定,等于要求一个杂技演员一边走钢丝一边模仿你打太极。
我接触这个方向有一段时间了,从最早的模仿学习、到后来的强化学习端到端、再到现在的分层框架与大规模并行训练,踩过的坑基本覆盖了这条技术路线的主要分支。这篇内容我打算把 General Whole-Body Tracking 的算法框架和训练范式拆开讲清楚,包括整体设计思路、核心模块、训练流程、常见问题排查,以及一些只有真正跑过实验才会知道的细节。适合已经有一定强化学习或机器人控制基础、想进入人形全身控制方向的读者,也适合正在做相关项目、卡在某个环节想找思路的人。
需要提前说明的是,这个领域迭代非常快,很多方案还在快速演化,我讲的是目前比较主流、经过验证的框架性思路,具体实现细节各家会有差异。我会尽量把“为什么这么设计”讲透,而不是只丢一堆公式和代码。
2. 整体框架设计:分层还是端到端,这是个问题
2.1 两种主流范式的取舍逻辑
做全身跟踪,第一个要做的决策就是:端到端直接输出关节力矩,还是分层——上层生成参考轨迹、下层做跟踪控制?这个问题在社区里争论了很久,我的观察是,两种路线各有适用场景,不存在绝对优劣。
端到端方案,典型做法是把参考动作序列和机器人当前状态一起喂进一个策略网络,网络直接输出每个关节的目标位置或力矩。这种方案的好处是结构简单、没有中间表示误差、理论上能学到一些人类难以手工设计的补偿行为。但它的缺点也很明显:训练极不稳定,样本效率低,而且一旦出错很难定位是感知问题、表示问题还是控制问题。我早期试过纯端到端,训练曲线像心电图,调参调到怀疑人生。
分层方案则是把问题拆成两层:上层负责把参考动作转换成机器人可执行的、物理上合理的参考轨迹(包括基座轨迹、关节轨迹、接触序列),下层负责用强化学习或模型预测控制去跟踪这条轨迹。这种方案的优势是模块化、可解释、每一层可以独立调试和替换。比如上层可以用运动重定向加动力学可行性过滤,下层用 PPO 训练一个鲁棒跟踪器。实测下来,分层方案在复杂动作上的成功率和稳定性明显更好,尤其是需要长时间连续跟踪的场景。
我的建议是:如果你刚入门,先从分层方案入手,把下层跟踪器训稳,再逐步往上加复杂度。端到端可以作为后期优化方向,但不适合作为第一个项目。
2.2 分层框架的典型结构
一个比较成熟的分层全身跟踪框架,通常包含以下几个模块:
- 参考动作预处理:把原始动捕数据或视频重定向结果做清洗、对齐、重采样,处理缺失标记点、抖动、脚滑等问题。
- 运动重定向:把人体骨架的动作映射到机器人骨架,保持末端执行器位置和整体姿态的相似性,同时考虑关节限位和自碰撞。
- 动力学可行性过滤:检查重定向后的轨迹是否满足摩擦锥、力矩限、ZMP 或 Capture Point 约束,不满足的段做平滑或裁剪。
- 下层跟踪策略:输入参考轨迹和机器人状态,输出关节目标,通常用强化学习训练,奖励函数包含跟踪误差、姿态正则、能耗、平滑度等项。
- 状态估计与接触检测:实时估计基座速度、高度、接触状态,为跟踪策略提供反馈。
这套结构的好处是每一层都有明确的输入输出契约,出问题可以逐层排查。比如机器人跟踪时脚打滑,你可以先看上层重定向后的接触序列是否合理,再看下层策略的接触奖励权重是否够大。
2.3 为什么通用性这么难
标题里有个关键词是“General”,也就是通用。通用意味着同一套框架要能跟踪走、跑、跳、转身、蹲起、挥手等各种动作,而不是针对单一动作调参。这对框架的泛化能力要求极高。
我总结下来,通用性主要卡在三个地方:一是动作分布差异大,走路的接触模式和跳跃完全不同,策略网络要能区分并切换;二是参考动作的物理合理性参差不齐,动捕数据里经常有脚滑、穿模、重心突变,直接拿来训会带偏策略;三是奖励函数很难一套通吃,跟踪走路时姿态正则权重要大,跟踪跳跃时反而要放松姿态、鼓励爆发。所以真正通用的框架,往往需要在训练时做课程学习(Curriculum Learning),从简单动作逐步过渡到复杂动作,同时用自适应奖励权重或域随机化来提升鲁棒性。
3. 核心模块拆解与实操要点
3.1 参考动作预处理:脏数据是常态
很多人以为动捕数据是干净的,实际拿到手才发现,标记点丢失、抖动、脚底滑动、地面穿透几乎是标配。我处理过一批公开动捕数据,大概三成以上的帧需要修复。预处理做不好,后面训练再努力也是白搭。
预处理的核心步骤包括:
- 缺失值插补:对短时丢失用线性或样条插值,长时丢失直接丢弃该段。
- 低通滤波:用 Butterworth 或 Savitzky-Golay 滤波去高频抖动,截止频率一般设在 6-10 Hz,具体看动作速度。
- 脚部接触修正:检测脚底接触帧,把接触期间的脚部位置锁定,消除脚滑。
- 地面对齐:估计地面平面,把动作整体对齐到机器人所在的地面高度。
- 重采样:统一到固定控制频率,常见是 30 Hz 或 50 Hz。
注意:滤波截止频率不要设太低,否则会把快速动作的细节抹掉,导致机器人跟踪时显得“软绵绵”。我一般会先可视化滤波前后的末端轨迹,确认关键帧没被削平再继续。
3.2 运动重定向:保持语义比保持数值更重要
重定向的目标是把人体动作映射到机器人,但两者骨架比例、关节数量、自由度分布都不一样。硬套 IK 往往会导致机器人姿态扭曲或者关节超限。我的经验是,重定向要优先保证末端执行器(手、脚)的位置和整体质心轨迹,关节角度可以做适度缩放和偏移。
具体做法上,常用的是带约束的优化:最小化末端位置误差加姿态相似度,约束包括关节限位、自碰撞、质心投影在支撑多边形内。优化变量是机器人各关节角度序列。这个优化可以离线做,也可以用 GPU 加速批量处理。
一个容易忽略的点是:重定向后的动作要保留接触信息。比如人脚接触地面的帧,机器人对应脚也应该接触,否则跟踪策略会学到错误的接触模式。我通常会在重定向后单独跑一遍接触检测,把接触序列作为额外输入喂给下层策略。
3.3 下层跟踪策略:奖励函数是灵魂
下层跟踪策略是整个框架里最核心也最难调的部分。目前主流是用 PPO 或类似的 on-policy 强化学习算法,在 Isaac Gym 或 MuJoCo 这类并行仿真环境里训练。策略输入通常包括:机器人本体感知(关节角、角速度、基座姿态、基座速度)、参考动作的未来若干帧、相位信息。输出是关节目标位置或力矩。
奖励函数的设计直接决定策略行为。我一般会分成几组:
| 奖励项 | 作用 | 典型权重范围 |
|---|---|---|
| 关节位置跟踪 | 让关节跟上参考 | 0.5 - 2.0 |
| 末端位置跟踪 | 保证手脚到位 | 1.0 - 3.0 |
| 基座姿态跟踪 | 保持躯干朝向 | 0.3 - 1.0 |
| 基座高度跟踪 | 防止蹲太低或站太高 | 0.5 - 1.5 |
| 接触一致性 | 脚接触与参考一致 | 0.5 - 2.0 |
| 动作平滑度 | 抑制抖动 | 0.01 - 0.1 |
| 力矩/能耗 | 省电、防过热 | 1e-4 - 1e-3 |
| 存活奖励 | 鼓励不摔倒 | 0.5 - 2.0 |
权重的平衡非常微妙。跟踪项权重太高,策略会为了跟动作而牺牲稳定,容易摔;稳定项权重太高,策略会“摆烂”,站在原地不动。我通常先用较大跟踪权重训一版,看它能不能跟,再逐步加稳定项,观察跟踪误差和摔倒率的变化曲线。
实操心得:奖励函数里加一个“参考动作可行性”的软约束很有用。具体做法是,如果参考动作本身在当前状态下动力学不可行(比如要求脚在空气中产生地面反力),就降低该帧的跟踪权重,让策略优先保稳定。这个技巧能显著降低早期训练的摔倒率。
3.4 域随机化与鲁棒性
仿真训出来的策略,直接上真机往往表现下降,因为仿真和现实有差距:摩擦系数、电机响应、传感器噪声、延迟、地面刚度都不一样。域随机化是缩小这个差距的常用手段,在训练时随机化以下参数:
- 地面摩擦系数(0.4 - 1.2)
- 电机力矩增益和延迟(±20%)
- 基座质量与惯量(±10%)
- 传感器噪声(高斯,标准差按实测)
- 外部推力扰动(随机方向,50-150 N,持续 0.1-0.3 s)
随机化范围要基于真机实测数据来定,不能拍脑袋。我一般会先在真机上做几组系统辨识实验,测出摩擦、延迟、增益的实际分布,再按这个分布设置随机化区间。范围太窄,策略不鲁棒;范围太宽,策略会过于保守,跟踪精度下降。
4. 训练范式与完整实操流程
4.1 课程学习:从走到跳的渐进路线
通用全身跟踪不可能一上来就训跳跃和转身,必须用课程学习。我的课程设计一般分四个阶段:
- 站立与平衡:只训站立、重心微调、抗扰动,让策略先学会不摔。
- 低速行走与转向:跟踪简单行走动作,速度从 0.3 m/s 逐步加到 1.0 m/s,加入转向。
- 复杂步态与姿态:加入蹲起、侧步、交叉步、挥手等上肢动作。
- 动态动作:跳跃、快速转身、单脚支撑、落地缓冲。
每个阶段的切换标准是:跟踪误差低于阈值且摔倒率低于 5%。切换时保留上一阶段的策略权重,只微调,不要从头训。我试过直接跳到第四阶段,结果策略完全学不会,浪费了两天机时。
4.2 并行仿真环境配置
现在训全身跟踪,基本离不开 GPU 并行仿真。Isaac Gym 和 Isaac Sim 是主流选择,MuJoCo 也有 MJX 这类 GPU 版本。配置要点:
- 环境数量:单卡 4090 上,人形机器人场景一般能跑 2048-4096 个并行环境,具体看模型复杂度和仿真步长。
- 仿真频率:物理步长 1/200 s 到 1/500 s,控制频率 30-50 Hz。控制频率太低,跟踪精度上不去;太高,训练慢且真机跟不上。
- 观测与动作空间:观测做归一化,动作做裁剪,避免数值爆炸。
- 随机种子:固定种子方便复现,但最终评估要用多个种子取平均。
注意:并行环境数量不是越多越好。环境太多,每个环境的经验多样性可能下降,而且显存吃紧容易崩。我一般从 1024 开始,逐步加到显存上限的 80% 左右。
4.3 训练超参与调参经验
PPO 的超参对结果影响很大,我常用的起点是:
# PPO 超参参考 learning_rate = 3e-4 n_steps = 24 # 每个环境每次采集的步数 batch_size = 4096 n_epochs = 5 gamma = 0.99 gae_lambda = 0.95 clip_range = 0.2 entropy_coef = 0.005 value_loss_coef = 0.5 max_grad_norm = 1.0调参顺序建议:先调学习率和 clip_range,再调 entropy_coef,最后调网络结构。网络一般用 MLP,2-3 层,每层 256-512 单元,激活函数用 ELU 或 ReLU。如果动作历史很重要,可以加 LSTM 或 Transformer,但会显著增加训练时间,非必要不加。
我踩过的一个坑是 entropy_coef 设太大,策略一直随机探索,跟踪误差下不去;设太小,策略过早收敛到局部最优,遇到新动作就摔。0.003-0.01 是比较稳的区间。
4.4 从仿真到真机的部署链路
仿真训完,部署到真机需要一套完整的链路:
- 策略导出:把 PyTorch 模型转成 ONNX 或 TorchScript,方便推理。
- 状态估计:真机上用 IMU、关节编码器、足底力传感器估计基座姿态和速度。基座线速度往往需要卡尔曼滤波或接触辅助估计。
- 参考动作流:把参考动作按控制频率实时喂给策略,注意时间对齐和延迟补偿。
- 安全层:加力矩限幅、关节限位、摔倒检测、急停逻辑。安全层是最后一道防线,不能省。
- 通信:控制指令通过 EtherCAT 或 CAN 下发,周期要稳定,抖动控制在 1 ms 以内。
真机调试时,我建议先用吊架把机器人吊起来,只跑下肢跟踪,确认不摔再放开。然后逐步加动作幅度,从走到小跑再到跳。每次加复杂度都要重新检查安全层阈值。
5. 常见问题与排查技巧实录
5.1 训练不收敛或跟踪误差震荡
这是最常见的问题。排查顺序:
- 检查参考动作是否归一化,观测是否做了 running mean/std。
- 检查奖励项权重是否失衡,尤其是跟踪项和稳定项的比例。
- 检查仿真步长和控制频率是否匹配,步长太大导致接触求解不准。
- 检查并行环境是否有异常环境(比如初始状态穿模),异常环境会污染梯度。
我遇到过一次跟踪误差一直震荡,最后发现是参考动作的基座高度序列有跳变,重定向时没做平滑。把高度序列低通滤波后,训练立刻稳定。
5.2 机器人跟踪时脚打滑或穿地
脚打滑通常是接触奖励权重不够,或者摩擦随机化范围太宽。穿地一般是仿真接触求解器参数问题,或者参考动作本身有穿透。解决办法:
- 提高接触一致性奖励权重。
- 缩小摩擦随机化下限,比如从 0.3 提到 0.5。
- 检查参考动作的脚部高度,接触帧脚底应贴地,非接触帧应有足够离地高度。
- 仿真里开启接触软约束,避免硬穿透。
5.3 真机上动作滞后或抖动
仿真到真机的滞后主要来自状态估计延迟和通信延迟。补偿方法:
- 在策略输入里加入参考动作的未来帧,让策略“预判”。
- 用一阶或二阶低通滤波平滑策略输出,但会引入额外滞后,要权衡。
- 检查通信周期,确保控制循环稳定在目标频率。
抖动则可能是策略输出高频分量太大,可以在动作上加低通滤波,或者在奖励里加动作变化率惩罚。
5.4 常见问题速查表
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| 训练不收敛 | 奖励失衡、观测未归一化 | 检查奖励权重、归一化 |
| 跟踪误差震荡 | 参考动作跳变、步长不匹配 | 平滑参考、调整步长 |
| 脚打滑 | 接触奖励低、摩擦随机化宽 | 提高接触权重、收窄摩擦 |
| 穿地 | 接触求解器、参考穿透 | 调求解器、修参考 |
| 真机滞后 | 状态估计延迟、通信抖动 | 加未来帧、稳通信 |
| 真机抖动 | 输出高频、滤波不足 | 加动作滤波、变化率惩罚 |
| 摔倒率高 | 稳定项权重低、课程太快 | 加稳定权重、放慢课程 |
| 泛化差 | 动作分布窄、随机化不足 | 扩动作集、加域随机化 |
5.5 几个只有跑过才知道的细节
第一,参考动作的相位信息很重要。把动作的相位(比如步态周期中的位置)作为观测输入,能显著提升跟踪的节奏感,尤其是周期性动作。我试过不加相位,策略跟踪走路时步频总是对不上。
第二,策略网络输出用目标关节位置比直接输出力矩更稳。力矩输出虽然理论上更灵活,但训练难度大,真机上力矩控制对模型精度要求高。位置输出配合 PD 控制器,鲁棒性好很多。
第三,训练时的初始状态分布要覆盖参考动作的起始姿态。如果初始状态和参考起始差太远,策略一开始就要花大力气去追,容易摔。我一般会让初始状态在参考起始姿态附近做小范围随机。
第四,评估不能只看平均跟踪误差,要看最差帧的误差和摔倒率。平均误差低但偶尔摔一次,真机上就是事故。我通常会把评估指标分成跟踪精度、稳定性、平滑度三组,综合判断。
6. 框架扩展与个人体会
这套框架训稳之后,可以往几个方向扩展。一是加入上肢操作,把全身跟踪和抓取、搬运结合,这时候奖励函数要加末端操作目标,接触序列也更复杂。二是加入感知输入,比如地形高度图、障碍物点云,让机器人在非平坦地面也能跟踪。三是用生成模型产生参考动作,替代动捕数据,实现更灵活的动作生成与跟踪闭环。
我个人在实际操作中的体会是,全身跟踪这件事,算法框架固然重要,但真正拉开差距的是数据质量和训练细节。同一套 PPO,同一套奖励,参考动作处理得好不好,课程设计得合不合理,域随机化范围定得准不准,结果能差出好几倍。我见过太多人把时间花在换算法、调网络结构上,却忽略了参考动作的脚滑和接触序列错误,最后怎么训都训不好。
最后再分享一个小技巧:训练时定期把策略在仿真里的跟踪结果渲染成视频,和参考动作并排对比。肉眼观察往往比看曲线更快发现问题,比如哪只脚接触不对、哪个关节跟不上、躯干是不是歪了。这个习惯帮我省了大量排查时间。