人形机器人在一个模拟器里能运动,并不代表换一个物理引擎之后还能正常运动。

真正做过 Sim2Sim 的同学通常会遇到这种情况:策略在训练环境里表现正常,一迁移就开始打滑、漂移、抖动,甚至刚起步就摔倒。问题往往不只是“模型没训练好”,还可能来自关节顺序、观测定义、动作缩放、控制周期和接触参数没有对齐。

这篇文章以 Unitree G1 为例,讲清楚一个完整链路:

Isaac Sim / IsaacLab 搭建环境
        ↓
RSL-RL + PPO 训练行走策略
        ↓
复杂地形与扰动下鲁棒微调
        ↓
导出 Actor 和控制元数据
        ↓
MuJoCo 中进行 Sim2Sim 验证

文章最后给出了精简开源项目,代码、MuJoCo 机器人资产、训练入口和演示权重都包含在仓库中;Isaac G1 USD 通过一条命令从 NVIDIA 官方资产地址准备。

在这里插入图片描述

一、这个项目解决什么问题?

项目目标不是只录一段“机器人走起来了”的视频,而是建立一套可以复现、可以评估、也能暴露失败工况的 G1 行走实验链路。

具体包含以下内容:

  • 在 IsaacLab 中定义 G1 强化学习环境;
  • 使用 PPO 从零训练 baseline 行走策略;
  • 在粗糙地形、随机摩擦和外力扰动下进行鲁棒微调;
  • 在 Isaac Sim 中播放并批量评估;
  • 将策略导出为 NPZ / TorchScript;
  • 在 MuJoCo 中对齐 123 维观测和 37 维动作;
  • 测试平地、粗糙地形、斜坡和台阶;
  • 输出 CSV 和 JSON 评估结果;本文截图与视频由原始私有项目的媒体流程制作,不包含在开源仓库中。

这里要特别说明:本文展示的是仿真和 Sim2Sim 验证,不是实机部署结果。

二、技术栈与项目结构

本项目已验证的主要环境如下:

组件 版本或用途
Isaac Sim 5.1.0 standalone
IsaacLab 2.3.2
Python Isaac Sim 内置 Python 3.11
PyTorch 2.7.0 + CUDA 12.8
强化学习 PPO / rsl-rl-lib 3.0.1
Sim2Sim MuJoCo 3.10
机器人 Unitree G1,37-DoF

精简后的项目结构是:

g1-walk-isaaclab-mujoco/
├─ isaac_sim/
│  ├─ assets/                  # 一键准备 Isaac G1 USD
│  ├─ g1_walk_sim51/          # 场景、观测、动作、奖励和 PPO 配置
│  ├─ train.py                # baseline 训练
│  ├─ train_robust.py         # 鲁棒微调
│  ├─ play.py                 # 可视化播放
│  ├─ eval.py                 # 指标评估
│  └─ checkpoints/            # baseline 和 robust 演示权重
├─ mujoco/
│  ├─ assets/                 # G1 MJCF 与 mesh
│  ├─ mujoco_eval/            # viewer、地形与批量评估
│  └─ policies/               # 导出的 Actor
├─ environment/               # 依赖与版本记录
├─ run.ps1                    # Windows 统一入口
└─ run.sh                     # Linux 统一入口

三、Isaac Sim、IsaacLab 和 RSL-RL 分别负责什么?

这三个名字很容易混在一起,可以把它们理解成三层:

  • Isaac Sim 负责机器人、场景和物理仿真;
  • IsaacLab 负责把场景组织成强化学习环境,包括观测、动作、奖励、终止条件和并行环境;
  • RSL-RL 负责 PPO 训练和策略网络更新。

也就是说,Isaac Sim 不是 PPO 算法,RSL-RL 也不负责渲染机器人。三者配合起来,才构成完整训练链路。

在这里插入图片描述
图 2:baseline 策略在 Isaac Sim 平地环境中的评估画面。

四、强化学习环境里最关键的三件事

1. 观测:机器人“看见”什么

本项目的策略输入共 123 维:

观测项 维度
基座线速度 3
基座角速度 3
投影重力 3
速度命令 3
相对关节位置 37
关节速度 37
上一次动作 37
合计 123

