转载自公众号:敢敢AUTOHUB
0. 前言
让人形机器人学会跳舞,听起来像是科幻电影中的场景,但在强化学习和运动模仿技术的推动下,这件事正在变得越来越现实。本文将完整介绍一条从"人类 RGB 视频"到"真实机器人跳舞"的技术链路:首先通过视觉算法从视频中提取人体运动轨迹,然后将人体模型重定向到机器人关节空间,接着在仿真环境中进行强化学习训练,最后在 MuJoCo 中验证并部署到真实的 Unitree G1 人形机器人上。
整条流程涉及四个核心开源项目:GVHMR(视频到人体模型)、GMR(人体到机器人重定向)、BeyondMimic(强化学习训练框架)、以及 rl_sar(仿真验证与真机部署框架)。本文不仅会逐一拆解每个环节的原理和操作步骤,还会深入分析 BeyondMimic 的算法设计,并详细记录将训练产物迁移到 rl_sar 项目中进行 sim2sim 和 sim2real 部署时遇到的关键问题与解决方案。
下图展示了 BeyondMimic 的整体框架,从运动跟踪到通过引导扩散实现多功能人形控制:
BeyondMimic整体框架
1. 端到端流程总览:从 RGB 视频到机器人跳舞
在正式进入每个模块的细节之前,有必要先建立对整条流程的全局认知。整个系统可以被拆分为五个串联的阶段,每个阶段的输入和输出都有明确的数据格式约定,任何一个环节的数据不匹配都会导致下游失败。
第一阶段是视频到人体模型的转换。GVHMR 接收一段普通的 RGB 视频作为输入,通过深度学习算法估计视频中人物的 SMPLX 人体模型参数,输出一个包含完整人体运动轨迹的 .pt 文件。这个文件记录了每一帧中人体的全局位置、朝向以及各关节的旋转角度。
第二阶段是人体模型到机器人模型的重定向。由于人体和机器人在骨骼结构、关节自由度、肢体比例上存在显著差异,不能直接将 SMPLX 的关节角度套用到机器人上。GMR 通过优化算法解决这个"体现差距"(embodiment gap)问题,将人体运动映射到 G1 机器人的关节空间,输出 .pkl 文件,再转换为 BeyondMimic 所需的 .csv 格式。
第三阶段是强化学习训练。BeyondMimic 基于 Isaac Lab 仿真平台,使用 PPO 算法训练机器人在物理仿真中跟踪参考动作。训练完成后导出 .onnx 模型文件和对应的 .npz 参考动作文件。
第四阶段是仿真验证。在 MuJoCo 物理引擎中加载训练好的策略和参考动作,验证机器人能否在独立的仿真环境中正确复现目标动作。这一步是真机部署前的必要安全检查。
第五阶段是真机部署。将验证通过的策略部署到 Unitree G1 实体机器人上,通过 rl_sar 框架的 C++ 实时控制循环驱动机器人执行动作。
2. GVHMR:从 RGB 视频提取人体运动轨迹
2.1 GVHMR 的作用与原理
GVHMR(Global-View Human Motion Recovery)是浙江大学开源的一个从单目 RGB 视频中恢复全局人体运动的算法。传统的人体姿态估计方法通常只能得到相对于相机坐标系的局部姿态,而 GVHMR 的核心贡献在于能够恢复人体在世界坐标系下的全局运动轨迹,包括全局平移和旋转。这对于后续的机器人运动重定向至关重要,因为机器人需要知道"人在空间中走了多远、转了多少",而不仅仅是"手臂抬了多高"。
GVHMR 的输出是一个 PyTorch 的 .pt 文件,其中包含了 SMPLX 人体模型的完整参数序列:全局位移(global translation)、全局朝向(global orientation)、身体姿态参数(body pose)以及手部姿态参数。这些参数足以在任意时刻重建出完整的人体三维网格。
2.2 环境配置
GVHMR 的安装按照其官方文档操作即可。需要注意的是,该项目依赖较多的预训练模型和第三方库,建议在独立的 conda 环境中安装。所需的 inputs 目录文件可以从以下链接获取:
链接: https://pan.baidu.com/s/1YffSEeTJi3aBQZM159h1pQ 提取码: pztv
2.3 数据转换操作
环境配置完成后,执行以下命令即可将视频转换为 SMPLX 运动轨迹:
python tools/demo/demo.py --video=docs/example_video/tennis.mp4 -s
其中 --video 参数指定输入视频的路径,-s 参数表示保存结果。程序运行完成后会输出一个 .pt 文件,务必记录该文件的完整路径,因为下一步 GMR 需要用到它。
GVHMR输出结果
上图展示了 GVHMR 处理视频后的输出信息,可以看到程序会打印出 .pt 文件的保存路径。在实际操作中,建议将视频文件放在项目目录下的统一位置,并为每个视频建立独立的输出目录,方便后续管理多个动作数据。
需要特别注意的是,输入视频的质量直接影响运动提取的精度。理想的输入视频应当满足以下条件:画面中只有一个人、人物全身可见、背景相对简洁、光照均匀。如果视频中存在严重遮挡或多人交叉,GVHMR 的输出质量会明显下降,进而影响整条流程的最终效果。
3. GMR:将人体运动重定向到 G1 机器人
3.1 为什么需要运动重定向
人体有超过 200 块骨骼和数百个自由度,而 Unitree G1 机器人只有 23 或 29 个可控关节。两者在骨骼拓扑结构、关节运动范围、肢体长度比例上都存在本质差异。例如,人类的肩关节是一个球窝关节,可以在三个轴上自由旋转,而机器人的肩关节通常由三个串联的旋转关节来近似实现。直接将 SMPLX 的关节角度赋值给机器人关节,不仅物理上不可行,还可能导致自碰撞或关节超限。
GMR(General Motion Retargeting)通过优化方法解决这个问题。它的核心思路是:选取人体和机器人之间对应的关键身体部位(如手、脚、头、躯干),通过最小化这些对应部位在笛卡尔空间中的位置差异,求解出机器人的关节角度序列。这个过程会自动处理骨骼长度差异和关节约束,确保输出的机器人动作在运动学上是可行的。
3.2 数据转换:pt 到 pkl
由于上一步使用的是 GVHMR 框架,这里选择 GMR 中的 "Retargeting from GVHMR to Robot" 方法进行重定向:
python scripts/gvhmr_to_robot.py \
--gvhmr_pred_file <path_to_hmr4d_results.pt> \
--robot unitree_g1 \
--record_video \
--save_path motions/G1/G1.pkl
参数说明:
• -gvhmr_pred_file:上一步 GVHMR 生成的 .pt 文件路径
•-robot unitree_g1:目标机器人型号
• -record_video:录制重定向过程的可视化视频
• -save_path:输出.pkl 文件的保存路径,务必记录
GMR重定向过程
转换成功后,程序会自动播放重定向结果的可视化视频,可以直观地检查机器人动作是否与原始人体动作在视觉上一致:
GMR重定向可视化
3.3 数据转换:pkl 到 csv
BeyondMimic 框架要求输入的参考动作格式为 CSV 文件,因此需要将 GMR 输出的 .pkl 文件进一步转换。运行以下命令:
python3 scripts/batch_gmr_pkl_to_csv.py --folder /home/teacher/zzw/GMR/motions/G1/
其中 --folder 参数指定包含 .pkl 文件的目录路径。转换后的 CSV 文件每一行代表一帧数据,格式为:
root_pos_x, root_pos_y, root_pos_z, root_quat_x, root_quat_y, root_quat_z, root_quat_w, joint_0, joint_1, ..., joint_N
前 7 列是根节点(骨盆)的全局位置和四元数朝向,后续列是各关节的角度值。这个 CSV 文件是整条流程中承上启下的关键数据格式,后续的 BeyondMimic 训练和 rl_sar 部署都会用到它。
4. BeyondMimic:强化学习训练全流程
4.1 BeyondMimic 项目概述
BeyondMimic 是 UC 伯克利和斯坦福联合开源的人形机器人全身运动追踪框架。该项目基于 NVIDIA Isaac Lab 仿真平台,使用经典的 PPO(Proximal Policy Optimization)算法训练机器人在物理仿真中高保真地跟踪参考动作。与早期的运动模仿方法相比,BeyondMimic 的核心优势在于:它不仅能处理静态或低动态的动作,还能在真实硬件上实现跳跃旋转、冲刺、侧手翻等高度动态的技能,同时保持业界领先的运动质量。
其对应论文为 BeyondMimic: From Motion Tracking to Versatile Humanoid Control via Guided Diffusion,项目主页为 beyondmimic.github.io。
该项目的训练流程包含四个步骤:数据预处理(csv2npz)、数据上传(WandB Registry)、强化学习训练、以及策略评估与导出。下面逐一展开。
4.2 环境配置
按照 BeyondMimic 官方仓库的安装教程进行配置。核心依赖包括 NVIDIA Isaac Sim 4.5.0、Isaac Lab 2.1.0、RSL-RL 以及 Python 3.10。由于训练需要大量 GPU 并行仿真环境(默认 4096 个),建议使用 RTX 4090 或 A100 级别的显卡。
BeyondMimic环境配置
此外,BeyondMimic 使用 WandB(Weights & Biases)进行运动数据和训练日志的管理。在开始训练之前,需要先注册 WandB 账号,创建一个 Organization,并在本地配置好登录凭证:
pip install wandb
wandb login
WandB配置
4.3 数据预处理:CSV 转 NPZ
BeyondMimic 的训练不直接读取 CSV 文件,而是需要先将其转换为包含完整物理信息的 NPZ 格式。这个转换过程不仅仅是格式变换,还包括帧率插值和正向运动学计算。
python scripts/csv_to_npz.py \
--input_file {motion_name}.csv \
--input_fps 30 \
--output_name {motion_name} \
--headless
参数说明:
• -input_file:上一步生成的 CSV 文件路径
-input_fps 30:输入 CSV 的帧率(通常为 30fps)
-output_name:在 WandB Registry 中的名称
-headless:不启动可视化窗口(去掉此参数可以看到机器人播放动作)
该脚本内部执行了以下关键步骤:首先将动作从输入帧率(如 30fps)插值到输出帧率(50fps,对应 dt=0.005s、decimation=4 的控制频率);然后在 Isaac Sim 中通过正向运动学计算每个身体部位的世界坐标系位置、姿态四元数、线速度和角速度;最后将所有数据打包为 NPZ 文件并上传到 WandB Registry。
NPZ 文件包含的数据字段如下:
{
'fps': 50, # 帧率
'joint_pos': [T, N_joints], # 关节位置序列
'joint_vel': [T, N_joints], # 关节速度序列
'body_pos_w': [T, N_bodies, 3], # 各身体部位世界坐标位置
'body_quat_w': [T, N_bodies, 4], # 各身体部位世界坐标姿态
'body_lin_vel_w': [T, N_bodies, 3], # 各身体部位线速度
'body_ang_vel_w': [T, N_bodies, 3], # 各身体部位角速度
}
需要注意的是,csv_to_npz.py 程序是无限循环运行的——它会持续重复播放转换后的数据。在不可视化模式下,程序看起来像是卡住了,实际上数据已经上传成功。当终端出现类似下图的信息时,即可按 Ctrl+C 终止进程:
csv2npz上传成功
4.4 数据验证
在启动训练之前,建议先回放一遍上传的数据,确认动作正确无误,避免训练错误的动作浪费算力:
python scripts/replay_npz.py \
--registry_name={your-organization}-org/wandb-registry-motions/{motion_name}
4.5 强化学习训练
数据准备就绪后,即可启动训练。BeyondMimic 使用 RSL-RL 框架实现 PPO 算法,在 Isaac Lab 中并行运行 4096 个仿真环境进行采样:
python scripts/rsl_rl/train.py \
--task=Tracking-Flat-G1-v0 \
--registry_name {your-organization}-org/wandb-registry-motions/{motion_name} \
--headless \
--logger wandb \
--log_project_name {project_name} \
--run_name {run_name}
如果最终目标是部署到真实机器人上,需要使用不依赖状态估计的任务变体,将 task 参数改为 Tracking-Flat-G1-Wo-State-Estimation-v0:
python scripts/rsl_rl/train.py \
--task=Tracking-Flat-G1-Wo-State-Estimation-v0 \
--registry_name {your-organization}-org/wandb-registry-motions/{motion_name} \
--headless \
--logger wandb \
--log_project_name {project_name} \
--run_name {run_name}
两个 task 的区别在于观测空间的设计。Wo-State-Estimation 变体省略了依赖外部定位系统的线性分量(锚点位置误差的平移部分和根部线速度),因为这些信息在真实机器人上难以精确获取。训练默认迭代 30000 次,在 RTX 4090 上通常需要数小时。
训练过程中的核心超参数配置如下:
# PPO 采样配置
num_steps_per_env = 24 # 每个环境每次采样的步数
num_envs = 4096 # 并行环境数量
# 网络架构
actor_hidden = [512, 256, 128] # Actor 网络隐藏层
critic_hidden = [512, 256, 128] # Critic 网络隐藏层
activation = "elu" # 激活函数
# PPO 优化参数
learning_rate = 1e-3 # 初始学习率(自适应调整)
clip_param = 0.2 # PPO 裁剪参数
entropy_coef = 0.005 # 熵正则化系数
num_learning_epochs = 5 # 每次迭代的训练轮数
num_mini_batches = 4 # 每轮的 mini-batch 数
gamma = 0.99 # 折扣因子
lam = 0.95 # GAE lambda
desired_kl = 0.01 # 目标 KL 散度
4.6 策略评估与导出
训练完成后,使用以下命令加载模型并在仿真中评估效果:
python scripts/rsl_rl/play.py \
--task=Tracking-Flat-G1-v0 \
--num_envs=2 \
--wandb_path={wandb-run-path}
BeyondMimic评测效果
评估脚本会自动从 WandB 下载训练好的模型和对应的参考动作,在仿真中运行策略并录制视频。同时,脚本会将策略导出为 ONNX 格式,用于后续在 rl_sar 中部署:
# play.py 内部的导出逻辑
export_motion_policy_as_onnx(
env, policy,
path="logs/.../exported/",
filename="policy.onnx"
)
导出的 ONNX 模型包含了观测归一化层和策略网络,可以直接被 C++ 的 onnxruntime 加载执行。
5. BeyondMimic 算法深度解析
前面介绍了 BeyondMimic 的操作流程,但要真正理解这个系统为什么能让机器人高保真地复现人类动作,需要深入其算法设计的核心。本节将从观测空间、奖励函数、自适应采样和域随机化四个维度展开分析。
5.1 观测空间设计
强化学习策略的输入——观测空间(observation space)——决定了策略能"看到"什么信息。BeyondMimic 的观测空间设计体现了一个关键的工程权衡:信息量越大,策略理论上能做出越精确的决策,但同时也增加了训练难度和对传感器的依赖。
对于 G1 29DoF 机器人,完整的观测向量维度为 154,由以下六个部分拼接而成:
观测向量 (154维) = motion_command (58) + motion_anchor_ori_b (6) + ang_vel (3) + dof_pos (29) + dof_vel (29) + actions (29)
各分量的含义如下:
• motion_command(58维):参考动作的关节位置和关节速度,维度为 num_of_dofs * 2。这是策略的"目标信号",告诉策略当前时刻机器人的各关节应该处于什么位置、以什么速度运动。这些数据来自预处理阶段生成的 NPZ 文件,在训练时由仿真环境按时间步索引提供。
• motion_anchor_ori_b(6维):锚点(躯干)的朝向误差,用 6D 旋转表示法编码。这个分量描述了当前机器人躯干朝向与参考动作躯干朝向之间的差异。使用 6D 表示而非四元数或欧拉角,是因为 6D 表示在旋转空间中是连续的,避免了四元数的双覆盖问题和欧拉角的万向锁问题,有利于神经网络的学习。
• ang_vel(3维):机器人基座的角速度,来自 IMU 陀螺仪。这个信号帮助策略感知自身的旋转状态,对于维持平衡至关重要。
• dof_pos(29维):当前各关节的实际位置(弧度),来自关节编码器。
• dof_vel(29维):当前各关节的实际速度,来自关节编码器的差分或直接测量。
• actions(29维):上一时间步策略输出的动作,即上一步的关节位置目标。将历史动作作为观测的一部分,可以帮助策略学习到动作的时序连贯性,避免输出剧烈抖动的控制信号。
对于 23DoF 的 G1 变体,观测维度相应缩减为 124 维(46 + 6 + 3 + 23 + 23 + 23)。
值得注意的是,BeyondMimic 提供了两种任务变体:Tracking-Flat-G1-v0 和 Tracking-Flat-G1-Wo-State-Estimation-v0。后者省略了锚点位置误差的平移分量和根部线速度,因为这些信息依赖外部定位系统(如动捕或 SLAM),在真实机器人上难以精确获取。如果最终目标是真机部署,应当选择 Wo-State-Estimation 变体进行训练。
5.2 奖励函数设计
奖励函数是强化学习的灵魂,它定义了"什么是好的行为"。BeyondMimic 的奖励函数由多个子项加权求和构成,每个子项负责约束机器人行为的一个方面。以下是核心奖励项及其物理含义:
# 关节位置跟踪奖励
r_joint_pos = exp(-5.0 * ||q_actual - q_ref||^2)
# 关节速度跟踪奖励
r_joint_vel = exp(-0.1 * ||dq_actual - dq_ref||^2)
# 身体部位位置跟踪奖励(关键身体部位在笛卡尔空间的位置误差)
r_body_pos = exp(-40.0 * ||p_body_actual - p_body_ref||^2)
# 身体部位朝向跟踪奖励
r_body_rot = exp(-10.0 * ||quat_body_actual - quat_body_ref||^2)
# 能量惩罚(鼓励节能的控制策略)
r_energy = -k_energy * sum(|tau * dq|)
# 动作平滑度惩罚(抑制控制信号的剧烈变化)
r_smooth = -k_smooth * ||a_t - a_{t-1}||^2
这些奖励项的设计遵循了几个重要原则。首先,所有跟踪奖励都使用指数函数 exp(-k * error^2) 的形式,而非简单的线性惩罚。指数形式的优势在于:当误差较小时,奖励接近 1,梯度较小,策略不会过度修正;当误差较大时,奖励迅速衰减到 0,提供强烈的纠正信号。这种"软约束"比硬性的阈值惩罚更有利于策略的平滑收敛。
其次,不同奖励项的系数(如关节位置的 5.0、身体位置的 40.0)反映了各项的相对重要性。身体位置的系数远大于关节位置,意味着系统更关注末端执行器(手、脚)在空间中的绝对位置是否正确,而非每个关节角度是否精确匹配。这符合运动控制的直觉:观众看到的是手脚的轨迹,而非肘关节的角度。
5.3 自适应采样机制
BeyondMimic 引入了一种自适应采样(Adaptive Sampling)机制来提升训练效率。传统的运动模仿训练中,每个 episode 从参考动作的随机时间点开始,所有时间点被均匀采样。但实际上,参考动作中不同片段的难度差异很大——站立和行走相对简单,而跳跃和旋转则困难得多。均匀采样会导致策略在简单片段上浪费大量训练资源,而在困难片段上采样不足。
自适应采样的核心思路是:记录每个时间点的训练失败率,对失败率高的时间点增加采样概率。具体实现如下:
# 自适应采样伪代码
for each training iteration:
# 1. 根据当前失败率分布采样起始时间点
start_times = sample_with_bias(failure_rates)
# 2. 运行仿真,收集轨迹
trajectories = simulate(policy, start_times)
# 3. 更新失败率统计
for t in start_times:
if episode_terminated_early(t):
failure_rates[t] += alpha # 增加失败计数
else:
failure_rates[t] *= decay # 衰减成功计数
# 4. 归一化为采样概率
sampling_probs = normalize(failure_rates)
这种机制使得训练资源自动向困难片段倾斜,显著加速了整体收敛速度。在实验中,自适应采样相比均匀采样可以将达到相同跟踪精度所需的训练迭代次数减少 30%-50%。
5.4 域随机化
从仿真到真实(sim-to-real)的迁移是强化学习部署的核心挑战。仿真环境与真实世界之间存在不可避免的差异——物理参数的不精确、传感器噪声、执行器延迟等。BeyondMimic 通过域随机化(Domain Randomization)来弥合这个差距,其核心思想是:在训练时随机扰动仿真环境的物理参数,迫使策略学习到对这些参数变化具有鲁棒性的控制策略。
BeyondMimic 中使用的域随机化参数包括:
# 域随机化配置
randomize_friction = True # 地面摩擦系数随机化
friction_range = [0.5, 1.25] # 摩擦系数范围
randomize_base_mass = True # 基座质量随机化
added_mass_range = [-1.0, 1.0] # 附加质量范围 (kg)
randomize_com_offset = True # 质心偏移随机化
com_offset_range = [-0.05, 0.05] # 质心偏移范围 (m)
push_robots = True # 随机推力扰动
push_interval_s = 15 # 推力间隔 (秒)
max_push_vel_xy = 0.5 # 最大推力速度 (m/s)
randomize_joint_default_pos = True # 关节默认位置随机化
joint_default_pos_range = [-0.05, 0.05] # 偏移范围 (rad)
这些随机化参数的选择并非随意的。摩擦系数的随机化范围 [0.5, 1.25] 覆盖了从光滑瓷砖到粗糙地毯的常见地面条件。质心偏移模拟了机器人负载变化或组装误差。随机推力则模拟了外部干扰,如被轻微碰撞。关节默认位置的随机化则补偿了关节编码器的零点漂移。
通过在训练中暴露于这些随机化的环境条件,策略学会了在不确定性下保持稳定的控制能力,这是成功进行 sim-to-real 迁移的关键前提。
6. BeyondMimic 项目代码结构分析
理解 BeyondMimic 的代码组织方式,有助于在需要修改训练配置、添加新机器人或调试问题时快速定位相关文件。本节对项目的核心目录和关键文件进行逐一解读。
6.1 项目目录总览
BeyondMimic 的代码仓库(对应 GitHub 上的 whole_body_tracking)遵循 Isaac Lab 扩展的标准目录结构:
whole_body_tracking/
├── exts/
│ └── robot_lab/
│ └── robot_lab/
│ ├── assets/ # 机器人 URDF/MJCF 模型文件
│ │ └── g1/
│ │ ├── g1.urdf
│ │ └── g1_29dof.xml # MuJoCo 格式模型
│ ├── tasks/ # 任务定义(环境、观测、奖励)
│ │ └── locomotion/
│ │ └── tracking/
│ │ ├── config/
│ │ │ └── g1/
│ │ │ ├── flat_env_cfg.py # 环境配置
│ │ │ └── agents/
│ │ │ └── rsl_rl_ppo_cfg.py # PPO 超参数
│ │ ├── tracking_env.py # 核心环境类
│ │ └── mdp/ # MDP 组件
│ │ ├── observations.py # 观测计算
│ │ ├── rewards.py # 奖励计算
│ │ └── events.py # 域随机化事件
│ └── utils/
│ └── motion_lib.py # 运动数据加载库
├── scripts/
│ ├── csv_to_npz.py # CSV 转 NPZ 预处理
│ ├── replay_npz.py # NPZ 数据回放验证
│ └── rsl_rl/
│ ├── train.py # 训练入口
│ └── play.py # 评估与导出入口
└── motions/ # 运动数据存放目录
└── g1/
└── *.csv # 参考动作 CSV 文件
6.2 核心文件解读
tracking_env.py —— 环境核心
这是整个训练系统的中枢。它继承自 Isaac Lab 的 ManagerBasedRLEnv,负责协调仿真步进、观测计算、奖励计算和环境重置。每个训练步骤的执行流程如下:
# tracking_env.py 核心循环(简化)
class TrackingEnv(ManagerBasedRLEnv):
def step(self, actions):
# 1. 将策略输出的动作转换为关节目标
joint_targets = self.default_dof_pos + actions * self.action_scale
# 2. 应用 PD 控制,计算关节力矩
torques = self.kp * (joint_targets - self.dof_pos) + self.kd * (0 - self.dof_vel)
# 3. 在仿真中施加力矩,步进物理引擎
self.sim.apply_torques(torques)
for _ in range(self.decimation): # decimation=4, 即每个控制步执行4个物理步
self.sim.step()
# 4. 读取新的状态
self.update_state()
# 5. 计算观测和奖励
obs = self.compute_observations()
rewards = self.compute_rewards()
return obs, rewards, dones, infos
这里有一个关键细节:decimation 参数。物理仿真的时间步长 dt=0.005s(200Hz),但策略的控制频率是 1/(dt * decimation) = 1/(0.005 * 4) = 50Hz。也就是说,策略每输出一个动作,物理引擎会执行 4 步仿真。这种设计既保证了物理仿真的精度,又降低了策略的决策频率,减轻了训练负担。
**observations.py —— 观测计算**
该文件定义了各个观测分量的计算方法。以 motion_command 为例:
def motion_command(env):
"""从参考动作中提取当前时刻的关节位置和速度目标"""
motion_time = env.episode_length_buf * env.dt * env.decimation
ref_joint_pos = env.motion_lib.get_joint_pos(motion_time)
ref_joint_vel = env.motion_lib.get_joint_vel(motion_time)
return torch.cat([ref_joint_pos, ref_joint_vel], dim=-1)
**rewards.py —— 奖励计算**
每个奖励项被实现为一个独立的函数,便于组合和调试:
def joint_pos_tracking(env):
"""关节位置跟踪奖励"""
error = torch.sum((env.dof_pos - env.ref_joint_pos) ** 2, dim=-1)
return torch.exp(-5.0 * error)
def body_pos_tracking(env):
"""身体部位笛卡尔位置跟踪奖励"""
error = torch.sum((env.body_pos - env.ref_body_pos) ** 2, dim=(-2, -1))
return torch.exp(-40.0 * error)
motion_lib.py —— 运动数据管理
这个工具类负责从 WandB Registry 加载 NPZ 格式的运动数据,并提供按时间索引的查询接口。它在内部维护了一个时间索引表,支持线性插值以获取任意时刻的参考状态。
6.3 PD 控制与动作空间
BeyondMimic 的动作空间是关节位置目标空间。策略输出的动作 a 经过以下变换得到实际的关节位置目标:
q_target = default_dof_pos + a * action_scale
其中 default_dof_pos 是机器人的默认站立姿态,action_scale 控制动作的幅度。然后通过 PD 控制器计算关节力矩:
tau = Kp * (q_target - q_actual) + Kd * (0 - dq_actual)
注意速度目标默认为 0,这意味着 PD 控制器会自然地阻尼关节运动,有助于稳定性。Kp 和 Kd 的值因关节而异——承重的腿部关节使用较大的增益(如髋关节 Kp=99),而手臂关节使用较小的增益(如肩关节 Kp=14)。
action_scale 的计算公式为:
action_scale = 0.25 * effort_limit / stiffness
这个公式确保了策略输出在 [-1, 1] 范围内时,关节目标不会超出物理可行的范围。effort_limit 是关节的最大力矩,stiffness 是 PD 控制器的 Kp 值。0.25 的系数提供了额外的安全裕度。
7. 将 BeyondMimic 集成到 rl_sar:从仿真验证到真机部署
这是本文最核心的实践部分。BeyondMimic 在 Isaac Lab 中完成训练后,需要将策略迁移到 rl_sar 框架中进行独立的仿真验证(sim2sim)和真实机器人部署(sim2real)。这个过程远非简单的"复制粘贴",涉及大量的参数对齐、数据格式转换和工程细节。本节将完整记录这一过程中的每个步骤和遇到的关键问题。
7.1 rl_sar 框架概述
rl_sar 是一个开源的强化学习 sim-to-real 部署框架,支持在 MuJoCo 和 Gazebo 仿真器中验证策略,并部署到 Unitree 系列机器人的真实硬件上。该框架使用 C++ 编写核心控制循环,通过 ONNX Runtime 或 LibTorch 加载训练好的策略模型,以满足实时控制对延迟的严格要求。
rl_sar 的架构设计围绕有限状态机(FSM)展开。机器人在不同的控制状态之间切换,每个状态对应一种行为模式。以 G1 机器人为例,其 FSM 包含以下状态:
RLFSMStatePassive ← 被动模式(关节阻尼,无主动控制)
↓ [按键 0 / 手柄 A]
RLFSMStateGetUp ← 起立(从当前姿态插值到默认站立姿态)
↓ [按键 1 / 手柄 RB+DPadUp]
RLFSMStateRLRoboMimicLocomotion ← 行走控制(基础运动策略)
↓ [按键 2-5 / 手柄方向键]
RLFSMStateRLRoboMimicCharleston ← 查尔斯顿舞(Num2)
RLFSMStateRLWholeBodyTrackingDance102 ← Dance 102(Num3)
RLFSMStateRLWholeBodyTrackingGangnamStyle ← 江南 Style(Num4)
RLFSMStateRLWholeBodyTrackingMimic ← 自定义动作(Num5)
↓ [按键 9 / 手柄 B]
RLFSMStateGetDown ← 蹲下(插值回初始姿态)
↓ [完成]
RLFSMStatePassive ← 回到被动模式
每个 FSM 状态在进入时加载对应的策略模型和配置文件,在运行时执行策略推理并输出关节控制指令。这种设计使得同一个机器人可以在运行时动态切换不同的技能,而无需重启程序。
7.2 rl_sar 的配置文件体系
rl_sar 使用 YAML 配置文件管理所有与策略相关的参数。配置文件分为两层:基础配置(base.yaml)和策略配置(config.yaml)。
base.yaml —— 机器人硬件参数
以 G1 23DoF 为例,policy/g1_23/base.yaml 定义了与硬件相关的基础参数:
# policy/g1_23/base.yaml(关键字段摘录)
g1_23:
num_of_dofs: 23
dt: 0.005 # 物理仿真时间步长
decimation: 4 # 控制频率 = 1/(dt*decimation) = 50Hz
# 关节名称(定义了训练时的关节顺序)
joint_names: [
"left_hip_pitch_joint", "left_hip_roll_joint", "left_hip_yaw_joint",
"left_knee_joint", "left_ankle_pitch_joint", "left_ankle_roll_joint",
"right_hip_pitch_joint", "right_hip_roll_joint", "right_hip_yaw_joint",
"right_knee_joint", "right_ankle_pitch_joint", "right_ankle_roll_joint",
"waist_yaw_joint",
"left_shoulder_pitch_joint", "left_shoulder_roll_joint",
"left_shoulder_yaw_joint", "left_elbow_joint", "left_wrist_yaw_joint",
"right_shoulder_pitch_joint", "right_shoulder_roll_joint",
"right_shoulder_yaw_joint", "right_elbow_joint", "right_wrist_yaw_joint"
]
# 默认站立姿态(弧度)
default_dof_pos: [
-0.10, 0.0, 0.0, 0.32, -0.20, 0.0, # 左腿
-0.10, 0.0, 0.0, 0.32, -0.20, 0.0, # 右腿
0.0, # 腰部偏航
0.0, 0.2, 0.0, 0.4, 0.0, # 左臂
0.0, -0.2, 0.0, 0.4, 0.0 # 右臂
]
# 关节映射:训练关节索引 → MuJoCo/SDK 关节索引
# 23DoF 跳过了 29DoF 中的 waist_roll(13), waist_pitch(14),
# left_wrist_pitch(20), left_wrist_yaw(21), right_wrist_pitch(27), right_wrist_yaw(28)
joint_mapping: [0,1,2,3,4,5,6,7,8,9,10,11,12,15,16,17,18,19,22,23,24,25,26]
# 力矩限制
torque_limits: [88,139,88,139,50,50, 88,139,88,139,50,50, 88,
25,25,25,25,25, 25,25,25,25,25]
# 编码器偏置(补偿硬件零点偏差)
use_encoder_bias: true
encoder_bias: [0,0,0,0,0,0, 0,0,0,0,0,0, 0,
0,0,0,0.87,0, 0,0,0,0.87,0]
这里有几个关键点需要特别注意:
第一,joint_mapping 的作用是将训练时的关节索引映射到 MuJoCo 仿真或真实硬件的关节索引。23DoF 的 G1 相比 29DoF 版本去掉了腰部的 roll/pitch 关节和手腕的 pitch/yaw 关节,因此映射数组中出现了跳跃(12 之后直接到 15,19 之后直接到 22)。
第二,encoder_bias 中左右肘关节的偏置值为 0.87 弧度。这是因为 mjlab(BeyondMimic 使用的 MuJoCo 仿真环境)中肘关节的零点定义与 Unitree SDK 不同。如果不加这个偏置,机器人的手臂会出现明显的姿态偏差。
config.yaml —— 策略专属参数
每个策略都有自己的 config.yaml,定义了与该策略相关的特定参数。以 23DoF 全身跟踪策略为例:
# policy/g1_23/whole_body_tracking/config.yaml(关键字段摘录)
g1_23/whole_body_tracking:
model_name: "policy3.pt"
# 观测空间定义(顺序必须与训练时完全一致)
observations: [
"whole_body_tracking/motion_command",
"whole_body_tracking/motion_anchor_ori_b",
"ang_vel", "dof_pos", "dof_vel", "actions"
]
num_observations: 124 # 46 + 6 + 3 + 23 + 23 + 23
clip_obs: 100.0
# 动作裁剪:空数组表示不裁剪(关键!)
clip_actions_lower: []
clip_actions_upper: []
# PD 增益(必须与训练时一致)
rl_kp: [40.179, 99.098, 40.179, 99.098, 28.501, 28.501,
40.179, 99.098, 40.179, 99.098, 28.501, 28.501,
40.179,
14.251, 14.251, 14.251, 14.251, 14.251,
14.251, 14.251, 14.251, 14.251, 14.251]
rl_kd: [2.558, 6.309, 2.558, 6.309, 1.814, 1.814,
2.558, 6.309, 2.558, 6.309, 1.814, 1.814,
2.558,
0.907, 0.907, 0.907, 0.907, 0.907,
0.907, 0.907, 0.907, 0.907, 0.907]
# 动作缩放(与训练时一致)
action_scale: [0.548, 0.351, 0.548, 0.351, 0.439, 0.439,
0.548, 0.351, 0.548, 0.351, 0.439, 0.439,
0.548,
0.439, 0.439, 0.439, 0.439, 0.439,
0.439, 0.439, 0.439, 0.439, 0.439]
# 参考动作 CSV 文件
motion_file: "G1_Take_102.bvh_50hz_23dof.csv"
# 运动数据关节映射(从 29DoF CSV 中选取 23DoF 对应的列)
motion_joint_mapping: [0,1,2,3,4,5,6,7,8,9,10,11,12,
15,16,17,18,19,22,23,24,25,26]
# 腰部关节索引(用于锚点朝向计算)
waist_joint_indices: [12]
7.3 MotionLoader:运动数据的 C++ 加载器
在 BeyondMimic 的训练环境中,参考动作由 Python 的 motion_lib.py 管理。但在 rl_sar 的 C 部署环境中,需要一个等价的 C 实现来加载和插值参考动作数据。这就是 MotionLoader 类的作用。
MotionLoader 从 CSV 文件中读取参考动作数据,并提供按时间查询的接口。其核心功能包括:
// motion_loader.hpp 核心接口
class MotionLoader {
public:
MotionLoader(const std::string& motion_file, float fps);
void Update(float time); // 更新到指定时间
void Reset(const std::vector<float>& robot_base_quat,
const std::vector<float>& robot_waist_angles); // 重置并对齐偏航角
std::vector<float> GetJointPos() const; // 获取插值后的关节位置
std::vector<float> GetJointVel() const; // 获取插值后的关节速度
std::vector<float> GetRootQuat() const; // 获取根节点四元数
std::vector<float> GetAnchorQuat() const; // 获取锚点(躯干)四元数
float GetDuration() const; // 获取动作总时长
};
MotionLoader 的一个关键设计是偏航角对齐(Yaw Alignment)。当机器人开始执行舞蹈动作时,它的朝向可能与参考动作的初始朝向不一致。Reset() 方法通过计算机器人当前躯干朝向与参考动作初始躯干朝向之间的偏航角差异,生成一个旋转变换矩阵,使得参考动作的朝向与机器人的实际朝向对齐。
锚点四元数的计算也值得关注。对于 G1 机器人,锚点定义为躯干(torso),其朝向由骨盆(root)朝向加上腰部关节的旋转得到:
torso_quat = root_quat * Rz(waist_yaw) * Rx(waist_roll) * Ry(waist_pitch)
对于 23DoF 的 G1,由于没有 waist_roll 和 waist_pitch 关节,这两个角度默认为 0,简化为:
torso_quat = root_quat * Rz(waist_yaw)
7.4 FSM 状态实现:以 WholeBodyTracking 为例
理解 FSM 状态的实现方式,是添加新舞蹈动作的基础。以下是 RLFSMStateRLWholeBodyTrackingDance102 状态的完整实现逻辑:
class RLFSMStateRLWholeBodyTrackingDance102 : public RLFSMState {
public:
void Enter() override {
rl.episode_length_buf = 0;
// 1. 加载策略配置
rl.config_name = "whole_body_tracking/dance_102";
std::string robot_config_path = rl.robot_name + "/" + rl.config_name;
rl.InitRL(robot_config_path);
// 2. 初始化运动数据加载器
std::string motion_file_path = std::string(POLICY_DIR) + "/"
+ robot_config_path + "/"
+ rl.params.Get<std::string>("motion_file");
float fps = 1.0f / (rl.params.Get<float>("dt")
* rl.params.Get<int>("decimation"));
rl.motion_loader = std::make_unique<MotionLoader>(
motion_file_path, fps);
rl.motion_length = rl.motion_loader->GetDuration();
// 3. 偏航角对齐
rl.motion_loader->Reset(
fsm_state->imu.quaternion,
GetWaistAnglesSafe(rl, fsm_state));
}
void Run() override {
if (!rl.rl_init_done) rl.rl_init_done = true;
// 计算当前动作时间
float motion_time = rl.episode_length_buf
* rl.params.Get<float>("dt")
* rl.params.Get<int>("decimation");
motion_time = std::fmin(motion_time, rl.motion_length);
// 更新参考动作到当前时间
rl.motion_loader->Update(motion_time);
// 执行策略推理 + PD 控制
RLControl();
// 动作播放完毕后切换回行走模式
if (motion_time / rl.motion_length == 1) {
rl.fsm.RequestStateChange(
"RLFSMStateRLRoboMimicLocomotion");
}
}
};
Enter() 方法在状态进入时执行一次,负责加载策略模型、初始化运动数据、对齐偏航角。Run() 方法在每个控制周期执行,负责更新参考动作时间、执行策略推理、输出控制指令。当动作播放完毕(motion_time 达到 motion_length)时,自动切换回行走模式。
如果要添加一个新的舞蹈动作,只需要:(1)准备好策略模型文件和参考动作 CSV 文件;(2)创建对应的 config.yaml;(3)在 fsm_g1.hpp 中仿照上述模式添加一个新的 FSM 状态类;(4)在 G1FSMFactory 中注册该状态。
7.5 踩坑记录:从 mjlab 训练到 rl_sar 部署的关键问题
将 BeyondMimic(mjlab)训练的策略迁移到 rl_sar 时,有若干极易出错的参数对齐问题。以下是实际部署过程中遇到的典型问题及其解决方案,每一个都可能导致机器人行为完全异常。
问题一:机器人"起飞"——PD 增益和力矩限制不匹配
现象:在 MuJoCo sim2sim 中加载策略后,机器人瞬间弹射到空中或剧烈抖动。
原因:rl_sar 默认的 PD 增益和力矩限制来自 Unitree 官方的行走策略配置,其 Kp 值通常在 100-300 的范围,力矩限制高达 300 Nm。而 BeyondMimic 训练时使用的是 MuJoCo position actuator 等效的增益值,Kp 范围在 14-99,力矩限制为 88/139/50/25 Nm。两者相差数倍。
当使用过大的 Kp 值时,即使策略输出的关节目标偏差很小,PD 控制器也会产生巨大的力矩,导致机器人失控。
解决方案:将 config.yaml 中的 rl_kp、rl_kd 和 base.yaml 中的 torque_limits 严格对齐到 mjlab 训练时的值:
# 正确的 23DoF PD 增益(来自 mjlab 训练配置)
rl_kp: [40.179, 99.098, 40.179, 99.098, 28.501, 28.501,
40.179, 99.098, 40.179, 99.098, 28.501, 28.501,
40.179,
14.251, 14.251, 14.251, 14.251, 14.251,
14.251, 14.251, 14.251, 14.251, 14.251]
# 正确的力矩限制(不是 300!)
torque_limits: [88,139,88,139,50,50, 88,139,88,139,50,50, 88,
25,25,25,25,25, 25,25,25,25,25]
问题二:机器人"趴在地上打滚"——动作裁剪范围错误
现象:机器人能站起来,但一进入策略控制就倒地并在地面上翻滚。
原因:rl_sar 的默认配置中 clip_actions 的范围设置为 [-100, 100]。而 BeyondMimic 的 mjlab 训练环境中,RSL-RL runner 默认不对动作进行裁剪(clip_actions=None)。当 rl_sar 使用 [-100, 100] 的裁剪范围时,虽然看起来范围很大不会实际裁剪,但这个配置会触发 rl_sar 内部的裁剪逻辑路径,可能引入数值精度问题。
更关键的是,如果错误地将裁剪范围设为 [-1, 1](某些行走策略的配置),策略输出会被严重截断,导致机器人无法执行大幅度动作。
解决方案:将 clip_actions_lower 和 clip_actions_upper 设为空数组,完全禁用动作裁剪:
# 正确配置:不裁剪动作
clip_actions_lower: []
clip_actions_upper: []
问题三:动作节奏不对——CSV 帧率不匹配
现象:机器人的动作看起来大致正确,但节奏明显偏快或偏慢,与参考视频不同步。
原因:BeyondMimic 训练时将参考动作从原始帧率(如 30fps)插值到了 50fps(对应 dt=0.005s、decimation=4 的控制频率)。如果部署时使用的 CSV 文件仍然是原始的 30fps 或 60fps 版本,MotionLoader 会按照错误的时间尺度播放动作。
解决方案:确保部署使用的 CSV 文件帧率与训练时一致。对于 23DoF 策略,应使用 50Hz 重采样的 CSV 文件:
# 正确:使用 50Hz 重采样的 CSV
motion_file: "G1_Take_102.bvh_50hz_23dof.csv"
# 错误:使用原始 60Hz 的 CSV
# motion_file: "G1_Take_102.bvh_60hz.csv"
如果手头只有其他帧率的 CSV,可以使用 Python 脚本进行重采样:
import pandas as pd
import numpy as np
from scipy.interpolate import interp1d
# 读取原始 CSV(假设 60fps)
data = pd.read_csv("motion_60hz.csv", header=None).values
original_fps = 60
target_fps = 50
# 生成时间轴
t_original = np.arange(len(data)) / original_fps
t_target = np.arange(0, t_original[-1], 1.0 / target_fps)
# 逐列插值
interpolator = interp1d(t_original, data, axis=0, kind='linear')
resampled = interpolator(t_target)
# 保存
np.savetxt("motion_50hz.csv", resampled, delimiter=",", fmt="%.6f")
问题四:23DoF 腰部关节处理
现象:23DoF 机器人的躯干朝向计算出现异常,导致 motion_anchor_ori_b 观测值错误。
原因:MotionLoader 在计算锚点四元数时,默认使用 joint[12](waist_yaw)、joint[13](waist_roll)、joint[14](waist_pitch)三个关节。但 23DoF 的 G1 没有 waist_roll 和 waist_pitch 关节。如果 CSV 文件中这两列仍然包含非零值(从 29DoF 的 CSV 直接截取),锚点朝向计算就会出错。
解决方案:在生成 23DoF 的 CSV 文件时,必须将 waist_roll(第 13 列)和 waist_pitch(第 14 列)的值置零。同时在 config.yaml 中正确设置 waist_joint_indices:
# 23DoF:只有 waist_yaw
waist_joint_indices: [12]
# 29DoF:三个腰部关节都有
# waist_joint_indices: [12, 13, 14]
快速自检清单
在每次部署新策略时,按照以下清单逐项检查,可以避免绝大多数问题:
□ model_name 是否指向正确的模型文件?(.pt 或 .onnx)
□ clip_actions_lower/upper 是否为空数组?(mjlab 训练不裁剪)
□ action_scale 是否与训练配置一致?(0.25 * effort_limit / stiffness)
□ rl_kp / rl_kd 是否与 mjlab 的 MuJoCo actuator 增益一致?
□ torque_limits 是否为 88/139/50/25 体系?(不是 300)
□ motion CSV 的帧率是否为 50Hz?(匹配 dt*decimation)
□ motion CSV 的自由度数是否正确?(23DoF 需要零化 waist_roll/pitch)
□ joint_mapping 是否正确跳过了不存在的关节?
□ encoder_bias 是否已配置?(肘关节 0.87)
□ num_observations 是否与模型输入维度一致?(23DoF=124, 29DoF=154)
7.6 Sim2Sim 仿真验证
在将策略部署到真实机器人之前,必须先在 MuJoCo 仿真中进行验证。rl_sar 提供了完整的 MuJoCo sim2sim 环境。
编译与运行
# 编译 rl_sar(确保已安装 MuJoCo、ONNX Runtime 等依赖)
cd rl_sar
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
# 运行 MuJoCo 仿真
./rl_sim
程序启动后,MuJoCo 可视化窗口会显示 G1 机器人站立在平面上。此时机器人处于 Passive 状态(关节阻尼模式)。按照以下步骤操作:
1. 按 Enter 键启动仿真循环
2. 按 0 键进入 GetUp 状态(机器人缓慢站起)
3. 等待站立完成后,按 3 键进入 Dance102 状态
(或按 4 进入 GangnamStyle,按 5 进入自定义 Mimic)
4. 观察机器人是否正确执行舞蹈动作
5. 动作完成后自动切换回 Locomotion 状态
6. 按 9 键蹲下,按 P 键回到 Passive 状态
在仿真验证过程中,需要重点观察以下几点:
- • 机器人是否能稳定站立而不倒?如果站立就倒,检查 PD 增益和力矩限制。• 动作幅度是否合理?如果动作过小或过大,检查 action_scale。• 动作节奏是否与参考视频一致?如果不一致,检查 CSV 帧率。• 手臂姿态是否正确?如果肘部角度异常,检查 encoder_bias。
7.7 Sim2Real 真机部署
仿真验证通过后,即可将策略部署到真实的 Unitree G1 机器人上。rl_sar 的真机部署通过 Unitree SDK 与机器人通信,控制循环运行在外部计算机上。
部署前准备
1. 确保机器人固件版本与 Unitree SDK 兼容
2. 通过以太网连接机器人和控制计算机
3. 确认网络连通性(ping 机器人 IP)
4. 将策略模型文件和配置文件部署到控制计算机上
5. 准备安全绳/支架,防止机器人摔倒
运行真机控制
# 启动真机控制程序
sudo ./rl_real_g1
真机控制的操作流程与仿真类似,但需要额外注意安全:
1. 程序启动后,机器人处于 Passive 状态
2. 确认机器人周围无障碍物
3. 按 M 键使能电机(Motor Enable)
4. 按 0 键起立
5. 起立完成后,按对应数字键切换到目标技能
6. 随时准备按 P 键切回 Passive 模式(紧急停止)
7. 结束后按 K 键失能电机(Motor Disable)
真机部署时的额外注意事项:
- • 首次部署新策略时,建议使用安全绳悬挂机器人,先验证动作的大致正确性。
- • 注意观察关节温度,高动态动作可能导致电机过热。
- • 如果机器人出现异常抖动,立即按 P 键切回 Passive 模式。
- • 真机的地面摩擦、关节摩擦等物理参数与仿真存在差异,策略的表现可能不如仿真中完美,这是正常的 sim-to-real gap。
8. 与 UniTracker 的对比分析
在讨论 BeyondMimic 之前,有必要提及另一个重要的人形机器人运动跟踪框架——UniTracker。两者都致力于让人形机器人复现人类动作,但在技术路线和设计哲学上存在显著差异。理解这些差异有助于读者根据自身需求选择合适的方案。
8.1 技术路线对比
UniTracker 采用的是"统一跟踪器"的思路,试图用一个通用的策略网络处理多种不同类型的运动任务。它通过将不同的运动参考信号(关节轨迹、末端执行器轨迹、质心轨迹等)统一编码为标准化的观测格式,使得同一个策略可以跟踪来自不同来源的运动指令。
BeyondMimic 则走了一条不同的路线。它首先训练一个高质量的运动跟踪策略(Motion Tracking Policy),然后在此基础上通过引导扩散(Guided Diffusion)模型生成新的运动轨迹,实现从"模仿"到"创造"的跨越。换言之,BeyondMimic 的运动跟踪只是第一步,其最终目标是让机器人具备多功能的运动能力。
8.2 关键差异
从工程实践的角度,两者的主要差异体现在以下几个方面:
训练框架:UniTracker 基于 Isaac Gym(较早版本的 NVIDIA 仿真平台),而 BeyondMimic 基于 Isaac Lab(Isaac Gym 的继任者)。Isaac Lab 提供了更模块化的 API 和更好的可扩展性,但也意味着更高的学习成本。
观测空间:UniTracker 的观测空间设计更加紧凑,通常不包含完整的参考动作关节位置和速度,而是使用更抽象的运动特征。BeyondMimic 则直接将参考动作的关节位置和速度作为观测的一部分(motion_command),信息更加直接但维度更高。
动作质量:在高动态动作(如跳跃、旋转)的跟踪质量上,BeyondMimic 凭借其自适应采样机制和精心设计的奖励函数,通常能达到更高的保真度。这也是其论文标题中"Beyond"一词的含义——超越简单的模仿。
部署便利性:UniTracker 的部署流程相对简单,因为其策略网络的输入输出接口更加标准化。BeyondMimic 的部署则需要额外处理参考动作数据的加载和同步,如本文第七部分所详细描述的那样。
8.3 选择建议
如果项目需求是让机器人跟踪特定的舞蹈或运动动作,且对跟踪质量有较高要求,BeyondMimic 是更好的选择。如果需求是构建一个通用的运动控制框架,能够灵活响应不同类型的运动指令,UniTracker 的架构可能更合适。在实际项目中,两者的技术思路并不互斥,完全可以借鉴各自的优点进行组合。
9 总结
当前的流程虽然已经能够实现从视频到机器人跳舞的完整链路,但仍有若干值得探索的方向:
- • 实时运动生成:当前流程是离线的——先录制视频、提取动作、训练策略、再部署。未来可以探索实时的视频到动作生成管线,实现"看到就能做"的即时模仿能力。• 多技能融合:BeyondMimic 的引导扩散模块已经展示了从单一跟踪到多功能控制的可能性。将多个舞蹈技能与行走、平衡等基础能力无缝融合,是实现真正通用人形机器人控制的关键。• 自适应 sim-to-real:当前的域随机化是"盲目"的——在训练时随机扰动所有参数。未来可以结合系统辨识技术,根据真实机器人的实际物理参数自适应地调整仿真环境,进一步缩小 sim-to-real gap。
参考资料
- 1. BeyondMimic 论文:https://arxiv.org/abs/2508.082412. BeyondMimic 项目主页:beyondmimic.github.io3. BeyondMimic 代码仓库:github.com/HybridRobotics/whole_body_tracking4. rl_sar 代码仓库:github.com/fan-ziqi/rl_sar5. GVHMR 代码仓库:github.com/zju3dv/GVHMR6. GMR 代码仓库:github.com/YanjieZe/GMR7. NVIDIA Isaac Lab 文档:isaac-sim.github.io/IsaacLab8. Unitree G1 技术文档:support.unitree.com9. GVHMR、GMR、Beyondmimic实现G1从RGB视频中学习动作:https://blog.csdn.net/sjdjdjsj/article/details/15524241910. BeyondMimic——从跳舞好手到通过引导扩散实现多功能控制:基于Diffuse-CLoC构建扩散框架,可模仿动作、导航避障:https://blog.csdn.net/v_JULY_v/article/details/150955950
883