论文精读:RoboGauge 与 MoE——四足策略的仿真成绩,能预测真机表现吗?

论文信息与阅读地图

  • 原题:Toward Reliable Sim-to-Real Predictability for MoE-based Robust Quadrupedal Locomotion
  • 作者:Tianyang Wu、Hanwei Guo、Yuhang Wang、Junshu Yang、Xinyang Sui、Jiayi Xie、Xingyu Chen、Zeyang Liu、Xuguang Lan;西安交通大学。
  • 正式发表:RSS 2026,DOI 10.15607/RSS.2026.XXII.156
  • 阅读版本:arXiv v4,2026-05-10,同时核对 RSS 正式 PDF
  • 作者资源:项目与实验视频训练代码评估代码C++ 部署代码
  • 本笔记核对日期:2026-09-08。论文结果、源码实现、教学算例和本站尚未实施的接入方案分别标注,不互相替代。

这篇值得记住的不是“八个专家比一个网络强”,而是两件相互配合的事:

  1. 训练端:让学生从本体历史中形成更有区分度的状态表示。
  2. 评估端:用另一套物理仿真、多场景和多种行为指标筛选策略,不把训练奖励当作真机成绩单。

先读第 1~4 节理解网络;第 5~8 节理解评估与计算;第 9~10 节看证据与源码差异;第 11 节对应本站现有 CPU/ONNX 后端。两张流程图是原创机制示意,不是论文实验截图,也不是本站已经复现该策略的证明。

1. 它在解决哪个问题:会走,与值得上真机,是两件事

1.1 为什么高训练奖励可能误导我们

训练优化的是某个仿真器、某组奖励和某种随机化分布下的回报。实际使用关心的却是:电机是否过热、动作是否抖动、停下是否及时、换一种摩擦和延迟后是否仍能站住。

一个直观例子:策略 A 靠猛烈甩腿获得较高速度跟踪奖励;策略 B 略慢,却很少触及关节软限位、力矩变化也平滑。若仿真里的执行器延迟过于理想,A 可能排第一;真机上的电流限制和通信延迟却会让它更脆弱。

因此要分开看:

信号 主要回答什么 不能独自证明什么
训练 return 策略有没有优化训练目标 真机可靠性
训练地形等级 curriculum 推进到了哪里 行走质量、硬件负担
独立 sim-to-sim 评估 换物理引擎和测试条件后表现如何 未覆盖环境的安全保证
有控制条件的真机实验 测试分布内的真实表现 任意地形、任意时长都可靠

1.2 “Predictability”不是预测下一个状态

RoboGauge 不是学习一个世界模型,再预测机器人下一秒的姿态。它提供的是策略评估代理:在 MuJoCo 中测得一组指标,检查它们是否比训练环境中的指标更接近真实测量,并据此辅助选 checkpoint。

论文所称的闭环,是“训练 → 独立评估 → 选模型或调整训练 → 再评估”的研发闭环;部署时则仍有“观测 → 动作 → 动力学 → 新观测”的控制闭环。不要混成同一个概念。依据:论文 I、IV、V-A

2. 先把输入、输出和信息权限分清楚

2.1 单帧观测与历史

把经过训练契约规定的坐标变换、缩放后的单帧观测记为:

ot=[ωtb,gtb,ct,qtq0,q˙t,at1].o_t=[\omega_t^b,g_t^b,c_t,q_t-q_0,\dot q_t,a_{t-1}].

维度 直观含义
机体角速度 3 身体正在怎么转
机体系重力投影 3 身体相对竖直方向怎么倾斜
命令 vx, vy, wz 3 现在希望向哪走、怎么转
相对默认姿态的关节位置 12 四条腿目前折到哪里
关节速度 12 腿正在如何运动
上一步动作 12 控制器刚刚要求腿做什么

总计 4545 维。作者原始 IsaacGym 实现使用 5 帧历史,即 5×45=2255\times45=225 个标量。论文下标 otH:to_{t-H:t} 容易引起“到底是 H 还是 H+1 帧”的歧义;部署时应以配置中的帧数和实际导出代码为准,而不是数下标猜测。

历史有用,不是因为它能直接看见前方台阶,而是因为“发出了什么动作、身体随后如何响应”包含地形接触、负载和动力学的线索。同样的瞬时关节位置,在两种不同运动历史下可能对应完全不同的接触情形。

2.2 Teacher 能看见的,不等于部署时能看见

原始实现的教师观测是 263 维:普通 45 维,再加基座线速度 3、足端接触力模长 4、归一化电机力矩 12、关节加速度 12、地形高度 187。学生必须从本体历史推断一个有用表示,不能在部署时偷偷读取这些仿真真值。代码:观测构造

