如是我闻: 在上一个指南中,我们学习了如何创建一个自定义的车杆环境。我们通过导入环境类及其配置类来手动创建了一个环境实例
# create environment configurationenv_cfg = CartpoleEnvCfg()env_cfg.scene.num_envs = args_cli.num_envs# setup RL environmentenv = RLTaskEnv(cfg=env_cfg)
虽然这种方法直接明了,但当我们拥有大量的环境时,这种方法并咋能扩展。在指南08中,我们将展示如何使用gymnasium.register()
方法将环境注册到gymnasium注册表中。这样我们就可以通过gymnasium.make()
函数创建环境。
import omni.isaac.orbit_tasks # noqa: F401
from omni.isaac.orbit_tasks.utils import parse_env_cfgdef main():"""Random actions agent with Orbit environment."""# create environment configurationenv_cfg = parse_env_cfg(args_cli.task, use_gpu=not args_cli.cpu, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric)# create environmentenv = gym.make(args_cli.task, cfg=env_cfg)
指南对应于orbit/source/standalone/environments
目录中的random_agent.py
脚本。让我们先搂一眼完整代码长啥样。
# Copyright (c) 2022-2024, The ORBIT Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause"""Script to an environment with random action agent."""from __future__ import annotations"""Launch Isaac Sim Simulator first."""import argparsefrom omni.isaac.orbit.app import AppLauncher# add argparse arguments
parser = argparse.ArgumentParser(description="Random agent for Orbit environments.")
parser.add_argument("--cpu", action="store_true", default=False, help="Use CPU pipeline.")
parser.add_argument("--disable_fabric", action="store_true", default=False, help="Disable fabric and use USD I/O operations."
)
parser.add_argument("--num_envs", type=int, default=None, help="Number of environments to simulate.")
parser.add_argument("--task", type=str, default=None, help="Name of the task.")
# append AppLauncher cli args
AppLauncher.add_app_launcher_args(parser)
# parse the arguments
args_cli = parser.parse_args()# launch omniverse app
app_launcher = AppLauncher(args_cli)
simulation_app = app_launcher.app"""Rest everything follows."""import gymnasium as gym
import torchimport omni.isaac.contrib_tasks # noqa: F401
import omni.isaac.orbit_tasks # noqa: F401
from omni.isaac.orbit_tasks.utils import parse_env_cfgdef main():"""Random actions agent with Orbit environment."""# create environment configurationenv_cfg = parse_env_cfg(args_cli.task, use_gpu=not args_cli.cpu, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric)# create environmentenv = gym.make(args_cli.task, cfg=env_cfg)# print info (this is vectorized environment)print(f"[INFO]: Gym observation space: {env.observation_space}")print(f"[INFO]: Gym action space: {env.action_space}")# reset environmentenv.reset()# simulate environmentwhile simulation_app.is_running():# run everything in inference modewith torch.inference_mode():# sample actions from -1 to 1actions = 2 * torch.rand(env.action_space.shape, device=env.unwrapped.device) - 1# apply actionsenv.step(actions)# close the simulatorenv.close()if __name__ == "__main__":# run the main functionmain()# close sim appsimulation_app.close()
代码解析
envs.RLTaskEnv
类继承自gymnasium.Env
类以遵循标准接口。然而,与传统的Gym环境不同,envs.RLTaskEnv
实现了一个向量化环境。这意味着多个环境实例同时在同一个进程中运行,并且所有数据都以批处理方式返回。
使用gym登记档
要注册一个环境,我们使用gymnasium.register()
方法。这个方法接收环境名称、环境类的入口点以及环境配置类的入口点。对于车杆环境,以下是在omni.isaac.orbit_tasks.classic.cartpole
子包中的注册调用示例:
import gymnasium as gymfrom . import agents
from .cartpole_env_cfg import CartpoleEnvCfg##
# Register Gym environments.
##gym.register(id="Isaac-Cartpole-v0",entry_point="omni.isaac.orbit.envs:RLTaskEnv",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": agents.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
参数是环境类的入口点。入口点是形如:的字符串。在车杆环境的案例中,入口点是omni.isaac.orbit.envs:RLTaskEnv
。入口点用于在创建环境实例时导入环境类。
env_cfg_entry_point
参数指定了环境的默认配置。默认配置使用omni.isaac.orbit_tasks.utils.parse_env_cfg()
函数加载。然后,它被传递给gymnasium.make()
函数以创建环境实例。配置入口点可以是一个YAML文件或一个python配置类。
创建环境
为了让gym
注册表了解omni.isaac.orbit_tasks
扩展提供的所有环境,我们必须在脚本开始时导入该模块。这将执行__init__.py
文件,该文件遍历所有子包并注册它们各自的环境。
import omni.isaac.orbit_tasks # noqa: F401
在本指南中,任务名称从命令行读取。任务名称用于解析默认配置以及创建环境实例。此外,其他解析的命令行参数,如环境数量、模拟设备和是否渲染,用于覆盖默认配置。
# create environment configurationenv_cfg = parse_env_cfg(args_cli.task, use_gpu=not args_cli.cpu, num_envs=args_cli.num_envs, use_fabric=not args_cli.disable_fabric)# create environmentenv = gym.make(args_cli.task, cfg=env_cfg)
一旦创建了环境,其余的执行将遵循标准的重置和步进过程。
代码运行
现在让我们运行脚本来查看结果:
./orbit.sh -p source/standalone/environments/random_agent.py --task Isaac-Cartpole-v0 --num_envs 32
这应该会打开一个展台,其内容与之前的创建RL环境教程类似。要停止模拟,可以选择关闭窗口,或在终端中按Ctrl+C。
此外,还可以通过添加--cpu
指示,将模拟设备从GPU更改为CPU:
./orbit.sh -p source/standalone/environments/random_agent.py --task Isaac-Cartpole-v0 --num_envs 32 --cpu
使用--cpu
指示,模拟将在CPU上运行。这对于调试模拟很有用。然而,模拟在CPU上的运行速度将比在GPU上慢得多(拜老黄)。
愿本文除一切机器人模拟器苦
以上