在训练期间采集传感器帧#

Isaac Lab 通过 CaptureEnvSensors Gymnasium 包装器,在训练时保存场景传感器的图像类输出。--capture_env_sensors 为正值时,Isaac Lab 遍历环境的 InteractiveScene 传感器,写出各传感器的 data.output 张量,例如 Camera 的 rgb、depth 或 normals。该参数指定每张保存的平铺图像中包含多少个并行环境视图。这与 录制视频 不同,后者从可视化器或场景传感器录制 MP4 视频片段。

采集参数已注册到 RSL-RL、RL-Games、Stable Baselines3 和 skrl 的共享训练入口中, play 脚本不支持这些参数。

使用 ./isaaclab.sh train 时,可通过以下命令行参数启用此功能:

  • --capture_env_sensors :每张保存的帧网格包含的并行环境数量(默认 0 ,表示禁用采集)

  • --capture_env_sensors_length :每个传感器帧采集窗口的长度,以 每回合内的 步数计(默认 200 )。设为 0 时,即使 --capture_env_sensors 为正值,也不会保存。

  • --capture_env_sensors_interval :传感器帧采集窗口之间的间隔,以 每回合内的 步数计(默认 2000 )

  • --capture_env_sensors_format :输出格式,为 tensorboard (默认)或 file

启用传感器采集会自动开启训练中的相机渲染,与 --video 相同,因此启动和运行速度都会降低。如果既需要逐传感器帧,又需要透视视口视频片段,可以同时使用传感器采集和 --video 。

示例用法:

uv run isaaclab train --rl_library rsl_rl --task=Isaac-Reorient-Cube-Shadow-Camera-Direct --capture_env_sensors 4 --capture_env_sensors_length 100 --capture_env_sensors_interval 2000 --capture_env_sensors_format file
./isaaclab.sh train --rl_library rsl_rl --task=Isaac-Reorient-Cube-Shadow-Camera-Direct --capture_env_sensors 4 --capture_env_sensors_length 100 --capture_env_sensors_interval 2000 --capture_env_sensors_format file

采集的帧与训练检查点保存在同一目录下,具体位置为 logs/<rl_workflow>/<task>/<run>/sensor_frames/train 。其中 <run> 是本次训练的运行目录(即保存检查点和 run.json 的带时间戳文件夹),不是输出标签和文件名中使用的回合索引。

概述#

传感器采集功能通过 isaaclab_rl.entrypoints.common 中的 wrap_sensor_capture 包装训练环境。当当前 回合内的 步数落在采集窗口内时,在重置和步进时保存帧。对每个具有图像类输出的场景传感器,该包装器会:

  • 读取 sensor.data.output ,跳过输出不是张量字典的传感器

  • 将各输出解析为 torch.Tensor ,其中 ProxyArray 缓冲区通过 .torch 访问器读取

  • 从各张量中选取前 capture_num_envs 个并行环境

  • 在显示归一化前,将非有限值替换为零

  • 使用 normalize_camera_output_for_display() 对各输出进行显示归一化,再通过 make_camera_output_grid() 将所选视图拼成一张图像网格

  • 根据 --capture_env_sensors_format ,将网格写入 TensorBoard 或保存为磁盘上的 PNG 文件

如果某种数据类型的传感器输出为 None ,则跳过它。只有定义了图像类场景传感器输出的任务(例如基于相机的强化学习环境)才会生成采集帧。

命令行选项#

训练入口在 add_common_train_args 中注册采集参数:

def add_common_train_args(
    parser: argparse.ArgumentParser,
    *,
    agent_default: str | None,
    agent_help: str,
    include_agent: bool = True,
    include_distributed: bool = True,
    max_iterations_type: Callable[[str], int] = int,
) -> None:
    """Add the training arguments shared by all reinforcement learning backends.

    Args:
        parser: The parser to add arguments to.
        agent_default: Default agent config entry point.
        agent_help: Help text for the ``--agent`` argument.
        include_agent: Whether to include the ``--agent`` argument.
        include_distributed: Whether to include the ``--distributed`` argument.
        max_iterations_type: Converter and validator for ``--max_iterations``.
    """
    add_video_args(parser, action="training")
    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.")
    add_frontend_args(parser)
    if include_agent:
        parser.add_argument("--agent", type=str, default=agent_default, help=agent_help)
    parser.add_argument("--seed", type=int, default=None, help="Seed used for the environment.")
    if include_distributed:
        parser.add_argument(
            "--distributed", action="store_true", default=False, help="Run training with multiple GPUs or nodes."
        )
        parser.add_argument(
            "--run_timestamp",
            type=str,
            default=None,
            help="Timestamp naming the run folder; train_multigpu passes one so that every rank shares the folder.",
        )
    parser.add_argument(
        "--max_iterations", type=max_iterations_type, default=None, help="RL Policy training iterations."
    )
    parser.add_argument(
        "--export_io_descriptors",
        action="store_true",
        default=False,
        help="Deprecated: export IO descriptors (removed in Isaac Lab 3.2).",
    )
    parser.add_argument(
        "--ray-proc-id",
        "-rid",
        type=int,
        default=None,
        help="Automatically configured by Ray integration, otherwise None.",
    )
    parser.add_argument(
        "--capture_env_sensors",
        type=int,
        default=0,
        help="Number of environment views to capture from each image-like scene sensor.",
    )
    parser.add_argument(
        "--capture_env_sensors_length",
        type=int,
        default=200,
        help="Length of each captured sensor frame window (in steps).",
    )
    parser.add_argument(
        "--capture_env_sensors_interval",
        type=int,
        default=2000,
        help="Interval between captured sensor frame windows (in steps).",
    )
    parser.add_argument(
        "--capture_env_sensors_format",
        choices=["tensorboard", "file"],
        default="tensorboard",
        help="Format used to save the captured sensor frames.",
    )