这里尤其要区分三种信息使用者:

  • 策略输入:IMU、关节编码器、命令和历史动作;不依赖外部地形传感器。
  • 训练监督与 critic:可以读取特权状态,帮助学习。
  • 评估器:可以读取 MuJoCo 接触力、刚体动力学,真机验证还用了动捕系统。

因此“策略仅用本体感知”不等于“论文所有评估指标都只需真机 IMU 就能准确计算”。这对理解后面的 ZMP 和摩擦裕度非常重要。依据:论文 III-A、V-A、附录 A

2.3 网络输出不是直接的电机力矩

输出是 12 维关节位置偏移,再由低层 PD 变成力矩:

qttarget=q0+saat,τt=Kp(qttargetqt)Kdq˙t.q_t^{\mathrm{target}}=q_0+s_a\odot a_t, \qquad \tau_t=K_p(q_t^{\mathrm{target}}-q_t)-K_d\dot q_t.

这只是控制结构;实际还必须按部署配置处理动作缩放、力矩限幅和电机次序。同样是 12 维动作,并不意味着两个 Go2 权重可以互换。

3. MoE 放在哪里:混合的是 latent,不是四条腿的动作

MoE 学生历史编码器与评估控制链:门控和专家共同形成 latent,Actor 再产生动作

原创示意。先混合对状态的理解,再通过 Actor 决定动作;Teacher 的特权信息只参与训练。

3.1 数学结构

xtx_t 为整理后的本体历史,门控网络输出 logits lkl_k,经 softmax 得到权重:

ωk=exp(lkmaxjlj)jexp(ljmaxrlr),z~tS=k=1KωkEk(xt).\omega_k=\frac{\exp(l_k-\max_j l_j)}{\sum_j\exp(l_j-\max_r l_r)}, \qquad \widetilde z_t^S=\sum_{k=1}^{K}\omega_k E_k(x_t).

减去最大 logit 是数值稳定的等价写法,不改变 softmax 的结果。所有权重非负、和为 1;因此归一化前的 z~tS\widetilde z_t^S 是本次专家输出的凸组合。实际代码还做 L2 normalization:

ztS=z~tSmax(z~tS2,ϵ).z_t^S=\frac{\widetilde z_t^S}{\max(\|\widetilde z_t^S\|_2,\epsilon)}.

最终 latent 以及机器人轨迹都不能再简单解释成上述凸组合。教师 latent 也会归一化,让师生拟合主要对齐表示方向;近零范数由数值下限保护。

Actor 随后读取当前观测和混合表示:

at=πθ(ot,ztS).a_t=\pi_\theta(o_t,z_t^S).

作者公开原始实现的默认配置是 8 个专家、32 维 latent,共享 Actor 的输入为 45+32=7745+32=77 维;其隐藏层为 512 → 256 → 128,输出为 12 维。这里指已经核对的原始 go2_rl_gym 配置,不是所有 MoE 或后续 IsaacLab 迁移版的通用参数。

3.2 为什么不直接把动作平均一下

假设两个专家分别认为当前处于“前腿刚碰到台阶”和“后腿需要重新支撑”的状态。先混合 latent,Actor 还可以结合当前姿态做一次非线性协调;直接混合关节动作,则可能把两种合理接触方案平均成一种不合理的支撑姿态。

数学上,非线性策略通常满足:

πθ ⁣(o,kωkzk)kωkπθ(o,zk).\pi_\theta\!\left(o,\sum_k\omega_k z_k\right) \ne \sum_k\omega_k\pi_\theta(o,z_k).

这是理解结构差异的推导,不是“latent 混合必然稳定”的定理。论文用 AC-MoE、MCP 等消融支持当前设计,但没有证明所有动作空间混合都会失败。

3.3 它不是大语言模型里常说的稀疏 top-k MoE

本实现是 dense softmax mixture:每次计算全部专家输出,再加权。不能因为名称有 MoE,就推断只运行一两个专家、CPU 推理必然更省。

代码中还用了共享 backbone 与分组 1×1 Conv1d 来批量组织专家的独立层。这种实现避免把每个专家都写成一套重复的大网络;分组卷积在这里也不是在地形图上做空间卷积。代码:Experts / MoE / StudentMoEEncoder

“第 1 个专家就是楼梯专家、第 2 个就是沙地专家”同样不是预先指定的标签。门控分工是训练结果;PCA 中的聚类只能提供表示差异的证据,不能替代专家语义和因果分析。

4. CTS 与负载均衡:学生怎样学,不只是网络怎样接

4.1 Concurrent 不是先练完老师再冻结

传统两阶段方法先训练 Teacher,再固定它来训练 Student。CTS 的特点是师生在同一训练阶段共同更新,使学生能够实际访问的状态分布参与策略优化。

这里的关键替换点是学生编码器:Teacher 从特权信息得到 ztTz_t^T,Student 的 MoE 从历史得到 ztSz_t^S,共享控制网络利用表示生成动作。学生需要让两种表示对控制具有兼容性。

