BeyondMimic 全身动作跟踪原理与机器人适配
动作回放可以直接设置机器人姿态,动作跟踪则必须靠电机力矩和地面接触改变状态。BeyondMimic 中的策略学的是后者:根据参考和当前状态不断纠偏,在关节限位、力矩饱和与平衡要求下完成动作。
本文从 BeyondMimic 在 G1 上的执行器参数化出发,分析逐际动力平台上的动作跟踪适配。逐际 SDK 随附的行走控制器、独立训练的速度跟踪策略、Omni 交互适配和 BeyondMimic 动作跟踪使用不同的控制接口,下面分别对照。文中的参数来自这些实现及训练时导出的配置;解析计算用于解释参数关系,不代替执行器辨识。

论文原图:Truong、Liao 等,BeyondMimic,Figure 1;未修改,版权归原作者。来源:论文/原图。图中平台和结果来自论文,并非本次机器人适配的实验。
本文拆解的是图左上的 motion tracking 部分:MotionCommand 提供参考,奖励比较参考与实际状态,actor 输出关节目标。右侧的状态—动作扩散模型属于后续蒸馏与任务引导,不能因为跟踪代码可运行就宣称已复现这条完整路线。下面展开跟踪控制的计算过程。
1. 跟踪策略学到的是反馈,而不是动作播放器
机器人满足浮动基座动力学:
其中浮动基座不能直接施加关节驱动力矩,必须借助接触力 保持平衡。参考轨迹 不一定满足这个方程,因此将其直接写入关节目标仍可能摔倒。
接触还要服从单边性与摩擦关系。用理想刚性接触的简化记号,法向间距、法向力与切向力满足:
脚离地时不能靠地面拉住身体;没有足够法向支撑时,也不能任意产生切向力。例如摩擦系数 0.6、法向支撑 100 N,对应的理想切向力上限为 60 N。位置参考和跟踪奖励本身并没有提供额外的摩擦能力。这里说明接触物理的理想约束,实际仿真由碰撞几何与接触求解器近似处理;BeyondMimic 的 actor 并不在线求解这套互补约束。
学习策略接收当前状态与参考条件,输出关节动作:
这里要分清三个角度:参考角来自动作数据,目标角由 q₀ + scale × a 生成,实际角来自机器人状态。策略动作 a 是网络输出,尚未乘 scale 时不等于关节角。
策略可以暂时偏离某个关节的参考,以维持整体平衡。它是否会这么做,取决于奖励、终止、训练分布与动作接口,不能仅靠“用了 PPO”推断。
时刻、坐标系
输出动作 a
得到关节位置目标
惯性、碰撞、摩擦
图 1:参考只作为条件和奖励目标进入闭环;实际身体状态由执行器和接触动力学产生。
2. 参考与观测必须使用一致的坐标约定
一个常见 actor 观测包括:关节相对默认姿态、关节速度、机体角速度、参考关节状态、参考 anchor 相对姿态,以及上一时刻动作。critic 可以额外看到世界位置、身体速度等仿真信息。
以 anchor 的 yaw 对齐为例,身体相对位置可以写为:
它弱化绝对平移和朝向的影响,但不能随意把 yaw 对齐换成完整 roll–pitch–yaw 对齐:后者会移除部分与重力方向相关的信息。root、torso、waist anchor 也不是同一个刚体;腰部有自由度时,把胸部姿态当根节点姿态会产生随动作变化的误差。
四元数必须明确顺序。对于同一个朝向,xyzw 与 wxyz 的四个数不是可以直接传递的接口。除长度为 4 外,还应测试单位范数、已知 90 度旋转和组合旋转方向。
3. 奖励中的尺度决定策略愿意牺牲什么
典型跟踪项为:
若 m,在这个简化单误差例子中,误差 0.1、0.3、0.6 m 的奖励分别约为 0.895、0.368、0.018。 不只是一个“收敛参数”,它决定错误多大时该项仍提供明显差异。
BeyondMimic 的基础奖励包含 anchor 位置和方向、身体相对位置与方向、身体线速度和角速度,以及动作变化、关节限位、非期望接触等惩罚。位置项的 std=0.3、方向项的 std=0.4 对应不同单位,不能直接比较数值大小判断哪个更严格。
身体位置项在实现中先对三维误差平方求和,再对选定身体平均,最后进入指数核。带着具体聚合顺序,总回报可写为:
策略优化的是折扣累计 R,而不是直接最小化某一帧关节角误差。也不能把“平均平方误差后取 exp”换成“每个身体取 exp 后平均”:误差集中在少数身体时,两种聚合会给出不同奖励。下表的系数属于 w,std 属于核内部的 sigma,控制周期属于最外层的积分尺度。
不要只盯关节角误差。腿部略有角度偏差但脚不滑,可能比关节角很像却地面穿透更好。是否允许这样的权衡,要由目标和评估指标明确规定。BeyondMimic 项目与实现
权重 0.5 和 std 0.3,改的是两件事
对于同一条位置误差,weight 决定这项在总回报中的占比,std 决定误差进入指数函数前按多大尺度归一化。以 0.1 m 误差为例:
| 设置 | 原始奖励 | 乘权重后 | 再乘 0.02 s 后 |
|---|---|---|---|
| weight = 0.5,std = 0.3 m | 0.89484 | 0.44742 | 0.00895 |
| weight = 1,std = 0.3 m | 0.89484 | 0.89484 | 0.01790 |
| weight = 0.5,std = 0.1 m | 0.36788 | 0.18394 | 0.00368 |
权重翻倍,所有误差下的贡献都翻倍。std 缩小,则重新分配了不同误差区间的奖励差异:远离目标时可能几乎全是零,靠近目标后才明显区分。它不会把物理碰撞变得更硬,也不会改变 PD 增益。std=0.4 rad 约为 22.9°,对应方向误差;不能拿它与 0.3 m 的位置尺度直接比大小。
基础跟踪任务的九项奖励
下面列出基础跟踪任务沿用的九项奖励及其系数。后文的选择性自碰撞方案另加五项接触/接近惩罚,不计入这张基础表。表列的是配置权重,Isaac Lab 的 RewardManager 在控制步内再乘 step_dt。这里物理步 0.005 s、decimation 4,因此控制步为 0.02 s;完美跟踪时六个正项合计 5,单步贡献为 0.1,未计惩罚。
表下代码均为等价的核心计算示意,省略环境对象访问与索引解析。
点击名称可跳到对应的公式与实现说明,并自动展开。
| 名称 | 权重 | 尺度/定义 | 作用 |
|---|---|---|---|
motion_global_anchor_pos |
0.5 | std = 0.3 m | 限制 anchor 全局漂移 |
motion_global_anchor_ori |
0.5 | std = 0.4 rad | 跟住 anchor 朝向 |
motion_body_pos |
1 | std = 0.3 m | 保留身体相对几何 |
motion_body_ori |
1 | std = 0.4 rad | 保留各身体姿态 |
motion_body_lin_vel |
1 | std = 1 m/s | 匹配平移速度 |
motion_body_ang_vel |
1 | std = 3.14 rad/s | 匹配转动速度 |
action_rate_l2 |
−0.1 | 原始动作平方和 | 抑制动作抖动 |
joint_limit |
−10 | 软限位越界量,rad | 远离关节限位 |
undesired_contacts |
−0.1 | 阈值 1 N | 减少不允许的身体碰撞 |
逐项实现
motion_global_anchor_pos
实现 motion_global_anchor_position_error_exp 对 anchor 三轴位置差取平方和,再做指数核。权重 0.5 控制该项的贡献,0.3 m 控制容忍尺度。误差 0.3 m 时原始值约 0.3679;它不能保证机器人永不漂移。
1 | err2 = (p_anchor_ref - p_anchor).square().sum(-1) |
motion_global_anchor_ori
实现 motion_global_anchor_orientation_error_exp 使用四元数的最短旋转角误差,先平方,再除以 0.4²。不要将四个四元数分量直接相减:q 和 −q 表示同一旋转。
1 | angle = quat_error_magnitude(q_ref, q_actual) |
motion_body_pos
实现 motion_relative_body_position_error_exp 比较经过 anchor/yaw 对齐的参考身体位置与实际位置:先对 xyz 求平方和,再对身体取均值,最后求一次 exp。它不是逐身体 exp 后求平均。MotionCommand 对齐 XY 与 yaw 时保留参考 anchor 的 Z,因此身体高度误差仍在该项中;不是把全部 xyz 平移都消掉。身体列表改变后,每个部位在均值中的占比也会改变。
1 | err2 = (p_body_aligned - p_body).square().sum(-1) |
motion_body_ori
实现 motion_relative_body_orientation_error_exp 对每个身体计算最短旋转角,平方后在身体维度平均,再用 0.4 rad 核。相对目标的构造与位置项共享参考约定,不能把局部和世界四元数混用。
1 | angle = quat_error_magnitude(q_body_aligned, q_body) |
motion_body_lin_vel
实现 motion_global_body_linear_velocity_error_exp 比较世界系身体线速度,三轴平方和后对身体平均;1 m/s 是误差尺度。位置很接近但身体仍在快速冲过目标时,这项会降低奖励。
1 | err2 = (v_ref_w - v_w).square().sum(-1) |
motion_body_ang_vel
实现 motion_global_body_angular_velocity_error_exp 比较世界系身体角速度。3.14 rad/s 是指数核尺度,不是机器人最大允许角速度。它补充姿态项,但不能替代力矩限制。
1 | err2 = (omega_ref_w - omega_w).square().sum(-1) |
action_rate_l2
Isaac Lab 的 action_rate_l2 返回连续两次动作之差的平方和,配置乘负权重。它没有除以控制周期,因此不是物理意义上的关节加速度。动作幅度和控制频率变化后,同一系数的效果也会变。
1 | cost = (action - previous_action).square().sum(-1) |
joint_limit
Isaac Lab 的 joint_pos_limits 对上下软限位之外的距离取正部,按关节相加。原始量非负、权重为负,且这里不是平方惩罚。它是奖励代价,不能替代执行器硬限位。
1 | cost = ((lower_soft - q).clamp_min(0) |
undesired_contacts
Isaac Lab 的 undesired_contacts 先在接触历史窗取每个身体的力范数峰值,超过 1 N 的身体记为 1,再求和。脚和允许接触的部位必须从筛选集合排除;阈值判断意味着超过 1 N 与超过 100 N 对同一个身体贡献一样。
1 | peak = contact_forces_history.norm(dim=-1).amax(dim=1) |
继承了系数,任务却不完全相同
适配任务以腰部俯仰关节之后的躯干作为 anchor,身体跟踪集合为 15 个部位,包括头部和左右肩、肘、腕。六个手臂部位约占身体均值的 40%;单独的 motion_arm_pos 已移除,因此不能再把注释中的候选权重 1.0 算进奖励。PD、armature 和 action scale 的差异见下文计算。
接触筛选也随任务变化。自由空间动作的基础适配只放行两脚触地;统一尺度的动作任务还保留了腕部中间刚体的排除项,但实际手部碰撞几何属于更末端的刚体。排除一个名字,不等于整只手都获得接触许可。后文的自碰撞传感器直接按手与腿、躯干、另一只手的刚体对取力,不能与这项全身非期望接触惩罚混为一谈。
4. Reference State Initialization 与自适应采样
只从动作第一帧开始训练,策略可能反复摔在前几秒,永远见不到后半段。随机参考状态初始化将动作中间的状态作为起点,使各阶段都有练习机会。
自适应采样进一步按片段统计失败情况,给难段更多采样概率。其概念形式为:
其中 是平滑后的失败统计,均匀项避免永久忽略其他片段。实际代码还会进行时间平滑与归一化。
本文讨论的适配任务采用固定首帧初始化,用来观察整段动作的连续执行。回合上限随动作长度设置:基础动作任务为 18.50 s,统一尺度的长动作任务为 42.30 s,选择性自碰撞任务为 32.18 s;这些是不同参考片段的时间预算,不是控制器固有常数。它与原生方法的自适应片段采样有明确区别:前者集中暴露开头到结尾的失败链,后者提高困难片段的训练覆盖。若切回自适应采样,需要解除固定起始帧约束。
但成功从中间帧跟踪几秒,不等于可以从站立连续完成整段动作。最终必须单独评估从动作开头完整执行,记录连续成功率和最早失败阶段。随机 reset 的高 reward 不能替代这个结果。
5. Armature 到底是什么
对于固定减速比 ,若电机角度满足 ,转子动能为:
因此反射到关节侧的惯量是:
例如 、,得到 ;若减速比变为 100,得到 0.2,增加四倍而不是两倍。这是用于说明减速比平方关系的教学算例,不是电机辨识结果。
MuJoCo 的 joint armature 表示附加到广义惯量的项。它不等于连杆全部惯量,也不等于摩擦或 PD 阻尼;改变它会改变加速度、接触响应和离散仿真行为。MuJoCo armature 定义
并联踝和腰不能直接复制电机侧数值
若多个电机坐标满足 ,速度映射为 ,则:
它可能随构型变化,并带非对角耦合。将 A/B 电机侧某个 armature 常数直接赋给串联等效 pitch/roll,是一种模型近似,而不是严格的惯量变换。
本文适配案例将并联驱动侧的惯量用于串联近似模型。这样便于复用关节级仿真接口,但会忽略传动映射带来的构型依赖与耦合;只有结合传动 Jacobian 和执行器辨识,才能判断近似是否足够准确。
6. 从二阶系统推导 PD,而不是背参数
忽略耦合、接触和重力补偿误差,考虑单关节:
固定目标时,误差 满足:
与标准二阶系统对应:
G1 配置采用 rad/s、,以各类 actuator armature 作为惯量尺度。其中一个 的关节组得到 、。 是过阻尼,不是临界阻尼。
这是执行器参数化策略,不是关于完整多刚体系统闭环极点的保证。若真实有效惯量 ,用 armature 计算的频率与阻尼比都不能直接当作真实测量结果。
7. 换一套执行器,同样的参数化规则会算出多少
以下固定 Hz、,将适配案例的 armature 数值代入。最后一列再使用 G1 风格 。这些是公式迁移的计算值,不是建议下发的增益。
| 关节组 | 配置 armature(kg·m²) | 公式 (N·m/rad) | 公式 (N·m·s/rad) | 公式 scale(rad/action) |
|---|---|---|---|---|
| 髋/膝 | 0.141250 | 557.63 | 35.50 | 0.06277 |
| 踝 | 0.1845504 | 728.58 | 46.38 | 0.01441 |
| 腰 | 约 0.1845504 | 728.58 | 46.38 | 0.01441 |
| 肩/肘 | 0.088671 | 350.06 | 22.29 | 0.02999 |
| 腕 | 0.015322 | 60.49 | 3.85 | 0.07853 |
| 头 | 0.015322 | 60.49 | 3.85 | 0.07853 |
例如踝关节,、,有:
如果上肢目标需要相对 offset 改变 2 rad,scale 0.02999 对应 raw action 约 66.7;如果改成 0.5,则只需 4。高斯动作若没有硬限幅,66.7 并非数学上绝对不可达;真正的问题是它可能远离初始分布、受到正则和训练稳定性的限制。不能把“小 scale”直接说成“动作范围严格被锁死”。
8. 参数的三层含义:公式、配置与实测响应
先区分三层数字。公式值来自人为指定的 10 Hz、阻尼比 2;配置值是执行器真正接收的 Kp、Kd 和 scale;实际响应还取决于姿态相关的有效惯量、重力、耦合、接触、饱和与延迟。前两层可以直接计算,第三层需要测量。
原生 G1 用同一参数化规则生成多组执行器增益。例如惯量尺度 0.010177520 对应 Kp≈40.18、Kd≈2.56。迁移到更大的 armature 后,沿用同一频率和阻尼比,会得到上一节的 557.63、728.58 等增益;并不是只更换机器人关节名字就还能得到同一组 Kp。
当前适配使用的 PD 数值
以下固定选择统一动作尺度方案:各关节 scale=0.25 rad/action。按关节扩展尺度的方案在下一节单独说明,不把两种设置拼成同一张“当前参数表”。Kp 单位为 N·m/rad,Kd 单位为 N·m·s/rad。表中频率与阻尼比仅以 armature 为标量惯量反算:
| 关节组 | Kp | Kd | 反算频率(Hz) | 反算阻尼比 | Kp × scale(N·m/action) |
|---|---|---|---|---|---|
| 髋 pitch | 220 | 6 | 6.28 | 0.54 | 55 |
| 髋 roll/yaw | 200 | 5 | 5.99 | 0.47 | 50 |
| 膝 | 240 | 6 | 6.56 | 0.52 | 60 |
| 踝 pitch/roll | 60 | 1.5 | 2.87 | 0.23 | 15 |
| 腰 yaw | 120 | 3 | 4.06 | 0.32 | 30 |
| 腰 roll/pitch | 90 | 2.5 | 3.51 | 0.31 | 22.5 |
| 肩 pitch/roll | 80 | 2.5 | 4.78 | 0.47 | 20 |
| 肩 yaw/肘 | 70 | 2 | 4.47 | 0.40 | 17.5 |
| 腕 | 30 | 1 | 7.04 | 0.74 | 7.5 |
| 头 | 20 | 0.8 | 5.75 | 0.72 | 5 |
这些频率是简化模型的计算结果,不是带宽测试。比如腿部落地后有效惯量和外力改变,同一组 Kp、Kd 不会自动维持表中的极点。
踝关节的 728.58 与 60 到底差在哪里
同样使用 armature 0.1845504,公式迁移得到 Kp=728.58、Kd=46.38;当前配置则为 Kp=60、Kd=1.5。比例增益约低 12.14 倍,阻尼增益约低 30.92 倍。armature 没有随之改成另一数值。
固定同一姿态、零速度和 0.1 rad 位置误差,公式组要求 72.86 N·m,超过 42 N·m 的力矩上限;配置组要求 6 N·m。在这一瞬间,前者会进入饱和。固定零位置误差、1 rad/s 的速度,阻尼项则分别要求 −46.38 与 −1.5 N·m。Kp 对位置误差起作用,Kd 对速度起作用,不能合并成一个“硬度系数”。
再考虑动作映射:公式组按四分之一力矩规则取 scale≈0.01441,单位动作在默认姿态附近对应 10.5 N·m;配置组 scale=0.25,对应 15 N·m。可见 Kp 降了,单位动作产生的比例力矩反而更大,因为目标角度的缩放同时改变了。
还可以把力矩上限换算成一个更直观的位置误差尺度。忽略速度项和其他力矩,在静止状态下,达到比例力矩饱和的误差为:
同样是 42 N·m 上限,公式组约在 0.0576 rad(3.30°)处饱和,配置组则为 0.7 rad(40.11°)。这不是允许机器人偏差这么大的建议,而是说明高 Kp 为什么更容易把小误差变成饱和请求。实际运动中,阻尼力矩也占用力矩预算,触发饱和的误差还会随速度和方向变化。
这套 BeyondMimic 适配复用了逐际速度跟踪训练中的名义 Kp/Kd,没有沿用 G1 的 10 Hz、阻尼比 2 参数化。但复用增益不代表复用了整个执行器接口:隐式/显式求解、延迟、限幅和动作零点仍有区别。
逐际 SDK 的行走参数是另一组
下面对照 SDK 随附的 walk 控制器与独立速度跟踪训练。SDK 一列指这里核对的版本,不代表厂商所有策略或后续版本。每格按 Kp / Kd / scale 排列,单位依次为 N·m/rad、N·m·s/rad、rad/action;训练一列的 Kp/Kd 也就是上面的 BeyondMimic 适配增益。
| 关节组 | SDK 行走 | 速度跟踪训练 |
|---|---|---|
| 髋 pitch | 139.41 / 17.75 / 0.2511 | 220 / 6 / 0.25 |
| 髋 roll/yaw | 139.41 / 17.75 / 0.2511 | 200 / 5 / 0.25 |
| 膝 | 139.41 / 17.75 / 0.2511 | 240 / 6 / 0.25 |
| 踝 pitch/roll | 93.65 / 11.92 / 0.1121 | 60 / 1.5 / 0.25 |
| 腰 yaw | 93.65 / 11.92 / 0.1121 | 120 / 3 / 0.25 |
| 腰 roll/pitch | 93.65 / 11.92 / 0.1121 | 90 / 2.5 / 0.25 |
| 肩 pitch/roll | 87.51 / 11.14 / 0.1200 | 80 / 2.5 / 0.25 |
| 肩 yaw/肘 | 87.51 / 11.14 / 0.1200 | 70 / 2 / 0.25 |
| 腕 | 15.12 / 1.93 / 0.3141 | 30 / 1 / 0.25 |
| 头 | 15.12 / 1.93 / 0.3141 | 20 / 0.8 / 0.25 |
踝关节最能说明区别:SDK 的 Kp 更高,Kd 约为训练配置的 7.95 倍,但 scale 更小。在各自默认姿态、零速度且未饱和时,单位动作的比例力矩分别是 93.65 × 0.1121 ≈ 10.50 N·m 和 60 × 0.25 = 15 N·m。因此“SDK 的 Kp 更大”不能推出“同一个网络动作产生更大的力矩”。
SDK 中踝和腰 roll/pitch 的用户力矩预算为 80 N·m,腰 yaw 为 42 N·m;速度跟踪训练中这三组均为 42 N·m。SDK 的踝 scale 虽然恰好对应约 10.5 N·m/action,却不是其 80 N·m 预算的四分之一。不能把所有参数倒推成同一个 0.25 × 力矩上限 / Kp 公式。
SDK 在目标角上限幅,Omni 在力矩上限幅
SDK 根据当前角度和速度,先算出允许的动作区间。把代码整理为单关节形式:
1 | budget = 0.95 * user_torque_limit |
这个区间由 −budget ≤ kp × (q_des − q) − kd × dq ≤ budget 解出。关节已经偏离默认姿态或正在运动时,区间也随之变化,因此它不是固定的动作范围。它约束的是采样状态下的名义 PD 请求,不是对下一时刻真实力矩或接触力的保证。
Omni 的这套交互适配则先在动作模块中计算 PD 力矩,再裁到力矩预算的 95%。例如踝的预算为 42 N·m,最终裁剪阈值为 39.9 N·m;SDK 踝关节的相应目标投影预算为 76 N·m。两处都有 0.95,实际限制仍不同。Omni 的 Isaac Sim 执行器增益设为零,是因为 PD 已在上游计算并作为力矩传入,不能据此判断“没有 PD”。
Omni 还优先使用逐关节动作尺度:髋 pitch 为 0.60、膝为 0.55、肩 pitch 为 0.70、肘为 0.50、头部为 0。配置中的统一 0.25 是后备值,不会覆盖这张逐关节表。以肘为例,同样 Kp=70,速度跟踪训练的单位动作对应 17.5 N·m,Omni 对应 35 N·m;BeyondMimic 的扩展尺度方案又是另一组数值,见下一节。
9. Action scale、默认姿态和限幅各管哪一段
动作先变成位置目标,再变成力矩:
| 参数 | 修改后直接改变什么 | 不应混淆的量 |
|---|---|---|
| 默认姿态 q₀ | 动作零点对应的关节角 | 参考姿态不一定就是动作零点 |
| scale | 一个网络动作单位对应多少 rad | 它不是力矩上限,也不是动作硬限幅 |
| Kp | 同样位置误差对应的比例力矩 | 它不增加电机允许的最大力矩 |
| Kd | 同样关节速度对应的阻尼力矩 | 它不等于减速器摩擦 |
| armature | 广义惯量中的附加项 | 它不是连杆惯量的替代品,也不是用来压抖动的 Kd |
| 力矩上限 | 截断最终命令的幅值 | scale 小也可能因大误差或大速度触发饱和 |
0.25 与 0.6 为什么都会出现
统一尺度方案中所有关节取 0.25;按动作范围扩展的另一方案中,例如左右肘取 0.6,左肩 pitch 为 0.85,右肩 pitch 为 0.70,头部取 0。左右数值不同,反映的是这段动作各关节需要的目标范围,并不是左右电机惯量因此不同。
若某关节相对默认姿态要到达 1.2 rad,scale=0.25 需要动作 4.8,scale=0.6 则需要动作 2。可用参考等效动作检查范围:
扩展方案按参考幅值把等效动作控制在大约 3.2 以内。这是范围设计目标,不是策略输出被硬裁到 ±3.2,也不保证动力学能完成参考。scale=0 的关节必须单独处理:目标始终为默认角,不能用上式除以零。
以肘关节 Kp=70、力矩上限=42 为例,在默认姿态且速度为零时,scale=0.25 对应 17.5 N·m/action,比例项在动作约 2.4 时达到上限;scale=0.6 对应 42 N·m/action,动作约 1 就到上限。扩大目标范围同时放大了动作到力矩的增益。
默认角也必须成套使用。这里统一尺度方案的默认肘角为 +0.4 rad,另一动作适配方案为 −0.2 rad。相同动作 0 会相差 0.6 rad;两套网络与默认姿态互换后,即使 scale 不变,命令也已经改变。
软限位 0.9 与 1.0 改变的是惩罚边界
原生 G1 和逐际速度跟踪训练的软限位系数为 0.9,本文 BeyondMimic 适配为 1.0。设硬限位为 [−1, 1] rad,0.9 对应软范围 [−0.9, 0.9],1.0 则保留完整硬范围。参考角 0.95 rad 在前者中产生 0.05 rad 越界代价;在后者中没有软限位代价。真实硬限位并未因此消失。
参考本来就接近关节极限时,缩小软范围会使跟踪奖励和限位惩罚互相冲突。是否缩小,应结合参考覆盖、机械余量和实际限位保护决定。
10. 控制频率、隐式 PD 与显式 PD
基础配置的仿真步长 0.005 s、decimation 4,策略周期为 0.02 s,即 50 Hz。策略每 20 ms 更新目标,仿真在中间继续推进。适配执行器还配置了 0–4 个物理步的随机动作延迟,对应 0–20 ms;分阶段训练的初始阶段缩为 0–2 步,即 0–10 ms。延迟步数使用物理时钟,不能乘策略周期后误写成 0–80 ms。
原生 G1 使用隐式执行器,本文适配使用带延迟的显式 PD。隐式执行器由求解器内部处理驱动器与约束,显式 PD 在当前状态直接算力矩后交给物理系统积分;相同 在不同步长、求解器与饱和实现下不保证完全一致。
逐际速度跟踪训练也使用隐式执行器,策略同为 50 Hz。SDK 行走控制器的默认命令循环为 1000 Hz,每 10 次循环推理一次,对应名义 100 Hz;实际频率还取决于启动配置和运行耗时。不能将这个默认值当作所有逐际策略的推理频率。
5 与 23 rad/s:字段不同,不能直接比较成硬限速
速度跟踪训练把腿部 velocity_limit_sim 设为 5 rad/s,踝为 13.6 rad/s,这些值交给物理求解器。BeyondMimic 适配在 DelayedPDActuator 中填的是 velocity_limit:腿部 23、踝 30 rad/s。后者是执行器模型字段,不等于 velocity_limit_sim。
这里的延迟 PD 继承理想 PD,力矩裁剪只读取 effort_limit,没有使用速度—力矩曲线。因此仅填写 velocity_limit=23,不能证明求解器会在 23 rad/s 硬限速,也不能证明超过该速度后电机力矩会衰减。要判断最终行为,需要检查加载后的求解器速度限值与实际执行器类型;DC motor 模型的速度相关饱和是另一种实现。Isaac Lab:执行器模型与限值字段
调参时应同时记录:仿真频率、策略频率、驱动更新频率、是否有 action delay、关节目标滤波、力矩/速度限值。把仿真从 200 Hz 改为 100 Hz,而只检查 reward 配置不变,不算控制系统保持不变。
11. 碰撞模型:几何、碰撞对和奖励是三层不同的设置
机器人外观正确,不等于碰撞模型正确。visual 决定画面,collision 决定接触几何,inertial 决定连杆质量与惯量。把足部碰撞网格换成盒体,通常是为了控制接触形状;质量和惯量是否变化,要看导入后的惯性属性是否被保留或重新计算。
逐际速度跟踪训练加载的是预制 USD,配置关闭内部自碰撞;BeyondMimic 适配从 URDF 导入,另有导入后修改碰撞体和碰撞对的扩展。两者即使使用同一平台、同样的关节增益,也不能假定碰撞网格、凸近似和过滤规则相同。下面的足部盒体与 8 对白名单专指 BeyondMimic 的选择性碰撞扩展,不是逐际 SDK 或速度跟踪任务的默认模型。预制 USD 的实际碰撞体还需在场景中展开核对,不能用 URDF 的尺寸代替。
足部为什么要只留盒体
这个适配模型的每只脚原本有两个碰撞体:一个长宽高为 0.25 × 0.094 × 0.02 m 的盒体,以及一份细节网格。只增加盒体而不关闭原网格,并不能让接触只发生在盒体上。
盒体中心相对足部刚体原点为 (0.018, 0, −0.0535) m,没有额外旋转。因此在该局部坐标系中,它覆盖:
| 方向 | 范围(m) | 对接触的影响 |
|---|---|---|
| x | −0.107 ~ 0.143 | 前后支撑边界,相对原点并不对称 |
| y | −0.047 ~ 0.047 | 横向支撑宽度 |
| z | −0.0635 ~ −0.0435 | 足底平面位于局部 z = −0.0635 |
这不是世界坐标中的地面高度。需要用足部刚体位姿把盒体变换到世界系,再判断是否接地。足部无旋转时,若初始化只让“脚的刚体原点”贴住地面,实际盒体会穿进地面 6.35 cm;求解器随后执行分离修正,机器人可能在第一步就被弹起。
选择性碰撞方案关闭了两脚的非盒体碰撞几何,保留可见网格。这样地面和另一只脚看到的是同一个平底盒体。代价是脚尖、脚跟曲面被简化,侧向擦碰也按盒体计算;它是否适合某段动作,需要检查实际支撑和近距离交叉姿态。
网格还可能经过凸包或凸分解。单个凸包会填掉凹陷,画面中两块零件之间有缝,碰撞近似却可能已经重叠。应查看实际碰撞体叠加,不能仅凭原始 STL 的外观判断。Isaac Sim:碰撞近似
自碰撞为什么不能只看一个布尔开关
原生 G1 配置启用自碰撞;本文适配的基础方案关闭内部自碰撞,保留机器人与地面、外部物体的接触。选择性方案则打开总开关,再过滤具体刚体对:
| 内部碰撞对 | 选择性方案 | 数量 |
|---|---|---|
| 左脚—右脚 | 保留 | 1 |
| 每只手—左右大腿 | 保留 | 4 |
| 每只手—躯干 | 保留 | 2 |
| 左手—右手 | 保留 | 1 |
| 其余内部刚体对 | 过滤 | 不参与这套内部碰撞计算 |
这是 8 对白名单,不是所有非相邻刚体都开启碰撞。手肘—躯干等未列出的组合,不能声称已受到物理自碰撞保护。地面和外部物体不在这份内部过滤名单里。
这样做的原因是,相邻关节附近的完整网格可能在合法姿态下重叠。直接全部开启,会让求解器试图分离本来应装配在一起的部件;全部关闭,又会放过双脚交叉穿透或手穿入躯干。白名单保留这段动作关心的组合,同时避开尚未整理好的其余碰撞体。更完整的模型仍需逐对清理几何与过滤规则。
对应的实现逻辑是:
1 | # 碰撞配置的逻辑示意;几何和过滤作用于导入后的资产 |
关掉 debug_vis 只是不画调试标记;关闭某个碰撞体才会改变接触物理;从奖励名单移除某个刚体则只改变学习目标。三个操作不能相互替代。
接触参数的数值分别控制什么
| 参数 | 本文设置/含义 | 调大后主要影响 |
|---|---|---|
| 物理步长 | 0.005 s | 步长更大时,同一速度每步走得更远,薄几何更容易漏检 |
| 位置/速度求解迭代 | 8 / 4 | 每个物理步中分配更多约束求解工作;不是把仿真频率变成 8 倍 |
| 最大分离修正速度 | 1 m/s | 允许更快消除已有穿透,但也可能出现更突然的分离运动 |
| contact offset | 接触开始生成的距离范围 | 更早建立接触约束,同时可能增加接触对和计算量 |
| rest offset | 静止接触的间隙约定 | 改变两形状停下时的几何间距 |
本例没有在机器人配置中显式覆盖后两项,不能把“未填写”写成“实际为零”。应查看导入资产上的最终属性。二者的长度单位是 m,与下面奖励中的 1 N、2 N 阈值没有换算关系。Isaac Lab:碰撞属性定义
还要把摩擦与接触几何分开。基础任务给机器人材质采样静摩擦 0.3–1.6、动摩擦 0.3–1.2、恢复系数 0–0.5;分阶段训练的初始阶段改为 0.6–1.3、0.5–1.1、0–0.1,后续阶段扩为 0.4–1.4、0.35–1.1、0–0.1。这些是材质随机化范围,并非某个训练完成后测出的常数,也不是奖励权重。
实际接触系数还取决于地面材质和 combine mode。地面的摩擦系数设为 1,组合模式为 multiply;若接触对最终采用乘法,机器人一侧的 0.6 与地面的 1 组合后仍为 0.6。缩小恢复系数范围是减少弹跳的不确定性,不能修复初始几何已经穿透的问题。
接触惩罚:1 N、2 N、50 N、80 N 并不是一类阈值
基础 undesired_contacts 在选定身体的净法向接触力超过 1 N 后计数,不区分 10 N 与 100 N。选择性方案另加五项,用按碰撞对象筛选的力矩阵区分“脚踩地”和“脚撞脚”,并加入手靠近大腿的预警。
| 新增项 | 权重 | 阈值与尺度 | 用途 |
|---|---|---|---|
foot_pair_contact |
−0.05 | 起罚 2 N;50 N 达到上限 | 左右脚互撞,排除足地接触 |
left_hand_self_contact |
−0.1 | 起罚 2 N;80 N 达到上限 | 左手与两腿、躯干、右手 |
right_hand_self_contact |
−0.1 | 起罚 2 N;80 N 达到上限 | 右手与两腿、躯干 |
left_hand_thigh_proximity |
−0.1 | 距离 0.25 m;过渡宽度 0.04 m | 左手靠近大腿轴线时提前惩罚 |
right_hand_thigh_proximity |
−0.1 | 距离 0.25 m;过渡宽度 0.04 m | 右手靠近大腿轴线时提前惩罚 |
这里的 force_matrix_w 和 net_forces_w 按所用接口表示法向接触力,不包含完整的切向摩擦力。因此下面的力阈值也不能当作总接触载荷限制。Isaac Lab:接触传感器数据
表中各项先产生 [0,1] 的代价,再乘负权重与 0.02 s。50 N/80 N 只表示惩罚饱和,不会把真实接触力限制在该值。 42 N·m 则是某组关节的力矩限值,单位和作用位置都不同。
foot_pair_contact
传感器只看左脚与右脚的接触。取筛选力矩阵的力向量范数,在对应身体与对象维度取最大值,记为 F,代价为:
1 | force = force_matrix.norm(dim=-1).amax(dim=(1, 2)) |
F≤2 N 时为零;F=26 N 时为 0.5;F≥50 N 时为 1。26 N 对应的单步贡献为 −0.05 × 0.5 × 0.02 = −0.0005。地面不在筛选对象中,正常支撑力不会进入这项。
left_hand_self_contact
左手传感器筛选两侧大腿、躯干和右手;用这些接触对象中的最大力范数计算 clamp((F−2)/78, 0, 1),而不是把所有力先求和。F=41 N 时代价为 0.5,单步贡献 −0.1 × 0.5 × 0.02 = −0.001。多处同时接触也不使这一项超过 1。
right_hand_self_contact
右手传感器筛选两侧大腿和躯干,阈值、饱和与权重同左手。右手列表不再包含左手,使手—手接触只通过左手那一项计入。物理碰撞对是无向的,奖励统计可以选择只从一个传感器方向读取。
left_hand_thigh_proximity
以手部刚体原点为点,以髋部到膝部的连线为线段,计算点到两侧线段的最小距离 d:
1 | segment = end - start |
d≥0.25 m 时为零,d=0.23 m 时为 0.5,d≤0.21 m 时为 1。0.04 m 是线性过渡宽度,不是指数核的标准差。d 是原点到轴线的距离,既不是网格表面间距,也不等于手与腿的真实安全余量。 这项提供便宜的几何预警,实际碰撞仍由碰撞体与求解器处理。
right_hand_thigh_proximity
与左手使用同一个点到线段公式,只将点换成右手刚体原点;仍对两侧大腿取最小距离。权重 −0.1、阈值 0.25 m、过渡宽度 0.04 m。F、距离预警和身体跟踪误差是不同信号:没有碰撞力时也可能触发预警,有碰撞力时也不能由这个代理距离反推出网格穿透深度。
先检查碰撞,再解释训练曲线
在 reset 后、第一次策略动作之前,先显示碰撞体与接触法线,检查足底高度、相邻部件穿透和异常接触。然后分别检查双脚交叉、手贴近躯干、手靠近大腿的姿态,确认名单里的接触会产生力,名单外的接触确实被过滤。
最后用同一策略、同一参考和同一随机种子比较“基础碰撞”和“选择性碰撞”。记录脚滑、身体接触力、力矩饱和与失败时刻,再判断变化来自几何、求解还是奖励。接触穿透造成的瞬时抖动,不能仅凭动作曲线就归因于 Kp 太大。
12. 如何验证参数,而不是靠动画判断
从单关节或小幅多关节阶跃开始,记录目标、实际角度、速度和力矩。分别改变目标幅值和初始姿态,判断是否出现饱和、延迟、耦合与接触影响。若要拟合二阶模型,应选未饱和、无显著碰撞的片段,并报告拟合残差。
进入整段动作后至少观察:跟踪位置误差、足滑、动作变化、饱和占比和跌倒时间。一个参数组如果把训练动作拟合得很好,却需要长期饱和,通常不是理想的迁移起点。
本文给出参数计算与模型差异分析,尚未报告这两组参数的实机阶跃响应或统一条件下的跟踪对照结果。
13. 从训练到部署,必须保留哪些约定
导出网络之前,先把以下内容当作一个整体冻结:关节名字和顺序、轴与零位、默认姿态、观测归一化、四元数顺序、action offset 与 scale、PD、周期和终止逻辑。
同一帧离线数据,训练环境与部署代码应生成数值一致的观测;同一个策略输出,应生成一致的关节目标。先用确定输入做逐级比对,再做物理回放。否则看似“sim-to-real gap”的问题,可能根本没有到物理层。
逐际的两个行走接口已经能给出具体反例:SDK 行走网络输入为 102 × 5 = 510 维,按完整帧堆叠,最新帧在前;独立速度跟踪策略为 104 × 5 = 520 维,多了二维步态相位,并按观测项分别堆叠五帧,每项内部从旧到新。SDK 的角速度缩放为 0.25,训练接口为 0.2。SDK 配置虽然保留步态频率字段,实际观测拼接没有启用步态项;应以送入网络的张量为准。
动作零点同样不同:SDK 的髋 pitch/膝/踝 pitch 默认角为 −0.15/0.30/−0.16 rad,速度跟踪训练为 −0.25/0.55/−0.30 rad。关节数组顺序也需按名称重排,不能因为都是 31 个动作就直接对接。只替换网络文件,输入维度、历史顺序、归一化和动作解释都可能同时出错。
参考与参数边界
- BeyondMimic、公开代码:跟踪框架及 G1 参数化。
- MuJoCo 建模文档、armature 定义。
- 本文数值对应上述执行器适配案例;并联到串联的惯量处理属于模型近似。计算表说明数值关系,不宣称已完成真实执行器辨识或证明某组参数最优。