当前位置: 首页 > news >正文

GMR 工程实践笔记:把自己的机器人接入动作重定向流程

上一篇理论篇主要聊了 GMR 的方法逻辑:关键体匹配、默认姿态对齐、非均匀局部缩放,以及两阶段 IK。理论上看起来比较清楚,但真正接入自己的机器人时,重点并不是“能不能跑通脚本”,而是:如何配置出一套稳定、可复用、质量还不错的smplx_to_robot映射表。

本文主要记录一次将自定义机器人接入 GMR 的实践流程和调试经验,不深扒代码细节,重点放在工程配置和一些实际踩坑点上。

理论篇参考上一篇文章:传送门
GMR 项目主页:https://jaraujo98.github.io/retargeting_matters/
代码仓库:https://github.com/YanjieZe/GMR


一、第一次接入自定义机器人的基本流程

第一次给自己的机器人做重定向,大致流程如下:

1. 放入自己的机器人 URDF 2. 补齐需要参考的连杆点,例如手、头、脚趾等 3. 将 URDF 转为 XML / MJCF 格式 4. 创建对应机器人的 ik_configs 配置文件 5. 在脚本加载项中注册机器人名称和模型路径 6. 根据机器人结构修改 ik_configs,配置映射部位和比例 7. 在两张 IK match 表中配置映射关系、权重、位置偏移和旋转偏移 8. 选择几段代表性动作进行重定向 9. 观察动作质量和匹配误差 10. 根据结果调整权重、offset 和 scale

这里最麻烦的是第一次配置。只要机器人配置稳定下来,后续换新的动作数据时,流程会简单很多,基本就是放入动作、运行重定向、检查结果。

整体上,这也和论文中的流程是一致的:

1. 找到人体和机器人的对应部位 2. 调整默认姿态和方向 3. 调整缩放比例 4. 配置两阶段 IK 权重 5. 计算得到机器人动作


二、URDF 不一定够,需要补参考连杆

GMR 的匹配对象是人体骨架 body 和机器人 link。
所以有些机器人虽然模型能正常仿真,但未必有足够适合重定向的参考 link。

比较常见需要补的点包括:

head left_hand / right_hand left_toe / right_toe torso reference point

这些点不一定需要自由度,可以用 fixed joint 加到 URDF 里。它们的作用不是改变机器人运动能力,而是提供更明确的空间参考。

比如脚部,如果只有 ankle,没有 toe 或 foot 参考点,那么脚掌方向的约束会比较弱。对于步行、转身、跑步这类动作,脚掌方向其实非常关键。
一个G1的参考点示意图:


三、核心配置:smplx_to_robot映射表

GMR 配置里最重要的是人体骨架到机器人 link 的映射表。以 G1 的一段配置为例:

"left_knee_link":["left_knee",0,10,[0.0,0.0,0.0],[0.5,-0.5,-0.5,-0.5]],

这一项从上到下分别是:

机器人连杆 人体骨架部位 位置权重 旋转权重 xyz 位置偏移 wxyz 四元数旋转偏移

也就是:

字段含义
left_knee_link机器人参与 IK 匹配的 link
left_knee人体骨架中对应的 body
0位置跟踪权重
10旋转跟踪权重
[0.0, 0.0, 0.0]位置偏移
[0.5, -0.5, -0.5, -0.5]旋转偏移,格式为 wxyz

这个表基本决定了机器人最终会“相信”人体骨架中的哪些点,以及相信到什么程度。


四、权重为 0,就是不跟踪

在 IK match 表中,权重非常直接。

如果某个部位的位置权重和旋转权重都设为 0,那么这个部位实际上就不会参与跟踪。比如把左手肘和左手腕权重都设为 0,可以看到机器人左臂基本保持 URDF 默认姿态,不会主动追踪人体动作。

左手肘和左手腕权重设为 0 后的重定向效果:

这点在调试时很有用。
不是所有人体关节都应该强行对齐,尤其是机器人没有对应自由度,或者 link 定义和人体差异较大时,高权重反而容易制造问题。

