Direct RL 环境是本项目足式机器人训练的核心仿真载体,与 Isaac Lab 的 Manager-based 环境相对,它采用显式代码驱动的方式组织物理步进、观测计算、奖励累加与事件触发,所有逻辑直接编码在环境类的 Python 方法中,而非通过配置化的 Manager 调度。这种设计在保留 Isaac Lab 场景系统与传感器能力的同时,赋予开发者对时序缓冲、观测分组、动作裁剪等环节的完全控制权,非常适合需要精细化定制历史观测堆叠、Actor-Critic 观测不对称以及地形感知增强的足式机器人任务。
Sources: base_env.py
继承链与架构总览
项目中的 Direct RL 环境遵循三层继承体系:最底层是 RSL-RL 定义的 VecEnv 抽象接口,中间层是 Isaac Lab 提供的 DirectRLEnv(封装了场景克隆、物理步进、渲染调度),最上层是项目基类 BaseEnv 及其两个特化子类 AttnEncEnv 与 InterruptEnv。BaseEnv 将所有与 ATOM01 机器人相关的通用逻辑固化下来,包括指令生成、奖励管理、域随机化事件、历史观测缓冲与终止条件判定,而子类仅需通过重写 compute_current_observations() 和 _get_observations() 来注入差异化感知策略。
classDiagram
class VecEnv {
<<abstract>>
+step(actions)
+get_observations()
}
class DirectRLEnv {
+scene
+sim
+_setup_scene()
}
class BaseEnv {
+reward_manager
+event_manager
+command_generator
+action_buffer
+actor_obs_buffer
+critic_obs_buffer
+step()
+compute_current_observations()
+_get_rewards()
+_get_dones()
+_reset_idx()
+update_terrain_levels()
}
class AttnEncEnv {
+compute_current_observations()
+_get_observations()
}
class InterruptEnv {
+init_buffers()
+compute_current_observations()
+_pre_physics_step()
+uniform_interrupt_resample()
}
VecEnv <|-- DirectRLEnv
DirectRLEnv <|-- BaseEnv
BaseEnv <|-- AttnEncEnv
BaseEnv <|-- InterruptEnv
Sources: vec_env.py, base_env.py
BaseEnv 核心生命周期
BaseEnv 的构造函数完成四项关键初始化:实例化 RewardManager 与 EventManager、创建 UniformVelocityCommand 指令生成器、解析场景中的接触传感器与射线扫描器,并调用 init_buffers() 建立多个 CircularBuffer。这些缓冲器以环形队列的形式维护观测与动作历史,actor_obs_buffer 与 critic_obs_buffer 的默认深度均为 10 步,action_buffer 的默认深度为 3 步,这直接决定了策略网络输入的时序维度。
step() 方法是整个训练循环的枢纽,其内部遵循固定的执行节拍:首先将策略输出动作存入 action_buffer 并做裁剪与缩放,随后以 decimation(默认为 4)为周期反复调用 _apply_action() 写入关节位置目标并推进物理仿真;物理步进结束后,更新指令生成器、触发 interval 模式的域随机化事件,接着依次计算终止标志、超时标志与奖励值;对需要重置的环境编号调用 _reset_idx() 完成场景与缓冲器的状态恢复;最后通过 _get_observations() 返回当前步的观测字典。该字典固定包含 "policy" 与 "critic" 两个键,分别对应对称减小的 Actor 观测与包含特权信息的 Critic 观测。
Sources: base_env.py, base_env.py
观测空间:Actor 与 Critic 的不对称设计
本项目采用经典的 Actor-Critic 观测分离 范式。compute_current_observations() 方法在基类中定义了两组观测的拼接规则。Actor 观测仅包含策略在真实部署时能够获取的本体信息:机体角速度、投影重力向量、速度指令、关节位置偏差、关节速度以及上一时刻动作,经 obs_scales 缩放后维度为 78。Critic 观测则在 Actor 观测的基础上追加特权信息:机体线速度、足端接触布尔值、足端接触力、足端腾空时间、足端离地高度、关节加速度与关节力矩,总维度为 139。
这种不对称设计的工程动机在于:Actor 网络必须在仅依赖机载 IMU 与编码器的条件下输出动作,而 Critic 网络在训练阶段可以利用仿真器中的完美状态来提供更准确的价值估计,从而引导 Actor 学习。历史观测通过 CircularBuffer 进行时间维度的堆叠,默认 10 步历史会将 Actor 输入扩展为 780 维,Critic 输入扩展为 1390 维。此外,当启用高度扫描时,Critic 还会追加射线扫描得到的局部地形高度图;若配置 enable_height_scan_actor=True,Actor 也会获得该地形信息。
Sources: base_env.py, base_env.py
配置体系与场景组装
环境的全部可调参数通过 BaseEnvCfg 以 @configclass 装饰器的层级结构进行组织,核心子配置包括:
| 配置类 | 职责 |
|---|---|
SceneContextCfg |
环境数量、间距、机器人资产、地形类型与生成器、高度扫描开关 |
RobotCfg |
观测历史长度、动作历史长度、动作缩放系数、终止接触体名称、足端体名称 |
NormalizationCfg / ObsScalesCfg |
观测裁剪阈值、各观测项缩放系数、高度扫描偏移 |
CommandsCfg / CommandRangesCfg |
指令重采样周期、朝向控制刚度、线速度与角速度指令范围 |
NoiseCfg / NoiseScalesCfg |
是否加噪及各观测通道的高斯噪声强度 |
EventCfg |
启动时与重置时的域随机化事件(摩擦、质量、质心、执行器增益、关节参数) |
RewardCfg |
各奖励项的函数、权重与附加参数 |
SceneCfg 负责将上述抽象配置翻译成 Isaac Lab 的场景原语,包括地形导入器、ATOM01 机器人实例、接触传感器、左右足端射线扫描器(GridPattern,分辨率为 0.01 m,尺寸 0.12 m × 0.04 m)以及可选的机体高度扫描器(GridPattern,分辨率 0.1 m)。足端射线扫描器以踝关节为原点向下投射,用于精确估计足端离地高度,是奖励函数 feet_height 与 feet_slide 的关键数据来源。
Sources: base_config.py, scene_cfg.py
奖励函数设计
项目的奖励函数集中定义在 mdp/rewards.py 中,所有函数均接收 env: BaseEnv 作为第一参数,并返回形状为 (num_envs,) 的 torch.Tensor。奖励项可归纳为以下五类:
| 类别 | 代表奖励项 | 权重量级 | 说明 |
|---|---|---|---|
| 指令跟踪 | track_lin_vel_xy_yaw_frame_exp |
+1.0 | 偏航坐标系下的水平线速度跟踪 |
| 指令跟踪 | track_ang_vel_z_world_exp |
+1.0 | 世界坐标系偏航角速度跟踪 |
| 运动正则 | energy, joint_torques_l2, joint_vel_l2, dof_acc_l2 |
-1e-4 ~ -2.5e-7 | 抑制能量消耗与高频抖动 |
| 动作正则 | action_rate_l2, action_smoothness_l2 |
-2e-2 | 惩罚动作突变与不平滑 |
| 足端行为 | feet_air_time_positive_biped, feet_slide, feet_force, feet_distance, feet_stumble, feet_height |
+0.1 ~ +0.25 | 鼓励双足合理步态与离地间隙 |
| 姿态与接触 | flat_orientation_l2, undesired_contacts, termination_penalty, dof_pos_limits |
-1.0 ~ -200.0 | 维持机体直立、避免异常碰撞 |
基类在 _get_rewards() 中直接委托 RewardManager.compute(dt=self.step_dt) 完成所有奖励项的聚合,开发者如需调整权重或增删项,只需在继承 RewardCfg 的配置类中重新声明 RewTerm 即可,无需改动环境代码。
Sources: mdp/rewards.py, base_env.py
终止条件与课程学习
_get_dones() 方法实现了三种终止判断的叠加:当配置的非足端躯体(如躯干、大腿)检测到接触力大于 1 N 时触发 terminated_buf;当机体俯仰/横滚角超过阈值或机体高度低于阈值时追加终止;最后当 episode_length_buf 达到 max_episode_length_s / step_dt 时触发 time_out_buf。reset_terminated 与 reset_time_outs 的区分对 PPO 的价值 bootstrap 计算至关重要。
地形课程学习通过 update_terrain_levels() 实现:每当环境重置时,若机器人当前位置与出生点的水平距离超过地形尺寸的一半,则提升该环境的地形难度;若距离过近则降级。该机制与 ROUGH_TERRAINS_CFG 中 curriculum=True 的设置联动,确保机器人只在熟练掌握当前难度后才面对更复杂地形。
Sources: base_env.py, base_env.py
三种环境变体对比
在 BaseEnv 之上,项目针对不同的研究目标提供了两个特化环境,它们共享相同的物理与奖励框架,仅在观测计算与动作干预层面进行扩展:
| 环境类 | 核心扩展 | 观测差异 | 典型用途 |
|---|---|---|---|
BaseEnv |
无 | 78-dim Actor / 139-dim Critic | 平坦/粗糙地形基础行走 |
AttnEncEnv |
高度图感知增强 | 追加 perception_a / perception_c 高度图分组;可选将 lin_vel 加入 Actor |
崎岖地形下的注意力编码器策略训练 |
InterruptEnv |
关节扰动注入 | Actor 观测追加 1-bit interrupt_mask |
提升策略对外部扰动与关节故障的鲁棒性 |
AttnEncEnv 通过重写 _get_observations() 将高度扫描结果以独立分组 "perception_a" 和 "perception_c" 的形式返回,这使得 RSL-RL Runner 可以将地形特征路由到注意力编码器模块,而非直接与本体观测拼接。InterruptEnv 则在 _pre_physics_step() 中对一定比例的环境注入随机关节偏移,同时在 Actor 观测中暴露一个二进制掩码,让策略显式感知到当前是否存在干预,从而学习对抗性鲁棒策略。
Sources: attn_enc_env.py, interrupt_env.py
Agent 配置与对称性增强
每个环境变体都配有对应的 Agent 配置类(如 ATOM01FlatAgentCfg、ATOM01AttnEncAgentCfg),它们继承自 BaseAgentCfg 并覆盖 PPO 超参数与网络结构。基类中已经预设了标准的 Actor-Critic 网络维度 [512, 256, 128]、激活函数 elu、学习率 1e-4 以及自适应 KL 调度策略。
特别值得注意的是,Agent 配置文件中包含大量镜像对称性函数,用于实现左右肢体观测与动作的镜像数据增强。这些函数通过预计算的索引置换与符号翻转,在训练时将一个 batch 的数据翻倍(原数据 + 镜像数据),从而隐式注入双足机器人的左右对称先验。对于 AttnEncEnv,镜像函数还扩展到了高度图观测 perception_a 与 perception_c,确保地形感知特征在左右翻转时保持几何一致性。
Sources: atom01_agent_cfg.py, atom01_attn_enc_agent_cfg.py
下一步阅读
理解 Direct RL 环境架构后,建议你按以下路径深入:
- 若需对比 Manager-based 的模块化设计范式,请阅读 Manager-based 环境架构。
- 若要修改地形难度或添加新的子地形类型,请参考 地形生成与场景配置。
- 若要设计新的奖励项或调整权重组合,请阅读 奖励函数与 MDP 设计。
- 若准备将
AttnEncEnv中的高度图接入注意力网络,请阅读 注意力编码器感知机制。