🤖 roboto_origin_03 Wiki
首页 / 项目根 / Sim2Sim迁移与MuJoCo验证

Sim2Sim(Simulation-to-Simulation)迁移是连接Isaac Lab大规模并行训练与真实机器人部署之间的关键验证环节。其本质在于:将在GPU并行环境中以数千个环境实例训练得到的神经网络策略,迁移到基于CPU的确定性物理引擎MuJoCo中,在单机器人、精确物理建模的条件下验证策略的鲁棒性与泛化能力。这一步骤成功通过后,策略方可进入Sim2Real阶段部署至真实硬件。本章聚焦MuJoCo验证环境的搭建、策略模型的导出流程、观测与控制管道的精确对齐,以及针对不同算法变体的专用验证脚本。

核心架构与数据流

Sim2Sim验证链路可被抽象为训练态导出→模型序列化→运行时加载→观测重映射→策略推理→底层PD执行六个阶段。与Isaac Lab中向量化环境一次性处理数千条轨迹不同,MuJoCo验证采用单实例串行仿真,更贴近真实机器人控制回路的时间特性。

flowchart LR
    subgraph Train["Isaac Lab 训练环境"]
        A1["并行环境 (8192 instances)"]
        A2["RSL-RL Runner"]
        A3["Actor-Critic Network"]
    end
    subgraph Export["模型导出"]
        B1["play.py / play_bm.py / play_amp.py"]
        B2["Torch JIT (policy.pt)"]
        B3["ONNX (policy.onnx)"]
    end
    subgraph Verify["MuJoCo 验证"]
        C1["sim2sim_atom01*.py"]
        C2["MjModel / MjData"]
        C3["观测构造与关节重映射"]
        C4["PD Controller"]
    end
    subgraph Output["结果输出"]
        D1["simulation.mp4"]
        D2["joint_positions.png"]
        D3["base_velocities.png"]
    end
    A1 --> A2 --> A3
    A3 --> B1
    B1 --> B2
    B1 --> B3
    B2 --> C1
    C1 --> C2 --> C3 --> C4
    C4 --> D1
    C4 --> D2
    C4 --> D3

在架构图中,模型导出阶段负责将PyTorch动态计算图固化。对于标准策略,调用export_policy_as_jitexport_policy_as_onnx完成序列化;而对于带注意力编码器(AttnEnc)的策略,则需通过自定义的TorchAttnEncPolicyExporterOnnxAttnEncPolicyExporter处理感知观测分支与编码器前向逻辑。MuJoCo端的所有脚本均遵循同一套内环高频仿真、外环策略推理的双层控制节奏。

Sources: play.py, sim2sim_atom01.py

策略导出:从训练环境到可部署模型

策略导出发生在训练完成后的play阶段。根据策略类型的不同,项目提供了三套导出入口:play.py(基础Locomotion与AttnEnc)、play_bm.py(BeyondMimic多技能)、play_amp.py(AMP模仿学习)。三套脚本的核心差异在于是否包含额外的观测编码器或循环网络,但导出逻辑遵循统一模式:首先从runner.alg.policy(或向后兼容的runner.alg.actor_critic)提取策略网络,再提取归一化器(actor_obs_normalizerstudent_obs_normalizer),最后写入{checkpoint_dir}/exported/目录。

对于标准前馈策略,export_policy_as_jitactor模块与归一化器封装为torch.jit.ScriptModule并保存为policy.pt。该文件可被torch.jit.load直接加载,无需依赖原始训练代码。对于注意力编码器策略,导出器额外处理了编码器encoder、可选的观测编码器actor_obs_encoder以及价值估计器estimator的前向组合逻辑,确保感知特征与本体观测在推理时正确拼接。ONNX导出遵循相同逻辑,但采用opset_version=18以兼容linux-aarch64平台。

Sources: play.py, play_bm.py, play_amp.py

MuJoCo模型配置

验证使用的物理模型定义于modules/atom01_description/mjcf/目录下,包含**atom01.xml(平面环境)与atom01_terrain.xml**(地形环境)两个变体。两者的关节树、惯量参数与执行器规格完全一致,差异仅在于世界体(worldbody)中的地面几何与机器人初始高度。

模型采用23个旋转电机执行器motor类型,gear=1,ctrlrange=±200),对应全身23个驱动关节。关节默认属性通过leg_joint_paramarm_joint_paramwaist_joint_param三类default类统一施加:damping=0.01、frictionloss=0.01、armature=0.01。传感器配置高度完整,包含基于site的IMU传感器(framequat姿态、gyro角速度、velocimeter线速度、accelerometer加速度)以及全部23个关节的actuatorposactuatorvelactuatorfrc。这些传感器数据构成了Sim2Sim观测空间的物理基础。

