Capturing sensor frames during training
Isaac Lab supports saving image-like outputs from scene sensors during training using the
CaptureEnvSensors Gymnasium wrapper. When --capture_env_sensors is set to a positive value,
Isaac Lab iterates over the environment’s ~isaaclab.scene.InteractiveScene sensors and
writes each sensor’s data.output tensors (for example, rgb, depth, or normals from a
~isaaclab.sensors.Camera). The flag value is the number of parallel environment views to
tile into each saved frame grid. This differs from /source/how-to/record_video, which records a single
perspective viewport clip of the scene.
The capture flags are registered on the shared training entrypoints for RSL-RL, RL-Games, Stable
Baselines3, and skrl. They are not available on play scripts.
This feature can be enabled using the following command line arguments with
./isaaclab.sh train:
--capture_env_sensors: number of parallel environments to include in each saved frame grid (default:0, which disables capture)--capture_env_sensors_length: length of each captured sensor frame window in per-episode steps (default:200). Set to0to disable saving even when--capture_env_sensorsis positive.--capture_env_sensors_interval: interval between captured sensor frame windows in per-episode steps (default:2000)--capture_env_sensors_format: output format, eithertensorboard(default) orfile
Enabling sensor capture automatically enables camera rendering during training, the same as
--video, which slows down both startup and runtime performance. Sensor capture can also be used
at the same time as --video when both per-sensor frames and a perspective viewport clip are
needed.
Example usage:
uv (Recommended)
isaaclab.sh / isaaclab.bat
The captured frames will be saved in the same directory as the training checkpoints, under
logs/<rl_workflow>/<task>/<run>/sensor_frames/train. Here <run> is the training run
directory (the same timestamped folder used for checkpoints and run.json), not the per-episode
index used in output tags and file names.
Overview
The sensor capture feature wraps the training environment through wrap_sensor_capture in
isaaclab_rl.entrypoints.common and saves frames on reset and step when the current
per-episode step falls inside a capture window. For each image-like scene sensor, the wrapper:
- reads
sensor.data.outputand skips sensors whose output is not a dictionary of tensors - resolves each output to a
torch.Tensor, including~isaaclab.utils.warp.ProxyArraybuffers through their.torchaccessor - selects the first
capture_num_envsparallel environments from each tensor - replaces non-finite values with zero before display normalization
- normalizes each output for display using
~isaaclab.utils.images.normalize_camera_output_for_displayand tiles the selected views into a single image grid with~isaaclab.utils.images.make_camera_output_grid - writes the grid to TensorBoard or to disk as a PNG, depending on
--capture_env_sensors_format
Sensors with None for a given data type are skipped. Only tasks that define scene sensors with
image-like outputs (such as camera-based RL environments) produce captured frames.
Command-line options
The training entrypoints register the capture flags in add_common_train_args:
Capture schedule
A frame is saved on every environment reset and after each step while the current per-episode
step is inside an active capture window. The episode step counter resets to 0 on every
environment reset. A step is inside the window when:
For example, with --capture_env_sensors_length 100 and --capture_env_sensors_interval 2000,
the wrapper saves episode steps 0-99 after each reset. If an episode lasts longer than 2000
steps, another capture window opens at episode steps 2000-2099, then 4000-4099, and so on.
This schedule uses a per-episode step counter. /source/how-to/record_video instead keys off the
Gymnasium RecordVideo wrapper’s global environment-step counter across episodes.
Episode indexing
Each environment reset increments an episode index that starts at 1 on the first reset. Captured
frames are grouped by this index so consecutive episodes can be compared:
- TensorBoard tags use
<sensor_name>/<data_type>/episode_<index>with a five-digit zero-padded episode index (for example,episode_00001) - File output uses
episode_<index>_step_<step>.pngunder each sensor and data-type directory, with a five-digit episode index and an eight-digit step index (for example,episode_00001_step_00000042.png)
The <step> value is the per-episode step counter (reset to 0 on every environment reset).
In TensorBoard, images are logged with global_step set to the total number of environment steps
since training started.
Image processing
Before tiling, each selected environment view is passed through
~isaaclab.utils.images.normalize_camera_output_for_display, which maps common camera data
types to a [0, 1] float range suitable for PNG export:
rgband unrecognized output types are divided by255to produce[0, 1]floats- Depth-like outputs (
depth,distance_to_camera,distance_to_image_plane) are divided by their per-frame maximum albedokeeps the first three channels and divides by255normalsare remapped from[-1, 1]to[0, 1]motion_vectorsare clamped to[-1, 1], remapped to[0, 1], and packed into the RG channels of an RGB image (B channel set to zero)
~isaaclab.utils.images.make_camera_output_grid arranges the capture_num_envs views into a
roughly square grid (nrow = round(sqrt(num_envs))) before the image is written.
Output formats
TensorBoard (default). Each sensor output is logged as a separate image series per episode with
the tag <sensor_name>/<data_type>/episode_<index>. View the captures alongside other training
metrics by pointing TensorBoard at the training log directory or the sensor_frames/train
subdirectory:
uv (Recommended)
isaaclab.sh / isaaclab.bat
File. PNG images are written per sensor, data type, episode, and step:
<sensor_name>/<data_type>/episode_<index>_step_<step>.png
Sensor and data-type names are sanitized for file output so they are safe as path components. For
example, a frame from the first episode at step 42 for sensor front/camera and data type
rgb is written as front_camera/rgb/episode_00001_step_00000042.png.
Summary
Choosing a capture method
See also
- /source/how-to/record_video - record a perspective viewport clip with
--video - /source/concepts/reinforcement_learning - the shared
train/playentrypoints that register the capture flags - https://isaac-sim.github.io/IsaacLab/release/3.0.0/source/concepts/visualization.html - visualizers and rendering during training
- /source/concepts/sensors/camera - camera sensors and annotator data types
- proxy_array - dual CPU/GPU sensor buffers read through
.torch