官方教程:https://isaac-sim.github.io/IsaacLab/main/source/tutorials/03_envs/create_manager_rl_env.html
Isaacsim+Isaaclab安装:https://blog.csdn.net/m0_47719040/article/details/146389391?spm=1001.2014.3001.5502
在Isaaclab中基于管理器的环境被分为两个类来实现,一下是两类区别
类名 | 适用场景 | 核心功能差异 | 典型用途示例 |
---|---|---|---|
envs.ManagerBasedEnv |
传统机器人控制 | 不包含奖励机制和终止条件 | 机械臂轨迹跟踪、无人机定点控制 |
envs.ManagerBasedRLEnv |
强化学习任务 | 包含奖励计算、终止判断、课程学习系统 | DRL算法训练、自适应控制策略开发 |
上一节中我们介绍了envs.ManagerBasedEnv
类及其对应的envs.ManagerBasedEnvCfg
配置类。本节将介绍envs.ManagerBasedRLEnv
类及envs.ManagerBasedRLEnvCfg
配置类。我们将使用之前的 cartpole
环境来介绍创建envs.ManagerBasedRLEnv
新环境时使用的不同组件。
教程对应的脚本为run_cartpole_rl_env.py
在scripts/tutorials/03_envs
目录下。
对应的类CartpoleEnvCfg
在/IsaacLab/source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/cartpole/cartpole_env_cfg.py
运行该程序:
source setup_conda_env.sh
python scripts/tutorials/03_envs/run_cartpole_rl_env.py --num_envs 32
运行你的代码。注:第八讲、Isaaclab创建基于管理器的基础环境 教程中学习了上述部分内容,了解如何指定场景、观察、动作和事件。因此,在本教程中,我们将仅关注环境中的强化学习组件。
注意这部分代码在/IsaacLab/source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/cartpole/cartpole_env_cfg.py
中。
奖励管理器(RewardManager):奖励管理器负责计算智能体在每个时间步的总奖励,通过组合多个奖励项(Reward Term)实现。每个奖励项对应一个特定的行为目标(如保持平衡、避免移动过快),其权重和计算方式通过 RewardTermCfg 配置。
总奖励公式为:
R t o t a l = ∑ i ( w i ⋅ R i ) R_{total}=\sum_{i}(w_{i}\cdot R_{i}) Rtotal=∑i(wi⋅Ri)
其中:
R i R_i Ri 为第 i i i 个奖励项的值。
w i w_i wi 为对应奖励项的权重,控制其对总奖励的影响程度。
@configclass
# Cartpole 的奖励项配置
class RewardsCfg:
"""Reward terms for the MDP."""
# 存活奖励(Alive Reward):鼓励智能体尽可能延长存活时间(避免 episode 终止)。
# 使用预定义函数 is_alive,该函数返回布尔值张量(True 表示环境未终止)。
# weight=1.0:每个存活步奖励 1.0 * 1.0 = 1.0,直接累加到总奖励中。
alive = RewTerm(func=mdp.is_alive, weight=1.0)
# 终止惩罚(Terminating Penalty):强化终止条件的负面效果,防止智能体主动触发终止(如故意让杆子倒下)。
# 返回布尔值张量(True 表示环境因失败终止)。
# weight=-2.0:终止时惩罚 1.0 * (-2.0) = -2.0。
terminating = RewTerm(func=mdp.is_terminated, weight=-2.0)
# 杆角度惩罚(Pole Angle Penalty):鼓励杆子保持直立(角度接近 0)
# func=mdp.joint_pos_target_l2:计算杆关节(cart_to_pole)当前位置与目标位置(target=0.0,即直立状态)的 L2 距离(平方误差)。
# weight=-1.0:角度偏离越大,惩罚越强(L2误差 * (-1.0))
pole_pos = RewTerm(
func=mdp.joint_pos_target_l2,
weight=-1.0,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=["cart_to_pole"]), "target": 0.0},
)
# 推车速度惩罚(Cart Velocity Penalty):抑制推车不必要的快速移动,鼓励稳定在轨道中心。
# func=mdp.joint_vel_l1:计算推车关节(slider_to_cart)速度的 L1 范数(绝对值之和)。
# weight=-0.01:速度越快,惩罚越强(绝对速度 * (-0.01))
# asset_cfg=SceneEntityCfg("robot", joint_names=["slider_to_cart"]):定位到 robot 资产中名为 slider_to_cart 的关节(推车的滑动关节)。
cart_vel = RewTerm(
func=mdp.joint_vel_l1,
weight=-0.01,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=["slider_to_cart"])},
)
# 杆角速度惩罚(Pole Angular Velocity Penalty):减少杆子的摆动速度,辅助主任务(保持直立)的稳定性。
# func=mdp.joint_vel_l1:计算杆关节(cart_to_pole)角速度的 L1 范数(绝对值)。
# weight=-0.005:角速度越快,惩罚越强(绝对角速度 * (-0.005))。
# asset_cfg=SceneEntityCfg("robot", joint_names=["cart_to_pole"]):定位到杆的旋转关节。
pole_vel = RewTerm(
func=mdp.joint_vel_l1,
weight=-0.005,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=["cart_to_pole"])},
)
总奖励:
R t o t a l = 1.0 ⋅ R a l i v e + ( − 2.0 ) ⋅ R t e r m i n a t i n g + ( − 1.0 ) ⋅ R p o l e p o s + ( − 0.01 ) ⋅ R c a r t _ v e l + ( − 0.005 ) ⋅ R p o l e _ v e l R_{total}=1.0⋅R_{alive}+(−2.0)⋅R_{terminating}+(−1.0)⋅R_{pole_pos}+(−0.01)⋅R_{cart\_vel}+(−0.005)⋅R_{pole\_vel} Rtotal=1.0⋅Ralive+(−2.0)⋅Rterminating+(−1.0)⋅Rpolepos+(−0.01)⋅Rcart_vel+(−0.005)⋅Rpole_vel
大多数学习任务都包含有限数量的步骤,一般称为(episode)。
例如,在推杆任务中,我们希望代理尽可能长时间地保持杆子平衡。但是,如果智能体达到不稳定或不安全的状态,我们希望终止该episode(实际上是一堆(state、obs、action、reward)组成的序列,具体看强化学习)。另一方面,如果智能体能够长时间保持杆子平衡,我们希望终止该episode并开始新的episode,以便代理能够从不同的起始配置(可以理解为实际上每次reset的时候会随机初始化对象)学习平衡杆子。
本节中对于managers.TerminationsCfg
的配置,希望在满足以下任一条件时终止任务:
1、当episode的长度超过max_episode_length
时终止,避免某一个杆子一直朝着错误的方向无限学习。
2、Cart(即滑块)超出某一个范围([-3, 3])时停止。
@configclass
class TerminationsCfg:
"""Termination terms for the MDP."""
# (1) episode长度终止条件
time_out = DoneTerm(func=mdp.time_out, time_out=True)
# (2) Cart超出范围终止条件
cart_out_of_bounds = DoneTerm(
func=mdp.joint_pos_out_of_manual_limit,
params={"asset_cfg": SceneEntityCfg("robot", joint_names=["slider_to_cart"]), "bounds": (-3.0, 3.0)},
)
除了上述内容之外,Isaaclab中还可以通过指令管理器(Command Manager)和课程管理器(Curriculum Manager)来定义命令和课程。
指令管理器(Command Manager)
由于Cartpole 的任务是固定的(保持杆子直立),无需动态目标,因此直接通过观察管理器提供状态反馈即可。
课程管理器(Curriculum Manager)
课程学习是一种模仿人类学习过程的训练策略,通过逐步增加任务难度,帮助智能体(AI代理)更高效地学习复杂技能。
Cartpole 的任务本身较为简单(平衡杆子),无需渐进式难度调整。直接通过固定随机化(如初始角度扰动)即可训练出稳定策略。
和上一节中一样将上述所有配置组合到环境配置中,方便后续的实例化。
@configclass
class CartpoleEnvCfg(ManagerBasedRLEnvCfg):
"""Configuration for the cartpole environment."""
# 场景配置
scene: CartpoleSceneCfg = CartpoleSceneCfg(num_envs=4096, env_spacing=4.0)
# 观测配置
observations: ObservationsCfg = ObservationsCfg()
# 动作配置
actions: ActionsCfg = ActionsCfg()
# 事件配置
events: EventCfg = EventCfg()
# 奖励配置
rewards: RewardsCfg = RewardsCfg()
# 终止条件配置
terminations: TerminationsCfg = TerminationsCfg()
# 仿真参数配置
def __post_init__(self) -> None:
"""Post initialization."""
# 步进配置
self.decimation = 2
# episode长度配置
self.episode_length_s = 5
# 查看器设置
self.viewer.eye = (8.0, 0.0, 5.0)
# 仿真参数配置
self.sim.dt = 1 / 120
self.sim.render_interval = self.decimation
对于ManagerBasedRLEnv官方文档做了更详细的说明,传送门放在下方:
https://isaac-sim.github.io/IsaacLab/main/source/api/lab/isaaclab.envs.html#isaaclab.envs.ManagerBasedRLEnv
def main():
"""Main function."""
# 解析命令行参数,整合环境配置
env_cfg = CartpoleEnvCfg()
env_cfg.scene.num_envs = args_cli.num_envs
# 根据环境配置初始化环境(实例化)
env = ManagerBasedRLEnv(cfg=env_cfg)
# 仿真循环
count = 0
while simulation_app.is_running():# 检查仿真应用是否在运行(如 Isaac Sim 窗口未关闭)
with torch.inference_mode():# 禁用梯度计算,提升性能
# 定期重置环境
if count % 300 == 0:
count = 0
env.reset()# 重置所有并行环境,实际上就是EventCfg中指定好的内容
print("-" * 80)
print("[INFO]: Resetting environment...")
# 生成随机动作
joint_efforts = torch.randn_like(env.action_manager.action)
# 执行环境步进
obs, rew, terminated, truncated, info = env.step(joint_efforts)
# 打印第一个环境的杆关节观察值
print("[Env 0]: Pole joint: ", obs["policy"][0][1].item())
# 更新计数器
count += 1
# 关闭环境释放资源
env.close()