配置项 平面环境 (atom01.xml) 地形环境 (atom01_terrain.xml)
地面类型 plane几何 hfield高度场
初始base高度 0.75 m 2.75 m
高度场文件 terrain_hfield.png
物理步长 0.001 s 0.001 s
求解器 PGS, iterations=100 PGS, iterations=100

地形环境的初始高度更高(2.75m),是为了避免高度场起伏导致机器人初始穿透地面。运行时可通过--terrain标志切换模型路径。

Sources: atom01.xml, atom01_terrain.xml

观测空间与控制管道

Sim2Sim脚本的核心复杂度在于将MuJoCo的物理状态精确地重构为策略训练时期望的观测向量。所有脚本共享同一套get_obspd_control原语,但在观测拼接、命令注入和干扰测试上存在变体。

观测提取

get_obs函数从MjData中解析六组物理量:关节位置q、关节速度dq、IMU姿态四元数quat、基座线速度v(通过旋转矩阵转换到机体坐标系)、IMU角速度omega,以及重力方向向量gvec。其中qdq仅取最后num_actions维,对应驱动关节;姿态传感器使用[x, y, z, w]顺序的Scipy四元数约定,需与Isaac Lab的约定对齐。

Sources: sim2sim_atom01.py

关节顺序重映射

Isaac Lab中的关节排序与URDF/MuJoCo的关节排序不同。脚本通过**usd2urdf**数组完成策略输出到MuJoCo关节索引的映射。以基础脚本为例,usd2urdf = [0, 6, 12, 1, 7, 13, 18, 2, 8, 14, 19, 3, 9, 15, 20, 4, 10, 16, 21, 5, 11, 17, 22]表示:策略输出的第0维动作作用于MuJoCo关节索引0,第1维作用于索引6,依此类推。在观测构造阶段,该映射同样以逆序方式将MuJoCo关节状态重组为策略输入顺序。

Sources: sim2sim_atom01.py

观测向量布局

基础策略的单帧观测维度为78,布局如下:

维度范围 物理量 说明
0–2 omega 基座角速度(机体坐标系)
3–5 gvec 重力方向投影
6 cmd.vx 前向线速度指令
7 cmd.vy 侧向线速度指令
8 cmd.dyaw 偏航角速度指令
9–31 q_obs 关节位置偏差(相对于default_pos)
32–54 dq_obs 关节速度
55–77 action 上一时刻策略输出

通过**frame_stack**机制(基础脚本为10帧),历史观测被沿时间轴堆叠,形成1 × (78 × 10)的策略输入。首帧通过np.tile复制填充,后续帧通过滑动窗口concatenate更新。

Sources: sim2sim_atom01.py

双层控制时序

MuJoCo以1000Hzdt=0.001)推进物理仿真,而策略推理频率通过**decimation**降采样控制。当decimation=20时,策略以50Hz运行;当decimation=10时,策略以100Hz运行。在每个低频控制周期,脚本执行策略推理得到目标关节位置target_pos,随后在每个高频物理步由pd_control计算力矩并注入data.ctrl。力矩经过±tau_limit限幅后进入MuJoCo求解器。

Sources: sim2sim_atom01.py

验证脚本矩阵与选型指南

项目针对五种不同的训练范式提供了专用的Sim2Sim验证脚本。开发者应根据训练时使用的算法与环境配置选择对应的脚本,确保观测空间维度与命令接口完全匹配。

脚本 适用算法/策略类型 观测维度 特殊功能 命令接口
sim2sim_atom01.py 基础PPO Locomotion 78 × frame_stack 标准验证,matplotlib绘图 固定零指令
sim2sim_atom01_amp.py AMP模仿学习 78 × frame_stack 键盘实时调速,相机跟随 小键盘8/2/4/6/7/9
sim2sim_atom01_bm.py BeyondMimic多技能 121 × frame_stack 动作参考跟踪,循环播放,RateLimiter 动作文件驱动
sim2sim_atom01_attn_enc.py 地形感知+注意力 78 × frame_stack + 地形扫描 MuJoCo射线地形感知,可视化 固定零指令
sim2sim_atom01_interrupt.py 中断/干扰鲁棒性 79 × frame_stack 时间窗口内注入is_interrupt标志与手臂扰动 固定零指令

若策略使用了与标准配置不同的frame_stacknum_single_obs或关节映射,必须在对应脚本的Sim2simCfg类中同步修改,否则会出现维度不匹配或关节错乱。

Sources: sim2sim_atom01.py, sim2sim_atom01_amp.py, sim2sim_atom01_bm.py

各策略类型的Sim2Sim实现细节

基础Locomotion验证

sim2sim_atom01.py是最简验证脚本,适用于基础Locomotion策略训练产出的模型。该脚本不包含交互式命令输入,默认以零速度指令运行,主要用于验证策略在静态平衡与基础抗扰动能力上的表现。脚本支持--headless模式:在无GUI条件下通过mujoco.Renderer逐帧渲染并编码为simulation.mp4,同时保存关节位置与基座速度对比图。

