第二章、Isaaclab强化学习包装器(1)
0 前言
官方文档:https://isaac-sim.github.io/IsaacLab/main/source/api/lab_rl/isaaclab_rl.html#module-isaaclab_rl.rl_games
第十二讲、Isaaclab中使用RL对智能体进行训练
本节将详细介绍RL-Games Wrapper包装器。
运行该程序:
- 进入安装 isaac lab 时创建的conda虚拟环境
- 在该环境下进入 isaac sim文件夹中运行
source setup_conda_env.sh
- 终端中输入
./isaaclab.sh -p scripts/reinforcement_learning/rl_games/train.py --task=Isaac-Cartpole-Direct-v0
运行你的代码,进行训练。
1 gym注册环境
import gymnasium as gym # 导入Gymnasium库# 在Gymnasium中注册名为"Isaac-Cartpole-Direct-v0"的自定义环境
gym.register(# 环境ID:唯一标识符,遵循Gym命名规范(通常包含版本号v0)id="Isaac-Cartpole-Direct-v0",# entry_point:指定环境类的入口位置# f"{__name__} 表示当前模块(文件),cartpole_env是模块内的类定义文件entry_point=f"{__name__}.cartpole_env:CartpoleEnv", # 禁用Gym内置的环境检查器(适用于特殊环境或加速初始化)disable_env_checker=True, # 传递给环境构造函数的额外参数(字典形式)kwargs={# 环境配置类的导入路径(指向CartpoleEnvCfg类)"env_cfg_entry_point": f"{__name__}.cartpole_env:CartpoleEnvCfg",# RL Games库的PPO算法配置文件路径(YAML格式)# agents是包含配置文件的子模块,rl_games_ppo_cfg.yaml是配置文件"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml",# RSL-RL库的PPO算法配置类路径# rsl_rl_ppo_cfg是模块,CartpolePPORunnerCfg是配置类"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:CartpolePPORunnerCfg",# SKRL库的PPO算法配置文件路径(YAML格式)"skrl_cfg_entry_point": f"{agents.__name__}:skrl_ppo_cfg.yaml",# Stable Baselines3库的PPO算法配置文件路径"sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml",},
)
2 RL-Games Wrapper包装器
# rl_games.common:rl-games 框架的核心模块,提供环境配置(env_configurations)和向量化环境(vecenv)的支持。
from rl_games.common import env_configurations, vecenv
# RlGamesGpuEnv 和 RlGamesVecEnvWrapper:自定义的 Isaac Lab 环境适配器,
# 用于将 Isaac Lab 的物理仿真环境封装成 rl-games 兼容的格式,并支持 GPU 加速。
from isaaclab_rl.rl_games import RlGamesGpuEnv, RlGamesVecEnvWrapper
from rl_games.torch_runner import Runner# 配置参数
rl_device = "cuda:0" # 指定强化学习训练使用的设备(GPU)
clip_obs = 10.0 # 观察值的裁剪范围(-10.0 到 10.0)
clip_actions = 1.0 # 动作值的裁剪范围(-1.0 到 1.0)# 环境包装
env = RlGamesVecEnvWrapper(env, rl_device, clip_obs, clip_actions)
# 作用:将原始的 Isaac Lab 环境 env 封装为 rl-games 兼容的向量化环境,并实现以下功能:
# 1 设备分配: 将环境数据(观测、动作)移动到 rl_device 指定的设备(如 GPU)。
# 2 数值裁剪: 根据 clip_obs 和 clip_actions 对观测和动作进行截断。
# 3 接口适配: 将 Isaac Lab 的 API 转换为 rl-games 的 VecEnv 接口(例如 step(), reset() 方法)。# 注册环境到 rl-games
# note: in agents configuration: environment name must be "rlgpu"
vecenv.register("IsaacRlgWrapper", lambda config_name, num_actors, **kwargs: RlGamesGpuEnv(config_name, num_actors, **kwargs)
)
# vecenv.register:向 rl-games 注册一个名为 "IsaacRlgWrapper" 的向量化环境工厂函数。
# 当配置文件中指定环境类型为 "IsaacRlgWrapper" 时,rl-games 会调用此函数创建环境。
# RlGamesGpuEnv:实际创建环境的类,负责管理多智能体(num_actors 指定并行环境数量)和 GPU 数据交互#关联环境配置
env_configurations.register("rlgpu", {"vecenv_type": "IsaacRlgWrapper", "env_creator": lambda **kwargs: env})
# env_configurations.register:将环境名称 "rlgpu" 绑定到具体的环境配置:
# 1 vecenv_type: 使用之前注册的 "IsaacRlgWrapper" 向量化环境类型。
# 2 env_creator: 环境创建函数直接返回已包装好的 env 对象。# 创建 Runner 并启动训练
# 初始化 Runner
runner = Runner()
runner.load("config.yaml") # 加载配置文件
# 启动训练
runner.reset()
我们以/IsaacLab/scripts/reinforcement_learning/rl_games/train.py
为例来看
# 配置参数
rl_device = agent_cfg["params"]["config"]["device"] # 指定强化学习训练使用的设备(GPU)
clip_obs = agent_cfg["params"]["env"].get("clip_observations", math.inf) # 观察值的裁剪范围
clip_actions = agent_cfg["params"]["env"].get("clip_actions", math.inf) # 动作值的裁剪范围
# 创建isaaclab的env环境
env = gym.make(args_cli.task, cfg=env_cfg, render_mode="rgb_array" if args_cli.video else None)
# 环境包装
env = RlGamesVecEnvWrapper(env, rl_device, clip_obs, clip_actions)
# 注册环境到 rl-games
vecenv.register("IsaacRlgWrapper", lambda config_name, num_actors, **kwargs: RlGamesGpuEnv(config_name, num_actors, **kwargs))
#关联环境配置
env_configurations.register("rlgpu", {"vecenv_type": "IsaacRlgWrapper", "env_creator": lambda **kwargs: env})
# 创建 Runner 并启动训练
runner = Runner(IsaacAlgoObserver())
runner.load(agent_cfg)
3 参数yaml文件
运行该程序:
- 进入安装 isaac lab 时创建的conda虚拟环境
- 在该环境下进入 isaac sim文件夹中运行
source setup_conda_env.sh
- 终端中输入
./isaaclab.sh -p scripts/reinforcement_learning/rl_games/train.py --task=Isaac-Cartpole-Direct-v0
运行你的代码,训练模型。
将在/IsaacLab/scripts/reinforcement_learning/rl_games/logs/rl_games/cartpole_direct/你的训练时间/params
文件夹下生成配置文件,我们主要关注agent.yaml
文件。
在1 gym注册环境
中有以行是"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml",
,我们关注/IsaacLab/source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/agents/rl_games_ppo_cfg.yaml
文件,我们会发现上述两个文件内容一样。
params:seed: 42 # 随机种子,确保实验可重复性# 环境包装器参数env:clip_observations: 5.0 # 观测值裁剪范围(-5.0到5.0),防止数值过大clip_actions: 1.0 # 动作值裁剪范围(-1.0到1.0),适配执行器限制# 算法配置algo:name: a2c_continuous # 使用连续动作空间的A2C算法(Advantage Actor-Critic)# 模型定义model:name: continuous_a2c_logstd # 带对数标准差输出的连续动作A2C模型# 神经网络架构配置network:name: actor_critic # 网络类型:Actor-Critic结构separate: False # 策略网络和价值网络是否共享底层参数(False表示共享)space:continuous: # 连续动作空间配置mu_activation: None # 策略网络均值输出的激活函数(None表示线性输出)sigma_activation: None # 策略网络标准差输出的激活函数mu_init: # 均值权重初始化方法name: default # 默认初始化(如Xavier/Glorot)sigma_init: # 标准差权重初始化name: const_initializer # 常数初始化val: 0 # 标准差初始值为0(需配合fixed_sigma=True)fixed_sigma: True # 固定标准差(不学习,常用于确定性策略)mlp: # MLP全连接层配置units: [32, 32] # 隐藏层神经元数量(2层,每层32个)activation: elu # 激活函数为ELU(Exponential Linear Unit)d2rl: False # 是否使用D2RL架构(深度堆叠MLP)initializer: # 权重初始化name: default # 默认初始化regularizer: # 正则化name: None # 无正则化load_checkpoint: False # 是否加载预训练模型load_path: '' # 预训练模型路径# 训练过程核心配置config:name: cartpole_direct # 实验名称(自定义标识)env_name: rlgpu # 环境名称(需与注册的名称一致)device: 'cuda:0' # 训练设备(GPU 0)device_name: 'cuda:0' # 同device,冗余参数multi_gpu: False # 禁用多GPU训练ppo: True # 是否启用PPO优化(与A2C混合配置可能存在问题)mixed_precision: False # 禁用混合精度训练normalize_input: True # 标准化观测输入(零均值单位方差)normalize_value: True # 标准化价值函数目标num_actors: -1 # 并行环境数量(-1表示从脚本获取)reward_shaper:scale_value: 0.1 # 奖励缩放因子(缩小奖励值范围)normalize_advantage: True # 标准化优势函数gamma: 0.99 # 折扣因子(长期回报衰减率)tau : 0.95 # GAE(Generalized Advantage Estimation)衰减因子learning_rate: 5e-4 # 初始学习率lr_schedule: adaptive # 学习率调整策略(自适应调整)kl_threshold: 0.008 # KL散度阈值(用于PPO,触发早停)score_to_win: 20000 # 训练目标得分(停止条件)max_epochs: 150 # 最大训练周期数save_best_after: 50 # 50个epoch后开始保存最佳模型save_frequency: 25 # 每25个epoch保存一次grad_norm: 1.0 # 梯度裁剪阈值(防止梯度爆炸)entropy_coef: 0.0 # 熵奖励系数(鼓励探索,0表示禁用)truncate_grads: True # 梯度截断(与grad_norm配合)e_clip: 0.2 # PPO的策略更新剪切范围(重要性采样剪切)horizon_length: 32 # 每个环境的步数(PPO中的时间步长度)minibatch_size: 32 # 小批量大小(每次梯度更新的样本数)mini_epochs: 8 # 每个大epoch中的小epoch数(PPO参数)critic_coef: 4 # 价值函数损失权重(平衡策略和价值损失)clip_value: True # 是否剪切价值函数更新(PPO特性)seq_length: 4 # RNN序列长度(非RNN模型可忽略)bounds_loss_coef: 0.0001 # 动作边界约束损失系数(防止动作越界)
更具体的内容可以参考:https://github.com/Denys88/rl_games