可以用下面的简化目标理解学生更新:

LS=MSE(ztS,sg(ztT))+λbalLbal.\mathcal L_S =\operatorname{MSE}(z_t^S,\operatorname{sg}(z_t^T)) +\lambda_{\mathrm{bal}}\mathcal L_{\mathrm{bal}}.

sg 表示这项学生拟合损失不反向修改教师目标。完整训练还有 PPO、value 与其他框架项;上式不是完整 PPO loss。

源码具体用了两个优化器:第一组更新 Teacher、共享 Actor、Critic 和动作分布参数;第二组只更新学生 MoE 编码器。学生 rollout 参与 PPO 数据,但学生 latent 在 Actor 的 PPO 路径中不回传梯度,Critic 的 latent 输入也 detach。不能据此写成“8 个专家都直接通过 PPO 奖励端到端更新”。 教师目标则在学生拟合时通过 no_grad() 生成。代码:双优化器与梯度边界

4.2 为什么需要 batch 级负载均衡

论文给出的思想是:让一个 batch 中每个专家的平均使用率接近均匀分配。

ωˉk=1Bb=1Bωk(b),Lbal=k=1K(ωˉk1K)2.\bar\omega_k=\frac{1}{B}\sum_{b=1}^{B}\omega_k^{(b)}, \qquad \mathcal L_{\mathrm{bal}} =\sum_{k=1}^{K}\left(\bar\omega_k-\frac{1}{K}\right)^2.

实际代码使用 MSE 形式对专家维度取平均,并以 0.01 加权;论文的求和形式与代码的平均形式差一个尺度,复制超参数时不能忽略。

最容易误解的是:均衡的是 batch 平均使用率,不要求每一时刻都均匀混合。

以两个专家为例,四个样本分别使用权重 (1,0)、(1,0)、(0,1)、(0,1),平均仍是 (0.5,0.5),均衡损失为零,但各样本的选择非常明确。反过来,每个样本始终使用 (0.5,0.5),损失也为零。

所以这项损失只能缓解“总用同一个专家”,不能独自保证专家学会不同技能;还需要任务和拟合损失推动实际分工。

5. 不能把训练进步全部归功于 MoE

论文的训练基线使用 8192 个并行 Go2、50 Hz 策略控制和 200 Hz 物理仿真,原始 PD 为所有关节 Kp=20K_p=20Kd=0.5K_d=0.5。除编码器外,命令和奖励设计也在改变。依据:论文 III-C、III-D、附录 B/C

5.1 命令分布本身就是课程

  • 从较低速度范围开始,逐步扩大;否则策略可能靠跳跃或高频甩腿过关。
  • 主动采样零命令、边界速度和原地转向,而不是只靠均匀随机数碰到这些情况。
  • 对不同地形使用不同训练速度上限,避免困难地形上的跟踪损失过度主导优化。
  • 动态调整命令,让低速阶段也有足够的预期位移探索更高地形等级。

这对自己的训练很有启发:如果 terrain curriculum 用终点位移判定升级,而命令不断左右抵消,一个会走的策略也可能永远停在低等级。先检查“试卷是不是给了足够位移机会”,再去改网络。

5.2 动态跟踪精度存在必须核对源码的符号问题

附录的动态 σ\sigma 旨在随地形与命令调整跟踪约束。不过 v4 表 IX 的指数写法与“增大系数以放松约束”的文字解释不能直接一致:

exp(σe2)exp(e2/σ)\exp(-\sigma e^2) \quad\text{与}\quad \exp(-e^2/\sigma)

对增大 σ\sigma 的反应正好相反。式 (15) 的分段中间项也不是可直接假定连续的标准插值。复现时应固定代码版本,检查实际 reward 函数;不要默默修正论文公式,再声称是在复现原文。

作为数学对照,若只是希望从 σ0\sigma_0 连续插值到 σ1\sigma_1,标准写法是 u=clip((vvmin)/(vmaxvmin),0,1)u=\operatorname{clip}((v-v_{\min})/(v_{\max}-v_{\min}),0,1),再取 (1u)σ0+uσ1(1-u)\sigma_0+u\sigma_1。这段是教学解释,不是作者原式的替代实现。

5.3 多地形权重与高速权重不要混为一谈

论文对多地形与平地高速模型使用了不同设置,例如参考机身高度分别为 0.38 m 与 0.33 m,高速还增加了髋关节对称等规整项。4.01 m/s 是专门高速实验的结果,不能直接理解为同一个通用 checkpoint 在雪地、楼梯、30 cm 障碍上都以该速度行进。

所谓“涌现窄步宽”也不意味着完全没有姿态偏置:相关髋关节奖励和参考高度会影响最终步态。可以说没有显式编排整条高速轨迹,不能说训练目标对步态完全中立。