其中“投影重力”可以帮助策略判断身体当前是直立、前倾还是侧倾;“上一次动作”可以让策略感知动作变化,减少突然的大幅控制跳变。

2. 动作:策略能控制什么

策略输出 37 维动作,与 37 个受控关节一一对应。动作不会直接当作电机力矩,而是先转成目标关节位置:

目标关节位置 = 默认关节位置 + 0.5 × 策略动作

然后由 PD 控制器根据目标位置和当前状态计算力矩。

3. 奖励:什么样的走路算“好”

奖励通常不只是“向前走得越远越好”。还需要同时考虑:

  • 跟踪目标速度;
  • 保持身体直立;
  • 减少横向漂移和多余旋转;
  • 控制动作幅度与动作变化率;
  • 限制不合理的关节速度和姿态;
  • 对摔倒或异常接触进行惩罚。

如果只奖励前进速度,机器人可能学会一种速度很快但姿态极不稳定的“冲出去”动作。

五、先训练 baseline,再做鲁棒微调

1. 从零训练 baseline

Windows PowerShell 下可以通过统一入口启动:

.\run.ps1 isaac-train --headless --num_envs 4096 --max_iters 1500 --seed 42 --run_name baseline

--headless 表示关闭实时渲染,把 GPU 资源优先留给并行仿真和训练;--num_envs 4096 表示同时采集 4096 个环境的数据。显存不足时,可以先改成 2048、1024 或更小。

在这里插入图片描述
图 3:把主要在平地训练的 baseline 放到粗糙地形中,能够更快暴露策略薄弱环节。

2. 鲁棒微调

有了 baseline 以后,再进入粗糙地形、随机摩擦和外力扰动环境微调:

.\run.ps1 isaac-train-robust --headless --num_envs 4096 --max_iters 2000 --seed 42

项目默认从已有 baseline checkpoint 开始,而不是重新从随机策略训练。这样做的原因很直观:先让机器人学会基本行走,再学习如何应对地形变化和扰动,通常比一开始就把所有困难同时塞进去更容易收敛。

在这里插入图片描述

图 4:鲁棒微调后的策略仍需回到平地检查,避免为了复杂地形牺牲基础步态。

在这里插入图片描述

图 5:robust quick-ft 策略在 Isaac 粗糙地形中的评估画面。

六、terrain_difficulty 0.35 到底是什么意思?

地形难度是一个 0 到 1 的归一化参数,不是 35 度,也不是 35 厘米。

它的基本计算方式是:

实际参数 = 最小值 + difficulty ×(最大值 - 最小值)

例如当前台阶高度范围是 0.05~0.23 米,当难度为 0.35 时:

0.05 + 0.35 × (0.23 - 0.05) = 0.113 米

也就是每级台阶高度约 11.3 厘米。不同地形会把同一个 difficulty 映射到坡度、台阶高度或障碍物高度,所以它描述的是“在当前地形参数范围中的位置”。

七、为什么还要迁移到 MuJoCo?

如果策略只在训练它的物理环境中评估,很难判断它到底学到了稳定的控制规律,还是对某个模拟器的接触细节产生了依赖。

换到 MuJoCo 后,下面这些差异会被放大:

  • 接触和摩擦模型;
  • 关节阻尼、刚度和力矩限制;
  • 基座姿态与速度的坐标系;
  • 关节名称与排列顺序;
  • 仿真步长和策略更新周期;
  • 模型质量、惯量和碰撞几何。

在这里插入图片描述

图 6:同一 baseline Actor 导入 MuJoCo 后,在平地工况中进行独立推理。

八、Sim2Sim 最容易踩坑的地方

1. 关节顺序必须完全一致

策略输出的第 0 个动作如果在 Isaac 中控制左髋关节,在 MuJoCo 中就不能变成右膝关节。维度都是 37 并不代表顺序正确。

2. 观测定义必须一致

除了维度,还要检查:

  • 线速度是在世界坐标系还是机体坐标系;
  • 四元数顺序是 wxyz 还是 xyzw
  • 角速度单位是否一致;
  • 关节角是否减去了默认姿态;
  • 上一次动作使用的是裁剪前还是裁剪后的值。