Sources: sim2sim_atom01.py

AMP模仿学习验证

sim2sim_atom01_amp.py面向AMP模仿学习与动作数据集训练的策略。其最大特点是集成了基于pynput的键盘监听器,允许在仿真过程中实时调整速度指令。控制映射采用小键盘布局:8/2增减前向速度vx4/6增减侧向速度vy7/9增减偏航速度dyaw0重置所有指令,f切换相机跟随模式。脚本还加入了实时时间同步逻辑,通过time.sleep补偿使仿真推进速度与真实时间对齐,便于直观感受机器人运动节律。

Sources: sim2sim_atom01_amp.py

BeyondMimic多技能验证

sim2sim_atom01_bm.py服务于BeyondMimic多技能与注意力策略。与基于速度指令的Locomotion不同,BeyondMimic策略需要外部动作参考作为观测输入。脚本通过--motion_file参数加载.npz动作文件,提取其中的body_pos_wbody_quat_wjoint_posjoint_vel,并在每个策略步将当前帧的动作参考拼接到观测向量中(前46维)。frame_idx函数支持--loop循环播放模式,当时间步超出动作帧数时回卷到起始帧。由于该策略的控制频率与外推参考频率需要严格同步,脚本使用loop_rate_limiters.RateLimiter将策略调用频率锁定在1/(dt*decimation)

Sources: sim2sim_atom01_bm.py

地形感知与注意力编码器验证

sim2sim_atom01_attn_enc.py验证了带注意力机制的地形感知策略。与标准脚本相比,它额外在MuJoCo中实现了射线地形扫描:以机器人基座水平位置为中心,向正下方发射17×11网格的射线(mj_ray),通过geomgroup过滤只与地面碰撞组交互,获取相对地形高度。射线结果经过height_scan_offset偏移与±1.0限幅后,拼接到策略输入的尾部作为感知观测。渲染时,脚本调用mjv_initGeom在场景中绘制红色小球标记射线落点,便于直观调试地形感知范围。

Sources: sim2sim_atom01_attn_enc.py

中断干扰鲁棒性验证

sim2sim_atom01_interrupt.py专门用于测试策略在外部干扰下的恢复能力。脚本在仿真时间t ∈ [1, 7]秒区间内将is_interrupt标志置为True,并直接覆盖左臂与右臂的目标关节位置:左臂保持固定姿态,右臂执行正弦摆动。这种硬编码的关节位置注入模拟了真实场景中手臂被外力牵拉或执行独立任务时的工况。观测空间中第78维为中断标志位,训练时策略已学习将该标志作为状态机切换信号,Sim2Sim阶段通过此脚本验证中断恢复逻辑的可靠性。

Sources: sim2sim_atom01_interrupt.py

运行指南与结果诊断

启动验证

执行Sim2Sim前,需确保已通过play.py等脚本导出policy.pt。基础验证命令如下:

# 平面环境 + 窗口渲染
python robolab/scripts/mujoco/sim2sim_atom01.py \
    --load_model logs/rsl_rl/atom01_locomotion/exported/policy.pt

# 地形环境 + 无头模式(输出视频与图表)
python robolab/scripts/mujoco/sim2sim_atom01.py \
    --load_model logs/rsl_rl/atom01_locomotion/exported/policy.pt \
    --terrain --headless

# AMP策略 + 键盘控制
python robolab/scripts/mujoco/sim2sim_atom01_amp.py \
    --load_model logs/rsl_rl/atom01_amp/exported/policy.pt

# BeyondMimic策略 + 动作参考
python robolab/scripts/mujoco/sim2sim_atom01_bm.py \
    --load_model logs/rsl_rl/atom01_bm/exported/policy.pt \
    --motion_file data/motions/atom01_bm/motion_00.npz --loop

诊断输出

在无头模式下,仿真结束后脚本自动生成两张matplotlib图表:

若发现某一关节存在系统性相位滞后,应检查kps/kds增益配置是否与训练环境一致;若基座速度存在稳态误差,通常意味着观测构造中的default_posusd2urdf映射与训练时不一致。

Sources: sim2sim_atom01.py

从Sim2Sim到Sim2Real的衔接

MuJoCo验证通过的本质含义是:策略神经网络在不同的物理引擎、不同的接触求解器、不同的数值积分方式下仍能保持稳定。这为后续部署架构与实时内核配置推理节点与ONNX策略部署提供了信心。值得注意的是,Sim2Sim脚本中使用的torch.jit.load接口可直接替换为真实硬件上的ONNX Runtime或TensorRT执行;get_obs中的传感器读取逻辑可直接映射到IMU驱动与传感器集成电机驱动与CAN总线通信提供的实际数据流;而pd_control层则对应真实执行器的底层伺服环路。因此,Sim2Sim代码不仅是验证工具,更是Python SDK与二次开发可直接参考的控制模板。