6. RoboGauge 测什么:六项行为指标,加两项物理裕度

6.1 先辨认版本

v4 的摘要附近和部分段落仍保留“6 项指标”的旧描述,但 表 II、IV-C 和附录表 XIII 已列出 8 项。笔记按新定义讲解,同时保留实机验证只覆盖原六项的边界。

指标 想识别的坏行为 使用时要留意
线速度跟踪误差 接到前进命令却走不动或过冲 坐标系、命令尺度与评估速度范围
角速度跟踪误差 转向迟缓、转过头 不能只看前向速度
关节功率 靠大力矩和高速摆腿换表现 不是电池电耗或温升的直接测量
关节软限位 经常顶到危险关节姿态 软限位比例与超限幅度的定义
姿态稳定性 机身侧向摇摆 重力投影某一分量不是完整姿态安全证书
力矩平滑性 高频震颤、冲击式输出 采样周期会影响差分尺度
ZMP 指标 动态合力作用点偏离支撑中心 不是支撑多边形边界的有符号距离
摩擦裕度 接触力接近滑动边界 需要接触法向力和摩擦系数等信息

不同原始量先归一化并统一为“越大越好”,才能聚合。不能把瓦特、弧度和米每秒直接相乘后当作分数。

源码细节也影响物理解释:默认 metric_dt=0.1 s,即以 10 Hz 采样指标,并非每个物理步都采样。“关节功率”使用各关节 τiq˙i|\tau_i\dot q_i| 的 RMS 再归一化,不是所有关节的功率之和或累计能量;“力矩平滑性”使用相邻指标采样时刻的力矩差 RMS,没有除以时间间隔,不能直接称为 dτ/dtd\tau/dt。换采样周期后照搬归一化参数,分数可能不再可比。代码:关节指标稳定性指标

6.2 ZMP:为什么世界坐标系不能混

论文附录 A 按刚体聚合惯性和重力项,求出合力 FF 与关于活动接触点中心的合矩 MM。投影到虚拟水平面后:

xzmp=My/Fz,yzmp=Mx/Fz.x_{\mathrm{zmp}}=-M_y/F_z, \qquad y_{\mathrm{zmp}}=M_x/F_z.

归一化分数使用 ZMP 到该中心的平面距离:

mzmp=max(0,1xzmp2+yzmp2Dnorm).m_{\mathrm{zmp}} =\max\left(0,1-\frac{\sqrt{x_{\mathrm{zmp}}^2+y_{\mathrm{zmp}}^2}}{D_{\mathrm{norm}}}\right).

我的理解:这提供了“偏离名义支撑尺度多少”的连续指标,但两组不同接触点即使中心相同,支撑多边形形状也可能差很大。因此不能把它叫作“到真实支撑边界还有多少米”。

实现时,位置、角速度、角加速度和惯量要在一致坐标系表达;如果将机体系惯量直接与世界系角速度做叉乘,数值可能看起来平滑,却不再是同一个物理量。还必须定义无接触、近零 FzF_z 时的处理,不把腾空样本的约定值解释成稳定性保证。

当前实现无接触时将 ZMP/摩擦分数返回 1,ZMP 的近零合力情况也作特殊处理,并另有 invalid/FZMP 等诊断日志。因此只看这两项的高分,不能证明所有时间点都有稳定支撑。

6.3 摩擦裕度:谁承重多,谁的接触更重要

对接触 ii,一种与论文一致的表示为:

si=max(0,1fitanμfin),mfric=ifinjfjnsi.s_i=\max\left(0,1-\frac{\|f_i^{\mathrm{tan}}\|}{\mu f_i^n}\right), \qquad m_{\mathrm{fric}}=\sum_i\frac{f_i^n}{\sum_j f_j^n}s_i.

教学算例:两只脚的法向力是 80 N 和 20 N,剩余裕度分别为 0.2 和 0.9,则总裕度是 0.8×0.2+0.2×0.9=0.340.8\times0.2+0.2\times0.9=0.34,不是简单平均得到的 0.55。主要承重脚接近摩擦极限,不能被另一只轻载脚的好成绩掩盖。

注意这个量只涉及所建模的平移摩擦条件,不是完整接触扳手锥全部约束都满足的证明。依据:论文附录 A-A

上式按每处单一有效接触作教学说明。实际代码先汇总同一足端的多个接触:切向力幅值之和与各接触 μfn\mu f_n 之和形成利用率,再对每只脚的余量按法向载荷加权。多接触点或不同摩擦系数时,不能把所有接触力直接向量相加后套一个固定 μ\mu

7. 从一段轨迹到总分:质量、难度、随机化都要算

RoboGauge 评估代码的分数流程:逐时刻指标合成、最差时间段、最高难度与跨场景聚合

原创示意,特别区分“先在时间上平均”与“先合成指标再选困难时段”。

7.1 五类地形为什么又写七种环境