一个典型例子是 G1 的torso_link - spine3。即便两者空间位置相差比较大,只要位置权重设为 0,就不会对重定向结果产生强约束。

所以配置映射表时,不要只看有没有对应关系,更要看权重是否合理。


五、人体关节很多,但不需要全都对齐

可用的人体关节很多,例如:

body_joint_names=["Pelvis","Left_Hip","Right_Hip","Spine1","Left_Knee","Right_Knee","Spine2","Left_Ankle","Right_Ankle","Spine3","Left_Foot","Right_Foot","Neck","Left_Collar","Right_Collar","Head","Left_Shoulder","Right_Shoulder","Left_Elbow","Right_Elbow","Left_Wrist","Right_Wrist","Left_Hand","Right_Hand"]

但实际配置时,不建议一股脑全部高权重对齐。约束太多容易过拟合,表现出来可能是:

动作抖动 局部关节异常扭动 腿部或手臂姿态不自然 为了满足某个点导致整体姿态变形

我的理解是,映射选择应该优先考虑三个问题:

1. 机器人是否真的有这个部位? 2. 这个部位对动作质量是否关键? 3. 机器人是否有能力合理实现这个约束?

比如机器人没有头部自由度,却高权重跟踪Head的方向,可能会导致机器人通过扭腰或扭 torso 去代偿头部旋转,结果反而很怪。

脚部则相反,通常值得重点关注。因为脚部不仅影响动作像不像,还直接影响接触、落地和稳定性。

例如,实践中,使用foot作为脚部主要参考点,效果通常比只用ankle更好一些。

原因大概是:ankle更像一个点,而foot更能表达脚掌方向。虽然 ankle 到 foot 之间可能没有额外自由度,但 foot 的方向信息对步态很有帮助,尤其是转身、跑步、落脚这类动作。

也可以 foot 和 ankle 都用,但权重不要太激进。脚部约束过强时,腿部姿态也可能变僵。

只使用 ankle、只使用 foot的效果对比


六、四元数偏移:本质是坐标系对齐

四元数 offset 是调试中最容易困惑的部分。

比如常见的:

[0.5,-0.5,-0.5,-0.5]

它并不是经验玄学,而是在做坐标系对齐。
GMR 中四元数格式是wxyz,这一点要特别注意。

原始动作骨架的默认状态中,关节四元数基本都是:

[1,0,0,0]

但这只说明它在骨架自己的坐标系下没有旋转,并不代表它和机器人 link 的局部坐标系一致。

观察原始骨架可以看到,它可能是面朝上躺平的大字形态,且轴系大致表现为:

z 轴朝身体前方 y 轴垂直身体 x 轴朝身体侧方


[1, 0, 0, 0]应用[0.5, -0.5, -0.5, -0.5]后,可以看到原本朝前的 z 轴被旋到 x 轴方向,原本朝左的 x 轴被旋到 y 轴方向,这样更接近常见机器人模型的 link 坐标定义。

这里最重要的原则是:

四元数 offset 不是为了让某一帧动作看起来顺眼,而是为了在默认姿态下对齐机器人 link 的局部坐标系。

虽然[0.5, -0.5, -0.5, -0.5]在很多位置上有效,但不是所有 link 都适用。

比如 G1 的 hip 部位使用的是right_hip_roll_link,它的局部轴系并不和 torso 保持一致,所以需要单独配置:

"right_hip_roll_link":["right_hip",0,10,[0.0,0.0,0.0],[0.4267755048530407,-0.5637931078484661,-0.5637931078484661,-0.4267755048530407]],


hip 使用特殊offset 后的效果:

可以发现,这套偏移是更符合机器人的坐标系设定的,这说明 offset 要看机器人 link 自己的坐标系,而不是无脑都套用同一套偏移。

手臂也类似。人体骨架通常是大字型姿态,而机器人默认一般是垂手姿态,G1 的手肘还带有一定弯曲。因此肩部配置会使用类似:

"left_shoulder_yaw_link":["left_shoulder",0,10,[0.0,0.0,0.0],[0.70710678,0.0,-0.70710678,0.0]],

