工程实战:机器人动作数据重定向
在何泰然大佬的几篇工作中,都用到了动作重定向这部分工作,由于不是工作核心,我们直接从代码层面进行实践,论文的解读可以参考我之前文章(传送门)。
算法是大脑,那数据就是“教科书”,数据重定向就是把这本“火星文”(人类动作数据)教科书翻译成机器人能看懂的“简体中文”。
由于 H2O、HOVER、ASAP 在重定向的部分都大同小异,并且在工程上都有独立的接口,即通过 pkl 数据文件进行交互。我们就主要从他们引用的重定向工作的原始仓库“PHC”进行实践,PHC 的作者也是与何泰然共 H2O 的一作。所以也是建议动作重定向和遥操作学习解耦开,重定向就在 PHC 工程下做就行了,然后把动作数据放到遥操作的项目里。或者在 ASAP 的仓库下做,因为 ASAP 把这部分工作更精简清晰一点。
虽然 PHC 包含了其他工作,但我们只使用 PHC 工程下的重定向部分:
# Retargeting to Your Own Humanoids
To retarget SMPL data to your own humanoids, you need to follow the following steps:
First, download and setup the SMPL body models as well as AMASS data (code is provided in the [README.md](../README.md)).
Then, run the following scripts to fit the SMPL motion and shape to your humanoids. We will use unitree_g1 as an example.
First, we will find the SMPL shape parameters that best fit the humanoid.
python scripts/data_process/fit_smpl_shape.py robot=unitree_g1_fitting
Then, we will find the SMPL motion parameters that best fit the humanoid. (pass in `+fit_all=True` to fit all the motion clips in AMASS, otherwise only fit one motion)
python scripts/data_process/fit_smpl_motion.py robot=unitree_g1_fitting +amass_root=/path/to/your/amass/data
To visualize the fitted motion, you can run the following script.
python scripts/vis/vis_q_mj.py robot=unitree_g1_fitting +motion_name=0-Transitions_mocap_mazen_c3d_dance_stand_poses
其实说来我也不知道为什么 H2O 系列工作都是引用的 PHC 的项目,虽然 PHC 的仓库里包含了动作重定向的内容,但这也不是 PHC 论文的工作啊?
我们这里使用开源的 天宫URDF 模型,重定向后的可视化效果如下,一个简单的出拳的动作:
关于安装和数据,主要需要下载 SMPL 和 AMASS 数据。
SMPL:A Skinned Multi-Person Linear Model,
SMPL官方链接
SMPL 可以认为是人类的骨骼数字模型,一个精准的、参数化的人体数字“模特”,骨骼绑定到三维模型上,这样当骨骼移动时,模型也会随之变形。可以用在各种类人智能体的运动模型上,游戏、动画、包括我们机器人模仿学习。
有了骨骼模型后,其实还不会动,因为没有动作数据,所以接下来就是下载 AMASS 数据:
AMASS官方链接
AMASS 可以理解为一个超大型的人体运动捕捉数据集的“整合包”,AMASS 利用 SMPL 模型,将五花八门的原始运动捕捉数据,都转化成了一系列由 SMPL 模型表现出来的标准的,逼真的人体运动,从而构建了 AMASS 这个强大的数据集。如果说 SMPL 是模特,那 AMASS 就是一本收录了这位模特所有 Pose 的“动作百科全书”,它整合了海量的真人动捕数据,从走路、跑步到跳舞、打拳,应有尽有,并且都用 SMPL 模型标准化了。
下载安装这俩是第一步,跟着仓库的 README 走就行,包括环境和依赖的安装,这里不再赘述。
一、磨刀不误砍柴工:先理解“工具”
有了以上数据内容后,其实和机器人还没什么关系,那接下来的工作就是把人体数据转换为机器人数据了,也就是我们领域要关注的问题了,也就是我们这里 PHC 要做的事情。
简而言之,通过 fit_smpl_shape.py 和 fit_smpl_motion.py,实现人类 AMASS 动作数据到机器人骨骼下可用于学习的动作数据的转换,如果不转换,人类骨骼尺寸、幅度等等和机器人差异较大,很难用于后续的动作模仿等学习。
- 通过
fit_smpl_shape进行形状拟合,找到最适合机器人的 SMPL 体型参数,通过优化多个形状和缩放参数,让 SMPL 关键关节位置与机器人默认 T-pose 下的关节位置尽可能贴近。 - 通过
fit_smpl_motion进行动作拟合,将 AMASS 动作序列转换为机器人的关节角度序列,通过正解机器人关节角度后,对比两者对应部位的空间距离,使用梯度下降,逐步调节关节角度,最小化每一帧中这个空间距离。
这个流程的好处是解耦。你只需要跑一次 fit_smpl_shape,生成一个 shape_optimized.pkl 文件,这个“体型定制参数”就能一直用下去。之后,无论你想翻译多少个动作,都用这套参数去跑 fit_smpl_motion 就行。
fit_smpl_motion 结束后,同样产生一个 pkl 数据,但这回里面是包含了你所提供的要拟合的目标动作,比如整个 AMASS 数据集或者其中某一个动作数据。这里,H2O、HOVER 会需要使用更多的数据,比如他们建议用整个 AMASS 数据集,因为学习目标是“遥操作”,而 ASAP 会只产生单独动作的数据,因为学习目标是“模仿学习”。
二、开干!三步搞定你自己的机器人配置
大道理讲完了,上代码!哦不,上配置!这部分工作的灵魂,其实就是修改 YAML 配置文件。
我们把目光锁定到这个文件:phc/data/cfg/robot/unitree_g1.yaml。这是官方给的 G1 机器人示例,我们要做的,就是把它复制一份,改成我们自己机器人的版本,比如 my_bot_cfg.yaml。
当然,你得先准备好自己机器人的 MJCF(MuJoCo 的 xml)模型文件。直接导出的模型可能跑不起来,根据报错改改就行,常见问题是 worldbody 下的 body 数量和自由度对不上,或者缺了一些定义。
好了,打开你的 YAML 文件,这是我们今天的主战场!
2.1 关节匹配
在 yaml 配置里,首先是动作部位对齐的字段的定义:
以 g1 为例,左边是你机器人 URDF/MJCF 里的 link 名字,右边是 SMPL 模型里对应的部位:
joint_matches:
- ["pelvis", "Pelvis"]
- ["left_hip_pitch_link", "L_Hip"]
- ["left_knee_link", "L_Knee"]
- ["left_ankle_roll_link", "L_Ankle"]
- ["right_hip_pitch_link", "R_Hip"]
- ["right_knee_link", "R_Knee"]
- ["right_ankle_roll_link", "R_Ankle"]
- ["left_shoulder_roll_link", "L_Shoulder"]
- ["left_elbow_pitch_link", "L_Elbow"]
- ["left_zero_link", "L_Hand"]
- ["right_shoulder_roll_link", "R_Shoulder"]
- ["right_elbow_pitch_link", "R_Elbow"]
- ["right_zero_link", "R_Hand"]
- ["head_link", "Head"]
我们要套用自己的机器人,需要改为自己机器人连杆对应的字段,大部分根据名字填就行,但有些地方可能需要琢磨一下,比如 hip 关节,你到底用 hip_pitch_link 还是 hip_roll_link 去对齐 SMPL 的 Hip?这得看你机器人的设计,可以都试试。
2.2 扩展配置
很多机器人模型,特别是为了控制简化的,可能压根就没定义“手”和“头”的 link。但重定向的时候又需要这些部位来对齐,咋办?extend_config 就是来解决这个问题的。它允许你在机器人的某个 link 上,“虚拟”地长出一个新的部位来。
看 G1 的例子,它有手,但没头:
extend_config:
- joint_name: "head_link"
parent_name: "pelvis"
pos: [0.0, 0.0, 0.4]
rot: [1.0, 0.0, 0.0, 0.0]
再看 H1 的例子,手和头都没有:
extend_config:
- joint_name: "left_hand_link"
parent_name: "left_elbow_link"
pos: [0.3, 0.0, 0.0]
rot: [1.0, 0.0, 0.0, 0.0]
- joint_name: "right_hand_link"
parent_name: "right_elbow_link"
pos: [0.3, 0.0, 0.0]
rot: [1.0, 0.0, 0.0, 0.0]
- joint_name: "head_link"
parent_name: "pelvis"
pos: [0.0, 0.0, 0.6]
rot: [1.0, 0.0, 0.0, 0.0]
rot 旋转基本都是 [1,0,0,0],但注意这个 pos!坐标系很关键。头在躯干(pelvis)正上方,所以是 [0, 0, 0.4]。如果你的机器人手臂默认是垂直向下的,那手应该在肘的正下方,比如 [0, 0, -0.3]。而 H1 的手臂默认是水平的(像端盘子),所以手在肘的 x 轴方向延伸,就是 [0.3, 0, 0]。方向错了,优化会非常难对齐,loss 会非常大,甚至会优化出一些畸形的模型。
2.3 初始姿态调整
最后就是 smpl 的初始态的调整了:
smpl_pose_modifier:
- Pelvis: "[np.pi/2, 0, np.pi/2]"
- L_Shoulder: "[0, 0, -np.pi/2]"
- R_Shoulder: "[0, 0, np.pi/2]"
- L_Elbow: "[0, -np.pi/2, 0]"
- R_Elbow: "[0, np.pi/2, 0]"
这一步的目的是,在开始优化前,先手动调整一下 SMPL 模型的初始姿态,让它尽量和你机器人的默认 T-pose 长得像。
为啥要这么做?因为直接让 SMPL 从标准大字形 T-pose 去拟合一个奇形怪状的机器人骨架,优化器会很痛苦,算出来的结果可能很差(loss 很高)。我们先手动把它掰扯得差不多了,优化器再进行微调,就能事半功倍。
怎么调?没啥捷径,暴力调参,改改参数,跑一下 fit_smpl_shape,看看出来的 loss,再看看可视化效果,找一个 loss 最低、看起来最顺眼的结果就行。这个过程有点繁琐但不难。
三、见证奇迹:从“卖家秀”到“买家秀”
配置改完,依次运行 fit_smpl_shape 和 fit_smpl_motion,你就能得到属于你自己机器人的动作数据(.pkl 文件)了!
看看效果,以宇树 H1 为例,这是优化前后的 SMPL 骨架和机器人骨架的贴合度对比,以下是可视化的侧视图,左边是优化后,右边是优化前,效果一目了然。

再看看我们用开源的天宫模型跑出来的 fit_shape 优化后效果,也还 OK:

最后,把生成的动作数据可视化一下,比如这个拳击动作,是不是有内味儿了?

最后在模型训练上测试一下,测试发现,用 h1 配置生成的动作数据,在 HOVER 项目里可以顺利训练并跑出不错的效果,以下两组数据分别是用 HOVER 自带的转换和从 PHC 的脚本转换后训练得到的 mean_reward 结果。
好了,今天这趟“数据前处理”的浑水就趟到这里。这套流程是后续所有模仿学习、遥操作任务的基石,代码都开源了,干就完了!
下回咱们再聊聊,拿到这些数据后,训练过程里又有哪些不为人知的坑哈哈。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)