注册环境#
在上一个教程中,我们学习了如何创建自定义的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)
代码#
本教程对应 source/standalone/environments
目录中的 random_agent.py
脚本。
random_agent.py的代码
1# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
2# All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5
6"""Script to an environment with random action agent."""
7
8"""Launch Isaac Sim Simulator first."""
9
10import argparse
11
12from omni.isaac.lab.app import AppLauncher
13
14# add argparse arguments
15parser = argparse.ArgumentParser(description="Random agent for Isaac Lab environments.")
16parser.add_argument(
17 "--disable_fabric", action="store_true", default=False, help="Disable fabric and use USD I/O operations."
18)
19parser.add_argument("--num_envs", type=int, default=None, help="Number of environments to simulate.")
20parser.add_argument("--task", type=str, default=None, help="Name of the task.")
21# append AppLauncher cli args
22AppLauncher.add_app_launcher_args(parser)
23# parse the arguments
24args_cli = parser.parse_args()
25
26# launch omniverse app
27app_launcher = AppLauncher(args_cli)
28simulation_app = app_launcher.app
29
30"""Rest everything follows."""
31
32import gymnasium as gym
33import torch
34
35import omni.isaac.lab_tasks # noqa: F401
36from omni.isaac.lab_tasks.utils import parse_env_cfg
37
38
39def main():
40 """Random actions agent with Isaac Lab environment."""
41 # create environment configuration
42 env_cfg = parse_env_cfg(
43 args_cli.task, device=args_cli.device, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric
44 )
45 # create environment
46 env = gym.make(args_cli.task, cfg=env_cfg)
47
48 # print info (this is vectorized environment)
49 print(f"[INFO]: Gym observation space: {env.observation_space}")
50 print(f"[INFO]: Gym action space: {env.action_space}")
51 # reset environment
52 env.reset()
53 # simulate environment
54 while simulation_app.is_running():
55 # run everything in inference mode
56 with torch.inference_mode():
57 # sample actions from -1 to 1
58 actions = 2 * torch.rand(env.action_space.shape, device=env.unwrapped.device) - 1
59 # apply actions
60 env.step(actions)
61
62 # close the simulator
63 env.close()
64
65
66if __name__ == "__main__":
67 # run the main function
68 main()
69 # close sim app
70 simulation_app.close()
代码解释#
envs.ManagerBasedRLEnv
类继承自 gymnasium.Env
类以遵循标准接口。然而,与传统的Gym环境不同, envs.ManagerBasedRLEnv
实现了*向量化*环境。这意味着多个环境实例同时在同一进程中运行,并且所有数据都以批处理方式返回。
同样,envs.DirectRLEnv
类也从 gymnasium.Env
类继承以用于直接工作流程。对于 envs.DirectMARLEnv
,虽然它不是从Gymnasium继承的,但可以以相同的方式注册和创建。
使用gym注册表#
要注册一个环境,我们使用 gymnasium.register()
方法。此方法接收环境名称、环境类的入口点以及环境配置类的入口点。
备注
gymnasium
注册表是一个全局注册表。因此,确保环境名称是唯一的很重要。否则,在注册环境时注册表会抛出错误。
基于管理器的环境#
对于基于管理器的环境,以下显示了在 omni.isaac.lab_tasks.manager_based.classic.cartpole
子包中注册cartpole环境的调用:
import gymnasium as gym
from . import agents
##
# 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": f"{__name__}.cartpole_env_cfg: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",
},
)
gym.register(
id="Isaac-Cartpole-RGB-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.cartpole_camera_env_cfg:CartpoleRGBCameraEnvCfg",
"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_camera_ppo_cfg.yaml",
},
)
gym.register(
id="Isaac-Cartpole-Depth-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.cartpole_camera_env_cfg:CartpoleDepthCameraEnvCfg",
"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_camera_ppo_cfg.yaml",
},
)
gym.register(
id="Isaac-Cartpole-RGB-ResNet18-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.cartpole_camera_env_cfg:CartpoleResNet18CameraEnvCfg",
"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_feature_ppo_cfg.yaml",
},
)
gym.register(
id="Isaac-Cartpole-RGB-TheiaTiny-v0",
entry_point="omni.isaac.lab.envs:ManagerBasedRLEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.cartpole_camera_env_cfg:CartpoleTheiaTinyCameraEnvCfg",
"rl_games_cfg_entry_point": f"{agents.__name__}:rl_games_feature_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
##
# Register Gym environments.
##
gym.register(
id="Isaac-Cartpole-Direct-v0",
entry_point=f"{__name__}.cartpole_env:CartpoleEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.cartpole_env: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",
},
)
gym.register(
创建环境#
要将所有 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)
一旦创建环境,其余执行将遇到标准的重置和步进。
代码执行#
现在我们已经阅读了代码,让我们运行脚本并看看结果:
./isaaclab.sh -p source/standalone/environments/random_agent.py --task Isaac-Cartpole-v0 --num_envs 32
这将打开一个与 创建基于管理器的强化学习环境 教程类似的阶段。要停止模拟,您可以关闭窗口,或在终端中按 Ctrl+C
。
此外,您还可以通过显式设置 --device
的值将模拟设备从 GPU 更改为 CPU:
./isaaclab.sh -p source/standalone/environments/random_agent.py --task Isaac-Cartpole-v0 --num_envs 32 --device cpu
使用 --device cpu
标志,模拟将在CPU上运行。这对于调试模拟很有用。但是,与在GPU上运行相比,模拟速度会慢得多。