在这个配置下,如果把机器人 shoulder roll 调到 90°,让手臂打直,会发现这个偏移量和机器人坐标系是匹配的,包括后续的小臂和手部也同理。

不过这里还有一个我暂时没有完全确认的问题:目前这种“手动旋转机器人后再观察匹配”的方式,更像是一个工程辅助验证方法,而不一定是严格的代码设计逻辑。仓库中并没有明确说明需要先旋转机器人再匹配,因此这里还需要继续研究坐标变换的真实顺序。


七、xyz offset 和 scale:直观,但最费时间

相比四元数,xyz offset 和 scale 更直观,但更依赖具体机器人和动作数据。

影响因素包括:

人体骨架身高和比例 机器人腿长、臂长、躯干比例 机器人 link 原点定义 foot / ankle / toe 的选择 不同动作库的骨架差异 root 缩放比例

目前比较有效的方法还是构建可视化脚本,反复观察:

原始人体骨架 偏移后的目标骨架 机器人 FK 后的实际 link 关键点位置误差 关键点旋转误差

对于一些怎么都对不齐的点,不建议死磕。可以降低位置权重,保留旋转约束,或者干脆弱化这个部位。

本质上,GMR 不是要让每个点都完美贴合,而是要让关键部位合理贴合。

原始动作骨架、未偏移结果、偏移后结果(但骨架保留原始效果以便表达区别)三图对比:


八、两阶段 IK:表一粗对齐,表二细对齐

GMR 中通常会有两张 IK match 表,对应两阶段 IK。

第一阶段主要是粗对齐。重点是:

root / pelvis 方向位置合理 torso 方向合理 双足位置合理 主要 end-effector 大致到位 其他关节旋转方向不要太离谱

第一阶段的目标不是精修动作,而是得到一个比较稳定的初始姿态。
如果第一阶段已经跑偏,第二阶段很容易在错误姿态附近继续优化。

第二阶段是细对齐。一般会加入更多 key body,并适当提高部分旋转或位置约束,让动作更贴近源动作。

可以简单理解为:

表一:先把机器人摆对 表二:再把动作修细

所以两张表不要配置成完全一样。
表一应该抓重点,表二可以更细,但也不能过度激进。否则动作细节可能更像了,但抖动、自碰撞和关节突变也更容易出现。

其他补充

不同数据格式骨架

左边是smplx右边是bvh,数据细节来看,不经映射的位置要调整,并且坐标轴也是需要彻底重新调整。


个人调试经验

整理一些目前比较有用的经验:

1. foot 通常比 ankle 更适合作为脚部主约束

foot 对脚掌方向更敏感,步行和转身效果会更好。ankle 可以辅助,但单独用 ankle 时脚掌方向约束偏弱。

2. 没有自由度的部位,权重要低

比如没有头部自由度,就不要高权重跟踪Head的方向。否则机器人可能通过 torso 或腰部去代偿,动作会变得很奇怪。

3. 不同动作库可能需要不同 scale 或 offset

不同动作库的骨架定义、身高比例、坐标系和帧率都可能不同。不要默认一套参数可以适配所有来源的数据。

4. 不要只用一个动作验证配置

一个动作调得很好,不代表配置稳定。建议在同一个动作库/作者下,至少准备几类动作:

普通步行 转身 跑步 上肢动作 大幅度动态动作

多动作都能接受,配置才比较可信。


十、几个待研究问题

目前还有一些问题没有完全搞清楚,后续值得继续看。

1. 权重和 scale 的影响能否量化?

现在调参主要依赖观察和枚举,成本比较高。后面可以考虑引入一些自动指标:

key body position error rotation error foot sliding ground penetration self-intersection joint velocity spike

如果这些指标能自动统计,调参效率会高很多。

2. 其他动作格式效果如何?

目前主要关注现有仓库主力支持的smplx格式数据。对于遥操数据、视频恢复动作、其他 mocap 格式,还需要单独测试。

3. 动作频率对训练效果有什么影响?