论文评估的五大类是平地、波浪、坡、楼梯、障碍;坡与楼梯各有两个方向,于是得到七个配置,论文将其描述为上行/下行。非平地按十级难度变化。这里的七种评估配置,不要与训练时包含 rough slope 的七种地形名称表混用。

源码要另外辨认:当前配置后缀 fd/bd 修改初始 yaw 和命令方向,在同一个地形、目标点上区分前向/倒退行走,并不能不加核对就当作物理意义的上坡/下坡。复现记录应保存实际 XML、起终点和初始朝向,而不只记录一个地形名字。

随机化也有两个层次:负载、摩擦、延迟、观测噪声是扰动类型;v4 核心评分中 M=9M=9 对应摩擦系数 0.2, 0.3, …, 1.0 的九档。它不是自动形成九类因素的全排列,也不等于训练表 I 的摩擦范围 0.5~1.5

7.2 几何平均让薄弱环节更难被“刷分”掩盖

记八个已归一化的好分数为 mkm_k

Q=exp(k=18wklogmkk=18wk).Q=\exp\left(\frac{\sum_{k=1}^{8}w_k\log m_k}{\sum_{k=1}^{8}w_k}\right).

这是加权几何平均的对数域写法,避免许多小数连续相乘产生下溢。当前评估配置对两项速度跟踪各取权重 2,其余六项各取 1。

几何平均不是“最差项决定一切”,而是比算术平均更惩罚不均衡。某项恰好为零时数学结果为零;实现为避免 log(0) 会设置数值下限,因此极小正数与严格零的区别也应记录。

7.3 Worst-50% 与运算顺序

当前作者评估代码先对每个时间样本的指标求几何平均,再在单个 goal family 内取最差 50% 的时间样本平均。这里不是连续最差半段,而是将样本排序后取较差一半;困难样本可以分散在整段时间里。

每个 seed 执行 max_velocitydiagonal_velocity 两个 family;同一 family 的不同命令阶段先合并时间样本。两个 family 的结果再等权平均,最后对三个评估 seeds 等权平均。它不是按 family 时长加权,也不是只选最好 seed。固定地形、摩擦和等级时,可将代码写成:

Q=1Rr=1R1Gg=1GWorstMean50%{qr,g,t}t,R=3,  G=2.Q=\frac{1}{R}\sum_{r=1}^{R}\frac{1}{G}\sum_{g=1}^{G} \operatorname{WorstMean}_{50\%}\{q_{r,g,t}\}_t, \qquad R=3,\;G=2.

这里的三次评估随机种子,要与训练三个 seed 再选一个 checkpoint,以及搜索等级用五个 seed,分别理解。代码:goal 内统计goal 间汇总seed 汇总

这不同于“先对整段轨迹的各项指标求均值,再算几何平均”。例如两时刻两指标分别是 (1,0.01)(0.01,1)

  • 先逐时刻合成,两次都是 0.01=0.1\sqrt{0.01}=0.1
  • 先对指标取时间均值,会得到 (0.505,0.505),再合成是 0.505。

两者相差很大。后者把发生在不同时刻的两个短板互相抵消了。

7.4 难度加分为什么允许相邻等级重叠

非平地最高可通过等级记为 LL^*,在至少通过第 1 级时,评分为:

S=0.09(L1)+0.19Q.S=0.09(L^*-1)+0.19Q.

L[1,10]L^*\in[1,10]Q[0,1]Q\in[0,1] 时,公式范围为 [0,1][0,1]。质量权重 0.19 大于一级的难度奖励 0.09,因此低一级的高质量运动有机会胜过高一级的勉强通过。

代码对平地单独取 S=QS=Q,不加等级项;非平地没有通过任何等级、记作 L=0L=0 时,该项得 0 分。不能把 0 级代入上式得到负分,也不能把平地机械当成 1 级、使其最高只有 0.19 分。

再对随机化条件和七个地形配置取算术平均得到汇总分数。最后的总分仍然是平均值,不是最坏环境安全下界;评估报告应同时保留分地形、分扰动结果。

难度搜索也隐含“越难通常越不容易通过”的近似单调性。真实步态可能在某个中间台阶高度更差,所以二分搜索节省测试量的同时,需要抽查相邻等级和失败轨迹。

7.5 失败回合不自动等于零质量

这是读源码后尤其需要保留的限制:出现翻倒等普通异常时,评估器会保存当前 family 已采集的指标,跳过其剩余子命令,再重置继续其他 family。没有把剩余计划时长全部补零status=error 也不会自动让已保存的 summary 全部归零。完全没有数据时的零值,与执行到一半失败,是不同情况。

因此报告必须同时查看 Q、错误状态、执行了多少命令、样本数量和失败轨迹。严重穿模还有重试路径,进程异常也可能留下部分汇总;仅见 “Benchmark Completed” 或一个不错的平均分,不足以确认整张评估矩阵都已完成。代码:异常与切换 goalstress 汇总