3. 控制频率必须一致

当前 MuJoCo 侧使用 1 ms 物理步长,每 20 ms 更新一次策略目标,也就是 50 Hz 策略频率。PD 力矩仍然在每一个物理步重新计算。

如果误把策略改成每 1 ms 推理一次,控制行为会和训练时完全不同。

4. 不要只看“有没有摔倒”

还应该记录速度跟踪误差、横向漂移、身体高度、倾角、动作变化率和关节速度等指标。机器人没摔倒,也可能只是站着不动。

九、真实评估结果:成功和失败都保留

下面是本次视频选取的四个 MuJoCo 工况,目标指令均为向前 1.0 m/s:

策略 地形 摩擦系数 单次录像结果
baseline model_1499 平地 0.8 约 6 秒录像内未记录摔倒
baseline model_1499 粗糙地形 0.8 1.84 秒摔倒
robust quick-ft model_1548 斜坡 1.0 约 6 秒录像内未记录摔倒
robust quick-ft model_1548 台阶 0.8 0.60 秒摔倒

在这里插入图片描述

图 7:baseline 在粗糙地形中于 1.84 秒摔倒。失败画面比单纯的成功演示更有诊断价值。

在这里插入图片描述

图 8:robust quick-ft 在摩擦系数 1.0 的斜坡录像中保持行走。

在这里插入图片描述

图 9:同一 robust quick-ft 在摩擦系数 0.8 的台阶工况中于 0.60 秒摔倒。

这组结果不能证明 robust 策略已经适应全部复杂地形。更准确的结论是:当前微调对特定斜坡工况有效,但台阶仍然是明显短板;下一步需要针对落脚高度变化、足端接触和台阶课程学习继续优化。

十、如何运行开源项目?

1. 准备 Isaac G1 USD

.\run.ps1 prepare-isaac-asset

脚本会从 NVIDIA 官方资产地址获取本项目所需的 USD,并校验 SHA-256;该第三方资产不直接进入公开 Git 历史。

2. 静态审计

.\run.ps1 verify

检查许可证、模型文件哈希、123→37 Actor 契约、路径可移植性、MuJoCo 模型和 mesh 引用。

3. Isaac 环境自检

.\run.ps1 isaac-self-check --headless

这一步会真实启动 Isaac Sim、加载 USD、创建环境并验证观测和动作维度。

4. 直接播放演示权重

.\run.ps1 isaac-play-baseline --terrain plane --max_steps 2000
.\run.ps1 isaac-play-robust --terrain rough --terrain_difficulty 0.35 --max_steps 2000
.\run.ps1 isaac-play-robust --terrain slope --terrain_difficulty 0.35 --max_steps 2000
.\run.ps1 isaac-play-robust --terrain stairs --terrain_difficulty 0.35 --max_steps 2000

5. MuJoCo 播放与批量评估

.\run.ps1 mujoco-viewer-baseline --terrain plane --friction 0.8
.\run.ps1 mujoco-viewer-robust --terrain slope --friction 1.0
.\run.ps1 mujoco-eval --terrain plane,rough,slope,steps --frictions 0.4,0.6,0.8,1.0 --duration 10

总结

一个完整的人形机器人强化学习项目,不应该停在“训练窗口里能走”。更可靠的流程应该包括:明确观测与动作契约、保留训练和评估入口、在多种地形下测试、导出独立策略,并换一个物理引擎检查策略对仿真细节的依赖。

这次 G1 实验既保留了平地和斜坡中的正常行走,也保留了粗糙地形和台阶中的摔倒结果。后者不是项目的污点,而是下一轮奖励设计、域随机化和课程学习最直接的依据。

B站解析视频:
https://www.bilibili.com/video/BV1963d6kE36/?vd_source=6aeed6700d488ca78e0e8c51ab08c727
开源项目地址(即将开源):
https://github.com/yezzzzye/g1-walk-isaaclab-mujoco

如果你正在做人形机器人、强化学习、IsaacLab 环境开发或 Sim2Sim 验证,欢迎交流。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