包装环境#
环境包装器是一种修改环境行为而不修改环境本身的方法。这可以用来应用函数来修改观察或奖励,记录视频,强制时间限制等。API的详细说明在 gymnasium.Wrapper
类中可用。
目前,所有继承自 ManagerBasedRLEnv
类或 DirectRLEnv
类的RL环境都与 gymnasium.Wrapper
兼容,因为基类实现了 gymnasium.Env
接口。要包装一个环境,您需要先初始化基础环境。然后,您可以通过多次调用 env = wrapper(env, *args, **kwargs)
来包装它,以便包装尽可能多的包装器。
例如,这是如何将一个环境包装起来强制在step或render之前调用reset的方式 :
"""Launch Isaac Sim Simulator first."""
from omni.isaac.lab.app import AppLauncher
# launch omniverse app in headless mode
app_launcher = AppLauncher(headless=True)
simulation_app = app_launcher.app
"""Rest everything follows."""
import gymnasium as gym
import omni.isaac.lab_tasks # noqa: F401
from omni.isaac.lab_tasks.utils import load_cfg_from_registry
# create base environment
cfg = load_cfg_from_registry("Isaac-Reach-Franka-v0", "env_cfg_entry_point")
env = gym.make("Isaac-Reach-Franka-v0", cfg=cfg)
# wrap environment to enforce that reset is called before step
env = gym.wrappers.OrderEnforcing(env)
用于记录视频的包装器#
gymnasium.wrappers.RecordVideo
包装器可用于记录环境的视频。该包装器接受一个 video_dir
参数,指定要保存视频的位置。根据指定的步数或情节,以指定的间隔将视频以 mp4 格式保存。
要使用该包装器,您需要首先安装 ffmpeg
。在Ubuntu上,可以通过运行以下命令进行安装 :
sudo apt-get install ffmpeg
注意
默认情况下,在无头模式运行环境时,Omniverse视口会被禁用。这样做是为了通过避免不必要的渲染来提高性能。
我们注意到在使用RTX 3090 GPU 的 Isaac-Reach-Franka-v0
环境中采用不同的渲染模式时的性能 :
没有开启离屏渲染的无 GUI 执行 : ~65,000 FPS
开启了离屏渲染的无 GUI 执行 : ~57,000 FPS
全渲染的 GUI 执行 : ~13,000 FPS
用于渲染的视口相机是场景中称为 "/OmniverseKit_Persp"
的默认相机。相机的姿势和图像分辨率可以通过 ViewerCfg
类进行配置。
ViewerCfg类的默认参数 :
@configclass
class ViewerCfg:
"""Configuration of the scene viewport camera."""
eye: tuple[float, float, float] = (7.5, 7.5, 7.5)
"""Initial camera position (in m). Default is (7.5, 7.5, 7.5)."""
lookat: tuple[float, float, float] = (0.0, 0.0, 0.0)
"""Initial camera target position (in m). Default is (0.0, 0.0, 0.0)."""
cam_prim_path: str = "/OmniverseKit_Persp"
"""The camera prim path to record images from. Default is "/OmniverseKit_Persp",
which is the default camera in the viewport.
"""
resolution: tuple[int, int] = (1280, 720)
"""The resolution (width, height) of the camera specified using :attr:`cam_prim_path`.
Default is (1280, 720).
"""
origin_type: Literal["world", "env", "asset_root", "asset_body"] = "world"
"""The frame in which the camera position (eye) and target (lookat) are defined in. Default is "world".
Available options are:
* ``"world"``: The origin of the world.
* ``"env"``: The origin of the environment defined by :attr:`env_index`.
* ``"asset_root"``: The center of the asset defined by :attr:`asset_name` in environment :attr:`env_index`.
* ``"asset_body"``: The center of the body defined by :attr:`body_name` in asset defined by :attr:`asset_name` in environment :attr:`env_index`.
"""
env_index: int = 0
"""The environment index for frame origin. Default is 0.
This quantity is only effective if :attr:`origin` is set to "env" or "asset_root".
"""
asset_name: str | None = None
"""The asset name in the interactive scene for the frame origin. Default is None.
This quantity is only effective if :attr:`origin` is set to "asset_root".
"""
body_name: str | None = None
"""The name of the body in :attr:`asset_name` in the interactive scene for the frame origin. Default is None.
This quantity is only effective if :attr:`origin` is set to "asset_body".
"""
调整参数后,您可以通过将环境包装在 gymnasium.wrappers.RecordVideo
包装器并启用离屏渲染标志来记录视频。此外,您需要指定环境的渲染模式为 "rgb_array"
。
例如,以下代码将记录 Isaac-Reach-Franka-v0
环境的视频,持续200步,并将其保存在 videos
文件夹中,步长为1500步。
"""Launch Isaac Sim Simulator first."""
from omni.isaac.lab.app import AppLauncher
# launch omniverse app in headless mode with off-screen rendering
app_launcher = AppLauncher(headless=True, enable_cameras=True)
simulation_app = app_launcher.app
"""Rest everything follows."""
import gymnasium as gym
# adjust camera resolution and pose
env_cfg.viewer.resolution = (640, 480)
env_cfg.viewer.eye = (1.0, 1.0, 1.0)
env_cfg.viewer.lookat = (0.0, 0.0, 0.0)
# create isaac-env instance
# set render mode to rgb_array to obtain images on render calls
env = gym.make(task_name, cfg=env_cfg, render_mode="rgb_array")
# wrap for video recording
video_kwargs = {
"video_folder": "videos/train",
"step_trigger": lambda step: step % 1500 == 0,
"video_length": 200,
}
env = gym.wrappers.RecordVideo(env, **video_kwargs)
学习框架的包装器#
每个学习框架都有自己的API与环境交互。例如, Stable-Baselines3 库使用 gym.Env 接口与环境进行交互。然而,像 RL-Games , RSL-RL 或 SKRL 这样的库使用自己的API来与学习环境进行交互。由于并非所有情况均适用,我们不会将 ManagerBasedRLEnv
和 DirectRLEnv
类建立在任何特定学习框架的环境定义基础上。相反,我们实现包装器来使其与学习框架的环境定义兼容。
使用Stable-Baselines3与RL任务环境的示例 :
from omni.isaac.lab_tasks.utils.wrappers.sb3 import Sb3VecEnvWrapper
# create isaac-env instance
env = gym.make(task_name, cfg=env_cfg)
# wrap around environment for stable baselines
env = Sb3VecEnvWrapper(env)
小心
在应用所有其他包装器后,应在最后使用相应学习框架的包装器包装环境。这是因为学习框架的包装器会修改环境API的解释,这可能不再与 gymnasium.Env
兼容。
添加新的包装器#
所有新的包装器都应添加到 omni.isaac.lab_tasks.utils.wrappers
模块。它们应该检查底层环境是否是 omni.isaac.lab.envs.ManagerBasedRLEnv
或 DirectRLEnv
类的实例,然后再应用该包装器。这可以通过使用 unwrapped()
属性来完成。
我们在这个模块中包括了一组包装器,供您作为实现自己包装器的参考。如果您实现了一个新的包装器,请考虑通过开放一个拉取请求将其贡献给框架。