8. 两个自己算得出的例子

以下数值是教学构造,不是论文实验数据

8.1 平均值高,不代表质量更均衡

为便于手算,这里八项权重都设为 1,区别于正式评估权重。

构造策略 八项分数 算术均值 几何均值
A 八项均为 0.7 0.7000 0.7000
B 七项 0.9,一项 0.1 0.8000 0.6839

若最后一项代表接近滑动边界,算术均值会把 B 评得更高;几何均值会提醒我们:它的高分建立在一个明显短板之上。

8.2 低一级但走得好,可能更值得部署

策略 C 在第 6 级质量为 0.95,策略 D 在第 7 级质量为 0.40:

SC=0.09×5+0.19×0.95=0.6305,SD=0.09×6+0.19×0.40=0.6160.S_C=0.09\times5+0.19\times0.95=0.6305, \qquad S_D=0.09\times6+0.19\times0.40=0.6160.

这里 C 更高。评分设计不是只奖励“碰巧爬得更高”,而是在通过能力与执行质量之间做显式取舍。

可以下载 无依赖 JavaScript 算例,在仓库根目录执行:

node source/downloads/code/robogauge_notes/score_demo.mjs

它只复算这些标量例子,不加载 ONNX、不启动 Docker,也不是完整 RoboGauge 评估器。修改脚本中的分数即可观察两种均值和等级重叠如何变化。

9. 结果应该怎样读,才不会高估论文

9.1 仿真比较支持改进,但不是无条件公平性证明

论文表 IV 报告的总分中,MoE 为 0.6713,CTS 为 0.5786,HIM 为 0.5379,DreamWaQ 为 0.5054。相比 CTS 的相对提升约为 16%,不能说成“真机成功率提高 16%”。

这里有两个限定:作者对每种算法训练三个种子,随后取最高 RoboGauge 分数的模型;这不是三种子均值和标准差。DreamWaQ/HIM 与 CTS/MoE 的训练和评估命令上限也不完全相同,论文对此作了解释,但阅读时仍需记住实验口径。

消融中,去掉命令信息、把 MoE 放到 Actor-Critic、使用 MCP 等变体均低于主模型,但差距明显小于主模型对 CTS 的总差距。不能把所有提升都归于“MoE 本身”;命令课程、奖励和采样也参与了改进。依据:论文 V-B、V-C,表 IV/V

9.2 “更能预测真机”有证据,但并非每项都更准

作者用 90 Hz 动捕及机器人反馈,在平地和 10 cm 楼梯等场景比较仿真预测与真机测量。表 III 的三类汇总误差,RoboGauge 比训练环境更小。

但附录表 XII 显示:线速度指标的平均绝对误差,RoboGauge 为 0.0873,IsaacGym 为 0.0221,反而是训练环境更接近。 这些是归一化分数的误差,不能附上 m/s 单位。其他多项指标则是 RoboGauge 更好。

因此合理结论是:它改善了该实验设置下多维性能评估的可信度;不是“MuJoCo 的每一个指标都比 IsaacGym 准”。此外,新增 ZMP 和摩擦指标没有出现在这张六项真机校准表里,不能把旧验证直接延伸到新增两项。

论文没有在这一节给出大规模 checkpoint 排序的 Spearman/Pearson 相关系数、完整置信区间或充分的跨机器人验证。它支持有用的选择工具,不构成任意新策略的迁移成功概率预测器。依据:论文 V-A、附录表 XII

9.3 真机视频之外,分母也很重要

几个有明确口径的结果:

  • 横向突发拉力实验:主模型 18/20,内置 RL 为 5/20
  • 30 cm 障碍:主模型 17/20,表中其他基线为 0/20
  • 瓷砖楼梯表中的 85/85 要结合正文“85 个台阶”理解,不应写成 85 次独立完整路线实验。
  • 平地高速实验在约 8 m 室内跑道内达到峰值 4.01 m/s;这是峰值及加速过程,不是长时间巡航测速。

户外实验报告的 100% 成功是作者所测场景的结果;未提供充分试验总量时,不应推断未来任意雪地或沙地都会成功。PCA 聚类、演示视频、存活计数和长期可靠性是不同强度的证据。依据:论文 VI、表 VI

10. 论文与代码不完全一致时,我会怎样复现

这不是吹毛求疵。评估标准的一个不等号或平均顺序,就可能改变 checkpoint 排名。

