在足式机器人强化学习训练中,地形生成与场景配置共同决定了智能体面临的物理挑战空间与感知输入空间。本页聚焦 RoboLab 项目中 Direct RL 环境 与 Manager-based 环境 的地形系统架构,解析从地形生成器预设、场景组装到课程学习动态调度的完整链路,并介绍将 Isaac Lab 地形导出至 MuJoCo 的实用工具。
架构概览:从配置到场景的链路
整个地形与场景系统采用分层配置 + 运行时组装的架构模式。最底层是 TerrainGeneratorCfg 定义地形子类型的组合规则;中间层通过 SceneContextCfg 将地形、机器人、传感器等要素聚合为场景上下文;最上层由 SceneCfg 继承 Isaac Lab 的 InteractiveSceneCfg,在环境初始化时完成 USD 场景的实例化。
flowchart TD
A[TerrainGeneratorCfg<br/>地形生成器配置] --> B[SceneContextCfg<br/>场景上下文]
C[HeightScannerCfg<br/>高度扫描配置] --> B
D[RobotCfg<br/>机器人配置] --> B
B --> E[SceneCfg<br/>场景配置]
E --> F[InteractiveScene<br/>USD 场景实例]
F --> G[BaseEnv<br/>Direct RL 环境]
G --> H[update_terrain_levels<br/>课程学习调度]
这一分层设计的优势在于:地形配置可以独立于具体环境进行复用,同一份 ROUGH_TERRAINS_CFG 既可用于 Direct RL 的 Rough 训练,也可被 Manager-based 的任务引用。同时,SceneCfg 作为桥梁,将抽象的配置参数转换为 Isaac Lab 场景图中的具体 Prim 与传感器。
Sources: terrain_generator_cfg.py, base_config.py, scene_cfg.py
地形生成器配置:三种预设地形
项目在 terrain_generator_cfg.py 中预定义了三种地形生成器配置,分别对应从简单到复杂的训练阶段。每种配置通过 sub_terrains 字典声明多种子地形的比例(proportion),生成器会在网格中按概率采样并实例化对应的地形块。
| 配置名称 | 课程学习 | 典型子地形 | 适用阶段 |
|---|---|---|---|
GRAVEL_TERRAINS_CFG |
False |
随机粗糙地面(30%)+ 平面(70%) | 基础策略学习、平坦地形验证 |
ROUGH_TERRAINS_CFG |
True |
金字塔楼梯、斜坡、随机网格、粗糙地面、平面 | rough 地形适应训练 |
ROUGH_HARD_TERRAINS_CFG |
True |
在 ROUGH 基础上增加高平台、星形、间隙、踏脚石 | 高难度鲁棒性训练 |
所有配置共享相同的地形网格尺寸 size=(8.0, 8.0)、采样精度 horizontal_scale=0.05 和 vertical_scale=0.005,以及 num_rows=10, num_cols=20 的网格规模。这意味着整个地形版图在 X/Y 方向上覆盖 80m × 160m 的连续区域。border_width=20.0 在版图外围生成缓冲区,避免机器人跑出边界后悬空。
ROUGH_TERRAINS_CFG 的子地形设计体现了从结构化到非结构化的渐进覆盖:正/倒金字塔楼梯(MeshPyramidStairsTerrainCfg / MeshInvertedPyramidStairsTerrainCfg)训练攀爬与下坡能力;正/倒斜坡(HfPyramidSlopedTerrainCfg / HfInvertedPyramidSlopedTerrainCfg)训练斜面平衡;随机网格(MeshRandomGridTerrainCfg)与随机粗糙地面(HfRandomUniformTerrainCfg)提供不规则扰动;而 40% 的平面比例确保机器人不会过早陷入极端地形。
Sources: terrain_generator_cfg.py
场景配置组成:SceneCfg 的元素解析
SceneCfg 继承自 InteractiveSceneCfg,在构造函数中接收 BaseSceneCfg(实际传入的是 SceneContextCfg 实例)并展开为具体的场景实体。其核心职责是声明地形导入器、机器人、传感器、灯光以及射线扫描器。
地形导入器(TerrainImporterCfg) 是场景的地基。它通过 terrain_type 决定导入模式:当值为 "generator" 时,Isaac Lab 会调用 terrain_generator 指定的配置 procedurally 生成地形;Manager-based 任务如 AMP 则常使用 "plane" 表示无限平面。collision_group=-1 确保地形与所有碰撞组交互,而 physics_material 中 static_friction=1.0 与 dynamic_friction=1.0 的设置为足式机器人提供了高摩擦的接触面,避免训练中不必要的滑动。
传感器方面,除了标准的 ContactSensorCfg 用于检测全身接触力与足部腾空时间外,SceneCfg 还配置了两组固定的足部射线扫描器(left_feet_scanner / right_feet_scanner)与一组可选的高度扫描器(height_scanner)。足部扫描器以 GridPatternCfg(resolution=0.01, size=[0.12, 0.04]) 在左右脚踝处向下投射射线,用于精确测量足端离地高度,直接服务于奖励函数中的 feet_height 与 feet_slide 项。高度扫描器则安装在机器人躯干(默认 base_link),以更大的视野(默认 size=(1.6, 1.0),resolution=0.1)扫描前方地形高程,为 Critic 网络提供特权观测。
Sources: scene_cfg.py
高度扫描与足部射线感知
高度扫描(Height Scan)是连接地形几何与策略网络的关键感知通道。HeightScannerCfg 通过一组参数控制扫描行为:prim_body_name 指定扫描器附着的刚体;offset=(0.0, 0.0, 20.0) 将射线起点抬高至地形上方,确保射线始终向下命中地面;drift_range 支持在训练时随机偏移扫描器位置以增强鲁棒性。
在 BaseEnv 的观测计算中,高度扫描值被处理为相对高度:
height_scan = self.height_scanner.data.pos_w[:, 2].unsqueeze(1) - self.height_scanner.data.ray_hits_w[..., 2]
height_scan = torch.clamp(height_scan - self.cfg.normalization.height_scan_offset, min=-1.0, max=1.0)
height_scan = torch.nan_to_num(height_scan, nan=1.0, posinf=1.0, neginf=-1.0)
这里 nan_to_num 的处理尤为重要:当射线未命中地形(如投射到间隙上方)时,返回值会被截断为 1.0,网络可以将其语义理解为“下方无地面”。同时,若配置 enable_height_scan_actor=True,高度扫描也会被拼接进 Actor 观测,使策略网络具备直接的地形预判能力;默认情况下仅供给 Critic,用于更精准的价值估计。
Sources: base_config.py, base_env.py
课程学习与地形难度动态调整
ROUGH_TERRAINS_CFG 与 ROUGH_HARD_TERRAINS_CFG 均开启 curriculum=True,这意味着地形难度不是静态固定的,而是在训练过程中根据机器人表现动态调整。BaseEnv 在每次环境重置时调用 update_terrain_levels:
flowchart LR
A[计算机器人距原点距离] --> B{距离 > size/2 ?}
B -->|是| C[地形等级 +1<br/>更难]
B -->|否| D{距离 < 期望位移×0.5 ?}
D -->|是| E[地形等级 -1<br/>更易]
D -->|否| F[保持当前等级]
具体逻辑为:若机器人在当前 episode 中的水平位移超过了地形块尺寸的一半(4m),则认为其已掌握当前难度,地形等级 move_up;若位移远低于指令速度的期望轨迹(command * max_episode_length_s * 0.5),则判定为挣扎,move_down 降级。scene.terrain.update_env_origins 随后将对应环境的出生点迁移到新等级地形块的中心。该机制确保训练样本始终分布在智能体的能力边界附近,最大化样本效率。
课程学习的统计信息通过 extras["log"] 输出,指标 Curriculum/terrain_levels 记录所有环境的平均地形等级,便于在 WandB 等日志系统中监控训练进度。
Sources: base_env.py, base_env.py
环境配置继承:Flat vs Rough
在 atom01_env_cfg.py 中,ATOM01FlatEnvCfg 与 ATOM01RoughEnvCfg 展现了地形配置如何通过继承切换。ATOM01FlatEnvCfg 选择 GRAVEL_TERRAINS_CFG 并关闭高度扫描,状态空间维度为 139;ATOM01RoughEnvCfg 继承前者后,仅修改三处关键配置:
| 配置项 | Flat 环境 | Rough 环境 |
|---|---|---|
terrain_generator |
GRAVEL_TERRAINS_CFG |
ROUGH_TERRAINS_CFG |
enable_height_scan |
False |
True |
state_space |
139 | 326 |
状态空间从 139 跃升至 326,增量主要来自高度扫描网格的像素点(1.6m × 1.0m 以 0.1m 分辨率采样,约 160 个点,再叠加历史帧拼接)。ATOM01RoughEnvCfg 还额外增大了 gpu_collision_stack_size 以应对复杂地形的碰撞检测开销,并微调了 ang_vel_xy_l2 与 lin_vel_z_l2 的奖励权重,降低对竖直方向运动的惩罚,允许机器人在崎岖地面上做更多的姿态调整。
这两个环境最终通过 gym.register 注册为 Atom01-Flat 与 Atom01-Rough,可通过标准的 gym.make 接口调用。
Sources: atom01_env_cfg.py, init.py
Manager-based 环境的地形配置
Manager-based 环境(如 AMP 与 BeyondMimic)采用与 Direct RL 不同的配置风格。以 amp_env_cfg.py 为例,AmpSceneCfg 直接在类体内声明 TerrainImporterCfg,默认使用 terrain_type="plane"。这种设计是因为 AMP 训练初期更关注运动模仿本身,复杂地形会分散对参考运动追踪的学习焦点。当需要引入地形挑战时,开发者可将 terrain_type 改为 "generator" 并绑定对应的 TerrainGeneratorCfg,无需修改环境逻辑代码。
beyondmimic_env_cfg.py 中的 MySceneCfg 同样默认采用平面地形,并使用了不同的视觉材质(Shingles_01.mdl),说明场景配置在 Manager-based 范式下保持了与 Direct RL 同等的可替换性。
Sources: amp_env_cfg.py, beyondmimic_env_cfg.py
地形导出与 Sim2Sim 部署
训练完成后,若要将策略迁移至 MuJoCo 进行 Sim2Sim 验证或真机部署,需要把 Isaac Lab 的 procedurally 生成地形转换为 MuJoCo 可加载的格式。项目提供了 export_terrain.py 工具脚本,支持三种导出模式:
| 导出模式 | 输出格式 | 用途 |
|---|---|---|
--export_mesh |
单一合并 OBJ + CoACD 分解 XML | MuJoCo 碰撞体导入 |
--export_meshes |
每个地形块独立 OBJ + XML | 按需加载局部地形 |
--export_hfield |
16-bit PNG 高度场 + XML 片段 | MuJoCo hfield 几何体 |
脚本内部使用 TerrainGenerator 直接实例化地形,并通过射线检测将 mesh 采样为规则网格高度图。对于 mesh 导出,脚本调用 CoACD(Approximate Convex Decomposition) 将非凸地形分解为多个凸包,生成 MuJoCo 的 <mesh> 与 <geom type="mesh"> 组合。这是因为 MuJoCo 的碰撞检测对凸几何体更高效,而 Isaac Lab 生成的金字塔楼梯、星形等地形本质上都是非凸结构。
在 Sim2Sim 部署脚本 sim2sim_atom01.py 中,通过 --terrain 参数可在平面模型 atom01.xml 与地形模型 atom01_terrain.xml 之间切换,实现训练地形与部署地形的一致性验证。
Sources: export_terrain.py, sim2sim_atom01.py
总结与下一步阅读
地形生成与场景配置在 RoboLab 项目中遵循配置驱动、分层解耦的原则:TerrainGeneratorCfg 负责“生成什么地形”,SceneContextCfg 负责“需要哪些场景要素”,SceneCfg 负责“如何组装进 USD 舞台”。课程学习机制通过 update_terrain_levels 将静态地形版图转化为动态训练课程,而 export_terrain.py 则打通了从 Isaac Lab 到 MuJoCo 的物理资产迁移通道。
如需深入理解地形几何如何影响策略的观测输入与奖励计算,建议继续阅读 奖励函数与 MDP 设计 与 事件管理与指令系统。若关注 Manager-based 环境的完整架构,可回溯 Manager-based 环境架构。