IsaacLab框架分析
- 强化学习基本框架
- OnPolicyAlgorithm类
- PPO
- OnPolicyAlgorithm类
- 基本工作流
- 创建空场景
- 添加prim到场景中
- 与物体交互
- 与刚体交互
- 与关节交互
- 与可变形物体交互
- 场景创建
- scene.InteractiveScene类
- 环境创建
- Manager-Based RL Environment
- Direct Workflow RL Environment
- 环境注册
- 训练
- 调试
- 添加传感器
- 使用任务空间控制器控制机器人
强化学习基本框架
OnPolicyAlgorithm类
OnPolicyAlgorithm
类,是稳定基线3 (Stable Baselines3) 中所有策略梯度 (On-Policy) 强化学习算法的基类,例如 A2C 和 PPO。
主要功能:
-
初始化和设置:
- 初始化算法的参数,包括策略网络、环境、学习率、折扣因子、GAE 参数、熵系数等。
- 设置学习率计划、随机种子。
- 根据观测空间类型选择合适的 rollout buffer (经验回放缓冲区)。
- 创建 rollout buffer 和策略网络,并将策略网络移动到指定的设备 (CPU 或 GPU)。
-
收集经验 (collect_rollouts):
- 使用当前策略与环境交互,收集经验数据并存储到 rollout buffer 中。
- 在收集经验的过程中,会调用回调函数进行一些操作,例如记录日志、保存模型等。
- 处理超时 (timeout) 情况,使用值函数进行 bootstrapping。
- 计算回报 (returns) 和优势 (advantage) 函数。
-
训练 (train):
- 这个方法是一个抽象方法,具体的训练逻辑由子类实现,例如 A2C 和 PPO。
- 子类需要根据 rollout buffer 中的经验数据更新策略网络的参数。
-
记录日志 (_dump_logs):
- 记录训练过程中的信息,例如迭代次数、奖励、episode 长度、成功率等。
-
学习 (learn):
- 这是算法的主循环,它会不断地收集经验和训练策略网络,直到达到指定的训练步数。
- 在训练过程中,会定期调用回调函数和记录日志。
关键概念:
- 策略梯度 (On-Policy): 这类算法直接学习策略,并根据当前策略收集的经验数据进行更新。
- Rollout Buffer: 存储经验数据的缓冲区,包括状态、动作、奖励、是否结束等信息。
- GAE (Generalized Advantage Estimation): 一种计算优势函数的方法,可以平衡偏差和方差。
- 熵系数 (Entropy Coefficient): 鼓励策略探索环境,避免过早收敛到次优解。
- 值函数系数 (Value Function Coefficient): 控制值函数损失的权重。
代码结构:
OnPolicyAlgorithm
继承自BaseAlgorithm
,BaseAlgorithm
提供了一些通用的功能,例如设置环境、策略、学习率等。OnPolicyAlgorithm
定义了一些抽象方法,例如train
,由子类实现具体的训练逻辑。OnPolicyAlgorithm
提供了一些辅助方法,例如collect_rollouts
、_dump_logs
、learn
等。
总结:
OnPolicyAlgorithm
是 Stable Baselines3 中策略梯度算法的基类,它定义了策略梯度算法的基本框架,包括初始化、收集经验、训练、记录日志等功能。具体的训练逻辑由子类实现,例如 A2C 和 PPO。 通过继承 OnPolicyAlgorithm
,可以方便地开发新的策略梯度算法。
PPO
PPO
类,是稳定基线3 (Stable Baselines3) 中实现的近端策略优化 (Proximal Policy Optimization) 算法。PPO 是一种常用的策略梯度强化学习算法,它在 A2C 的基础上进行了改进,通过引入 clipped surrogate objective 和 KL 惩罚项来提高训练的稳定性和效率。
主要功能:
-
初始化和设置:
- 初始化算法的参数,包括策略网络、环境、学习率、折扣因子、GAE 参数、clip range 等。
- 检查参数的有效性,例如
batch_size
是否大于 1,rollout buffer 的大小是否合适等。 - 设置学习率计划、clip range 计划。
-
训练 (train):
- 将策略网络设置为训练模式。
- 更新优化器的学习率。
- 计算当前的 clip range。
- 进行
n_epochs
轮训练,每轮训练都遍历一遍 rollout buffer 中的数据。 - 对于每个 minibatch 的数据,计算价值函数、动作的对数概率、熵、优势函数、比率等。
- 计算 clipped surrogate loss、价值函数损失、熵损失。
- 计算近似 KL 散度,用于提前停止训练。
- 进行梯度下降更新策略网络的参数。
- 记录训练过程中的信息,例如损失函数、KL 散度、clip fraction 等。
关键概念:
- Clipped Surrogate Objective: PPO 使用 clipped surrogate objective 来限制策略更新的幅度,防止策略更新过度偏离之前的策略。
- KL 惩罚项: PPO 可以选择使用 KL 惩罚项来限制策略更新的幅度,防止策略更新过度偏离之前的策略。
- Advantage Normalization: PPO 通常会对优势函数进行归一化,以提高训练的稳定性。
- Entropy Bonus: PPO 可以选择使用熵奖励来鼓励策略探索环境,避免过早收敛到次优解。
代码结构:
PPO
继承自OnPolicyAlgorithm
,OnPolicyAlgorithm
是策略梯度算法的基类。PPO
实现了train
方法,定义了 PPO 算法的训练逻辑。PPO
使用了RolloutBuffer
来存储经验数据。PPO
使用了ActorCriticPolicy
作为策略网络。
总结:
PPO
是 Stable Baselines3 中实现的近端策略优化算法,它是一种常用的策略梯度强化学习算法。PPO 通过引入 clipped surrogate objective 和 KL 惩罚项来提高训练的稳定性和效率。PPO
类实现了 PPO 算法的训练逻辑,并提供了一些辅助方法,例如 learn
等。
基本工作流
创建空场景
https://isaac-sim.github.io/IsaacLab/source/tutorials/00_sim/create_empty.html
这段代码演示了如何使用 Python 脚本在 Isaac Sim 中创建一个简单的空场景。它涵盖了启动模拟器、配置模拟上下文、运行模拟以及退出模拟等步骤。
代码解析:
-
导入必要的库:
argparse
: 用于解析命令行参数。omni.isaac.lab.app
: 用于启动 Isaac Sim 应用程序。omni.isaac.lab.sim
: 用于配置和控制模拟器。
-
解析命令行参数:
- 使用
argparse
创建一个参数解析器。 - 使用
AppLauncher.add_app_launcher_args
将 Isaac Sim 启动器的命令行参数添加到解析器中。 - 解析命令行参数,并将结果存储在
args_cli
中。
- 使用
-
启动 Isaac Sim 应用程序:
- 使用
AppLauncher
类启动 Isaac Sim 应用程序,并将解析的命令行参数传递给它。 - 将应用程序对象存储在
simulation_app
中。
- 使用
-
配置模拟上下文:
- 使用
SimulationCfg
类创建一个模拟配置对象sim_cfg
,设置模拟步长dt
为 0.01 秒。 - 使用
SimulationContext
类创建一个模拟上下文对象sim
,并将配置对象sim_cfg
传递给它。 - 使用
sim.set_camera_view
设置主摄像机的视角,其中第一个列表指定相机位置,第二个列表指定相机目标点。
- 使用
-
运行模拟:
- 使用
sim.reset
方法重置模拟器,这会初始化物理引擎并开始模拟。 - 使用
while
循环不断执行模拟步骤,直到 Isaac Sim 应用程序停止运行 (simulation_app.is_running()
返回 False)。 - 在循环中,使用
sim.step
方法执行单个模拟步骤。
- 使用
-
关闭模拟器应用程序:
- 在模拟循环结束后,使用
simulation_app.close
方法关闭 Isaac Sim 应用程序。
- 在模拟循环结束后,使用
关键概念:
- 模拟器 (Simulator): 一个用于模拟物理世界行为的软件环境。Isaac Sim 就是一个用于机器人仿真的模拟器。
- 场景 (Scene): 模拟器中的一个虚拟环境,包含各种对象和属性。
- 模拟上下文 (Simulation Context): 用于控制模拟器行为的对象,例如启动、停止、重置和单步执行模拟。
- 模拟配置 (Simulation Configuration): 用于配置模拟器参数的对象,例如模拟步长、物理引擎参数等。
- 模拟步长 (Simulation Time Step): 模拟器执行单个步骤的时间间隔。
代码总结:
这段代码展示了如何使用 Python 脚本在 Isaac Sim 中创建一个简单的空场景,并运行模拟。它涵盖了以下步骤:
- 启动 Isaac Sim 应用程序。
- 创建一个模拟上下文对象,并配置模拟参数。
- 重置模拟器并启动模拟循环。
- 不断执行模拟步骤,直到模拟器停止运行。
- 关闭模拟器应用程序。
添加prim到场景中
代码核心目标:
这段代码的目标是在 Isaac Sim 模拟器中创建一个包含各种元素的 3D 场景,包括地面、灯光、基本几何形状和从 USD 文件加载的网格模型(例如桌子)。
代码实现步骤:
-
初始化 Isaac Sim 应用程序:
- 使用
argparse
解析命令行参数,获取启动 Isaac Sim 应用程序所需的参数。 - 使用
AppLauncher
类启动 Isaac Sim 应用程序。
- 使用
-
设计场景 (design_scene 函数):
- 生成地面:
- 使用
sim_utils.GroundPlaneCfg()
创建一个地面配置对象cfg_ground
。 - 使用
cfg_ground.func()
函数将地面生成到场景中,路径为 "/World/defaultGroundPlane"。
- 使用
- 生成灯光:
- 使用
sim_utils.DistantLightCfg()
创建一个远光灯配置对象cfg_light_distant
,设置光照强度和颜色。 - 使用
cfg_light_distant.func()
函数将远光灯生成到场景中,路径为 "/World/lightDistant",并设置其位置。
- 使用
- 创建 Xform Prim:
- 使用
prim_utils.create_prim()
创建一个名为 "/World/Objects" 的 Xform Prim,用于组织场景中的对象。Xform Prim 用于对场景中的对象进行分组和变换。
- 使用
- 生成基本形状:
- 使用
sim_utils.ConeCfg()
创建一个圆锥体配置对象cfg_cone
,设置半径、高度和颜色。 - 使用
cfg_cone.func()
函数将两个圆锥体Cone1
和Cone2
生成到场景中,并设置其位置。 - 使用
sim_utils.ConeCfg()
创建另一个圆锥体配置对象cfg_cone_rigid
,设置半径、高度、颜色,并添加刚体物理属性(质量、碰撞属性等)。 - 使用
cfg_cone_rigid.func()
函数将圆锥体ConeRigid
生成到场景中,并设置其位置和方向。 - 使用
sim_utils.MeshCuboidCfg()
创建一个长方体配置对象cfg_cuboid_deformable
,设置尺寸、颜色,并添加可变形体物理属性。 - 使用
cfg_cuboid_deformable.func()
函数将长方体CuboidDeformable
生成到场景中,并设置其位置。
- 使用
- 从 USD 文件生成:
- 使用
sim_utils.UsdFileCfg()
创建一个 USD 文件配置对象cfg
,指定 USD 文件路径 (SeattleLabTable)。 - 使用
cfg.func()
函数将桌子模型生成到场景中,路径为 "/World/Objects/Table",并设置其位置。桌子模型以引用的方式添加到场景中,这意味着对桌子模型的修改会反映到场景中,而无需直接修改 USD 文件。
- 使用
- 生成地面:
-
主函数 (main 函数):
- 初始化模拟上下文,设置模拟步长。
- 设置主摄像机视角。
- 调用
design_scene()
函数设计场景。 - 重置模拟器并开始模拟。
- 在循环中执行模拟步骤,直到模拟器停止运行。
-
程序入口:
if __name__ == "__main__":
语句确保只有当脚本作为主程序运行时才会执行main()
函数。- 最后,关闭 Isaac Sim 应用程序。
关键概念:
- USD (Universal Scene Description): 一种用于描述 3D 场景的软件系统和文件格式。
- Prim (Primitive): USD 场景的基本构建块,可以是网格、灯光、相机、变换或其他 Prim 的组。
- 属性 (Attribute): Prim 的属性,例如颜色、大小等。
- 关系 (Relationship): Prim 之间的连接,例如网格 Prim 与材质 Prim 之间的关系。
- 阶段 (Stage): USD 场景的容器,包含所有 Prim、属性和关系。
- Xform (Transform Prim): 仅包含变换属性的 Prim,用于对其他 Prim 进行分组和变换。
- 刚体 (Rigid Body): 在模拟中不会发生形变的物体。
- 可变形体 (Deformable Body): 可以发生形变的物体,例如布料、橡胶等。
- 引用 (Reference): 将外部文件以引用的方式添加到场景中,以便在不修改原始文件的情况下进行修改。
- Isaac Nucleus: Isaac Sim 的资源库,包含各种预先构建好的 USD 模型,例如机器人、家具、环境等。
总结:
这段代码演示了如何在 Isaac Sim 中使用 Python 生成各种 Prim 到场景中,包括地面、灯光、基本形状和网格。它还介绍了 USD 的基本概念,以及如何使用 Isaac Lab 提供的配置驱动接口来简化场景设计过程。通过学习这段代码,可以掌握在 Isaac Sim 中进行场景设计的基本方法,并将其应用到更复杂的仿真任务中。
与物体交互
与刚体交互
这段代码演示了如何在 Isaac Sim 中创建刚体并与其交互。它涵盖了场景设计、模拟循环的运行,以及与刚体交互的具体方法。
代码结构:
-
导入必要的库:
argparse
用于处理命令行参数。torch
用于张量计算。omni.isaac.core.utils.prims
用于创建场景元素。omni.isaac.lab.sim
用于与 Isaac Sim 进行交互。omni.isaac.lab.utils.math
用于数学计算,例如采样圆柱体上的随机位置。omni.isaac.lab.assets
用于加载刚体模型。omni.isaac.lab.sim
用于模拟上下文。
-
解析命令行参数:
- 使用
argparse
解析命令行参数,这些参数用于启动 Isaac Sim 应用程序。
- 使用
-
启动 Isaac Sim 应用程序:
- 使用
AppLauncher
类启动 Isaac Sim 应用程序。
- 使用
-
设计场景 (design_scene 函数):
- 创建地面平面和灯光。
- 创建四个名为 "Origin1"、"Origin2"、"Origin3" 和 "Origin4" 的坐标系,用于放置刚体。
- 使用
RigidObjectCfg
配置刚体,包括:prim_path
:刚体在场景中的路径,使用正则表达式/World/Origin.*/Cone
表示在每个 Origin 坐标系下创建一个名为 Cone 的刚体。spawn
:刚体的生成配置,使用sim_utils.ConeCfg
创建圆锥体。init_state
:刚体的初始状态,使用默认配置。
- 使用
RigidObject
类实例化刚体,并将配置对象传递给构造函数。 - 返回一个字典
scene_entities
,其中包含场景中的实体(例如刚体),以及一个列表origins
,其中包含每个刚体的初始位置。
-
运行模拟循环 (run_simulator 函数):
- 重置模拟状态:
- 每隔一段时间重置刚体的根状态,包括位置和速度。
- 使用
RigidObject.data.default_root_state
获取刚体的默认根状态。 - 使用
math_utils.sample_cylinder
在圆柱体上采样随机位置,并将随机位置添加到根状态的平移部分。 - 使用
RigidObject.write_root_state_to_sim
将根状态写入模拟缓冲区。 - 使用
RigidObject.reset
重置刚体的内部缓冲区。
- 执行模拟步骤:
- 使用
RigidObject.write_data_to_sim
将其他数据(例如外力)写入模拟缓冲区。 - 本教程中没有应用外力,因此此方法不是必需的,但为了完整性而包含在内。
- 使用
sim.step()
执行模拟步骤。
- 使用
- 更新状态:
- 使用
RigidObject.update()
更新刚体的内部缓冲区。 - 打印刚体的根位置。
- 使用
- 重置模拟状态:
-
主函数 (main 函数):
- 加载 Isaac Sim 模拟器。
- 设置主摄像机视角。
- 调用
design_scene()
函数创建场景。 - 重置模拟器。
- 调用
run_simulator()
函数运行模拟循环。
-
程序入口:
if __name__ == "__main__":
语句确保只有当脚本作为主程序运行时才会执行main()
函数。- 最后,关闭 Isaac Sim 应用程序。
关键概念:
- 刚体 (Rigid Object): 在模拟中不会发生形变的物体。
- 根状态 (Root State): 刚体的位置和速度。
- 模拟缓冲区 (Simulation Buffer): 用于存储模拟数据的缓冲区,例如刚体的根状态、外力等。
总结:
这段代码演示了如何在 Isaac Sim 中创建刚体并与其交互,包括设置根状态、执行模拟步骤和更新刚体状态。通过学习这段代码,可以掌握在 Isaac Sim 中进行刚体仿真的基本方法,并将其应用到更复杂的仿真任务中。
与关节交互
这段代码演示了如何在 Isaac Sim 中与铰接机器人(例如倒立摆)进行交互。它涵盖了场景设计、模拟循环的运行,以及与机器人交互的具体方法。
代码结构:
-
导入必要的库:
argparse
用于处理命令行参数。torch
用于张量计算。omni.isaac.core.utils.prims
用于创建场景元素。omni.isaac.lab.sim
用于与 Isaac Sim 进行交互。omni.isaac.lab.assets
用于加载机器人模型。omni.isaac.lab_assets
用于加载预定义的机器人配置。
-
解析命令行参数:
- 使用
argparse
解析命令行参数,这些参数用于启动 Isaac Sim 应用程序。
- 使用
-
启动 Isaac Sim 应用程序:
- 使用
AppLauncher
类启动 Isaac Sim 应用程序。
- 使用
-
设计场景 (design_scene 函数):
- 创建地面平面和灯光。
- 创建两个名为 "Origin1" 和 "Origin2" 的坐标系,用于放置倒立摆机器人。
- 使用预定义的配置对象
CARTPOLE_CFG
创建倒立摆机器人。 CARTPOLE_CFG
包含机器人的生成策略、默认初始状态、关节驱动器模型等信息。- 使用
Articulation
类实例化倒立摆机器人,并将配置对象传递给构造函数。 - 返回一个字典
scene_entities
,其中包含场景中的实体(例如机器人),以及一个列表origins
,其中包含每个机器人的初始位置。
-
运行模拟循环 (run_simulator 函数):
- 重置模拟:
- 与刚体类似,铰接机器人也有根状态,可以使用
Articulation.write_root_state_to_sim()
方法设置。 - 此外,铰接机器人还有关节状态,可以使用
Articulation.write_joint_state_to_sim()
方法设置。 Articulation.reset()
方法用于重置内部缓冲区和缓存。
- 与刚体类似,铰接机器人也有根状态,可以使用
- 执行模拟步骤:
- 向铰接机器人发送控制指令包括两个步骤:
- 设置关节目标值:使用
Articulation.set_joint_effort_target()
等方法设置关节位置、速度或力矩目标值。 - 将数据写入模拟器:使用
Articulation.write_data_to_sim()
方法将转换后的控制指令写入 PhysX 缓冲区。
- 设置关节目标值:使用
- 本教程中使用关节力矩控制倒立摆,需要将关节刚度和阻尼参数设置为零,这在预定义的配置对象中完成。
- 向铰接机器人发送控制指令包括两个步骤:
- 更新状态:
Articulation
类包含一个ArticulationData
对象,用于存储机器人的状态。- 使用
Articulation.update()
方法更新缓冲区中的状态。
- 重置模拟:
-
主函数 (main 函数):
- 加载 Isaac Sim 模拟器。
- 设置主摄像机视角。
- 调用
design_scene()
函数创建场景。 - 重置模拟器。
- 调用
run_simulator()
函数运行模拟循环。
-
程序入口:
if __name__ == "__main__":
语句确保只有当脚本作为主程序运行时才会执行main()
函数。- 最后,关闭 Isaac Sim 应用程序。
关键概念:
- 铰接机器人 (Articulation): 由多个刚体通过关节连接而成的机器人,例如倒立摆、机械臂等。
- 根状态 (Root State): 铰接机器人树形结构中根节点的状态,通常指位置和方向。
- 关节状态 (Joint State): 铰接机器人关节的状态,通常指关节角度和速度。
- 控制指令 (Commands): 用于控制铰接机器人运动的指令,例如关节位置、速度或力矩目标值。
总结:
这段代码演示了如何在 Isaac Sim 中与铰接机器人进行交互,包括设置根状态和关节状态、发送控制指令以及更新机器人状态。通过学习这段代码,可以掌握控制铰接机器人的基本方法,并将其应用到更复杂的机器人仿真任务中。
与可变形物体交互
这段代码演示了如何在 Isaac Sim 中与可变形体(例如软体)进行交互。它涵盖了场景设计、模拟循环的运行,以及与可变形体交互的具体方法,例如设置节点位置和速度,以及应用运动学指令控制网格节点移动软体。
代码结构:
-
导入必要的库:
argparse
用于处理命令行参数。torch
用于张量计算。omni.isaac.core.utils.prims
用于创建场景元素。omni.isaac.lab.sim
用于与 Isaac Sim 进行交互。omni.isaac.lab.utils.math
用于数学计算,例如生成随机方向。omni.isaac.lab.assets
用于加载可变形体模型。omni.isaac.lab.sim
用于模拟上下文。
-
解析命令行参数:
- 使用
argparse
解析命令行参数,这些参数用于启动 Isaac Sim 应用程序。
- 使用
-
启动 Isaac Sim 应用程序:
- 使用
AppLauncher
类启动 Isaac Sim 应用程序。
- 使用
-
设计场景 (design_scene 函数):
- 创建地面平面和灯光。
- 创建四个名为 "Origin1"、"Origin2"、"Origin3" 和 "Origin4" 的坐标系,用于放置可变形体。
- 使用
DeformableObjectCfg
配置可变形体,包括:prim_path
:可变形体在场景中的路径,使用正则表达式/World/Origin.*/Cube
表示在每个 Origin 坐标系下创建一个名为 Cube 的可变形体。spawn
:可变形体的生成配置,使用sim_utils.MeshCuboidCfg
创建立方体网格。- 设置可变形体属性,例如
rest_offset
和contact_offset
。 - 设置视觉材质,例如颜色。
- 设置物理材质,例如泊松比和杨氏模量。
- 设置可变形体属性,例如
init_state
:可变形体的初始状态,设置初始位置。debug_vis
:是否启用调试可视化。
- 使用
DeformableObject
类实例化可变形体,并将配置对象传递给构造函数。 - 返回一个字典
scene_entities
,其中包含场景中的实体(例如可变形体),以及一个列表origins
,其中包含每个可变形体的初始位置。
-
运行模拟循环 (run_simulator 函数):
- 重置模拟状态:
- 每隔一段时间重置可变形体的节点状态,包括位置和速度。
- 使用
DeformableObject.data.default_nodal_state_w
获取可变形体的默认节点状态。 - 对节点位置应用随机变换,使可变形体初始状态略有不同。
- 使用
DeformableObject.write_nodal_state_to_sim
将节点状态写入模拟缓冲区。 - 使用
DeformableObject.write_nodal_kinematic_target_to_sim
将节点运动学目标重置为当前节点状态,并释放所有节点的运动学约束。 - 使用
DeformableObject.reset
重置可变形体的内部缓冲区。
- 执行模拟步骤:
- 更新部分可变形体的运动学目标,例如使索引为 0 和 3 的立方体沿 z 轴移动。
- 使用
DeformableObject.write_nodal_kinematic_target_to_sim
将节点运动学目标写入模拟缓冲区。 - 使用
DeformableObject.write_data_to_sim
将内部数据写入模拟缓冲区。 - 使用
sim.step()
执行模拟步骤。
- 更新状态:
- 使用
DeformableObject.update()
更新可变形体的内部缓冲区。 - 打印可变形体的根位置(计算为所有节点位置的平均值)。
- 使用
- 重置模拟状态:
-
主函数 (main 函数):
- 加载 Isaac Sim 模拟器。
- 设置主摄像机视角。
- 调用
design_scene()
函数创建场景。 - 重置模拟器。
- 调用
run_simulator()
函数运行模拟循环。
-
程序入口:
if __name__ == "__main__":
语句确保只有当脚本作为主程序运行时才会执行main()
函数。- 最后,关闭 Isaac Sim 应用程序。
关键概念:
- 可变形体 (Deformable Object): 在模拟中可以发生形变的物体,例如软体。
- 节点状态 (Nodal State): 可变形体网格节点的位置和速度。
- 运动学目标 (Kinematic Target): 用户指定的节点位置目标,用于控制可变形体的运动。
- 有限元方法 (FEM): 用于模拟可变形体形变的数值方法。
总结:
这段代码演示了如何在 Isaac Sim 中与可变形体进行交互,包括设置节点状态、应用运动学指令和更新可变形体状态。通过学习这段代码,可以掌握在 Isaac Sim 中进行可变形体仿真的基本方法,并将其应用到更复杂的仿真任务中。
场景创建
scene.InteractiveScene类
这段文档介绍了 Isaac Sim 中的 scene.InteractiveScene
类,它提供了一种便捷的接口,用于在模拟中生成和管理场景元素。
背景:
在之前的教程中,我们手动将资源生成了模拟环境,并创建了对象实例来与它们交互。然而,随着场景复杂性的增加,手动执行这些任务变得乏味。在本教程中,我们将介绍 scene.InteractiveScene
类,它提供了一种便捷的接口,用于生成图元并在模拟中管理它们。
交互式场景:
从高层次上讲,交互式场景是场景实体的集合。每个实体可以是非交互式图元(例如地面、光源)、交互式图元(例如关节、刚体)或传感器(例如相机、激光雷达)。交互式场景提供了一个便捷的接口,用于生成这些实体并在模拟中管理它们。
与手动方法相比,它提供了以下好处:
- 减轻了用户需要单独生成每个资源的负担,因为这是隐式处理的。
- 为多个环境启用用户友好的场景图元克隆。
- 将所有场景实体收集到单个对象中,这使得它们更易于管理。
在本教程中,我们以“与关节交互”教程中的 Cartpole 示例为例,并将 design_scene
函数替换为 scene.InteractiveScene
对象。虽然在这个简单的示例中使用交互式场景似乎有点大 overkill,但随着将来向场景中添加更多资源和传感器,它将变得更加有用。
代码解释:
1. 场景配置:
- 场景由一组实体组成,每个实体都有自己的配置。这些配置在一个继承自
scene.InteractiveSceneCfg
的配置类中指定。然后将配置类传递给scene.InteractiveScene
构造函数以创建场景。 - 对于 Cartpole 示例,我们指定与之前教程相同的场景,但现在将它们列在配置类
CartpoleSceneCfg
中,而不是手动生成它们。
@configclass
class CartpoleSceneCfg(InteractiveSceneCfg):
"""Configuration for a cart-pole scene."""
# ground plane
ground = AssetBaseCfg(prim_path="/World/defaultGroundPlane", spawn=sim_utils.GroundPlaneCfg())
# lights
dome_light = AssetBaseCfg(
prim_path="/World/Light", spawn=sim_utils.DomeLightCfg(intensity=3000.0, color=(0.75, 0.75, 0.75))
)
# articulation
cartpole: ArticulationCfg = CARTPOLE_CFG.replace(prim_path="{ENV_REGEX_NS}/Robot")
- 配置类中的变量名称用作从
scene.InteractiveScene
对象访问相应实体的键。例如,可以通过scene["cartpole"]
访问 Cartpole。 - 地面和光源使用
assets.AssetBaseCfg
类指定,而 Cartpole 使用assets.ArticulationCfg
类配置。任何不是交互式图元的东西(即既不是资源也不是传感器)在模拟步骤期间都不会被场景处理。 - 不同的图元的图元路径规范:
- 地面:
/World/defaultGroundPlane
- 光源:
/World/Light
- Cartpole:
{ENV_REGEX_NS}/Robot
- 地面:
ENV_REGEX_NS
变量是一个特殊变量,在场景创建期间会被环境名称替换。任何在其图元路径中具有ENV_REGEX_NS
变量的实体都将为每个环境克隆。此路径由场景对象替换为/World/envs/env_{i}
,其中i
是环境索引。
2. 场景实例化:
- 我们现在创建一个
scene.InteractiveScene
类的实例,并将配置对象传递给它的构造函数。在创建CartpoleSceneCfg
的配置实例时,我们使用num_envs
参数指定要创建的环境副本的数量。这将用于为每个环境克隆场景。
# Design scene
scene_cfg = CartpoleSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)
scene = InteractiveScene(scene_cfg)
3. 访问场景元素:
- 与之前教程中从字典访问实体的方式类似,可以使用
[]
运算符从InteractiveScene
对象访问场景元素。运算符接受字符串键并返回相应的实体。键是通过每个实体的配置类指定的。例如,Cartpole 在配置类中使用键"cartpole"
指定。
# Extract scene entities
# note: we only do this here for readability.
robot = scene["cartpole"]
4. 运行模拟循环:
- 脚本的其余部分看起来类似于之前与
assets.Articulation
交互的脚本,在调用的方法上有一些细微的差别:assets.Articulation.reset()
→scene.InteractiveScene.reset()
assets.Articulation.write_data_to_sim()
→scene.InteractiveScene.write_data_to_sim()
assets.Articulation.update()
→scene.InteractiveScene.update()
- 在底层,
scene.InteractiveScene
的方法调用场景中实体的相应方法。
总结:
本教程介绍了如何使用 scene.InteractiveScene
创建包含多个资源的场景。我们还看到了如何使用 num_envs
参数为多个环境克隆场景。scene.InteractiveSceneCfg
在 omni.isaac.lab_tasks
扩展下的任务中还有更多示例用法。请查看源代码以了解它们如何用于更复杂的场景。
简而言之,scene.InteractiveScene
提供了一种更便捷、更易于管理的方式来创建和控制 Isaac Sim 中的复杂场景,尤其是在需要处理多个环境或大量场景元素的情况下。
环境创建
Manager-Based RL Environment
这段代码演示了如何在 Isaac Lab 中创建一个基于管理器的强化学习 (RL) 环境,并以倒立摆任务为例,展示了如何配置奖励、终止条件、指令和课程等强化学习要素。
核心目标:
这段代码的目标是创建一个可配置的、基于管理器的倒立摆强化学习环境,使用户能够训练智能体学习如何平衡杆。
代码实现步骤:
-
定义场景配置 (CartpoleSceneCfg 类):
- 使用
@configclass
装饰器将CartpoleSceneCfg
类定义为配置类,继承自InteractiveSceneCfg
。 - 定义地面、倒立摆机器人和灯光等场景元素的配置。
- 使用
AssetBaseCfg
配置每个场景元素,包括 Prim 路径、生成配置 (spawn
) 和初始状态 (init_state
)。
- 使用
-
定义指令配置 (CommandsCfg 类):
- 使用
@configclass
装饰器将CommandsCfg
类定义为配置类。 - 由于倒立摆任务不需要指令,因此使用
mdp.NullCommandCfg()
配置一个空指令。
- 使用
-
定义动作配置 (ActionsCfg 类):
- 使用
@configclass
装饰器将ActionsCfg
类定义为配置类。 - 使用
mdp.JointEffortActionCfg
配置关节力矩动作,指定要控制的关节 ("slider_to_cart") 和缩放比例。
- 使用
-
定义观察配置 (ObservationsCfg 类):
- 使用
@configclass
装饰器将ObservationsCfg
类定义为配置类。 - 定义一个嵌套的
PolicyCfg
类,继承自ObsGroup
,用于配置策略观察组。- 定义两个观察项:
joint_pos_rel
和joint_vel_rel
,分别使用mdp.joint_pos_rel
和mdp.joint_vel_rel
函数计算关节的相对位置和速度。 - 在
__post_init__
方法中,设置enable_corruption
为False
(不启用噪声污染) 和concatenate_terms
为True
(将观察项连接成单个张量)。
- 定义两个观察项:
- 定义一个
policy
属性,实例化PolicyCfg
类。
- 使用
-
定义事件配置 (EventCfg 类):
- 使用
@configclass
装饰器将EventCfg
类定义为配置类。 - 定义两个事件项:
reset_cart_position
: 在重置时 (mode="reset"
) 随机重置滑块的位置和速度,使用mdp.reset_joints_by_offset
函数。reset_pole_position
: 在重置时 (mode="reset"
) 随机重置杆的角度和角速度,使用mdp.reset_joints_by_offset
函数。
- 使用
-
定义奖励配置 (RewardsCfg 类):
- 使用
@configclass
装饰器将RewardsCfg
类定义为配置类。 - 定义五个奖励项:
alive
: 智能体存活的奖励。terminating
: 智能体终止的惩罚。pole_pos
: 保持杆直立的奖励。cart_vel
: 滑块速度低的奖励。pole_vel
: 杆角速度低的奖励。
- 使用
RewTerm
配置每个奖励项,指定奖励函数、权重和参数。
- 使用
-
定义终止条件配置 (TerminationsCfg 类):
- 使用
@configclass
装饰器将TerminationsCfg
类定义为配置类。 - 定义两个终止条件:
time_out
: 超时终止,使用mdp.time_out
函数判断。cart_out_of_bounds
: 滑块超出边界终止,使用mdp.joint_pos_out_of_manual_limit
函数判断。
- 使用
DoneTerm
配置每个终止条件,指定终止函数和参数。
- 使用
-
定义课程配置 (CurriculumCfg 类):
- 使用
@configclass
装饰器将CurriculumCfg
类定义为配置类。 - 由于倒立摆任务不需要课程,因此使用
pass
跳过配置。
- 使用
-
定义环境配置 (CartpoleEnvCfg 类):
- 使用
@configclass
装饰器将CartpoleEnvCfg
类定义为配置类,继承自ManagerBasedRLEnvCfg
。 - 定义场景配置
scene
,使用CartpoleSceneCfg
,设置环境数量和环境间距。 - 定义观察配置
observations
,使用ObservationsCfg
。 - 定义动作配置
actions
,使用ActionsCfg
。 - 定义事件配置
events
,使用EventCfg
。 - 定义课程配置
curriculum
,使用CurriculumCfg
。 - 定义奖励配置
rewards
,使用RewardsCfg
。 - 定义终止条件配置
terminations
,使用TerminationsCfg
。 - 定义指令配置
commands
,使用CommandsCfg
。 - 在
__post_init__
方法中,设置模拟步长、降采样率、最大回合步数和观察视角。
- 使用
-
创建并运行环境 (main 函数):
- 创建
CartpoleEnvCfg
配置对象env_cfg
。 - 根据命令行参数设置环境数量。
- 使用
ManagerBasedRLEnv
类创建环境对象env
,传入配置对象env_cfg
。 - 在循环中:
- 每隔一段时间重置环境。
- 生成随机动作。
- 执行环境步骤,获取观察结果、奖励、终止状态和信息。
- 打印杆的角度。
- 关闭环境。
关键概念:
- 基于管理器的强化学习环境: 使用管理器 (Manager) 来管理强化学习环境的各个方面,例如场景、动作、观察、奖励、终止条件、指令和课程。
- 奖励管理器 (RewardManager): 负责计算智能体的奖励,可以包含多个奖励项 (RewardTerm)。
- 终止条件管理器 (TerminationManager): 负责判断回合是否终止,可以包含多个终止条件 (TerminationTerm)。
- 指令管理器 (CommandManager): 负责管理智能体的目标或指令,可以生成、更新和提供指令作为观察。
- 课程管理器 (CurriculumManager): 负责管理环境的难度,可以根据智能体的学习进度调整任务难度。
总结:
这段代码展示了如何使用 Isaac Lab 创建一个基于管理器的强化学习环境,并以倒立摆任务为例,演示了如何配置场景、动作、观察、奖励、终止条件、指令和课程。通过学习这段代码,可以掌握创建可配置的强化学习环境的基本方法,并将其应用到更复杂的仿真任务中。
Direct Workflow RL Environment
定义了一个名为 CartpoleEnv
的类,它实现了 Isaac Sim 中的 Cartpole 环境。Cartpole 是一个经典的控制问题,目标是通过控制小车的左右移动来保持杆子竖直不倒。
主要功能:
-
环境配置 (CartpoleEnvCfg):
CartpoleEnvCfg
类继承自DirectRLEnvCfg
,定义了 Cartpole 环境的各种参数,包括:- env: 仿真步长、episode 长度、动作缩放比例、动作和观测空间维度等。
- simulation: 仿真时间步长、渲染间隔等。
- robot: 小车和杆子的配置,包括关节名称等。
- scene: 场景配置,包括环境数量、环境间距等。
- reset: 重置环境时的参数,包括小车最大位置、杆子初始角度范围等。
- reward scales: 奖励函数的缩放比例,包括存活奖励、终止奖励、杆子位置奖励、小车速度奖励、杆子速度奖励等。
-
环境初始化 (CartpoleEnv.init):
- 初始化环境,包括获取小车和杆子的关节索引、动作缩放比例等。
-
场景设置 (CartpoleEnv._setup_scene):
- 创建小车和杆子模型。
- 添加地面。
- 克隆环境,并设置碰撞过滤器。
- 将小车和杆子添加到场景中。
- 添加灯光。
-
仿真步骤前 (CartpoleEnv._pre_physics_step):
- 在每个仿真步骤之前,将 Agent 的动作缩放至合适的范围。
-
应用动作 (CartpoleEnv._apply_action):
- 将缩放后的动作应用到小车的关节上,控制小车的移动。
-
获取观测值 (CartpoleEnv._get_observations):
- 获取环境的观测值,包括杆子的角度、杆子的角速度、小车的位置、小车的速度。
-
获取奖励 (CartpoleEnv._get_rewards):
- 根据环境状态计算奖励值,奖励函数的设计鼓励杆子保持竖直,并惩罚小车移动过快或杆子摆动过大。
-
获取结束标志 (CartpoleEnv._get_dones):
- 判断 episode 是否结束,结束条件包括:
- episode 超过最大长度。
- 小车超出边界。
- 杆子角度超过阈值。
- 判断 episode 是否结束,结束条件包括:
-
重置环境 (CartpoleEnv._reset_idx):
- 重置指定环境的状态,包括:
- 将小车和杆子重置到初始位置。
- 随机设置杆子的初始角度。
- 重置指定环境的状态,包括:
-
计算奖励函数 (compute_rewards):
- 一个辅助函数,用于计算奖励值。
关键概念:
- Isaac Sim: NVIDIA Omniverse Isaac Sim 是一个用于机器人仿真的平台。
- Cartpole: 一个经典的控制问题,目标是通过控制小车的左右移动来保持杆子竖直不倒。
- DirectRLEnv: Isaac Sim 中用于构建强化学习环境的基类。
- Articulation: Isaac Sim 中用于表示机器人或其他多关节物体的类。
- Reward Function: 强化学习中的奖励函数,用于评估 Agent 的行为。
代码结构:
- 代码首先定义了环境配置类
CartpoleEnvCfg
。 - 然后定义了环境类
CartpoleEnv
,它继承自DirectRLEnv
。 CartpoleEnv
类实现了环境的初始化、场景设置、仿真步骤、动作应用、观测值获取、奖励获取、结束标志获取和环境重置等功能。- 最后定义了一个辅助函数
compute_rewards
,用于计算奖励值。
总结:
这段代码实现了一个 Isaac Sim 中的 Cartpole 环境,它可以用于训练强化学习 Agent 来解决 Cartpole 控制问题。代码结构清晰,功能完整,可以作为 Isaac Sim 中构建其他强化学习环境的参考。
环境注册
这段文档解释了如何在 Isaac Sim 中注册自定义环境,以便通过 gymnasium.make()
函数方便地创建环境实例。
背景:
在之前的教程中,我们学习了如何创建自定义的 Cartpole 环境。我们可以通过导入环境类及其配置类来手动创建环境实例。
# create environment configuration
env_cfg = CartpoleEnvCfg()
env_cfg.scene.num_envs = args_cli.num_envs
# setup RL environment
env = ManagerBasedRLEnv(cfg=env_cfg)
虽然这种方法很直接,但是当我们拥有大量的环境时,它就无法扩展。在本教程中,我们将展示如何使用 gymnasium.register()
方法将环境注册到 Gymnasium 注册表中。这允许我们通过 gymnasium.make()
函数创建环境。
代码示例:
from omni.isaac.lab_tasks.utils import parse_env_cfg
def main():
"""Random actions agent with Isaac Lab environment."""
# create environment configuration
env_cfg = parse_env_cfg(
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
)
# create environment
env = gym.make(args_cli.task, cfg=env_cfg)
代码解释:
envs.ManagerBasedRLEnv
类和envs.DirectRLEnv
类都继承自gymnasium.Env
类,遵循标准接口。- 与传统的 Gym 环境不同,
envs.ManagerBasedRLEnv
实现了矢量化环境,这意味着多个环境实例在同一进程中同时运行,所有数据都以批处理方式返回。
使用 Gym 注册表:
- 要注册环境,我们使用
gymnasium.register()
方法。此方法接受环境名称、环境类的入口点和环境配置类的入口点。 - 注意: Gymnasium 注册表是一个全局注册表。因此,确保环境名称是唯一的非常重要。否则,注册表在注册环境时会引发错误。
基于管理器的环境:
- 对于基于管理器的环境,以下代码显示了
omni.isaac.lab_tasks.manager_based.classic.cartpole
子包中 Cartpole 环境的注册调用:
import gymnasium as gym
from . import agents
from .cartpole_env_cfg import CartpoleEnvCfg
##
# Register Gym environments.
##
gym.register(
id="Isaac-Cartpole-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": CartpoleEnvCfg,
"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:CartpolePPORunnerCfg",
"skrl_cfg_entry_point": f"{agents.__name__}:skrl_ppo_cfg.yaml",
"sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml",
},
)
id
参数是环境的名称。按照惯例,我们使用前缀Isaac-
命名所有环境,以便在注册表中更容易搜索它们。环境的名称通常后跟任务的名称,然后是机器人的名称。例如,对于 ANYmal C 在平坦地形上的腿部运动,环境称为Isaac-Velocity-Flat-Anymal-C-v0
。版本号v<N>
通常用于指定同一环境的不同变体。否则,环境的名称可能会变得太长且难以阅读。entry_point
参数是环境类的入口点。入口点是<module>:<class>
形式的字符串。在 Cartpole 环境的情况下,入口点是omni.isaac.lab.envs:ManagerBasedRLEnv
。入口点用于在创建环境实例时导入环境类。env_cfg_entry_point
参数指定环境的默认配置。默认配置使用omni.isaac.lab_tasks.utils.parse_env_cfg()
函数加载。然后将其传递给gymnasium.make()
函数以创建环境实例。配置入口点可以是 YAML 文件或 Python 配置类。
直接环境:
- 对于基于直接的环境,环境注册遵循类似的模式。我们不是将环境的入口点注册为
ManagerBasedRLEnv
类,而是将环境的入口点注册为环境的实现类。此外,我们在环境名称后添加后缀-Direct
以将其与基于管理器的环境区分开来。 - 例如,以下代码显示了
omni.isaac.lab_tasks.direct.cartpole
子包中 Cartpole 环境的注册调用:
import gymnasium as gym
from . import agents
from .cartpole_camera_env import CartpoleCameraEnv, CartpoleDepthCameraEnvCfg, CartpoleRGBCameraEnvCfg
from .cartpole_env import CartpoleEnv, CartpoleEnvCfg
##
# Register Gym environments.
##
gym.register(
id="Isaac-Cartpole-Direct-v0",
entry_point="omni.isaac.lab_tasks.direct.cartpole:CartpoleEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": CartpoleEnvCfg,
"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_ppo_cfg.yaml",
"rsl_rl_cfg_entry_point": f"{agents.__name__}.rsl_rl_ppo_cfg:CartpolePPORunnerCfg",
"skrl_cfg_entry_point": f"{agents.__name__}:skrl_ppo_cfg.yaml",
"sb3_cfg_entry_point": f"{agents.__name__}:sb3_ppo_cfg.yaml",
},
)
创建环境:
- 要将
omni.isaac.lab_tasks
扩展提供的所有环境通知 Gym 注册表,我们必须在脚本开始时导入模块。这将执行__init__.py
文件,该文件迭代所有子包并注册其各自的环境。
import omni.isaac.lab_tasks # noqa: F401
- 在本教程中,任务名称是从命令行读取的。任务名称用于解析默认配置以及创建环境实例。此外,其他解析的命令行参数(例如环境数量、模拟设备以及是否渲染)用于覆盖默认配置。
# create environment configuration
env_cfg = parse_env_cfg(
args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
)
# create environment
env = gym.make(args_cli.task, cfg=env_cfg)
- 创建环境后,其余的执行遵循标准的重置和步进操作。
总结:
这段文档解释了如何在 Isaac Sim 中注册自定义环境,以便通过 gymnasium.make()
函数方便地创建环境实例。它涵盖了基于管理器的环境和直接环境的注册过程,并提供了代码示例和详细解释。通过注册环境,我们可以更方便地管理和使用 Isaac Sim 中的大量环境。
训练
使用 Stable Baselines3 库在 Isaac Sim 环境中训练强化学习 (RL) Agent 的脚本。它结合了 Isaac Sim 的环境配置和 Stable Baselines3 的训练流程。
主要功能:
-
参数解析和环境配置:
- 使用
argparse
解析命令行参数,包括是否录制视频、视频参数、环境数量、任务名称、随机种子、最大迭代次数等。 - 使用
AppLauncher
启动 Isaac Sim 应用程序。 - 使用 Hydra 加载任务配置文件,并根据命令行参数覆盖环境配置。
- 创建日志目录,并将环境和 Agent 配置保存到 YAML 和 pickle 文件中。
- 使用
-
环境创建和包装:
- 使用
gym.make
创建 Isaac Sim 环境。 - 如果需要录制视频,则使用
gym.wrappers.RecordVideo
包装环境。 - 使用
Sb3VecEnvWrapper
包装环境,使其兼容 Stable Baselines3。 - 设置环境的随机种子。
- 如果配置中指定了输入或价值归一化,则使用
VecNormalize
包装环境。
- 使用
-
Agent 创建和训练:
- 使用
PPO
创建 Stable Baselines3 的 PPO Agent。 - 配置 Stable Baselines3 的日志记录器。
- 创建
CheckpointCallback
回调函数,用于定期保存模型 checkpoints。 - 使用
agent.learn
开始训练 Agent。 - 训练完成后,保存最终的模型。
- 使用
-
环境关闭:
- 关闭 Isaac Sim 环境。
- 关闭 Isaac Sim 应用程序。
关键概念:
- Isaac Sim: NVIDIA Omniverse Isaac Sim 是一个用于机器人仿真的平台。
- Stable Baselines3: 一个基于 PyTorch 的强化学习库,提供了各种常用的 RL 算法实现。
- PPO: 近端策略优化算法,一种常用的策略梯度强化学习算法。
- VecEnv: Stable Baselines3 中用于并行模拟多个环境的接口。
- Hydra: 一个用于配置管理的框架,可以方便地管理复杂的配置文件。
代码结构:
- 脚本首先解析命令行参数和加载 Hydra 配置文件。
- 然后创建 Isaac Sim 环境,并使用 Stable Baselines3 的包装器进行包装。
- 接下来创建 PPO Agent,配置日志记录器和回调函数。
- 最后开始训练 Agent,并在训练完成后保存模型。
总结:
这段代码演示了如何使用 Stable Baselines3 在 Isaac Sim 环境中训练 RL Agent。它结合了 Isaac Sim 的环境配置和 Stable Baselines3 的训练流程,提供了一个完整的 RL 训练脚本示例。
调试
使用 Stable Baselines3 库在 Isaac Sim 环境中播放强化学习 (RL) Agent Checkpoint 的脚本。它加载之前训练好的模型,并在环境中运行 Agent,展示其学习到的策略。
主要功能:
-
参数解析和环境配置:
- 使用
argparse
解析命令行参数,包括是否录制视频、视频参数、是否禁用 Fabric、环境数量、任务名称、Checkpoint 路径等。 - 使用
AppLauncher
启动 Isaac Sim 应用程序。 - 解析任务配置文件和 Agent 配置文件。
- 确定 Checkpoint 路径,如果未指定,则根据
use_last_checkpoint
参数选择最后一个或最佳的 Checkpoint。
- 使用
-
环境创建和包装:
- 使用
gym.make
创建 Isaac Sim 环境。 - 如果需要录制视频,则使用
gym.wrappers.RecordVideo
包装环境。 - 使用
Sb3VecEnvWrapper
包装环境,使其兼容 Stable Baselines3。 - 如果配置中指定了输入或价值归一化,则使用
VecNormalize
包装环境。
- 使用
-
Agent 加载:
- 使用
PPO.load
加载之前训练好的 PPO Agent 模型。
- 使用
-
环境模拟:
- 重置环境,获取初始观测值。
- 在 Isaac Sim 应用程序运行期间,循环执行以下操作:
- 使用
agent.predict
获取 Agent 的动作。 - 使用
env.step
执行动作,并获取新的观测值、奖励、是否结束等信息。 - 如果录制视频,则在录制完成后退出循环。
- 使用
-
环境关闭:
- 关闭 Isaac Sim 环境。
- 关闭 Isaac Sim 应用程序。
关键概念:
- Isaac Sim: NVIDIA Omniverse Isaac Sim 是一个用于机器人仿真的平台。
- Stable Baselines3: 一个基于 PyTorch 的强化学习库,提供了各种常用的 RL 算法实现。
- PPO: 近端策略优化算法,一种常用的策略梯度强化学习算法。
- VecEnv: Stable Baselines3 中用于并行模拟多个环境的接口。
- Checkpoint: 保存模型参数的文件,用于加载和恢复训练好的模型。
代码结构:
- 脚本首先解析命令行参数和加载配置文件。
- 然后创建 Isaac Sim 环境,并使用 Stable Baselines3 的包装器进行包装。
- 接下来加载之前训练好的 PPO Agent 模型。
- 最后循环模拟环境,并使用 Agent 的策略进行控制。
总结:
这段代码演示了如何使用 Stable Baselines3 在 Isaac Sim 环境中播放 RL Agent Checkpoint。它加载训练好的模型,并在环境中运行 Agent,展示其学习到的策略。
添加传感器
这段代码演示了如何在 Isaac Sim 中为机器人配置和使用各种传感器,以获取环境信息。以 ANYmal-C 四足机器人为例,展示了如何添加相机传感器、高度扫描传感器和接触传感器。
代码解析:
-
初始化和导入:
- 导入必要的库,包括
omni.isaac.lab
模块,用于与 Isaac Sim 进行交互,以及torch
用于张量操作。 - 使用
argparse
解析命令行参数,包括要生成的 ANYmal-C 机器人环境数量--num_envs
。 - 使用
AppLauncher
类启动 Isaac Sim 应用程序。
- 导入必要的库,包括
-
场景配置 (
SensorsSceneCfg
类):- 使用
@configclass
装饰器将SensorsSceneCfg
类定义为配置类,继承自InteractiveSceneCfg
。 - 场景元素配置:
ground
: 定义地面,使用sim_utils.GroundPlaneCfg()
配置。dome_light
: 定义穹顶灯光,使用sim_utils.DomeLightCfg
配置灯光颜色和强度。robot
: 定义 ANYmal-C 机器人,使用预定义的ANYMAL_C_CFG
并修改 Prim 路径,{ENV_REGEX_NS}/Robot
会根据环境数量生成多个机器人实例,例如/env_0/Robot
,/env_1/Robot
等等。
- 传感器配置:
camera
: 定义相机传感器,使用CameraCfg
配置,包括:prim_path
: 相机传感器在场景中的路径,这里相对于机器人基座。update_period
: 传感器更新数据的频率,以秒为单位。height
和width
: 相机分辨率。data_types
: 传感器获取的数据类型,例如 RGB 图像、深度图像等。spawn
: 使用sim_utils.PinholeCameraCfg
配置针孔相机模型,设置焦距、对焦距离、水平视角和裁剪范围。offset
: 使用CameraCfg.OffsetCfg
配置相机相对于机器人基座的偏移,设置位置、旋转和惯例 ("ros")。
height_scanner
: 定义高度扫描传感器,使用RayCasterCfg
配置,包括:prim_path
: 传感器在场景中的路径,这里相对于机器人基座。update_period
: 传感器更新数据的频率,以秒为单位。offset
: 使用RayCasterCfg.OffsetCfg
配置传感器相对于机器人基座的偏移,设置位置。attach_yaw_only
: 是否仅附着在偏航轴上,设置为True
表示传感器只跟随机器人的偏航旋转。pattern_cfg
: 使用patterns.GridPatternCfg
配置均匀网格模式的光线投射,设置分辨率和大小。debug_vis
: 是否启用调试可视化,设置为True
会在场景中显示光线投射的点。mesh_prim_paths
: 要扫描的网格 Prim 路径,这里设置为地面。
contact_forces
: 定义接触传感器,使用ContactSensorCfg
配置,包括:prim_path
: 传感器在场景中的路径,这里使用正则表达式匹配所有以 "_FOOT" 结尾的 Prim,即机器人的四个脚。update_period
: 传感器更新数据的频率,以秒为单位,设置为 0 表示与模拟步长相同。history_length
: 要存储的接触信息的历史长度,设置为 6 表示存储最近 6 个模拟步骤的信息。debug_vis
: 是否启用调试可视化。
- 使用
-
运行模拟循环 (
run_simulator
函数):sim_dt
: 获取模拟步长。sim_time
: 记录模拟时间。count
: 记录模拟步数。- 模拟循环:
- 每 500 步重置场景,包括机器人的根状态和关节状态,并添加一些随机扰动。
- 应用默认动作到机器人,设置关节位置目标。
- 执行模拟步骤 (
sim.step()
),并更新场景 (scene.update(sim_dt)
)。 - 打印传感器信息,包括:
- 相机传感器获取的 RGB 和深度图像的形状。
- 高度扫描传感器获取的最大高度值。
- 接触传感器获取的最大接触力。
-
主函数 (
main
函数):- 初始化模拟上下文 (
SimulationContext
),设置模拟步长为 0.005 秒。 - 设置主摄像机视角。
- 使用
SensorsSceneCfg
创建场景配置对象scene_cfg
,设置环境数量和环境间距。 - 使用
InteractiveScene
类创建场景对象scene
,传入配置对象scene_cfg
。 - 重置模拟器 (
sim.reset()
),初始化传感器。 - 调用
run_simulator
函数运行模拟循环。
- 初始化模拟上下文 (
关键概念:
- Prim: USD 场景中的基本元素,可以是网格、灯光、相机、传感器等。
- 传感器 (Sensor): 用于获取环境信息的设备,例如相机、激光雷达、接触传感器等。
- 更新周期 (Update Period): 传感器更新数据的频率,以秒为单位。
- 偏移 (Offset): 传感器相对于其父级 Prim 的位置和旋转。
- 数据类型 (Data Type): 传感器获取的数据类型,例如 RGB 图像、深度图像、点云等。
- 光线投射 (Ray Casting): 一种用于检测物体碰撞和获取距离信息的技术。
- 接触传感器 (Contact Sensor): 用于检测物体之间接触的传感器。
- 交互式场景 (InteractiveScene): Isaac Lab 中用于管理场景的类,提供了方便的 API 用于添加、控制和获取场景元素信息。
总结:
这段代码演示了如何在 Isaac Sim 中为机器人配置和使用各种传感器,以获取环境信息。通过学习这段代码,可以掌握在 Isaac Sim 中添加和使用传感器的方法,并将其应用到更复杂的仿真任务中。
代码示例解读:
- 代码中使用
configclass
装饰器简化了配置类的定义,使其更易读和维护。 - 传感器配置使用了
CameraCfg
、RayCasterCfg
和ContactSensorCfg
等类,这些类提供了丰富的参数来配置不同的传感器类型。 - 模拟循环中通过访问传感器的
data
属性来获取传感器数据,并进行简单的处理和打印。
使用任务空间控制器控制机器人
这段代码演示了如何在 Isaac Sim 中使用任务空间控制器控制机器人,以 Franka Emika Panda 和 Universal Robots UR10 机械臂为例,展示了如何使用 controllers.DifferentialIKController
类跟踪期望的末端执行器位姿指令。
代码核心目标:
这段代码的目标是展示如何在 Isaac Sim 中使用差分逆运动学 (Differential Inverse Kinematics, IK) 控制器控制机器人的末端执行器达到目标位姿。
代码实现步骤:
-
初始化 & 导入:
- 导入必要的库,包括用于控制 Isaac Sim 的
omni.isaac.lab
模块以及torch
用于张量操作。 - 使用
argparse
解析命令行参数,包括要使用的机器人类型--robot
(默认 Franka Emika Panda) 和要生成的机器人环境数量--num_envs
。 - 使用
AppLauncher
类启动 Isaac Sim 应用程序。
- 导入必要的库,包括用于控制 Isaac Sim 的
-
场景配置 (
TableTopSceneCfg
类):- 使用
@configclass
装饰器将TableTopSceneCfg
类定义为配置类,继承自InteractiveSceneCfg
。 - 场景元素配置:
ground
: 定义地面,使用sim_utils.GroundPlaneCfg()
配置,并设置初始位置。dome_light
: 定义穹顶灯光,使用sim_utils.DomeLightCfg
配置灯光颜色和强度。table
: 定义桌子,使用sim_utils.UsdFileCfg
从 USD 文件加载桌子模型,并设置缩放比例。robot
: 根据命令行参数--robot
选择机器人模型,使用预定义的FRANKA_PANDA_HIGH_PD_CFG
或UR10_CFG
,并修改 Prim 路径,{ENV_REGEX_NS}/Robot
会根据环境数量生成多个机器人实例。
- 使用
-
运行模拟循环 (
run_simulator
函数):- 创建差分 IK 控制器:
- 使用
DifferentialIKControllerCfg
配置控制器,包括:command_type
: 指令类型,设置为 "pose",表示控制末端执行器位姿。use_relative_mode
: 是否使用相对模式,设置为False
,表示使用绝对位姿控制。ik_method
: IK 求解方法,设置为 "dls",表示使用阻尼最小二乘法。
- 使用
DifferentialIKController
类创建控制器对象diff_ik_controller
,传入配置对象、环境数量和设备。
- 使用
- 创建可视化标记:
- 使用
VisualizationMarkers
类创建两个标记对象,ee_marker
用于可视化当前末端执行器位置,goal_marker
用于可视化目标位置。
- 使用
- 定义目标位姿:
- 创建一个包含三个目标位姿的列表
ee_goals
,每个位姿包含位置和方向信息。 - 将目标位姿列表转换为
torch.tensor
。
- 创建一个包含三个目标位姿的列表
- 初始化控制器指令:
- 创建一个缓冲区
ik_commands
用于存储控制器指令,初始值为第一个目标位姿。
- 创建一个缓冲区
- 获取机器人关节和刚体索引:
- 根据机器人类型,使用
SceneEntityCfg
类获取机器人手臂关节和末端执行器刚体的索引。 - 对于固定基座机器人,雅可比矩阵的末端执行器索引需要减 1,因为根刚体不包含在雅可比矩阵中。
- 根据机器人类型,使用
- 模拟循环:
- 每 150 步重置场景,包括机器人的关节状态、控制器指令和目标位姿索引。
- 获取机器人雅可比矩阵、末端执行器位姿、基座位姿和关节位置。
- 使用
subtract_frame_transforms
函数将末端执行器位姿转换到基座坐标系。 - 使用
diff_ik_controller.compute
函数计算目标关节位置。 - 使用
robot.set_joint_position_target
函数设置机器人的关节位置目标。 - 执行模拟步骤 (
sim.step()
),并更新场景 (scene.update(sim_dt)
)。 - 更新可视化标记的位置。
- 创建差分 IK 控制器:
-
主函数 (
main
函数):- 初始化模拟上下文 (
SimulationContext
),设置模拟步长为 0.01 秒。 - 设置主摄像机视角。
- 使用
TableTopSceneCfg
创建场景配置对象scene_cfg
,设置环境数量和环境间距。 - 使用
InteractiveScene
类创建场景对象scene
,传入配置对象scene_cfg
。 - 重置模拟器 (
sim.reset()
),初始化场景。 - 调用
run_simulator
函数运行模拟循环。
- 初始化模拟上下文 (
关键概念:
- 任务空间控制 (Task-Space Control): 直接控制机器人末端执行器在空间中的位姿,而不是控制各个关节的角度。
- 差分逆运动学 (Differential Inverse Kinematics, IK): 一种计算机器人关节角度以达到目标末端执行器位姿的方法,通常使用雅可比矩阵进行计算。
- 阻尼最小二乘法 (Damped Least Squares): 一种求解逆运动学问题的常用方法,可以解决奇异性问题。
- 雅可比矩阵 (Jacobian Matrix): 描述机器人末端执行器速度与关节速度之间关系的矩阵。
总结:
这段代码展示了如何在 Isaac Sim 中使用差分 IK 控制器实现机器人的任务空间控制,通过设置目标末端执行器位姿,控制器可以自动计算出各个关节的目标角度,并控制机器人运动到目标位姿。