项目 论文表述 当前源码核对结果/处理方式
指标数量 部分段落 6 项,新表格 8 项 明确区分原六项与新增 ZMP、摩擦
达标阈值 正文“超过 80%”,附录另有三种子旧描述 success_mean >= 0.8;五个种子时 4/5 可通过
时间聚合 文字公式容易被理解为先平均指标再合成 代码先步级合成,再取困难时间片段
mean@25 文字中有 top-25% 表述 当前实现升序截取最差 25%,不是最好 25%
负载均衡 专家偏差求和 实现 MSE 平均,需要连同系数理解
动态跟踪系数 公式与放松约束的文字存在张力 固定实际 reward 实现,不能只抄表 IX
摩擦与地形列表 核心实验用 0.2~1.0 九档、七配置 当前 CLI 默认摩擦仍为 0.5~2.5,默认 stress 地形列表少了 obstacle;须显式覆盖
checkpoint 与自碰撞 主结果对应指定训练模型 当前训练默认开启自碰撞,README 的 137k 模型却是关闭版本,164k 开启版本另列
输出的 ± 很容易被读作标准差或置信区间 当前 stress robust_score 打印的是 np.var 方差,不能沿用其他 summary 的标准差解释

复现报告至少应固定论文版本、代码 commit、checkpoint、模型 XML、观测/动作配置、评估随机种子与归一化参数。源码链接和检查入口列在文末;之后仓库默认配置变化,不应自动覆盖本文的证据版本。

另外,所核对评估代码要求 mujoco<3.3.0,注明接触动力学变化会影响结果。本站已有 MuJoCo 后端与之不是同一个版本契约;这不意味着要降级现有镜像,而是完整评估应独立固定环境,保留已经验收的基线。CLI 默认配置仿真器版本检查

11. 对照本站 CPU/ONNX:可以借鉴,但现在不能直接替换

11.1 现有 flat policy 与论文策略不是同一个控制器

本站 MuJoCo Playground 的 Go2 当前使用另一个社区平地 PPO 策略。它已经有 C++ CPU 推理、MuJoCo/PD、watchdog 和故障恢复,但尚未接入本论文的 MoE 权重或 RoboGauge

接口 本站现有 flat 策略 本文作者 MoE 导出/部署
策略来源 独立社区平地策略 本论文训练与部署仓库
本体历史 当前帧,45 维 5 帧,225 维;还要核对排列
角速度/关节速度缩放 1/1 0.25/0.05
命令 vx, vy, wz 缩放 [1,1,1] [2,2,0.25]
动作缩放 0.5 0.25
网络输出契约 单一 12 维动作输出 导出代码还返回门控权重与 latent
每腿 PD Kp=[20,20,40]Kd=[1,1,2] 全部 Kp=20Kd=0.5
模型与时序 本站固定 Unitree MJCF、500 Hz 物理 作者部署模型与仿真频率单独固定
评估覆盖 短时站立、前进、watchdog、恢复 多地形、难度、扰动和多维评分

右列具体指公开 go2_moe_cts_137k_0.6713 的配套配置。尤其不能因为两者都是 Go2、都是 12 个电机,就复用旧默认姿态、关节映射和观测缩放。配套部署 YAML

11.2 最隐蔽的坑:225 个数怎样排

历史可以按“帧”组织:

frame-major:
[整帧 t-4 的 45 项][整帧 t-3 的 45 项]...[整帧 t 的 45 项]

也可以按“观测项”组织:

term-major:
[角速度的 5 帧][重力投影的 5 帧][命令的 5 帧]
[关节位置的 5 帧][关节速度的 5 帧][上一动作的 5 帧]

作者 ONNX 导出路径使用后一种输入布局,模型内部再通过 flatten_obs() 整理;TorchScript 路径则可以在模型内部维护历史,外部只传当前帧。“同一模型的 TorchScript 和 ONNX”也不一定有同样输入接口。 5 帧相邻间隔为 20 ms,最早与最晚时间戳相差 80 ms;不是五个完整的 20 ms 间隔。代码:TorchScript 与 ONNX exporter

重置也有差异:TorchScript 历史会清零;当前 C++ 部署的 term buffer 使用当前读数重复填满。启动后前几步的输入分布因此不同,必须在契约和对齐测试中明确。代码:历史缓冲与初始化

把本站 deque 简单取出五帧拼接,可能形状完全正确但语义全错。接入前要以人工构造、每项带唯一编号的输入做布局单测,并与训练侧输出逐元素比对。

11.3 多输出和 CPU 的两个误解

作者公开了 ONNX checkpoint,但导出路径包含动作、门控权重和 latent;应实际枚举输出名和 shape,不能臆造辅助输出的名字。本站现有 runtime 只接受一个输入、一个输出,需要显式适配或重新导出只有动作的部署图。

MoE 仍可在 CPU 上运行。作者默认 C++ 路径使用 ONNX Runtime session 与 CPU tensor,没有注册 CUDA provider;并未因为安装包名带 GPU 就自动启用 GPU 推理。但“能够 CPU 推理”不等于已证明本站机器长时间达到 50 Hz:需要将纯 Session::Run、历史构建、IPC、MuJoCo stepping、渲染和端到端控制周期分别计时。代码:OrtRunner