GMR 脚本里写死了 30 fps,而宇树官方动作数据可能是 50 Hz,bymimic仓库里则是区分了高频低频的训练环境。这里需要继续确认:

retarget 后是否需要插值? 频率变化如何影响 tracking 效果?

这个问题对后续训练很关键。

4. 是否需要为每个动作库单独配置 scale?

不同动作库录制者体型、骨架标准可能不同。理论上可能需要不同 scale,但也可能动作数据内部已经做了统一标准化。这个需要更多动作源验证。

5. table2 里的rot_offset是否真的生效?

代码分析时发现,第二阶段表里的rot_offset似乎没有被实际套用。这里还不能确定是论文设计如此,还是代码实现遗漏。

十一、SMPL-X 到机器人动作重定向工程流程

最后,我们再快速过一下重定向过程中都干了什么。

输入数据

输入是一个 SMPL-X 动作.npz文件,通常来自 AMASS/OMOMO 等数据集。脚本主要使用其中的:

  • pose_body: 每帧身体关节轴角姿态,形状通常为(N, 63)
  • root_orient: 每帧根节点全局朝向,形状为(N, 3)
  • trans: 每帧根节点全局平移,形状为(N, 3)
  • betas: 人体形状参数。
  • gender: SMPL-X body model 性别选择。
  • mocap_frame_rate: 原始动作帧率。

这些参数本身还不是“骨架点位序列”,而是 SMPL-X 参数化人体模型的输入。

SMPL-X 前向计算

load_smplx_file()会根据输入文件中的genderbetas创建 SMPL-X body model,并把root_orientpose_bodytrans输入模型,得到每一帧的人体关节位置和完整姿态。

之后get_smplx_data_offline_fast()将 SMPL-X 输出整理成重定向系统使用的格式:

{"pelvis":(position,quaternion),"left_hip":(position,quaternion),"left_knee":(position,quaternion),...}

其中四元数格式为[w, x, y, z]。这个阶段也会根据目标帧率进行时间对齐或重采样,并返回实际使用的aligned_fps

逐帧重定向

脚本逐帧取出 SMPL-X 处理后的人体数据:

smplx_data=smplx_data_frames[i]qpos=retarget.retarget(smplx_data)

retarget()内部主要做几件事:

  1. 将人体骨架按目标机器人尺度进行缩放。
  2. 对人体匹配点应用位置偏移和旋转偏移。
  3. 将处理后的人体点位和朝向设置为 IK 任务目标。
  4. 使用mink.solve_ik()求解机器人当前帧的qpos

返回的qpos是 MuJoCo 机器人状态,通常包含:

  • qpos[:3]: 机器人根节点位置。
  • qpos[3:7]: 机器人根节点四元数,格式为[w, x, y, z]
  • qpos[7:]: 机器人各关节角度。

输出数据

最后脚本会把所有帧的机器人动作保存为.pkl。输出结构如下:

{"fps":aligned_fps,"root_pos":root_pos,"root_rot":root_rot,"dof_pos":dof_pos,"local_body_pos":None,"link_body_list":None,}

其中:

  • root_pos:(T, 3),机器人根节点位置。
  • root_rot:(T, 4),机器人根节点四元数。保存时会从 MuJoCo 的[w, x, y, z]转为[x, y, z, w]
  • dof_pos:(T, robot_dof),机器人关节位置序列。
  • fps: 动作播放帧率。

这里的dof_pos是关节角,单位为 rad。以 G1 29DoF 为例,dof_pos的形状是(T, 29),每一帧包含 29 个关节角,列顺序由机器人 XML 中的 joint 顺序决定。

这个.pkl就是后续播放、训练或进一步转换的机器人动作数据。

技术要点

  • SMPL-X 负责从参数化人体动作恢复人体关节位置和朝向。
  • MuJoCo 提供目标机器人运动学模型。
  • mink将人体目标点和机器人 link 之间的匹配关系转化为 IK 优化问题。
  • IK 配置负责定义人体部位到机器人 link 的映射、权重、缩放和坐标系校准。
  • 输出结果不是力控或轨迹控制命令,而是逐帧机器人运动学状态。