采集时机#

每次环境重置时,以及当前 回合内的 步数位于有效采集窗口内时的每一步之后,都会保存一帧。每次环境重置都会将回合步数计数器重置为 0 。满足以下条件时,该步位于采集窗口内:

step % capture_env_sensors_interval < capture_env_sensors_length

例如,设置 --capture_env_sensors_length 100 和 --capture_env_sensors_interval 2000 后,包装器会在每次重置后保存回合内第 0-99 步的画面。如果一回合超过 2000 步,会在第 2000-2099 步再次开启采集窗口,随后是 4000-4099 步,依此类推。

备注

此调度使用 每回合 步数计数器。录制视频 则使用由 VideoRecorder 维护的 跨回合全局 环境步数计数器。

回合索引#

每次环境重置都会递增回合索引,第一次重置时索引为 1 。采集帧按该索引分组,便于比较连续回合:

  • TensorBoard 标签使用 <sensor_name>/<data_type>/episode_<index> ,回合索引补零至五位(例如 episode_00001 )

  • 文件输出保存在各传感器和数据类型目录下,文件名为 episode_<index>_step_<step>.png ,回合索引为五位,步数索引为八位(例如 episode_00001_step_00000042.png )

<step> 是回合内的步数计数器(每次环境重置时归零)。在 TensorBoard 中记录图像时, global_step 设置为从训练开始累计的环境总步数。

图像处理#

拼接之前,各所选环境视图会经过 normalize_camera_output_for_display() 处理,将常见相机数据类型映射为适合导出 PNG 的 [0, 1] 浮点范围:

  • rgb 和未识别的输出类型除以 255 ,生成 [0, 1] 范围的浮点数

  • 深度类输出( depth 、 distance_to_camera 、 distance_to_image_plane )除以各自的逐帧最大值

  • albedo 保留前三个通道并除以 255

  • normals 从 [-1, 1] 重新映射到 [0, 1]

  • motion_vectors 先截断至 [-1, 1] ,再映射到 [0, 1] ,随后放入 RGB 图像的 R、G 通道(B 通道设为零)

写入图像前, make_camera_output_grid() 将 capture_num_envs 个视图排列成近似正方形的网格( nrow = round(sqrt(num_envs)) )。

输出格式#

TensorBoard(默认)。 每个传感器输出按回合记录为独立的图像序列,标签为 <sensor_name>/<data_type>/episode_<index> 。将 TensorBoard 指向训练日志目录或 sensor_frames/train 子目录,即可将采集画面与其他训练指标一起查看:

uv run python -m tensorboard.main --logdir logs/rsl_rl/Isaac-Reorient-Cube-Shadow-Camera-Direct/<run>/sensor_frames/train
./isaaclab.sh -p -m tensorboard.main --logdir logs/rsl_rl/Isaac-Reorient-Cube-Shadow-Camera-Direct/<run>/sensor_frames/train

文件。 按传感器、数据类型、回合和步数写入 PNG 图像:

<sensor_name>/<data_type>/episode_<index>_step_<step>.png

写入文件时会清理传感器和数据类型名称,确保它们可安全用作路径组成部分。例如,传感器 front/camera 的 rgb 数据类型在第一回合第 42 步的画面,会保存为 front_camera/rgb/episode_00001_step_00000042.png 。

总结#

--capture_env_sensors_format

输出位置

查看方式

tensorboard (默认)

sensor_frames/train 事件文件

TensorBoard 图像标签页(按传感器、数据类型和回合索引标记)

file

sensor_frames/train/<sensor>/<data_type>/episode_<index>_step_<step>.png

任意图像查看器或文件浏览器

选择采集方式#

目标

用途

输出

在训练期间查看传感器输出

本页( --capture_env_sensors )

PNG 文件或 TensorBoard 图像

录制或分享视频

录制视频 (VideoRecorderCfg)

MP4 视频

另请参阅#

  • 录制视频:通过 --video 录制透视视口的视频片段

  • 强化学习 — 注册采集参数的共享 train / play 入口

  • 可视化 — 可视化器与训练期间的渲染

  • 相机 — 相机传感器与标注器数据类型

  • 使用 ProxyArray — 通过 .torch 读取的 CPU/GPU 双接口传感器缓冲区