本站遥测 inferenceMs 目前包含 worker 往返,不是纯 ONNX 内核耗时。应增加 p50/p95/p99、missed-deadline、内存和带渲染负载测试,再讨论专家数的性能代价。

11.4 我建议的复现顺序

  1. 先学评估思想:在原有 flat 策略上固化前后左右、转向和急停测试;自定义指标明确称为本站评估,不冒充 RoboGauge 分数。
  2. 再对齐策略契约:固定作者 checkpoint 与 YAML,测试历史布局、关节顺序、缩放、ONNX 多输出和重置时的历史填充。
  3. 再做平地闭环:独立策略 ID、独立 adapter,在仿真里测试站立、各方向指令、超时和跌倒保护,不覆盖旧策略。
  4. 最后接完整评估:复用固定版本 RoboGauge,逐地形保存原始日志、失败次数和完整随机化配置。

这四步是后续方案,不是本篇笔记已经执行的实验。本轮没有替换镜像、启动真机控制或声称复现论文性能。

12. 读完后应该能回答的问题

  1. 为什么当前观测相同,历史不同,学生仍应输出不同 latent?
  2. batch 平均门控均匀,是否就证明每个专家有不同技能?
  3. 为什么先平均再求几何均值,会掩盖交替出现的短板?
  4. ZMP 离接触中心近,是否一定意味着远离支撑多边形边缘?
  5. 为什么 0.6713 不能直接翻译成“真机成功率 67.13%”?
  6. 一个 [1,225] 输入、12 动作的 ONNX,为什么仍可能无法正确部署?
  7. 如果一个 checkpoint 被同一评估套件反复挑选,是否可能对评估本身过拟合?

我的总结是:这篇最有价值的是把“更强的表示”和“更可信的选模型依据”放在同一个研发循环里。MoE 增加能力,RoboGauge 帮助发现能力的边界;后者不能被一个漂亮的总分替代。

相关笔记与原始资料

本文源码核对快照

仓库 本次固定 commit 重点入口
go2_rl_gym 30e74dc507bec ActorCriticMoECTS、MoE 编码器、双优化器、exporter
RoboGauge d1b2ecf5a0d1 base_goal.pybase_gauge_config.pylevel_pipeline.py
unitree_cpp_deploy a422ec4c5268 137k ONNX、其配套 YAML、ObservationManager、OrtRunner

这里确认了公开文件、源代码和接口约定;本轮没有下载并执行作者 ONNX 二进制,没有实测其 CPU 时延。后续要保存实际模型文件的 SHA-256 并枚举真实输入输出,不能用源码阅读替代模型验收。

本文的标量算例和两张流程图用于教学解释;没有复制论文整页或自动播放真机视频。封面沿用本站 NotUsed 素材,已移动到论文分类的 logo 目录。

3d打印 actor-critic adaptive sampling ai辅助设计 algorithm algorithms anymal apriltag ardupilot atlas attention automation axis-angle bang-bang belief encoder blender bode c++ cadquery calibration camera calibration camera-intrinsics chrome cmake cmakelists cnn colcon computer-vision conan control controller_manager cpp cpu d435i dagger data_struct db depth camera depth-camera design-pattern diagnostics direct collocation dots dtof economics eigen elevation map elf executor factory-pattern fcpx fiducial marker figure finance forge fourier fov freecad gae gazebo gdb geometry git gnu gru guitar hardware humanoid ibus imu interest isaac gym isaac lab isaaclab kdl laplace latent variable latex launch learning-notes legged locomotion legged robotics legged-robot legged_gym life linux linux-kernel linux-tools mac math matlab matrix memory mixture of experts mlp money motion imitation motion-control motor moveit mpc mujoco music-theory network neural mapping ocs2 ode onnx openscad operator optimal algorithm optimal-control perceptive locomotion perf performance personal-finance piano pinhole-camera pinocchio pixhawk pixhawk 6c point-cloud policy distillation ppo privileged learning profiling px4 python qgroundcontrol qos quadrotor realsense reinforcement learning representation learning reward tuning rnn robogauge robot robot parkour robotics ros ros2 ros2_control rsl_rl rtb security sensor-fusion shell signal-processing sim-to-real simulation socket soft dynamics constraints spot ssh stairs stl stm32 tcp-ip teacher policy teacher student teacher-student temporal convolution terrain reconstruction thread tools tron1 twist ubuntu uml uncertainty unitree unitree g1 urdf vae valgrind vcxsrv velocity vim web wifi wiring work workflow wsl z-transform zero-shot transfer 中文输入 交叉编译 人形机器人 依赖管理 分支管理 动力学 四旋翼 四足机器人 实验诊断 强化学习 接触动力学 数值计算 机器人
知识共享许可协议