第九讲、Issalab中基于管理器创建RL环境

0 前言

官方教程: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.pyscripts/tutorials/03_envs目录下。
对应的类CartpoleEnvCfg/IsaacLab/source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/cartpole/cartpole_env_cfg.py

运行该程序:

  • 进入安装 isaac lab 时创建的conda虚拟环境
  • 在该环境下进入 isaac sim文件夹中运行source setup_conda_env.sh
  • 终端中输入python scripts/tutorials/03_envs/run_cartpole_rl_env.py --num_envs 32运行你的代码。

第九讲、Issalab中基于管理器创建RL环境_第1张图片注:第八讲、Isaaclab创建基于管理器的基础环境 教程中学习了上述部分内容,了解如何指定场景、观察、动作和事件。因此,在本教程中,我们将仅关注环境中的强化学习组件。

1 定义奖励

注意这部分代码在/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(wiRi)
其中:
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.0Ralive+(2.0)Rterminating+(1.0)Rpolepos+(0.01)Rcart_vel+(0.005)Rpole_vel

2 定义终止条件

大多数学习任务都包含有限数量的步骤,一般称为(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)},
    )

3 定义命令、定义课程学习

除了上述内容之外,Isaaclab中还可以通过指令管理器(Command Manager)和课程管理器(Curriculum Manager)来定义命令和课程。

指令管理器(Command Manager)

  • 目标导向任务支持:
    在需要智能体达成动态目标的场景中(如移动到指定位置、抓取移动物体),指令管理器负责生成、更新和跟踪这些目标(指令)。
  • 指令类型示例:
    移动目标:目标坐标、方向。
    速度指令:期望的移动速度。
    任务参数:抓取物体的目标尺寸或重量。

由于Cartpole 的任务是固定的(保持杆子直立),无需动态目标,因此直接通过观察管理器提供状态反馈即可。

课程管理器(Curriculum Manager)
课程学习是一种模仿人类学习过程的训练策略,通过逐步增加任务难度,帮助智能体(AI代理)更高效地学习复杂技能。

  • 渐进式学习:通过逐步增加任务难度,帮助智能体从简单子任务过渡到复杂场景。
  • 动态参数调整:根据训练进度(如平均奖励、成功率)自动修改环境参数,例如:
    • 增大物体质量随机范围。
    • 缩小目标容差(要求更精准)。
    • 增加干扰力或障碍物数量。

Cartpole 的任务本身较为简单(平衡杆子),无需渐进式难度调整。直接通过固定随机化(如初始角度扰动)即可训练出稳定策略。

4 把所有东西联系起来

和上一节中一样将上述所有配置组合到环境配置中,方便后续的实例化。

@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

5 运行模拟

对于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()

你可能感兴趣的:(Isaaclab-17讲,python,linux,人工智能,机器人,ubuntu)