Issca Lab
Issca Lab 介绍
NVIDIA Isaac 家族不是单一产品,而是一套面向「物理 AI / 具身智能」的机器人全栈平台。
一、Isaac 家族核心成员(按层级)
| 产品 | 定位 | 和 RL 的关系 | 现状 |
|---|---|---|---|
| Isaac Gym | 早期独立 GPU 物理 RL 仿真器 | 纯 RL 吞吐原型 | 已弃用,迁 Isaac Lab |
| Isaac Sim | 基于 Omniverse 的高保真仿真器(PhysX + RTX + USD + 传感器) | 提供环境/物理/渲染,不含训练循环 | 主力维护,仿真底座 |
| Isaac Lab | 架在 Isaac Sim 上的开源机器人学习框架 | RL/模仿学习主战场,千级并行 env,接 RSL-RL/SKRL/SB3 | 当前标准答案 |
| Isaac ROS | ROS 2 上的 CUDA 加速感知/导航包 | 训好的策略部署到 Jetson 真机 | 边缘部署层 |
| Isaac GR00T | 人形 VLA 基础模型 + 数据蓝图 | 用 Isaac Lab 做后训练/评测 | 人形专用 |
| 辅助库 | cuMotion(运动规划)/FoundationPose/FoundationStereo/TeleOp/Cosmos | 提供姿态、深度、遥操数据、合成数据 | 配合 Sim+Lab 用 |
关系:Isaac Sim = 操作系统级仿真平台,Isaac Lab = 上面的 RL 训练 App,装 Lab 会自动带 Sim 依赖。
二、强化学习场景
- 99% 做机器人 RL / 模仿学习的新项目 → 只装
Isaac Lab
它默认把 Isaac Sim 作为依赖拉进来,拿到的是「仿真+并行训练+task manager+RL 库接口」完整组合,别再碰 Isaac Gym。 - 只做数字孪生 / 合成数据 / 可视化,不训策略 → 单装
Isaac Sim - 人形机器人 + 视觉语言动作(VLA) + 少量演示微调 →
Isaac Lab+GR00T+Cosmos+TeleOp - 真机部署 → 训完用
Isaac ROS跑在Jetson Orin/Thor上
硬件门槛:本地至少 RTX 3090/4090 级;大规模并行建议 A100/H100 或 OVX/DGX。
提醒
- 看到 2023 年前的 Isaac Gym / OmniIsaacGymEnvs / Orbit 教程:Orbit 已合并进 Isaac Lab,Gym 已废弃,import 基本要重写到
isaaclab.* - Isaac Lab 3.x 起可轻量独立跑(不挂 Omniverse 渲染),但高保真传感器任务仍要 Sim 后端
- 别在 RL 初期死磕 RTX 光追渲染,先关渲染跑吞吐,再开渲染做 sim2real 校验
三、RL 学习路径
阶段 0|前置(1 周)
- 物理 AI 概念、ROS 2 基础、OpenUSD 概念、PyTorch 基础
- NVIDIA 官方《自主机器人入门》《OpenUSD 学习路径》
阶段 1|仿真底座(2–3 周)
- 平台:Linux 是首要支持平台(官方文档默认 Ubuntu 22.04+),Windows 也能跑但坑多,真做 RL 并行训练基本都在 Linux 上
- 课程:Getting Started With Isaac Sim(界面/USD 场景/PhysX/加传感器/ROS2 bridge)
- 动手:把一个 URDF 机械臂转 USD,配相机+夹爪,跑通一个开环抓取场景
- 目标:理解 stage、articulation、contact、domain randomization
阶段 2|RL 框架核心(3–4 周,重点)
- 课程:Getting Started With Isaac Lab(manager-based / direct 工作流、Cloner 并行、reward 设计)
- 先跑官方 env:Cartpole → Quadcuped locomotion(PPO) → Franka 抓取
- 接 RL 库:RSL-RL(最常用)→ SKRL → SB3
- 目标:单机 4090 上 4096 env 并行,几小时出收敛曲线
# Linux + conda/uv 建个隔离环境,Python 版本对齐 Isaac Sim(4.X→3.10,5.X→3.11,6.X→3.12)
conda create -n env_isaaclab python=3.11
conda activate env_isaaclab
# 1) pip 装 Isaac Sim
pip install "isaacsim[all,extscache]==5.1.0" --extra-index-url https://pypi.nvidia.com
# 2) 克隆 Isaac Lab 源码,可编辑安装(带 rsl_rl/sb3/skrl 等)
git clone https://github.com/isaac-sim/IsaacLab.git
cd IsaacLab
./isaaclab.sh --install # 等价于 pip install -e .[all]
# 3) 跑 PPO 四足/蚂蚁
python scripts/reinforcement_learning/rsl_rl/train.py --task=Isaac-Ant-v0 --headless
阶段 3|自定义任务(持续)
- 用
isaaclab.tasks写自己的 reward / observation / action - 加域随机化、噪声、动力学标定,压 sim2real 差距
- 用 Isaac Lab-Arena 做策略评测
阶段 4|模仿学习 / 人形进阶(可选)
- TeleOp 采演示 → GR00T 后训练 → Lab 评测 → Jetson Thor 部署(参考 Unitree G1 / SO-101 官方 workflow)
- 四足/人形步态、双臂装配、避障导航分别对应 Locomotion / Manipulation / Navigation 任务族
阶段 5|真机闭环
- Isaac ROS GEMs 做感知,加载 Lab 导出的 policy checkpoint,NITROS 零拷贝打通实时控制
这五个不是同一层的东西,混着比容易乱。按「它到底是什么」先分层,再给一张对照表,最后落到你做 Isaac Lab RL 该怎么选。
四、机器人描述语言
URDF 更基础;从「物理仿真自包含、离可跑 RL 最近」的角度,MJCF(MuJoCo XML)更基础。两者都是 XML,但 URDF 只描述「机器人长啥样+怎么连」,MJCF 一口气把「地面、接触、执行器、传感器、solver」全描述了
- URDF:XML,单机器人运动学描述(link/joint/inertial/visual/collision),ROS 事实标准。
- Xacro:不是独立格式,是 URDF 的宏预处理器(变量/宏/循环/include),
xacro a.xacro > a.urdf后产物还是 URDF。 - SDF(SDFormat):XML,Gazebo 原生,URDF 的超集——能描述整个世界(灯光/地面/多机器人/传感器/物理求解器/插件)。
- MJCF:XML,MuJoCo 原生,面向接触动力学与 RL,支持 tendon/equality/actuator 精细建模,闭链也能表达。
- USD / OpenUSD:Pixar 发明、NVIDIA 主推的通用场景图(二进制 .usdc / 文本 .usda / 包 .usdz),不是纯机器人格式,而是「机器人+环境+材质+灯光+物理 schema+动画+分层合成」全装进去。机器人只是其中一类 Prim,靠
UsdPhysics/IsaacRobotSchema等 schema 挂物理。
| 维度 | URDF | Xacro | SDF | MJCF | USD (OpenUSD) |
|---|---|---|---|---|---|
| 本质 | 机器人 XML | URDF 宏 | 世界 XML | MuJoCo XML | 场景图 |
| 主要生态 | ROS/ROS2 | ROS 构建期 | Gazebo | MuJoCo/MJX | Omniverse/Isaac Sim |
| 范围 | 单机器人树 | 同 URDF | 整个世界 | 机器人+场景物理 | 任意复杂场景 |
| 闭链/平行机构 | ❌ 不支持 | ❌ | ✅ | ✅ equality 约束 | ✅(经 UsdPhysics) |
| 执行器模型 | 弱(仅 limit/damping) | 同 URDF | 中(plugin) | 强(motor/tendon/gear) | 中(DriveAPI 可双向映射 PhysX/MJCF) |
| 接触参数 | 无原生 | 无 | 有 | 极细(solref/solimp/condim) | 靠 PhysicsMaterial/ContactAPI |
| 传感器 | 靠 Gazebo plugin 补 | 同左 | 原生支持多 | 原生内置 | 原生 + RTX 传感器 |
| 渲染/材质 | 无 | 无 | 基础 | 几乎无 | 全 PBR / MaterialX / RTX |
| 分层/复用 | 无(靠 xacro) | 宏级 | include/nesting | 有限 | 原生 layers/references/variants |
| 大规模并行 | 不适用 | 不适用 | 一般 | MuJoCo 快 | Isaac 千级 env 靠 instanceable |
| 人类可读 | 是 | 是 | 是 | 是 | .usda 是,.usdc 否 |
| 转其他格式 | 源格式 | →URDF | URDF→SDF 几乎无损 | →URDF 丢 tendon/闭链 | ←URDF/MJCF 导入~80%,反向丢材质/层 |
各自站位
- URDF:ROS 管线里描述「这机器人长啥样、关节怎么连」的最小公约数,RViz/MoveIt/实机部署绕不开。
- Xacro:URDF 写人形/多腿/重复模组时少写 80% 重复代码的构建期工具,运行时不存在。
- SDF:用 Gazebo/Ignition 跑完整世界(仓库/风场/多机)才需要它,URDF 可直接
gz sdf -p转。 - MJCF:RL 研究圈(尤其 legged/dexterous)的亲儿子,MuJoCo/MJX 下接触和 actuator 调起来最顺。
- USD:Isaac Sim / Omniverse 的唯一一等公民,不是「机器人描述语言」而是「机器人和整个世界的可合成数字资产」,做高保真 sim2real、SDG、数字孪生必用。
黄金守则:URDF(或 Xacro 展开后的 URDF)做 canonical source,USD 做 Isaac 侧运行格式,MJCF 做 MuJoCo 对照实验。
- 厂商给 URDF/Xacro →
xacro robot.xacro > robot.urdf - Isaac Lab 里用
scripts/tools/convert_urdf.py(或 Isaac Sim URDF Importer)转 USD,开make_instanceable: true(4096 env 并行共享 VRAM,不开必 OOM) - 在 USD 里补 URDF 丢不掉的东西:PBR 材质、RTX 相机、PhysicsDriveAPI(stiffness/damping)、articulation root、self-collision 开关
- 同一机器人要在 MuJoCo 跑基线 →
urdf2mjcf转 MJCF,手动补 tendon/actuator/contact,别指望自动转换保真 - 永远别双向编辑:URDF 改了重转 USD,USD 里只调 Isaac 专用层(用 USD layer 机制叠加,不破坏底层 robot 层)
转换损耗记住三点最痛的:
- URDF→MJCF:闭链、tendon、actuator 动力学全丢
- URDF→USD:Gazebo 传感器标签不认,material 丑,需重指定 drive
- USD→URDF:材质/层/变种/PBR 全没,只能回退出骨架
从零开始写机器人文件
判断建议:
- 在做 MuJoCo+SB3 的 A1 PPO → 直接手写 MJCF 最短路,不用先写 URDF 再转
- 要进 ROS/Isaac Lab → 维护一份 URDF(或 xacro),按仿真器转 MJCF/USD
- 「从零学机器人建模」→ 先写 URDF(概念干净:link/joint 而已),再写 MJCF(懂物理参数)
写 URDF(最小可运行)
URDF 的原子单元就两个:<link>(刚体,含 visual/collision/inertial)和 <joint>(parent→child 的连接)。最小例子——一个底座加一个会转的杆:
<?xml version="1.0"?>
<robot name="minimal_arm">
<!-- 根link必须有一个,世界通过fixed joint挂它 -->
<link name="base_link">
<visual>
<geometry><box size="0.4 0.3 0.1"/></geometry>
<material name="blue"><color rgba="0.2 0.4 1 1"/></material>
</visual>
<collision>
<geometry><box size="0.4 0.3 0.1"/></geometry>
</collision>
<inertial>
<mass value="1.0"/>
<inertia ixxy="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
</inertial>
</link>
<link name="arm_link">
<visual>
<geometry><cylinder radius="0.05" length="0.5"/></geometry>
</visual>
<collision>
<geometry><cylinder radius="0.05" length="0.5"/></geometry>
</collision>
<inertial>
<mass value="0.5"/>
<inertia ixxy="0.005" ixy="0" ixz="0" iyy="0.005" iyz="0" izz="0.005"/>
</inertial>
</link>
<joint name="arm_joint" type="revolute">
<parent link="base_link"/>
<child link="arm_link"/>
<origin xyz="0 0 0.05" rpy="0 1.5708 0"/>
<axis xyz="0 0 1"/>
<limit lower="-1.57" upper="1.57" effort="10" velocity="2"/>
</joint>
</robot>
校验(Ubuntu/ROS 下):check_urdf minimal_arm.urdf;Windows 无 ROS 可用 urdfdom 的 urdf_to_graphiz 或直接在 RViz2 里看。
要点:inertial 不能省(URDF 漏惯性→动力学炸),joint 必须 parent/child 成对,整体是树。
写 MJCF(最小可运行)
且能直接 python -m mujoco.viewer 看
MJCF 用 <body> 嵌套表达父子(不用显式 parent/child),<joint> 写在 body 内,<actuator> 单独一段。最小单摆:
<mujoco model="pendulum">
<compiler angle="radian" meshdir="../meshes"/>
<option timestep="0.002" gravity="0 0 -9.81"/>
<worldbody>
<light name="light" pos="0 0 3"/>
<geom name="floor" type="plane" pos="0 0 0" condim="3"/>
<body name="pole" pos="0 0 1">
<joint name="hinge" type="hinge" axis="0 1 0" damping="0.1"/>
<geom type="capsule" fromto="0 0 0 0 0 -1" radius="0.05" mass="1.0"/>
<site name="tip" pos="0 0 -1"/>
</body>
</worldbody>
<actuator>
<motor name="hinge_motor" joint="hinge" gear="1" ctrlrange="-5 5"/>
</actuator>
</mujoco>
保存 pendulum.xml,跑:
python -m mujoco.viewer --mjcf pendulum.xml
能看到摆下垂、能拖滑块加力矩。这就是 MJCF 比 URDF 更「自包含」的地方:URDF 这份等价物还得外接 Gazebo/ROS-Control 才能动,MJCF 自带 actuator+option 直接仿真。
落到 A1 四足:从零写 MJCF 的正确顺序
规格里已经确定:关节序 FL/FR/RL/RR,hip±0.1,thigh 前 0.8/后 1.0,calf -1.5,stand z=0.42,12 自由度。手写 MJCF 推荐顺序:
- 骨架树:
<worldbody>里先写basebody,<free>joint 给 6DOF 基座(位置0 0 0.42) - 四条腿嵌套:
base → hip_body(pos=0.15 0.1 0) → thigh_body → calf_body → foot_site,每层 body 内嵌<joint type="hinge" axis="..." range="..."/> - geom 代替 mesh 起步:先用
type="box"/"capsule"把腿画出来调运动学,确认轴向后再换mesh stl(A1 官方有 trunk/hip/thigh/calf.stl) - default 块:
<default>里统一定 joint damping、geom rgba、motor ctrlrange,少写重复属性 - actuator:12 个
<position>或<motor>关节,对应你 PD 控制(kp/kd用gainprm或外层写) - contact/exclude:相邻 body(如 thigh 与 trunk)加
<exclude>避免自碰爆炸 - sensor:
<imu>site 挂 base,<jointpos>/<jointvel>全 12 关节,对应你 obs 里的 12 维 - option/flag:
timestep=0.002、solver=Newton、cone=elliptic,接触用solref/solimp调刚度
四足 MJCF 的坑:axis 写在子 body 局部坐标系,hip 绕 X、thigh 绕 Y、calf 绕 Y,但前后腿镜像时 axis 符号要翻(FR 膝 axis=
0 -1 0,FL 膝 axis=0 1 0)。这块 Datawhale 的 Pupper MJCF 教程把 HAA/HFE/KFE 三层轴和 quat 讲得比较实,可对照。
工作流
金标准源:URDF(或 xacro) ← 写一次,ROS/Isaac 都用
├─ MuJoCo 训练 → convert_urdf.py 转 MJCF,手补 actuator/contact/tendon
└─ Isaac Lab → Isaac Sim URDF Importer 转 USD,手补 material/sensor
但当前阶段(MuJoCo+SB3 调 A1 PPO) 不需要 URDF 这层中转,直接维护 a1.xml(MJCF),等要迁 Isaac 再反查 URDF。MJCF 改 joint limit / 加 xfrc 扰动 / 调 friction 都在一个文件里完成,比 URDF→Gazebo 插件→ROS-Control 短得多。
绑定 mesh
Viewer 里的「异形结构」是 OBJ/STL 是最常用的做法。MuJoCo 的 <geom> 本身支持 box/sphere/capsule/cylinder/plane 等基础图元,也能直接 type="mesh" 引外部网格。简单连杆用图元就行;一旦要画 A1 外壳、轮子、夹爪、地形坑洞这种非凸异形,就得靠 mesh 文件。
一、MuJoCo 绑定的 mesh 格式
- OBJ(Wavefront):首选,能带 MTL 材质分组,MuJoCo 原生读
- Binary STL:可以,但不带材质、法线要自动算、面数高会慢
- 不认 STEP/IGES/SolidWorks 原生件,必须先转 STL/OBJ
结论:异形外观 = 引 OBJ/STL;但物理碰撞默认只算它的 convex hull(凸包),这是新手最容易懵的点——viewer 里看着是凹形杯子,仿真里其实是个凸壳,插桩/抓握会穿帮。
二、绑定 mesh 的标准写法(两步走)
1)<asset> 里声明 mesh
<mujoco>
<compiler angle="radian" meshdir="meshes"/> <!-- meshdir 省得每条写路径 -->
<asset>
<mesh name="trunk" file="trunk.obj" scale="1 1 1"/>
<mesh name="thigh_fl" file="thigh_fl.stl" scale="0.001 0.001 0.001"/>
</asset>
scale常用在 CAD 毫米 → MuJoCo 米(乘 0.001)- OBJ 顶点若不在关节原点,用
refpos/refquat补偿,或提前在 Blender 里把原点移到关节处(推荐后者,XML 干净)
2)<geom> 里引用,且视觉/碰撞分离
<body name="thigh_fl" pos="0.15 0.1 0">
<joint name="thigh_fl_j" type="hinge" axis="0 1 0" range="-1.57 1.57"/>
<!-- 视觉:好看但别参与碰撞 -->
<geom type="mesh" mesh="thigh_fl" class="visual"
contype="0" conaffinity="0" group="2"/>
<!-- 碰撞:用简化 capsule 或 convex 分解件 -->
<geom type="capsule" fromto="0 0 0 0 0 -0.25" radius="0.04"
class="collision" group="3"/>
</body>
要点:
contype=0 conaffinity=0→ 这个 geom 只渲染不碰撞,异形 OBJ 通常放这- 碰撞用 capsule/box 近似,或对该 OBJ 做 convex decomposition(见下)
group控制 viewer 显隐:按2隐藏视觉、3显示碰撞、H看凸包
三、从 CAD/网上下载到 viewer 完整流程
1. 源头:SolidWorks/Fusion/网上下载 STL/OBJ
(单位毫米→在 Blender 里 Ctrl+A 应用缩放,整体 ×0.001)
2. Blender 修:
- 原点移到关节中心(Edit Mode 选关节处顶点 → Cursor to Selected → Origin to Cursor)
- Z-up、右旋坐标系对齐 MuJoCo
- 删内部面、修非流形边(MeshLab: Re-Orient all faces coherently)
- 面数精简到几百~几千(Quadric Edge Collapse)
- 导出 OBJ(勾 Z-up, +X forward)
3. (可选)凹形件做凸分解:
pip install obj2mjcf
obj2mjcf --obj-dir ./meshes --save-mjcf --compile-model --decompose
→ 把杯子/夹爪拆成若干 convex hull 组合,碰撞才准
4. 写 MJCF:asset 声明 + body 里 geom 引用(视觉/碰撞分离)
5. 校验:python -m mujoco.viewer --mjcf your.xml
快捷键:2/3 切视觉碰撞,H 看凸包,Ctrl+R 看编译后碰撞形状
四、A1 四足落地
用 capsule 搭的 A1 能跑 PPO,但 viewer 里是「棍棍机器人」。要换成宇树官方外观:
- 去 MuJoCo Menagerie 或 Unitree 官方拿
a1/a1.xml+meshes/*.stl(trunk/hip/thigh/calf 各一份) - 把
a1.xml里<geom type="mesh" mesh="trunk"/>这种直接留着,关节轴/limit/stand_z=0.42 按你规格改 - 碰撞件保留 capsule 近似(四足腿细,capsule 足够),外壳 trunk 用
contype=0只好看 - 若从 SolidWorks 画 A1:每条连杆单独导出一个 STL,原点放该连杆关节处,别把整机器人导成一个 OBJ(否则凸包包成铁疙瘩)
五、「异形不显示 / 飞天上 / 全白」排查
- 不显示:路径错(用
meshdir相对路径)、OBJ 有多 sub-mesh 没拆(用 obj2mjcf 拆)、scale 写成 0 - 飞一边去:OBJ 顶点原点不在关节处,没用
refpos也没在 Blender 移原点 → 编译时 MuJoCo 会自动把 mesh 质心对齐到 geom 原点,导致 body 局部偏移 - 全白无材质:OBJ 没 MTL,或没在
<material>里给 geom 配 rgba - 看着凹其实穿模:正常现象,默认碰撞走 convex hull;要真凹形碰撞必须
--decompose出多 convex 或手搭 primitive 组合
Issca Lab 应用
windows 或者 Linux
- VS Code
- Cuda
Issca
以 Windows 下 Isaac Lab 为例
一、Isaac Lab =「Sim 底座 + Lab 框架 + RL 库」三层
1. Isaac Sim(仿真应用程序/运行时)
- 基于 Omniverse,PhysX 物理 + RTX 渲染 + 传感器(相机/LiDAR/IMU)
- Windows 11 x64 官方支持(不是必须 Ubuntu,但 Linux 是首要支持平台,Windows 部分传感器/渲染特性滞后)
- 推荐装法:pip 包
isaacsim[all,extscache]==5.1.0(Isaac Sim 5.x 锁 Python 3.11,4.x 锁 3.10) - Windows 注意:开长路径支持,否则安装报路径过长错误;首次启动接受 Omniverse EULA;驱动用 580.88+ 生产分支
2. Isaac Lab(Python 框架,不是 exe)
- git clone 源码,
isaaclab.bat --install可编辑安装(pip install -e .等价) - 它不自带训练算法,只提供环境(MDP)框架 + 并行封装 + 任务配置系统
- 配套 RL 库靠 selector 装:
rl[rsl-rl]/rl[sb3]/rl[skrl]/rl[rl-games]
3. RL 库层
- RSL-RL(A1 四足最常用,PPO 轻量)
- SB3( MuJoCo 里已经在用,Isaac Lab 也接,但并行吞吐不如 RSL-RL)
- SKRL / rl_games
所以「Isaac Lab 应用程序」这个说法不准确:Sim 是应用,Lab 是
import isaaclab的 Python 包。
二、Windows 最小可跑安装顺序(RTX 独显机)
:: 1) 建环境(Isaac Sim 5.x → Python 3.11)
conda create -n env_isaaclab python=3.11
conda activate env_isaaclab
:: 2) 装 CUDA 版 PyTorch(cu128 例)
pip install -U torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128
:: 3) 装 Isaac Sim pip 包
pip install "isaacsim[all,extscache]==5.1.0" --extra-index-url https://pypi.nvidia.com
:: 4) 克隆 Isaac Lab 源码并可编辑安装
git clone https://github.com/isaac-sim/IsaacLab.git
cd IsaacLab
isaaclab.bat -i "rl[rsl-rl]" :: 装核心 + RSL-RL
:: 5) 验证(应弹出黑视口)
isaaclab.bat -p scripts\tutorials\00_sim\create_empty.py --viz kit
显存底线 8GB 能跑小场景,16GB+ 才舒服;32GB 内存起步。
三、Isaac Lab 相关库全景(与 MuJoCo 栈对照)
| 层 | MuJoCo 路线(之前) | Isaac Lab 路线 |
|---|---|---|
| 物理/渲染 | mujoco 引擎 |
isaacsim(PhysX+RTX) |
| 环境框架 | 手写 gym.Env |
isaaclab.envs (ManagerBasedRLEnv / DirectRLEnv) |
| 向量化并行 | 手搓 DummyVecEnv | 原生 GPU 多 env(2048/4096 一体) |
| 机器人描述 | URDF/MJCF | URDF/MJCF/USD(自动转 USD) |
| 训练 | SB3 PPO | RSL-RL / SB3 / SKRL |
| 回调/日志 | SB3 Callback | 同 SB3 或 Lab 自带 Logger |
四、Sim 流程:一次 step 的内部运行
典型 RL 训练循环(headless 跑,不开渲染窗口省 15~20% GPU):
- Lab 环境 reset:按
EnvCfg建 Scene(地面、灯光、A1 的 USD、传感器),data张量分配在 GPU - 采样动作:Actor 网络输出 12 维 joint pos 残差 → ActionManager 叠到
DEFAULT_JOINT_ANGLES→ 送 Sim 的set_joint_position_target - Sim 步进:PhysX 解算关节/接触/摩擦,
decimation控制「1 个 RL step = N 个物理子步」(如 1:4 @ 200Hz 物理) - 观测采集:ObservationManager 从
data.root_lin_vel_w,data.joint_pos等取张量,做归一化 - 奖励/终止:RewardManager 算 height/vel_track/trot_sync 各项;termination 判翻倒/过低
- buffer 收集:RSL-RL 把 (obs, act, rew, done) 压进 GPU buffer
- PPO 更新:攒够
n_steps跑 minibatch 更新,和 SB3 逻辑一致但全在 GPU - 周期 reset:按 EventManager 做随机化(mass/friction/base push),回到默认站立 + 噪声
Manager-based vs Direct 选择:
- Manager-Based:Obs/Rew/Act/Term 各写 Config 类,改奖励就是改 dict,不碰 step 主体 → 你三阶段切换权重用这个最舒服
- Direct:一个
DirectRLEnv子类手写step(),少一层 manager 调用开销,适合刷极限吞吐或写极简 demo
五、与 MuJoCo A1 脚本衔接
- 现在的
a1_speed_follow_ppo.py(MuJoCo+SB3+DummyVecEnv)不必删,作为算法验证用 - 迁 Isaac Lab 时:把
DEFAULT_JOINT_ANGLES、reward 公式(height/exp、vel_track、trot_sync)、phase 切换逻辑平移成 Manager 的 term 函数 - MuJoCo 里
qpos[2]=0.42→ Isaac 里base_z在RobotBaseCfg.init_state.pos = (0,0,0.42) - 观测 35 维布局可以原样保留,在
ObservationsCfg里拼 - 好处:从 1 个 env 变 4096 并行,A1 四足 PPO 从「几天」变「几小时」,且自带 domain randomization 工具
Windows 上跑训练务必 --headless,GUI 视口只在调试单 env 时开;若显卡是 GTX 1650(,VRAM 4GB 跑 Isaac Sim 会非常吃力——建议降并行数到 256~512 或继续用 MuJoCo 做算法迭代、Isaac 只做最终迁移。
Mujoco → Issca Lab 映射
一、架构映射(MuJoCo → Isaac Lab)
规格里的三阶段 PPO 从 gym.Env 迁移到 Isaac Lab 的 Manager-Based 架构,核心是把原来一个 step() 拆成 5 个 Manager:
你的手写 step() Isaac Lab Manager
───────────────────────── ─────────────────────────────
self._get_base_height() ──→ ObservationManager (35维)
reward = Σ w_i × comp_i ──→ RewardManager (Phase权重切换)
action = default + clip() ──→ ActionManager (残差+裁剪)
if flipped or too_low: ──→ TerminationManager (terminated/truncated)
reset(): xfrc=0, noise ──→ EventManager + _reset_idx
关键区别:你不再重写 step() 主体,只 override 生命周期钩子(_pre_physics_step、_post_physics_step、_get_observations、_check_termination),训练循环由父类 ManagerBasedRLEnv 驱动。
二、一次完整训练流程(Sim 内部 step)
PPO 循环 (RSL-RL, 全 GPU)
│
├─ for step in range(n_steps=2048): ← 收集阶段
│ │
│ ├─ Actor → 12维残差动作
│ │
│ ├─ ActionManager: target = default + delta*scale; clamp(limits)
│ │ set_joint_position_target()
│ │
│ ├─ _pre_physics_step():
│ │ ├─ 施加 xfrc_applied 扰动 (Phase3)
│ │ └─ write_joint_position_target_to_sim()
│ │
│ ├─ PhysX 步进 × decimation(4) ← 1 RL step = 4 物理步 @200Hz
│ │ (接触/摩擦/关节解算)
│ │
│ ├─ _post_physics_step():
│ │ ├─ _step_count += 1
│ │ ├─ _phase_internal += 2π/50 ← ★★ 持续递增, Phase<3 观测为0
│ │ ├─ _update_contact_and_foot_vel()
│ │ └─ _update_joint_vel_history() ← Trot corr 滑动窗口
│ │
│ ├─ ObservationManager → _get_observations() (÷固定常数, 手动归一化)
│ │
│ ├─ RewardManager → Σ weights[key] × _reward_*(...)
│ │ Phase1: height/upright/default_pose/alive
│ │ Phase2: + lin_vel_xy/ang_vel_yaw
│ │ Phase3: + trot_sync/trot_contact/foot_slip
│ │
│ ├─ TerminationManager → flipped>60° / height<0.15
│ │ terminated (摔倒) ≠ truncated (超时) ← ★★ 严格区分
│ │
│ └─ buffer.push()
│
├─ PPO 更新 (minibatch, GPU)
└─ Callback: 每200K存 checkpoint + _norm.pkl
三、15 个改动点速查(全部 ★★ 标记在代码里)
| 编号 | 类别 | 改动 |
|---|---|---|
| A1 | 矛盾修复 | 双层高度:STANDING_HEIGHT=0.42(reset base_z)≠ PHASE1_TARGET=0.30(奖励目标蹲稳) |
| A2 | 精确化 | 裁剪在残差叠加之后:clamp(default+delta),非 clamp(delta) |
| A3 | 精确化 | Phase 权重合并抽出 make_reward_weights(phase) |
| A4 | 可训练 | height 容差 0.05→0.08(梯度更平滑) |
| A5 | 可训练 | orientation/upright 去冗余,Phase1 仅 upright |
| A6 | 精确化 | PHASE2/3_WEIGHTS 独立字典 |
| A7 | 精确化 | Manager-Based 不重写 step() 主体 |
| A8 | 精确化 | gait 相位内部持续递增,Phase<3 观测为 0(防升级跳变) |
| A9 | 工程 | reset 强制清零 xfrc_applied(规格硬要求) |
| A10 | 精确化 | terminated vs truncated 区分(bootstrap 正确性) |
| A11 | 工程 | Trot corr NaN 防护(denom.clamp 1e-6) |
| A12 | 可训练 | VecNormalize → 手动归一化等价(GPU 多 env 原生) |
| A13 | 可训练 | 余弦调度基于全局累计步数,续训 lr 连续 |
| A14 | 工程 | 方式 B 降级交互(骨架简化为报错) |
| A15 | 工程 | 扰动 ramp up/down 自动清零 |
四、文件结构
a1_isaaclab/
├── a1_speed_follow_env.py ← 环境主体 (615行, 全部规格映射)
├── train.py ← 训练入口 (PHASE_CONFIG + 方式A/B/C)
├── phase_weights.py ← 权重切换验证 (独立可运行)
├── test_weights.py ← 纯Python权重验证 (无需torch)
├── run_training.bat ← Windows 一键启动菜单
├── USAGE.txt ← 快速使用指南
└── README.md ← 详细流程/映射表/改动索引
五、使用步骤
:: 1. 验证权重切换 (无需 Isaac Lab)
python phase_weights.py
:: 2. 单 env 跑通 (确认 obs=35维, base_z=0.42)
python a1_speed_follow_env.py
:: 3. 方式 A: 从头训练
python train.py --phase 1 --max-steps 5000000
:: 4. 方式 B: Phase1 模型续训 Phase2
python train.py --phase 2 --increase-steps 3000000 ^
--load-model F:/.../phase1_final_xxx.zip
注意:骨架中 _update_contact_and_foot_vel(足端接触检测)、build_ppo(选 RSL-RL/SB3 后端)、USD 路径这 3 处需按你实际模型补齐——接口和位置都已预留好。
已验证:Phase 权重切换逻辑在 Phase1/2/3 下分别正确激活对应奖励项(输出见上方测试)。
a1_isaaclab.zip

浙公网安备 33010602011771号