整体流程可以概括为:

SMPL-X .npz -> SMPL-X body model 前向计算 -> 人体关节位置/姿态序列 -> 缩放与坐标系校准 -> 机器人 IK 求解 -> 机器人 root + joint motion -> .pkl 动作文件

总结

把自己的机器人接入 GMR,核心工作不是跑脚本,而是配置好smplx_to_robot映射表。

这张表里最重要的是:

映射哪个机器人 link 参考哪个人体 body 位置权重是多少 旋转权重是多少 xyz offset 如何设置 quaternion offset 如何设置

其中,映射关系决定机器人“看哪里”,权重决定机器人“有多在意”,offset 和 scale 决定人体动作目标是否真的适合当前机器人。

我的整体感受是,GMR 的工程配置本质上是在做一次折中:
既不能让机器人完全无视人体动作,也不能让它死追所有人体关节。比较好的结果通常来自合理取舍:关键部位强约束,非关键部位弱约束;可实现的部位认真跟踪,不可实现的部位适当放过。

当这套配置稳定之后,GMR 就会变成一个比较实用的动作数据生产工具。对于后续 motion tracking、模仿学习或者遥操作数据处理来说,前面这一步调得越稳,后面的训练就越省心。

http://www.jsqmd.com/news/858657/

相关文章:

  • PhanTap硬件探针原理与红队流量感知实战
  • 红黑树详解
  • 北京雅思写作提分机构排名!2026靠谱榜单出炉 - 品牌测评鉴赏家
  • 2026年5月最新 环保监测十大口碑品牌排名 - 水质仪表品牌排行榜
  • 2026上海健身教练培训机构推荐:5家高性价比靠谱机构全解析 - 品牌2025
  • 2026年常州热缩管源头厂家深度横评:从新能源防护到军工定制化解决方案全景对标 - 精选优质企业推荐官
  • 一句话看懂 vibing-steampunk
  • 如何快速管理Android设备:Fastboot Enhance完整指南
  • 一张图看懂中画幅vs全画幅AI渲染差异:2024 Q2 Midjourney V6.1 GPU显存占用热力图实测对比
  • 2026求职新范式:深度测评鹅来面OfferGoose,你的AI求职“第二大脑”
  • 2026高性价比普拉提培训机构推荐:靠谱又划算怎么选? - 品牌2025
  • 面膜哪个牌子美白补水效果最好?面膜口碑最好的前十名,润养舒缓长效维稳 - 博客万
  • 从 Claude Code 到 SAP ADT,vibing-steampunk 把 ABAP 开发带进 Agentic 工程现场
  • 金华润富黄金回收深度解析 - 润富黄金珠宝行
  • 能预防口腔溃疡的牙膏哪家好你想知道的都在这了 - 速递信息
  • OpenModScan:工业自动化领域的专业Modbus调试工具终极指南
  • 微信批量发送终极指南:三步实现高效自动化消息群发
  • 每天被短视频偷走时间?我做了个会“打断你分心”的 Chrome 插件:PauseCat
  • Qt 高级开发 009: C++ Lambda 表达式
  • macOS光标个性化深度指南:Mousecape技术解析与实战应用
  • 视频怎么转文字?2026年视频转文字工具方法盘点及推荐 - 软件小管家
  • LeagueAkari技术深度解析:基于LCU API的英雄联盟客户端工具集架构设计与实现
  • RAG 检索增强系统:从原理到实战的完整指南
  • 木塑地板厂家技术实力盘点:核心维度对比解析 - 奔跑123
  • 2026国产EDA怎么选?GPU国产芯片封装设计软件方案推荐看这篇 - 品牌2025
  • 交换与路由技术整理与总结(持续更新版)
  • Minecraft多版本管理的终极解决方案:Prism Launcher深度解析
  • 国内装修水管品牌排行:5家实力企业深度解析 - 奔跑123
  • 25+干皮抗老精华油怎么选?干敏肌必读的4个核心要点 - 新闻快传
  • 由C++速通C#