Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Space Robotics Bench (SRB) provides modular environments and tasks for autonomous systems across extraterrestrial scenarios, robots, and research workflows.

Start: System Requirements → Installation → Basic Usage.

SRB targets Isaac Sim 6.1.0 and Isaac Lab 3.0.0; Docker is the tested installation path.

SimForge generates scenes and assets on demand.

System Requirements

Hardware Requirements

SRB targets Isaac Sim 6.1.0 (v6.1.0) and Isaac Lab 3.0.0 (release/3.0.0). Their commits are 7c206f75bdadd9e05fc457f19863ca4c3f0cb693 and fdc650c88dfd86aa158b9a1760b6537fef360555. Docker x86_64 is tested. Native, Apptainer/HPC, and arm64 are untested. The tables show SRB’s minimum requirements and NVIDIA’s tested baseline.

SRB declared minimum

ComponentRequirement
CPUx86_64 Linux
GPUNVIDIA GPU with RT Cores for Isaac Sim workflows
RAM16 GB (32 GB for simulator; estimates)
VRAMAbout 4 GB for GPU-accelerated workflows that do not launch Isaac Sim; about 12 GB for SRB simulator workflows (estimates). Isaac Sim’s tested baseline is 16 GB.
Disk Space50 GB SSD, plus source, assets, and caches

Isaac Sim needs a dedicated NVIDIA GPU with RT Cores; AMD, Intel, and older NVIDIA GPUs without RT Cores are unsupported. Host-only commands and tests need no GPU.

SRB supports linux/amd64 with NVIDIA RTX. Linux arm64/aarch64 installers are untested and unsupported.

NVIDIA Isaac Sim 6.1 tested baseline

NVIDIA’s Isaac Sim 6.1 requirements specify this x86_64 baseline:

ComponentNVIDIA tested baseline
OSUbuntu 22.04/24.04
CPU4 cores (Intel Core i7 7th generation or AMD Ryzen 5 minimum)
RAM32 GB
GPUGeForce RTX 4080 minimum
VRAM16 GB
Storage50 GB SSD
Linux driver595.58.03

Training and large sensor scenes need more RAM and VRAM. GPUs without RT Cores, including A100/H100, are unsupported. NVIDIA aarch64 support is limited to DGX Spark (DGX OS 7, driver 580.159.03); SRB does not support it.

Software Requirements

SRB requires Linux and an NVIDIA driver appropriate for the GPU. Other operating systems are unsupported.

ComponentRequirement
OS (Native Installation)Ubuntu 22.04/24.04, x86_64
OS (Docker Installation)Linux (X11 required only for GUI workflows)
NVIDIA DriverAppropriate for the GPU; see NVIDIA’s tested Isaac Sim 6.1 baseline above
Python3.12.*
Isaac SimSource VERSION 6.1.0-rc.26, built from commit 7c206f75bdadd9e05fc457f19863ca4c3f0cb693
Isaac Lab3.0.0 (release/3.0.0) at fdc650c88dfd86aa158b9a1760b6537fef360555
ROS 2Jazzy, installed and sourced separately when ROS workflows are used

SRB builds Isaac Sim from source and installs Isaac Lab in that Python environment. Docker also supports NVIDIA’s NGC Isaac Sim image, with different paths, UID, and cache ownership; SRB workflows use the source image.

NVIDIA Driver

Install the NVIDIA driver using NVIDIA’s official guide or your distribution’s package manager.

Next: Installation

Installation

Clone the repository with submodules, then follow one installation guide:

git clone --recurse-submodules https://github.com/AndrejOrsula/space_robotics_bench.git
cd space_robotics_bench
MethodUse whenLimits
Docker (Recommended)Simple, reproducible installation and updates; helper scripts for GUI, headless, and ephemeral sessions; least-privilege profile for lightweight commands.Moderate development experience (via Dev Containers). Isaac Sim’s trusted profile grants host-adjacent access (not suitable for HPC).
NativeFull system integration (documented path) and a smooth development experience.Complex setup; potential dependency conflicts; untested.
Apptainer/SingularityHPC deployment.Requires local Docker to build the Apptainer image (.sif); limited interactive development support; untested.

Use Docker with a locally built image or a release image pinned by its full sha256 digest. Do not pipe a mutable branch’s setup script into a shell: clone or authenticate and inspect the runner first. See system requirements for platform support and simulator pins.

Installed wheel support

Wheels support data and CLI commands that need no simulator assets or repository files. CLI dependencies need pip install "srb[cli]"; the base wheel omits them but includes the srb entry point and hyperparameter resources. srb test, srb doc, and simulator-launching commands need a source checkout; simulator commands also work in an SRB container with assets. Clone tagged releases with submodules, e.g. git clone --recurse-submodules --branch 0.1.0 https://github.com/AndrejOrsula/space_robotics_bench.git. GitHub source archives omit submodules and simulator assets.

Wheel runs log to logs/ in the current directory. Cache defaults to $XDG_CACHE_HOME/srb (~/.cache/srb if XDG_CACHE_HOME is unset, empty, or relative); set SRB_CACHE_ROOT to change it.

Temporary Docker sessions

The runner uses --rm, so the container filesystem is discarded on exit. See the Docker installation guide for runner profiles and image requirements.

Next: Docker installation

Installation — Native

Native installs are untested and need manual work. Builds use Isaac Sim 6.1.0 and Isaac Lab 3.0.0 (system requirements). On Ubuntu 22.04, use uv Python 3.12; system Python is older. Use Isaac Sim’s python.sh for SRB and Isaac Lab.

1. Prepare the host

sudo apt-get update
sudo apt-get install -y git git-lfs gcc-11 g++-11 cmake build-essential curl unzip xz-utils python3 jq
curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.12
uv python find 3.12

Without sudo, install git-lfs locally and add ~/.local/bin to PATH:

mkdir -p ~/.local/bin /tmp/git-lfs-install
curl -sSL https://github.com/git-lfs/git-lfs/releases/download/v3.6.1/git-lfs-linux-amd64-v3.6.1.tar.gz -o /tmp/git-lfs.tar.gz
tar xzf /tmp/git-lfs.tar.gz -C /tmp/git-lfs-install
cp /tmp/git-lfs-install/git-lfs-*/git-lfs ~/.local/bin/
rm -rf /tmp/git-lfs.tar.gz /tmp/git-lfs-install

2. Initialize Git LFS

Run this before cloning, including after the local fallback:

git lfs install

3. Clone SRB

Initialize submodules, then run commands from the repository root:

git clone https://github.com/AndrejOrsula/space_robotics_bench.git
cd space_robotics_bench
git submodule update --init --recursive

4. Build Isaac Sim

Accept NVIDIA’s license before setting ACCEPT_EULA=Y. The build requires sudo, substantial time, and disk space.

ACCEPT_EULA=Y \
SRC_BRANCH=release/6.1 \
SRC_COMMIT_SHA=7c206f75bdadd9e05fc457f19863ca4c3f0cb693 \
  ./.docker/install/install_isaacsim.bash "$HOME/isaac-sim"

5. Configure the Isaac Sim environment

Copy the installer’s export VK_DRIVER_FILES=... line. It detects or creates the Vulkan ICD path. Add all exports to shell config, source it, and keep ~/.local/bin on PATH for CLI wrappers.

Environment Variables

ShellConfiguration filePATH commandOther exports
bash~/.bashrcexport PATH="$HOME/.local/bin:$PATH"export ISAACSIM_PYTHON="$HOME/isaac-sim/python.sh"; export ISAACSIM_PATH="$HOME/isaac-sim"; export ISAAC_PATH="$HOME/isaac-sim"; export CARB_APP_PATH="$HOME/isaac-sim/kit"; export EXP_PATH="$HOME/isaac-sim/apps"; export LD_PRELOAD="$HOME/isaac-sim/kit/libcarb.so"; export ISAACSIM_ASSET_ROOT="$HOME/isaac-sim/assets"; export ISAACSIM_ASSET_ROOT_PROFILE="isaac-sim-6.1"; export OMNI_KIT_ALLOW_ROOT="1"
zsh~/.zshrcexport PATH="$HOME/.local/bin:$PATH"Same export lines as bash
fishuniversal variablesfish_add_path "$HOME/.local/bin"set -Ux ISAACSIM_PYTHON "$HOME/isaac-sim/python.sh"; set -Ux ISAACSIM_PATH "$HOME/isaac-sim"; set -Ux ISAAC_PATH "$HOME/isaac-sim"; set -Ux CARB_APP_PATH "$HOME/isaac-sim/kit"; set -Ux EXP_PATH "$HOME/isaac-sim/apps"; set -Ux LD_PRELOAD "$HOME/isaac-sim/kit/libcarb.so"; set -Ux ISAACSIM_ASSET_ROOT "$HOME/isaac-sim/assets"; set -Ux ISAACSIM_ASSET_ROOT_PROFILE "isaac-sim-6.1"; set -Ux VK_DRIVER_FILES "/etc/vulkan/icd.d/nvidia_icd.json"; set -Ux OMNI_KIT_ALLOW_ROOT "1"

For bash/zsh, append with cat >> ~/.bashrc << 'EOF' or cat >> ~/.zshrc << 'EOF', close EOF, and source the file. In fish, set VK_DRIVER_FILES to the ICD path printed by the installer; the example above uses a common path. ISAACSIM_ASSET_ROOT defaults to $HOME/isaac-sim/assets; use the printed root and profile.

Vulkan ICD locationUse
/usr/share/vulkan/icd.d/nvidia_icd.jsonCommon with Ubuntu driver packages
/etc/vulkan/icd.d/nvidia_icd.jsonCreated by the script if neither existing path is found

6. Install Isaac Lab

Install the pinned Isaac Lab source. Its script resolves NumPy conflicts and installs array_api_compat.

SRC_BRANCH=release/3.0.0 \
SRC_COMMIT_SHA=fdc650c88dfd86aa158b9a1760b6537fef360555 \
  ./.docker/install/install_isaaclab.bash "$HOME/isaaclab"

7. Install Blender and SimForge

Follow Blender’s official Linux instructions, then use SRB’s Blender installer for Blender 4.5 and SimForge:

./.docker/install/install_blender.bash "$HOME/blender"

Installer downloads Blender, links ~/.local/bin/blender, installs Docker-pinned simforge[dev] 0.4.0 and simforge-foundry 0.3.1 in Blender Python, checks exact pins before download, then applies SRB’s Isaac Lab compatibility patch (.docker/install/patch_simforge_isaaclab.bash). Avoid Snap: it blocks Python dependency integration.

8. Install optional RL frameworks

Source your shell configuration first; most scripts require ISAACSIM_PYTHON.

FrameworkCommandBehavior / limit
DreamerV3./.docker/install/install_dreamerv3.bash "$HOME/dreamerv3"Editable source install
TD-MPC2./.docker/install/install_tdmpc2.bash "$HOME/tdmpc2"Clones source only; install dependencies such as tensordict and torchrl later via pyproject.toml
robomimic./.docker/install/install_robomimic.bash "$HOME/robomimic"Pins upstream; applies Docker-matching lazy-language patch (srb/integrations/robomimic/patches/); verifies revision before install and prevents offline language-model downloads
rsl_rl./.docker/install/install_rsl_rl.bash "$HOME/rsl_rl"Source install

The TD-MPC2 script pins upstream and applies srb/integrations/tdmpc2/patches/, including the Q-ensemble initialization fix. It skips upstream’s dependency-pin commit to avoid downgrading Isaac Sim Torch/TensorDict/TorchRL. SRB rejects checkouts without the backport; use this script or the error’s pin, never plain git clone.

Set TDMPC2_PATH:

# Bash
echo "export TDMPC2_PATH='$HOME/tdmpc2/tdmpc2'" >> ~/.bashrc && source ~/.bashrc
# Zsh
echo "export TDMPC2_PATH='$HOME/tdmpc2/tdmpc2'" >> ~/.zshrc && source ~/.zshrc
# Fish
set -Ux TDMPC2_PATH "$HOME/tdmpc2/tdmpc2"

The robomimic checkout remains in place; no SRB extra includes it.

9. Install SRB

Install SRB with optional dependencies for all workflows:

"$ISAACSIM_PYTHON" -m pip install --editable ".[all]"

Adjust the all extra in pyproject.toml as needed. Published metadata rejects direct Git references, so extras omit Git-pinned upstreams; install robomimic in step 8. all omits the v2e event-camera backend and E2VID reconstruction operator. Install these pinned groups with bundled pip 25.1 or newer:

"$ISAACSIM_PYTHON" -m pip install --upgrade 'pip>=25.1'
"$ISAACSIM_PYTHON" -m pip install --editable ".[event-v2e,event-reconstruction]" --group source-event-v2e --group source-event-reconstruction

10. Set up the CLI

Put executable ISAACSIM_PYTHON and its destination (default ~/.local/bin) on PATH. Setup uses ISAACSIM_PYTHON or fallback python3 for SRB’s Hydra completion cache. register-python-argcomplete lookup checks Isaac Sim, system PATH, then Isaac Sim’s Python package.

./.docker/helpers/setup_cli.bash
# Regenerate completions only for these shells
./.docker/helpers/setup_cli.bash --completions-only bash zsh fish
srb completions generate
srb completions install
exec "$SHELL" -l

The setup script copies srb, simforge, and space_robotics_bench shims to ~/.local/bin and configures detected shells; it exits with an error when no requested shell gets completions. Hydra override completions need jq. If setup fails or shims are skipped, run "$ISAACSIM_PYTHON" -m srb.

11. Verify the installation

The first Isaac Sim launch takes longer while shaders compile. See Troubleshooting for failures.

ComponentCheck
Isaac Sim"$ISAACSIM_PYTHON" -c "
from isaacsim import SimulationApp
sim = SimulationApp({'headless': True})
print('Isaac Sim OK — is_running:', sim.is_running())
sim.close()
"
Isaac Lab"$ISAACSIM_PYTHON" -m pip show isaaclab
Blenderblender --version
SRB and CLI"$ISAACSIM_PYTHON" -m srb --help; command -v srb; srb --help; "$ISAACSIM_PYTHON" -m srb cache update
Quick simulation"$ISAACSIM_PYTHON" -m srb agent zero --headless -e sample_collection --cfg ignore --perf --perf_duration 10; confirm the final performance report includes steps per second

Troubleshooting

“Failed to create any GPU devices”

Symptom: Isaac Sim cannot create a GPU device. Cause: VK_DRIVER_FILES does not point to a valid Vulkan ICD file. Fix: Check the configured path, then set it to the existing ICD file.

ls -la "$VK_DRIVER_FILES"
find /etc/vulkan /usr/share/vulkan -name "nvidia_icd.json" 2>/dev/null

Update VK_DRIVER_FILES in your shell configuration.

“Application failed to start”

Symptom: Isaac Sim fails to start. Cause: DISPLAY is unset. Fix: On a headless server, set it for the virtual display:

# Bash/Zsh
echo 'export DISPLAY=:99' >> ~/.bashrc  # or ~/.zshrc
# Fish
set -Ux DISPLAY :99

numpy version conflicts

Symptom: NumPy version errors return. Cause: Manual package changes reintroduced conflicts after the installer resolved them. Fix: Install compatible packages:

"$ISAACSIM_PYTHON" -m pip install "numpy>=2.1" array_api_compat

Extras

Development

See IDE configuration.

Next: Basic Usage

Installation — Docker (Recommended)

Docker isolates SRB. Its source image builds the Isaac Sim and Isaac Lab versions in system requirements. Headless runtime and task catalog are tested; GUI and WebRTC are untested.

1. Clone the Repository

git clone --recurse-submodules https://github.com/AndrejOrsula/space_robotics_bench.git
cd space_robotics_bench

2. Install Docker Engine & NVIDIA Container Toolkit

Follow the official Docker Engine, Linux post-install, and NVIDIA Container Toolkit instructions. Interactive use needs a working host NVIDIA driver (nvidia-smi). GUI forwarding also needs xauth (sudo apt-get install -y xauth) and an X11 session with DISPLAY set. Run the pinned installer:

./.docker/host/install_docker.bash
InstallerDefault / limits
HostUbuntu 22.04/24.04; amd64/arm64. Verifies Docker (and, when installing the toolkit, NVIDIA) repository key fingerprints; refuses unavailable versions.
DockerEngine/CLI 29.8.0; containerd.io 2.3.6; Buildx 0.37.1; Compose 5.6.0; rootless extras 29.8.0. Override with SRB_DOCKER_CE_VERSION, SRB_DOCKER_CLI_VERSION, SRB_DOCKER_CONTAINERD_VERSION, SRB_DOCKER_BUILDX_VERSION, SRB_DOCKER_COMPOSE_VERSION, SRB_DOCKER_ROOTLESS_EXTRAS_VERSION.
NVIDIA Container Toolkit1.20.0 when a working GPU is detected. Override with SRB_NVIDIA_TOOLKIT_VERSION; set SRB_INSTALL_NVIDIA_TOOLKIT=false on CPU-only hosts.
Docker groupNon-interactive calls add membership only with SRB_ADD_DOCKER_GROUP=true.

Start a new login session after adding the user to the docker group for passwordless Docker. Until then, SRB helpers use sudo docker ... as needed.

3. Run

Build the image and start the runner:

SRB_IMAGE_NAME=space_robotics_bench ./.docker/build.bash 6.1.0
export SRB_DOCKER_IMAGE='space_robotics_bench:6.1.0'
./.docker/run.bash

Local tags resolve to immutable image IDs; missing tags fail without remote fallback. Default safe is interactive, isolates networking/IPC, drops capabilities, and has no host devices or mounts. Use it for lightweight commands without Isaac Sim:

DOCKER_TTY=false ./.docker/run.bash srb --help

For remote releases, provide the complete registry digest; mutable tags are rejected:

SRB_DOCKER_IMAGE='<registry>/<image>@sha256:<64-hex-digest>' ./.docker/run.bash srb --help

Keep the image reference consistent across run.bash, dev.bash, and any join/HPC wrapper used together.

Isaac Sim requires GPU access and host networking for ROS 2 discovery and livestreaming. When an NVIDIA GPU is detected or force-enabled, simulator exposes all host-visible NVIDIA GPUs; the runner has no per-GPU selector. Select simulator:

SRB_DOCKER_PROFILE=simulator ./.docker/run.bash

Unprivileged simulator enables no-new-privileges, NVIDIA runtime when an NVIDIA GPU is detected or force-enabled, /dev/dri when available on the host, host networking/IPC, writable simulator caches, GUI forwarding/history, and writable /root/ws; it neither uses --privileged nor mounts full /dev. Disable host networking or use private IPC with explicit shared memory (default 8g):

# Bridge networking (no ROS 2 multicast discovery with host nodes)
SRB_DOCKER_PROFILE=simulator WITH_HOST_NETWORK=false ./.docker/run.bash

# Private IPC namespace with an explicit /dev/shm size (default 8g)
SRB_DOCKER_PROFILE=simulator WITH_HOST_IPC=false SRB_DOCKER_SHM_SIZE=16g ./.docker/run.bash

trusted-simulator enables --privileged, mounts all /dev, and prints a security warning. Use only with a locally trusted image or authenticated digest for hardware passthrough (cameras, serial adapters, joysticks):

SRB_DOCKER_PROFILE=trusted-simulator ./.docker/run.bash

Useful variants:

# Headless simulator session
SRB_DOCKER_PROFILE=simulator WITH_GUI=false ./.docker/run.bash

# Without GPU and GUI, for commands that do not launch Isaac Sim
SRB_DOCKER_PROFILE=simulator WITH_GPU=false WITH_GUI=false ./.docker/run.bash

# Simulator without writable source or shell history
SRB_DOCKER_PROFILE=simulator WITH_DEV_VOLUME=false WITH_HISTORY=false ./.docker/run.bash

# Force the NVIDIA runtime when GPU detection fails (diagnostics only)
SRB_DOCKER_PROFILE=simulator WITH_GPU_FORCE_NVIDIA=true ./.docker/run.bash

# Non-interactive command execution, for CI and scripts
DOCKER_TTY=false ./.docker/run.bash bash -lc "srb --help"

Pass variables with -e; bare -e NAME forwards secrets. Exported caller variables use a private temporary env file hidden from Docker’s command line and ps. Invalid entries exit 2: empty names, whitespace or leading # in names, invalid bare-name identifiers, or newline values. Errors expose only entry position and length. Docker applies -e before the entrypoint adds PYTHONPATH, LD_LIBRARY_PATH, PATH, and ROS entries; override them inside the command.

While the container runs, join from another terminal:

./.docker/join.bash

Both scripts accept a trailing command:

SRB_DOCKER_PROFILE=simulator ./.docker/run.bash bash
./.docker/join.bash 0 fish

4. Verify Installation

Verify inside the container; see Troubleshooting for help.

Isaac Sim

If using default safe, restart from the host with SRB_DOCKER_PROFILE=simulator ./.docker/run.bash, check GPU visibility, then launch Isaac Sim:

nvidia-smi
"$HOME/isaac-sim/isaac-sim.sh"

The first launch may take longer during shader compilation and environment setup.

Space Robotics Bench

srb --help
srb cache update

srb cache update launches Isaac Sim and builds the offline task catalog, which enables tab completion of task names and overrides. The simulator profile mounts the repository at /root/ws, so the catalog persists in .cache/ across containers.

GUI Forwarding

echo "$DISPLAY"
test -n "$XAUTHORITY" && ls -l "$XAUTHORITY"

Extras

Build a New Docker Image

Build a custom image with the script:

./.docker/build.bash

Build RUN steps use bridge networking and daemon DNS by default.

Symptom: Could not resolve host: github.com or uv reports operation timed out during a build.

Cause: VPN-only, split-horizon, or loopback stub DNS (such as systemd-resolved at 127.0.0.53) can block bridge DNS.

Fix: Auto mode probes bridge DNS and uses --network host with a warning only when lookup completes without a matching host; other failures stop. Set SRB_BUILD_NETWORK to any docker build --network value:

SRB_BUILD_NETWORK=default ./.docker/build.bash  # keep the bridge, fail loudly
SRB_BUILD_NETWORK=host ./.docker/build.bash     # skip the probe, always host

Forwarded --network takes precedence. For a durable fix, set reachable "dns" in /etc/docker/daemon.json and restart Docker.

Isaac Lab 3.0 pins runtime deps in root pyproject.toml; extensions declare none. Builds install extensions editable, then root deps via .docker/helpers/isaaclab_root_requirements.py (requirements/overrides). Documented omissions: Newton viewer (SRB is PhysX-only; PhysX articulations import newton); Isaac Lab’s transformers pin (SRB lock selects another via robomimic); rsl-rl-lib (already locked). RSL_RL_DEV=true replaces the locked library with an editable checkout at RSL_RL_COMMIT_SHA (off by default).

Image Dependencies

Dockerfile exports committed uv.lock with --frozen --all-extras --group image-runtime --group vcs-sources, then installs the editable project with --no-deps. image-runtime locks shared simulator/framework deps; vcs-sources pins Git robomimic, v2e, and e2vid, which PyPI metadata rejects. Neither is a published SRB extra. Registry artifacts retain lock hashes; Git sources use full commit refs. By default, ROBOMIMIC_DEV=true omits robomimic for the patched checkout; pinned checkouts are explicit build inputs. Arm64 omits unavailable usd-core and uses bundled USD.

The robomimic checkout lazily patches e10526b9a40c78b41f1e37e60041dc0ec0a5f60f; builds verify 9e88eb3288079c6014f912e8d805c76dcd40157a. Low-dimensional dataset imports/learning need no CLIP weights; language observations need the model and tokenizer.

After changing Isaac Sim or Isaac Lab pins, rebuild and remove old-pin caches with srb clean.

Optional NVIDIA NGC Isaac Sim Image

The ngc profile runs NVIDIA’s official Isaac Sim 6.1 image (nvcr.io/nvidia/isaac-sim), pinned to an architecture-specific digest:

SRB_DOCKER_PROFILE=ngc SRB_NGC_MODE=headless ./.docker/run.bash

Modes are SRB_NGC_MODE=headless (default), webrtc, and gui, with ngc-headless, ngc-webrtc, and ngc-gui shorthand profiles. The container runs as UID 1234:1234; Isaac Sim is at /isaac-sim, and the checkout is at /workspace. ACCEPT_EULA=Y accepts NVIDIA’s license unless overridden. Writable caches use SRB_NGC_CACHE_DIR (default ~/.cache/space_robotics_bench/ngc/isaac-sim-6.1/<arch>). WebRTC needs host networking; GUI mode needs a real display. SRB tasks, ROS 2, and Rust are untested.

NGC always requires an RTX-class GPU; other profiles opt in with SRB_REQUIRE_RTX=true. Preflight checks NVIDIA hardware ray tracing with vulkaninfo (VK_KHR_ray_tracing_pipeline, VK_KHR_acceleration_structure), not product names: L40S, A40, GB10 qualify; GTX/software devices do not. Errors distinguish missing/failed vulkaninfo, no device, or no ray-tracing device. GUI merges X credentials to user-owned ${TMPDIR:-/tmp}/srb-xauth-<project>-<user>/Xauthority.

Join a Running Container

Use the join script:

./.docker/join.bash

For multiple containers, choose a listed index. Set SRB_CONTAINER_NAME as for run.bash; only <name> and <name><digits> appear, excluding NGC. Set DOCKER_TTY=false in CI/scripts to avoid docker exec --tty failing with the input device is not a TTY.

DOCKER_TTY=false ./.docker/join.bash 0 bash -lc "srb --help"

Development

Simulator, trusted-simulator, and development profiles mount the workspace, so edits persist on the host; safe does not. For development, open a Dev Container.

Use ./.docker/dev.bash for development variables or bind mounts. It wraps run.bash with unprivileged simulator; SRB_DOCKER_PROFILE=trusted-simulator adds --privileged and /dev (security warning). LOG_LEVEL defaults to info; set LOG_LEVEL=debug ./.docker/dev.bash ... for verbose Isaac/SimForge startup logs.

The wrapper shell places mounted /root/ws before the ROS overlay on PYTHONPATH, so srb subprocesses find checkout modules without rebuilding. On exit, created checkout files (such as .cache/, logs/, outputs/) return to the host user. SRB_DOCKER_DEV_WRAPPER=false runs commands as given.

Rust caches persist across containers. Host Cargo registry, Git, and target caches default to ~/.cache/space_robotics_bench/docker. Container builds use CARGO_TARGET_DIR=/root/.cache/srb/cargo-target, preserving image artifacts in /root/.cargo/target. Override the host cache with SRB_DOCKER_CACHE_DIR=/path/to/cache ./.docker/dev.bash ... or the container target with SRB_CARGO_TARGET_DIR=/path/in/container ./.docker/dev.bash ...; do not set the latter to /root/.cargo/target.

Next: Basic Usage

Installation — Apptainer/Singularity

Build the .sif from the Docker image, which pins Isaac Sim and Lab (requirements), then transfer it to the cluster.

Setup (Local)

Apptainer installs are untested.

1. Clone the repository

Clone from the repository root:

git clone --recurse-submodules https://github.com/AndrejOrsula/space_robotics_bench.git
cd space_robotics_bench

2. Install Docker Engine and NVIDIA Container Toolkit

Install Docker Engine, follow its Linux post-install steps, and install NVIDIA Container Toolkit. Or run the pinned helper:

./.docker/host/install_docker.bash

The helper supports Ubuntu 22.04/24.04 amd64/arm64, verifies key fingerprints, and pins Docker Engine/CLI 29.8.0 and optional NVIDIA Container Toolkit 1.20.0. Docker’s guide covers version overrides and non-interactive group behavior.

3. Install Apptainer

Follow Apptainer installation instructions or install on Ubuntu:

sudo add-apt-repository -y ppa:apptainer/ppa
sudo apt update
sudo apt install -y apptainer

4. Build the Apptainer Image

Run the build script:

./.docker/hpc/build.bash 6.1.0

This builds a tagged Docker image and converts it to .docker/hpc/images/space_robotics_bench.sif.

5. Record image details

Before transfer, record its source digest and architecture, plus SIF metadata and checksum:

docker image inspect --format '{{.Id}} {{.Architecture}}' space_robotics_bench:6.1.0 # prefix '<user>/' if `docker info` lists a Username
apptainer inspect .docker/hpc/images/space_robotics_bench.sif
sha256sum .docker/hpc/images/space_robotics_bench.sif

A docker info username prefixes the image tag: <username>/space_robotics_bench:6.1.0.

Deployment (HPC Cluster)

1. Transfer repository and image

Choose one method:

scp -r /path/to/space_robotics_bench user@hpc-cluster:/path/to/space_robotics_bench
rsync -avr /path/to/space_robotics_bench user@hpc-cluster:/path/to/space_robotics_bench

2. Connect to the cluster

ssh user@hpc-cluster

3. Run the image

On a module node, adjust run.bash. The script loads tools/Singularity and calls singularity. Because singularity exec skips the Docker entrypoint, the script sources /entrypoint.bash (ROS Jazzy).

/path/to/space_robotics_bench/.docker/hpc/run.bash bash
SettingBehavior
Mount / cachesSource image: checkout at /root/ws; caches under ${SCRATCH:-$HOME}/volumes/space_robotics_bench/. NGC image: checkout at /workspace (override with SRB_NGC_WORKSPACE); caches under ${SCRATCH:-$HOME}/volumes/space_robotics_bench/ngc/isaac-sim-6.1/<arch> (override with SRB_NGC_CACHE_DIR).
WITH_GPUDefaults true (--nv); false omits passthrough but keeps Isaac Sim in the image.
CommandArguments follow run.bash; bash opens an interactive shell.

For NGC images:

SettingBehavior
IMAGE_PATHRequired for NGC; set it when .sif is outside .docker/hpc/images/.
ProvenanceChecks the recorded SIF checksum on each run; large files may take longer.
SRB_NGC_CACHE_OWNERSHIPuser (default) or skip; the invoking user runs Singularity and owns caches.
Paths, digest, and RTXSets ISAACSIM_PATH=/isaac-sim; requires an NGC SIF via IMAGE_PATH and checks its recorded digest and checksum. The RTX check matches Docker NGC preflight.

Use the target architecture’s <arch digest> for both NGC commands. From the repository root:

SRB_DOCKER_PROFILE=ngc IMAGE_PATH=X.sif ./.docker/hpc/run.bash bash
apptainer build X.sif docker://nvcr.io/nvidia/isaac-sim@sha256:<arch digest>
ref='nvcr.io/nvidia/isaac-sim@sha256:<arch digest>'
printf 'source=%s\nsif_sha256=%s\n' "$ref" "$(sha256sum X.sif | cut -d' ' -f1)" > X.sif.ngc-source
/path/to/space_robotics_bench/.docker/hpc/run.bash bash -lc '
source /opt/ros/jazzy/setup.bash
export ROS_DOMAIN_ID=0
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
printf "%s\n" "$ROS_DISTRO" "$AMENT_PREFIX_PATH" "$LD_LIBRARY_PATH" "$RMW_IMPLEMENTATION" "$ROS_DOMAIN_ID"
srb agent ros --headless -e peg_in_hole
'

HPC GUI and WebRTC sessions are untested.

4. Verify Installation

In the container, see Troubleshooting.

Isaac Sim

nvidia-smi
"${ISAACSIM_PATH:-$HOME/isaac-sim}/isaac-sim.sh"

Initial launch may take longer because Isaac Sim compiles shaders and prepares the environment.

Space Robotics Bench

Check the SRB cache and interpreter:

srb --help
srb cache update
"${ISAACSIM_PATH:-$HOME/isaac-sim}/python.sh" -c "import isaacsim; print(isaacsim.__file__)"
"${ISAACSIM_PATH:-$HOME/isaac-sim}/python.sh" -c "import srb; print(srb.__file__)"
srb --help

isaacsim and srb paths must share an installation; the last command runs the srb found on PATH. SRB has no --version command.

Extras

Schedule a SLURM Job

Adjust the cluster SLURM script:

/path/to/space_robotics_bench/.docker/hpc/submit.bash [CMD]

It writes under $HOME/jobs/ by default and submits with sbatch. Review the partition, constraint, memory, wall time, and GPU settings.

Next: Basic Usage

Basic Usage

After installation, list registries and run an environment:

Native installation: If srb is unavailable, run:

"$ISAACSIM_PYTHON" -m srb --help

1. List Assets, Actions & Environments

Reference: srb ls — List Assets and Environments

srb ls --live

Use --live for headless Isaac Sim discovery and cache refresh; plain srb ls prints cached names. See the CLI reference for categories and options.

Live tables list assets (scenery, objects, robots), action groups, hardware interfaces, and environments. Hardware interface examples are not validated on hardware.

1. Assets (click to expand)

Scenery asset (automatically registered as “mars_surface” scenery/terrain)

class MarsSurface(Terrain):
    ## Scenario - The asset is suitable for the Mars domain
    DOMAINS: ClassVar[Sequence[Domain]] = (Domain.MARS,)

    ## Source selector — opt in to real DEMs by passing `source="real"`.
    source: Literal["procedural", "real"] = "procedural"
    site: str = "jezero"

    ## Model - filled in model_post_init
    asset_cfg: AssetBaseCfg | None = None  # type: ignore[assignment]

    def _build_procedural_asset_cfg(self) -> AssetBaseCfg:
        return AssetBaseCfg(
            prim_path="{ENV_REGEX_NS}/mars_surface",
            ## Spawner procedurally generates SimForge models
            spawn=SimforgeAssetCfg(
                assets=[simforge_foundry.MarsSurface()],
                collision_props=CollisionPropertiesCfg(),
                # Static triangle-mesh collision is required; otherwise
                # particles and objects fall through the SimForge mesh.
                mesh_collision_props=MeshCollisionPropertiesCfg(
                    mesh_approximation="none"
                ),
            ),
        )

    def model_post_init(self, __context):
        # Build first so the parent forwards density, scale, and texture
        # settings to the newly constructed spawner config.
        self.asset_cfg = resolve_surface_asset_cfg(
            surface_name=self.__class__.__name__,
            body="mars",
            site=self.site,
            source=self.source,
            build_procedural_asset_cfg=self._build_procedural_asset_cfg,
            build_real_asset_cfg=build_real_terrain_asset_cfg,
        )
        super().model_post_init(__context)

Object asset (automatically registered as “sample_tube” object/common)

class SampleTube(Object):
    ## Model - Rigid object affected by physics
    asset_cfg: RigidObjectCfg = RigidObjectCfg(
        prim_path="{ENV_REGEX_NS}/sample",
        ## Spawner loads a static USD file
        spawn=UsdFileCfg(
            usd_path=(
                SRB_ASSETS_DIR_SRB_OBJECT.joinpath("sample_tube.usdc").as_posix()
            ),
            collision_props=CollisionPropertiesCfg(),
            mesh_collision_props=MeshCollisionPropertiesCfg(
                mesh_approximation="convexDecomposition"
            ),
            rigid_props=RigidBodyPropertiesCfg(),
            mass_props=MassPropertiesCfg(density=1500.0),
        ),
    )

Robot asset (automatically registered as “franka” robot/manipulator)

class Franka(SerialManipulator):
    ## Model - Articulation with several links connected by joints
    asset_cfg: ArticulationCfg = ArticulationCfg(
        prim_path="{ENV_REGEX_NS}/franka",
        ## Spawner loads a static USD file
        spawn=UsdFileCfg(
            usd_path=SRB_ASSETS_DIR_SRB_ROBOT.joinpath("manipulator")
            .joinpath("franka_arm.usdz")
            .as_posix(),
            ...
        ),
        ## Initial joint configuration of the robot
        init_state=ArticulationCfg.InitialStateCfg(
            joint_pos={
                "panda_joint1": 0.0,
                "panda_joint2": 0.0,
                "panda_joint3": 0.0,
                "panda_joint4": radians(-90.0),
                "panda_joint5": 0.0,
                "panda_joint6": radians(90.0),
                "panda_joint7": radians(45.0),
            },
        ),
        ...
    )
    ## End effector - The default hand is separate to allow for easy replacement
    end_effector: Tool | None = FrankaHand()

    ## Action modes — coded-in alternatives selectable via
    ## `env.robot.action_mode=<key>`. The first entry is the default.
    action_modes: ClassVar[dict[str, ActionGroup]] = {
        "diff_ik": InverseKinematicsActionGroup(
            DifferentialInverseKinematicsActionCfg(
                asset_name="robot",
                joint_names=["panda_joint[1-7]"],
                base_name="panda_link0",
                body_name="panda_link7",
                controller=DifferentialIKControllerCfg(
                    command_type="pose",
                    use_relative_mode=True,
                    ik_method="dls",
                ),
                scale=0.1,
                body_offset=DifferentialInverseKinematicsActionCfg.OffsetCfg(),
            ),
        ),
        "osc_fixed": OperationalSpaceControlActionGroup(
            OperationalSpaceControllerActionCfg(
                asset_name="robot",
                joint_names=["panda_joint[1-7]"],
                body_name="panda_link7",
                controller_cfg=OperationalSpaceControllerCfg(
                    target_types=["pose_rel"],
                    impedance_mode="fixed",
                    motion_stiffness_task=100.0,
                    motion_damping_ratio_task=1.0,
                    nullspace_control="position",
                    inertial_dynamics_decoupling=True,
                ),
                nullspace_joint_pos_target="center",
                position_scale=0.1,
                orientation_scale=0.1,
                body_offset=OperationalSpaceControllerActionCfg.OffsetCfg(),
            )
        ),
        "osc_var_stiffness": OperationalSpaceControlActionGroup(
            OperationalSpaceControllerActionCfg(
                asset_name="robot",
                joint_names=["panda_joint[1-7]"],
                body_name="panda_link7",
                controller_cfg=OperationalSpaceControllerCfg(
                    target_types=["pose_rel"],
                    impedance_mode="variable_kp",
                    motion_stiffness_limits_task=(10.0, 250.0),
                    motion_damping_ratio_task=1.0,
                    nullspace_control="position",
                    inertial_dynamics_decoupling=True,
                ),
                nullspace_joint_pos_target="center",
                position_scale=0.1,
                orientation_scale=0.1,
                stiffness_scale=120.0,
                body_offset=OperationalSpaceControllerActionCfg.OffsetCfg(),
            )
        ),
        "osc_var_full": OperationalSpaceControlActionGroup(
            OperationalSpaceControllerActionCfg(
                asset_name="robot",
                joint_names=["panda_joint[1-7]"],
                body_name="panda_link7",
                controller_cfg=OperationalSpaceControllerCfg(
                    target_types=["pose_rel"],
                    impedance_mode="variable",
                    motion_stiffness_limits_task=(10.0, 250.0),
                    motion_damping_ratio_limits_task=(0.5, 2.5),
                    nullspace_control="position",
                    inertial_dynamics_decoupling=True,
                ),
                nullspace_joint_pos_target="center",
                position_scale=0.1,
                orientation_scale=0.1,
                stiffness_scale=120.0,
                damping_ratio_scale=1.0,
                body_offset=OperationalSpaceControllerActionCfg.OffsetCfg(),
            )
        ),
        "joint_pos_rel": JointPositionRelativeActionGroup(),
    }
    ...
    ## Frames - Relevant frames for attaching the robot and mounting tool/sensors
    frame_base: Frame = Frame(prim_relpath="panda_link0")
    frame_flange: Frame = Frame(
        prim_relpath="panda_link7",
        offset=Transform(
            pos=(0.0, 0.0, 0.107),
            rot=rpy_to_quat(0.0, 0.0, -45.0),
        ),
    )

2. Teleoperate a Robot

Reference: srb agent teleop — Teleoperate Agent

Collect Mars Sample Return tubes in sample_collection with the Franka manipulator:

srb agent teleop --env sample_collection

Isaac Sim opens; focus its window to use the terminal controls.

ControlKeys
ResetL
GainO decrease; P increase
EventR / K
TranslateW / S: +X / −X; A / D: −Y / +Y; Q / E: +Z / −Z
RotateZ / X: ±X; T / G: ↻ / ↺ about ±Y; C / V: ↺ / ↻ about ±Z

Note: Direct teleoperation uses high-level actions. Low-level joint tasks (e.g., locomotion_velocity_tracking) need a policy to map commands to actions; see Teleoperation via Policy.

Move to a Different Domain

Reference: Environment Configuration
Reference: Environment Configuration — Domain

Collect procedural moon_rock samples on the Moon with Hydra overrides:

srb agent teleop --env sample_collection env.domain=moon env.sample=moon_rock

3. Run Random Actions

Reference: srb agent rand — Random Agent

Run locomotion_velocity_tracking with random actions (default Spot):

srb agent rand --env locomotion_velocity_tracking

Hint: --hide_ui hides most of the Isaac Sim UI.

Change the Robot

Reference: Environment Configuration — Robot

Set env.robot to a legged robot or humanoid such as Unitree G1:

srb agent rand --env locomotion_velocity_tracking env.robot=unitree_g1

Simulate Multiple Robots

Reference: Environment Configuration — Parallelism

Run 16 Cassie instances in parallel:

srb agent rand -e locomotion_velocity_tracking env.robot=cassie env.num_envs=16

Hint: locomotion_velocity_tracking shares terrain by default (other tasks may differ). Set env.stack=false for unique terrain geometry and materials per robot. Set SF_BAKER=0 to skip texture baking and speed generation; unbaked surfaces render with a magenta placeholder material:

SF_BAKER=0 srb agent rand -e locomotion_velocity_tracking env.stack=false env.num_envs=16

4. Customize Environment Templates

Reference: Assets
Reference: Environment Configuration — Robot

Start custom scenarios from a robot-category template; sample_collection and locomotion_velocity_tracking are goal-oriented tasks.

Try _ground_manipulation with the Spot quadruped and Franka manipulator:

srb agent rand -e _ground_manipulation

Diversify Robot Configurations

Randomize Unitree quadrupeds (random_unitree_quadruped) and Universal Robots manipulators (random_ur_manipulator, UR3e–UR30); select mobile-manipulator parts via env.robot.mobile_base and env.robot.manipulator.

srb agent rand -e _ground_manipulation env.robot.mobile_base=random_unitree_quadruped env.robot.manipulator=random_ur_manipulator env.num_envs=6 env.stack=true

Customize Payloads & End Effectors

Reference: srb agent zero — Zero Agent

Use + in env.robot or its mobile-base/manipulator fields to attach Cargo Bay to Anymal D and pair Unitree Z1 with Shadow Hand:

srb agent zero -e _ground_manipulation env.robot.mobile_base=anymal_d+cargo_bay env.robot.manipulator=unitree_z1+shadow_hand

Hint: Both sides of + are required (for example, anymal_d+cargo_bay); omitting either side (+payload, +end_effector, mobile_robot+, or manipulator+) raises an error.

Task and domain determine supported combinations; sensor poses and action-space dimensions adjust automatically.

srb agent zero -e _aerial_manipulation env.robot.mobile_base=ingenuity env.robot.manipulator=franka+scoop
srb agent zero -e _orbital_manipulation env.robot.mobile_base=gateway env.robot.manipulator=canadarm3

5. Enable Cameras

Most tasks disable visual sensors for performance; some enable them by default. Where supported, add visual to env.active_sensors.

View the Ingenuity helicopter on Mars:

srb agent teleop -e _aerial 'env.active_sensors=[proprioception,contact,transform,visual]'
OverrideDefaultLimit or meaning
env.camera_resolution(64, 64)Width and height; tasks may override.
env.camera_data_types("rgb", "depth")Task configuration determines available types and may override RGB and depth defaults.
env.camera_update_period-1.0For cameras without an authored period, negative selects the agent rate.
env.camera_clipping_rangeNoneNear/far planes in metres; near must be positive, far greater than near and below 1000 m. Fills missing ranges or ranges with render-default far planes; preserves camera-authored ranges with far planes below 1000 m.

Next: Workflows

Workflows

Develop and validate algorithms, and generate synthetic data.

Available Workflows

Next: ROS 2 Workflow

ROS 2 Workflow

Connect SRB to ROS 2 or Space ROS for autonomy development and validation.

The active ROS 2 agent receives actions from ROS and steps the environment. The passive interface lets a workflow control actions while ROS publishes sensors and exposes services.

1. Start an Active ROS 2 Agent

Use srb agent ros with a batched Box action space:

srb agent ros -e peg_in_hole env.num_envs=2 'env.active_sensors=[proprioception,contact,transform,visual]'

For closed-loop control, --ros_sync awaits fresh actions after step one:

srb agent ros --ros_sync -e peg_in_hole env.num_envs=2 'env.active_sensors=[proprioception,contact,transform,visual]'

See the ROS agent reference for option details.

Debug with action and observation delays at zero:

srb agent ros --ros_sync -e waypoint_navigation env.action_delay_steps=0 env.observation_delay_steps=0

List Topics

Without local ROS 2, run .docker/join.bash, then list topics:

ros2 topic list
Topics (expand)
/clock
/parameter_events
/rosout
/srb/env0/action/cmd_vel
/srb/env0/action/event
/srb/env0/action/raw
/srb/env0/cam_base/camera_info
/srb/env0/cam_base/image_depth
/srb/env0/cam_base/image_rgb
/srb/env0/cam_base/pointcloud
/srb/env0/cam_scene/camera_info
/srb/env0/cam_scene/image_depth
/srb/env0/cam_scene/image_rgb
/srb/env0/cam_scene/pointcloud
/srb/env0/cam_wrist/camera_info
/srb/env0/cam_wrist/image_depth
/srb/env0/cam_wrist/image_rgb
/srb/env0/cam_wrist/pointcloud
/srb/env0/end_effector/joint_pos
/srb/env0/end_effector/joint_states
/srb/env0/reward
/srb/env0/reward/penalty_action_rate
/srb/env0/reward/penalty_undesired_robot_contacts
/srb/env0/reward/reward_align_peg_to_hole_primary
/srb/env0/reward/reward_align_peg_to_hole_secondary
/srb/env0/reward/reward_distance_ee_to_obj
/srb/env0/reward/reward_distance_peg_to_hole_bottom
/srb/env0/reward/reward_distance_peg_to_hole_entrance
/srb/env0/reward/reward_grasp
/srb/env0/reward/reward_lift
/srb/env0/robot/delta_twist
/srb/env0/robot/joint_states
/srb/env0/terminated
/srb/env0/truncated
/srb/env1/...          (mirrors env0)
/srb/envs/action/cmd_vel
/srb/envs/action/event
/srb/envs/action/raw
/srb/envs/end_effector/joint_pos
/srb/envs/robot/delta_twist
/tf
/tf_static

Namespaces:

  • /srb/env[0-N]/... targets one environment; /srb/envs/... targets all.

With env.num_envs=1, prefixes vanish, e.g. /srb/reward and /srb/action/cmd_vel.

TopicMessage TypeDescription
/clockrosgraph_msgs/ClockSimulation time
/tf, /tf_statictf2_msgs/TFMessageScene transforms
Control
**/{robot_name}/{action_name}Robot-specificRobot control; normalized policy actions (message fields are containers, not SI units)
**/action/rawstd_msgs/Float64MultiArrayFlat action vector in action-space order
**/action/cmd_velgeometry_msgs/TwistAvailable when the task action config supports direct commands
**/action/eventstd_msgs/BoolAvailable when the task action config supports direct commands
Perception
**/[{sensor_name}]/{data}Sensor-specificScene sensors
**/{robot_name}/joint_statessensor_msgs/JointStateArticulation joints
MDP
**/rewardstd_msgs/Float32Total reward
**/reward/{term_name}std_msgs/Float32Reward terms
**/terminatedstd_msgs/BoolTermination flag
**/truncatedstd_msgs/BoolTruncation flag

Subscribe to Topics

Echo env0’s reward:

ros2 topic echo /srb/env0/reward
data: 2.36441707611084
---
data: 2.3652756214141846
---
data: 2.36613130569458
---
data: 2.3669850826263428
---

Publish to Topics

Publish at 20 Hz:

ros2 topic pub --rate 20 /srb/envs/action/cmd_vel geometry_msgs/Twist "{linear: {z: -0.2}, angular: {z: 0.785}}"

2. Start the Passive ROS 2 Interface

Enable the passive interface with --interface ros. Run rand on eight multi_sample_collection instances with visual sensors:

srb agent rand -e multi_sample_collection env.num_envs=8 'env.active_sensors=[proprioception,contact,transform,visual]' --interface ros

--interface accepts multiple values; following Hydra key=value overrides forward automatically.

Call Services

Reset one via /srb/env{i}/reset, or all via /srb/envs/reset. Requests are queued and apply after the next step; with --ros_sync, that step waits for a fresh action.

ros2 service list

Reset one environment:

ros2 service call /srb/env0/reset std_srvs/srv/Empty
ros2 service call /srb/envs/reset std_srvs/srv/Empty

Next: Reinforcement Learning Workflow

Reinforcement Learning Workflow

1. Train your 1st RL Agent

Reference: srb agent train — Train Agent

Train online with srb agent train; offline algorithms use separate workflows.

Watch SBX PPO on landing; omit --headless:

srb agent train --algo sbx_ppo --env landing env.num_envs=512 --hide_ui

Check terminal progress; checkpoints save regularly. Usually stop with Ctrl+C.

2. Evaluate your Agent

Reference: srb agent eval — Evaluate Agent

srb agent eval --algo sbx_ppo --env landing env.num_envs=16
srb agent eval --algo sbx_ppo --env landing env.num_envs=16 --model logs/landing/sbx_ppo/${TIMESTAMP}/ckpt/${CHECKPOINT}

Note: SB3/SBX .zip checkpoints live in ckpt/.

3. Try a Different Algorithm

TypeFramework algorithms
Model-basedDreamerV3: dreamer; TD-MPC2: tdmpc2
On-policyStable-Baselines3 (SB3): sb3_a2c, sb3_ppo, sb3_ppo_lstm, sb3_trpo; SBX: sbx_ppo; RSL-RL: rsl_rl_ppo; skrl: skrl_a2c, skrl_ppo, skrl_ppo_rnn, skrl_rpo, skrl_trpo
Off-policySB3: sb3_ddpg, sb3_td3, sb3_sac, sb3_crossq, sb3_tqc; SBX: sbx_ddpg, sbx_td3, sbx_sac, sbx_crossq, sbx_tqc; skrl: skrl_ddpg, skrl_td3, skrl_sac
EvolutionarySB3: sb3_ars

skrl: Hyperparameter profiles are untuned starting points.

srb agent train --headless --algo <ALGO> --env landing env.num_envs=1024

Hint: --headless and more parallel environments can speed training.

4. Monitor Training Progress

Compare runs with TensorBoard; local artifacts and TensorBoard are on by default. W&B is opt-in:

tensorboard --logdir ./logs --bind_all
  • DreamerV3: srb agent train ... 'agent.logger.outputs=[tensorboard,wandb]'
  • SB3 & SBX: srb agent train ... +agent.wandb=true
  • skrl: srb agent train ... agent.agent.experiment.wandb=true

Note: W&B logging requires an account and API key.

Each run records its provenance and metrics; see Run records.

5. Configure Hyperparameters

Reference: Agent Configuration

srb agent train --algo dreamer      agent.run.train_ratio=128  ...
srb agent train --algo sb3_ppo      agent.gamma=0.99           ...
srb agent train --algo sbx_sac      agent.learning_rate=0.0002 ...
srb agent train --algo skrl_ppo     agent.models.separate=True ...

Next: Hyperparameter Tuning

Hyperparameter Tuning

Tune an algorithm with Optuna through srb agent tune. Install the tuning extra first:

uv sync --extra tune

Study modes

  1. Preflight a study. Run the check before a long search. It assembles a trial without Isaac. Omit --gpus; see CLI reference.

    srb agent tune check -e <env> --algo <algo> --trial-steps <n>
    
  2. Choose a study mode and run it.

    Single task: Tune one task and export its task config.

    srb agent tune run --env sample_collection --algo skrl_ppo \
      --trial-steps 20_000_000 --n-trials 40 --n-workers 2 --gpus 0,1
    

    Portfolio: Tune tasks sequentially, one child per segment. Divergence and running aggregates prune weak trials. Export globally. See portfolio details.

    srb agent tune run --tasks sample_collection peg_in_hole landing --algo skrl_ppo \
      --trial-steps 10_000_000 --n-trials 30 --normalize baseline --aggregate median
    

Inspecting and exporting

srb agent tune status --study srb-skrl_ppo-state-sample_collection-v1
srb agent tune export --study srb-skrl_ppo-state-sample_collection-v1 --to task --dry-run
srb agent tune export --study srb-skrl_ppo-state-sample_collection-v1 --to task

TPE’s one-seed default can make best_trial a lucky outlier. Use validate to rerun top trials with fresh seeds and rank by mean; see CLI reference.

Use --seeds-per-trial K to average distinct seeds during search. See its cost and pruning behavior in the CLI reference.

export records provenance and restores production budget and W&B flag. --to defaults to task for single-task, global for portfolios, where --to task is rejected. Review and commit the diff; see CLI reference for overwrite and shadow warnings.

Picking a trial budget (wall-clock worksheet)

Set --trial-steps where reference runs reach 50–70% of converged return. Production YAMLs may train until stopped (for example, 2e8). Estimate:

hours_per_trial ≈ trial_steps / (env_steps_per_second) / 3600 × n_tasks
study_hours     ≈ n_trials × hours_per_trial × seeds_per_trial / n_workers

Runtime depends on throughput, pruning, and worker overhead. At 40,000 env-steps/s, 20_000_000 steps take ~8.3 min/trial; 40 trials with 2 workers take ~2.8 h. At 5,000 env-steps/s, expect ~67 min/trial or ~22 h. Project with --fps, cap with --max-wall-hours, pilot 10–20 trials.

Config layering

Under hyperparams/, configs resolve task-specific to global by modality:

SlotScopeStateVisual
L0 / L0vGlobal<framework>/<algo>.yaml<framework>/<algo>_visual.yaml
L1 / L1vTask-specifictask/<task>/<framework>/<algo>.yamltask/<task>/<framework>/<algo>_visual.yaml

Pass --obs {state,visual} to train, eval, and tune for modality config and log directory (…/<algo>/ or …/<algo>-visual/). It prevents cross-loading and preserves the algorithm label. Visual tuning is unsupported; see Agent Configuration.

How it works

  1. The Isaac-free driver samples with study.ask() and launches train children in process groups: one per seed for single-task trials, and one per task segment per seed for portfolio trials. Each child boots Isaac.
  2. It writes full agent: config and env: seed and num_envs to trial_cfg.yaml. Children report episode statistics as JSONL; the driver counts total environment steps.
  3. Single-task studies report smoothed return at 20 rungs; portfolios report running aggregates at task-segment rungs. The terminal budget is reserved for the final objective and is not reported as a pruning rung. MedianPruner stops weak trials with killpg; crashes and timeouts FAIL, a non-finite reported return PRUNEs, and a missing or NaN final objective FAILs. The study continues; objective is the tail mean over the final training quarter.

Isolation contains VRAM failures and NaN physics. Worker processes across nodes share a journal.

Cross-task normalization

Trial user_attrs store each task’s raw and normalized score (seg/<task>/raw, seg/<task>/norm).

Parallelism and resuming

  1. Set --n-workers N slots per driver; --gpus 0,1 round-robins GPUs. Starts stagger to avoid Isaac shader-cache races until metrics arrive.
  2. Share logs/tune/<study>/journal.log across nodes; each SLURM array element is one worker, and Optuna assigns trials without scheduler integration.
  3. Rerun to resume; terminal and RUNNING trials count toward --n-trials. Changes to search space, budget, objective, obs mode, or task set need a new --version.
  4. Abrupt driver termination may leave trials RUNNING; handled cancellation marks active trials FAIL; repair with srb agent tune repair --study S --stale-hours H.
  5. Pruned child logdirs are deleted, including checkpoints and TensorBoard events. --keep-artifacts retains them; trial_cfg.yaml and metrics.jsonl remain.

Reproducibility

Each logs/tune/<study>/trials/<n>/ preserves config, seed (seed-base + trial × seeds-per-trial + replicate), and metadata. Replicates use rep-<k>/trial_cfg.yaml. metadata.json records study/trial; logs/tune/<study>/driver.json records host, pid, and start time. Records aid reconstruction, not identical results. See Agent Configuration.

Next: Imitation Learning

Imitation Learning Workflow

Collect expert demonstrations, train offline, evaluate, then deploy a compatible policy. SRB supports compatible tasks, datasets, and algorithms. Robomimic requires one environment and compatible observations and actions.

1. Collect demonstrations

Teleoperate the task and keep successful demonstrations. Follow the success rules.

srb agent collect --env peg_in_hole --num_episodes 50

The keyboard is the default. A 6-DoF SpaceMouse gives higher fidelity. An XR headset adds an immersive view, not input (Extended Reality).

srb agent collect --env peg_in_hole --teleop_device spacemouse

For collection defaults, success-only behavior, and dataset paths, see the srb agent collect reference.

2. Train an IL policy

Train offline; Isaac Sim is not needed. Pass --dataset. A fresh learn run directory does not find earlier collect/ data and errors if no dataset is supplied. Verified private HDF5 copies stay open until workers, handles, and logging close. Configured allocation limits are checked before provider reads. See limits, provenance, and --normalize_actions.

srb agent learn --algo robomimic_bc --env peg_in_hole \
  --dataset logs/peg_in_hole/collect/<timestamp>/datasets/demos_<timestamp>.hdf5

For the RNN variant, use robomimic_bc_rnn:

srb agent learn --algo robomimic_bc_rnn --env peg_in_hole \
  --dataset logs/peg_in_hole/collect/<timestamp>/datasets/demos_<timestamp>.hdf5

HDF5 stores per-step dones, terminated, and truncated. dones = terminated OR truncated marks episode boundaries. Value learners bootstrap through time-limit and collector-horizon truncations; they stop only on terminated. Robomimic bcq, cql, iql, td3_bc, and iris (BCQ value component) read dones and treat truncations as terminal.

3. Evaluate the policy

Evaluate a learn checkpoint:

srb agent eval --algo robomimic_bc --env peg_in_hole env.num_envs=1

Robomimic uses one environment:

  • Collection raises robomimic collection requires num_envs == 1 if configured otherwise.
  • Evaluation rejects num_envs != 1 with integration.robomimic.vector_env.unsupported.
  • Offline learn creates no environment.

Evaluation checks task success at rollout end. If the task has no success signal, it warns and reports success_rate: null, never 0%.

For normalized actions, checkpoint norm_factor_min and norm_factor_max restore the environment range. The caller cannot override this range. If the checkpoint lacks a range but the run directory has logs/normalization_params.txt, evaluation errors and requires retraining. Otherwise, it loads unscaled actions.

Nested observations use slash-joined training keys.

4. Deploy to hardware

Use IL for sim-to-real with a compatible task, checkpoint, and hardware interface. Hardware operation is unvalidated. See Sim-to-Real Transfer for real_agent gen and real_agent eval.

5. Optional: iterate

Augment with policy rollouts

Collect more demonstrations with a partially trained policy (DAgger-style). Apply the same --success_only rules as in step 1.

srb agent collect --algo robomimic_bc --env peg_in_hole \
  --num_episodes 200

Rerun srb agent learn on merged HDF5 files. It accepts one --dataset for union training.

Combine with RL

IL may not generalize to unseen conditions. Incompatible checkpoint formats prevent direct RL warm-starting. See the reinforcement learning workflow:

Next: Sim-to-Real Transfer

Sim-to-Real Transfer

Generate and verify a RealEnv bridge before running a simulation-trained policy with srb real_agent. This page covers adapter wiring and evaluation, not validated hardware operation; operators remain responsible for physical safety.

Runtime and reporting limits:

  • RealEnv checks every adapter before actions and post-action observations. Degraded fallback frames fail.
  • Transports are not physically atomic. A later send failure cannot undo earlier sends, so RealEnv latches and attempts safe stops.
  • Kortex reports show submitted commands (Cartesian metres/radians per step; joint velocity radians/s), not measured motion or controller acknowledgements.

1. Train a policy in simulation

Train a stable checkpoint; evaluation depends on algorithm, backend, and preflight gates. Dreamer’s train_real fine-tuning is experimental. Example: Dreamer on waypoint_navigation, Leo Rover, one environment, Earth gravity:

srb agent train --headless --algo dreamer --env waypoint_navigation env.robot=leo_rover env.num_envs=1 env.domain=earth

See the Reinforcement Learning Workflow.

2. Generate and verify the bridge

srb real_agent gen inspects a simulated Gymnasium environment and writes a lightweight hardware counterpart independent of the simulation backend. --hardware selects HardwareInterface drivers; for Leo Rover, ros_cmd_vel sends velocity, ros_tf supplies pose, and ros_mw provides pause/resume. Specify the robot so generation can extract settings such as action scaling.

srb real_agent gen --env waypoint_navigation env.robot=leo_rover --hardware ros_cmd_vel ros_tf ros_mw

Generation starts a temporary headless SRB session and replaces a Python module in sim_to_real/env. The module defines RealEnv with selected hardware IDs as defaults and registers under srb_real/; shipped waypoint code defaults to dummy. Find IDs with srb real_agent gen --help or browse sim_to_real/hardware.

Regenerate the waypoint module with your robot and hardware IDs before evaluation; shipped code uses cadre and dummy. Its deployment profile, configure_waypoint_navigation_hardware in srb/interfaces/sim_to_real/deploy_profiles/multi_robot.py, configures ros_tf for robot→target with 2D position and yaw, and ros_cmd_vel with the drive filter and simulator-scale clamps. The waypoint profile sets required_dynamic_frame_pairs to robot→target; these required pairs also declare observation keys. Bare ros_tf declares none. Verify profiles on the target robot.

Registration is lazy: importing srb or srb.interfaces.sim_to_real.env registers no srb_real/ ID. register_all() sweeps generated modules, and srb real_agent commands call it. srb_real/ tasks therefore do not appear in srb ls env or environment pages, which list only srb/. Shipped modules register srb_real/excavation, srb_real/formation_following, srb_real/terrain_landscaping, srb_real/terrain_landscaping_crater, and srb_real/waypoint_navigation. Agent verbs (not validate) generate a missing module in a subprocess, then exit and ask for a re-run.

See the srb real_agent gen reference.

3. Deploy and evaluate on hardware

Run policy evaluation

Check bridge routes and the production profile, then run generated RealEnv on configured hardware without launching simulation.

srb real_agent eval --env waypoint_navigation --algo dreamer

The regenerated profile routes actions through ros_cmd_vel/RosCmdVelInterface and supplies next-step pose observations through ros_tf/RosTfInterface; ros_mw provides middleware services.

Runtime cleanup and validation

Runtime verbs (eval, rand, zero, validate) close the environment on Ctrl-C, SIGTERM, errors, or normal exit while keeping ROS alive. Cleanup latches the session, submits final stops, then releases an owned context. Repeated signals cannot interrupt cleanup, but a blocking transport can delay it. Successful SIGTERM cleanup exits 143. Failed stops retain environment/context for retry; submission proves neither controller receipt nor that the robot stopped.

Validation cleans up the environment, abort watcher, and telemetry in one scope: environment closes before telemetry; ROS context releases only after successful closure. Failed closes retain resources for retry; completed closes are not repeated. ROS initializes immediately before environment construction, not on dry runs or earlier preflight failures. Compatible signal ownership also protects preflight resources. Ctrl-C/SIGTERM during rollout propagates after cleanup without guaranteeing an interrupted-rollout report. Ordinary failures report and exit 4 if cleanup succeeds; persistent cleanup failure raises and retains resources, so a report alone does not prove shutdown.

Embedding processes must invoke the CLI runtime on the main thread. An initialized default ROS context is allowed only with native handlers disabled (SignalHandlerOptions.NO); conflicts are rejected before hardware construction. Borrowed contexts remain active and Python handlers are restored on exit. Library-created RealEnv leaves process signal/context handling to the caller.

ROS policy input

srb real_agent ros accepts flat policy vectors on the environment’s action/raw topic, using generated action order and hardware mapping without simulator configuration. Missing, invalid, or stale input aborts through hardware stop methods. See the ROS input contract for message bounds, startup/freshness timeouts, and cleanup.

Dataset collection

Nonhuman real_agent collect sources (random, zero, or loaded policy) use RealEnv scalar steps and write datasets with single-environment batch axes and the real split. Without a success term, success-only collection uses explicit terminal-step boolean metadata; collector time limits do not make intermediate metadata a final outcome.

Native teleoperation and human collection

Native direct teleop and human collection need generated COMMAND_MAPPING (declared by shipped modules); ROS is default, with SpaceMouse or haptic supported. Keyboard/gamepad input and teleop --algo/--model are rejected. See the generation contract and native input details.

4. Advanced workflows

Zero and random agents

Use only after hardware validation and operator-controlled bring-up. zero sends zero policy input, which may actuate after mapping; it is not an emergency stop. rand sends random actions, not a safety check.

srb real_agent zero --env waypoint_navigation
srb real_agent rand --env waypoint_navigation

Dreamer real-data fine-tuning (srb real_agent train --algo dreamer --continue) remains experimental.

5. Additional task examples

5.1 Excavation

excavation targets a Husky + Kinova mobile manipulator with scoop payload. OSC and joint-velocity depend on the robot motion-generation stack. Deployment is unsupported: both commands raise route ValueError before ROS acquisition. OSC needs ros_optitrack for proprio/base_pose_world_optitrack (missing from generated HARDWARE), and no shipped adapter supplies state/ee_pose_world. Joint-velocity cannot route robot/delta_twist, accepted only by ros_kortex_cartesian (alias) and moveit_servo. The excavation profile configures only ros_depth_heightmap to the training grid: 16×16 cells at 3.75 cm, in kinova_base_link, centered on the default scoop target, invalid cells at 1.5 m. Shipped code omits this profile.

OSC (operational-space control):

srb real_agent eval --env excavation --algo skrl_ppo \
  --hardware ros_depth_heightmap ros_tf ros_imu ros_kortex_cartesian ros_scoop_target ros_mw

Joint-velocity variant:

srb real_agent eval --env excavation --algo skrl_ppo \
  --hardware ros_depth_heightmap ros_tf ros_imu ros_kortex_joint_vel ros_scoop_target ros_mw
InterfaceRole and limitation
ros_depth_heightmapProjects RealSense depth into a local heightmap grid.
ros_tfSupplies TF frame-pair observations; OptiTrack base pose additionally needs omitted ros_optitrack.
ros_imuSupplies IMU angular velocity and linear acceleration.
ros_kortex_cartesianCartesian-admittance Kinova arm control, FK, and contact-force readings.
ros_scoop_targetSupplies policy-required scoop-target command observations.
ros_mwMiddleware pause/resume services.
ros_kortex_joint_velSends Kinova joint velocities; use when an external motion-generation layer (e.g. NVIDIA fabrics) translates policy output into reactive joint targets.

For simulation rollouts, monitor success_rate, terminal_reward, scoop_particle_count, and action_smoothness. Hardware RealEnv does not emit scoop_particle_count because it has no particle simulation.

5.2 Terrain Landscaping

Canonical deployment uses RaphRover + prismatic-velocity RaphShovel and one external heightmap. It has no onboard depth camera, IMU observation, blade-pitch channel (measured or synthetic), previous-action feedback, or Leo Rover profile.

Task IDTarget manifestGenerated module
terrain_landscaping_craterFixed crater; hash pinned in modulesrb/interfaces/sim_to_real/env/terrain_landscaping_crater.py
terrain_landscapingPer-episode mission; module sets REQUIRES_RUNTIME_TARGET_MANIFEST = Truesrb/interfaces/sim_to_real/env/terrain_landscaping.py

terrain_landscaping_mound is simulation-only, with no generated module. General landscaping requires its hashed per-episode mission manifest to construct deployment RealEnv.

Regenerate checked-in bridge modules in place, then compare each with a fresh render:

# Regenerate (writes modules in place)
srb real_agent gen --env terrain_landscaping_crater
srb real_agent gen --env terrain_landscaping

# Check byte-identical fresh renders
srb real_agent gen --env terrain_landscaping_crater --check
srb real_agent gen --env terrain_landscaping --check

See --check for the drift check.

Generation derives modules through env.srb_spec from the frozen IO contract; it emits no np.finfo dtype-extrema bounds. The schema has 3 normalized velocity actions: robot/cmd_vel [0:2] (linear, angular) and payload/joint_vel [2:3]; plus 7 finite-bound actor observation leaves (1287 float32 values, in contract order): proprio_dyn/heightmap_current_global, proprio_dyn/heightmap_target_global, proprio_dyn/heightmap_current_local, proprio_dyn/heightmap_target_local, proprio/mission_pose, proprio/base_velocity, proprio_dyn/heightmap_age_s. SINGLE_OBSERVATION_SPACE assembles four map outputs and one packed vector, not seven top-level outputs. Deployment identity constants are ENV_ID, IO_SCHEMA_FINGERPRINT, TARGET_MANIFEST_SHA256, REQUIRES_RUNTIME_TARGET_MANIFEST, and DEPLOYMENT_REQUIREMENTS; target_map_sha256, reset_layout_sha256, manifest_sha256, and io_schema_fingerprint are distinct hashes.

Capability preflight blocks deployment. Before ROS acquisition, hardware start, or policy loading, canonical landscaping RealEnv checks the union of tags claimed by hardware interfaces and capability providers. All four are required: raph.drive_velocity, raph.shovel_prismatic_velocity, landscaping.external_heightmap_batch, and landscaping.observable_task_evaluator. srb.interfaces.sim_to_real.validation.landscaping.LandscapingRealEvaluator is the only shipped claimant (evaluator tag). Pass it as RealEnv(..., task_evaluator=...); it grades accepted external frames against the verified target manifest, owns reward, and rejects model artifacts with mismatched task ID, IO-schema fingerprint, target manifest, reset layout, or normalization policy before ROS, hardware start, or inference. Other tags have no shipped claimants, so construction raises typed DeploymentNotReadyError listing them. Deployment needs Raph ROS drive/shovel adapters and a live external heightmap mapper claiming those tags; SRB ships none.

hyperparams/validation/terrain_landscaping_crater.yaml declares no hardware and fails capability preflight (exit 4). Metrics are success_rate, final_grading_mae_m, final_fraction_within_tolerance, action_smoothness, and map_age_s; final-step info adds central-ROI/local MAE, sustained success, four distinct hashes, and calibration version. See Terrain Landscaping Training for learners, observation contract, and limitations. TD-MPC2 is unsupported for both IDs and fails before expensive side effects.

6. Validation Workflow

6.1 Capture a simulation baseline

Evaluate each checkpoint once in simulation:

srb agent eval --env excavation --algo skrl_ppo --model <ckpt> \
    env.num_envs=1

Use --model and Hydra override env.num_envs=1 for this simulator baseline; the validation spec does not configure the run. It configures hardware n_episodes and .rrd recording; srb real_agent validate --wandb enables W&B. The harness reads baseline scalars (success_rate, terminal_reward, action_smoothness, etc.) from sim_baseline.metrics_json or, failing that, a W&B run ID (see Validation spec YAML). srb agent eval does not write this file; provide a flat JSON object of finite numbers for every tracked metric (real-only metrics such as success_rate need no baseline).

6.2 Validation spec YAML

The spec defines the contract among the operator, generated RealEnv, and harness. CLI flags override selected runtime fields; YAML holds task, policy, hardware, criteria, telemetry, baseline, and drift settings.

FieldTypeRequiredDefault / limit
spec_idstring or nullnonull
taskstringyesrequired
algostringyesrequired
checkpointstringyesrequired
hardwarelist[string]yesrequired
metrics_to_tracklist[string]yesrequired
n_episodesintegerno10
max_episode_secondsfloat secondsno120.0
thresholdsobjectnosee below
rerunobjectnosee below
sim_baselineobjectnosee below
drift_windowinteger sessionsno5
storage_rootpathnologs/real_validation
notesstringno""

checkpoint accepts a raw checkpoint or SRB model artifact path; notes is copied to the spec snapshot.

Threshold optionTypeDefault / limit
thresholds.success_rate_minfloat0.5; minimum real success rate
thresholds.sim_real_ratio_minfloat0.7; floor for higher-is-better real/sim ratios
thresholds.lower_is_better_metricslist[string][]; names lower-is-better metrics; error/loss names auto-detected
thresholds.action_smoothness_max_ratiofloat1.5; max smoothness ratio
thresholds.crash_rate_maxfloat0.0; max crash/safety-event rate
thresholds.drift_z_maxfloat3.0; max z-score across recent sessions

Lower-is-better real/sim ratios cap at 1/sim_real_ratio_min; add metric names to lower_is_better_metrics.

Rerun optionTypeDefault
rerun.app_idstringsrb-validation
rerun.web_portinteger9090
rerun.grpc_portinteger9876
rerun.bind_addressstring or null0.0.0.0
rerun.keep_historical_databooltrue
rerun.keep_scalar_historybooltrue
rerun.record_to_rrdbooltrue; saves rollout.rrd
Simulation baseline optionTypeDefault
sim_baseline.wandb_run_idstring or nullnull; W&B run with sim summary scalars
sim_baseline.local_rrdpath or nullnull; not parsed for metrics; as the only source it yields a degraded baseline
sim_baseline.metrics_jsonpath or nullnull; local metrics JSON, tried before W&B

6.3 Run validation on the real robot

srb real_agent validate \
    --spec hyperparams/validation/excavation.yaml \
    --checkpoint <real-or-shared-ckpt> \
    --episodes 10 \
    --storage-root /tmp/srb_validation

Flags: --spec, --checkpoint, --episodes, --wandb, --no-tensorboard, --no-rerun-web, --storage-root, --post-status, --dry-run. Artifacts and TensorBoard are local by default; W&B is opt-in.

For graceful abort from another process, touch the exact .abort path logged at information level. It is in the session’s unique workspace beside private .staging:

touch '/exact/session/workspace/.abort'

Programmatic callers can read ValidationHarness.abort_request_path; information logging exposes the CLI path. Checks occur between reset, policy, and step calls: external_abort latches, stops later episodes, and records an incomplete failed session; an active operation may finish first. This is not an emergency stop or controller watchdog. Cleanup removes unpublished .abort. Inherited SRB_ABORT=1 also cancels; exporting it in another shell cannot affect a running process.

Dry runs never pass: --dry-run skips environment and policy construction, then finalizes with pass_overall: false, hardware_evidence: false, exit_code: 4, metrics.n_episodes: 0; all three criteria are skipped, the badge is red with non-hardware evidence, and the session is excluded from drift history.

The harness starts Rerun at http://localhost:9090, runs --episodes rollouts through generated RealEnv, writes session and storage-root artifacts, and checks:

  1. Threshold: success floor and sim/real ratios pass. The success floor applies without a baseline; with a positive success_rate_min, zero successes cannot pass.
  2. Crash: no policy_nan, hardware_event, disk_full, or safety abort (sensor_stale, sensor_incomplete, calibration_mismatch, manifest_mismatch).
  3. Drift: tracked-metric z-scores are at most thresholds.drift_z_max over the last K sessions.

Horizon endings are time_limit_truncation with final metrics, not wall-clock timeout. Out-of-MDP abort reasons/counts (sensor_stale, sensor_incomplete, calibration_mismatch, manifest_mismatch, operator_abort) are neither task termination nor truncation. Operator stop fails the success floor, not crash criterion.

Edge caseResult
Incomplete rollout (n_episodes or --episodes), out-of-MDP abort, or SRB_ABORT (external_abort)(a) fails with counts/reasons; safety abort also fails (b). The session is excluded from drift history.
Baseline comparisonDirection-aware around `
Drift historyRequires two earlier sessions; less history or no comparable metric skips optional (c). drift_window < 2 disables drift.
Post-rollout evaluation error (malformed baseline, missing metric)Invalid session; exit 4, hardware_evidence: false; report published.
Unreachable W&B baselineDegraded baseline; (a) fails, exit 1, hardware_evidence: false. success_rate is real-only.

Exit codes:

CodeName / criterionMeaning
0pass / allThreshold, crash, and drift pass.
1threshold_fail / criterion_aThreshold metrics fail, e.g. success rate or sim/real ratio.
2crash_fail / criterion_bCrash or safety-relevant termination.
3drift_fail / criterion_cTracked metrics exceed z-score limit.
4preflight_fail / preflightRollout cannot start (e.g. missing generated code, hardware wiring, incompatible checkpoint, or dry-run), or post-rollout evaluation fails; hardware_evidence: false.

Validation runs only generated srb_real/<task> environments; unresolved IDs fail with exit 4, never falling back to srb/<task> Isaac tasks. Shipped specs:

Spec under hyperparams/validation/Module generated?validate --spec result
excavation.yamlyesExit 4 preflight: generated environment cannot construct; see excavation.
formation_following.yamlyesRuns.
terrain_landscaping_crater.yamlyesExit 4 preflight: no hardware declared; no Raph adapters ship.

6.4 Validation artifacts

logs/real_validation/
+-- _index.jsonl
+-- index.html
+-- <task>/
    +-- <uuid>_<utc-timestamp>/
        +-- current.json
        +-- generations/
            +-- <generation-uuid>/
                +-- spec.yaml
                +-- episodes.jsonl
                +-- rollout.rrd
                +-- tensorboard/
                +-- summary.json
                +-- report.md
                +-- badge.json
ArtifactScope; writerProduced whenPurpose
spec.yamlSession; write_spec_snapshotPreflightRebuild-summary input.
episodes.jsonlSession; TelemetryRolloutAppend-only step, event, and episode-end metrics.
rollout.rrdSession; Telemetryrerun.record_to_rrd=true and Rerun startsInspection and twin replay.
tensorboard/Session; TelemetryEnabled and availableOptional scalar logs.
summary.json, report.md, badge.jsonSession; write_session_reportFinalization or rebuild-summaryMachine result, report, Shields.io payload.
_index.jsonlStorage root; DriftStoreFinalizationAppend-only drift history/dashboard rows.
index.htmlStorage root; write_validation_indexFinalizationCross-session pass/fail and metrics dashboard.

Each run regenerates logs/real_validation/index.html; trend charts group by (task, algo, metric). Compare the failed session’s simulation ghost (transparent) with its real run (solid), aligned by episode:

srb real_agent replay-twin \
    --session logs/real_validation/excavation/<uuid>_<ts>/generations/<generation-uuid> \
    --baseline baselines/excavation/<sha>.rrd

If a crash leaves summary.json missing, rebuild it from spec.yaml and episodes.jsonl:

srb real_agent rebuild-summary logs/real_validation/excavation/<uuid>_<ts>/generations/<generation-uuid>

The harness records estop, joint-limit, and contact-force events for criterion (b), but does not enforce safety or replace deadman switches, joint-limit watchdogs, or estop circuitry.

7. Creating custom hardware interfaces

Add a Python file under sim_to_real/hardware, subclass HardwareInterface, declare supported_action_spaces/supported_observation_spaces (used for routing), and implement apply_action (send commands), sync (refresh readings), and observation; override start/close (calling super()) to connect and clean up. _template.py is an example. Discovery exposes it to --hardware.

Next: Terrain Landscaping Training

Terrain Landscaping Training

No trained policy ships.

Tasks

See Mobile Robotics for the observation contract.

Targets: checked-in crater_target_manifest.json, mound_target_manifest.json; general missions are hashed and mass-balanced.

TaskEpisodeReward
Crater300 steps (30 s)grading MAE
Mound300 steps (30 s)excess volume above target
General600 steps (60 s)grading MAE

Documented success target (all tasks): at least 90% of observable grading cells within 0.02 m of the target for 20 consecutive accepted frames, reported at truncation. This target has not been validated against a physical system.

Choose env.external_heightmap.profile: ideal (default, no error), randomized (up to 0.1 s delay, 5% dropped frames, 2 mm elevation noise, small registration and pose errors), or failure_stale (stale-frame abort). Seeded defaults do not represent measured lab errors.

Training

Crater and mound auto-load task-local DreamerV3 and skrl PPO profiles, shadowing global profiles; general uses global profiles. See hyperparams/task/terrain_landscaping_{crater,mound}/ for these files.

srb agent train --headless --algo dreamer -e terrain_landscaping_mound env.num_envs=1
srb agent train --headless --algo skrl_ppo -e terrain_landscaping_crater env.num_envs=1
  • Dreamer: strict merge rejects unknown or dropped keys. Profiles use 10,000 steps and train_ratio: 512.0; gradient updates equal steps × train_ratio ÷ (batch_size × batch_length).

  • One environment: Dreamer landscaping rejects env.num_envs > 1; mixed batches cannot selectively reset. Stacked multi-environment particle scenes are unsupported; multi-environment particle training has not been validated.

  • TD-MPC2 disabled: all three tasks fail before creating logs, config, replay, or model:

    TD-MPC2 landscaping is disabled: velocity-controlled shovel extension is unobserved and TD-MPC2 keeps no recurrent or history state to infer it.
    
  • GPU required: PhysX particles need a GPU; tasks read them through CPU-facing USD (sim.device = "cpu"). “Force CPU” disables particles; see Particles.

Dreamer checkpoints

OperationRestoresDoes not restore
--continue (same log directory)step, agent parameters, optimizer, replaysimulator state, partial episodes, recurrent carries, RNG
Agent import into new runagent state; starts at step 0everything else
Evaluation or policy loadagent state for inferenceeverything else

Resume is not bitwise; it fails when ckpt_generation.json lacks replay chunks. Loads verify task ID, IO-schema fingerprint, observation layout, target manifest, measurement profile, and normalization against the live environment. SRB_ALLOW_UNVERIFIED_LANDSCAPING_CHECKPOINT allows missing metadata, not mismatches.

Results and limitations

  • Crater: no shipped controller meets the success criterion; a pushing blade disturbs the graded surface about as fast as it fills the crater.
  • Mound: the scripted reference clears 1.75 L.
  • General task: the scripted reference does not improve on zero action.
  • Leaving the mission-pose (±2.0 m) or body-velocity envelope terminates the episode. Out-of-envelope elevations raise ExternalHeightmapFrameError (see Modelling Envelope).
  • Particle behavior is simulation-only and not calibrated against regolith.

Deployment

See Sim-to-Real for bridge status, capabilities, and crater-spec validation. Validation Workflow covers dry runs.

Next: Environments

Environments

SRB environments:

Namespaces

These pages list the simulated Gymnasium srb/ environments enumerated by srb ls env and srb doc docgen.

srb_real/ contains generated ROS 2 RealEnv deployment interfaces for srb real_agent. They are not validated on physical robots and have no simulated scenario. Real-task metrics require an explicitly configured task evaluator. Sim-to-Real Transfer lists shipped IDs, generation, and registration.

Environments – Manipulation (Static)

Fixed-base robot arm manipulation environments.

Manipulation (_manipulation)

Template environment for fixed-base manipulation tasks. Configure via env.robot=<manipulator>.

_manipulation

Episode Length10.0s (500 steps)
Reward Terms4
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–

Debris Capture (debris_capture)

Capture and securement of floating debris in microgravity with a fixed-base manipulator

Episode Length10.0s (500 steps)
Reward Terms11
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_distance_ee_to_objGaussian160.08
reward_graspSoftThreshold16–
penalty_debris_velocity_linLinear-3–
penalty_debris_velocity_angLinear-1–
reward_approach_velocity_alignmentHyperbolic40.1
penalty_approach_speedLinear-2–
penalty_debris_too_farLinear-8–
  • distance_debris_too_far applies penalty_debris_too_far only; episodes end by horizon (truncated).
  • Episode info omits success; bounded evaluation reports return only.

Excavation (excavation)

Extraction of granular material (regolith)

Episode Length8.0s (400 steps)
Reward Terms13
Default RobotKinova Gen3N7

Robots

Kinova Gen3N7

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.05–
penalty_joint_torqueLinear-0.00001–
penalty_joint_accelerationLinear0–
penalty_undesired_robot_contactsLinear0–
reward_approach_pileGaussian1.50.15
reward_scoop_depthTukey2–
reward_scoop_orientationGaussianTracking10.26
reward_liftHyperbolic20.2
penalty_jerkLinear-0.02–
penalty_joint_accLinear-0.000001–
penalty_undesired_contactsLinear-0.5–
terminal_particle_count_scaledScaled10–
terminal_success_bonusScaled50–
  • Heightmap bins live regolith positions onto the observation grid at runtime; PhysX particle sets cannot be raycast.
  • imu_pedestal is active only at env.num_envs=1; otherwise it is disabled with a warning and returns zero observations.
  • Episode-end info includes success; bounded evaluation reports success rate and return.
  • Wrist event camera: add events to env.active_sensors.

Excavation Demo (excavation_demo)

Manual excavation demo with presentation-oriented lunar regolith defaults

excavation_demo

Episode Length1800.0s (90000 steps; truncation disabled)
Reward Terms13
Default RobotKinova Gen3N7

Robots

Kinova Gen3N7

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.05–
penalty_joint_torqueLinear-0.00001–
penalty_joint_accelerationLinear0–
penalty_undesired_robot_contactsLinear0–
reward_approach_pileGaussian1.50.15
reward_scoop_depthTukey2–
reward_scoop_orientationGaussianTracking10.26
reward_liftHyperbolic20.2
penalty_jerkLinear-0.02–
penalty_joint_accLinear-0.000001–
penalty_undesired_contactsLinear-0.5–
terminal_particle_count_scaledScaled10–
terminal_success_bonusScaled50–

Modular Assembly (modular_assembly)

Pick-and-place modular elements into an assembly configuration

modular_assembly

Episode Length20.0s (1000 steps)
Reward Terms10
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear0–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-32–
reward_top_down_orientationGaussianTracking160.25
reward_pair_positionLinear8–
reward_pair_orientationLinear2–
reward_peg_hole_entrance_alignmentLinear8–
reward_peg_hole_alignmentLinear64–
reward_successLinear512–

Multi Peg In Hole (multi_peg_in_hole)

A variation of peg-in-hole assembly with multiple pegs and holes

Episode Length40.0s (2000 steps)
Reward Terms19
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_top_down_orientationGaussianTracking10.25
reward_distance_ee_to_objHyperbolic00.25
reward_graspLinear8–
reward_liftLinear4–
reward_align_peg_to_hole_primaryGaussianTracking00.4
reward_align_peg_to_hole_secondaryGaussian00.2
reward_distance_peg_to_hole_entrance_gradualHyperbolic00.16
reward_distance_peg_to_hole_entranceGaussian00.04
reward_distance_peg_to_hole_bottomGaussian00.003
reward_distance_ee_to_objsLinear2.5–
reward_align_pegs_to_holes_primaryLinear8–
reward_align_pegs_to_holes_secondaryLinear4–
reward_distance_pegs_to_holes_entrance_gradualLinear8–
reward_distance_pegs_to_holes_entranceLinear32–
reward_distance_pegs_to_holes_bottomLinear256–

Multi Sample Collection (multi_sample_collection)

A variation of sample collection with multiple samples

Episode Length22.5s (1125 steps)
Reward Terms12
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_top_down_orientationGaussianTracking10.25
reward_distance_ee_to_objGaussian00.15
reward_graspLinear4–
reward_liftLinear8–
reward_distance_obj_to_targetGaussian00.15
penalty_obj_fallenLinear0–
reward_distance_ee_to_objsLinear2.5–
reward_distance_objs_to_targetLinear32–

Peg In Hole (peg_in_hole)

Precision assembly task requiring the robot to insert a peg into a hole

Episode Length10.0s (500 steps)
Reward Terms13
Default RobotFranka
Multi Variantmulti_peg_in_hole

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_top_down_orientationGaussianTracking10.25
reward_distance_ee_to_objHyperbolic40.25
reward_graspSoftThreshold8–
reward_liftGaussianZoneTracking40.08
reward_align_peg_to_hole_primaryGaussianTracking80.4
reward_align_peg_to_hole_secondaryGaussian40.2
reward_distance_peg_to_hole_entrance_gradualHyperbolic80.16
reward_distance_peg_to_hole_entranceGaussian320.04
reward_distance_peg_to_hole_bottomGaussian2560.003

Evaluation

  • Episode info has no success; bounded evaluation reports return only.

Sample Collection (sample_collection)

Grasping and collection of samples on planetary surfaces

Episode Length7.5s (375 steps)
Reward Terms10
Default RobotFranka
Multi Variantmulti_sample_collection

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_top_down_orientationGaussianTracking10.25
reward_distance_ee_to_objGaussian40.15
reward_graspSoftThreshold6–
reward_liftGaussianZoneTracking120.15
reward_distance_obj_to_targetGaussian320.15
penalty_obj_fallenLinear-16–
  • obj_floor_z drives penalty_obj_fallen; falls do not terminate. Horizon ends as truncated.
  • Wrist event camera: add events to env.active_sensors.
  • Episode info omits success; bounded evaluation reports return only.

Screwdriving (screwdriving)

Fastening of a pre-inserted bolt

Episode Length15.0s (750 steps)
Reward Terms13
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_top_down_orientationGaussianTracking80.04
penalty_object_top_down_orientationLinear-64–
reward_distance_ee_to_bolt_driver_slotHyperbolic120.4
reward_distance_ee_to_bolt_driver_slot_closeHyperbolic320.02
reward_distance_ee_to_bolt_driver_slot_precisionHyperbolic5120.005
reward_contactSoftThreshold4–
reward_screwingScaled128–
penalty_distance_obj_to_target_too_farThreshold-256–
reward_distance_obj_to_targetLinear2048–

Evaluation

  • Episode info has no success; bounded evaluation reports return only.

Solar Panel Assembly (solar_panel_assembly)

Complex assembly sequence involving solar panel components

Episode Length50.0s (2500 steps)
Reward Terms17
Default RobotFranka

Robots

Canadarm3 | Franka | Kinova J2N6S | Kinova J2N7S | Kinova Gen3N7 | Levion Arms | So Arm100 D5 | So Arm100 D7 | Unitree Z1 | Ur3 | Ur3E | Ur5 | Ur5E | Ur10 | Ur10E | Ur16E | Ur20 | Ur30 | Random Ur Manipulator | Vispa | Zeroglab Arms

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
penalty_undesired_robot_contactsThreshold-0.5–
reward_top_down_orientationGaussianTracking10.25
reward_distance_ee_to_objsLinear2.5–
reward_graspSoftThreshold8–
reward_liftLinear4–
reward_align_pegs_to_holes_primaryLinear8–
reward_align_pegs_to_holes_secondaryLinear4–
reward_distance_pegs_to_holes_entrance_gradualLinear8–
reward_distance_pegs_to_holes_entranceLinear32–
reward_distance_pegs_to_holes_bottomLinear256–
reward_distance_ee_to_panelHyperbolic100.25
reward_panel_liftGaussianZoneTracking160.1
reward_distance_panel_to_target_gradualHyperbolic320.1
reward_distance_panel_to_targetGaussian10240.015

Evaluation

  • Episode info has no success; bounded evaluation reports return only.

Environments – Mobile Robotics

Mobile robot navigation and locomotion tasks for Isaac Sim 6.1.0 with Isaac Lab 3.0.0.

Aerial (_aerial)

Template environment for aerial mobile robots. Configure via env.robot=<aerial_robot>.

_aerial

Simulation only; no trained policy ships.

Episode Length10.0s (250 steps)
Reward Terms1
Default RobotIngenuity

Robots

Crazyflie | Ingenuity

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–

Ground (_ground)

Template environment for ground mobile robots. Configure via env.robot=<ground_robot>.

_ground

Episode Length10.0s (250 steps)
Reward Terms1
Default RobotCadre

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–

Orbital (_orbital)

Template environment for orbital mobile robots. Configure via env.robot=<orbital_robot>.

_orbital

Episode Length10.0s (250 steps)
Reward Terms2
Default RobotCubesat

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-1–

Camera clipping. Set env.camera_clipping_range=[near,far] to override the render far plane and uint8 depth quantization; depth beyond far saturates and geometry is omitted from RGB.

EnvironmentFar planeReason or limit
Orbital default100 m ((0.01, 100.0) m)Orbital robots define no clipping range.
rendezvous50 mmax_target_distance; about 20 cm per uint8 depth step, versus 39 cm at 100 m.
orbital_evasion150 m100 m bounds radius plus obstacle field.
landing, moonfall400 mNadir camera reaches 200–220 m above terrain, tilted up to 30°.

Aerial Navigation (aerial_navigation)

Aerial navigation to a dynamic waypoint with terrain-clearance tracking

aerial_navigation

Simulation only; no trained policy ships.

Episode Length60.0s (1500 steps)
Reward Terms7
Default RobotIngenuity

Robots

Crazyflie | Ingenuity

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
reward_altitude_trackingHyperbolicTracking41
reward_waypoint_approachHyperbolic162
penalty_tilt_angleOffsetLinear-2–
reward_terrain_clearanceHyperbolicBarrier80.5
penalty_energyLinear-0.5–
reward_waypoint_reachedThreshold32–

Bounded evaluation. Aerial Navigation and linked tasks omit success; bounded evaluation reports return only.

Beam Transport (beam_transport)

Two-robot collaborative transport of a rigid beam payload to a target point

beam_transport

Two Spot quadrupeds carry a rigid beam to a target on procedural MoonSurface. One shared policy observes robots in fixed order and splits one joint action across them, as in formation following.

beam_kinematic_mount_enabledBehavior
true (default)Mount beam at pair midpoint and heading, level at fixed height. Reward shapes support-slot alignment and gentle transport; no grasp/contact dynamics, tilt/drop penalties, or tilt success gate.
falseFree-beam ablation; restores tilt/drop penalties and tilt success gate.

No trained policy ships. Train and evaluate with:

srb agent train --algo dreamer --env beam_transport
srb agent eval --algo dreamer --env beam_transport --model <path/to/checkpoint>

Rollouts report min_beam_distance_to_target (m), success-hold streak, and success_rate. At zero success, minimum distance shows partial progress.

Episode Length30.0s (750 steps)
Reward Terms15
Default RobotSpot

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
reward_beam_positionGaussian161.5
reward_beam_midpoint_alignmentGaussian100.25
reward_robot_support_slotsGaussian120.2
reward_beam_progressScaled8–
reward_attachment_balanceGaussian40.15
reward_successLinear24–
penalty_beam_tiltLinear-4–
penalty_beam_dropLinear-16–
penalty_beam_speedLinear-2–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.00000025–
penalty_undesired_lin_vel_zLinear-0.5–
penalty_undesired_ang_vel_xyLinear-0.1–
penalty_gravity_rotation_alignmentLinear-2–

Success limits. Hold target pose for success_hold_steps=8 steps (0.32 s); target distance ≤ target_zone_radius_xy=0.20 m; beam-to-midpoint and support-slot alignment ≤ beam_attachment_radius_xy=0.30 m; planar speed ≤ target_speed_threshold_xy=0.35 m/s. Free-beam mode also requires 1 - |cos θ| ≤ beam_tilt_tolerance=0.20 (θ ≲ 37° from vertical). Holding success terminates the episode; otherwise it truncates at 30 s. Resets preserve robot spacing with a shared planar offset within ±1.5 m and shared yaw over the full circle; the mounted beam follows the transformed pair.

Policy spaces. Observations: per-robot planar position, velocity, and beam offset; beam position and 6D rotation; beam-target offset and distance; assignment-invariant support-slot error; beam planar/angular velocity; pair midpoint. Positions are environment-relative; inter-body offsets are unchanged. Actions drive both Spot quadrupeds. The reward table includes per-robot penalties for joint torque/acceleration, vertical velocity, roll/pitch rate, and projected-gravity alignment.

Episode-end info publishes success; bounded evaluation reports success rate and return.

Flight (flight)

Generic powered aerial flight profile with takeoff, transfer, and final landing

flight

Flight: 90 s Martian mission—ascend to cruise altitude, transfer to landing pad, guarded touchdown approach. Mars is default because rotorcraft need atmosphere; see Modelling envelope. Aerial configuration’s domain-selected scenery owns default Mars spawn and clearance.

Set env.landing_only=true to start in final descent phase 2, skipping ascent and transfer. This is the aerial Flight variant; orbital landing is separate.

Episode Length90.0s (2250 steps)
Reward Terms8
Default RobotIngenuity

Robots

Crazyflie | Ingenuity

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
reward_waypoint_approachHyperbolic124
reward_altitude_trackingHyperbolicTracking61
reward_waypoint_reachedThreshold20–
penalty_tilt_angleOffsetLinear-2–
reward_terrain_clearanceHyperbolicBarrier60.8
penalty_energyLinear-0.6–
reward_mission_progressLinear60–

Termination/success. Crash terminates below termination_min_clearance or above termination_max_tilt. Pad arrival latches success in episode_outcome_info (crashed, on_pad, mission_phase), but episode runs to the limit. Success requires reaching the pad without crashing on the final step. At default weights, reward_mission_progress pays 60 per completed phase each step, more than other terms combined per step.

Formation Following (formation_following)

Multi-robot formation tracking behind a moving formation center

formation_following

Three Cadre-class rovers follow a drifting center in triangular slots (1.5, 0), (-0.75, 1.3), (-0.75, -1.3) m. Center follows a smooth random walk or ROS formation_center TF.

One shared policy: concatenate observations in fixed rover order, split one joint action across rovers, return one team reward per environment. Observation/action sizes scale linearly with team size. Small teams avoid decentralized communication and role assignment while keeping checkpoints reproducible. Companion centralized surface task: beam transport.

No trained policy ships.

srb agent train --algo dreamer --env formation_following
srb agent eval --algo dreamer --env formation_following --model <path/to/checkpoint>

Rollouts report mean per-rover slot-distance error (formation_distance_error, m), mean heading error (formation_orientation_error, rad), success-hold streak, and success_rate. At zero success, errors show partial progress.

Episode Length60.0s (1500 steps)
Reward Terms9
Default RobotCadre

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_formation_trackingLinear-1–
reward_formation_progressScaled4–
reward_formation_velocityLinear2–
reward_point_towards_targetLinear0.5–
reward_formation_precisionLinear4–
reward_in_zoneLinear0–
reward_formation_orientationLinear4–
reward_action_rate_in_formationLinear32–

Success limits. All rovers stay within formation_success_position_tolerance_xy=0.20 m of their slots and formation_success_yaw_tolerance≈0.349 rad (20°) in heading for success_hold_steps=8 (0.32 s). Holding success terminates the episode (terminate_on_success=true; formation_following_decentralized keeps running); otherwise it truncates at 60 s. Infinite-horizon (is_finite_horizon=false).

Policy spaces. Each rover observes planar slot offset and heading-to-slot (sin, cos); policy observes center and rover planar velocities. Fixed episodic reset noise: 1 cm position, 2.5° heading. Actions: planar linear/angular velocity.

ROS center. ROS replaces random walk with formation_center TF. First post-reset pose re-anchors center; reset jump is not velocity. Not hardware-validated.

Episode-end info publishes success; bounded evaluation reports success rate and return.

Formation Following Decentralized (formation_following_decentralized)

Single-rover policy view for decentralized formation following

formation_following_decentralized

Episode Length60.0s (1500 steps)
Reward Terms9
Default RobotCadre

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_formation_trackingLinear-1–
reward_formation_progressScaled4–
reward_formation_velocityLinear2–
reward_point_towards_targetLinear0.5–
reward_formation_precisionLinear4–
reward_in_zoneLinear0–
reward_formation_orientationLinear4–
reward_action_rate_in_formationLinear32–

Formation Following Orbital (formation_following_orbital)

Orbital formation tracking in microgravity

formation_following_orbital

Episode Length60.0s (600 steps)
Reward Terms7
Default RobotCubesat

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-8–
penalty_fuel_consumptionLinear0–
penalty_action_magnitudeLinear-8–
penalty_formation_trackingLinear-2–
reward_formation_precisionLinear16–
reward_formation_orientationLinear48–
reward_action_rate_in_formationLinear48–

Slot assignment. randomize_formation_assignment=false assigns environment i to slot i % N (N formation positions), including partial resets. When true (default), each reset draws a random slot.

Landing (landing)

Landing of spacecraft on planetary surfaces with varying terrain and obstacles

Episode Length40.0s (1000 steps)
Reward Terms11
Default RobotPeregrine Lander

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-1–
penalty_angular_velocityLinear-0.25–
penalty_gravity_rotation_alignmentLinear-1–
penalty_horizontal_linear_velocityLinear-0.1–
reward_vertical_linear_velocityHyperbolic81
reward_landing_angleLinear8–
reward_landing_velocityLinear16–
reward_landing_fuelLinear4–
penalty_crashLinear-32–
penalty_below_targetLinear-16–

See evaluation note.

Event cameras. Add events to env.active_sensors for the onboard (landing, moonfall) or front (velocity_tracking, waypoint_navigation) event camera.

Locomotion Velocity Tracking (locomotion_velocity_tracking)

Locomotion with legged robots and humanoids while tracking desired velocity commands

Simulation only; no trained policy ships.

Episode Length20.0s (500 steps)
Reward Terms12
Default RobotSpot

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cassie | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped | Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
reward_cmd_lin_vel_xyLinear4–
reward_cmd_ang_vel_zLinear2–
penalty_undesired_lin_vel_zLinear-0.5–
penalty_undesired_ang_vel_xyLinear-0.1–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.00000025–
penalty_undesired_robot_contactsThreshold-2–
penalty_gravity_rotation_alignmentLinear-2–
reward_feet_air_timeLinear0.75–
reward_quadruped_trotLinear1–
penalty_foot_slipLinear-0.5–

Termination matches Locomotion Waypoint Navigation: undesired non-foot contact, fall (planar projected gravity above 0.85), or non-finite state. Time limits truncate.

See evaluation note.

Locomotion Waypoint Navigation (locomotion_waypoint_navigation)

Navigation to a dynamic waypoint with legged robots and humanoids

Simulation only; no trained policy ships.

Episode Length60.0s (1500 steps)
Reward Terms13
Default RobotSpot

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cassie | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped | Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_position_trackingLinear-1–
reward_point_towards_targetLinear1–
reward_position_tracking_precisionLinear4–
reward_orientation_trackingLinear8–
reward_action_rate_at_targetLinear16–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.00000025–
penalty_undesired_robot_contactsThreshold-2–
penalty_undesired_lin_vel_zLinear-0.5–
penalty_undesired_ang_vel_xyLinear-0.1–
penalty_gravity_rotation_alignmentLinear-2–
reward_feet_air_timeLinear0.5–

Episodes terminate if non-foot contact exceeds its configured undesired-contact threshold, projected gravity’s planar norm exceeds 0.85 (fall), or contact/gravity state is non-finite (fail-closed). Time limits truncate, not terminate.

See evaluation note.

Moonfall (moonfall)

Heavy-weight lunar descent with deployment stage and multi-stage landing phases

moonfall

Episode Length70.0s (1750 steps)
Reward Terms12
Default RobotPeregrine Lander

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-1–
penalty_angular_velocityLinear-0.25–
penalty_gravity_rotation_alignmentLinear-1–
penalty_horizontal_linear_velocityLinear-0.1–
reward_waypoint_progressHyperbolic44
reward_vertical_linear_velocityHyperbolic81
reward_landing_angleLinear8–
reward_landing_velocityLinear16–
reward_landing_fuelLinear4–
penalty_crashLinear-32–
penalty_below_targetLinear-16–

See event camera options.

See evaluation note.

Orbital Evasion (orbital_evasion)

Navigation of spacecraft in microgravity while avoiding obstacles

Episode Length30.0s (750 steps)
Reward Terms7
Default RobotCubesat

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-1–
penalty_angular_velocityLinear-0.25–
reward_obstacle_clearanceHyperbolicBarrier42
penalty_distance_robot_to_targetLinear-0.32–
penalty_out_of_boundsLinear-16–
reward_target_approachHyperbolic85

Termination. max_target_distance affects penalty_out_of_bounds, not terminated. Collision terminates when robot center of mass enters an obstacle keep-out sphere (0.5 * obstacle_scale * 1.4; 3.5 m for default 5 m asteroids), i.e. clearance falls below termination_min_obstacle_distance (0 m). Robot is a point: large robots may touch obstacles without termination, and about 7% of asteroids extend beyond the sphere on one axis. Obstacle centers spawn at z ∈ [-43, -7] m, at least 7 m from robot spawn and target. Time limits set truncated.

See evaluation note.

Orbital Waypoint Navigation (orbital_waypoint_navigation)

Navigation to a dynamic waypoint in orbital microgravity

orbital_waypoint_navigation

Episode Length30.0s (300 steps)
Reward Terms9
Default RobotSatellite Mockup

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLogCosh-4–
penalty_fuel_consumptionLinear0–
penalty_action_magnitudeLogCosh-1–
penalty_angular_velocityLogCosh-2–
penalty_position_distanceLinear-1–
penalty_velocity_at_targetLogCosh-4–
reward_position_approachHyperbolic42
reward_position_precisionScaled8–
reward_smooth_station_keepingScaled8–

See evaluation note.

Rendezvous (rendezvous)

Maneuvering of spacecraft in microgravity to rendezvous with an uncooperative target

Episode Length25.0s (625 steps)
Reward Terms7
Default RobotCubesat

Robots

Floating Platform | Int Ball1 | Int Ball2 | Apollo Lander | Peregrine Lander | Vikram Lander | Resilience Lander | Random Lander | Iss | Gateway | Cubesat | Satellite Mockup | Venus Express | Starship | Super Heavy

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-8–
penalty_angular_velocityLinear-0.05–
penalty_distance_robot_to_targetLinear-16–
penalty_too_farLinear-16–
reward_precision_positionGaussian1280.025
reward_precision_orientationLinear128–

Termination. Exceeding max_target_distance incurs penalty_too_far but leaves terminated false so the agent can recover. Only the time limit sets truncated.

See evaluation note.

Terrain Landscaping (terrain_landscaping)

Terrain landscaping with a ground mobile robot reshaping a particle bed

terrain_landscaping

No trained policy ships. Dreamer requires env.num_envs=1; TD-MPC2 is unsupported; Raph hardware validation is incomplete. See Terrain Landscaping Training.

Setup: RaphRover + articulated RaphShovel (env.robot=raph_rover+raph_shovel). Filtered actions, in order: rover linear, rover angular, shovel extension velocity (terms robot/cmd_vel = linear, angular; payload/joint_vel = prismatic). Shovel resets raised at its 0.2 m joint limit; zero velocity holds position via actuator damping, keeping blade above settled particles until policy lowers it.

Reset: rover within ±1.1 m of bed center, random yaw. Blade reaches about 0.53 m from rover origin and starts clear of ±2.0 m walls. Rear-axle Ackermann steering limits yaw rate; full C/V turn gives about half the command.

Teleoperate (one environment):

srb agent teleop -e terrain_landscaping env.num_envs=1
InputAction
W/S, C/VForward/reverse; turn.
Q/ERaise/lower shovel. Release sends zero velocity; damping resists drift, no auto-retract.
SpaceMouse forward/back, verticalSame channels; rover ignores lateral translation.

Each episode deforms the flat reset bed with a hashed, mass-balanced mission: cut/fill balance within 1e-4 m³; cuts stay above available material, fills below containment ceiling, significant deformation in reachable zone. Seed (env.general_mission_seed, env_id, episode_index) reproduces missions across processes. Manifest records generator version, seed, frame, geometry, physical bounds, target-map, reset-layout, and manifest hashes. Infeasible missions redraw; exhausted attempts raise. Configure env.general_mission_profile.*.

This task shares only reward implementation and observation contract with terrain_landscaping_crater; targets, manifests, and curriculum stages are separate.

Episode Length60.0s (600 steps)
Default RobotRaph Rover

Robots

Raph Rover

Observation contract. Actor uses external heightmaps, not depth; PhysX particles cannot be raycast. Each policy step publishes one accepted-or-held 10 Hz live-regolith frame. Seven ordered leaves: global current/target (16×16), rover-frame local current/target (24×16), mission pose (x,y,yaw), body velocity (vx,vy,wz), frame age; flattened to 1287 float32. Elevations use mission-frame +z, matching deployment adapters. No validity mask: all 146×146 source cells finite; incomplete/out-of-envelope frames rejected whole. Unobserved: shovel extension, previous action, particle positions, simulator world pose, privileged current-minus-target maps. env.external_heightmap.profile: ideal, randomized, failure_stale.

Reward/episode. Sole reward 1 / (1 + mae / 0.02) on fixed mission grading cells, shared with crater. MDP continues (is_finite_horizon=false); time limit truncates. Success is evaluation-only, never termination or bonus.

Canonical tasks require RaphRover and RaphShovel; other robots or payloads fail before scene binding. Actor observations and canonical deployment profile omit shovel state.

Frame validity. Map, pose, and velocity share a timestamp; local crop uses that pose. Simulation resets capture one synchronous frame; deployment resets wait up to 2.0 s. A missing frame raises (no zero substitute). Frames older than 0.5 s stale-abort outside MDP. Dropped updates repeat the last complete map and increase frame age.

TD-MPC2 is unsupported because shovel extension is unobserved; it fails with an actionable error before creating logs, config, replay, or model. See Terrain Landscaping Training.

Terrain Landscaping Crater (terrain_landscaping_crater)

Separate deterministic baseline: fill one shallow crater from a nearby regolith pile

terrain_landscaping_crater

No trained policy ships; Dreamer supports only env.num_envs=1; TD-MPC2 is unsupported; the task is not validated on Raph hardware. See Terrain Landscaping Training.

Separate deterministic task from terrain_landscaping: no curriculum, scheduler, or automatic switching. Layered bed: one shallow bowl crater and one loose pile; crater particles reused, preserving particle count/mass. RaphRover starts fixed with both forward. Visible 4 m slab below physical ground, dark neutral terrain, and light regolith keep the bed readable against lunar skydome in viewport/headless captures.

Static analytic flat-bed target: crater_target_manifest.json; config fails if crater, pile, or spawner settings cannot reproduce hashed reset layout. Reward: 1 / (1 + mae / 0.02) on fixed manifest grading cells using oracle particle truth. Success: 90% of cells within tolerance for 20 consecutive newly accepted mapper frames; report at time-limit truncation, never termination/bonus. Continuing MDP (is_finite_horizon=false): the time limit truncates; leaving the rover pose/velocity envelope terminates. Physics perturbations/lighting randomization disabled. Action/observation schemas match terrain_landscaping.

Inspect by teleoperation:

srb agent teleop -e terrain_landscaping_crater env.num_envs=1
Episode Length30.0s (300 steps)
Default RobotRaph Rover

Robots

Raph Rover

FeatureDefaults
CraterCenter (0.45 m, 0.20 m), radius 0.36 m, depth 0.11 m.
PileCenter (-0.25 m, -0.20 m), radius 0.32 m, height 0.28 m.

Override under env.*. Out-of-bed, overlapping, or under-capacity layouts fail before particle spawn.

Observation contract. Same heightmap and frame contract as terrain_landscaping; schema flattens to 1287 float32.

TD-MPC2 has the same unsupported setup and fails before logs, config, replay, or model. PhysX PBD particles require a CUDA-capable NVIDIA GPU; particle state uses CPU readback (sim.device = "cpu") for heightmap, reward, and rendering. See Terrain Landscaping Training.

Terrain Landscaping Mound (terrain_landscaping_mound)

Separate deterministic baseline: level one regolith mound on a flat bed, graded by excess volume

terrain_landscaping_mound

No trained policy ships, Dreamer runs with env.num_envs=1 only, TD-MPC2 is not supported, and the task is not validated on Raph hardware. See Terrain Landscaping Training.

Episode Length30.0s (300 steps)
Default RobotRaph Rover

Robots

Raph Rover

Traversal (traversal)

Straight-line path following at a target velocity

traversal

Episode Length120.0s (3000 steps)
Reward Terms5
Default RobotNifty

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.05–
penalty_lateral_pos_deviationLinear-1–
reward_vel_progressLinear8–
reward_action_rate_at_targetLinear32–
penalty_rolloverLinear-16–

Termination. Exceeding max_tilt_rad incurs penalty_rollover but leaves terminated false so the rover can recover. The time limit sets truncated.

See evaluation note.

Velocity Tracking (velocity_tracking)

Basic tracking of desired velocity commands

Episode Length20.0s (500 steps)
Reward Terms5
Default RobotCadre

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
reward_cmd_lin_vel_xyLinear4–
reward_cmd_ang_vel_zLinear2–
penalty_undesired_lin_vel_zLinear-0.5–
penalty_undesired_ang_vel_xyLinear-0.1–

Commands (vx, vy, wz) are sampled uniformly in ±1 m/s and rad/s. Wheeled drives use their own limits instead and get no lateral command.

See evaluation note.

See event camera options.

Waypoint Navigation (waypoint_navigation)

Navigation to a dynamic waypoint

Episode Length60.0s (1500 steps)
Reward Terms6
Default RobotCadre

Robots

Anymal C | Anymal D | Random Anymal Quadruped | Cadre | Cassie | Husky | Leo Rover | Mars Rover | Nifty | Open Source Rover | Perseverance | Pragyan | Raph Rover | Spot | Unitree A1 | Unitree Go1 | Unitree Go2 | Random Unitree Quadruped

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_position_trackingLinear-1–
reward_point_towards_targetLinear1–
reward_position_tracking_precisionLinear4–
reward_orientation_trackingLinear8–
reward_action_rate_at_targetLinear16–

See evaluation note.

See event camera options.

Environments – Mobile Manipulation

Environments combining mobility and manipulation.

Aerial Manipulation (_aerial_manipulation)

Template environment for aerial mobile manipulators. Configure via env.robot.mobile_base=<aerial_robot> and env.robot.manipulator=<manipulator>.

_aerial_manipulation

Simulation only; no trained policy ships.

Episode Length10.0s (500 steps)
Reward Terms2
Default RobotGeneric Aerial Manipulator

Robots

Generic Aerial Manipulator

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_undesired_robot_contactsThreshold-0.5–

Ground Manipulation (_ground_manipulation)

Template environment for ground mobile manipulators. Configure via env.robot.mobile_base=<ground_robot> and env.robot.manipulator=<manipulator>.

_ground_manipulation

Episode Length10.0s (500 steps)
Reward Terms2
Default RobotGeneric Ground Manipulator

Robots

Generic Ground Manipulator

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_undesired_robot_contactsThreshold-0.5–

Orbital Manipulation (_orbital_manipulation)

Template environment for orbital mobile manipulators. Configure via env.robot.mobile_base=<orbital_robot> and env.robot.manipulator=<manipulator>.

_orbital_manipulation

Episode Length10.0s (500 steps)
Reward Terms2
Default RobotGeneric Orbital Manipulator

Robots

Generic Orbital Manipulator

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_undesired_robot_contactsThreshold-0.5–

Mobile Debris Capture (mobile_debris_capture)

Capture of floating debris in microgravity with a floating-base mobile manipulator

Episode Length60.0s (3000 steps)
Reward Terms10
Default RobotGeneric Orbital Manipulator

Robots

Generic Orbital Manipulator

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-2–
penalty_angular_velocityLinear-0.05–
penalty_joint_torqueLinear-0.000025–
penalty_joint_accelerationLinear-0.0005–
reward_distance_end_effector_to_objGaussian160.2
reward_graspSoftThreshold32–
reward_minimize_rel_lin_velGaussian120.01
reward_minimize_rel_ang_velGaussian240.03
penalty_debris_too_farLinear-16–

distance_debris_too_far activates penalty_debris_too_far; it does not terminate the episode. The finite horizon reports truncated. Episode info has no success, so bounded evaluation reports return only.

Spacewalk (spacewalk)

Humanoid spacewalk: rail-aligned waypoint traversal near spacecraft structure

spacewalk

Simulation only; no trained policy ships. Thruster-less humanoid traverses waypoints and station-keeps by pushing off spacecraft structure.

ModeSelectScenery and pathRail observation / contact
EVA (default)spacewalk / env.mode=evaExterior ISS+Gateway; EVA_WAYPOINT_PATH creates handrailsRail-distance observation
IVAenv.mode=iva / spacewalk_ivaKibou; base retargets to IVA_WAYPOINT_PATH inside rail-free moduleConstant no_handrail_distance; walls unsensed, infer contact from IMU

Aliases spacewalk_eva / spacewalk_iva make benchmark/launch configuration explicit. Built-in EVA waypoints clear the station; custom paths must too, or humanoid, rails, and cameras can enter station meshes. Set env.use_waypoint_path=false for one random target within ±target_pos_range m of spacecraft origin, a simpler reaching ablation.

Train and evaluate.

The task checks only the current waypoint each control step and advances at most one waypoint. Passing through an intermediate waypoint between samples does not count as reaching it.

srb agent train --algo dreamer --env spacewalk_eva
srb agent eval --algo dreamer --env spacewalk_eva --model <path/to/checkpoint>

No task-specific DreamerV3 profile exists; the global preset (deter = 8192, train_ratio = 32) is not tuned for contact locomotion. Evaluation reports:

MetricMeaning
success_rateFraction reaching/holding final waypoint
min_distance_to_targetMinimum sampled distance to the active waypoint; may miss waypoint arrivals
min_distance_to_final_targetClosest final-waypoint distance; completion measure
waypoint_progressPath advancement: index / (num_waypoints − 1)
dist_to_nearest_handrailBody-to-rail distance (EVA)

Diagnose near-zero success. Read min_distance_to_target with waypoint_progress:

  • Low progress + large distance: never nears first waypoint.
  • Low progress + small distance: nears a waypoint, cannot advance reliably.
  • Progress near 1 + zero success: inspect min_distance_to_final_target; above success_radius means goal region not reached, at/below means required hold failed.

EVA scenery. ISSGatewayScenery:

SettingEffect / default
env.scenery.station_template_usd_pathReplace ISS+Gateway with one USD station file
env.scenery.use_exact_station_mesh_collisionTriangular-mesh collision; default false
env.scenery.add_handrails, env.scenery.handrail_segment_specsControl rails aligned to waypoint path
env.scenery.handrail_specsX-axis rail shorthand

Success: final waypoint within success_radius (0.5 m) for success_stability_steps (10 control steps). Episode-sticky flag records reaching and briefly holding, not ending there. Resets randomize position in a ±0.5 m box at EVA path start or Kibou origin, orientation fully, linear velocity ±0.1 m/s, angular velocity ±5°/s.

Control / physicsConstraint
25 Hz control / 200 Hz physics (env_rate = 5 ms, decimation 8)Eight contact-resolving push-off substeps; rate pinned because articulation diverges at 50 Hz orbital default
Finger jointsRate limit: stiffness 40, armature 0.001, undamped period about 31 ms

Observation/action. DreamerV3 vector fields: tf_rot6d_robot (6D orientation), body-frame target vector tf_pos_robot_to_target, path-mean dist_to_spacecraft, nearest-rail distance, normalized progress, body-frame linear/angular velocity, joint positions/velocities, IMU linear acceleration/ angular velocity. No contact state; infer contact from IMU acceleration. Actions: per-joint position targets; dimension follows actuated USD articulation joints at runtime. JointPositionToLimits bounds physical limits. Raw observations: metre-scale distances, [0,1] progress, [-1,1] rot6d. DreamerV3 symlog handles this range; normalize for other algorithms. No real-hardware validation spec, real environment generation, or joint-position actuation adapter.

Episode Length20.0s (500 steps)
Reward Terms9
Default RobotUnitree G1

Robots

Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.5–
penalty_angular_velocityLinear-2–
reward_distance_to_targetGaussian162.5
reward_progressScaled8–
reward_approach_velocityGaussianAlignment120.7854
reward_reachingSoftThreshold32–
reward_stabilityGaussian80.1
reward_success_holdLinear10–
penalty_drift_from_spacecraftSoftThreshold-6–
Reward roleTerms / behavior
Guidancereward_distance_to_target Gaussian (scale 2.5); reward_approach_velocity direction alignment; signed per-step reward_progress.
GoalDominant reward_reaching: sharp soft-threshold at 0.5 m, independent of success_radius except its 0.5 m default.
Holdreward_stability: low-velocity Gaussian in success region; reward_success_hold: success-streak fraction.
SafetyAction-rate/angular-velocity penalties damp jitter; one-sided penalty_drift_from_spacecraft discourages leaving work envelope.

Waypoints reach ~6 m from work-volume centre, within the drift penalty’s 9 m knee, barely penalizing traversal. Leaving structure is effectively unrecoverable without a push surface; the penalty discourages escape without pulling to origin. Reward favors reaching/holding the goal.

Shaping. Distance/reaching rewards follow the current waypoint, advancing immediately on arrival. No advance bonus: observe/report waypoint_progress, never reward it. Intermediate advances transiently drop per-step reward by about that leg’s distance/reaching rewards. Final goal stays optimal; agents must cross the local dip instead of camping outside each radius.

Horizon/contact. Truncate at 20 s / 500 steps; no failure termination and termination always false. Finite horizon (is_finite_horizon=true), so RSL-RL does not bootstrap at the time limit. Rewards cover traversal/station-keeping only; rigid station, Gateway, and handrail contact are neither rewarded nor penalized. No grasp reward or penalty for brushing structure.

Locomotion/routes. Without thrusters/ground, internal joint motion cannot change centre-of-mass velocity; translation needs station/rail push-offs. Randomized initial drift (±0.1 m/s) covers only part of a multi-metre leg. Rails cue distance and provide propulsion; at EVA endpoint, brace to arrest velocity. Rewards measure approach velocity/progress/distance, not contact; infer push-offs from downstream effects. EVA: ~12.5 m exterior rail route with lateral turn; 20 s needs ~0.6 m/s average and efficient push-off chaining. IVA: short, confined Kibou; waypoint spacing comparable to shared 0.5 m success_radius, favoring final acquisition/station-keeping over long-range traversal.

Spacewalk Eva (spacewalk_eva)

Humanoid EVA traversal along exterior spacecraft handrails

spacewalk_eva

Simulation only; no trained policy ships. See Spacewalk for training and evaluation.

Episode Length20.0s (500 steps)
Reward Terms9
Default RobotUnitree G1

Robots

Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.5–
penalty_angular_velocityLinear-2–
reward_distance_to_targetGaussian162.5
reward_progressScaled8–
reward_approach_velocityGaussianAlignment120.7854
reward_reachingSoftThreshold32–
reward_stabilityGaussian80.1
reward_success_holdLinear10–
penalty_drift_from_spacecraftSoftThreshold-6–

Evaluation. Episode-end info publishes success; bounded evaluation reports success rate and return.

Spacewalk Iva (spacewalk_iva)

Humanoid IVA traversal inside the Kibou module

spacewalk_iva

Simulation only; no trained policy ships. See Spacewalk for training and evaluation.

Episode Length20.0s (500 steps)
Reward Terms9
Default RobotUnitree G1

Robots

Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.5–
penalty_angular_velocityLinear-2–
reward_distance_to_targetGaussian162.5
reward_progressScaled8–
reward_approach_velocityGaussianAlignment120.7854
reward_reachingSoftThreshold32–
reward_stabilityGaussian80.1
reward_success_holdLinear10–
penalty_drift_from_spacecraftSoftThreshold-6–

Environments – Digital Twins

Facility-inspired simulator environments, not validated against their physical counterparts.

Lunalab (lunalab)

Digital twin of the LunaLab planetary analogue testbed

lunalab

Episode Length100000.0s (2500000 steps; truncation disabled)
Reward Terms2
Default RobotGeneric Ground Manipulator

Robots

Generic Ground Manipulator

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_undesired_robot_contactsThreshold-0.5–

Zerog Lab (zerog_lab)

Digital twin of a zero-gravity laboratory testbed

zerog_lab

Episode Length100000.0s (1000000 steps; truncation disabled)
Reward Terms2
Default RobotGeneric Orbital Manipulator

Robots

Generic Orbital Manipulator

Rewards
TermTypeWeightScaleNotes
penalty_action_rateLinear-0.1–
penalty_fuel_consumptionLinear-1–

Assets

Overview

Robots, objects, and scenery available in the Space Robotics Bench.

Robot Arms & Manipulators

Serial and dual-arm manipulators registered in the Space Robotics Bench for dexterous manipulation, assembly, and maintenance across terrestrial and space environments.

Overview

Franka

Franka (franka)

7-DoF torque-controlled research arm from Franka Robotics

franka

DoF7
End EffectorFrankaHand
Base Framepanda_link0
Flange Framepanda_link7
Sensors3
Action Modes5 (default: diff_ik)
SourceSRB
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position71.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
panda_shoulderpanda_joint[1-4]87 N·m2.175 rad/s4000800
panda_forearmpanda_joint[5-7]12 N·m2.61 rad/s4000800
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerapanda_link0/camera_base
cam_wristCamerapanda_link7/camera_wrist
Initial Joint Configuration
JointPosition
panda_joint10.0 rad
panda_joint20.0 rad
panda_joint30.0 rad
panda_joint4-1.570796 rad (-90 deg)
panda_joint50.0 rad
panda_joint61.570796 rad (90 deg)
panda_joint70.785398 rad (45 deg)

Kinova

Kinova Gen3N7 (kinova_gen3n7)

7-DoF lightweight research arm from Kinova Robotics

kinova_gen3n7

DoF7
End EffectorNone
Base Framebase_link
Flange Frameend_effector_link
Sensors3
Action Modes6 (default: diff_ik)
SourceIsaac Lab
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
smooth_oscSmooth Operational Space Controller6pos=0.1, ori=0.1
joint_pos_relRelative Joint Position71.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
armjoint_[1-7]540–2340 N·m10 rad/s500200
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCameraend_effector_link/camera_wrist
Initial Joint Configuration
JointPosition
joint_10.0 rad
joint_20.785398 rad (45 deg)
joint_30.0 rad
joint_40.785398 rad (45 deg)
joint_50.0 rad
joint_61.570796 rad (90 deg)
joint_70.0 rad

Kinova J2N6S (kinova_j2n6s)

kinova_j2n6s

DoF6
End EffectorKinova300
Base Framej2n6s_link_base
Flange Framej2n6s_link_6
Sensors3
Action Modes2 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
armj2n6s_joint_[1-6]20–80 N·m100 rad/s1500–4000500–1000
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameraj2n6s_link_base/camera_base
cam_wristCameraj2n6s_link_6/camera_wrist
Initial Joint Configuration
JointPosition
j2n6s_joint_10.0 rad
j2n6s_joint_22.617994 rad (150 deg)
j2n6s_joint_35.759587 rad (330 deg)
j2n6s_joint_4-1.570796 rad (-90 deg)
j2n6s_joint_50.0 rad
j2n6s_joint_60.0 rad

Kinova J2N7S (kinova_j2n7s)

kinova_j2n7s

DoF7
End EffectorKinova300
Base Framej2n7s_link_base
Flange Framej2n7s_link_7
Sensors3
Action Modes2 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
joint_pos_relRelative Joint Position71.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
armj2n7s_joint_[1-7]20–80 N·m100 rad/s1000–4000500–1000
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameraj2n7s_link_base/camera_base
cam_wristCameraj2n7s_link_7/camera_wrist
Initial Joint Configuration
JointPosition
j2n7s_joint_10.0 rad
j2n7s_joint_22.617994 rad (150 deg)
j2n7s_joint_30.0 rad
j2n7s_joint_40.523599 rad (30 deg)
j2n7s_joint_51.570796 rad (90 deg)
j2n7s_joint_60.0 rad
j2n7s_joint_70.0 rad

Multi-Arm

Levion Arms (levion_arms)

levion_arms

DoF4
End EffectorNone
Base Framebase_link
Sensors0
Action Modesdefault: dual_arm_joint_pos_abs
Action Modes
ModeControllerDimsScale
dual_arm_joint_pos_abs *Joint Position To Limits41.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
left_armleft_shoulder_joint, left_elbow_joint15 N·m–40080
right_armright_shoulder_joint, right_elbow_joint15 N·m–40080
Initial Joint Configuration
JointPosition
.*shoulder_joint0.0 rad
right_elbow_joint0.4 rad (22.918312 deg)
left_elbow_joint-0.4 rad (-22.918312 deg)

Zeroglab Arms (zeroglab_arms)

zeroglab_arms

DoF7
End EffectorNone
Base Frame_virtual_world
Sensors0
Action Modesdefault: dual_arm_osc
Action Modes
ModeControllerDimsScale
dual_arm_osc *Operational Space Controller24arm_ceiling: pos=0.1, ori=0.1, stiffness=120.0; arm_wall: pos=0.1, ori=0.1, stiffness=120.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
railrail_joint400 N·m0.2 rad/s30002500
arm.*shoulder.*, .*elbow.*, .*wrist.*87 N·m100 rad/s80040
Initial Joint Configuration
JointPosition
rail_joint2 rad (114.591559 deg)
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Two arms (ceiling and wall) share this configuration, each with a rail_joint and six arm joints. DoF, actuators, and initial joints are per arm; dual_arm_osc drives both arms with 12 dimensions each.

SO-ARM100

So Arm100 D5 (so_arm100_d5)

5-DoF low-cost open-source motor-driven arm

so_arm100_d5

DoF5
End EffectorSOArm100Gripper
Base FrameBase
Flange FrameFixed_Gripper
Sensors3
Action Modes3 (default: diff_ik)
SourceSRB
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.05
osc_var_stiffnessOperational Space Controller12pos=0.05, ori=0.05, stiffness=120.0
joint_pos_relRelative Joint Position51.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*10 N·m10 rad/s10020
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameraBase/camera_base
cam_wristCameraFixed_Gripper/camera_wrist
Initial Joint Configuration
JointPosition
Shoulder_Rotation0.0 rad
Shoulder_Pitch-0.261799 rad (-15 deg)
Elbow0.349066 rad (20 deg)
Wrist_Pitch0.087266 rad (5 deg)
Wrist_Roll0.0 rad

So Arm100 D7 (so_arm100_d7)

7-DoF low-cost open-source motor-driven arm

so_arm100_d7

DoF7
End EffectorNone
Base FrameBase
Flange FrameEnd_Servo
Sensors3
Action Modes2 (default: diff_ik)
SourceSRB
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.05
joint_pos_relRelative Joint Position71.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*10 N·m10 rad/s10020
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameraBase/camera_base
cam_wristCameraEnd_Servo/camera_wrist
Initial Joint Configuration
JointPosition
Shoulder_Pitch2.094395 rad (120 deg)
Shoulder_Yaw0.0 rad
Humeral_Rotation0.0 rad
Elbow-1.570796 rad (-90 deg)
Wrist_Roll0.0 rad
Wrist_Yaw0.0 rad
Wrist_Pitch-1.570796 rad (-90 deg)

Space

Canadarm3 (canadarm3)

Large-scale space manipulator for the Lunar Gateway station

canadarm3

DoF7
End EffectorNone
Base Framecanadarm3_large_0
Flange Framecanadarm3_large_7
Sensors3
Action Modes2 (default: diff_ik)
SourceSRB
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
joint_pos_relRelative Joint Position71.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
jointscanadarm3_large_joint_[1-7]2500 N·m5 rad/s4000025000
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameracanadarm3_large_0/camera_base
cam_wristCameracanadarm3_large_7/camera_wrist
Initial Joint Configuration
JointPosition
canadarm3_large_joint_10.872665 rad (50 deg)
canadarm3_large_joint_20.0 rad
canadarm3_large_joint_30.959931 rad (55 deg)
canadarm3_large_joint_41.308997 rad (75 deg)
canadarm3_large_joint_5-0.523599 rad (-30 deg)
canadarm3_large_joint_60.0 rad
canadarm3_large_joint_70.0 rad

Vispa (vispa)

Space manipulator designed for planetary surface operations

vispa

DoF6
End EffectorNone
Base Framelink0
Flange Framelink6
Sensors3
Action Modes3 (default: diff_ik)
SourceSRB
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.05
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
jointsjoint[1-6]500 N·m5 rad/s2500500
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameralink0/camera_base
cam_wristCameralink6/camera_wrist
Initial Joint Configuration
JointPosition
joint10.0 rad
joint2-0.523599 rad (-30 deg)
joint32.094395 rad (120 deg)
joint40.0 rad
joint51.570796 rad (90 deg)
joint60.0 rad

Unitree

Unitree Z1 (unitree_z1)

Compact lightweight arm from Unitree Robotics

unitree_z1

DoF6
End EffectorNone
Base Framelink00
Flange Framelink06
Sensors3
Action Modes2 (default: diff_ik)
SourceIsaac Lab
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.05
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCameralink00/camera_base
cam_wristCameralink06/camera_wrist
Initial Joint Configuration
JointPosition
joint10.0 rad
joint21.570796 rad (90 deg)
joint3-0.785398 rad (-45 deg)
joint40.785398 rad (45 deg)
joint50.0 rad
joint60.0 rad

Universal Robots

Random Ur Manipulator (random_ur_manipulator)

random_ur_manipulator

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur10 (ur10)

Heavy-duty collaborative arm from Universal Robots

ur10

DoF6
End EffectorNone
Base Framebase_link
Flange Frameee_link
Sensors3
Action Modes5 (default: diff_ik)
SourceIsaac Lab
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCameraee_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur10E (ur10e)

ur10e

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur16E (ur16e)

ur16e

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur20 (ur20)

ur20

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur3 (ur3)

Compact collaborative robot arm from Universal Robots

ur3

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
SourceIsaac Sim
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur30 (ur30)

ur30

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur3E (ur3e)

ur3e

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur5 (ur5)

Versatile mid-range collaborative arm from Universal Robots

ur5

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
SourceIsaac Sim
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Ur5E (ur5e)

ur5e

DoF6
End EffectorNone
Base Framebase_link
Flange Framewrist_3_link
Sensors3
Action Modes5 (default: diff_ik)
Action Modes
ModeControllerDimsScale
diff_ik *Differential Inverse Kinematics60.1
osc_fixedOperational Space Controller6pos=0.1, ori=0.1
osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
joint_pos_relRelative Joint Position61.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
arm.*87 N·m100 rad/s80040
Sensors
NameTypeLocation
contacts_robotContact Sensor.*
cam_baseCamerabase_link/camera_base
cam_wristCamerawrist_3_link/camera_wrist
Initial Joint Configuration
JointPosition
shoulder_pan_joint0.0 rad
shoulder_lift_joint-1.570796 rad (-90 deg)
elbow_joint1.570796 rad (90 deg)
wrist_1_joint-1.570796 rad (-90 deg)
wrist_2_joint-1.570796 rad (-90 deg)
wrist_3_joint-1.570796 rad (-90 deg)

Tools

Grippers, hands, and other end-of-arm tools registered in the Space Robotics Bench. They attach to robot arms for dexterous manipulation, sample collection, and assembly.

Overview

Active

Allegro Hand (allegro_hand)

allegro_hand

Typetool
VariantDataset
Collision–

Electric Screwdriver M3 (electric_screwdriver_m3)

electric_screwdriver_m3

Typetool
VariantDataset
Collision–

Electric Screwdriver M5 (electric_screwdriver_m5)

electric_screwdriver_m5

Typetool
VariantDataset
Collision–

Franka Hand (franka_hand)

franka_hand

Typetool
VariantDataset
Collision–

Kinova300 (kinova300)

kinova300

Typetool
VariantDataset
Collision–

Robotiq Hand E (robotiq_hand_e)

robotiq_hand_e

Typetool
VariantDataset
CollisionconvexHull

Shadow Hand (shadow_hand)

shadow_hand

Typetool
VariantDataset
Collision–

So Arm100 Gripper (so_arm100_gripper)

so_arm100_gripper

Typetool
VariantDataset
Collision–

Passive

Manual Screwdriver M3 (manual_screwdriver_m3)

manual_screwdriver_m3

Typetool
VariantDataset
Collisionsdf
Density1500 kg/m³

Manual Screwdriver M5 (manual_screwdriver_m5)

manual_screwdriver_m5

Typetool
VariantDataset
Collisionsdf
Density1500 kg/m³

Random Scoop (random_scoop)

random_scoop

Typetool
VariantDataset
Collisionsdf

Scoop (scoop)

scoop

Typetool
VariantProcedural
Collisionsdf

Scoop Custom1 (scoop_custom1)

scoop_custom1

Typetool
VariantDataset
Collisionsdf

Scoop Custom2 (scoop_custom2)

scoop_custom2

Typetool
VariantDataset
Collisionsdf

Scoop Custom3 (scoop_custom3)

scoop_custom3

Typetool
VariantDataset
Collisionsdf

Scoop Rectangular (scoop_rectangular)

scoop_rectangular

Typetool
VariantDataset
Collisionsdf

Scoop Spherical (scoop_spherical)

scoop_spherical

Typetool
VariantDataset
Collisionsdf

Scoop Triangular (scoop_triangular)

scoop_triangular

Typetool
VariantDataset
Collisionsdf

Mobile Robots

Mobile platforms registered in the Space Robotics Bench include wheeled rovers, legged robots, aerial vehicles, landers, spacecraft, and a surface vessel for navigation and locomotion tasks.

Overview

Landers

Apollo Lander (apollo_lander)

apollo_lander

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Mass4280 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust171.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Peregrine Lander (peregrine_lander)

peregrine_lander

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Mass825 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust171.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Random Lander (random_lander)

random_lander

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Action Modes
ModeControllerDimsScale
thrust *Thrust31.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Resilience Lander (resilience_lander)

resilience_lander

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Mass340 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust91.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Vikram Lander (vikram_lander)

vikram_lander

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Mass626 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust131.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Legged Robots

Anymal C (anymal_c)

anymal_c

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
legs.*HAA, .*HFE, .*KFE80 N·m7.5 rad/s––
Sensors
NameTypeLocation
imu_robotImubase
contacts_feetContact Sensor.*FOOT
cam_frontCamerabase/camera_front
Initial Joint Configuration
JointPosition
.*HAA0.0 rad
.*F_HFE0.4 rad (22.918312 deg)
.*H_HFE-0.4 rad (-22.918312 deg)
.*F_KFE-0.8 rad (-45.836624 deg)
.*H_KFE0.8 rad (45.836624 deg)

Anymal D (anymal_d)

anymal_d

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
legs.*HAA, .*HFE, .*KFE80 N·m7.5 rad/s––
Sensors
NameTypeLocation
imu_robotImubase
contacts_feetContact Sensor.*FOOT
cam_frontCamerabase/camera_front
Initial Joint Configuration
JointPosition
.*HAA0.0 rad
.*F_HFE0.4 rad (22.918312 deg)
.*H_HFE-0.4 rad (-22.918312 deg)
.*F_KFE-0.8 rad (-45.836624 deg)
.*H_KFE0.8 rad (45.836624 deg)

Cassie (cassie)

cassie

DoF12
End EffectorNone
Base Framepelvis
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limits121.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
legship_.*, thigh_.*, ankle_.*200 N·m10 rad/s100–2003–6
toestoe_.*20 N·m10 rad/s201
Sensors
NameTypeLocation
imu_robotImupelvis
contacts_feetContact Sensor(left|right)_toe
cam_frontCamerapelvis/camera_front
Initial Joint Configuration
JointPosition
hip_abduction_left0.1 rad (5.729578 deg)
hip_rotation_left0.0 rad
hip_flexion_left1 rad (57.29578 deg)
thigh_joint_left-1.8 rad (-103.132403 deg)
ankle_joint_left1.57 rad (89.954374 deg)
toe_joint_left-1.57 rad (-89.954374 deg)
hip_abduction_right-0.1 rad (-5.729578 deg)
hip_rotation_right0.0 rad
hip_flexion_right1 rad (57.29578 deg)
thigh_joint_right-1.8 rad (-103.132403 deg)
ankle_joint_right1.57 rad (89.954374 deg)
toe_joint_right-1.57 rad (-89.954374 deg)

Random Anymal Quadruped (random_anymal_quadruped)

random_anymal_quadruped

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
legs.*HAA, .*HFE, .*KFE80 N·m7.5 rad/s––
Sensors
NameTypeLocation
imu_robotImubase
contacts_feetContact Sensor.*FOOT
cam_frontCamerabase/camera_front
Initial Joint Configuration
JointPosition
.*HAA0.0 rad
.*F_HFE0.4 rad (22.918312 deg)
.*H_HFE-0.4 rad (-22.918312 deg)
.*F_KFE-0.8 rad (-45.836624 deg)
.*H_KFE0.8 rad (45.836624 deg)

Random Unitree Quadruped (random_unitree_quadruped)

random_unitree_quadruped

DoFruntime-resolved
End EffectorNone
Base Frametrunk
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
base_legs.*_hip_joint, .*_thigh_joint, .*_calf_joint33.5 N·m21 rad/s250.5
Sensors
NameTypeLocation
imu_robotImutrunk
contacts_feetContact Sensor.*foot
cam_frontCameratrunk/camera_front
Initial Joint Configuration
JointPosition
.*L_hip_joint0.1 rad (5.729578 deg)
.*R_hip_joint-0.1 rad (-5.729578 deg)
F[L,R]_thigh_joint0.8 rad (45.836624 deg)
R[L,R]_thigh_joint1 rad (57.29578 deg)
.*_calf_joint-1.5 rad (-85.943669 deg)

Spot (spot)

spot

DoFruntime-resolved
End EffectorNone
Base Framebody
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Positionruntime-resolved0.2
Actuators
GroupJointsEffortVelocityStiffnessDamping
spot_hip.*_h[xy]45 N·m–601.5
spot_knee.*_kn––601.5
Sensors
NameTypeLocation
imu_robotImubody
contacts_feetContact Sensor.*foot
cam_frontCamerabody/camera_front
Initial Joint Configuration
JointPosition
[fh]l_hx0.1 rad (5.729578 deg)
[fh]r_hx-0.1 rad (-5.729578 deg)
f[rl]_hy0.9 rad (51.566202 deg)
h[rl]_hy1.1 rad (63.025357 deg)
.*_kn-1.5 rad (-85.943669 deg)

Unitree A1 (unitree_a1)

unitree_a1

DoFruntime-resolved
End EffectorNone
Base Frametrunk
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
base_legs.*_hip_joint, .*_thigh_joint, .*_calf_joint33.5 N·m21 rad/s250.5
Sensors
NameTypeLocation
imu_robotImutrunk
contacts_feetContact Sensor.*foot
cam_frontCameratrunk/camera_front
Initial Joint Configuration
JointPosition
.*L_hip_joint0.1 rad (5.729578 deg)
.*R_hip_joint-0.1 rad (-5.729578 deg)
F[L,R]_thigh_joint0.8 rad (45.836624 deg)
R[L,R]_thigh_joint1 rad (57.29578 deg)
.*_calf_joint-1.5 rad (-85.943669 deg)

Unitree Go1 (unitree_go1)

unitree_go1

DoFruntime-resolved
End EffectorNone
Base Frametrunk
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
base_legs.*_hip_joint, .*_thigh_joint, .*_calf_joint23.7 N·m30 rad/s––
Sensors
NameTypeLocation
imu_robotImutrunk
contacts_feetContact Sensor.*foot
cam_frontCameratrunk/camera_front
Initial Joint Configuration
JointPosition
.*L_hip_joint0.1 rad (5.729578 deg)
.*R_hip_joint-0.1 rad (-5.729578 deg)
F[L,R]_thigh_joint0.8 rad (45.836624 deg)
R[L,R]_thigh_joint1 rad (57.29578 deg)
.*_calf_joint-1.5 rad (-85.943669 deg)

Unitree Go2 (unitree_go2)

unitree_go2

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
base_legs.*_hip_joint, .*_thigh_joint, .*_calf_joint33.5 N·m21 rad/s250.5
Sensors
NameTypeLocation
imu_robotImubase
contacts_feetContact Sensor.*foot
cam_frontCamerabase/camera_front
Initial Joint Configuration
JointPosition
.*L_hip_joint0.1 rad (5.729578 deg)
.*R_hip_joint-0.1 rad (-5.729578 deg)
F[L,R]_thigh_joint0.8 rad (45.836624 deg)
R[L,R]_thigh_joint1 rad (57.29578 deg)
.*_calf_joint-1.5 rad (-85.943669 deg)

Multicopters

Crazyflie (crazyflie)

crazyflie

DoFruntime-resolved
End EffectorNone
Base Framebody
Sensors2
Action Modesdefault: body_acc
Action Modes
ModeControllerDimsScale
body_acc *Multicopter Body Acceleration40.5
Actuators
GroupJointsEffortVelocityStiffnessDamping
dummy.*––00
Sensors
NameTypeLocation
imu_robotImubody
cam_onboardCamerabody/camera_onboard

Ingenuity (ingenuity)

ingenuity

DoF2
End EffectorNone
Base Framebody
Sensors3
Action Modesdefault: body_acc
Action Modes
ModeControllerDimsScale
body_acc *Multicopter Body Acceleration40.5
Actuators
GroupJointsEffortVelocityStiffnessDamping
rotorsrotor_joint_[1-2]7.5 N·m261.799388 rad/s01000
Sensors
NameTypeLocation
imu_robotImubody
cam_onboardCamerabody/camera_onboard
altimeterHeightmap Sensorbody

Orbital Robots

Cubesat (cubesat)

cubesat

DoFruntime-resolved
End EffectorNone
Base Framecubesat
Sensors2
Action Modesdefault: thrust
Action Modes
ModeControllerDimsScale
thrust *Thrust121.0
Sensors
NameTypeLocation
imu_robotImucubesat
cam_onboardCameracubesat/camera_onboard

Floating Platform (floating_platform)

floating_platform

DoF1
End EffectorNone
Base Framebase_link
Sensors2
Action Modes2 (default: thrust_only)
Action Modes
ModeControllerDimsScale
thrust_only *Thrust81.0
thrust_and_reactionThrust9thrust=1.0; reaction_wheel_torque=0.05
Actuators
GroupJointsEffortVelocityStiffnessDamping
reaction_wheelrw_revolute_joint1 N·m100 rad/s00
Sensors
NameTypeLocation
imu_robotImubase_link
cam_onboardCamerabase_link/camera_onboard

Gateway (gateway)

gateway

DoFruntime-resolved
End EffectorNone
Base Framegateway
Sensors2
Action Modesdefault: body_acc
Action Modes
ModeControllerDimsScale
body_acc *Body Acceleration62.5
Sensors
NameTypeLocation
imu_robotImugateway
cam_onboardCameragateway/camera_onboard

Int Ball1 (int_ball1)

int_ball1

DoFruntime-resolved
End EffectorNone
Base Framebase_link
Sensors2
Action Modesdefault: thrust
Mass1 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust61.0
Sensors
NameTypeLocation
imu_robotImubase_link
cam_onboardCamerabase_link/camera_onboard

Int Ball2 (int_ball2)

int_ball2

DoFruntime-resolved
End EffectorNone
Base Framebase_link
Sensors2
Action Modesdefault: thrust
Mass1.5 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust61.0
Sensors
NameTypeLocation
imu_robotImubase_link
cam_onboardCamerabase_link/camera_onboard

Iss (iss)

iss

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: body_acc
Action Modes
ModeControllerDimsScale
body_acc *Body Acceleration62.5
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Satellite Mockup (satellite_mockup)

satellite_mockup

DoFruntime-resolved
End EffectorNone
Base Framesatellite_mockup
Sensors2
Action Modesdefault: thrust
Action Modes
ModeControllerDimsScale
thrust *Thrust121.0
Sensors
NameTypeLocation
imu_robotImusatellite_mockup
cam_onboardCamerasatellite_mockup/camera_onboard

Starship (starship)

starship

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Mass100000 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust181.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Super Heavy (super_heavy)

super_heavy

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Mass200000 kg
Action Modes
ModeControllerDimsScale
thrust *Thrust591.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Venus Express (venus_express)

venus_express

DoFruntime-resolved
End EffectorNone
Base Framebase
Sensors2
Action Modesdefault: thrust
Action Modes
ModeControllerDimsScale
thrust *Thrust191.0
Sensors
NameTypeLocation
imu_robotImubase
cam_onboardCamerabase/camera_onboard

Surface Vehicles

Heron (heron)

heron

DoFruntime-resolved
End EffectorNone
Base Framebase_link
Sensors2
Action Modesdefault: thrust
Action Modes
ModeControllerDimsScale
thrust *Thrust21.0
Sensors
NameTypeLocation
imu_robotImubase_link
cam_onboardCamerabase_link/camera_onboard

Wheeled Robots

Cadre (cadre)

cadre

DoFruntime-resolved
End EffectorNone
Base Framechassis
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.4, ang=0.7853981633974483
Actuators
GroupJointsEffortVelocityStiffnessDamping
wheel_jointswheel_joint_.*250 N·m6.28 rad/s02000
suspension_jointssuspension_joint.*500 N·m0.25 rad/s4005
Sensors
NameTypeLocation
imu_robotImuchassis
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerachassis/camera_front

Husky (husky)

husky

DoFruntime-resolved
End EffectorNone
Base Framechassis
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.1, ang=0.7853981633974483
Actuators
GroupJointsEffortVelocityStiffnessDamping
wheel_jointswheel_joint_.*250 N·m6.28 rad/s02000
Sensors
NameTypeLocation
imu_robotImuchassis
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerachassis/camera_front

Leo Rover (leo_rover)

leo_rover

DoFruntime-resolved
End EffectorNone
Base Framechassis
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.4, ang=1.0471975511965976
Actuators
GroupJointsEffortVelocityStiffnessDamping
drivewheel_joint_.*80 N·m30 rad/s05000
rockerrocker_joint_.*500 N·m2 rad/s20.5
Sensors
NameTypeLocation
imu_robotImuchassis
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerachassis/camera_front

Mars Rover (mars_rover)

mars_rover

DoFruntime-resolved
End EffectorNone
Base FrameBody
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.5, ang=0.7853981633974483
Actuators
GroupJointsEffortVelocityStiffnessDamping
base_steering.*Steer.*12 N·m6 rad/s80001000
base_drive.*Drive.*12 N·m6 rad/s1004000
passive_joints_boogie.*RevoluteJoint0 N·m15 rad/s00
passive_joints_rocker.*Rocker.*0 N·m15 rad/s00
passive_joints_differential.*Differential.*0 N·m15 rad/s00
Sensors
NameTypeLocation
imu_robotImuBody
contacts_wheelsContact Sensor.*[Dd]rive.*
cam_frontCameraBody/camera_front

Nifty (nifty)

nifty

DoF12
End EffectorNone
Base Framechassis
Sensors3
Action Modesdefault: nifty
Action Modes
ModeControllerDimsScale
nifty *Joint Velocity12joint_vel_wheel_drive=1.5707963267948966; joint_pos_steer=0.7853981633974483; joint_pos_suspension_yaw=0.5235987755982988; joint_pos_suspension_roll=0.2617993877991494
Actuators
GroupJointsEffortVelocityStiffnessDamping
wheel_jointswheel_joint_fl, wheel_joint_fr, wheel_joint_rl, wheel_joint_rr80 N·m1.570796 rad/s080
steer_jointssteer_joint_fl, steer_joint_fr, steer_joint_rl, steer_joint_rr200 N·m0.523599 rad/s10050
suspension_joint_yawsuspension_joint_yaw_f, suspension_joint_yaw_r200 N·m0.261799 rad/s1250750
suspension_joint_rollsuspension_joint_roll_f, suspension_joint_roll_r200 N·m0.261799 rad/s150005000
Sensors
NameTypeLocation
imu_robotImuchassis
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerachassis

Open Source Rover (open_source_rover)

open_source_rover

DoFruntime-resolved
End EffectorNone
Base Framechassis
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.2, ang=0.3490658503988659
Actuators
GroupJointsEffortVelocityStiffnessDamping
joint_wheeljoint_wheel_.*50 N·m40 rad/s02000
joints_steerjoint_steer_.*500 N·m0.5 rad/s10080
joints_rockerjoint_rocker_.*1500 N·m0.3 rad/s252
joints_bogiejoint_bogie_.*750 N·m0.6 rad/s14
joint_linkagejoint_linkage25 N·m0.2 rad/s0.050.1
Sensors
NameTypeLocation
imu_robotImuchassis
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerachassis/camera_front

Perseverance (perseverance)

perseverance

DoFruntime-resolved
End EffectorNone
Base Framebody
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.7, ang=1.3089969389957472
Actuators
GroupJointsEffortVelocityStiffnessDamping
drive_jointsdrive_joint.*150 N·m40 rad/s025000
steer_jointssteer_joint.*400 N·m2 rad/s500200
rocker_jointssuspension_joint_rocker.*2500 N·m5 rad/s4000400
bogie_jointssuspension_joint_bogie.*500 N·m4 rad/s20025
Sensors
NameTypeLocation
imu_robotImubody
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerabody/camera_front

Pragyan (pragyan)

pragyan

DoFruntime-resolved
End EffectorNone
Base Framebody
Sensors3
Action Modesdefault: drive
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.35, ang=1.3962634015954636
Actuators
GroupJointsEffortVelocityStiffnessDamping
drive_jointswheel_drive_joint_.*150 N·m40 rad/s05000
rocker_jointsrocker_joint_.*2500 N·m5 rad/s1000400
bogie_jointsboogie_joint_.*500 N·m4 rad/s250200
Sensors
NameTypeLocation
imu_robotImubody
contacts_wheelsContact Sensor.*wheel.*
cam_frontCamerabody/camera_front

Raph Rover (raph_rover)

raph_rover

DoFruntime-resolved
End EffectorNone
Base Framechassis
Sensors3
Action Modes2 (default: drive)
Action Modes
ModeControllerDimsScale
drive *Wheeled Drive2lin=0.4, ang=1.0471975511965976
drive_filteredFiltered Wheeled Drive2lin=0.4, ang=1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
drivedrive_joint_.*80 N·m30 rad/s0500
steersteer_joint_.*500 N·m2 rad/s40050
Sensors
NameTypeLocation
imu_robotImuchassis
contacts_wheelsContact Sensorwheel.*
cam_frontCamerachassis/camera_front

Mobile Manipulators

Mobile manipulators registered in the Space Robotics Bench: generic platforms that mount a manipulator on an aerial, ground, or orbital base, and humanoid robots. Generic platforms assemble their parts at runtime, so their listed DoF, sensors, and action modes cover only the class defaults; the composed robot inherits those of its parts.

Overview

Combined Platforms

Generic Aerial Manipulator (generic_aerial_manipulator)

DoFruntime-resolved
End EffectorNone
Sensors0
Action Modes–

Generic Ground Manipulator (generic_ground_manipulator)

DoFruntime-resolved
End EffectorNone
Sensors0
Action Modes–

Generic Orbital Manipulator (generic_orbital_manipulator)

DoFruntime-resolved
End EffectorNone
Sensors0
Action Modes–

Humanoids

Humanoid21 (humanoid21)

humanoid21

DoFruntime-resolved
End EffectorNone
Base Framepelvis
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
body.*––2–200.1–5
Sensors
NameTypeLocation
imu_robotImupelvis
contacts_feetContact Sensor(left|right)_foot
cam_frontCamerapelvis/camera_front

Humanoid28 (humanoid28)

humanoid28

DoFruntime-resolved
End EffectorNone
Base Framepelvis
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
body.*––––
Sensors
NameTypeLocation
imu_robotImupelvis
contacts_feetContact Sensor(left|right)_foot
cam_frontCamerapelvis/camera_front

Unitree G1 (unitree_g1)

unitree_g1

DoFruntime-resolved
End EffectorNone
Base Framepelvis
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
legs.*_hip_yaw_joint, .*_hip_roll_joint, .*_hip_pitch_joint, .*_knee_joint, torso_joint300 N·m100 rad/s150–2005
feet.*_ankle_pitch_joint, .*_ankle_roll_joint20 N·m–202
arms.*_shoulder_pitch_joint, .*_shoulder_roll_joint, .*_shoulder_yaw_joint, .*_elbow_pitch_joint, .*_elbow_roll_joint, .*_five_joint, .*_three_joint, .*_six_joint, .*_four_joint, .*_zero_joint, .*_one_joint, .*_two_joint300 N·m100 rad/s4010
Sensors
NameTypeLocation
imu_robotImupelvis
contacts_feetContact Sensor(left|right)_ankle_roll_link
cam_frontCamerapelvis/camera_front
Initial Joint Configuration
JointPosition
.*_hip_pitch_joint-0.2 rad (-11.459156 deg)
.*_knee_joint0.42 rad (24.064227 deg)
.*_ankle_pitch_joint-0.23 rad (-13.178029 deg)
.*_elbow_pitch_joint0.87 rad (49.847328 deg)
left_shoulder_roll_joint0.16 rad (9.167325 deg)
left_shoulder_pitch_joint0.35 rad (20.053523 deg)
right_shoulder_roll_joint-0.16 rad (-9.167325 deg)
right_shoulder_pitch_joint0.35 rad (20.053523 deg)
left_one_joint1 rad (57.29578 deg)
right_one_joint-1 rad (-57.29578 deg)
left_two_joint0.52 rad (29.793805 deg)
right_two_joint-0.52 rad (-29.793805 deg)

The DoF and joint_pos action dimensions are runtime-resolved from the Unitree G1 USD articulation. The actuator configuration includes shoulder, elbow, ankle, and hand-like zero through six joint patterns.

Unitree H1 (unitree_h1)

unitree_h1

DoFruntime-resolved
End EffectorNone
Base Framepelvis
Sensors3
Action Modesdefault: joint_pos
Action Modes
ModeControllerDimsScale
joint_pos *Joint Position To Limitsruntime-resolved1.0
Actuators
GroupJointsEffortVelocityStiffnessDamping
legs.*_hip_yaw, .*_hip_roll, .*_hip_pitch, .*_knee, torso300 N·m100 rad/s150–2005
feet.*_ankle100 N·m100 rad/s204
arms.*_shoulder_pitch, .*_shoulder_roll, .*_shoulder_yaw, .*_elbow300 N·m100 rad/s4010
Sensors
NameTypeLocation
imu_robotImupelvis
contacts_feetContact Sensor(left|right)_ankle_link
cam_frontCamerapelvis/camera_front
Initial Joint Configuration
JointPosition
.*_hip_yaw0.0 rad
.*_hip_roll0.0 rad
.*_hip_pitch-0.28 rad (-16.042818 deg)
.*_knee0.79 rad (45.263666 deg)
.*_ankle-0.52 rad (-29.793805 deg)
torso0.0 rad
.*_shoulder_pitch0.28 rad (16.042818 deg)
.*_shoulder_roll0.0 rad
.*_shoulder_yaw0.0 rad
.*_elbow0.52 rad (29.793805 deg)

Objects

Objects registered in the Space Robotics Bench, from manipulable items such as pegs, bolts, blocks, and rock samples to payloads, pedestals, and lights.

Overview

Construction Blocks

Lego Block 1X1 (lego_block_1x1)

lego_block_1x1

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Lego Block 1X2 (lego_block_1x2)

lego_block_1x2

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Lego Block 1X3 (lego_block_1x3)

lego_block_1x3

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Lego Block 1X4 (lego_block_1x4)

lego_block_1x4

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Lego Block 2X2 (lego_block_2x2)

lego_block_2x2

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Lego Block 2X3 (lego_block_2x3)

lego_block_2x3

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Lego Block 2X4 (lego_block_2x4)

lego_block_2x4

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Random Lego Block (random_lego_block)

random_lego_block

Typemodular_element
VariantDataset
Collisionsdf
Density800 kg/m³

Geological Samples

Apollo Sample (apollo_sample)

apollo_sample

Typecommon
VariantDataset
CollisionconvexHull
Density2000 kg/m³

Asteroid (asteroid)

asteroid

Typecommon
VariantProcedural
CollisionconvexHull
Density2000 kg/m³

Lunalab Boulder (lunalab_boulder)

lunalab_boulder

Typecommon
VariantDataset
CollisionconvexHull
Density2000 kg/m³

Mars Rock (mars_rock)

mars_rock

Typecommon
VariantProcedural
CollisionconvexHull
Density2000 kg/m³

Moon Rock (moon_rock)

moon_rock

Typecommon
VariantProcedural
CollisionconvexHull
Density2000 kg/m³

Random Rock (random_rock)

random_rock

Typecommon
VariantProcedural
CollisionconvexHull
Density2000 kg/m³

Sample Tube (sample_tube)

sample_tube

Typecommon
VariantDataset
CollisionconvexDecomposition
Density1500 kg/m³

Spaceport Moon Rock (spaceport_moon_rock)

spaceport_moon_rock

Typecommon
VariantDataset
CollisionconvexHull
Density2000 kg/m³

Hardware

Bolt M8 (bolt_m8)

bolt_m8

Typecommon
VariantDataset
Collisionsdf

Bolt M8 Tight (bolt_m8_tight)

bolt_m8_tight

Typecommon
VariantDataset
Collisionsdf

Hole (hole)

hole

Typecommon
VariantProcedural
Collision–

Nut M8 (nut_m8)

nut_m8

Typecommon
VariantDataset
Collision–

Nut M8 Tight (nut_m8_tight)

nut_m8_tight

Typecommon
VariantDataset
Collision–

Peg (peg)

peg

Typecommon
VariantProcedural
Collisionsdf
Density1000 kg/m³

Profile Hole (profile_hole)

profile_hole

Typecommon
VariantDataset
Collision–

Profile Peg (profile_peg)

profile_peg

Typecommon
VariantDataset
CollisionboundingCube
Density1000 kg/m³

Short Profile Peg (short_profile_peg)

short_profile_peg

Typecommon
VariantDataset
CollisionboundingCube
Density1000 kg/m³

Other

Beam (beam)

beam

Typecommon
VariantPrimitive
Collision–
Density250 kg/m³

Beneficiation Unit (beneficiation_unit)

beneficiation_unit

Typecommon
VariantDataset
CollisionconvexDecomposition
Density1000 kg/m³

Cargo Bay (cargo_bay)

cargo_bay

Typepayload
VariantDataset
CollisionconvexDecomposition
Density1000 kg/m³

Husky Payload Lunalab (husky_payload_lunalab)

husky_payload_lunalab

Typepayload
VariantDataset
Collision–
Density500 kg/m³

Industrial Pedestal100 (industrial_pedestal100)

industrial_pedestal100

Typepedestal
VariantDataset
Collision–

Industrial Pedestal25 (industrial_pedestal25)

industrial_pedestal25

Typepedestal
VariantDataset
Collision–

Industrial Pedestal50 (industrial_pedestal50)

industrial_pedestal50

Typepedestal
VariantDataset
Collision–

Projector Light (projector_light)

projector_light

Typelight
VariantDataset
Collision–

Raph Shovel (raph_shovel)

raph_shovel

Typepayload
VariantDataset
Collision–

Primitive Shapes

Random Shape (random_shape)

random_shape

Typecommon
VariantPrimitive
Collision–
Density1000 kg/m³

Structures & Containers

Solar Panel (solar_panel)

solar_panel

Typecommon
VariantDataset
Collisionsdf
Density500 kg/m³

Scenery

Environmental scenery registered in the Space Robotics Bench includes terrains, facilities, and other scene elements.

Overview

Facilities

Iss Gateway Scenery (iss_gateway_scenery)

iss_gateway_scenery

Typeextravehicular
VariantDataset
Domainsorbit
Sub-assetsiss, gateway

Set station_template_usd_path on ISSGatewayScenery to use a single static station USD while retaining static collision geometry for stable benchmark scenes. Align segment handrails with benchmark waypoint paths using handrail_segment_specs; handrail_specs is shorthand for X-axis rails.

Kibou (kibou)

kibou

Typeintravehicular
VariantDataset
Domainsorbit
Sub-assetslamp

Zeroglab (zeroglab)

zeroglab

Typeintravehicular
VariantDataset
Domainsorbit
Sub-assetslamp

Terrain

Ground Plane (ground_plane)

ground_plane

Typeterrain
VariantPrimitive
Domainsasteroid, earth, mars, moon

Lunalab (lunalab)

lunalab

Typesubterrane
VariantDataset
Domainsasteroid, earth, mars, moon
Sub-assetsterrain, lamp, boulder

Lunar Site Apollo15 (lunar_site_apollo15)

Typeterrain
Domainsmoon

Lunar Site Apollo17 (lunar_site_apollo17)

Typeterrain
Domainsmoon

Mars Surface (mars_surface)

mars_surface

Typeterrain
Domainsmars

Martian Site Jezero (martian_site_jezero)

Typeterrain
Domainsmars

Martian Site Jezero V2 (martian_site_jezero_v2)

Typeterrain
Domainsmars

Moon Surface (moon_surface)

moon_surface

Typeterrain
Domainsmoon

Oberpfaffenhofen (oberpfaffenhofen)

oberpfaffenhofen

Typeterrain
VariantDataset
Domainsasteroid, earth, mars, moon

Plane (plane)

plane

Typeterrain
VariantPrimitive
Domainsasteroid, earth, mars, moon
Sub-assetsobstacle

Terrain Generator (terrain_generator)

Typeterrain
Domainsasteroid, earth, mars, moon

Integrations & Interfaces

Choose an integration to connect SRB to a framework or tool:

Next: Reinforcement Learning

Integration — Reinforcement Learning

Start training with these steps:

  1. Install SRB.
  2. Complete Basic Usage.
  3. Follow the RL Workflow to train and evaluate an agent.
  4. Optionally, configure Parallelism for environment count, layout, and stacking constraints.

SRB’s Gymnasium environments support Reinforcement Learning (RL) policy prototyping, training, evaluation, and generalization studies across space robotics tasks with modern frameworks. SRB targets Isaac Sim 6.1.0 and Isaac Lab 3.0.0; see Requirements.

RL can develop autonomous behavior under communication delays or environmental uncertainty. SRB provides tasks from navigation to mobile manipulation, procedural generation and domain randomization, and consistent evaluation metrics. Batched data collection depends on task/provider support. The compatibility matrix covers supported robot categories; see Parallelism for environment-count and stacking constraints.

Available Integrations

Official framework integrations:

  • Dreamer [JAX] — Model-based RL.
  • Stable-Baselines3 (SB3) [PyTorch] — Popular RL algorithms.
  • SBX [JAX] — JAX implementations of popular RL algorithms.
  • skrl [PyTorch] - SRB’s adapter supports single-agent RL algorithms through the PyTorch API. It targets the skrl 2.1 API (skrl~=2.1, the Isaac Lab 3.0 profile); other major versions fail early with optional_dependency_unavailable, and checkpoints from skrl 1.x are not supported.
  • TD-MPC2 [PyTorch] — Scalable, sample-efficient model-based RL.
  • RSL-RL [PyTorch] — Fast on-policy PPO, widely used in legged locomotion research.

Unsupported Frameworks

ACME is unsupported: adapters share Isaac Sim’s Python process, and ACME’s dependencies (dm-reverb, dm-launchpad, and dm-acme[jax]’s jaxlib==0.4.3 pin) do not resolve with the SRB Docker runtime’s Python 3.12.

RL Games and RLinf are not SRB integrations.

Next: Reinforcement Learning Workflow

Integration — Imitation Learning

Train an imitation learning (IL) policy from demonstrations with robomimic_* algorithms:

  1. Collect demonstrations with srb agent collect, or use an existing dataset in the robomimic-compatible HDF5 format.
  2. Train with srb agent learn --dataset and a robomimic_* algorithm. See the learning reference.
  3. To prefill an integrated reinforcement learning (RL) framework, export canonical SRB JSONL with srb dataset export. skrl_sac, skrl_ddpg, skrl_td3, and Dreamer can prefill replay from this format; integrated RL frameworks cannot load Robomimic HDF5 directly.

When to Use Imitation Learning

Use IL alongside RL when reward engineering is difficult, rewards are sparse (for example, assembly, sample collection, or docking), or expert trajectories are available from teleoperation, planners, or prior policies. Demonstrations can reduce exploration, but they do not establish a safe operating envelope; hardware deployment needs separate validation. IL rollouts can collect demonstrations or shape RL curricula, but RL checkpoints cannot warm-start from IL checkpoints because their formats differ.

Available Integrations

robomimic (PyTorch) provides BC (MLP/RNN/Transformer), BCQ, CQL, IQL, TD3-BC, GL, HBC, IRIS, and Diffusion Policy, using a standard HDF5 dataset format.

Data Format

Demonstrations use the robomimic-compatible HDF5 layout:

  • Each episode group contains obs/, next_obs/, actions, rewards, terminated, truncated, and dones datasets, plus a per-episode success attribute.
  • Observation keys use <group>/<leaf> paths for SRB observation groups, such as state/<leaf>, proprio/<leaf>, command/<leaf>, and state_privileged/<leaf> when those groups are present.
  • Per-episode success flags support collection-time --success_only filtering.

Datasets from srb agent collect load directly in srb agent learn.

See Also

Next: Imitation Learning Workflow

Integration — Extended Reality (XR)

Add --xr to a simulation-based agent command for XR teleoperation, demonstration collection, or scene inspection through Isaac Sim’s OpenXR pipeline. Target versions: Isaac Sim 6.1.0 and Isaac Lab 3.0.0. SRB XR is untested with headsets.

XR supports immersive teleoperation and demonstration collection, plus inspection of scale, lighting, and hardware placement in Martian, Lunar, and orbital scenes. Trajectory quality and Imitation Learning performance depend on task and device.

Hardware & Software Requirements

XR uses Isaac Sim’s OpenXR runtime. Supported Isaac Sim headsets may work with SRB: Meta Quest (Link/Air Link), Valve Index, HTC Vive, and Windows Mixed Reality. See the Isaac Sim 6.1 documentation for the support matrix and runtime setup.

Enabling XR

Use these flags:

  • --xr — enables the VR/AR XR session.
  • --rendering_mode xr — accepted for XR launches; applies no RTX preset because the XR Kit experience selected by --xr carries XR rendering settings. performance, balanced, and quality select SRB RTX presets.

These flags work with simulation-based agent subcommands: zero, rand, teleop, ros, train, eval, and collect. Flags affect rendering and headset display; actions remain subcommand-specific (teleop uses --teleop_device; zero, rand, eval, and ros use their respective sources).

Visualization of Trained Policies in XR

Inspect a trained policy in-scene, for example when behavior seems odd:

srb agent eval --env peg_in_hole --algo sbx_ppo --xr --rendering_mode xr

Immersive Teleoperation

Pair XR with a teleop device. The headset provides depth perception and head motion; the device supplies actions.

srb agent teleop --env peg_in_hole --xr --rendering_mode xr \
  --teleop_device spacemouse

Demonstration Collection in XR

During collection, observations come from the environment-configured sensors; XR changes the display, not the observations.

srb agent collect --env peg_in_hole --xr --rendering_mode xr \
  --teleop_device spacemouse --num_episodes 50

Tips

  • Prefer env.num_envs=1; parallel environments increase rendering cost and may lower comfort-critical frame rates.
  • For stereo-induced motion sickness, lower env.num_envs or set --rendering_mode performance and use XR for inspection.
  • When collecting, cap long XR episodes with srb agent collect --horizon to limit dataset length.
  • XR controllers are unsupported as teleoperation input.

See Also

Next: ROS 2

Interface — ROS 2 & Space ROS

Use ROS 2 to access supported sensor data and robot actions from simulation and agent workflows. Availability depends on the action space and runtime.

ROS 2 exposes supported simulation data and actions through standard interfaces and messages such as geometry_msgs and sensor_msgs. Use RViz2, tf2, and rosbag2 to visualize, debug, and record data. Nodes can run across processes or machines. Reuse algorithms and control systems as a starting point for hardware workflows, then validate them separately.

Space ROS

Space ROS extends ROS beyond Earth. For SRB, use ROS 2 Jazzy, set RMW_IMPLEMENTATION to rmw_cyclonedds_cpp or rmw_fastrtps_cpp, and set ROS_DOMAIN_ID to an integer from 0 through 232. Space ROS compatibility is unvalidated. Space Robotics Bench continues Parallel ProcGen Environments, developed during the NASA Space ROS Sim Summer Sprint Challenge.

Choose either integration:

  • Indirect (recommended): Run SRB’s ROS 2 interface on standard ROS 2 middleware and communicate with Space ROS nodes through standard ROS 2 interfaces; no Space ROS-specific setup is required beyond the ROS settings above.
  • Direct: Source Space ROS before SRB to run its ROS 2 interface with Space ROS middleware alongside other Space ROS nodes.

Implementation

The bridge dynamically provides:

  • Dynamic interfaces - Creates supported publishers, subscribers, and services for the selected environment; no manual endpoint configuration.
  • Parallel environments - Uses separate ROS namespaces per simulation instance; global control is also available.
  • Message translation - Translates environment states, sensor outputs, and control commands from simulation tensors to ROS interfaces.
  • Data and actions - Interface modules expose supported sensors, transforms, batched Box actions, and step outputs, but not every simulation entity.

Get Started

  1. Installation
  2. Basic Usage
  3. ROS 2 Workflow

Manual TF trajectory visualizer

Use the standalone TF-to-Path node in the checkout to observe transforms. Run it in the ROS domain containing those transforms. It requires sourced ROS 2 Jazzy and the rclpy, tf2_ros, geometry_msgs, and nav_msgs ROS packages; the Python plotting extra does not provide them.

  1. Source ROS 2 Jazzy and run the node from the checkout, replacing the frame names with those from your system:

    source /opt/ros/jazzy/setup.bash
    python srb/interfaces/sim_to_real/utils/visual/ros_tf_traj_display.py \
      --ros-args -p source_frame:=world -p target_frame:=target -p publish_rate_hz:=10.0
    
  2. Add target_path (nav_msgs/msg/Path, published in source_frame) as an RViz Path display.

  3. Stop the node when the observation session ends.

The node preserves transform orientation and keeps at most 1000 poses by default. It publishes visualization data, not robot commands, and has no installed ros2 run executable or srb subcommand.

The waypoint evaluator at srb/interfaces/sim_to_real/utils/eval/waypoint_navigation.py is a separate manual evaluation tool.

Next: ROS 2 Workflow

Environment Configuration

Configure environments with Hydra.

Command-Line Overrides

srb agent <WORKFLOW> --env <ENV> \
    env.domain=moon \
    env.robot=ur10 \
    env.num_envs=4 \
    env.stack=false \
    ...

Configuration Files

Each environment’s @configclass extends BaseEnvCfg. Hydra loads task Python defaults, merges CLI overrides, and writes the resolved config to <logdir>/.hydra/config.yaml unless the command disables its output directory.

Save overrides in YAML and pass them with --cfg:

srb agent zero --env peg_in_hole --cfg ./my_overrides.yaml

For example, my_overrides.yaml can contain:

env:
  domain: mars
  num_envs: 8
  robot: ur10

Note: --cfg default uses the environment default; --cfg ignore, none, or null disables the config file.

Tip: Dict-form asset shortcuts expand automatically: env.robot=franka becomes env.robot.name=franka.

Key Parameters

Scenario/Environment

  • env.domain - Domain
  • env.ephemeris - Ephemeris
  • env.robot - Robot
  • env.scenery - Set a registry asset name, such as env.scenery=moon_surface.
    • For asset-instance scenery, set fields such as env.scenery.flat_area_size=3.0 or env.scenery.boulder_count=0.
    • If the task accepts a scenery variant (Scenery | AssetVariant), you can also set body, lat_deg, lon_deg, and size_m. Set lat_deg, lon_deg, and size_m to construct RealTerrain. The default body is env.domain (moon, mars, or earth).
    • Fixed-type scenery, such as terrain_landscaping’s Plane, accepts only that asset’s fields.
  • env.robot_spawn_height_range - Ground tasks only: root height offset range in metres above the robot’s default spawn height, applied on reset, e.g. env.robot_spawn_height_range=[0.3,0.5]. If unset, the task’s randomize_robot_state range applies.
  • env.num_envs, env.stack - Parallelism
  • env.particles - Particles
  • env.reward - Reward & Normalization

Simulation

  • env.sim - Low-level simulation parameters (physics, rendering, etc.)
  • env.visuals - Visual appearance settings

Debugging

  • env.debug_vis - Enables debug visualization features

Environment Configuration — Parallelism

Set env.num_envs to choose the number of parallel simulation instances.

Number of Environments

env.scene.num_envs sets the count; env.num_envs overrides it when set:

srb agent rand -e _manipulation env.scene.num_envs=16
srb agent zero -e _manipulation env.num_envs=128

Instances share one batched DirectEnv; cross-environment collisions are filtered. Visual sensors are not guaranteed isolation: spacing or sensor range alone may not prevent cross-environment visibility.

Environment Spacing

env.scene.env_spacing sets environment distance. env.spacing overrides it when set; otherwise the scene value is inherited:

srb agent rand -e _manipulation env.num_envs=64 env.scene.env_spacing=20.0
srb agent rand -e _manipulation env.num_envs=32 env.spacing=10.0

Note: env.stack=true forces env.scene.env_spacing=0.0; otherwise the framework applies env.spacing when set or inherits env.scene.env_spacing.

Environment Stacking

env.stack controls asset sharing:

Independent Environments (env.stack=false)

  • ⚠️ Each environment has its own scene and position
  • ✅ Greater visual and physical diversity
  • ✅ Supports tasks with visual sensors
  • ❗ Slower initialization
  • ❗ Higher memory use
srb agent rand -e _manipulation env.num_envs=16 env.stack=false

Stacked Environments (env.stack=true)

  • ⚠️ Environments share scenery and position
  • ✅ Faster initialization
  • ✅ Lower memory use
  • ❗ Less environmental diversity
  • ❗ Visual sensor compatibility and camera isolation are not guaranteed; verify the task before relying on them
  • ❗ Stacked multi-environment particle simulation is unsupported: with env.particles=true and env.num_envs != 1, the framework forces env.stack=false and logs a warning
srb agent rand -e _manipulation env.num_envs=16 env.stack=true

Note: Set env.stack=false for visual observations or independent scenery. Defaults are task-specific. These task IDs use env.stack=true: excavation_demo, lunalab, velocity_tracking, locomotion_velocity_tracking, waypoint_navigation, locomotion_waypoint_navigation, orbital_waypoint_navigation, formation_following, formation_following_decentralized, formation_following_orbital, moonfall, traversal, and landing. Stacking shares scenery and forces spacing to zero:

srb agent train --algo dreamer --env waypoint_navigation \
  env.num_envs=64 env.stack=false

Environment Configuration — Domain

Set env.domain to choose a planetary or orbital domain. Each domain provides default gravity and lighting. Scenery provides terrain. Domains have no atmospheric model.

Available Domains

Choose one of five domains. No shipped task defaults to earth or asteroid:

DomainDescription
moon [default]Lunar surface
marsMartian surface
earthEarth surface
asteroidLow-gravity body
orbitOrbital microgravity environment

Set the domain on the command line:

# Run a simulation on Mars
srb agent teleop --env sample_collection env.domain=mars

Gravity affects free bodies and mobile bases. Shipped manipulators disable gravity. To use gravity from another domain, set env.gravity=<domain>. This also uses that domain’s gravity randomization. modular_assembly defaults to earth gravity.

Lighting sets intensity, color temperature, angular diameter, and skydome. To set fog, use env.visuals.fog. Rendered irradiance is not calibrated atmospheric lighting.

Variant resolution excludes candidates whose nonempty DOMAINS omits the selected domain; an empty list permits all. This rule applies only to variants.

Environment Configuration — Robot

Tip: List registered robots and categories with srb ls --live robot; list cached names with srb ls robot. Use supported _ categories in -e.

Robot Selection

srb agent rand -e _manipulation env.robot=ur10
srb agent rand -e _ground env.robot=unitree_go1
srb agent rand -e _aerial env.robot=crazyflie

Select a robot with env.robot=<name>. This replaces task values and resets the robot’s owned fields, end effector, and payload. Kinova on Franka gets its gripper; Husky gets its default payload.

  • Attach a task tool with env.robot=ur10+<tool>; selecting a robot drops task tools.
  • Set env.robot.end_effector=... or env.robot.payload=... in any CLI order. Set a single field with an override such as env.robot.end_effector.<field>=....
  • Set or clear asset fields explicitly when changing selectors. srb agent eval and --continue replay embodiment by reapplying .hydra/overrides.yaml, but values supplied in --cfg YAML can remain through a selector change.
  • Selecting a named top-level asset, such as env.sample=moon_rock, resets it too. Selecting env.robot.mobile_base=... or .manipulator=... preserves that component’s sub-assets.

End Effector for Manipulators

Select an end effector with base+end_effector:

srb agent rand -e _manipulation env.robot=ur10+shadow_hand

Payload for Mobile Robots

Select a payload with base+payload:

srb agent rand -e _ground env.robot=spot+cargo_bay

Payloads can be static rigid geometry or ActivePayload articulations. Active payloads mount as separate scene articulations and add actions after the base. For landscaping, the action order is two filtered RaphRover drive channels, then one continuous RaphShovel velocity channel.

srb agent rand -e terrain_landscaping env.robot=raph_rover+raph_shovel

Landscaping maps normalized [-1, 1] actions to robot/cmd_vel slice [0:2] (linear scale and saturation 0.4 m/s; angular scale and saturation 1.0 rad/s) and payload/joint_vel slice [2:3] (scale and saturation 0.04 m/s). These are simulator limits, not hardware-calibrated. See Terrain Landscaping Training.

Asset-instance CLI customizations. Each srb agent or srb real_agent invocation rebuilds task config through Hydra.

  • extract_defaults_from_class serializes assets as {"name": ...}, with action_mode, nested assets, and all serializable plain fields (numbers, strings, booleans, or lists, tuples, and dicts thereof), including class defaults. Serializable config fields pass through; nonserializable manager-term configs are skipped.
  • AssetResolver calls asset constructors with declared values for model_post_init and the spawner. It also sends overrides such as env.scenery.flat_area_size=3.0 to simulation.

Combine Mobile Manipulators

In mobile-manipulation environments, set env.robot.mobile_base and env.robot.manipulator:

srb agent rand -e _ground_manipulation env.robot.mobile_base=unitree_a1 env.robot.manipulator=unitree_z1
srb agent rand -e _ground_manipulation env.robot.mobile_base=anymal_d+cargo_bay env.robot.manipulator=ur10+shadow_hand

Compose a mobile manipulator in one env.robot token. Use a registered mobile robot, manipulator, and optional end effector. Tasks whose default robot is not a composite mobile manipulator accept only ground mobile bases here:

srb agent rand -e _ground_manipulation env.robot=unitree_a1+unitree_z1
srb agent rand -e _ground_manipulation env.robot=husky+ur10+robotiq_hand_e

Change Action Modes

Set action_mode with a Hydra override on the robot, mobile base, manipulator, or tool. Each robot, active payload, and active tool adds its action_mode to the action space. This works for registered tasks whose composed robot exposes the field:

srb agent rand -e _manipulation env.robot.action_mode=joint_pos_rel
srb agent rand -e _manipulation env.robot=ur10 env.robot.action_mode=joint_pos_rel

Environment Configuration — Particles

Set env.particles=true to use granular materials such as regolith, sand, and dust. Requires Isaac Sim 6.1.0, Isaac Lab 3.0.0, PhysX, and CUDA GPU dynamics.

srb agent teleop -e _manipulation env.particles=true \
  env.particles_size=0.01 env.particles_ratio=0.1

Enabling Particles

  1. Set env.particles=true.
  2. Choose parameters from the table.

Defaults are in BaseEnvCfg (srb/core/env/common/base/env_cfg.py). Scalars apply to all systems. Two-value ranges interpolate across env.particles_systems. Set particles_init_pos to (x, y, z).

Configuration Parameters

ParameterMeaningDefault
env.particlesEnablefalse
env.particles_systemsIndependent systems per environment1
env.particles_spawnerPile kernel: grid, pyramid, crater_pile, or mound_pilegrid
env.particles_sizeDiameter (m)(0.01, 0.005)
env.particles_areaPile width relative to environment spacing(0.75, 0.5)
env.particles_ratioVolume-fill ratio(0.025, 0.1)
env.particles_heightInteger stack height per system(1, 10)
env.particles_densityPBD density (kg/m³)1600.0
env.particles_frictionParticle friction coefficient1.0
env.particles_dampingVelocity damping0.2
env.particles_cohesionParticle stickiness0.01
env.particles_adhesionSurface stickiness0.05
env.particles_materialAdvanced, non-scalar visual override (VisualMaterialCfg)None
env.particles_dim_xyGrid count per system (dim_x = dim_y)Derived (None)
env.particles_init_posFirst-system position (x, y, z)Derived (None)
env.particles_freezeFreeze after settling but keep renderingfalse
env.particles_conform_to_terrainSnap to terrain without PBD settlingfalse
env.particles_conform_jitterConforming XY scatter (m); 0 keeps a regular grid0.0
env.particles_pile_center_jitterSettled-pile XY offset per reset (m); 0 disables0.0

Behavior

grid fills particles_area. pyramid makes centre-dense piles. Excavation derives particles_dim_xy, particles_height, and particles_init_pos from particles_size (a 0.35 m wide, 0.4 m tall pile at the scoop target) and ignores overrides of those three.

Multiple systems (particles_systems>1) stack vertically and interpolate settings across systems. Particles settle under gravity, collide with rigid bodies and articulations, and can be manipulated. They disable Fabric (env.sim.use_fabric=false) for consistent PhysX state.

Excavation and terrain landscaping track reshaping in runtime heightmaps because PhysX sets cannot be raycast. Landscaping’s versioned external-heightmap interface uses a fixed footprint-aware surface rule, not ad-hoc binning.

Where Particles Are Simulated vs. Where They Are Read

PhysX PBD requires GPU dynamics and a CUDA-capable NVIDIA GPU. Otherwise each set fails at parse time with Particles feature is only supported on GPU. Please enable GPU dynamics flag in Property/Scene of physics scene!; particles stay bit-identically inert while rigid bodies move.

The GPU solver exposes CPU-facing USD points (UsdGeom.Points) through /physics/updateParticlesToUsd. Isaac Sim 6’s CUDA direct-data pipeline suppresses readback, so SRB uses CPU simulation with GPU scene dynamics. Landscaping sets sim.device = "cpu" so its heightmap, reward, and renderer read USD points.

App-global /persistent/physics/overrideGPUSettings overrides authored physxScene:enableGPUDynamics=true. “Force CPU” persists 0 in kit/data/Kit/IsaacLab/*/user.config.json, disabling particles; SRB clears it at spawn with a warning. Values are -1 per scene, 0 for CPU, and 1 or 2 for GPU.

Each set’s simulationOwner matches env.sim.physics_prim_path. Missing owners or non-UsdPhysics.Scene targets fail fast without stage traversal. Ownership makes scene assignment deterministic; unowned sets move, so missing ownership alone does not explain inert particles.

Systems are siblings (<env>/particles0System). Isaac Lab clones env_0’s set and target for per-environment variants such as procedural terrain; SRB retargets clones after scene cloning and before physics (DirectEnv._setup_scene). Initialization rejects foreign or shared systems, which solve in the wrong collision group and fall through terrain.

Settling raises instead of caching if any environment’s median height drops over settle_max_median_drop (10 m). Plateaus count as settled only below settle_plateau_max_vel (0.1 m/s); terminal-speed free fall also plateaus.

SRB converts cloned positions and velocities between local and world-frame ParticleSystem buffers, binding each clone to its own system. ParticleSystem.initialize() validates particle-system binding; runtime simulation behavior still needs testing; multiple environments force env.stack=false (see Parallelism). Below-terrain grains may evade the median guard, remain cached, and fall every reset.

Domain Randomization

RandomizationBehavior
env.particles_pile_center_jitterEach reset restores and rigidly translates the settled pile in XY by independent per-environment samples in [-jitter, +jitter], without re-settling. 0.05 shifts ±5 cm without changing its profile; default 0 keeps it fixed. Ignored with env.particles_freeze=true.
Excavation and terrain-landscaping materialEach reset samples PBD friction [0.6, 1.0] and density [2700, 3100] kg/m³, varying repose angle and bulk behaviour. Task-wired, without an env.* knob; friction and density are spawn baselines, not episode constants.

Static Renders

For frozen renders, env.particles_freeze=true disables systems after settling by clearing PhysX particleSystemEnabled and zeroing velocities; points remain visible. Pair with --snapshot. env.particles_conform_to_terrain=true snaps the grid to terrain without PBD settling; env.particles_conform_jitter adds XY scatter. Use when settling is unavailable and regolith needs terrain relief.

Reward & Normalization Configuration


Define task reward configs by inheriting from BaseRewardCfg or a domain subclass.

To retune a term, use a CLI override such as env.reward.penalty_action_rate.weight=-0.2. You usually do not need to edit Python. See the task’s RewardCfg for defaults.

1. Defining a Reward Configuration

Example:

from srb.core.reward import BaseRewardCfg, LinearRewardTerm, GaussianRewardTerm

class RewardCfg(BaseRewardCfg):
    # Smoothness & efficiency penalties
    penalty_action_rate: LinearRewardTerm = LinearRewardTerm(weight=-0.5, limit=4.0)

    # Task specific target rewards
    reward_target_approach: GaussianRewardTerm = GaussianRewardTerm(
        weight=4.0, scale=0.5
    )

On each environment step, the runtime:

  1. Calls advance_step_state() to update per-step state.
  2. Calls extract_step_return() to return current-state metrics in the task dictionary.
  3. Sums the reward terms the task returns and optionally normalizes the total.

2. Types of Reward Terms

Terms are in srb.core.reward.terms, except TukeyRewardTerm in srb.core.reward.normalize. All are exported from srb.core.reward and inherit from RewardTerm.

📐 Linear and Clamped Terms

  • LinearRewardTerm: Scales |metric| linearly; use ScaledRewardTerm to preserve sign. $$\text{Reward} = \text{clamp}(\text{weight} \times |\text{metric}|, -\text{limit}, \text{limit})$$
  • QuadraticRewardTerm: Scales squared metrics by weight.
  • OffsetLinearRewardTerm / OffsetQuadraticRewardTerm: Activate beyond a deadband threshold.

🎯 Kernel and Tracking Terms

  • GaussianRewardTerm: Returns a positive bell-shaped value multiplied by weight; use a negative weight for a penalty. It depends on squared error, so the error sign does not change the result. $$\text{Reward} = \text{weight} \times \exp\left(-\frac{\text{metric}^2}{2 \, \text{scale}^2}\right)$$
  • GaussianTrackingRewardTerm: Gaussian-shaped around its configured target, scaled by weight (positive for reward, negative for penalty).
  • GaussianZoneTrackingRewardTerm: Rewards values within a flat band around its target.

🛡️ Barrier Terms

  • HyperbolicBarrierRewardTerm / GaussianBarrierRewardTerm: Shape rewards or penalties around safety thresholds; contributions approach zero farther beyond them.

3. Reward Normalization

To estimate best and worst step returns, BaseRewardCfg sums signed term reward_bounds and normalize_offset_per_step. One-sided terms use the weight sign. Sign-changing terms such as ScaledRewardTerm and SmoothMaxRewardTerm span both bounds:

$$R_{\text{worst}} = \sum_{T} \text{worst}(T) + o_{\text{worst}} \qquad R_{\text{best}} = \sum_{T} \text{best}(T) + o_{\text{best}}$$

Normalization Modes

Set the reward config’s normalize parameter:

Normalization ModeValueBehavior & MathematicsRecommended For
AUTO (Default)"auto"Uses EPISODE for finite-horizon tasks, otherwise PER_STEP.Default; excavation and terrain_landscaping override it with NONE.
NONE"none"Returns the sum unchanged.Debugging or classic benchmarks.
PER_STEP"per_step"Divides by $S = \max(R_{\text{best}},R_{\text{worst}}
EPISODE"episode"Divides by $S = \max(R_{\text{best}},R_{\text{worst}}

4. Normalization Troubleshooting & Best Practices

Tip

Balance reward terms. An extreme limit such as limit=1000.0 can dominate the scale and make smaller terms negligible.

Print reward bounds to find dominant terms and assess the normalization range:

reward_cfg = YourTaskRewardCfg()
worst, best = reward_cfg.get_bounds()
print(f"Worst per-step: {worst}, Best per-step: {best}")

Randomization, noise and delay profiles

SRB configures three things separately: event randomization, action and observation delay, and Isaac Lab action-noise models.

Task/configRandomizationDelayNoiseProvenance
waypoint_navigationtarget_pose_evolution, a tagged task event at a 0.05 s intervalAction (0, 3) and observation (0, 1) agent steps; per-reset draws use env.seedWaypoint-relative observation noise: 0.01 m / 2.5° episode bias plus 0.0025 m / 0.5° per-step noiseTask defaults; uncalibrated
locomotion_waypoint_navigationInherits target_pose_evolutionInherits action (0, 3) and observation (0, 1) agent stepsInherits waypoint-relative observation noise: 0.01 m / 2.5° episode bias plus 0.0025 m / 0.5° per-step noiseInherited waypoint task config; uncalibrated
waypoint_navigation with env.sim_to_real_profile=waypoint_navigation_synthetic_v1Same target eventAction and observation (1, 2) agent steps, fixed for each episode; 25 Hz means 40–80 msGaussian action noise, standard deviation 0.02 in normalized policy-action units; the waypoint observation noise above remains in metres and radianssynthetic_unmeasured
Other shipped task configsMany define tagged or untagged event termsNo other task config enables nonzero action or observation delayNo default task config enables Isaac Lab action_noise_model or observation_noise_modelPer-task terms

Opt in to the synthetic profile:

srb agent train --algo sbx_ppo --env waypoint_navigation \
  env.sim_to_real_profile=waypoint_navigation_synthetic_v1 \
  env.seed=20260908

The base config sets env.seed=0. default_seed applies only when the task config has env.seed=None; any explicit seed, including 0, wins.

Delay ranges count integer agent steps. At 25 Hz, one step is 0.04 s. On reset, each environment samples its delay. Observation-delay history starts with the fresh observation; action-delay history starts with zeros.

Override delay and noise fields only with values matching the task default or the profile; other values fail. Zero change probability disables boundary redraws, so subset resets cannot reuse another environment’s history. The profile requires agent_rate=0.04 seconds and rejects custom action_noise_model to keep delay and noise units fixed.

The synthetic_unmeasured profile has synthetic delays and Gaussian action noise, not hardware calibration, sensor statistics, or latency measurements.

RandomizationView exposes active event terms and reports untagged EventTermCfg fields as UNTAGGED. The profile does not retag other task configs or enable noise globally.

Environment Configuration — Ephemeris

Use srb.core.ephemeris to query Sun/planet azimuth, elevation, distance, angular diameter, and irradiance scale for a surface site and UTC epoch. Live queries use NASA/JPL NAIF SPICE through spiceypy.

  1. Install the optional dependency for live queries: pip install 'srb[spice]' (srb[all] also includes it). Core srb omits it (wheel ~30 MB); missing spiceypy raises srb.utils.extras.MissingExtraError with this install command.
  2. Fetch kernels with srb ephemeris download or let first use fetch them. Imported table queries need neither kernels nor spiceypy; see Illumination Products.

Kernel Bundle

SPICE needs position (.bsp), orientation (.bpc/.tf), leap-second (.tls), and constants (.tpc) kernels; SRB pins and furnishes this ~43 MB bundle in table order. Bundle coverage is 1849-12-26–2150-01-22; de440s.bsp queries cover 1850-01-01–2149-12-31.

FilePurposeSHA-256
naif0012.tlsLeap seconds; current through 2016-12-31678e32bdb5a744117a467cd9601cd6b373f0e9bc9bbde1371d5eee39600a039b
pck00011.tpcRadii, orientation, IAU_MARS/IAU_EARTH frames3dff7b1dbeceaa01f25467767d3fa25816051c85d162d1edf04acb310ee28bb1
de440s.bspSun, Earth, Moon, Mars barycenter positions; 1849–2150c1c7feeab882263fc493a9d5a5b2ddd71b54826cdf65d8d17a76126b260a49f2
moon_pa_de440_200625.bpcLunar principal-axis orientation, MOON_ME frame60cd55aa401ea2ea97360636f567554bfe4e37bb829f901b4460a455dfaf783f
moon_de440_250416.tfLunar MOON_ME frame aliasesa47c71e9c9f33796bdafb2c9d69a7ee447b6016ecad80f71cd6f3e479f9cf768

KERNEL_BUNDLE in srb/core/ephemeris/kernels.py authoritatively lists files, URLs, and hashes.

Fetching kernels

resolve_kernels() fetches on demand by default, verifies SHA-256, and publishes atomically. Pre-fetch with:

srb ephemeris download

Attribution and redistribution

Kernels come from NAIF’s public archive (https://naif.jpl.nasa.gov/pub/naif/generic_kernels); unmodified files may be redistributed. SRB tries the Hugging Face dataset mirror (SRB_EPHEMERIS_HF_REPO_ID) before NAIF. Acknowledge SPICE/NAIF in published derived data: Acton (1996), “Ancillary data services of NASA’s Navigation and Ancillary Information Facility”; Acton et al. (2018).

Environment Variables

VariableDefaultEffect
SRB_EPHEMERIS_CACHE_ROOT<SRB cache>/ephemeris (checkout: <SRB repo>/.cache; wheel: $XDG_CACHE_HOME/srb or ~/.cache/srb; SRB_CACHE_ROOT overrides)Kernel cache directory; override to share it or use a pre-provisioned read-only mount.
SRB_EPHEMERIS_AUTO_FETCH1 (enabled)0 or false disables on-demand downloads. Missing kernels then raise KernelsMissingError with srb ephemeris download as remedy; no silent network access.
SRB_EPHEMERIS_HF_REPO_IDunsetHugging Face dataset repo id (org/name) tried before NAIF. Unset uses NAIF directly.
SRB_EPHEMERIS_TABLE_PRODUCTunsetProduct file for provider="table" when set_table_product() was not called.

CLI Usage

See CLI reference. Examples:

# Fetch the pinned bundle into the cache
srb ephemeris download

# Query Sun/Earth geometry at a Shackleton-rim-like site
srb ephemeris info --body moon --lat -89.66 --lon 0.0 \
  --utc 2026-11-01T12:00:00 --bodies sun,earth

Programmatic Usage

from srb.core.ephemeris import SiteSpec, query

site = SiteSpec(body="moon", lat_deg=-89.66, lon_deg=0.0, alt_m=0.0)
state = query(site, "2026-11-01T12:00:00", bodies=("sun", "earth"))

sun = state.bodies["sun"]
print(f"az={sun.azimuth_deg:.2f} el={sun.elevation_deg:.2f}")
print(f"irradiance_scale={state.irradiance_scale:.4f}")  # (1 AU / distance)^2

query() dispatches through EphemerisProvider: spice queries kernels; table reads srb_illum/2 without spiceypy at query time.

Terrain lighting

Bakes query live SPICE; imported table products cannot drive terrain bakes.

  1. In a real-terrain site manifest (srb/terrain/manifest.yaml), set lighting: ephemeris, plus surface coords and a curated UTC epoch:

    my_site:
      body: moon
      coords: { lat: 20.1908, lon: 30.7717 }
      lighting: ephemeris
      epoch: "1972-12-11T19:54:57"
    
  2. Bake the terrain. The bridge queries site/epoch once and builds a LightingPreset: solar irradiance and the night-visibility ramp set Sun intensity; body defaults set color temperature and base intensity. The output is .../srb_assets/lights/ephemeris/<body>_<site>_<epoch>_<identity>/generations/<generation id>/lights.usd under SRB_ASSETS_DIR_SRB_LIGHTS. The 16-hex SHA-256 <identity> covers writer version, base/computed presets, coordinates, epoch, and grid-north correction. Immutable generations contain lights.usd and identity.json; identical requests reuse a slot, while changed inputs (including LIGHTS_WRITER_VERSION) get a new one. Publication is locked against concurrent first use and interrupted writers; no manual cache deletion is needed.

Grid north. Convert true-north query azimuth with az_grid = az_true + γ, using persisted north_convergence_deg (γ) in sibling meta.json’s georef block; do not recompute it. γ=0 for equirectangular/lon-0 sites and is nonzero for polar-stereographic patches. srb asset list terrain reports sun=EL°@AZ° (ephemeris @ <utc>, true-north); lights.usd adds +γ, so bearings agree only when γ=0.

Missing kernels. The bridge never queries or downloads. Default on_missing="fallback" warns once per (site, body, epoch) (warn_ephemeris_lighting_fallback_once) and uses the body-default lunar_default/mars_default preset for offline bakes. on_missing="error" raises KernelsMissingError. Fetch with srb ephemeris download; asset listing reports (ephemeris @ <utc>, kernels missing) without querying.

Returning to a named static lighting preset restores byte-identical pre-ephemeris output; unused ephemeris lighting is inert. Static presets use the cache path .../srb_assets/lights/<preset>/<content hash>/generations/<generation id>/lights.usd. Its 16-character hash covers writer version, preset name, and every field, so catalog edits (for example sun_elevation_deg) get a fresh slot.

Environment Lighting

BaseEnvCfg.ephemeris is always EphemerisCfg() (default enabled=False). When enabled, it drives the single global /World/sunlight without a terrain bake. Disabled mode never calls query() or touches the scene graph, so output is unchanged.

  1. Set a fixed epoch to query once at config/scene-build time:

    srb agent teleop -e _ground \
      env.ephemeris.enabled=true \
      env.ephemeris.epoch.utc=2026-11-01T12:00:00
    
  2. Or sample an epoch uniformly on each reset; draws use env.seed for reproducibility:

    srb agent zero -e waypoint_navigation \
      env.ephemeris.enabled=true \
      env.ephemeris.epoch.utc_range='[2026-01-01T00:00:00,2026-12-31T00:00:00]'
    

EpochSpec requires exactly one of utc, utc_range, or utc_windows (duration-weighted; see sunlit_epoch_windows). Fixed mode queries during config/scene construction; features needing live state query the fixed UTC again on reset, and positive time_scale causes interval queries.

A Sun at/below the horizon is valid night and warns once. Sampled mode uses a static config-time placeholder, then randomize_sun_ephemeris re-queries at reset with dedicated np.random.default_rng(env_cfg.seed) on env.unwrapped; equal seeds yield equal epoch sequences. The Sun light is scene-wide, so in sampled mode any reset, including one environment’s partial reset, changes lighting and ephemeris observations for all environments. Visibility may set intensity exactly zero below -angular_radius. The year-long lunar sample spans many ~29.5-Earth-day synodic months and can produce roughly half fully dark Moon episodes: narrow the range or account for darkness in task/reward design. First dark reset per site warns once.

EphemerisCfg optionDefaultBehavior
enabledfalseOpt-in gate; disabled path does not query or touch the scene.
provider"spice"Live SPICE or imported "table" data.
epochEpochSpec(utc="2026-11-01T12:00:00")time_scale=0.0, update_interval_s=600.0.
siteNoneObserver site; precedence below.
orbitNoneRequired on Domain.ORBIT; invalid on surface domains.
bodies("sun",)Requested bodies; must include Sun.
drive_sunlighttrueWhen ephemeris is enabled and drive_sunlight=true (the default), drives /World/sunlight; four static randomizers (randomize_sunlight_orientation, randomize_sunlight_intensity, randomize_sunlight_angular_diameter, randomize_sunlight_color_temperature) are disabled so they cannot overwrite the ephemeris result.
drive_skydomefalseSee Skydome co-drive; requires drive_sunlight=true.
expose_observationsfalseAdds the Direct observation vector; see Observation vector.
eclipsefalseScales Sun intensity by the modeled occluder; see Eclipse.
on_missing"fallback""error" fails early; fallback warns and leaves existing lighting unchanged.

Site resolution (once per environment build):

  1. Explicit env.ephemeris.site wins. Its body must match surface env.domain (else build raises); in orbit mode it selects the central body.
  2. Otherwise, matching-body RealTerrain with a curated manifest site supplies coords and persisted convergence as SiteSpec.north_yaw_deg = −γ (active/passive equivalent of terrain’s az_grid = az_true + γ). A body mismatch ignores terrain with a warning.
  3. Otherwise DEFAULT_SITES: equatorial lon-0 for Moon/Earth; Jezero crater (18.44°N, 77.45°E) for Mars.

Nested SiteSpec defaults to None, so env.ephemeris.site.* has no Hydra CLI overrides or completion keys; children appear only for populated nested defaults. Set it in Python or use real-terrain scenery:

from srb.core.ephemeris import EphemerisCfg, SiteSpec

cfg.ephemeris = EphemerisCfg(
    enabled=True,
    site=SiteSpec(body="moon", lat_deg=-89.66, lon_deg=0.0),
)

Radiometry. Surface intensity is:

intensity = domain.light_intensity
          × irradiance_multiplier(body, state.irradiance_scale)
          × sun_visibility_factor(elevation_deg, 0.5 * angular_diameter_deg)

state.irradiance_scale = (1 AU / r)² is absolute; Domain.light_intensity already uses each body’s mean distance (Mars: 590 W/m² at ≈1.524 AU). Direct multiplication double-counts distance (Mars ≈254 W/m², 43% of correct). irradiance_multiplier normalizes by the mean-distance value, retaining only variation (≈±3.4% Earth/Moon; ≈±19% Mars); a query near mean Mars distance gives ≈591 vs Domain.MARS 590 W/m² (0.18% off). Orbit intensity references 1 AU and applies the scale directly, including Mars-centered orbits.

Missing kernels. Environment lighting only probes pinned kernels on disk. on_missing="error" raises KernelsMissingError before Kit boot; sampled mode rechecks each reset. Default "fallback" warns once per domain (fixed) or site body (sampled), retaining the built-in static or previous-reset light. It does not query, write, or create/advance the epoch RNG.

Enabled ephemeris conflicts with env.sunlight_rpy, since both drive orientation. Supported domains: MOON, MARS, EARTH, configured ORBIT; ASTEROID is rejected. Real terrain runs attach_companions() automatically. drive_sunlight suppresses companion lighting with a one-time warning naming both settings; otherwise companion lighting owns the scene sun (scene.sunlight=None, static sun randomizers skipped), enabling manifest lighting: ephemeris in the running env. See Terrain Stacks: companion and ephemeris sun precedence. Per-env suns are unsupported.

With drive_sunlight=false, do not enable drive_skydome, expose_observations, eclipse, positive epoch.time_scale, or orbit mode; each requires Sun application and raises config ValueError. A surface site.body mismatch with env.domain also raises ValueError.

Orbit and Dynamics

Domain.ORBIT adds a circular-orbit observer, analytic eclipse, moving Sun, optional observations, and skydome co-drive; it has no visual Earth/Moon prim. Orbit numerics use pure NumPy.

Orbit mode (Domain.ORBIT)

The central body defaults to Earth; choose another in Python with site=SiteSpec(body=..., lat_deg=None, lon_deg=None). Orbit sites have no lat/lon; surface sites are rejected.

OrbitSpec fieldDefaultMeaning and limit
altitude_mrequiredAbove mean body radius; must be > 0.
inclination_deg0.0Must be in [0, 180].
raan_deg0.0Right ascension of ascending node.
arg_lat_deg0.0Angle from ascending node at reference epoch (dt_s=0).

Circular Kepler motion uses central-body J2000 axes: n = sqrt(GM/a³), a = body_radius + altitude_m, u = arg_lat_deg + n·dt_s, rotated by R3(-raan) · R1(-inc). GM_M3S2/BODY_RADIUS_M cover Earth, Moon, Mars; other bodies raise. Sun direction uses the body-center SPICE query without observer offset (≈5×10⁻⁵ rad LEO error): suitable for lighting/eclipses, not navigation truth. No J2, drag, or eccentricity.

env.ephemeris.orbit.* has no Hydra CLI overrides or tab-completion keys because the nested default is None; configure it in Python:

from srb.core.ephemeris import EphemerisCfg
from srb.core.ephemeris.orbit import OrbitSpec

cfg.ephemeris = EphemerisCfg(
    enabled=True,
    orbit=OrbitSpec(altitude_m=400_000.0, inclination_deg=51.6),
    eclipse=True,
)

Eclipse

Disk overlap scales Sun intensity: 1.0 no overlap, 0.0 total, 1 − (a_occ/a_sun)² annular, otherwise circular-lens partial-overlap area. No atmosphere, limb darkening, or extra penumbra gradient.

DomainOccluder / behavior
ORBITCentral body synthesized from propagated observer position; no extra SPICE query.
MOON surfaceEarth. Earth geometry is optional unless explicitly listed in env.ephemeris.bodies; absent optional geometry disables eclipse with a warning.
MARS/EARTH surfaceNo occluder; factor 1.0, warning once per site body. Mars moons and Earth-site lunar/solar eclipse geometry are unsupported.

bodies must include Sun. Accepted names: sun, earth, moon, mars, venus; duplicates/unknown names are config errors. SPICE supports all; table products always contain Sun and may contain Earth. A requested but unavailable product body raises typed UnsupportedCapabilityError (fallback allowed); an invalid name raises InvalidInputError. List non-Sun bodies when geometry is needed beyond eclipse’s optional auto-add.

Moving sun

epoch.time_scale must be finite and >=0; positive values update via progress_sun_ephemeris every epoch.update_interval_s simulation seconds (finite and >0) at epoch0 + time_scale × elapsed_sim_time, using fixed/reset lighting logic. epoch0 is fixed UTC or the latest utc_range/utc_windows reset sample. Each reset resamples; shifts outside de440s.bsp query coverage (1850-01-01–2149-12-31) raise _parse_epoch ValueError.

With orbit eclipse and time_scale=0, reset uses dt_s=0, so eclipse remains fixed at arg_lat_deg for the episode. Set time_scale>0 for eclipse cadence.

Phase-dependent earthshine

Moon terrain bakes scale 200-lux earthshine by f=(1+cos φ)/2, where φ (earthshine_fraction) is the Earth phase between Earth→site and Earth→Sun. Full Earth gives f≈1; new Earth gives f≈0. Negative Sun elevation is retained; visibility sets intensity to zero below horizon. Environment mode has no earthshine prim.

Observation vector

When enabled, Direct observations add obs["ephemeris"] with shape (num_envs, 7):

SlotsValues
0:3Sun unit direction in robot base frame (inverse xyzw quaternion rotation).
3:6Occluder unit direction in base frame; zero if no active occluder (eclipse off or none modeled).
6:7Eclipse factor; 1.0 when eclipse is off.

ephemeris_observation reads state cached at config/reset/interval, without SPICE or USD/Isaac work. It merges after the observation-delay wrapper (thus is not delayed); non-finite values become zero.

Skydome co-drive

drive_skydome is inert in ORBIT. On surfaces with drive_sunlight=true, it sets skydome world yaw to -azimuth_sun on config/reset/interval and disables randomize_skydome_orientation. It requires drive_sunlight; yaw is deterministic and follows the Sun, but texture/cardinal alignment is not guaranteed because textures lack directional metadata.

Memory and Threading Contract

spice_provider.py alone imports spiceypy; CLI help, completion, and parser construction remain Isaac-free. CSPICE’s global kernel pool is not thread-safe across furnish/query cycles; SpiceProvider serializes access and furnishes once per process. Repeated queries reuse it. After fork (including pytest-xdist and multiprocessing data loaders), inherited SPICE state is uncertain; the next query calls kclear() before furnishing.

Environment Configuration — Terrain Stacks

Preview terrain coverage without downloading products:

srb asset stack --body moon --lat -89.46 --lon 137.3 --size-m 2000
srb asset stack --body moon --lat -89.46 --lon 137.3 --size-m 2000 --json

The catalog model

V2 fuses a gap-free DEM base with finer partial DEM insets, sunlit/PSR colour, masks, and quality layers for arbitrary regions or declared sites. V1 pairs one DEM with one ortho. Target Isaac Sim 6.1.0 / Isaac Lab 3.0.0 (requirements).

Cache and catalog compatibility

Per-body catalogs (srb/terrain/catalog/<body>.yaml, loaded by srb.terrain.catalog.loader) pin product URLs, SHA-256, footprint, native GSD, license, priority_class, and curated consent. srb.terrain.catalog.resolve.resolve_stacks intersects footprints and returns prioritized DEM, sunlit/PSR colour, mask, and quality stacks in a CompositionPlan.

Preview reports only the --deshade request (on (request) or off); manifest deshade: true can still enable bake correction. Use catalog layers in a manifest version: 2 site’s dem_stack/color_stack, with the v1 RealTerrain(body=..., site=...) or srb asset download terrain <site> interface, or request any region.

Setting / behaviorDefault or limit
SRB_TERRAIN_CATALOG_DIRReplaces shipped catalogs with a hand-built catalog directory.
SRB_TERRAIN_CACHE_ROOTOverrides cache root. Checkouts use SRB scenery cache; wheels use $XDG_CACHE_HOME/srb/terrain, or ~/.cache/srb/terrain if XDG is unset or relative.
Cache identityNamed single-source sites use effective patch geometry, enabled ortho, and attribution; equivalent integer/float geometry spellings share identity. Pre-0.1.0 SRB bakes are not reused: download or bake again. srb asset doctor preserves seed and coordinate precision.
CleanupRaw archives share content identity, so --raw/--all cleanup requires omitting site; baked cleanup is site-specific. Clean incomplete unpublished bakes; inspect corrupt published pointers.
Concurrent raw acquisition (POSIX)Different sources download concurrently; identical content waits for active acquisition. Raw cleanup waits for fetch and verification.
Catalog admissionYAML uses body/layers; rejects unknown catalog/alignment keys, malformed footprint coordinates/rings, and polar caps outside (0, 90]. Polygon topology unchecked. Alignment offsets: dx_m, dy_m, and dz_m.
Region / raster valuesAntimeridian coordinates are rounded; signed zero is normalized. Target GSD must be positive and finite. Integer colour is normalized by dtype maximum; float loaders supply unit-scale values (photometric class has no scale/offset). Mixed stacks are normalized before compositing.
Failed fetchConsent refusal or source-size limits abort the stack; degraded data is not cached. Cached-window identity includes padding distance and resampling method, preserving admitted nodata margins on reread.

Catalog status per body

BodyLayers and curated families
moon (19)pgda_ldem_83s_10mpp / pgda_ldem_80s_20mpp (LOLA polar DEM); NAC DTM: lroc_nac_dtm_shackrdge02, lroc_nac_dtm_nobile03, lroc_nac_dtm_malapert02, lroc_nac_dtm_malapert03; usgs_astro_haworth_sfs_dem_1m; A3CLR Connecting Ridge/Haworth DEM/ortho pairs: zenodo_sfs_a3clr06_connridge_dem_5m / zenodo_sfs_a3clr06_connridge_omos_5m, zenodo_sfs_a3clr02_haworth_dem_5m / zenodo_sfs_a3clr02_haworth_omos_5m; lroc_shadowcam_dtm_faustini_6m + lroc_shadowcam_cmosaic_faustini01_20m; lroc_nac_roi_haworth_lo1_20m; lroc_wac_emp_643nm_south_100m; imbrium_ldam_50s_1000m; pgda_lpsr_85s_60m; and lroc_nac_pole_south_cm065_p892s2250_1m + lroc_nac_pole_south_cm135_p892s2250_1m. The last pair are band-1 P892S2250 tiles, one per subsolar epoch, reference_only: true, resolvable only by explicit layer_id, never bake input.
mars (2)usgs_astro_hirise_jezero_dtm_1m + usgs_astro_hirise_jezero_ortho_1m (HiRISE Jezero).
earth (2)copernicus_glo30_dryvalleys_s78e161 (polar GLO-30); usgs_3dep_nm_southeast_x45y364_1m (non-polar 1 m 3DEP).

Moon catalog details:

  • LDAM is a detached PDS3 .LBL/.IMG pair from HTTPS-only imbrium; cap:50S is its inscribed extent, and nominal 1000 m/pixel holds at the pole.
  • At overlap, priority-3 643 nm WAC_EMP takes precedence over priority-4 1064 nm LDAM, possibly creating a spectral seam.
  • No shipped Moon DEM covers the 50S–60S annulus where LDAM would be the only colour.
  • Only band-1 NAC_POLE_SOUTH_CM P892S2250 (8,276,814,528 B) is pinned per epoch; other tiles (8–31 GB) are not.
  • A3CLR DEMs/orthos cover only Connecting Ridge and Haworth. See Adding a v2 source layer to curate more.

Named site: Jezero v2

The manifest retains v1 jezero and adds jezero_v2: center (18.44, 77.44), 2,000 m medium patch, pinned HiRISE DTM DEM base and ortho colour base.

RealTerrain(body="mars", site="jezero_v2")
srb asset download terrain jezero_v2 --lod medium

Native jezero_v2 bake is not validated against pinned HiRISE products.

Providers

Catalog providers are exact-host allowlists in srb/terrain/sources/*.py. Shipped catalogs use:

ProviderBodyAllowed hostsAuth
pgdamoonpgda.gsfc.nasa.govnone
lroc_pdsmoonpds.lroc.im-ldi.com, data.lroc.im-ldi.com, pds.shadowcam.im-ldi.com, pds.mcp.nasa.govnone
zenodomoonzenodo.org, www.zenodo.orgnone
imbriummoonimbrium.mit.edunone
usgs_astromoon, marsastrogeo-ard.s3.us-west-2.amazonaws.com, asc-astropedia.s3.us-west-2.amazonaws.com, asc-pds-services.s3.us-west-2.amazonaws.com, astrogeology.usgs.gov, pilot.wr.usgs.gov, planetarymaps.usgs.govnone
copernicus_s3earthcopernicus-dem-30m.s3.amazonaws.com, copernicus-dem-90m.s3.amazonaws.comnone
usgs_3depearthprd-tnm.s3.amazonaws.comnone

imbrium (LOLA team’s MIT archive) accepts HTTPS only despite PGDA’s HTTP link; TLS works, so plaintext is refused. Every redirect hop rechecks _accepts_url; HTTPS-to-HTTP downgrade is a hard error. Mars/Earth providers use unauthenticated public HTTPS GETs; they do not configure API-key or SigV4 authentication headers. Signed query-string URLs are not explicitly rejected. Shipped Mars HiRISE layers are USGS ARD COGs via usgs_astro; the registered uahirise provider (hirise.lpl.arizona.edu, www.uahirise.org, uahirise.org) has no shipped layer.

Region requests

  1. Configure RealTerrain with all three region fields; see region identity.
  2. Preview coverage using srb asset stack; see CLI.
  3. Bake with srb asset download terrain or use the same RealTerrain config in an environment.
from srb.assets.scenery import RealTerrain
terrain = RealTerrain(body="moon", lat_deg=-89.66, lon_deg=0.0, size_m=2000.0)

Region identity: the slug

Set lat_deg, lon_deg, and size_m together. Partial input raises ValueError naming missing fields. Region fields cannot be combined with site, dem_path, patch_size_m, or patch_center_xy_m.

Region size and resolved center define the bake footprint. lod maps through. size_m is capped at 8000 m (MAX_REGION_SIZE_M); split larger areas.

Hydra dotted overrides work on any env with RealTerrain scenery:

srb agent teleop -e _ground \
  env.scenery.lat_deg=-89.66 env.scenery.lon_deg=0.0 env.scenery.size_m=2000

Hydra registers these keys (no +) for any task whose scenery accepts a variant (Scenery | AssetVariant). Resolver derives omitted env.scenery.body from env.domain; set it explicitly to request another body:

srb agent teleop -e _ground \
  env.domain=moon env.scenery.body=moon \
  env.scenery.lat_deg=-89.66 env.scenery.lon_deg=0.0 env.scenery.size_m=2000

Python construction, srb asset download terrain --lat --lon --size-m, and srb asset stack --lat --lon --size-m take the same region coordinates; download bakes, stack only previews its source stack. All coordinates are required; Hydra rejects unknown scenery keys.

The machine-independent slug replaces a manifest site name:

region_{body}_{lat_deg:+08.4f}_{lon_deg:+09.4f}_{int(round(size_m))}m
# e.g. region_moon_-89.6600_+000.0000_2000m

Normalization wraps longitude to [-180, 180) (180 = -180), converts signed zero to 0.0, rounds latitude/longitude to 1e-4 degrees (about 3 m on Moon), and size to whole metres. Requests within these quanta share region and cache entry.

Bodies and canonical CRSs

Body = Literal["moon", "mars", "earth"] is supported across requests, catalogs, providers, materials, physics, lighting, augment presets, companions, and scenery. srb.terrain.ingest.planetary_crs.canonical_crs_for supplies polar/geographic CRSs. normalize_crs matches raw DEM headers by projection parameters first, authority code as fast path.

BodySouth polarNorth polarGeographic
moonIAU_2015:30135IAU_2015:30130IAU_2015:30100
marsIAU_2015:49935IAU_2015:49930IAU_2015:49900
earthEPSG:3031EPSG:3413EPSG:4326

Mars uses IAU_2015 sphere radius 3396190.0 m (not the often-quoted 3389500 m ellipsoid figure). Earth polar CRSs use WGS84 semi-major axis 6378137.0 m.

EPSG:3413 (lon_0=-45) matches by authority code only, unlike EPSG:3031; see _CANONICAL_PARAM_SIGNATURES in planetary_crs.py. Polar stereographic lat_ts/k_0 are scale-normalized. WKT equivalent to EPSG:3031 (standard parallel -71) matches; unscaled south-polar WGS84 differs by about 2.7%. Unscaled south-polar WGS84 falls back to matched_by="body_default" (EPSG:4326) and retains its CRS, so reprojection is not skipped. Shipped layers are unscaled polar or geographic; local user DEMs may be affected.

Body-aware, non-polar-capable resolution

At |lat_deg| >= 60°, requests use canonical polar stereographic. Elsewhere, they use a per-request local stereographic CRS for consistent footprint comparisons.

local_stereographic_crs(body, lat_deg, lon_deg) uses the quantized 1e-4° center: +proj=stere +lat_0=<lat> +lon_0=<lon> +R=<body radius> +units=m +no_defs (Earth: +ellps=WGS84). The projection center is (0, 0). Distortion within 8 km is negligible for meshes, containment, and offsets.

Its nonzero center is not a canonical signature, so normalize_crs reports matched_by="body_default"; bake georef preserves the proj string rather than the authority ID. The helper rejects |lat_deg| >= 90 - 1e-9. Poles use the canonical polar CRS to avoid Earth’s unscaled oblique-stereographic scale difference.

What happens when a region can’t resolve

No covering footprint returns an empty plan and warning; environments fall back to procedural terrain, CLI errors, and baking an empty DEM plan raises RegionUnresolvedError:

ConsumerOutcome
RealTerrain environmentWarn once with slug and reason; procedural fallback, training continues.
srb asset download terrain --lat ...Print reason, exit 1; no procedural fallback. If catalog has no layers, error names catalog file and dormancy state.

Footprints: the bbox: form

Catalog footprint (see footprint forms) accepts cap:<lat><N|S>, projected-metre WKT POLYGON(...)/MULTIPOLYGON(...), or geographic degrees:

bbox:<lonmin>,<latmin>,<lonmax>,<latmax>

Use bbox: for non-polar and most Mars/Earth products. WKT needs a shared canonical CRS, while local stereographic varies by request.

Longitudes in [-360, 360] are accepted and normalized once to [-180, 180); common 0–360°E metadata works unchanged. If normalized lonmin > lonmax, the box wraps the antimeridian and contains lon >= lonmin or lon <= lonmax.

Set latmin <= latmax. Inversion raises pydantic.ValidationError naming the footprint at catalog load, before bytes move. Containment projects sample points back via xy_to_latlon in the resolved CRS, then checks the degree box.

CLI

# Region target excludes positional site, --all, and site-only --patch/--patch-size/--center/--no-ortho:
srb asset download terrain --lat -89.66 --lon 0.0 --size-m 2000 \
  [--body moon] [--lod medium] [--deshade] [--force]
# Preview without downloading:
srb asset stack --body moon --lat -89.66 --lon 0.0 --size-m 2000 [--deshade]
# Assess without baking; doctor/info recognize region-derived cache entries:
srb asset doctor terrain [--deshade]

Region downloads use env bake_or_load for consent, cache, and provenance. Doctor/availability download_command reproduces --deshade when needed for its separate cache entry.

Per-env location variety

Region requests can bake K distinct patches (one USD each) for env assignment; manifest sites and local dem_path have fixed footprints. Use num_locations + location_spread_m for seeded offsets or locations for explicit centers:

from srb.assets.scenery import RealTerrain
terrain = RealTerrain(body="moon", lat_deg=-89.66, lon_deg=0.0, size_m=2000.0,
                      num_locations=8, location_spread_m=3000.0)
terrain = RealTerrain(body="moon", size_m=2000.0,
                      locations=[(-89.66, 0.0), (-89.40, 15.0), (-89.80, -20.0)])

Pre-bake serially with same consent/cache/provenance behavior:

srb asset download terrain --lat -89.66 --lon 0.0 --size-m 2000 \
  --num-locations 8 --location-spread-m 3000

Output is <slug>: <path> per location in derivation order. Variety flags require region form (like --patch-size/--center); invalid use or --num-locations < 1 exits 2. locations sets K at any latitude, requires non-empty centers and size_m, shares size_m, lod, and deshade, and excludes lat_deg/lon_deg center and num_locations != 1; location_spread_m must be positive for multiple derived locations. On RegionUnresolvedError, print slug and stop; skip later locations, retaining earlier bakes.

Semantics

AspectBehavior
Primary patchIndex 0 is requested center verbatim (or locations[0]). primary_baked_usd_path anchors companions, SimForge augmentation, and other single-path readers.
DerivationIndexes 1..K-1 use numpy.random.default_rng([905, seed]) with a fixed salt independent of other seed consumers. They are sampled uniformly in a disk (r = location_spread_m · √u) in the resolved CRS: canonical polar near poles, local stereographic elsewhere. Spread defaults to size_m.
Prefix stabilityRNG does not depend on K; increasing K preserves earlier derived slugs and cache entries.
UniquenessAll K slugs must differ after 1e-4°/whole-metre normalization. Collision (small spread or duplicate explicit centers) raises RegionInvalidError, names duplicate slugs, suggests larger spread or deduplication; no dedupe/re-jitter.
SpawningK=1 uses one UsdFileCfg; K>1 uses MultiAssetSpawnerCfg(func=spawn_multi_asset_compat) at env-scoped prim path. PerEnvironmentCloneStrategy assigns env i location i % K; all locations used when num_envs >= K. env.stack=true spawns only index 0.
Bake costAll K bake serially/eagerly at construction or CLI; no lazy/parallel path. Only min(num_envs, K) spawn; K=8, two envs still bakes eight and spawns two.
Clone budgetRegion spawner is never shrunk. Larger K uses more of MAX_CLONE_PLAN_COMBINATIONS = 65536, reducing other multi-variant spawner budget and shrinking SimForge num_assets.

Deshade (illumination-corrected colour)

Set deshade=True to remove capture-time topographic shading from sunlit colour during fusion. For each sunlit layer, divide by a fused-DEM hillshade at catalog sun_azimuth_deg/sun_elevation_deg; preserve mean brightness and NaN nodata. Never deshade PSR. Missing sun angles or fused DEM leave colour unchanged and add named warning to meta.json fusion warnings.

SurfaceSetting
ManifestSite deshade: true in srb/terrain/manifest.yaml.
PythonRealTerrain(..., deshade=True).
CLI--deshade for srb asset download terrain, stack, or doctor.

Effective value is manifest OR request: request True enables, never disables manifest True. It enters v2 cache identity, so on/off bakes coexist; default False leaves key unchanged. V1 single-source sources.dem sites cannot deshade: DeshadeUnsupportedError; CLI checks manifest before fetching bytes.

RequestRequirement and failure
v2 catalog layer estimated over 1 GiB (MAX_UNAPPROVED_SOURCE_BYTES)Curated allow_large_download: true AND fetch-time SRB_TERRAIN_LARGE_OK=1; else LargeDownloadConsentRequiredError, no prompt (check_layer_consent, srb/terrain/sources/acquisition.py).
cog_remoteGate full size_bytes, as full source downloads; see Current limits.
Region requestSame gate for each source’s bytes.
v1 manifest siteSite allow_large_download: true alone.
srb asset stack preview“Consent required” is descriptive (--allow-large OR env var); preview ignores layer allow_large_download, fetches nothing, grants no authorization.

Companions and the ephemeris sun

BaseEnvCfg._add_scenery calls attach_companions() for RealTerrain when attach_companions_enabled=True (default); set false to opt out. Curated-site companions can supply sky, lighting, and rocks. Region requests have no manifest entry and therefore have no companions. Presentation catalogs are srb/terrain/hdri/catalog.yaml, srb/terrain/lights/catalog.yaml, and srb/terrain/rocks/catalog.yaml; source DEM catalogs do not supply companions. No shipped site declares one; no sky dome or rock set ships, so shipped curated-site envs use the default sun/skydome. jezero_late_morning is unused procedural static lighting in srb/terrain/lights; on Jezero it renders much darker than the default sun.

arbitrate_companion_scene resolves companions against enabled env.ephemeris:

Priority / conditionEffect
1. env.ephemeris.enabled and drive_sunlightEphemeris owns sun; suppress companion lighting (warn once). If drive_skydome, suppress companion sky. Rocks attach.
2. Otherwise, companion lighting existsCompanion owns sun: scene.sunlight=None; skip four randomize_sunlight_* randomizers, warning once if configured. scene.lighting and scene.sunlight are mutually exclusive. Manifest lighting: "ephemeris" without enabled env ephemeris uses its baked preset.
3. Companion sky existsReplace domain-default skydome and clear randomize_skydome_orientation, unless operator set non-default string (e.g. env.skydome=high_res) or disabled it (null/false); operator wins.

Each suppression warns once with both conflicting knobs. Region requests silently attach no curated companions; env.ephemeris supplies real sun there. If any site companion fails to build/attach (e.g. offline), the entire set is dropped with a one-time warning; there is no per-product fallback. Attached lighting owns the sun and changes curated-site rendering. Opt out via attach_companions_enabled=False or scenery sky=None/lighting=None. Non-"ephemeris" lighting= presets are procedural.

Illumination sidecar

illumination.npz (srb_illum/2) is an out-of-band sidecar imported by srb ephemeris import, not bake input or a cache-key field. RealTerrain.illumination_product_path points beside the primary/index-0 baked USD (see Per-env location variety); masked-spawn code in srb/core/mdp/illumination.py and the illumination_fraction_at reward helper consume it. See Illumination Products for the schema and importer.

Augmentation database

Bakes can write deterministic crater and rock placements (augmentation.npz, srb_augdb/1), optionally stamp craters into the DEM, and scatter rocks with RealTerrain.augment="database". See Terrain stack augmentation for the schema, determinism, cache identity, and scatter behaviour.

Synthetic super-resolution layer slot

radiometry: synthetic reserves an opt-in schema/resolver slot for model-generated DEM/colour; it sorts after every real candidate:

UseBehavior
Footprint search, defaultExclude synthetic before candidate selection; real layers resolve without warning.
Footprint search, admittedCandidates sort by (is_synthetic, priority_class, native_gsd_m, layer_id), putting synthetic last even below real priority 9 (e.g. synthetic priority 0/GSD 0.5 m).
v2 manifest dem_stack/color_stackExplicit layer_id implicitly admits synthetic. Opt-in filtering also applies to footprint resolution and declared-site mask/quality/PSR-colour candidates.

RegionRequest.allow_synthetic=False and TerrainSpec.allow_synthetic=False are threaded like deshade. This setting is not in the region slug; CacheKey.hash12() appends synthetic=1 only when true because pixels can change. TerrainSpec.allow_synthetic=True with region.allow_synthetic=False raises at construction (the effective value comes from RegionRequest). No shipped catalog has synthetic layers or an integrated model; this feature is unrelated to rock augmentation.

Current limits

LimitEffect / remedy
Coverage is narrowFew pinned products; see Catalog status per body.
cog_remoteCompatibility label only: download complete source via redirect-validating, size-bounded provider; verify pinned SHA-256; read local window. Direct GDAL /vsicurl is refused. First use needs full-source disk space; see Consent. Later bakes reuse content-addressed cache. Fusion meta.json records bytes_verified: true per contributing layer.
Published cache readersReaders hold no lock. Publish retains only new and previous generations; two newer publishes of one entry may delete files used by a long-running process. Restart after re-baking.
Region cache lookupKey needs resolved stack hashes, so each call loads catalog/resolves footprints before cache check (K times for K locations).

Agent Configuration

Configure agents with Hydra.

srb agent train --algo sb3_ppo --env peg_in_hole \
    agent.learning_rate=0.0003 \
    agent.batch_size=128

Default Hyperparameters

Use hyperparams/ for defaults. Add optional task overrides in hyperparams/task/.

Modifying Configurations

Edit framework defaults or pass Hydra overrides.

Configuration Files

Defaults are grouped by framework (YAML except Robomimic’s JSON):

hyperparams/
├── sb3/           # Stable Baselines 3 (ppo, sac, td3, ...)
├── sbx/           # SB3 eXtensions
├── skrl/          # SKRL (ppo, a2c, ppo_rnn, ...)
├── rsl_rl/        # RSL RL
├── robomimic/     # Robomimic
├── dreamerv3.yaml # DreamerV3 (single-algorithm framework)
└── tdmpc2.yaml    # TD-MPC2 (single-algorithm framework)

Use framework-prefixed algorithm names (sb3_ppo, sbx_sac, skrl_ppo, rsl_rl_ppo, dreamer, tdmpc2) and pass Hydra overrides on the command line.

Note: For algorithms with a registered agent dictionary, --cfg replaces the whole agent mapping. Include every required setting; omitted registered values are dropped.

SKRL SAC

hyperparams/skrl/sac.yaml pins SRB’s bounded/squashed Gaussian policy, two critics and target critics, plus explicit terminated/truncated replay flags. skrl_sac supports train, eval, and policy collection.

Tuned configurations

srb agent tune writes the requested modality’s config, resolving task-specific → global layers:

  • hyperparams/<framework>/<algo>.yaml — global per-algorithm set (state observations); <algo>_visual.yaml for visual observations.
  • hyperparams/task/<task>/<framework>/<algo>.yaml — optional per-task override that takes precedence for that task only.

The # Tuned by srb agent tune … provenance header records study, trial, objective, seeds, date, git SHA, and Optuna version. See Hyperparameter Tuning.

Visual profiles (hyperparams/visual_profiles.yaml) do not ship. Optuna tuning spaces are included under srb/tuning/spaces. Without them, train and eval reject --obs visual; use --obs state or supply a valid catalog. tune supports only --obs state.

Event Camera (IMX636)

Configure EventCameraCfg, enable a task camera, and record with srb agent --record-events; use srb dataset record-events for synthetic data.

srb agent zero --headless --env velocity_tracking --record-events 'env.active_sensors=[proprioception,contact,transform,events]'

SRB models the Prophesee IMX636 (EVK4). Per-pixel brightness changes produce microsecond-timestamped events for high-dynamic-range, fast-motion scenes such as lunar shadows, direct sunlight, and docking. Synthetic events are not calibrated against EVK4 data.

The standalone sensor is not a Camera subclass. It has its own pose, intrinsics, high-rate renderer, IMX636 preset, and per-env RNG. Patched v2e_streaming is signal-only and is included in the default image only when the image is built with the provider patch option (Runtime producer bounds).

Configuration

EventCameraCfg configures the sensor. BaseEnvCfg creates its native RGB camera in Isaac; a scene binding retains the Isaac-free config and adds observations.

from srb.core.sensor.event_camera import EventCameraCfg

cfg = EventCameraCfg(
    prim_path="/World/robot/ee/event_cam",
    resolution=(1280, 720),
    sub_render_hz=250.0,
    preset_name="imx636_nominal",
    backend="v2e",
    representation="voxel_grid",
    rng_seed=None,
)
FieldMeaning
resolution: (W, H)Render size before crop/downsample; native IMX636 (1280, 720).
roi_crop: (x, y, w, h)?; downsample: intPre-backend crop and integer downsampling factor; affects observations and stored events.
preset_name: strIMX636Preset, default imx636_nominal; explicit threshold/noise fields override it.
sub_render_hz: floatTick cap, default 250 Hz; see Render-rate guidance.
representation: str; time_bins: intvoxel_grid, histogram, time_surface, stacked, or raw; grid defaults to T=5.
event_chunk_rows: intTransport rows/chunk, default 65,536; capped by provider_workspace_rows and 1,000,000.
observation_window_events: int?Per-step retained-event/memory cap. None = 4·W·H at final geometry (3,686,400 rows, about 118 MB/env/sensor at 32 bytes/event for 1280×720). Overflow fails closed.
provider_workspace_rows: intProvider timestamp/event/permutation workspace cap, default 1,048,576; separate from transport chunks.
backend: strRegistered EventGenerator name.
backend_device: str?Torch provider device (v2e, V2CE); None selects cuda if available, else cpu.
v2ce_model_path: str?Local V2CE checkpoint; a V2CE backend without one fails at construction.
hot_pixel_rate_hz: floatPer-hot-pixel rate from preset hot_pixel_frac mask (200 Hz default). Each tick injects Poisson ON events, capped at 64 per started 1 / sub_render_hz period. Rate is metadata; first post-reset reference frame has none.
rng_seed: int?Base seed; reset mixes env index and episode ID. None uses run seed (env.cfg.seed, via torch.initial_seed()). Name salts sensor seed collisions; backends use private RNGs.

Presets

Built-in presets (srb.core.sensor.event_camera.preset):

Presetpos_thresneg_thressigma_threscutoff_hzshot_noise_rate_hzUse case
imx636_nominal0.200.200.03505Generic indoor / orbital lighting.
imx636_low_light0.200.200.052020Lunar permanently-shadowed regions, deep night.
imx636_outdoor_sunlit0.200.200.02702Direct-sun Mars / lunar daylight.
clean0.200.200.0000Noise-free reference.

Register a custom preset:

from srb.core.sensor.event_camera.preset import (
    IMX636Preset, register_preset,
)

register_preset(IMX636Preset(
    name="excavation_dust",
    pos_thres=0.18, neg_thres=0.18, sigma_thres=0.04,
    cutoff_hz=40.0, leak_rate_hz=0.15,
    shot_noise_rate_hz=12.0, refractory_period_s=5e-4,
    hot_pixel_frac=2e-4,
))

Presets are not calibrated against EVK4. Illumination increases in order: imx636_low_light, imx636_nominal, imx636_outdoor_sunlit. Keep hardware properties refractory_period_s and hot_pixel_frac constant when retuning.

Backends, extras, licenses

Select the backend with cfg.backend = "<name>".

BackendModuleExtraLicenseNotes
noopsrb.core.sensor.event_camera.backend.NoopBackendBuilt-inMITsupports_batching=False; emits zero events for tests and does not consume RGB frames.
v2esrb.core.sensor.event_camera.backends.v2e.V2eBackendsrb[event-v2e] + pinned sourceMIT (v2ecore)Default, supports_batching=False; IMX636 noise, no interpolation, private RNG, episode-relative time.
v2e_streamingsrb.core.sensor.event_camera.backends.v2e.V2eStreamingBackendsrb[event-v2e] + pinned source + local patchMIT (v2ecore)Bounded signal-only EventEmulator.iter_events; no shot-noise ordering claim.
metavisionsrb.core.sensor.event_camera.backends.metavision.MetavisionBackendsrb[event-metavision]Apache-2.0 (openeb)supports_batching=True; GPUEventSimulator from metavision_core_ml.event_simulator.
v2cesrb.core.sensor.event_camera.backends.v2ce.V2CEBackendsrb[event-v2ce]MITsupports_batching=True, learned torch simulator. Uses v2ce.inference.V2CE or ucsd-hdsi-dvs/V2CE-Toolbox (scripts.v2ce_3d + scripts.LDATI). Fetch hf-andrejorsula-v2ce; set v2ce_model_path or model_path=<path> or construction fails.

Env-runtime batched dispatch

EventBackendDispatch checks factory.supports_batching at construction. noop/v2e use one _per_env generator per (env_id, sensor), fed on refresh. metavision/v2ce share one _shared adapter/sensor. On each tick, dispatch calls process_batch(rgb_batch, t_ns) and routes outputs to env buffers. No env mask is used: stale slots are None. Adapters own temporal state and lazily allocate a simulator/model per env. Reset calls reset_env(env_id, seed=…, episode_id=…) for that slice. Batched adapters must override it or dispatch raises ValueError; per-env adapters default to reset() and private-RNG reseeding. Both paths share buffers, manifests, HDF5.

AGPL forbidden. AGPL-licensed event repositories (notably ev-ultralytics) MUST NOT appear in any SRB extra or be vendored into the tree.

Install the extra and pinned v2e source:

pip install 'srb[event-v2e]' 'v2e @ git+https://github.com/SensorsINI/v2e.git@cac638444557a224ba6ee5c29260916f152c00bd'

v2e and reconstruction E2VID are Git-pinned because PyPI rejects direct references, so extras omit them. In checkouts run uv sync --all-extras --group source-event-v2e; source-event-reconstruction carries E2VID and vcs-sources selects all pinned sources.

Missing backend extras or pinned sources raise MissingExtraError with the exact pip install command.

Representations

cfg.representation selects the fixed-shape RL tensor:

RepresentationOutput shapeDescription
voxel_grid(B, T, H, W) float32Polarity-signed time_bins grid (default).
histogram(B, 2, H, W) float32Polarity-separated event counts.
time_surface(B, 2, H, W) float32Exponentially decayed age of last event, per polarity.
stacked(B, 2T, H, W) float32Per-polarity voxel grid stacked along channel.
raw(B, N, 4) int64 + (B,) int64 countsPadded raw event list (length raw_max_events).

B is env count, T = cfg.time_bins, and H/W are effective resolution (after ROI and downsample).

Render-rate guidance

Each new frame is sent once at simulation time; frames less than 1 / cfg.sub_render_hz apart are skipped. The cap cannot raise render rate. Shipped tasks render once per decimated env step; increase render rate for more ticks. Pinned v2e spreads events over the prior-frame interval, so long gaps lose intermediate motion. Manifest/HDF5 sub_render_hz is measured cumulative frame rate (configured cap until frame two). Recommended minimum rates:

Task classRecommended render and event tick rate
Static / slow-manipulation (e.g. inspection)100 Hz
Mobile robotics (rover traverse)250 Hz (sub_render_hz default)
Excavation, drilling, scoop impact500 Hz
Landing touchdown, docking contact1000 Hz

Recording during rollouts

  1. Enable events in env.active_sensors (alias of event_camera). Tasks with an event camera spawn it then: front (velocity_tracking, waypoint_navigation), onboard (landing, moonfall, zerog_lab), or wrist (excavation, sample_collection). Without it, --record-events fails because the scene has no event camera.

  2. Run srb agent with --record-events (zero, rand, teleop, ros, train, eval, collect). BaseEnvCfg adds the camera, DirectEnv binds it, and the recorder writes one file per env/episode/sensor under <run logdir>/camera_videos/<timestamp>/ unless env.camera_record_dir is set.

Live observations always use the configured backend, ROI, downsampling, representation, and validation. HDF5/manifest recording needs camera_record or event_record_requested; RGB MP4 needs camera_record. --record-events sets both. Add visual to env.active_sensors for paired RGB (rgb_mp4_path):

srb agent zero --headless --env velocity_tracking --record-events 'env.active_sensors=[proprioception,contact,transform,visual,events]'

Backends that require RGB fail closed without native RGB. noop accepts missing RGB and emits zero events.

Known v2e_streaming task limits:

  • landing and moonfall (onboard, downward camera): random rollouts can record episodes without events; v2e logs no signal events generated on every frame, and a longer landing rollout can reach the per-episode event-observation element limit while still empty.
  • excavation (wrist camera): depending on the rollout, finalizing an episode can exceed the default observation_window_events bound (3,686,400 rows). Closing the environment raises that failure, so collection does not report success without the episode.
  • Very short episodes can exceed the same bound at reset on other tasks too, for example velocity_tracking with env.episode_length_s=2; its default 20 s episodes stay within it.

For synthetic recordings without Isaac, run srb dataset record-events; its EVENT_HDF5 output works with storage, validation, and export tools.

This command records a deterministic moving-patch fixture, not task or sensor events. Provenance reserves task_id="fixture_moving_patch", policy_id="synthetic_fixture", empty isaaclab_version, and detected SRB revision. --task sets summary task; --policy-id is compatibility-only. Summary source is synthetic_fixture. Detection requires the exact task ID; missing markers/metadata or backend names alone do not identify fixtures.

LeRobot, Zenodo, and NPZ warn and preserve the fixture marker and task/policy identity. LeRobot/Zenodo set contains_synthetic_fixture: true if any selected item is a fixture, including mixed sets. to_zenodo_bundle ignores extra_metadata overrides of that flag/identity. Statistics/reconstruction scorecards warn and save source, task_id, policy_id.

  1. Pass --seed INT to seed the synthetic environment/event-camera run:
srb dataset record-events --output events --backend noop --seed 42

Without it, the process run seed applies. The recorder derives backend seeds per env/episode and records them in manifest seed.

Dataset layout

Files use StorageFormat.EVENT_HDF5. The writer streams into a private staging file (HDF5 SWMR when available, else a warning) and publishes the final path only when the episode closes, so readers never see a partial file. It prefers Blosc:zstd-3 compression, falling back to gzip-6.

The synthetic srb dataset record-events path produces a timestamped output directory under --output; its sensor is named event_camera:

20260521T140312/
├── events_manifest.jsonl
├── events_env0_ep0/
│   └── events_event_camera_env0_ep0.h5
├── events_env0_ep1/
│   └── events_event_camera_env0_ep1.h5
├── events_env1_ep0/
│   └── events_event_camera_env1_ep0.h5
├── events_env1_ep1/
│   └── events_event_camera_env1_ep1.h5
└── ...

event_hdf5_path and rgb_mp4_path are relative to the timestamped run directory and point into the env/episode directory.

srb agent --record-events uses the same layout with a concrete backend and the task’s sensor name (e.g. event_camera_front). rgb_mp4_path pairs event_camera_<name> with the co-located camera’s image_<name>_rgb clip and is empty when that clip is absent; another camera’s clip or a depth clip is never paired.

HDF5 layout

/events/t    int64    ns           (N,)   chunked, compressed
/events/x    uint16                (N,)
/events/y    uint16                (N,)
/events/p    int8     ±1            (N,)
/metadata    group    attrs:
                       schema_version, sensor_preset, resolution,
                       sub_render_hz, backend_name, backend_version,
                       backend_commit_sha, representation, time_bins,
                       episode_id, policy_id, policy_checkpoint_hash,
                       task_id, seed, srb_git_sha, isaaclab_version,
                       rgb_mp4_path (optional), success_flag, reward_summary,
                       compression, event_count, event_sha256,
                       dropped_batches, writer_telemetry,
                       hot_pixel_mask, hf_repo_ids   (JSON-encoded),
                       hot_pixel_rate_hz
                       (optional; absent means unknown)

Schema v1 is frozen; breaking changes bump EVENT_HDF5_VERSION and require a converter and republish.

Before assignment, the writer checks attribute count, UTF-8/JSON bytes, and cumulative storage against fixed ceilings. Rejection aborts its private stage.

Manifest JSONL

One row per (env_id, episode_id, sensor_name):

{
  "sensor_name": "event_camera_onboard",
  "env_id": 0,
  "episode_id": 0,
  "task_id": "landing",
  "seed": 42,
  "event_hdf5_path": "events_env0_ep0/events_event_camera_onboard_env0_ep0.h5",
  "rgb_mp4_path": "",
  "event_count": 184321,
  "event_sha256": "<64 hex digits>",
  "success_flag": 1,
  "reward_summary": "{\"total\": 2.5}",
  "srb_git_sha": "deadbeef",
  "isaaclab_version": "2.x.y",
  "backend_name": "v2e",
  "backend_version": "1.5.0",
  "backend_commit_sha": "",
  "sensor_preset": "imx636_nominal",
  "resolution": [1280, 720],
  "representation": "voxel_grid",
  "time_bins": 5,
  "sub_render_hz": 250.0,
  "policy_id": "ppo_landing_v3",
  "policy_checkpoint_hash": "abc123…"
}

Manifest rows and HDF5 /metadata share EventEpisodeProvenance. Rows also carry routing (sensor_name, env_id, event_hdf5_path, event_count, event_sha256). Both store hot_pixel_mask and hf_repo_ids (JSON in HDF5 attrs).

reward_summary total and final_reward use the (optionally normalized) reward the agent receives; terms holds the raw per-term values of the final step.

srb_git_sha, isaaclab_version, backend_version, policy_checkpoint_hash, and seed describe configuration, not deterministic replay. Dreamer directory SHA-256 covers sorted member paths, sizes, and file hashes; symlinks are recorded, not followed. Empty/unreadable dirs yield an empty hash and warning.

Random/human collection records its controller as policy_id. Strict validation permits empty checkpoint hashes for random, human, zero, rand, teleop, ros, synthetic_fixture; other policies require one. Missing SRB or Isaac Lab provenance fails. srb_git_sha is the Git revision of the SRB checkout, which images also include. It identifies build source, not unchanged runtime files. isaaclab_version is the installed package version and may differ from pinned source.

Reading events

from srb.core.sensor.event_camera import read_event_hdf5

ev = read_event_hdf5("events_env0_ep0/events_event_camera_env0_ep0.h5")
ev["t"], ev["x"], ev["y"], ev["p"]      # numpy arrays
ev["metadata"]                           # dict of attrs

read_event_hdf5 checks row count, decoded column sizes, and cumulative bytes before materializing. Over-limit reads fail without truncation. Iterate larger files instead:

from srb.core.sensor.event_camera.storage import iter_event_hdf5

for chunk in iter_event_hdf5("events_env0_ep0/events_event_camera_env0_ep0.h5", 4096):
    consume(chunk["t"], chunk["x"], chunk["y"], chunk["p"])

Chunks respect requested rows and the repository batch ceiling; final count and digest are validated without assembling the file in memory.

Runtime producer bounds

event_chunk_rows caps transport chunks: dispatch slices oversized one-shot results and rejects oversized streaming yields. With a writer sink, dispatch writes each validated chunk synchronously before pulling again, propagating backpressure to genuine iterators without retaining a result map. Batched iterators yield exactly one entry per env. Iterator, shape, cardinality, sink, or size failures fail that env and abort its staged writer.

Streams must progress: per-env yields cannot be empty; batched yields may have idle envs but need events for one active env. End the iterator for an empty interval or dispatch raises event_camera.stream_no_progress to stop an unbounded empty-yield loop.

strict_streaming=True rejects backends without declared support and a dispatch iterator override (iter_frame per-env, iter_batch batched). Upstream v2e, Metavision, and V2CE return complete arrays/lists, not streams. v2e_streaming uses the patch in srb/core/sensor/event_camera/backends/v2e_pin.toml. Install the pinned base, then apply/check the patch from the SRB wheel:

python -m srb.core.sensor.event_camera.backends.v2e_install --apply
python -m srb.core.sensor.event_camera.backends.v2e_install --check

Docker uses --build-arg SRB_EVENT_V2E_STREAMING=true. The patch bounds timestamp-vector, per-iteration event-matrix, and permutation allocations by provider_workspace_rows; event_chunk_rows caps yields. Set shot_noise_rate_hz=0. Construction/reset require the imported v2ecore.emulator digest to match the patch and provider photoreceptor noise, CSDVS, and SCIDVS off. It emits signal chunks and resets on cancellation. If the recorder rejects a chunk (e.g. writer backpressure timeout), it closes the iterator and rebuilds the emulator. Unpatched materialized output is not strict streaming; shot-noise streaming is unsupported.

Async writer

EventHDF5Writer defaults to async daemon-thread writes so env steps stay non-blocking:

  • Bounded queue.Queue(maxsize=256) between env and writer threads.
  • Saturation raises EventHDF5BackpressureError and aborts the affected staged episode. Published datasets never silently drop event batches.
  • close() enqueues a sentinel and joins the thread, draining everything still queued.

Force synchronous mode (tests, deterministic CI):

from srb.core.sensor.event_camera import EventHDF5Writer

with EventHDF5Writer(path, metadata, async_writes=False) as w:
    w.append(events)

Validation

Run CLI validation on demand, outside the inner loop:

CheckCommandWhat it checks
Statisticssrb dataset validate-events statsEvent rate, polarity ratio, ISI distribution vs. real Gen4.
Reconstructionsrb dataset validate-events reconstructionReconstructed frame SSIM (and optional LPIPS) vs. source RGB.

Both need explicit EVENT_HDF5 inputs, e.g. srb dataset validate-events stats --synth synthetic.h5 --real recorded.h5 --output stats.json. Fetch reference captures by URL or fixture mirror; SRB does not commit them.

stats requires equal declared native resolutions; --resolution fills only missing metadata. Out-of-grid events fail. Per-pixel rate distance is exact 1-D Wasserstein over counts/duration-seconds, allowing unequal stream lengths; non-positive duration yields NaN. Scorecards include on_count and off_count: infinite ON/OFF (no OFF) is JSON null; no events is undefined. --sparsity-window-ms must be finite and at least 1 ns.

Reconstruction-fidelity:

srb dataset validate-events reconstruction \
  --events events.h5 \
  --rgb-npy frames.npy \
  --times-npy frame_times_ns.npy \
  --output recon_card.json \
  --operator baseline      # 'baseline' (pure-numpy) or 'e2vid' (gated)
  # --lpips                  # optional, requires srb[event-reconstruction]

baseline bins events between successive RGB timestamps and min-max normalises per-pixel polarity sums (pure numpy, always available). e2vid requires srb[event-reconstruction]. Fetch its registered checkpoint mirror with srb event-camera fetch-weights --mirror hf-andrejorsula-e2vid before using the operator. SRB uses the MIT e2vid provider from uzh-rpg/e2calib and does not vendor GPL rpg_e2vid code.

When an input carries the exact moving-patch fixture marker, reconstruction scoring warns and persists its source, task, and policy identity in the scorecard. validate-events stats does the same for the marked stream in a pairwise comparison. Marker-free and metadata-free inputs are not inferred to be fixtures.

Model weights

SRB does not redistribute E2VID or V2CE checkpoints. srb event-camera fetch-weights downloads from a registered mirror or explicit URL with its SHA256 and aborts on a digest mismatch. See Weight mirrors for fetch commands, mirror names, hashes, and how to add a mirror.

Publishing datasets

# LeRobot v3 (HuggingFace Hub / behaviour-cloning pipelines)
srb dataset export-lerobot-v3 <event_hdf5_dir> --output ./bundles/lerobot

# Zenodo archival deposit
srb dataset export-zenodo-bundle <event_hdf5_dir> --output ./bundles/zenodo.tar.gz

LeRobot and Zenodo warn and preserve fixture markers. RAW EVT3 and ROS bag reject fixtures because they cannot preserve those markers. Import ordinary task recordings with explicit provenance:

srb dataset import-raw-evt3 landing.raw \
  --output landing.h5 \
  --task landing \
  --policy-id prophesee_landing
srb dataset export-rosbag landing.h5 --output ./landing_bag

Never export record-events output to RAW EVT3 or ROS bag: it always carries the reserved fixture marker, regardless of --task/--policy-id.

LeRobot v3 has no canonical event-camera schema; bundles use SRB’s extended event_camera modality:

bundle/
├── meta/
│   ├── info.json            # codebase_version v3.0 + srb_event_camera schema
│   ├── stats.json
│   ├── tasks.parquet
│   └── episodes/chunk-000/file-000.parquet  # one row per (env, episode, sensor)
├── data/chunk-000/file-000.parquet          # one row per episode, event pointers
└── events/<sensor_name>/chunk-000/episode-{n:06d}.h5  # canonical EVENT_HDF5

info.json adds event_path beside data_path/video_path and an srb_event_camera block (schema version, registered sensors, presets, backends, resolutions). Episode parquet copies manifest provenance (srb_git_sha, policy_checkpoint_hash, backend_version, seed, sub_render_hz, etc.) for filtering without HDF5 reads; these fields do not prove deterministic replay.

fps is the maximum recorded sub_render_hz (measured event tick rate) across rows. Mixed-task bundles (e.g. landing 1000 Hz + traversal 250 Hz) declare the highest rate as temporal resolution.

RAW EVT3 import

Normalize Prophesee RAW EVT3 into canonical EVENT_HDF5 without Metavision/OpenEB:

srb dataset import-raw-evt3 active_marker.raw \
  --output active_marker.h5 \
  --task active_marker \
  --policy-id prophesee_source

The importer requires a % format EVT3 or % evt 3.0 header line, decodes EVT3 address/vector CD events, unwraps 24-bit timestamps to nanosecond t, and stores source resolution in /metadata/resolution. It skips/counts words before the first EVT_TIME_HIGH (mid-stream files), prints skipped_leading_words, and warns if nonzero. Non-empty files without it fail missing_time_high. It ignores bit 11 of EVT_ADDR_Y (system type). After the first EVT_TIME_HIGH, trigger, marker, and continued words have no CD events and are ignored; malformed structure fails closed. The SRB header % srb_t0_ns <digits> is added to each timestamp; any other line naming that key is rejected.

export-raw-evt3 (also without Metavision/OpenEB) and export-rosbag rebase to the first event, floored to microseconds, and record origin in % srb_t0_ns (ROS time_base uses that origin); late-start episodes export correctly. EVT3 timing floors to its microsecond precision. Gaps over 60 s between consecutive events fail.

References

  • Module: srb/core/sensor/event_camera/
  • v2e — Hu et al., “v2e: From Video Frames to Realistic DVS Events”.
  • Prophesee IMX636 / EVK4 product page and datasheet.

Event-Camera Weight Mirrors

Fetch checkpoints with srb event-camera fetch-weights. It verifies SHA256 and aborts on mismatch. SRB does not redistribute weights in the repository.

Artifact--artifact valueFilenameConsumer
E2VID reconstructione2vid (default)E2VID_lightweight.pth.tar (~41 MiB)srb.datasets.event_validation.reconstruction.e2vid_reconstruct
V2CE learned simulatorv2cev2ce_3d.ptsrb.core.sensor.event_camera.backends.v2ce.V2CEBackend

E2VID’s checkpoint comes from rpg_e2vid. SRB’s runtime adapter uses the MIT e2vid package from uzh-rpg/e2calib via srb[event-reconstruction]; do not vendor GPL model code into SRB.

Both maintainer-pinned mirrors are in the public Hugging Face repository AndrejOrsula/srb-event-camera-weights.

MirrorArtifactSHA256
hf-andrejorsula-e2vidE2VID_lightweight.pth.tar4cfeb2c850bf48fc9fa907e969cb8a04e3c51314da2d65bdb81145ac96574128
hf-andrejorsula-v2cev2ce_3d.pt97920e0c3f3c1df55f12800c166bf1de11466f7546bdb7b40261c5a14cddef26

Upstream sources:

  • E2VID: http://rpg.ifi.uzh.ch/data/E2VID/models/E2VID_lightweight.pth.tar
  • V2CE: https://drive.google.com/file/d/1-aC6CTGZgAZk3snANZ46FAGNkPzu_Scw

Fetching weights

Fetch a registered mirror or provide a URL and digest:

srb event-camera list-mirrors
srb event-camera fetch-weights --mirror hf-andrejorsula-e2vid
srb event-camera fetch-weights --mirror hf-andrejorsula-v2ce

srb event-camera fetch-weights --artifact e2vid \
  --url https://example.com/path/to/E2VID_lightweight.pth.tar \
  --sha256 <hex digest>

Mirrors pin artifact identity and verified SHA256; --mirror ignores --artifact and --sha256. Files go to ~/.cache/srb/event_weights/, or $XDG_CACHE_HOME/srb/event_weights/ when set. Private Hugging Face URLs accept bearer tokens from HF_TOKEN, HUGGING_FACE_HUB_TOKEN, or the Hugging Face CLI token cache.

Adding a mirror

Add a WeightMirror to KNOWN_MIRRORS in srb/core/sensor/event_camera/weights.py:

WeightMirror(
    short_name="huggingface-<owner>-e2vid",  # include the artifact kind
    artifact=WeightArtifact(
        name="E2VID_lightweight.pth.tar",
        url="https://huggingface.co/<owner>/<repo>/resolve/main/E2VID_lightweight.pth.tar",
        sha256="<hex digest>",
        size_bytes=<file size>,
    ),
    license_note="GPL-3.0, © 2019 Rebecq et al.",
    notes="Mirrored 2026-MM-DD from rpg_e2vid release X.Y.Z.",
),

Each mirror must:

  1. Fetch through urllib.request without consent interstitials or rate-limited redirects; verify with srb event-camera fetch-weights --url <url> --sha256 <sha> --force.
  2. Serve the exact upstream checkpoint. Give distinct short_name and artifact.name values for modified or retrained checkpoints.
  3. Use a stable URL, not ephemeral or signed storage.
  4. Pin the maintainer-verified SHA256 of a known-good download.
  5. Record the upstream license in license_note: rpg_e2vid published the E2VID checkpoint under GPL-3.0; SRB’s E2VID Python provider (uzh-rpg/e2calib) and V2CE-Toolbox are MIT.

Event-Camera Fixture Mirrors

Use the registered Prophesee Gen4-HD active-marker recording in frozen EVENT_HDF5 schema v1, the Gen4 reference fixture, to test the schema, importer, statistics, and opt-in E2VID path. It is not calibration data.

SRB ships no captures in git. Ownership and publication rights for each recording depend on its source and the terms that govern that recording. Check those terms before redistributing a capture or publishing a mirror.

Fetching fixtures

List and fetch a registered mirror or provide a URL and digest:

srb event-camera list-fixtures
srb event-camera fetch-fixture --mirror hf-andrejorsula-active-marker-gen4

srb event-camera fetch-fixture \
  --url https://your-host.example/gen4_reference.h5 \
  --sha256 <hex digest>

Mirrors pin schema version and maintainer-verified SHA256. Downloads go to ~/.cache/srb/event_fixtures/ by default, or $XDG_CACHE_HOME/srb/event_fixtures/ when XDG_CACHE_HOME is set.

Prophesee Active Marker mirror

The hf-andrejorsula-active-marker-gen4 mirror is in the public AndrejOrsula/srb-event-camera-fixtures dataset. Prophesee’s terms govern redistribution.

To rebuild it, convert Prophesee’s active_marker share (https://kdrive.infomaniak.com/app/share/975517/d39fd010-8d56-4ce1-980d-224d5654b478; ZIP SHA256 3a2aced3efee1b37b89e53bcb8b2882985ff6da9b556e7cfa1494e42e509098f), extract MV_SDK_5_x/active_marker_dataset/active_marker.raw, then import it with srb dataset import-raw-evt3 (see RAW EVT3 import).

The import contains 22,316,758 events at 1280x720.

Adding a fixture mirror

Add a FixtureMirror to KNOWN_FIXTURES in srb/core/sensor/event_camera/fixtures.py:

FixtureMirror(
    short_name="zenodo-<owner>-gen4",  # include the sensor kind
    artifact=FixtureArtifact(
        name="gen4_reference.h5",
        url="https://zenodo.org/records/<id>/files/gen4_reference.h5",
        sha256="<hex digest>",
        size_bytes=<file size>,
        schema_version=1,
        sensor_model="prophesee_gen4_hd",
        num_episodes=<count>,
    ),
    license_note="CC-BY-4.0, © 2026 <owner/lab>",
    notes="Captured 2026-MM-DD on EVK4-HD, <scene summary>.",
),

Each mirror must:

  1. Fetch through urllib.request without consent interstitials or expiring signed URLs; verify with srb event-camera fetch-fixture --url <url> --sha256 <sha> --force.
  2. Serve EVENT_HDF5 schema v1 with EventEpisodeMetadata reproducibility attributes. Give modified or resampled captures distinct short_name and artifact.name values.
  3. Pin the sensor model in FixtureArtifact.sensor_model.
  4. Use stable hosting (Zenodo, Hugging Face datasets, or an institutional research-data repository), not ephemeral or presigned storage.
  5. Pin the maintainer-verified SHA256 of a known-good download.
  6. Record capture licensing in license_note (often CC-BY-4.0 for academic captures); never exceed upstream terms.

Command Line Interface (CLI)

Run srb <subcommand> [options]; use -h/--help for help or TAB to browse:

srb --help
srb <subcommand> -h
srb <TAB> <TAB>

Subcommands

SubcommandDescription
agentAgents
real_agentGenerate/run sim-to-real bridge
datasetInspect/validate/convert/replay/publish datasets
modelPackage/validate/publish policies
list/lsList assets, groups, environments
asset/assetsManage surface assets, rocks, sky-domes, lighting presets
event-cameraWeights/backend metadata
ephemerisQuery Sun/planet geometry; fetch SPICE kernels; import illumination
cacheRegenerate caches
guiLaunch the GUI
isaac/isaacsimIsaac Sim utilities (sim, python)
doc/docsBuild docs; render thumbnails
testRun Python/Rust tests
cleanRemove SRB / Isaac Sim / SimForge caches
completionsManage completions

gui, isaacsim, and doc build/serve return child status. srb test exits 1 on any Python tier failure; a Rust failure exits at once with Cargo’s status. Signal N logs terminated by signal <NAME> and exits 128+N (139 for SIGSEGV); timeout exits 124.

Agent Subcommands

Run srb agent <action> [options]:

SubcommandPurpose
zeroZero actions
randRandom actions
teleopDirect/trained-policy teleoperation
rosROS 2 / Space ROS action topics
trainTrain RL policy
evalEvaluate policy
collectRecord demos from human/policy/random/zero controllers
learnOffline imitation learning from demos
tuneOptuna hyperparameter optimization; spawn training per trial

Shared Agent Options

Simulation-based commands share these; offline learn/tune use separate options and do not launch Isaac Sim. tune spawns srb agent train.

ArgumentDescriptionDefault / limit
-e/--env/--task ENVEnvironment IDRequired
--cfg PATHHydra YAML; DEFAULT/IGNORE/NONE/NULL recognizedDEFAULT
--headlessNo displayFalse
--hide_uiHide most Isaac Sim UI; fullscreenFalse
--livestream {-1,0,1,2}Force: 0 off, 1 native, 2 WebRTC; -1 defers to LIVESTREAM env var-1
--rendering_mode {performance,balanced,quality,xr}Isaac RTX preset after Kit start; xr applies none; defaults to quality for srb/excavation_demounset (auto: demo uses quality)
--xrXR for VR/ARFalse
--enable_camerasRender cameras, not video; auto for env.active_sensors=[…,visual]/event_camera/events, srb/excavation_demo (unless env.demo_cameras=false), or --video/--record-events/--snapshot/--xrFalse
--kit_args=VALUEForward args to Omniverse Kit""
--interface [IFACE …]Enable interfaces gui/ros[]
--logdir/--logs PATHRoot logsCheckout: logs/; installed: working-dir logs/
--videoRecord videoFalse
--record-events/--record_eventsRecord event-camera rollouts with provenance; requires event_camera (alias events) in env.active_sensors; container includes default v2e; see Event CameraFalse
--snapshot PATHOne rendered PNG after initial reset, then exit; implies --enable_camerasunset
--snapshot-warmup NRender passes for path-traced/anti-aliased convergence; needs --snapshot16
--snapshot-settle NRobot-settling physics steps; 0 disables; needs --snapshot0
--perfPerformance test instead of workflowFalse
--perf_output PATHReport path (STDOUT); needs --perfSTDOUT
--perf_duration SECMaximum duration (seconds); 0 = unlimited; needs --perf150.0
--repl [BACKEND]Python REPL with simulation (ptpython/bpython)unset

Hydra-composing agent commands forward unregistered tokens (env.scene.num_envs=4, agent.* keys of the selected algorithm, …); repeated keys apply in order, last wins (env.seed=1 env.seed=2 sets 2). Child wrappers may pass tokens after -- (e.g. srb test to pytest/cargo). srb agent tune rejects bare overrides/--; use --pin KEY=VALUE per trial.

Attach values beginning with - to --kit_args using =, e.g. --kit_args=--ext-folder=/path/to/ext1.

Event Camera Subcommands

Event-camera weights and backends:

Sub-subcommandDescription
srb event-camera fetch-weightsDownload E2VID/V2CE weights; verify SHA256
srb event-camera list-mirrorsList registered E2VID + V2CE mirrors
srb event-camera fetch-fixtureDownload Gen4 HDF5 fixture; verify SHA256
srb event-camera list-fixturesList registered Gen4 HDF5 mirrors
srb event-camera backendsList registered generators; --detailed shows metadata

Cache Subcommands

Offline completion/GUI caches:

Sub-subcommandDescription
srb cache updateRegenerate task/asset/config/enum/GUI caches
srb cache claim-clean-root [--target srb|isaacsim|all]Add path/inode-bound srb clean markers; fixed Isaac and selected NGC roots may adopt existing content
srb cache status [--json] [--strict]Inspect caches; no Isaac Sim
srb cache doctor [--json] [--strict]Validate payloads; no Isaac Sim; reports by default; --strict exits 1 for incomplete/invalid cache

Completions Subcommands

Shell completions:

Sub-subcommandDescription
srb completions generateRegenerate completion cache via srb cache update
srb completions installInstall Fish/Bash/Zsh completion scripts

Restart with exec "$SHELL" -l to load Bash/Zsh registrations. Install fails when no requested shell could be configured.

Besides subcommands and flags, completion covers task ids in srb/x and short x forms (srb_real/x for srb real_agent runtime actions), --algo labels, --cfg sentinels and YAML paths, asset target names, and event-camera mirrors. After srb agent/srb real_agent actions it adds Hydra override keys and values for the selected task (-e/--env/--task) and --algo: nested env.* and agent.* keys, +/++/~ prefixes, enum and boolean values, and bracketed container elements such as 'env.active_sensors=[visual,events]'. For srb agent tune, overrides complete only after --pin. Fish falls back to path completion when nothing else matches. Hydra candidates need jq and successful srb completions generate; scripts follow the published cache pointer, so regeneration needs no reinstall.

srb list (alias srb ls) — List Assets and Environments

srb ls lists cached asset, hardware-interface, and environment names. Stale or incomplete snapshots trigger a warning.

Usage

srb list [options]
srb ls   [options]   # alias
srb ls --live        # discover with Isaac Sim and refresh the cache

Options

ArgumentDescriptionDefault
*categoriesCategories: all, action, asset, env, scenery, object, robot. asset selects scenery, object, and robot.[all]
--liveDiscover registries and refresh the cache.False

With --live, discover current registries, including action groups, in headless Isaac Sim and refresh the completion and GUI cache.

  1. After registration changes, run srb ls --live to discover them and refresh the cache.

Note: Underscore-prefixed task names (such as _aerial) are templates listed with concrete tasks. Customize them with Hydra overrides such as env.robot=<name>.

Output

--live prints the requested tables. By default, all includes action groups and Hardware Interfaces. The Assets table adds an Action Modes column; * marks the default.

Offline output lists cached names only. In offline output, action lists hardware interfaces, not action groups.

Hint: In VSCode, --live tables link to source code.

Example --live Output (Truncated)

                                                              Assets
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ # ┃ Name                        ┃ Type    ┃ Subtype            ┃ Parent Class          ┃ Asset Config    ┃ Path                             ┃ Action Modes                         ┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 1 │ mars_surface                │ scenery │ terrain            │ Terrain               │ AssetBaseCfg    │ terrain.py                       │                                      │
├───┼─────────────────────────────┼─────────┼────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────────┼──────────────────────────────────────┤
│ 2 │ cargo_bay                   │ object  │ payload            │ Payload               │ AssetBaseCfg    │ payload.py                       │                                      │
├───┼─────────────────────────────┼─────────┼────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────────┼──────────────────────────────────────┤
│ 3 │ scoop                       │ object  │ tool               │ Tool                  │ RigidObjectCfg  │ tool/scoop.py                    │                                      │
│ 4 │ shadow_hand                 │ object  │ tool               │ ActiveTool            │ ArticulationCfg │ tool/gripper/shadow_hand.py      │                                      │
├───┼─────────────────────────────┼─────────┼────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────────┼──────────────────────────────────────┤
│ 5 │ sample_tube                 │ object  │ common             │ Object                │ RigidObjectCfg  │ sample.py                        │                                      │
├───┼─────────────────────────────┼─────────┼────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────────┼──────────────────────────────────────┤
│ 6 │ franka                      │ robot   │ manipulator        │ SerialManipulator     │ ArticulationCfg │ manipulation/franka.py           │ *diff_ik, osc_fixed, ...             │
│ 7 │ random_ur_manipulator       │ robot   │ manipulator        │ SerialManipulator     │ ArticulationCfg │ manipulation/universal_robots.py │ ...                                  │
├───┼─────────────────────────────┼─────────┼────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────────┼──────────────────────────────────────┤
│ 8 │ random_unitree_quadruped    │ robot   │ mobile_robot       │ LeggedRobot           │ ArticulationCfg │ mobile/ground/unitree.py         │ ...                                  │
├───┼─────────────────────────────┼─────────┼────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────────┼──────────────────────────────────────┤
│ 9 │ unitree_g1                  │ robot   │ mobile_manipulator │ Humanoid              │ ArticulationCfg │ mobile_manipulation/unitree.py   │ *joint_pos                           │
│ . │ ...                         │ ...     │ ...                │ ...                   │ ...             │ ...                              │ ...                                  │
└───┴─────────────────────────────┴─────────┴────────────────────┴───────────────────────┴─────────────────┴──────────────────────────────────┴──────────────────────────────────────┘

                           Action Groups
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ # ┃ Name                          ┃ Path                       ┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 1 │ body_acceleration             │ common/body.py             │
│ 2 │ body_acceleration_relative    │ common/body.py             │
│ 3 │ joint_position                │ common/joint.py            │
│ 4 │ joint_position_relative       │ common/joint.py            │
│ 5 │ joint_position_binary         │ common/joint.py            │
│ 6 │ joint_velocity                │ common/joint.py            │
│ 7 │ joint_velocity_binary         │ common/joint.py            │
│ 8 │ joint_effort                  │ common/joint.py            │
│ 9 │ inverse_kinematics            │ manipulation/task_space.py │
│ . │ ...                           │ ...                        │
└───┴───────────────────────────────┴────────────────────────────┘

                                                          Environments
┏━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ # ┃ ID                               ┃ Entrypoint                   ┃ Config                             ┃ Path                                      ┃
┡━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 1 │ _manipulation <template>         │ Task(ManipulationEnv)        │ TaskCfg(ManipulationEnvCfg)        │ manipulation/_manipulation                │
│ 2 │ sample_collection                │ Task(ManipulationEnv)        │ TaskCfg(ManipulationEnvCfg)        │ manipulation/sample_collection            │
│ 3 │ _aerial <template>               │ Task(AerialEnv)              │ TaskCfg(AerialEnvCfg)              │ mobile/_aerial                            │
│ 4 │ _ground <template>               │ Task(GroundEnv)              │ TaskCfg(GroundEnvCfg)              │ mobile/_ground                            │
│ 5 │ _orbital <template>              │ Task(OrbitalEnv)             │ TaskCfg(OrbitalEnvCfg)             │ mobile/_orbital                           │
│ 6 │ locomotion_velocity_tracking     │ LocomotionTask(Task)         │ LocomotionTaskCfg(TaskCfg)         │ mobile/velocity_tracking                  │
│ 7 │ _aerial_manipulation <template>  │ Task(AerialManipulationEnv)  │ TaskCfg(AerialManipulationEnvCfg)  │ mobile_manipulation/_aerial_manipulation  │
│ 8 │ _ground_manipulation <template>  │ Task(GroundManipulationEnv)  │ TaskCfg(GroundManipulationEnvCfg)  │ mobile_manipulation/_ground_manipulation  │
│ 9 │ _orbital_manipulation <template> │ Task(OrbitalManipulationEnv) │ TaskCfg(OrbitalManipulationEnvCfg) │ mobile_manipulation/_orbital_manipulation │
│ . │ ...                              │ ...                          │ ...                                │ ...                                       │
└───┴──────────────────────────────────┴──────────────────────────────┴────────────────────────────────────┴───────────────────────────────────────────┘

srb agent zero — Zero Agent

Run an environment with zero-valued actions. If zero is the equilibrium action, internal dynamics alone drive the environment.

Usage

srb agent zero --env ENV_ID [options]

Options | Shared Agent Options

No additional options are available for this subcommand.

Example

Run the zero agent in the _ground template environment:

  • Create 4 parallel environment instances
  • Use the Cassie bipedal robot
srb agent zero -e _ground env.num_envs=4 env.robot=cassie

srb agent rand — Random Agent

Run an environment with randomly sampled actions to exercise its response to varied inputs.

Usage

srb agent rand --env ENV_ID [options]

Options | Shared Agent Options

No additional options are available for this subcommand.

Example

Run the random agent in the _aerial template environment:

  • Hide most of the simulation UI
  • Use the body_acc action mode (default for the Ingenuity rotorcraft)
srb agent rand -e _aerial --hide_ui env.robot.action_mode=body_acc

srb agent teleop — Teleoperate Agent

Test environments and agent behavior by controlling robots with supported devices.

Usage

srb agent teleop --env ENV_ID [options]

Options | Shared Agent Options

OptionDescriptionDefault
--teleop_device [DEV …]Interface (keyboard, spacemouse, ros, gamepad, haptic)env default, else [keyboard]
--pos_sensitivity VALTranslation sensitivity1.0
--rot_sensitivity VALRotation sensitivity (rad/s)π (≈3.14)
--invert_controls/--invertIn manipulation mode, flip the first two translational controls. Boolean optional forms --no-invert_controls and --no-invert disable inversion.True
Teleoperation via Policy
--algo ALGOAlgorithm of the policy (RL or IL)
--model MODELPath to the policy checkpoint or an SRB model artifact directory; this exact policy is loaded
--obs {state,visual}Observation modality of the policy: selects the agent-config variant and the log tree searched for its latest checkpointstate

Teleoperation Modes

Action space selects direct or policy control:

Direct Teleoperation

Use direct teleoperation when actions map to high-level commands such as desired end-effector pose or mobile-robot acceleration.

Examples

In _manipulation, use ur10:

srb agent teleop -e _manipulation env.robot=ur10

In _orbital, use spacemouse:

srb agent teleop -e _orbital --teleop_device spacemouse

Teleoperation via Policy

Use a trained RL or imitation-learning policy for complex or high-dimensional actions, such as humanoid joint control.

Any algorithm supported by srb agent eval works. The device supplies command-like observations. The policy generates actions.

Examples

Reference: Reinforcement Learning Workflow
Reference: srb agent train — Train Agent

  1. Train Dreamer on locomotion_velocity_tracking:

    srb agent train --headless --algo dreamer -e locomotion_velocity_tracking env.num_envs=256
    
  2. Teleoperate with it:

    srb agent teleop --algo dreamer -e locomotion_velocity_tracking
    
  3. To load another checkpoint instead of the latest, set --model:

    srb agent teleop --algo dreamer -e locomotion_velocity_tracking --model logs/locomotion_velocity_tracking/dreamer/...
    

SpaceMouse input

Failed or None reads discard buffered six-axis motion. No successful read for 0.5 s also discards it. Valid reads restore input, while lost reports during continuing reads retain the last motion.

Reset discards in-flight reads. Failed reads preserve the gripper toggle. This is not a hardware stop or inactivity timeout.

Native teleoperation

Native srb real_agent teleop requires generated COMMAND_MAPPING metadata and direct ROS, SpaceMouse, or haptic input. ROS is the default. Keyboard, gamepad, and policy-command arguments are unavailable. See the native direct-input contract.

Public Demo Launch

For public events, excavation_demo defaults to one environment, manual reset, long horizon, all HUD lines visible, and the high-quality RTX preset.

srb agent teleop --env excavation_demo

Add --hide_ui for fullscreen without the Isaac Sim UI:

srb agent teleop --env excavation_demo --hide_ui

Task config defaults to spacemouse, haptic, and keyboard; thus --teleop_device is optional. Set venue or visual tier with Hydra overrides such as env.scenery=lunalab or env.demo_regolith_quality=visual.

srb agent ros — ROS 2 Agent

Usage and options

srb agent ros --env ENV_ID [options]

See Shared Agent Options.

OptionDefaultBehavior
--ros_sync/--ros-syncfalseFirst step may use the available action; later steps wait for a fresh one. Reset requests apply after the next step, so publish an action after requesting a reset. Use for closed-loop RL, LQR, or MPC.
--ros_action_timeout/--ros-action-timeout SECONDSWait indefinitelyLimit fresh-action waits with --ros_sync; on timeout, clear cached commands and apply zero.
--ros_unthrottled/--ros-unthrottledfalseDisable non-sync pacing and run sample-and-hold as fast as possible.

Steps use the latest action at env.agent_rate. Slower publishers repeat cached actions. env.agent_rate must be finite and positive; otherwise SRB rejects it. If unset, the loop is unpaced.

Subscriptions use best-effort, latest-only QoS (KEEP_LAST, depth 1) to prevent backlogs. Commands expire after 0.5 seconds of monotonic wall time, including during sync waits. Each message renews only its environment/action slices. Velocity and event inputs expire separately; events cannot renew velocity. Malformed or non-finite messages do not renew commands.

Mapped actions must be finite. SRB clamps them to batched Box bounds, which must admit zero. Raw and term overrides own their addressed slices until expiry or reset. Velocity and event traffic updates only mapped or unclaimed slices. Fully overridden updates change no action slice but still refresh the velocity and event caches.

Reset, expiry, and buffer publication share a lock. A contended nonblocking read returns zero. SRB does not apply cleared, expired, or rejected samples. Embedders can set RosInterface(env, command_timeout_s=0.25) or disable expiry with None. The CLI wait timeout is separate.

Accessors return a borrowed device buffer. The ROS agent follows this pattern; embedders sharing reset or close callbacks should too:

with interface.action_transaction() as (action, sequence):
    step_result = env.step(action)

Do not use the buffer after exit. Non-transactional accessors require serialized reads and consumption. Nested reads are rejected, and same-thread reset clears the buffer. If close finds active consumption, ingress and endpoints remain for retry after it ends. CUDA work completes before buffer clearing and scope release. A hung consumer can delay reset. Keep polling; zero policy action is not a watchdog or emergency stop.

RealEnv raw policy input

Send raw actions

srb real_agent ros --env ENV_ID accepts flat policy actions on action/raw in the environment namespace, normally /srb/action/raw. Publish std_msgs/Float64MultiArray values in generated-environment action order and bounds. RealEnv applies hardware mapping and scales. Simulation term, velocity, and event mappings do not define real teleoperation semantics.

QoS is best-effort, volatile, keep-last, depth one. Callbacks run independently of stepping. Messages have no producer timestamps. Age starts at callback receipt and continues through sensor checks and wrapper processing. Later messages cannot extend it.

Missing, malformed, out-of-bounds, or expired commands abort the session. Hardware interfaces stop themselves; invalid input is never replaced with zero. Cleanup stops the session, then closes the command source, RealEnv, and process-owned ROS context. Failed cleanup retains resources for retry.

Checks cannot interrupt blocked hardware calls or act as a watchdog. Hardware operation is not validated; test physical stopping under supervision.

Settings

SettingDefaultBehavior
Initial input wait5 secondsRequire valid first message before dispatch.
Command lifetime0.5 secondsCheck age before dispatch and each prepared hardware command.
--ros_action_timeout SECONDSUnsetPositive finite value overrides wait and lifetime.
--ros_sync/--ros-syncfalseFirst step may use current sample; later steps await newer sample, aborting on expiry.
--ros_unthrottled/--ros-unthrottledfalseDoes not bypass expiry or RealEnv action rate.

Examples

See ROS 2 Workflow.

srb agent train — Train Agent

Start or Resume a Run

  1. Choose an algorithm and environment.
  2. Add environment overrides after options.
  3. For replay prefill, see SKRL or Dreamer.
  4. Optionally package a successful run (see Model Artifacts).
srb agent train --algo sbx_ppo --env landing env.num_envs=512 --hide_ui

srb agent train --algo sbx_ppo --env landing --continue_training
srb agent train --algo sbx_ppo --env landing \
  --model logs/landing/sbx_ppo/<run>/ckpt/<ckpt>

Explicit --model checkpoint paths resolve relative to the current working directory. Logs default to <repo>/logs in a checkout and <cwd>/logs when installed; use --logdir to change the root.

Run records

Each run has metadata.json and run.json; the record lists source and asset commits, simulator pair, image, host, GPU, driver, seed, algorithm, implementation, task, step budget, and hyperparameter overrides. Online training writes TensorBoard scalars to metrics.jsonl ({"tag", "step", "wall_time", "value"} per line); re-export interrupted runs with python -m srb.utils.metrics_jsonl <logdir>.

Source checkouts record Git commits; site-packages installs report null. Asset metadata records its submodule commit, pinned gitlink, and dirty flag (null if unknown). Metadata files and config snapshots redact secret-named values and flags, forwarded kit_args, URL credentials and query values, plus Authorization and Bearer values as <redacted>. SRB atomically reserves directories and suffixes same-second runs, such as -001.

Options | Shared Agent Options

OptionDefaultLimits / behavior
--algo ALGOREQUIREDRL algorithms only
--obs {state,visual}stateSelects the config and log tree (<algo> or <algo>-visual) and prevents cross-modality loading. visual is unsupported; see Agent Configuration.
--continue_training, --continueFalseResumes the latest checkpoint of the latest run, or trains from scratch in that run when it has none; mutually exclusive with --model. Support depends on the framework; TD-MPC2 rejects it.
--model PATHunsetResumes from the specified checkpoint. Support depends on the framework; TD-MPC2 imports weights only.
--demo-dataset, --demo_dataset PATHunsetCanonical SRB JSONL for skrl_sac, skrl_ddpg, skrl_td3, or dreamer; requires --demo-max-transitions.
--demo-max-transitions, --demo_max_transitions NunsetPositive cap on the complete source; requires --demo-dataset.

Resume behavior by framework

FrameworkBehavior and limits
TD-MPC2--model imports weights only; the optimizer, replay, schedules, and step counter restart at logged step 0. --continue_training is unsupported.
sb3_*, sbx_*Both options restore the step and learning-rate schedule, then train only the remaining portion of the original n_timesteps; increase that value to extend training. Checkpoints are saved every +agent.save_freq=N environment steps (default 50000). Continuation after a finished run warns and does nothing; --model at the budget fails. With +agent.save_replay_buffer=true, off-policy runs save ckpt/rl_model_replay_buffer_<N>_steps.pkl; only the newest periodic buffer is kept, plus ckpt/replay_buffer.pkl. Each buffer can take gigabytes. If the matching buffer is missing, learning_starts restarts at the resumed step. With normalization, ckpt/rl_model_<N>_steps.zip pairs with ckpt/rl_model_vecnormalize_<N>_steps.pkl for resume and evaluation. A missing matching per-checkpoint stats file fails if the run uses per-checkpoint statistics; legacy checkpoints may fall back to run-level stats with a warning. If no stats exist, resume and evaluation fail instead of using fresh stats.
rsl_rl_ppoAdds max_iterations training iterations.
skrl_*Resumes from the checkpoint timestep through agent.trainer.timesteps and retains agent_<N>.pt. Continuation after a finished run warns and does nothing; --model at the budget fails. If the checkpoint lacks a timestep or uses experiment.store_separately, resume fails unless +agent.resume_timestep=N supplies one. A saved timestep takes precedence, and evaluation ignores the override. Replay is not saved for ordinary SKRL runs; demo-prefilled replay is included in combined agent checkpoints. If off-policy skrl_sac, skrl_td3, or skrl_ddpg replay is empty, learning_starts restarts at the resumed timestep; random_timesteps does not repeat. Demo-prefilled replay keeps the configured warm-up. The actor cannot receive state_privileged__*; the critic can.

Supported Algorithm Families

Registered labels include dreamer, tdmpc2, sbx_ppo, sb3_ppo, rsl_rl_ppo, skrl_ppo, skrl_sac, and skrl_ppo_rnn. SRB provides SKRL models and profiles for skrl_sac and skrl_ppo_rnn. See the Reinforcement Learning Workflow for Hydra overrides and Weights & Biases logging.

SKRL Demonstration Prefill

skrl_sac, skrl_ddpg, and skrl_td3 prefill replay from canonical SRB JSONL exports with metadata.demo_io_contract. The trainer validates observation projections and action coordinates, including runtime scales, against the live wrapper. It preserves explicit next observations and separate termination and truncation flags.

The cap applies to the whole source; exceeding it causes an error. The transition count must divide evenly by env.num_envs and fit the replay capacity; rows are neither padded nor dropped. The trainer checks admission before native allocation. Limits are 192 MiB for replay payloads and 256 MiB for serialized checkpoints. Oversized configurations report the maximum supported agent.memory.memory_size for the environment count and I/O dimensions. These limits do not bound peak process memory.

srb agent train --algo skrl_sac --env peg_in_hole \
  --demo-dataset /data/peg_in_hole_canonical \
  --demo-max-transitions 1000 \
  env.num_envs=1 agent.memory.memory_size=8192 --hide_ui

Resume requires both options and identical source bytes, I/O layout, and replay dimensions. Combined checkpoints restore replay, optimizer, and random state at the saved next timestep; the simulation resets. Resume rejects agent.agent.experiment.store_separately=true. Evaluation uses weights only.

DDPG and TD3 restore exploration-noise state and learning-rate schedules; TD3 also restores its delayed actor-update counter. Resume requires complete native modules and unchanged update, scheduler, sampling, and exploration settings, including native Gaussian or Ornstein-Uhlenbeck noise parameters and actor cadence. Custom noise implementations are rejected. Demo and online replay use the checkpoint-bound agent.agent.rewards_shaper_scale; arbitrary reward-shaping callbacks are unsupported.

Prefill is unsupported for other SKRL labels, SB3 (sb3_*), SBX (sbx_*), and RSL-RL (rsl_rl_ppo). srb dataset compatibility DATASET --purpose train reports the training mode and compatibility for each algorithm. For offline demonstrations, use Robomimic with srb agent learn.

Dreamer Checkpoints and Continuation

Dreamer resumable state requires the original agent.replay.save=true and agent.replay.save_wait=true settings; persistence is disabled by default. Weights-only checkpoints lack replay and cannot use --continue; import them into a new run. Dreamer training runs in worker processes and rejects --perf, --hide_ui, and --repl.

The authoritative manifest selects the committed agent, step, and replay generation together. In-run --model must identify that checkpoint; older generations are rejected. Use a new log directory to import weights from another generation.

Cleanup retains the current generation and its parent, preserves files with uncertain ownership, and waits for same-run readers. Snapshots pin saved chunks and exclude later in-memory updates. Failed cleanup may leave extra files without invalidating the committed checkpoint.

Dreamer Demonstration Prefill

dreamer uses paired options and canonical SRB JSONL. The task, observation terms, action layout, and runtime scales must match; actions must be continuous and within [-1, 1]. Each simulator worker needs matching projection metadata; missing or mismatched metadata causes rejection. The local route uses one environment; the process route uses one environment per worker.

Prefilled runs also require replicas: 1, positive replay_context, and the save settings above. Set replay.size and replay.chunksize for the source and observation/context dimensions; defaults of several million items may exceed admission limits. Replay arrays and staged rows, including recurrent context, are each capped at 256 MiB. Total process memory and model allocations are not bounded.

Dreamer adds a successor row per episode, retains terminal observations, and separates termination from timeout. Two 12-transition episodes yield 26 native rows and 18 windows at sequence length 9. Capacity counts windows and must fit the batch window; excess source transitions are rejected. Within each episode, projected next_obs must equal the next observation. Recurrent context uses the demonstrated previous actions.

Same-run resume requires an identical source path and bytes, projection, and bound learner/replay configuration. A mismatch is rejected before restore or config/metadata overwrite. Resume restores the agent and replay without reinserting demonstrations. Native replay omits the sampler cursor and random state, so batches are not bit-exact. Evaluation uses weights only.

Dreamer demonstration prefill has not been validated with GPU simulator training or on hardware. TD-MPC2 does not support it.

Model Artifacts

Package successful runs as portable SRB artifacts with --model-artifact-output. Record provenance with --model-artifact-dataset, or package the run afterward with srb model from-run.

OptionDefaultLimits / behavior
--model-artifact-output PATHunsetOutput artifact directory, after training succeeds
--model-artifact-checkpoint PATHunsetCheckpoint to package; absolute or run-directory-relative
--model-artifact-task TASKunsetOverride task identity
--model-artifact-embodiment NAMEunsetOverride embodiment identity
--model-artifact-action-mode MODEunsetOverride action-mode identity
--model-artifact-framework NAMEunsetOverride framework metadata
--model-artifact-dataset PATHunsetDataset manifest, artifact directory, or file for provenance and identity inference
--model-artifact-dataset-repo-id IDunsetTraining dataset repository id
--model-artifact-dataset-revision REVISIONunsetTraining dataset revision
--model-artifact-repo-id IDunsetOverride Hugging Face model repository id

For demo-prefilled runs, packaging retains the training-time manifest and member digests if the source moves or is removed. Explicit --model-artifact-dataset controls the declared dataset link; consumed demo binding stays in artifact metadata.

srb agent eval — Evaluate Agent

Run a trained policy in a registered environment.

Usage

srb agent eval --env ENV_ID (--algo ALGO | --model MODEL) [options]

Supported algorithm labels: sb3_*, sbx_*, skrl_*, rsl_rl_ppo, dreamer, tdmpc2, and robomimic_*.

Options | Shared Agent Options

OptionDescriptionDefault
--algo ALGOAlgorithm. Loads latest standard-log checkpoint unless --model is set.unset
--model PATHCheckpoint or SRB artifact. Infers algorithm from path if --algo is omitted.unset
--obs {state,visual}Selects observation, agent-config variant, and checkpoint tree (<algo> or <algo>-visual). visual is unsupported; see Agent Configuration.state

The command errors unless --algo or --model is set.

Bounded quantitative evaluation

Set positive SRB_EVAL_EPISODES=N to request bounded evaluation. SB3, SBX, and RSL-RL act deterministically. SRB artifacts are bounded only when the loader reports deterministic inference.

The quota is split across environments: each gets N // num_envs episodes, and the lowest N % num_envs environment IDs get one extra. Count only episodes started during evaluation. Environments keep stepping after their quota. Extra episodes do not count, which avoids short-episode bias.

Mean return is undiscounted. Rewards are summed without discount or extra framework normalization. Task shaping and configured normalization still apply, so returns are not unshaped physical metrics.

Task success info supplies success metrics. Without it, success_rate, successes, and failures are null. Termination alone does not count as success.

Results and output

Bounded results contain:

  • Episode counts: episodes_requested, episodes_completed, and n_episodes.
  • Metrics: mean_return, success_rate, successes, and failures.
  • Run state: complete, incomplete, steps, max_steps, and stop_reason.
  • Environment details: num_envs and episode_sampling (per_env_quota).

SB3 and SBX also return requested_checkpoint (pre-fallback selection or null), loaded_checkpoint (file or null), and checkpoint_fallback (whether an incomplete selection was replaced). The returned result and its JSON contain these fields. Ignore unused fields.

Bounded paths log one SRB_EVAL_RESULT JSON record. They write formatted results to SRB_EVAL_OUT or, if unset, the log-directory eval.json.

The finite guard allows twice the requested episodes multiplied by the maximum episode length. If the maximum is unavailable, it allows 1000 steps per episode. An early stop sets complete: false and incomplete: true.

Without SRB_EVAL_EPISODES, providers run their visualization or diagnostic evaluation.

Provider-specific behavior

Robomimic (robomimic_*) requires checkpoint-reported deterministic inference. It rejects stochastic or unknown behavior before acting. It runs N episodes in one environment; horizon does not truncate them. Set and record env.seed (default 42). Unbounded mode uses its rollout count and writes to SRB_EVAL_OUT or the log-directory eval.json.

SKRL is not quantitative. It only lowers a higher trainer budget to about twice the requested episodes times the time limit. It ignores non-integer or nonpositive values. It does not count episodes, enforce quotas, report shortfalls, or emit the record. Do not compare its output quantitatively.

TD-MPC2 MPC stays stochastic even with exploration noise disabled. Bounded evaluation rejects it; unbounded MPC is diagnostic only. With agent.mpc=false, it uses the policy mean and the quotas and results described above.

Pinned Dreamer samples its latent posterior and policy, so it is not deterministic.

Set env.seed explicitly; the episode budget does not change it:

SRB_EVAL_EPISODES=256 SRB_EVAL_OUT=/tmp/landing-eval.json \
  srb agent eval --env landing --algo sb3_ppo env.seed=1000

Examples

# Latest SBX PPO checkpoint on landing
srb agent eval --env landing --algo sbx_ppo env.num_envs=16

# Infer algorithm from checkpoint path
srb agent eval --env landing \
  --model logs/landing/sbx_ppo/<run>/ckpt/<ckpt>

# SRB artifact, bundled restore config if available
srb agent eval --env excavation \
  --model /models/srb_excavation_kinova_gen3_smooth_osc_rsl_rl_ppo

SRB artifacts use shared loading for collection and real-world validation, preserving bundled Dreamer, TD-MPC2, or RSL-RL configs without the training log directory (model docs).

srb agent collect — Collect Demonstrations

Usage

srb agent collect --env ENV_ID [options]

Options | Shared Agent Options

OptionDescriptionDefault
--collector SOURCEhuman, policy, random, or zero; defaults to policy with --algo/--model, else human.inferred
--num_episodes NEpisodes to collect.100
--horizon NMax steps/episode. Horizon cuts and mid-episode simulator closes record the last row as truncated=True, done=True, not terminal success/failure.400
--success_onlySave successful demos only; see Tips.False
--teleop_device [DEV …]keyboard, spacemouse, ros, gamepad, haptic.env default, else [keyboard]
--pos_sensitivity VALTranslation sensitivity.1.0
--rot_sensitivity VALRotation sensitivity.π (≈3.14)
--invert_controls/--invertIn manipulation, invert only the first two translational controls; --no-invert_controls/--no-invert disable.True
--algo ALGORL or imitation-learning policy algorithm.—
--model MODELRaw checkpoint or SRB model artifact path.—
--obs {state,visual}Select policy config variant and latest-checkpoint log tree.state

Collection Modes

1. Teleoperation (default)

Without --algo/--model, collect human actions and observations:

srb agent collect --env peg_in_hole --num_episodes 50

Keyboard teleop needs GUI; with --headless it fails before collection. Choose another --teleop_device or remove --headless. XR uses --xr; see Extended Reality.

For real teleoperation, srb real_agent collect --collector human requires generated COMMAND_MAPPING metadata; see native direct-input contract for devices and episode controls. Scalar RealEnv HDF5 steps have single-environment batch axes (split=real, controller=human).

2. Policy Rollout

Set --algo (optionally --model) to roll out a trained policy:

srb agent collect --env peg_in_hole --algo sbx_ppo --num_episodes 200

SRB supports dreamer, tdmpc2, rsl_rl_ppo, sb3_*, sbx_*, skrl_*, and robomimic_*. Without --model, it loads the latest standard training-logdir checkpoint and reuses that algorithm’s latest run. Native RSL-RL model_*.pt and TD-MPC2 models/*.pt resolve as in evaluation. --model accepts raw checkpoints or SRB model artifact directories. An adjacent config.yaml supports stateful/config-heavy Dreamer, TD-MPC2, and RSL-RL adapters outside the original run. Metadata stores checkpoint/source as model/model_artifact.

3. Built-in Sources

Use --collector random/zero for baseline data:

srb agent collect --env peg_in_hole --collector random --num_episodes 20
srb agent collect --env excavation --collector zero --num_episodes 5 --horizon 200

random samples the action space using env.seed (same seed repeats actions). Split is independent: real collection may use split=real with controller=random, controller=zero, controller=human, or controller=policy.

Multi-Modal Recording

Add visual to env.active_sensors for RGB-D and events for the event camera, e.g. a floating platform in the Zero-G lab:

srb agent collect --headless --env zerog_lab --collector random \
  --num_episodes 10 env.num_envs=1 \
  'env.active_sensors=[proprioception,contact,transform,visual,events]' \
  --record-events

Each row stores RGB-D image_<camera> (uint8, depth in the last channel), the event_<sensor> tensor, the state vector, action, and reward. --record-events adds raw event HDF5, RGB/depth MP4s, and events_manifest.jsonl under <run logdir>/camera_videos/<timestamp>/ (the input of srb dataset event exports). Set env.camera_resolution=[W,H] and env.event_camera_resolution=[W,H] to size the images.

Output

Robomimic-compatible HDF5 output:

CollectionDataset directory
Human, random, zerologs/<env_id>/collect/<timestamp>/datasets/
PolicyResolved run directory, e.g. logs/<env_id>/<algo>/<timestamp>/datasets/

Train from the dataset with srb agent learn; see Imitation Learning Workflow.

Logs default to <checkout>/logs in a source checkout or <cwd>/logs when installed. Override the location with --logdir/--logs.

Policy reuse stores metadata.json, run.json, and .hydra/ under collect/<timestamp>-<suffix>/, preserving training metadata/config. SRB artifacts are read in place. Metadata records the source, episode controls, teleop devices, and reproduction command.

If collection saves no episodes, it reports no episodes were saved after N attempt(s) and writes no dataset. If it saves fewer than requested, it keeps the dataset and warns with saved/requested counts.

Autonomous collection makes up to three attempts per requested episode. All modes stop when the simulator closes. A finite positive unwrapped step_dt sets autonomous/human sidecar fps=1/step_dt; otherwise timing is unknown. LeRobot v3 requires known timing; see dataset CLI.

Observation format

Per-sample low-dimensional observations have shape [D]; cameras have shape [H, W, C] (Robomimic accepts cameras as images).

On errors or Ctrl-C, collection publishes saved episodes with masks and an SRB sidecar. Demos store success; LeRobot exports it only on the final row as Boolean success.

Simulated uint8 depth is normalized over near/far and scaled by 255; it saturates beyond far or on empty rays. env.camera_clipping_range=[near,far] fills visual cameras retaining the render-default far plane (1000 m or more), preserving explicit ranges. Orbital cameras use (0.01, 100) m (about 39 cm/level), rendezvous (0.01, 50) m, orbital_evasion (0.01, 150) m, landing/moonfall (0.01, 400) m, and other default-far cameras 20 m (about 8 cm/level). Real-camera depth is metric float32, unlike simulated depth.

With visual or events in env.active_sensors, SRB raises env.num_rerenders_on_reset to at least 1 so the first episode image and event baseline show the reset scene. This adds one render per step where an environment resets. Set env.camera_rerender_on_reset=false to opt out.

Datasets omit policy determinism. SRB reports only plain bc (MLP, RNN, transformer) as deterministic when the saved config disables GMM/Gaussian/VAE heads. Other algorithms/heads (e.g. GMM, VAE, diffusion, BCQ), or omitted head settings, are reported as non-deterministic or unknown; bounded evaluation (SRB_EVAL_EPISODES) refuses them.

Tips

--success_only checks the success term or, if absent, ending-step episode success info at the final row (termination, horizon, simulator shutdown, or teleop save). Earlier success does not count.

After reset, use episode info because the term sees the next episode. If an environment-ended episode publishes no success info, collection warns that success is unavailable and records it as false. Orbital tasks and spacewalk (never terminates; truncates at the time limit) are judged at the horizon.

Tasks with success_signal = "episode_info" in docs/data/tasks.toml (e.g. excavation, formation_following, beam_transport) publish the flag.

Without either signal, autonomous collection stops with --success_only needs a success signal. Keyboard saves count only with the task flag; teleop-device saves count as success. Real collection follows these rules; terminal success requires an evaluator, and srb real_agent attaches none.

Every mode requires env.num_envs=1. Otherwise, collection raises robomimic collection requires num_envs == 1 before creating dataset files. Set the Hydra override explicitly.

srb agent learn — Learn from Demonstrations

Train offline on srb agent collect data without Isaac Sim, for faster startup and lower resource use.

Usage

srb agent learn --algo ALGO --env ENV_ID [options]

Options

OptionDescriptionDefault
-e/--env/--task ENVEnvironment ID for logs/specsREQUIRED
--cfg PATHYAML whose agent section overrides the algorithm configDEFAULT (none)
--algo ALGOImitation-learning algorithmREQUIRED
--dataset PATHOptional HDF5 demos; omission searches new run directory, errors if noneNone
--num_epochs NEpoch countAlgo default
--normalize_actionsNormalize dataset actionsFalse
--logdir/--logsOutput rootlogs/ at checkout root or current directory when installed

Trailing agent.KEY=VALUE overrides apply after --cfg, for example agent.train.batch_size=16; other overrides and arguments after -- are rejected.

Dataset admission and normalization

Training uses verified private HDF5 copies until workers, handles, and logging close; source changes cannot affect training. Config keeps the source path for provenance, not as an archive.

Admission rejects demos if declared num_samples differs from the actions or any selected per-step dataset length. Every configured filter key must name a dataset under the HDF5 mask/ group; an empty mask fails with the filter key. When all three arrays exist, dones must equal terminated OR truncated. Empty validation (split 1.0, or one demo with any positive split) requires agent.experiment.validate=false and agent.train.hdf5_validation_filter_key=null.

Cache, sequence, batch, and worker allocations share a 16 GiB ceiling. Arrays also have byte and element limits; excess declarations fail before payload reads. Retained metadata is capped at 128 MiB. Limits cover dataset allocations, not total process, model, optimizer, or device memory. Native configs can use custom action keys without unused SRB transition fields.

--normalize_actions globally scalar-normalizes a private copy in a Linux worker (2 GiB address space, 16 GiB output, 120 seconds); native_limits=Hdf5NativeLimits(...) can lower these limits. Source stays unchanged; training readmits transformed input and drops lossy scale-offset compression. normalization_params.txt records the range unless actions are constant or absent. Standalone normalization publishes files atomically one at a time; failure restores the previous pair. RobomimicNormalizationCleanupError.retry_cleanup() retries failed cleanup.

Supported Algorithms

Offline learning uses robomimic.

AlgorithmDescription
robomimic_bcBehavioral Cloning (MLP)
robomimic_bc_rnnBC with RNN policy
robomimic_bc_transformerBC with Transformer policy
robomimic_bcqBatch-Constrained Q-Learning
robomimic_cqlConservative Q-Learning
robomimic_iqlImplicit Q-Learning
robomimic_td3_bcTD3 with BC regularization
robomimic_glGoal-conditioned learning
robomimic_hbcHierarchical BC
robomimic_irisIRIS (latent skill discovery)
robomimic_diffusion_policyDiffusion Policy

See Robomimic algorithm documentation for hyperparameters.

Note: hyperparams/robomimic/bcq.json and iris.json disable VAE/GMM action samplers and the distributional critic. BCQ and IRIS’s BCQ value component requires at least one enabled. Training rejects these profiles before data access. Enable one (Robomimic default: action_sampler.vae.enabled=true) to use either algorithm.

Examples

srb agent learn --algo robomimic_bc --env peg_in_hole \
  --dataset logs/peg_in_hole/collect/<run>/datasets/demos_<timestamp>.hdf5
srb agent learn --algo robomimic_bc_rnn --env peg_in_hole \
  --dataset /path/to/demos.hdf5 --num_epochs 500

Output

Checkpoints and metrics go to <logdir>/<env_id>/<algo>/<timestamp>/. Evaluate:

srb agent eval --algo robomimic_bc --env peg_in_hole

Collect more demonstrations:

srb agent collect --algo robomimic_bc --env peg_in_hole --num_episodes 200

--model-artifact-output OUT packages the run as an SRB model artifact; the other --model-artifact-* options match srb agent train. --dataset records training-data provenance unless artifact dataset options override it.

See Also

srb agent tune — Hyperparameter Optimization

Verbs

check preflights; run starts or resumes; status summarizes; validate reruns top trials on fresh seeds; export writes a tuned config; repair fails stale trials; baseline captures portfolio normalization values. The Isaac-free study runs trials in child processes; one failure does not stop it. Install Optuna with uv sync --extra tune.

srb agent tune check    [options]
srb agent tune run      [options]
srb agent tune status   --study S
srb agent tune validate --study S
srb agent tune export   --study S
srb agent tune repair   --study S
srb agent tune baseline [options]

All actions reject bare key=value overrides and tokens after -- with srb agent tune <action>: error: unsupported arguments ...; fix a setting for every trial with --pin KEY=VALUE. Use --pin to fix values across trials.

check Options

check runs run’s pre-trial checks, assembles one trial config in memory, validates the adapter, search space, base config, pins and collisions, sampler, merge, and budget conversion, and launches no study or training child. Checks print [OK], [WARN], or [FAIL]; hard errors return non-zero. Accepted run options:

OptionsDefault or limit
-e/--env/--task, --tasksChoose one task or portfolio; pass either --env/--task or --tasks, not both.
--algoRequired.
--obs, --trial-steps--trial-steps required.
--pin, --trial-num-envs, --seed-base, --seeds-per-trial, --normalize, --aggregate, --objective, --fps, --n-trials, --n-workers, --version, --logdirSee run defaults below.

For --normalize baseline portfolios, it verifies fresh floor/ref baselines for every task. --fps adds the run wall-clock projection.

srb agent tune check --env sample_collection --algo skrl_ppo --trial-steps 10_000_000 --fps 50000
srb agent tune check --tasks sample_collection peg_in_hole --algo skrl_ppo \
  --trial-steps 10_000_000 --normalize baseline   # checks baselines.yaml too

run Options

OptionDefault or limit
-e/--env/--task ENVSingle task; mutually exclusive with --tasks
--tasks T [T …]Portfolio; mutually exclusive with -e/--env/--task
--algo ALGOREQUIRED; e.g. skrl_ppo
--obs {state,visual}state; visual is unsupported
--trial-steps NREQUIRED; env-step budget per trial and task segment
--n-trials N20; terminal and RUNNING trials count on resume
--n-workers N1 concurrent trial slots
--gpus 0,1Unset inherits environment/framework default; otherwise round-robin
--trial-num-envs N1024; pinned parallel envs, drives budget conversion
--seed-base N42
--seeds-per-trial K1
--pin agent.X=Y …—; fixed values across trials
--objective {ep_return_mean,success_rate}ep_return_mean (episode-weighted mean over the last 25% of steps)
--normalize {none,baseline,rank}none
--aggregate {median,mean,min}median
--max-wall-hours H—; stop scheduling at this wall limit
--trial-timeout S—; kill trials exceeding this duration
--fps F—; measured env-steps/s for wall-clock projection
--n-startup N10; 15 for portfolio
--boot-stagger S30 if --n-workers > 1, else 0; skipped after first child emits metrics
--keep-artifactsFalse; PRUNED child logdirs removed; trial_cfg.yaml and metrics.jsonl survive
--retry-failed N0; retry up to N FAILed sets except reason=timeout; raise --n-trials to run them
--version N1; bump for an incompatible rerun
--logdir/--logslogs/tune
--storage URLJournal default; PostgreSQL requires tune-rdb (postgresql:// or postgresql+psycopg2://)

Journal storage is default; --storage selects PostgreSQL without fallback. SRB validates and redacts credentials, bounds the pool, and records frozen study identity before creation. Schema checks fail closed; SRB does not migrate. Back up before upgrades. Install both extras with uv sync --extra tune --extra tune-rdb.

The task must emit the selected objective. If it never reports success, --objective success_rate fails each trial early with success_rate_unavailable instead of running its full budget.

Averaging seeds during a study (--seeds-per-trial)

--seeds-per-trial K runs K distinct seeds (seed-base + trial*K + replicate) and gives TPE their mean. Pruning uses replicate 0: weak trials stop after one child; survivors cost about K times more. Crashed replicates are excluded; n_seeds and n_seeds_ok are recorded. Replicate 0 uses trials/NNN/; others use trials/NNN/rep-K/ and discard checkpoints. Use K for cleaner search objectives; validate can rerank top trials on fresh seeds at lower cost than a multi-seed study.

Resume validates the frozen manifest and refuses changes to search space, --trial-steps, --objective, --obs, --seeds-per-trial, or tasks; bump --version for incompatible studies. Seed-base and Optuna-version drift are allowed. Keep K fixed so trials use the same seed schedule (seed-base + trial*K + replicate).

baseline Options

Capture per-task floor/ref values for --normalize baseline; output: hyperparams/tune/baselines.yaml.

OptionDefault or limit
-e/--env/--task, --tasks—; tasks to baseline
--algo ALGOREQUIRED
--obs {state,visual}state
--budget/--ref-steps NREQUIRED; reference env-steps equal trial budget
--floor-steps N200000 random-rollout env-steps
--trial-num-envs N1024; pinned parallel envs, drives budget conversion
--seed-base N42; task k uses seed-base + k
--gpus 0,1Unset inherits environment/framework default; otherwise round-robin
--objective {ep_return_mean,success_rate}ep_return_mean
--trial-timeout S—
--force, --dry-runFalse; overwrite entries / compute without writing baselines.yaml
--logdir/--logs PATHlogs/tune

Entries store random-policy mean floor, reference-run tail-mean ref, source config path, and its git blob SHA. tune run and tune check warn on SHA drift; recapture before trusting normalization.

Portfolio (Multi-Task) Studies

--tasks A B C … tunes one parameter set across tasks in fixed order, with one srb agent train child per segment under trials/NNN/seg-<task>/. Normalized scores form one objective; diverging segments prune the trial. MedianPruner compares each segment’s running aggregate, skipping the first max(1, K // 3) of K segments and the last, so two-task studies prune only on divergence.

Raw returns (--normalize none) require shared task reward scales; otherwise the driver warns. baseline uses (score − floor) / (ref − floor) from baselines.yaml; missing entries fail, stale SHAs warn. rank uses fractional rank per task across completed trials; it needs no baseline but early ranks are non-stationary. Aggregation defaults to median (resists outliers); min lets one weak task sink a trial; mean averages scores. Portfolio exports default to global L0.

  1. Capture floor/ref baselines for the task set.
  2. Run the portfolio study normalized against those baselines.
  3. Export the winner to the global per-algorithm config.
srb agent tune baseline --tasks sample_collection peg_in_hole landing \
  --algo skrl_ppo --budget 10_000_000
srb agent tune run --tasks sample_collection peg_in_hole landing --algo skrl_ppo \
  --trial-steps 10_000_000 --n-trials 30 --normalize baseline --aggregate median
srb agent tune export --study srb-skrl_ppo-state-multi-<hash8>-v1   # --to global by default

Registered search spaces

State-observation spaces are registered for these online RL labels:

FrameworkLabels
skrlskrl_ppo; skrl_sac; skrl_ppo_rnn
stable-baselines3sb3_ppo, sb3_sac, sb3_tqc, sb3_td3, sb3_crossq
sbx (JAX SB3)sbx_ppo, sbx_sac, sbx_tqc, sbx_td3, sbx_crossq
rsl_rlrsl_rl_ppo
DreamerV3dreamer
TD-MPC2tdmpc2

Unknown --algo labels list available spaces and exit. Registered but unavailable labels fail capability preflight.

DreamerV3 / TD-MPC2 caveats

Dreamer uses run.steps; TD-MPC2 uses steps as its native total-step budget. Export resets these driver-owned keys to production values; --pin rejects them. With num_envs > 1, framework and reporter step counts may differ by a constant factor; calibrate a short run before trusting projections.

Dreamer tunes run.train_ratio and a model_size capacity preset (12M to 100M). TD-MPC2 tunes optimizer, MPPI planner, and loss; model_size sets architecture dimensions at load.

validate Options (noise arbiter)

validate reruns the top K completed trials on fresh seeds, ranks their mean objectives, and writes <study>/validation.json without changing study records. Candidates use recorded trials/NNN/trial_cfg.yaml files, including pins; only the seed and --validate-steps budget change. Portfolio candidates rerun every segment with study normalization. Winners need --min-ok COMPLETEd seeds (default: strict majority); others are marked (below min-ok).

OptionDefault or limit
--study NAMEREQUIRED
--storage URLjournal default; PostgreSQL Optuna URL
--top-k K3 trials by training value
--seeds S3 fresh seeds per candidate, averaged
--seed-base B10000; seed = B + i; keep B through B+S-1 clear of training seeds
--min-ok NMajority of --seeds COMPLETEd seeds
--validate-steps NStudy budget (env-steps); raise for higher fidelity
--gpus 0,1Unset inherits environment/framework default; otherwise round-robin
--n-workers N1 concurrent rerun slots
--trial-timeout S—; kill reruns exceeding this many seconds
--keep-artifactsFalse
--logdir/--logslogs/tune
srb agent tune validate --study srb-skrl_ppo-state-sample_collection-v1 \
  --top-k 5 --seeds 4 --gpus 0,1

The printout names the robust winner and prints its export command; if it differs from best_trial, it notes the change.

status / export / repair Options

OptionApplies toDefault or limit
--study NAMEAllREQUIRED; e.g. srb-skrl_ppo-state-pick-v1
--storage URLstatus, export, repairjournal default; PostgreSQL Optuna URL
--logdir/--logs PATHstatus, export, repairlogs/tune
--trial (trial number or best)exportbest
--to {task,global}exportStudy-dependent: task for single-task, global for portfolio; portfolio --to task is ambiguous and errors
--dry-runexportFalse; print diff without writing
--forceexportFalse; overwrite existing file
--stale-hours Hrepair24; fail RUNNING trials older than this

Examples

srb agent tune run --env sample_collection --algo skrl_ppo \
  --trial-steps 20_000_000 --n-trials 40 --n-workers 2 --gpus 0,1

Output

Study files live under logs/tune/<study-name>/:

logs/tune/srb-skrl_ppo-state-sample_collection-v1/
  journal.log        # Optuna JournalStorage (NFS-safe; shared by parallel workers)
  study.yaml         # frozen manifest (search-space hash, budget, objective, seed base)
  trials/000/        # per-trial: trial_cfg.yaml, metrics.jsonl, logs/

Exports include a provenance header in hyperparams/<framework>/<algo>.yaml (global) or hyperparams/task/<task>/<framework>/<algo>.yaml (task-specific); <algo> is the framework-local name (e.g. ppo). Dreamer and TD-MPC2 use single files: dreamerv3.yaml and tdmpc2.yaml in the same roots.

See Also

srb real_agent — Sim-to-Real Bridge

Subcommands

srb real_agent <action> [options]
ActionPurpose
gen, sim2real_genGenerate Gymnasium counterpart (sim2real_gen alias).
zero, randZero/random actions.
teleop, rosDirect input; ROS 2 / Space ROS topics.
train, evalTrain/evaluate hardware policy.
collectHuman, policy, random, zero datasets.
validateRun hardware telemetry checks and report pass/fail.
rebuild-summaryRebuild summary.json / report.md.
replay-twinCompare session with baseline .rrd in Rerun.

For simulation-side counterparts, see srb agent.

srb real_agent gen

  1. Generate a hardware counterpart with Isaac Sim. Its generated runtime targets hardware:

    srb real_agent gen --env ENV_ID [options]
    srb real_agent gen --env waypoint_navigation env.robot=leo_rover --hardware ros_cmd_vel ros_tf ros_mw
    
    OptionDefault / limit
    -e, --env, --task ENV_IDRequired; ALL selects cached non-template environments.
    --cfg PATHDEFAULT; Hydra values DEFAULT, IGNORE, NONE, NULL.
    --hardware, --hw [HW …][] keeps an existing module’s HARDWARE; e.g. ros_cmd_vel, ros_tf, ros_mw, ros_depth_heightmap, ros_imu.
    --checkFalse; deterministic freshness gate, described below.

    RealEnvGenerator converts the registered Gymnasium spec to srb/interfaces/sim_to_real/env/<env_id>.py.

    Before use, install the required modules and selected backends on the deployment target. If a runtime-dispatched command needs a generated environment and srb_real/ registration is missing, it generates the environment in a subprocess. The command then exits with instructions to rerun it.

  2. Review modules against the robot deployment config. Native teleop and human collection need declared live actions:

    • Six device values: translation and rotation on XYZ, after device gains.
    • An event mapped to named action slices.

    The generator and RealEnv check the exact action order. The adapter scales actions. Without a declaration, COMMAND_MAPPING = None. Policy and raw ROS ignore this mapping. Custom simulator mappers require it. Native teleop and human collection fail before hardware starts. Shipped modules declare the mapping.

--check — the freshness gate

--check renders a temporary file beside the target. It formats the file with Ruff, or with fallback Black, then compares it byte-for-byte with the checked-in module.

If the files differ, the command prints a unified diff and writes nothing. Missing formatters raise FormatterUnavailableError. Formatter failures raise FormatterFailedError. With --env ALL --check, it checks cached modules and skips missing modules. It fails if there are orphans or the cache is empty.

Landscaping task IDs

terrain_landscaping_crater uses a fixed crater manifest. terrain_landscaping uses a per-episode mission manifest. Neither task accepts env.particles_height. Missing capability tags cause RealEnv construction to fail. See Terrain Landscaping.

Runtime commands

Shared runtime options:

OptionDefault / limit
-e, --env, --task ENVRequired; environment under srb_real/.
--cfg PATHDEFAULT; Hydra YAML override.
--hardware, --hw [HW …][]; runtime hardware interfaces.
--logdir, --logs PATHlogs/ in a source checkout or current working directory when installed.
CommandOptions and behavior
teleop, human collect--teleop_device (ros default; spacemouse, haptic); --pos_sensitivity (1.0); --rot_sensitivity (3.1415927 rad/s); --invert_controls (True). Simulator-only keyboard/gamepad fail before hardware or input acquisition.
collect--collector (human, policy, random, zero; infers policy with --algo/--model, else human); --num_episodes (100); --horizon (400); --success_only (False); policy accepts --algo, --model.
ros--ros_sync/--ros-sync (False); --ros_action_timeout/--ros-action-timeout (unset: 5 s startup wait, 0.5 s command lifetime); --ros_unthrottled/--ros-unthrottled (False). See real_agent ros.
trainRL --algo required (e.g. dreamer, tdmpc2, sbx_ppo); --continue_training (False) / --model (None).
evalRequires --algo and/or --model (each defaults None); choices include dreamer, tdmpc2, sbx_ppo, robomimic_bc, robomimic_cql.

Native teleop has no policy-command interface. It rejects --algo and --model; use eval or policy collect instead. srb agent teleop retains policy mode.

In eval and policy collect, SRB --model artifacts supply --algo when it is omitted. They also supply the bundled config. Real datasets set split=real and controller=human|policy|random|zero. Artifacts record the resolved checkpoint and source paths.

Native direct input

Before a session starts, native teleop and human collection validate mappings and devices. The mapper returns one flat action for the adapter to scale. --invert_controls inverts XY for manipulation only.

ROS teleop uses global /cmd_vel (Twist) and /gripper (Bool) topics with sensitivity gains. Its inputs differ from the flat policy actions in real_agent ros. ROS and haptic timeouts are separate from the raw-policy sample deadline. Native haptic has no simulator-contact force feedback.

Termination or --horizon ends an episode. ROS and haptic input have no manual save, discard, or reset controls (see collection). SpaceMouse keeps its buttons, including left-button reset; the CLI lists them.

Datasets preserve observation leaf contract shapes and terminal rows at environment or horizon end. The command reports open and cleanup failures. It cleans up input before releasing the environment ROS node/context. See teleop for device details.

Validate hardware

  1. Run validation with its YAML spec:

    srb real_agent validate --spec SPEC_PATH [options]
    
    OptionDefault / limit
    --spec PATHRequired; e.g. hyperparams/validation/excavation.yaml.
    --checkpoint PATHNone; overrides checkpoint; raw path or SRB artifact.
    --episodes NNone; overrides n_episodes.
    --wandbFalse; enable optional Weights & Biases summary sink.
    --no-tensorboardFalse; disable TensorBoard scalar sink.
    --no-rerun-webFalse; disable viewer; local .rrd remains if rerun.record_to_rrd=true (default), Rerun is installed and starts.
    --post-statusFalse; post pass/fail as a GitHub commit status; requires the gh CLI.
    --storage-root PATHlogs/real_validation in shipped specs.
    --dry-runFalse; validates spec and session setup, skips deployment checks and environment/policy factories; on success exit_code: 4 (preflight_fail), pass_overall: false.

    Validation runs the generated environment and available policy reset hooks for each episode. The artifact manifest supplies algo if the spec omits it or sets REQUIRED_AT_RUNTIME. Conflicts fail.

    Artifacts bundle Dreamer, TD-MPC2, RSL-RL, or SKRL config. Raw SKRL/RSL-RL checkpoints need the training .hydra/config.yaml. Validation fails if that file is missing or the metadata policy config is sanitized. See validation workflow and exit codes.

Rebuild a validation summary

  1. Rebuild summary.json and report.md after spec, metric, or post-processing changes without rerunning hardware. SESSION_DIR must contain spec.yaml and logged .jsonl / .rrd telemetry:

    srb real_agent rebuild-summary SESSION_DIR
    

Replay against a baseline

  1. Compare time-aligned hardware (real solid) with simulation (sim ghost) in local Rerun:

    srb real_agent replay-twin --session SESSION_DIR --baseline BASELINE_RRD_PATH
    
    OptionMeaning
    --session SESSION_DIRValidation session containing rollout.rrd.
    --baseline BASELINE_RRD_PATHBaseline .rrd captured from simulation.

srb asset — Manage Assets

Run srb asset <action> [options]. Hydra-style key=value overrides report stray tokens in a named error (exit 2).

Actions

  • list and info discover assets; doctor diagnoses them.
  • download fetches assets; bake bakes a local DEM.
  • clean, cache-stats, and prefetch-fixtures manage caches; validate-manifest checks manifests; stack previews offline.

Kind Choices

KINDAssets
terrainPlanetary DEMs/orthophotos.
rocksProcedural/photogrammetric sets.
hdriHigh Dynamic Range Image skydomes.
lightsCurated presets.

srb asset list

srb asset list KIND [--body {moon,mars,earth}]

--body filters by celestial body.

srb asset info

srb asset info KIND TARGET

TARGET: site, rock set, skydome, or lighting preset.

srb asset doctor

srb asset doctor terrain [TARGET] [options]

Optional arguments: TARGET and --body.

--body filters by celestial body. With TARGET, it rejects a site on another body.

OptionDefault or meaning
--patch PATCHdefault.
--lod {low,medium,high}medium.
--patch-size SIZEFloat, meters.
--center X,YMeters, e.g. 100.0,200.0.
--no-orthoSkip orthophoto check/generation.
--seed SEEDProcedural seed, 0.
--deshadeCorrected variant; separate cache.

srb asset download

srb asset download KIND [TARGET] [options]

Terrain accepts a curated TARGET or a region (--lat, --lon, --size-m), never both.

Regions also accept --body, --deshade, --num-locations, and --location-spread-m.

OptionDefault or meaning
TARGETAsset; omit with --all or region.
--allFetch/bake all registered terrain sites, rock sets, or HDRIs. Lights require a TARGET.
--body {moon,mars,earth}For regions, defaults to moon; with --all, filters terrain sites, rock sets, or HDRIs.
--patch PATCHDefault default.
--lod {low,medium,high}Default medium.
--patch-size SIZEFloat, meters.
--center X,YMeters.
--no-orthoSkip orthophoto baking.
--seed SEEDProcedural seed, default 0.
--lat LAT --lon LON --size-m SIZERegion: coordinates in degrees, size in meters; require all three; omit TARGET/--all.
--deshadeCorrected terrain color; manifest deshading applies if omitted.
--num-locations NRegion patches, default 1; above 1: deterministic offsets.
--location-spread-m SIZEOffset radius, meters; for --num-locations > 1, default is region size.
--forceRe-download/re-bake valid cached entries.
--debugVerbose pipeline logs and traceback per failed item.

Non-terrain kinds reject terrain-only options and --force. --lod medium and --num-locations 1 act like omission.

srb asset bake

srb asset bake terrain --dem DEM_PATH --body {moon,mars,earth} --site-name NAME --attribution ATTR [options]
OptionDefault or meaning
--dem DEM_PATHUser DEM path, absolute/relative (e.g. GeoTIFF).
--body {moon,mars,earth}Body.
--site-name NAMECustom-site name.
--attribution ATTRMetadata attribution string.
--patch-size SIZEFloat, meters.
--lod {low,medium,high}Mesh LOD, default medium.
--seed SEEDProcedural rock/displacement seed, default 0.
--debugVerbose mesh logs.

srb asset clean

srb asset clean KIND [TARGET] [options]
Argument/optionDefault or meaning
KINDterrain, rocks, hdri, lights; only terrain supported. Others exit 2: clean: unsupported kind: '<kind>'; use 'terrain'
TARGETOptional; clean only its baked cache.
--rawRemove shared raw archives; omit target.
--bakedRemove baked cache publications and their required files; raw archives remain unless --raw is also selected.
--allRemove all kind cache entries; omit target.

Pass one of --raw, --baked, or --all (otherwise exit 2). Raw archives share content identity. TARGET with --raw/--all is a usage error (exit 2). Clean one site’s baked cache: srb asset clean terrain TARGET --baked.

srb asset validate-manifest

srb asset validate-manifest [--manifest MANIFEST_PATH] [--check-urls] [--check-shas]
OptionDefault or meaning
--manifest MANIFEST_PATHCustom YAML; default: packaged.
--check-urlsHTTP-check mirrors and links.
--check-shasCheck downloaded raw dataset SHA256 against manifest.

srb asset cache-stats

srb asset cache-stats

Prints cache root, total size, entries/sites per body, stale temporary-directory count.

srb asset stack

srb asset stack --body {moon,mars,earth} --lat LAT --lon LON --size-m SIZE [options]
OptionDefault or meaning
--body {moon,mars,earth}Required body.
--lat LAT, --lon LONRequired coordinates, degrees.
--size-m SIZE (--size)Region size in meters; max 8000 m; larger requests refused.
--lod {low,medium,high}medium.
--target-gsd GSDTarget ground-sample distance, meters.
--catalog PATHYAML catalog override (mainly fixture testing).
--allow-largeShows the preview as if large downloads were approved; does not download.
--deshadeText preview reports the request; it does not resolve corrected output.
--jsonJSON instead of table; serializes the plan and omits the --deshade request.

“Consent required” is descriptive; fetch rechecks per-layer consent at srb.terrain.sources.acquisition.check_layer_consent. “Consent required: none” from --allow-large or SRB_TERRAIN_LARGE_OK=1 does not affect fetches.

srb asset prefetch-fixtures

srb asset prefetch-fixtures

Pre-bakes every manifest terrain site at lod=low.

Examples

srb asset list terrain --body moon
srb asset info terrain jezero
srb asset download terrain jezero --lod high
srb asset bake terrain \
  --dem /path/to/my_dem.tif \
  --body moon \
  --site-name Shackleton_Ridge \
  --attribution "LOLA / Kaguya Team" \
  --lod high
srb asset doctor terrain jezero --lod high
srb asset clean terrain --baked
srb asset cache-stats

srb dataset — Manage Dataset Artifacts

Manage SRB datasets in canonical JSONL, robomimic HDF5, LeRobot-style layouts, or real-validation telemetry.

Usage

srb dataset <action> [options]

Actions

ActionPurpose
infoPrint manifest, artifact hash and action-schema summaries (JSON).
validateCheck manifest, files and declared physical counts; --deep checks rows/tables; --strict makes warnings errors.
compatibilityReport learning, collection/eval or publication compatibility; --algo ALGO focuses on one algorithm, otherwise reports the matrix.
exportConvert srb_jsonl to srb_jsonl, robomimic_hdf5 or lerobot, and robomimic_hdf5 to srb_jsonl or lerobot; lerobot is an export target only.
pullDownload from Hugging Face Hub by --repo-id or --task/--embodiment/--action-mode; --dry-run plans without network access.
pushUpload to Hugging Face or plan with --dry-run.
cardWrite a Hugging Face README.md dataset card.
replaySummarize canonical data or preview in Rerun (--backend rerun).
from-validationConvert real validation data to canonical SRB (split=real).

See Event Camera for event capture, validation and export actions: record-events, validate-events (stats, reconstruction), export-lerobot-v3, export-zenodo-bundle, export-raw-evt3, import-raw-evt3 and export-rosbag.

For fixture generation, seed/provenance markers, export restrictions, explicit task provenance, LeRobot/Zenodo mixed selections, scorecards, and RAW EVT3/ROS bag behavior, see Event Camera recording.

NPZ exports warn and preserve fixture provenance.

For task data, import with explicit provenance. Example: srb dataset import-raw-evt3 INPUT.raw --output INPUT.h5 --task landing --policy-id POLICY.

export-zenodo-bundle preserves manifest-row JSON text. It normalizes surrounding whitespace and line endings only. Derived Hub repo ids go only in zenodo_metadata.json, so bundles pass SRB validation.

Missing --citation-md files fail before writes. --doi adds a DOI to metadata and README. Without --doi, no DOI is added. export-rosbag writes metadata.yaml and bag_0.db3 in --output.

Algorithm Compatibility

srb dataset compatibility DATASET --purpose train --algo ALGO reports implemented training input.

training_dataset_mode is offline, replay_prefill, or unsupported. Collection, eval, and publication compatibility does not imply demonstration-training support.

Unsupported focused training returns compatible=false with exit 1. Omit --algo for the matrix.

Checks cover manifest metadata and storage. The trainer checks payload, action, and observation semantics.

Publication Format

Publish as srb_jsonl (preferred) or lerobot (optional data dependencies). Convert training-oriented robomimic_hdf5 before push.

Admission and file references

Limits: 100,000 entries, 32 directory levels, 16 GiB per file, and 16 GiB total member bytes.

.srb.json selects the manifest and referenced file or directory. Sibling files are excluded. Referenced directories set traversal depth.

External manifests use one entry and share the byte budget. Embedded manifests count once. LeRobot data selects the format root, which includes sibling meta.

References stay relative to the manifest dataset root. Robomimic sidecars store the data file relative to the sidecar, so a run directory stays valid after it is moved or copied.

A legacy absolute reference that no longer exists resolves to the same-named entry beside the manifest. Absolute/external references are readable, but external sidecar refs cannot be contained uploads or strict demonstration replay inputs.

Validation, export, and replay read verified private copies. Caller changes cannot alter reads, and replacement during copy is rejected. Unversioned directories lack atomic multi-file writer generations.

Provenance and summaries retain original paths. Temporary copies are released when the operation or iterator closes.

Conversion and export limits

Robomimic HDF5 payloads must be direct. Validation rejects external or symbolic links, virtual datasets, and external raw storage. Internal hard links are supported. Sidecars may reference directly stored HDF5 elsewhere.

Canonical conversion uses a temporary disk row-location index, up to 16 GiB. It preserves numeric episode and stable step order without retaining whole episodes.

HDF5 exports declare demo array shapes and dtypes before samples. LeRobot discovers the full column schema before Parquet batches. Canonical JSONL lines, including the newline, are limited to 16 MiB. Resource-limit failures preserve published output.

LeRobot timing and Parquet

LeRobot infers type and size per value. It is slow for image-heavy data; use srb_jsonl.

LeRobot v3 requires a finite, positive nominal source fps. TrajectoryRecorder accepts an optional fps keyword and stores it in the SRB sidecar.

Fractional rates work. Missing timing causes an error; it is not inferred. Unknown-rate JSONL/Robomimic data remain readable and convertible.

Timestamps are float32 seconds (frame_index / fps). The frame index resets per episode. Global index values are contiguous. Episode dataset_from_index/dataset_to_index values match the data_from/data_to aliases.

Deep validation checks fields, timing, order, and counts. It retains physical row counts on feature-dtype mismatch.

Parquet uses bounded schema, sizing, and write passes. One decoded Arrow ceiling covers frame, episode, and task tables. Released rows and batches do not accumulate as live memory.

Preflight rejects oversized products before opening a writer. The product limit is 16 GiB; the array limit is 2 GiB.

Cards and upload behavior

Fresh publishable exports include README.md. card defaults to returning its verified card without rewriting.

To create a missing card, provide external --output. push can generate one privately.

push --dry-run plans a bounded manifest/file inventory without payload copies. It neither deep-validates nor guarantees upload success.

Actual push validates a held private snapshot through upload. Caller-owned bytes stay unchanged.

Replay and JSON input limits

For canonical JSONL, --max-episodes counts distinct first-seen episode_index values across files. It retains later continuations in stream order. Interleaving may require scanning unselected rows. --max-steps limits yielded rows.

Present keys per episode index must agree. Replay summaries reject action-dimension changes and bound episode, observation-key, success, and action-schema bookkeeping.

Canonical JSONL and strict demonstration readers structurally check JSON before parsing. Each document allows at most 1,000,000 containers, keys, and scalar values. Maximum depth is 64, with the root at zero.

Duplicate entries count even if only the last is parsed. Strings and escaped delimiters follow JSON rules. Programmatic whole-read lines are limited to 256 MiB; normal lines are limited to 16 MiB. These limits apply to input, not process memory.

APIs that retain full episodes or transitions share 16,000,000 nodes across rows and files. Streaming export applies cumulative byte limits and admits rows separately.

Manifests, LeRobot JSON, and Robomimic contract/environment metadata use this decoder. Native training shares the allowance across manifests, environment metadata, and normalized inputs. Unchanged owned metadata is reused.

LeRobot validation

Parquet reads reject unsupported Arrow extensions and ambiguous dotted paths before decoding. Conservative footer bounds may reject variable-width or nested rows that would otherwise fit.

Validation checks row shapes, primitive compatibility, and termination agreement. Manifest roots may name slash-separated leaves. Omitted dtypes and unknown shapes remain unspecified. Extra provider columns are allowed. meta/stats.json is a bounded JSON object.

Nullable columns and structured object observations work, including exporter [1] for scalar observations and bookkeeping. Actions and non-scalar arrays match the declared rank.

Fixed shapes describe non-null values. Nulls provide no shape or value evidence. Object arrays keep outer dimensions and may contain nullable mappings. Termination flags must be non-null booleans.

Robomimic validation

Validation and export check physical scalar types before count and success attributes.

Known HDF5 text fields (env_name, env_kwargs, env_args, action_schema) use bounded Linux decoding: 64 MiB per value and 128 MiB aggregate metadata. Fixed- and variable-length strings retain their values.

Bounded Linux workers inspect HDF5 for count-only and deep validation. Count-only checks counts and present masks. Deep validation also checks demos, observations, and termination.

Ordered diagnostics and observation keys share a finite report allowance. Exhaustion fails rather than returning partial success.

Merge admission and behavior

Merge rejects inputs when demos differ in action dimension or observation keys, or when demo_io_contract, action_schema, or env_name differs.

The output keeps the first input’s env_kwargs and the shared demo_io_contract and action_schema. Merge validates private input copies and prepares the full private output before staging. Invalid input creates no destination parent.

Publication is atomic. Pre-promotion failure preserves prior output. A shared copy allowance admits fixed-width extra demo members and declared chunks.

Copied scalar variable-length text counts encoded bytes against per-attribute and shared metadata limits, not descriptors. Short strings, exact fits, and following empty values or inputs remain valid.

Initialized-stage copy_merged_hdf5 admits each input first. The caller discards a failed private stage. Uncopied unknown attributes use descriptor-only admission.

Scalar text is materialized in the finite worker before byte checks, without a per-attribute limit. Other variable-length attribute and dataset heaps are unchecked.

Native worker limits

Linux workers run native inspection and merge admission/copy under these ceilings, including startup:

  • Address space: 2 GiB.
  • Output file: 16 GiB.
  • Time: 120 seconds.

Hdf5NativeLimits may lower these limits with merge_datasets(..., native_limits=...). Verify cleanup and output identity before publication.

These ceilings limit damage, but admitted arrays may still exceed native overhead. Lower source-byte limits apply before parent hashing and copying and are shared across inputs.

Merge selects sorted demo_* and builds fresh masks. train_split must be in [0, 1]; positive splits retain a training demo.

Merge uses the first metadata result, even if empty. It regenerates env_args and drops action_schema and original attribute storage. Generated attributes must fit lowered metadata limits before private output. Oversized regenerated env_args fails.

Arbitrary HDF5 reference-graph fidelity is not guaranteed. Some decoder heaps are unbounded. Install h5py in the selected interpreter. Metadata workers ignore caller PYTHONPATH, PYTHONHOME, and user site.

Publication cleanup errors

PublicationCommitCleanupError may follow commitment if private-stage/marker cleanup fails. committed_paths lists destinations. retry_cleanup() retries without merge/output replacement.

Cleanup identities persist, and foreign replacements stay untouched. If merge and input cleanup fail pre-promotion, PublicationCleanupError retains the original failure and pending stage/input owners. Paths are empty if nothing was committed.

Typed native/metadata cleanup errors retain process/source copies for retry. Context exit/GC retain pending copies. Snapshots cannot enter another consumer context.

Training and recorder configuration

Native Robomimic training retains verified copies. It admits configured fields, masks, metadata, and dataset allocations before provider reads. Per-demo model_file uses bounded metadata decoding.

See offline learning for cache, worker, and normalization behavior.

TrajectoryRecorder retains observation/action copies. It rejects invalid or oversized rows before adding. Bounded-batch save raises ResourceLimitError above max_demos.

Keyword-only max_decoded_bytes, max_batch_bytes, max_metadata_bytes, and max_file_bytes lower defaults of 16 GiB, 256 MiB, 128 MiB, and 16 GiB. Arrays, config, and rows share allowances.

Construction captures the action declaration, environment metadata, observation keys, action dimensions, provenance, and certification. Caller changes or public diagnostic edits cannot reconfigure it.

Present HDF5 environment metadata/schema must match before append/finalize (JSON key order is ignored). If absent, dimensions/observation roots must match. Append validates masks; finalize may rebuild. Nested paths/shapes agree across observations, next observations, and episodes.

Present SRB sidecar must match identity, data target, and captured config/provenance. Stale counts/splits may rebuild. Manifest JSON is sorted/indented with a newline; maximum size is 64 MiB.

Recorder publication and decoder limits

Append/finalization modify private copies under a publication lock. Each save/finalize copies the current HDF5, so I/O grows over time. Pre-promotion failure preserves the previous file/episode for retry.

After HDF5 commit, the episode is consumed and counts advance even if cleanup fails. Cleanup retry must not append it again.

Finalization prepares the sidecar before HDF5 promotion and serializes both writes with cooperating writers. HDF5 and sidecar publish separately. Post-promotion sidecar failure is reported and retryable with finalize().

Native HDF5 decoder allocations outside metadata, inspection, merge and normalization workers need separate limits, including recorder append reads. Encoded-storage checks on other attributes do not bound later consumers.

Action Metadata

Actions are flat vectors for framework compatibility. Grouped actions add metadata.action_schema, which records ordered component names, paths, shapes, dimensions, and flat offsets.

info exposes action_dim, action_components, and action_schema. Export preserves schema in canonical JSONL, robomimic HDF5, and LeRobot.

Validation checks metadata.action_dim. LeRobot copies schema to meta/info.json as srb_action_schema; deep validation checks manifest agreement. Cards include a compact table. Replay summaries print schema; Rerun logs actions/<component>.

Validation always reconciles declared episode/sample/action counts with physical JSONL, HDF5 or Parquet lengths. If a reader (e.g. h5py, pandas Parquet backend) is unavailable, count validation fails explicitly; unchecked data is never reported valid.

Demonstration I/O Metadata

Robomimic collection records metadata.demo_io_contract vsrb.demo_io.v1. It contains the observation projection, ordered action components/dimensions/ bounds, and available runtime scales. Export preserves it in the canonical manifest.

Each observation row has its term shape; simulated depth is uint8. See collection output for layout/limits.

Deep validation requires declared leaf term shape, capable dtype, and in-range values. obs/next_obs leaves must agree. HDF5 data.demo_io_contract must equal the manifest.

LeRobot meta/info.json carries srb_demo_io_contract, implied image views as srb_visual_views, and matching feature shapes. Collection smoothing/stacking config is under env_wrappers. Recorded actions are pre-smoothing policy commands.

Certified rows require explicit next_obs, terminated, and truncated. Nested observation leaves/shapes must match next observations.

Certified LeRobot v3 exports carry transition extension srb.lerobot.transitions.v1. Each action row pairs observation.* and next_observation.* features, including the terminal endpoint. The manifest and meta/info.json share the srb_transition_extension path mapping.

Component-wise percent encoding distinguishes literal dots, slashes, and percent signs from nested paths. Strict validation checks the mapping, paired shapes, physical counts, and three Boolean flags. SRB replay reconstructs original nested observations.

LeRobot 0.4 stores one-element features as scalars. Certified exports retain original shapes in manifest obs_shapes ([] vs [1]) for replay. Feature ranks above five are rejected before publication.

Stock-consumer compatibility applies to the pinned LeRobot 0.4 reader. Endpoint columns do not ensure every upstream policy consumes demonstration transitions.

Uncertified exports omit the transition extension. Markerless LeRobot replay does not invent next observations or termination flags.

Data without a demo contract remains readable, but conversion cannot add a contract or recover unrecorded termination flags. Strict replay checks metadata against its live wrapper before inserting transitions.

Examples

srb dataset validate /data/srb_excavation --deep --strict
srb dataset export /logs/excavation/collect/datasets/demos.hdf5 \
  --output /data/srb_excavation_policy --format srb_jsonl
srb dataset replay /data/srb_excavation_policy \
  --backend rerun --save /tmp/srb_excavation.rrd
srb dataset push /data/srb_excavation_policy --dry-run
srb dataset pull --task excavation --embodiment kinova_gen3 \
  --action-mode smooth_osc --dry-run
srb dataset pull --repo-id space_robotics_bench/srb_excavation_kinova_gen3_smooth_osc \
  --output /data/srb_excavation_policy
srb dataset from-validation logs/real_validation/excavation/<session> \
  --output /data/srb_excavation_real \
  --embodiment kinova_gen3 --action-mode smooth_osc

pull --output requires an absent or empty directory. Non-empty destinations are refused. Downloads never merge revisions.

from-validation sets split=real. Sessions with a validation algorithm/checkpoint default to controller=policy; other sessions default to real.

--embodiment/--action-mode default to real_hardware/real. --controller choices: human, policy, random, zero, real.

srb model — Manage Model Artifacts

Package checkpoints as self-contained SRB model artifacts with SRB identity, metrics, framework restore metadata, and optional dataset provenance, including from consumed-demo runs.

Usage

srb model <action> [options]

Actions

ActionPurpose
create CHECKPOINT --output OUTPackage one checkpoint. Requires --algo, plus --task, --embodiment, and --action-mode unless inferred from --dataset.
from-run RUN --output OUTPackage a completed SRB run’s latest checkpoint; infer algorithm and task from metadata.json. Without --dataset or consumed-demo provenance, also pass --embodiment and --action-mode.
info PATHPrint manifest JSON.
validate PATHValidate manifest, checkpoint, and bundled config paths; --strict makes warnings errors.
card PATHGenerate a Hugging Face README.md model card; schema 3 artifacts bundle the canonical card without rewriting it.
push PATHUpload or dry-run Hugging Face publication.

Both package actions accept repeated --metric key=value and --metadata key=value. Metrics must be finite numbers; text, nan, and inf are rejected. Metadata values are strings.

Portable Restore

from-run preserves available restore context:

  • Dreamer and TD-MPC2 can include config.yaml.
  • RSL-RL checks run-root config.yaml, then .hydra/config.yaml’s agent section, then metadata.json’s run.agent_cfg.
  • SKRL checks .hydra/config.yaml’s agent section, then metadata.json’s run.agent_cfg.

Reject the last source if it contains redacted or non-finite placeholders. The error names the key path. Redaction covers secret-looking key names and credential strings (URL userinfo, credential headers, and Bearer values). Warnings show key paths only.

For SB3/SBX, packaging requires inventoried vecnormalize.pkl statistics when the source RL-Zoo config declares normalization. Missing or ambiguous source evidence can remain unknown. Verify normalization state before packaging.

These commands accept artifact directories wherever they accept checkpoint paths: srb agent eval, srb agent collect, srb agent teleop, srb real_agent eval, and srb real_agent validate.

Loading an artifact can execute code (pickled checkpoints and statistics, SKRL model expressions). Load only artifacts from trusted sources.

SB3/SBX preserves RL-Zoo normalization state:

  • Packaging:
    • Normalized runs require inventoried, hashed vecnormalize.pkl.
    • Non-normalized runs record that state.
    • Missing or contradictory context fails packaging.
    • Re-package artifacts without a normalization declaration from the original run before inference.
  • Inference:
    • Restores frozen statistics without normalizing evaluation rewards.
    • Dict observations and recurrent episode state retain the policy layout.

Publish with dataset provenance from --dataset, a recorded consumed-demo run, or --dataset-repo-id plus optional --dataset-revision.

Preparation, validation, and restore stream hashes under per-file and aggregate limits, rejecting oversized or changing files. Schema 1/2 restore copies checkpoints and configs to temporary storage, verifies hashes, and removes partial copies on failure.

Examples

# Package the latest checkpoint from a run and infer identity from the dataset
srb model from-run logs/excavation/rsl_rl_ppo/<run> \
  --dataset /data/srb_excavation_policy \
  --output /models/srb_excavation_rsl_rl_ppo

# Validate and inspect the artifact
srb model validate /models/srb_excavation_rsl_rl_ppo --strict
srb model info /models/srb_excavation_rsl_rl_ppo

# Dry-run the Hugging Face upload, including the generated README.md
srb model push /models/srb_excavation_rsl_rl_ppo --dry-run

# Reuse the packaged artifact for policy rollout
srb agent collect --env excavation --model /models/srb_excavation_rsl_rl_ppo

srb isaac — Isaac Sim Utilities & Python REPL

srb isaac (srb isaacsim) wraps the Isaac Sim launcher and Python interpreter.

Usage

srb isaac sim         # Launch the Isaac Sim GUI application
srb isaac python      # Run the Isaac Sim Python interpreter

Use srb isaac python without the app or a scene for scripting and exploration. To attach a REPL to a running simulation, pass --repl to an agent command: zero, rand, teleop, ros, train, eval, or collect.

Put -- after the sub-subcommand to forward remaining arguments verbatim:

srb isaac python -- -m pip list
srb isaac sim -- --no-window
srb isaac sim -- --/app/window/title="My SRB Session"

Before launch, srb isaac sim checks that the resolved launcher is an executable file. If Isaac Sim is unavailable, set ISAACSIM_PATH to the installation containing isaac-sim.sh, or put isaacsim on PATH. Missing, non-file, and non-executable paths produce typed CLI errors.

Aliases

With no further argument, srb isaacsim aliases srb isaac sim and opens the GUI.

Python Example

from srb.core.app import AppLauncher

app = AppLauncher(headless=True).app

import torch
from srb.tasks.manipulation.sample_collection import Task, TaskCfg

env_cfg = TaskCfg(num_envs=4)
env = Task(env_cfg)
env.reset()

for _ in range(50):
    env.step(action=torch.tensor(env.action_space.sample(), device=env.device))

env.close()
app.close()

In-Flight REPL with --repl

Attach a Python REPL to a running simulation with --repl:

srb agent zero --env sample_collection --repl ptpython
srb agent train --algo sbx_ppo --env landing --headless --repl

The background thread preloads env, sim_app, and mute()/unmute() helpers to silence simulator stdout. Choose ptpython (default) or bpython.

SRB_REPL can also enable the REPL:

SRB_REPL valueBackend
ptpython, 1, or true (case-insensitive)ptpython
bpythonbpython
Any other valueREPL stays off

Explicit --repl takes precedence.

Note: Offline srb agent learn does not launch Isaac Sim, so it has no --repl option.

See Also

  • srb agent — agent subcommands that accept --repl
  • srb gui — native Rust GUI for SRB

srb ephemeris — Real Sun/Planet Geometry (Optional Feature)

Usage

srb ephemeris <action> [options]

Install srb[spice] for live queries. Help and completion need neither the extra nor Isaac Sim; download/info load spiceypy and numpy; import needs no spiceypy (details).

Actions

ActionPurpose
downloadFetches ~43 MB of pinned kernels (bundle).
infoPrints body azimuth, elevation, distance, angular diameter, and irradiance scale.
importImports illumination as an srb_illum/2 sidecar (Lunarlab/PGDA details).

info Options

OptionRequiredDescription
--body {moon,mars,earth}YesObserver.
--lat LATYesLatitude, [-90, 90]°.
--lon LONYesLongitude, °.
--alt ALTNo (default 0.0)Height above mean radius, m.
--utc UTCYesISO-8601 epoch; de440s: 1850–2149.
--bodies BODIESNo (default sun,earth)Choices: sun,earth,moon,mars,venus; Sun included; no duplicates/unknowns.

import Options

OptionRequiredDescription
--source {lunarlab-zarr,lunarlab-npz,pgda-lpsr}YesFormat.
--input PATHYesSource.
--baked-dir PATHNoTarget baked patch.
--out PATHYes*Output.
--crs CRSYes*Target CRS.
--center-xy CX,CYYes*Center.
--size-m SIZEYes*Patch size.
--lat LAT / --lon LONYes*Site coordinates.
--gsd-m GSDYes*Grid spacing.
--epoch-range T0,T1NoUTC range.
--epoch-stride NNo (default 1)Epoch sampling interval.
--body {moon,mars,earth}No (default moon)Terrain body; PGDA-LPSR supports Moon only.
  • Without --baked-dir, starred options are required. Baked metadata supplies CRS, patch size, site, and default output. Grid spacing uses source resolution unless --gsd-m overrides it; --out overrides the output path. Do not pass --lat/--lon with it (status 2). See importer rules.

Examples

srb ephemeris download

Shackleton:

srb ephemeris info --body moon --lat -89.66 --lon 0.0 \
  --utc 2026-11-01T12:00:00 --bodies sun,earth
sun: az=279.043° el=1.512° dist=149685302 km diam=0.559°
earth: az=64.201° el=2.551° dist=384412 km diam=1.916°
irradiance_scale=1.0021

Apollo 17:

srb ephemeris info --body moon --lat 20.19 --lon 30.77 \
  --utc 1972-12-11T19:54:57 --bodies sun

Jezero:

srb ephemeris info --body mars --lat 18.44 --lon 77.45 \
  --utc 2021-02-18T20:55:00 --bodies sun

Lunarlab:

srb ephemeris import --source lunarlab-zarr \
  --input /data/lunarlab/<product>/epochs.zarr \
  --baked-dir <terrain-cache>/moon/<site>/<patch-key>

PGDA-69 LPSR:

srb ephemeris import --source pgda-lpsr \
  --input /data/pgda/lpsr_shackleton.tif \
  --crs "IAU_2015:30135" --center-xy 0.0,10309.969398639505 \
  --size-m 4000 --gsd-m 5.0 --lat -89.66 --lon 0.0 \
  --out /tmp/shackleton_illumination.npz

Disabling Auto-Fetch

Queries fetch missing kernels by default. Disable fetch to require pre-fetch:

export SRB_EPHEMERIS_AUTO_FETCH=0
srb ephemeris download   # run once, ahead of time, with network access

Missing kernels then raise KernelsMissingError naming srb ephemeris download.

See Also

Graphical User Interface (GUI)

Launch the Rust GUI with ROS 2 Jazzy sourced:

source /opt/ros/jazzy/setup.bash
srb gui

The GUI uses egui and r2r. It does not support the optional NVIDIA NGC image.

Pages

  • Tasks: Browse, filter, and select catalog tasks.
  • Session: Run, restart, or end the selected task. Tune gravity and latency while it runs.
  • Metrics: Plot environment 0 reward (/gui/reward) while a task runs.
  • Configure (window): Edit task options and Hydra overrides. Then preview, copy, or run the equivalent command.
    • Displayed text redacts credentials. Processes receive the exact arguments.
    • Put argparse options before Hydra key=value overrides. Do not use --.

The footer toggles the theme and records episode configurations. Recorded DATA rows contain the launched configuration and published runtime_params, such as gravity. The values stay null until the first successful publish. Each launch republishes all parameters. Volatile ROS QoS means new processes can miss values.

Demo defaults:

OptionDefault
Rendering modequality
Teleop deviceskeyboard spacemouse
Interfacegui
Task-specific env.stackCatalog default; true for excavation_demo (parallelism)

Cached haptic devices have generic advanced-controls checkboxes. They have no dedicated GUI controls.

srb gui — Launch GUI

Hint: Arguments after -- go to the GUI application. The exceptions are -h and --help.

SRB checks for cargo and rustc. If either is missing, set an executable prebuilt GUI:

SRB_GUI_BINARY=/path/to/gui srb gui

Outside a source checkout, run python -m srb. Use the Python interpreter where SRB is installed: ISAACSIM_PYTHON, Isaac Sim’s Python, or python3.

In a development tree, SRB uses target/release/gui or target/debug/gui only when cargo or rustc is missing. It prints a warning in that case. Otherwise, SRB builds the GUI from source. SRB_GUI_BINARY takes precedence. Missing or invalid inputs cause a typed CLI error before startup.

Example

srb gui -- --help

Refresh GUI Catalog

After changing task metadata, cache generation, assets, thumbnails, or interfaces, run srb cache update:

srb cache update

Discovery launches Isaac Sim 6.1. srb cache status and srb cache doctor inspect catalogs without it but cannot regenerate metadata. Repair missing, incomplete, or tampered pointers and generations with srb cache update.

Task cards and options use immutable gui_catalog.json generations. srb cache update hashes and validates twelve members. It then atomically switches current.json.

Generations live at <cache root>/namespaces/<namespace>/offline/generations/<generation-id>/.

Set SRB_CACHE_ROOT to choose the cache root. Defaults:

  • Source checkout: <checkout>/.cache
  • Other installs: ~/.cache/srb, or $XDG_CACHE_HOME/srb when set

Before reading the catalog, the GUI validates the pointer, manifest, members, semantics, and catalog.

srb gui sets SRB_GUI_OFFLINE_CACHE_ROOT to Python’s resolved root.

Direct launches query srb cache status --json with a 30-second timeout. A failure or disagreement opens a recovery page.

Task Thumbnails

Thumbnails load from:

docs/src/_graphics/tasks/<task>.webp

Generate or refresh a thumbnail with:

srb doc thumbnail --task excavation_demo --force --width 320 --height 240

After rendering, srb doc thumbnail republishes the current generation. It rebuilds the GUI catalog and copies the other members.

If the generation is absent or outdated, the command warns without changing the cache. Missing thumbnails are nonfatal. The fallbacks are robot, scenery, domain, and the SRB placeholder.

Command Shape

srb agent teleop --env excavation_demo --hide_ui --rendering_mode quality --interface gui --teleop_device keyboard spacemouse env.domain=MOON env.seed=0 env.num_envs=1 env.stack=true env.robot=kinova_gen3n7+scoop_custom3

The customization panel accepts Hydra overrides, such as env.demo_regolith_quality=visual.

Compatibility Matrix

The matrix shows supported robot categories for each task. A ✓ marks a supported combination; a blank cell means unavailable. Tasks prefixed with _ (for example, _manipulation) are reusable templates, not preconfigured goal scenarios; they expose a generic environment and require robot and task-specific goal configuration.

Scope. This matrix is about robot categories only. A ✓ says a task accepts at least one robot of that category, not every robot in it: the three terrain_landscaping tasks, for example, accept only RaphRover with the RaphShovel payload and raise TypeError for any other. It does not say that the task is solved, that any learner has been validated on it, or that it has been run on physical hardware. See the note below the table for the landscaping tasks.

TaskManipulatorMobile ManipulatorMobile Robot
lunalab✓
zerog_lab✓
_manipulation✓
debris_capture✓
excavation✓
excavation_demo✓
modular_assembly✓
multi_peg_in_hole✓
multi_sample_collection✓
peg_in_hole✓
sample_collection✓
screwdriving✓
solar_panel_assembly✓
_aerial✓
_ground✓
_orbital✓
aerial_navigation✓
beam_transport✓
flight✓
formation_following✓
formation_following_decentralized✓
formation_following_orbital✓
landing✓
locomotion_velocity_tracking✓✓
locomotion_waypoint_navigation✓✓
moonfall✓
orbital_evasion✓
orbital_waypoint_navigation✓
rendezvous✓
terrain_landscaping✓
terrain_landscaping_crater✓
terrain_landscaping_mound✓
traversal✓
velocity_tracking✓
waypoint_navigation✓
_aerial_manipulation✓
_ground_manipulation✓
_orbital_manipulation✓
mobile_debris_capture✓
spacewalk✓
spacewalk_eva✓
spacewalk_iva✓

What this table does not say

A row in this matrix is not a support claim for any learner or for physical hardware. For the measured state of the terrain landscaping tasks, see Terrain Landscaping Training.

Action Space Catalog

Each robot offers one or more action modes, chosen at launch via env.robot.action_mode=<mode> (the default mode is marked *). Dims gives action-vector length; Scale multiplies policy output before it reaches the controller. runtime-resolved length depends on the loaded asset (e.g. a joint-space mode with pattern .*) and is read from the action manager when the environment is built.

The machine-readable action spec (env.srb_spec.action) targets the action manager’s runtime terms. Schema-version-2 descriptors name runtime terms directly, e.g. the multicopter cmd_vel, body-acceleration body_vel and task-space delta_twist terms. A schema-version-1 descriptor may split one runtime term into semantic fields, such as lin and ang for the wheeled-drive cmd_vel term, but its summed field dimensions must equal the summed runtime term dimensions. A mismatch of either kind fails the spec build instead of publishing a wrong layout. Groups without descriptors use the schema-version-0 fallback: no semantics, no dimension check. Metadata that carries an unsupported descriptor (the multicopter thrust / multicopter.rotor_thrusts, the task-space quaternion ee_rot / end_effector.orientation, or the velocity-labelled body lin / body.linear_velocity) is rejected on load.

Task-space modes publish one runtime-length delta_twist term: three position-delta channels (m), then three axis-angle rotation-delta channels (rad); position-only inverse kinematics uses the first three. Variable-stiffness operational-space modes append six stiffness channels, and full-impedance modes append six stiffness and then six damping-ratio channels.

Multicopter Body Acceleration (body_acc on the multicopters) is a velocity command despite its name: four channels (linear_x, linear_y, linear_z, angular_z) are clamped to [-1, 1] and multiplied by the scale into m/s and rad/s, and x and y are rotated by the current yaw. Body Acceleration (body_acc on the orbital bodies) is an acceleration command: six channels are clamped to [-1, 1] and multiplied by the scale into a linear (m/s²) and angular (rad/s²) acceleration in the world frame, which is integrated into the root velocity as acceleration * physics_dt on every physics step. The velocity change over one environment step is therefore acceleration * step_dt whatever the decimation. The relative controller variant, when configured, expresses the same command in the body frame.

Task-space modes (diff_ik, osc_*, smooth_osc) act on the tool centre point that tasks observe as robot_ee (the tf_end_effector target): the manipulator’s flange frame composed with the mounted tool’s TCP, or the bare flange when no tool is mounted. The environment config sets every such term’s body_offset to that frame. Isaac Lab’s task-space terms carry the body Jacobian to it in the articulation root frame, the frame the end-effector pose and velocity are measured in (a term’s base_name, when set, must name the root body), and the operational-space terms damp the TCP velocity derived from the flange link frame rather than its centre of mass. A pure rotation command therefore turns the tool about its TCP.

RobotModeControllerDimsScale
Canadarm3diff_ik *Differential Inverse Kinematics60.1
Canadarm3joint_pos_relRelative Joint Position71.0
Frankadiff_ik *Differential Inverse Kinematics60.1
Frankaosc_fixedOperational Space Controller6pos=0.1, ori=0.1
Frankaosc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Frankaosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Frankajoint_pos_relRelative Joint Position71.0
Kinova J2N6Sdiff_ik *Differential Inverse Kinematics60.1
Kinova J2N6Sjoint_pos_relRelative Joint Position61.0
Kinova J2N7Sdiff_ik *Differential Inverse Kinematics60.1
Kinova J2N7Sjoint_pos_relRelative Joint Position71.0
Kinova Gen3N7diff_ik *Differential Inverse Kinematics60.1
Kinova Gen3N7osc_fixedOperational Space Controller6pos=0.1, ori=0.1
Kinova Gen3N7osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Kinova Gen3N7osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Kinova Gen3N7smooth_oscSmooth Operational Space Controller6pos=0.1, ori=0.1
Kinova Gen3N7joint_pos_relRelative Joint Position71.0
Levion Armsdual_arm_joint_pos_abs *Joint Position To Limits41.0
So Arm100 D5diff_ik *Differential Inverse Kinematics60.05
So Arm100 D5osc_var_stiffnessOperational Space Controller12pos=0.05, ori=0.05, stiffness=120.0
So Arm100 D5joint_pos_relRelative Joint Position51.0
So Arm100 D7diff_ik *Differential Inverse Kinematics60.05
So Arm100 D7joint_pos_relRelative Joint Position71.0
Unitree Z1diff_ik *Differential Inverse Kinematics60.05
Unitree Z1joint_pos_relRelative Joint Position61.0
Ur3diff_ik *Differential Inverse Kinematics60.1
Ur3osc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur3osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur3osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur3joint_pos_relRelative Joint Position61.0
Ur3Ediff_ik *Differential Inverse Kinematics60.1
Ur3Eosc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur3Eosc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur3Eosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur3Ejoint_pos_relRelative Joint Position61.0
Ur5diff_ik *Differential Inverse Kinematics60.1
Ur5osc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur5osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur5osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur5joint_pos_relRelative Joint Position61.0
Ur5Ediff_ik *Differential Inverse Kinematics60.1
Ur5Eosc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur5Eosc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur5Eosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur5Ejoint_pos_relRelative Joint Position61.0
Ur10diff_ik *Differential Inverse Kinematics60.1
Ur10osc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur10osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur10osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur10joint_pos_relRelative Joint Position61.0
Ur10Ediff_ik *Differential Inverse Kinematics60.1
Ur10Eosc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur10Eosc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur10Eosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur10Ejoint_pos_relRelative Joint Position61.0
Ur16Ediff_ik *Differential Inverse Kinematics60.1
Ur16Eosc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur16Eosc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur16Eosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur16Ejoint_pos_relRelative Joint Position61.0
Ur20diff_ik *Differential Inverse Kinematics60.1
Ur20osc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur20osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur20osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur20joint_pos_relRelative Joint Position61.0
Ur30diff_ik *Differential Inverse Kinematics60.1
Ur30osc_fixedOperational Space Controller6pos=0.1, ori=0.1
Ur30osc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Ur30osc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Ur30joint_pos_relRelative Joint Position61.0
Random Ur Manipulatordiff_ik *Differential Inverse Kinematics60.1
Random Ur Manipulatorosc_fixedOperational Space Controller6pos=0.1, ori=0.1
Random Ur Manipulatorosc_var_stiffnessOperational Space Controller12pos=0.1, ori=0.1, stiffness=120.0
Random Ur Manipulatorosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Random Ur Manipulatorjoint_pos_relRelative Joint Position61.0
Vispadiff_ik *Differential Inverse Kinematics60.05
Vispaosc_var_fullOperational Space Controller18pos=0.1, ori=0.1, stiffness=120.0, damping=1.0
Vispajoint_pos_relRelative Joint Position61.0
Zeroglab Armsdual_arm_osc *Operational Space Controller24arm_ceiling: pos=0.1, ori=0.1, stiffness=120.0; arm_wall: pos=0.1, ori=0.1, stiffness=120.0
Humanoid21joint_pos *Joint Position To Limitsruntime-resolved1.0
Humanoid28joint_pos *Joint Position To Limitsruntime-resolved1.0
Unitree H1joint_pos *Joint Position To Limitsruntime-resolved1.0
Unitree G1joint_pos *Joint Position To Limitsruntime-resolved1.0
Crazyfliebody_acc *Multicopter Body Acceleration40.5
Ingenuitybody_acc *Multicopter Body Acceleration40.5
Heronthrust *Thrust21.0
Anymal Cjoint_pos *Joint Position To Limitsruntime-resolved1.0
Anymal Djoint_pos *Joint Position To Limitsruntime-resolved1.0
Random Anymal Quadrupedjoint_pos *Joint Position To Limitsruntime-resolved1.0
Cadredrive *Wheeled Drive2lin=0.4, ang=0.7853981633974483
Cassiejoint_pos *Joint Position To Limits121.0
Huskydrive *Wheeled Drive2lin=0.1, ang=0.7853981633974483
Leo Roverdrive *Wheeled Drive2lin=0.4, ang=1.0471975511965976
Mars Roverdrive *Wheeled Drive2lin=0.5, ang=0.7853981633974483
Niftynifty *Joint Velocity12joint_vel_wheel_drive=1.5707963267948966; joint_pos_steer=0.7853981633974483; joint_pos_suspension_yaw=0.5235987755982988; joint_pos_suspension_roll=0.2617993877991494
Open Source Roverdrive *Wheeled Drive2lin=0.2, ang=0.3490658503988659
Perseverancedrive *Wheeled Drive2lin=0.7, ang=1.3089969389957472
Pragyandrive *Wheeled Drive2lin=0.35, ang=1.3962634015954636
Raph Roverdrive *Wheeled Drive2lin=0.4, ang=1.0471975511965976
Raph Roverdrive_filteredFiltered Wheeled Drive2lin=0.4, ang=1.0
Spotjoint_pos *Joint Positionruntime-resolved0.2
Unitree A1joint_pos *Joint Position To Limitsruntime-resolved1.0
Unitree Go1joint_pos *Joint Position To Limitsruntime-resolved1.0
Unitree Go2joint_pos *Joint Position To Limitsruntime-resolved1.0
Random Unitree Quadrupedjoint_pos *Joint Position To Limitsruntime-resolved1.0
Floating Platformthrust_only *Thrust81.0
Floating Platformthrust_and_reactionThrust9thrust=1.0; reaction_wheel_torque=0.05
Int Ball1thrust *Thrust61.0
Int Ball2thrust *Thrust61.0
Apollo Landerthrust *Thrust171.0
Peregrine Landerthrust *Thrust171.0
Vikram Landerthrust *Thrust131.0
Resilience Landerthrust *Thrust91.0
Random Landerthrust *Thrust31.0
Issbody_acc *Body Acceleration62.5
Gatewaybody_acc *Body Acceleration62.5
Cubesatthrust *Thrust121.0
Satellite Mockupthrust *Thrust121.0
Venus Expressthrust *Thrust191.0
Starshipthrust *Thrust181.0
Super Heavythrust *Thrust591.0

Sensor Catalog

Each robot ships with configured sensors. Location is the prim-path regex relative to the robot prim where a sensor is attached. Types: Camera (RGB / depth images), Imu (linear acceleration and angular velocity), Contact Sensor (per-link contact state), and Heightmap Sensor (ray-cast elevation grid).

RobotSensor NameTypeLocation
Canadarm3contacts_robotContact Sensor.*
Canadarm3cam_baseCameracanadarm3_large_0/camera_base
Canadarm3cam_wristCameracanadarm3_large_7/camera_wrist
Frankacontacts_robotContact Sensor.*
Frankacam_baseCamerapanda_link0/camera_base
Frankacam_wristCamerapanda_link7/camera_wrist
Kinova J2N6Scontacts_robotContact Sensor.*
Kinova J2N6Scam_baseCameraj2n6s_link_base/camera_base
Kinova J2N6Scam_wristCameraj2n6s_link_6/camera_wrist
Kinova J2N7Scontacts_robotContact Sensor.*
Kinova J2N7Scam_baseCameraj2n7s_link_base/camera_base
Kinova J2N7Scam_wristCameraj2n7s_link_7/camera_wrist
Kinova Gen3N7contacts_robotContact Sensor.*
Kinova Gen3N7cam_baseCamerabase_link/camera_base
Kinova Gen3N7cam_wristCameraend_effector_link/camera_wrist
So Arm100 D5contacts_robotContact Sensor.*
So Arm100 D5cam_baseCameraBase/camera_base
So Arm100 D5cam_wristCameraFixed_Gripper/camera_wrist
So Arm100 D7contacts_robotContact Sensor.*
So Arm100 D7cam_baseCameraBase/camera_base
So Arm100 D7cam_wristCameraEnd_Servo/camera_wrist
Unitree Z1contacts_robotContact Sensor.*
Unitree Z1cam_baseCameralink00/camera_base
Unitree Z1cam_wristCameralink06/camera_wrist
Ur3contacts_robotContact Sensor.*
Ur3cam_baseCamerabase_link/camera_base
Ur3cam_wristCamerawrist_3_link/camera_wrist
Ur3Econtacts_robotContact Sensor.*
Ur3Ecam_baseCamerabase_link/camera_base
Ur3Ecam_wristCamerawrist_3_link/camera_wrist
Ur5contacts_robotContact Sensor.*
Ur5cam_baseCamerabase_link/camera_base
Ur5cam_wristCamerawrist_3_link/camera_wrist
Ur5Econtacts_robotContact Sensor.*
Ur5Ecam_baseCamerabase_link/camera_base
Ur5Ecam_wristCamerawrist_3_link/camera_wrist
Ur10contacts_robotContact Sensor.*
Ur10cam_baseCamerabase_link/camera_base
Ur10cam_wristCameraee_link/camera_wrist
Ur10Econtacts_robotContact Sensor.*
Ur10Ecam_baseCamerabase_link/camera_base
Ur10Ecam_wristCamerawrist_3_link/camera_wrist
Ur16Econtacts_robotContact Sensor.*
Ur16Ecam_baseCamerabase_link/camera_base
Ur16Ecam_wristCamerawrist_3_link/camera_wrist
Ur20contacts_robotContact Sensor.*
Ur20cam_baseCamerabase_link/camera_base
Ur20cam_wristCamerawrist_3_link/camera_wrist
Ur30contacts_robotContact Sensor.*
Ur30cam_baseCamerabase_link/camera_base
Ur30cam_wristCamerawrist_3_link/camera_wrist
Random Ur Manipulatorcontacts_robotContact Sensor.*
Random Ur Manipulatorcam_baseCamerabase_link/camera_base
Random Ur Manipulatorcam_wristCamerawrist_3_link/camera_wrist
Vispacontacts_robotContact Sensor.*
Vispacam_baseCameralink0/camera_base
Vispacam_wristCameralink6/camera_wrist
Humanoid21imu_robotImupelvis
Humanoid21contacts_feetContact Sensor(left|right)_foot
Humanoid21cam_frontCamerapelvis/camera_front
Humanoid28imu_robotImupelvis
Humanoid28contacts_feetContact Sensor(left|right)_foot
Humanoid28cam_frontCamerapelvis/camera_front
Unitree H1imu_robotImupelvis
Unitree H1contacts_feetContact Sensor(left|right)_ankle_link
Unitree H1cam_frontCamerapelvis/camera_front
Unitree G1imu_robotImupelvis
Unitree G1contacts_feetContact Sensor(left|right)_ankle_roll_link
Unitree G1cam_frontCamerapelvis/camera_front
Crazyflieimu_robotImubody
Crazyfliecam_onboardCamerabody/camera_onboard
Ingenuityimu_robotImubody
Ingenuitycam_onboardCamerabody/camera_onboard
IngenuityaltimeterHeightmap Sensorbody
Heronimu_robotImubase_link
Heroncam_onboardCamerabase_link/camera_onboard
Anymal Cimu_robotImubase
Anymal Ccontacts_feetContact Sensor.*FOOT
Anymal Ccam_frontCamerabase/camera_front
Anymal Dimu_robotImubase
Anymal Dcontacts_feetContact Sensor.*FOOT
Anymal Dcam_frontCamerabase/camera_front
Random Anymal Quadrupedimu_robotImubase
Random Anymal Quadrupedcontacts_feetContact Sensor.*FOOT
Random Anymal Quadrupedcam_frontCamerabase/camera_front
Cadreimu_robotImuchassis
Cadrecontacts_wheelsContact Sensor.*wheel.*
Cadrecam_frontCamerachassis/camera_front
Cassieimu_robotImupelvis
Cassiecontacts_feetContact Sensor(left|right)_toe
Cassiecam_frontCamerapelvis/camera_front
Huskyimu_robotImuchassis
Huskycontacts_wheelsContact Sensor.*wheel.*
Huskycam_frontCamerachassis/camera_front
Leo Roverimu_robotImuchassis
Leo Rovercontacts_wheelsContact Sensor.*wheel.*
Leo Rovercam_frontCamerachassis/camera_front
Mars Roverimu_robotImuBody
Mars Rovercontacts_wheelsContact Sensor.*[Dd]rive.*
Mars Rovercam_frontCameraBody/camera_front
Niftyimu_robotImuchassis
Niftycontacts_wheelsContact Sensor.*wheel.*
Niftycam_frontCamerachassis
Open Source Roverimu_robotImuchassis
Open Source Rovercontacts_wheelsContact Sensor.*wheel.*
Open Source Rovercam_frontCamerachassis/camera_front
Perseveranceimu_robotImubody
Perseverancecontacts_wheelsContact Sensor.*wheel.*
Perseverancecam_frontCamerabody/camera_front
Pragyanimu_robotImubody
Pragyancontacts_wheelsContact Sensor.*wheel.*
Pragyancam_frontCamerabody/camera_front
Raph Roverimu_robotImuchassis
Raph Rovercontacts_wheelsContact Sensorwheel.*
Raph Rovercam_frontCamerachassis/camera_front
Spotimu_robotImubody
Spotcontacts_feetContact Sensor.*foot
Spotcam_frontCamerabody/camera_front
Unitree A1imu_robotImutrunk
Unitree A1contacts_feetContact Sensor.*foot
Unitree A1cam_frontCameratrunk/camera_front
Unitree Go1imu_robotImutrunk
Unitree Go1contacts_feetContact Sensor.*foot
Unitree Go1cam_frontCameratrunk/camera_front
Unitree Go2imu_robotImubase
Unitree Go2contacts_feetContact Sensor.*foot
Unitree Go2cam_frontCamerabase/camera_front
Random Unitree Quadrupedimu_robotImutrunk
Random Unitree Quadrupedcontacts_feetContact Sensor.*foot
Random Unitree Quadrupedcam_frontCameratrunk/camera_front
Floating Platformimu_robotImubase_link
Floating Platformcam_onboardCamerabase_link/camera_onboard
Int Ball1imu_robotImubase_link
Int Ball1cam_onboardCamerabase_link/camera_onboard
Int Ball2imu_robotImubase_link
Int Ball2cam_onboardCamerabase_link/camera_onboard
Apollo Landerimu_robotImubase
Apollo Landercam_onboardCamerabase/camera_onboard
Peregrine Landerimu_robotImubase
Peregrine Landercam_onboardCamerabase/camera_onboard
Vikram Landerimu_robotImubase
Vikram Landercam_onboardCamerabase/camera_onboard
Resilience Landerimu_robotImubase
Resilience Landercam_onboardCamerabase/camera_onboard
Random Landerimu_robotImubase
Random Landercam_onboardCamerabase/camera_onboard
Issimu_robotImubase
Isscam_onboardCamerabase/camera_onboard
Gatewayimu_robotImugateway
Gatewaycam_onboardCameragateway/camera_onboard
Cubesatimu_robotImucubesat
Cubesatcam_onboardCameracubesat/camera_onboard
Satellite Mockupimu_robotImusatellite_mockup
Satellite Mockupcam_onboardCamerasatellite_mockup/camera_onboard
Venus Expressimu_robotImubase
Venus Expresscam_onboardCamerabase/camera_onboard
Starshipimu_robotImubase
Starshipcam_onboardCamerabase/camera_onboard
Super Heavyimu_robotImubase
Super Heavycam_onboardCamerabase/camera_onboard

Illumination Products

table synthesizes EphemerisState from imported terrain-patch rasters, without live SPICE queries or NAIF kernels. It provides environment lighting, radiometry, and surface eclipse geometry.

Schema srb_illum/2

One np.savez_compressed archive (SCHEMA_ID="srb_illum/2", product_version=2) stores meta JSON and rasters on a north-up, axis-aligned, pixel-center Real-Terrain-v2 patch grid; include at least one tier:

Tier/keyDtype and shapeMeaning
Epoch sunlitbool (T,H,W)Per-epoch line-of-sight mask.
Epoch sun_fractionfloat32 (T,H,W), NaN holesContinuous illuminated-disk fraction.
Epoch times_utc(T,) ISO-8601Epoch axis.
Epoch sun_azel(T,2) float64True-north compass azimuth and patch-center elevation, degrees.
Epoch sun_angular_diameter_deg(T,) float64Sun angular diameter.
Optional epoch earth_losbool (T,H,W)Source Earth visibility.
Optional epoch earth_azel(T,2) float64Source Earth geometry.
Static psruint8 (H,W), {0,1,255}Permanently-shadowed region; 255 nodata.
Static lit_fractionfloat32 (H,W), NaN holesTime-averaged illuminated fraction.
Static max_sun_elfloat32 (H,W), NaN holesMaximum elevation reached.

Epoch keys are required together; static keys are independently optional. At least one tier is required. srb_illum/1 is unsupported (load_product: legacy schema 'srb_illum/1' requires explicit migration); re-import its source. Float rasters: bilinear (including 1×N/N×1); bool/uint8: nearest-neighbor. Out-of-bounds psr: PSR_NODATA (255). patch_center_xy_m anchors local (x,y) (east,north; origin at center) to the pixel transform; local_xy_to_rowcol_f and rowcol_to_local_xy are inverses.

Stored sun_azel/earth_azel use query conventions: true-north compass azimuth and patch-center elevation. Importers correct source-grid azimuth/elevation once; table queries apply site.north_yaw_deg before geometry.direction_world().

Importers

Importers reproject to north-up ProductGrid; azimuth uses az_true = az_grid − γ with source-CRS convergence γ at its reference center. Elevation uses first-order curvature/parallax el_site = el + degrees(s_par/body_radius_m), where s_par is along-azimuth center offset in source-grid CRS. This matches lunarlab masks.ramp_elevation, not full spherical recomputation. zarr, rasterio, pyproj load lazily; module import remains Isaac-free.

SourceFunctionRequirements
lunarlab spice_maps epochs.zarrimport_lunarlab_zarrzarr/numcodecs.
lunarlab legacy save_masks .npzimport_lunarlab_npzNumPy only.
PGDA product-69 LPSR GeoTIFFimport_pgda_lpsrBase rasterio; Moon-only, static tier.
  1. Use --baked-dir to import into a baked patch. It reads the grid, CRS, patch center, and site latitude/longitude from baked-patch meta.json. Output defaults to <baked-dir>/illumination.npz.

    New cache generations record an illumination block in meta.json: filename, schema, SHA-256, source, epoch count/start/step, static keys, and import timestamp. Bake metadata is the georeference authority, so --baked-dir with --lat/--lon exits SystemExit(2).

  2. Without a bake, specify --crs, --center-xy, --size-m, --gsd-m, --lat, --lon, and --out.

    --size-m must be an integer multiple of --gsd-m. Otherwise, SystemExit(2) reports both values and the remainder, preventing subpixel center skew.

    Lunarlab accepts --body {moon,mars,earth}, default moon. pgda-lpsr is Moon-only and rejects --epoch-range/--epoch-stride (SystemExit(2); stride default 1) because it has no epoch axis.

For examples, see the CLI reference:

srb ephemeris import --source lunarlab-zarr \
  --input /data/lunarlab/<product>/epochs.zarr \
  --baked-dir <terrain-cache>/moon/<site>/<patch-key>

srb ephemeris import --source pgda-lpsr \
  --input /data/pgda/lpsr_shackleton.tif \
  --crs "IAU_2015:30135" --center-xy 0.0,10309.969398639505 \
  --size-m 4000 --gsd-m 5.0 --lat -89.66 --lon 0.0 \
  --out /tmp/shackleton_illumination.npz

srb[spice] and srb[all] include zarr>=2.16,<4 and numcodecs for lunarlab zarr. Docker installs the frozen all-extras export, then the editable project with --no-deps.

Without the extra, import_lunarlab_zarr raises ImportError naming it. .npz and PGDA need no extra (rasterio is a base dependency).

Decode detailBehavior
Packed maskslunarlab sunlit/earth_los: np.unpackbits(arr, axis=-1)[..., :W].
sun_fractionuint8 decodes as q / 254.0; q == 255 becomes NaN.
earth_loslunarlab’s DSN-union station-view mask, not single-site Earth-center line of sight; imported unchanged.
PGDA LPSRint16: PSR iff DN == 20000; nodata DN == -32768. Canonical uint8 {0,1,255} passes through; other dtypes raise ValueError.
PSR fractionsNeither source supplies continuous PSR fraction; psr remains hard {0,1,255}, never interpolated as probability.

Table provider

TableProvider.query() uses set_table_product(path) or SRB_EPHEMERIS_TABLE_PRODUCT. It caches at most one parsed file by identity/mtime; re-imports are visible without restart.

Epoch keys are required. Static-only files raise ValueError (“the table provider needs per-epoch sun az/el”). The provider selects the nearest epoch_index() within half an epoch step (3600 s with fewer than two epochs). Farther queries raise ValueError; no interpolation is used.

Table mode supports surface sites only. Combining table mode with env.ephemeris.orbit fails validation before Kit boot.

epoch_et uses approx_et_seconds() with fixed TT−UTC 69.184 s (32.184 s + 37 leap seconds since 2016-12-31). It is accurate to <2 ms from 2017, wrong earlier, and must change if a leap second is added. No downstream calculation uses it.

Table mode skips kernel checks and works without kernels. Provider queries validate a private product snapshot; mutable public IlluminationProduct methods validate inputs.

SPICE kernel hash reuse is keyed by process/file identity and invalidated on replacement/fork. Failed furnishing clears partial state, and the next query waits for uncertain cleanup. Offset-aware epochs normalize to UTC before SPICE parsing.

On the Moon, Earth requested only for eclipse is optional. earth_azel enables it; without it, the factor stays 1.0, with one warning per body/provider. Reset queries use this optional behavior when Earth is added only for eclipse.

Explicit earth in env.ephemeris.bodies requires Earth geometry. Missing data raises the typed availability error, including for config-time lighting.

Consumers

srb/core/mdp/illumination.py exposes static-tier MDP tools. Epoch cubes feed table queries and sunlit_epoch_windows, not per-step rewards/observations.

Term/helperInputs and behavior
reset_root_state_uniform_illumination_maskedReset event; uses pose_range, velocity_range, asset_cfg; mask="psr" (default) selects psr==1, while mask="lit_fraction" selects lit_fraction>=threshold (threshold=0.5); nodata/NaN are excluded. invert=false by default and complements only valid cells. Uniform valid-cell choice, jitter ±gsd/2; other pose/velocity sampling matches reset_root_state_uniform_poisson_disk_2d. Empty candidates raise ValueError. Optional product_path.
illumination_fraction_atTorch helper sampling lit_fraction (default) or max_sun_el at positions_w, converting world to patch-local through env.scene.env_origins; NaN→0.0. Optional product_path. These float rasters are reward-ready. psr is excluded because its out-of-bounds sentinel is 255; use IlluminationProduct.sample_static directly.

Both prefer explicit product_path, then env.unwrapped.cfg._scenery.illumination_product_path. If unresolved, ValueError names srb ephemeris import.

RealTerrain.illumination_product_path derives from primary_baked_usd_path (index-0/requested-center child), so K>1 terrain variants share that sidecar. It resolves only when the file matches the SHA-256 recorded in that block.

The product is outside terrain CacheKey; re-importing at a fixed key does not invalidate or detect stale illumination data.

sunlit_epoch_windows(product, min_lit_fraction=...) creates EpochSpec.utc_windows.

Grid mode measures valid non-NaN sunlit cells. Point mode (xy_local) uses continuous sun_fraction. Consecutive passing epochs merge into ISO (start_utc,end_utc) pairs; windows shorter than min_duration_s (default 0) are dropped.

Assign directly:

from srb.core.ephemeris import EpochSpec
from srb.core.ephemeris.products import load_product, sunlit_epoch_windows

product = load_product("illumination.npz")
windows = sunlit_epoch_windows(product, min_lit_fraction=0.6)  # grid mode
cfg.ephemeris.epoch = EpochSpec(utc=None, utc_windows=windows)

Windows exclude utc/utc_range. Each reset chooses a window proportional to max(duration_s, 1.0) and samples uniformly; zero-duration windows weigh 1.

With time_scale>0, each reset draws a new start, but progression ignores window bounds and may leave the curriculum window during a long episode.

Stats Dashboard

Count
Robots64
- Manipulator21
- Mobile Manipulator7
- Mobile Robot36
Objects54
Scenery14
Tasks43
- Digital Twin3
- Manipulation11
- Mobile22
- Mobile Manipulation7
Action Modes (total)121
Sensor Types4

IDE Configuration

VSCode Setup

Visual Studio Code (VS Code) is recommended. Other IDEs work too.

Extensions

Install these recommended extensions. SRB uses Python annotations, and SRB configures strict mypy for selected modules; CI runs pytest and pre-commit checks, not mypy:

code --reuse-window \
     --install-extension ms-python.python \
     --install-extension ms-python.vscode-pylance \
     --install-extension ms-python.mypy-type-checker \
     --install-extension charliermarsh.ruff \
     --install-extension tamasfe.even-better-toml

For Rust:

code --reuse-window \
     --install-extension rust-lang.rust-analyzer \
     --install-extension tamasfe.even-better-toml

Workspace Settings

The workspace settings configure Python paths with these assumptions:

  • Isaac Sim is installed at ../isaac-sim
  • Isaac Lab is installed at ../isaaclab
  • SimForge sources, if used, are at ../simforge and ../simforge_foundry

Using the Dev Container

For a preconfigured environment, use the Dev Container.

Dev Container

Use SRB’s Dev Container, configured in devcontainer.json.

Prerequisites

The container builds from the repository Dockerfile, mounts the checkout at /root/ws, forwards X11, and reuses host Omniverse and shader caches. It uses the Isaac Sim and Isaac Lab versions pinned in system requirements; Isaac Sim lives at /root/isaac-sim.

Host caches: ~/.cache/isaac-sim, ~/.cache/nvidia/GLCache, ~/.cache/ov, ~/.nv/ComputeCache, ~/.cache/simforge. Data: ~/.nvidia-omniverse/data/ov, ~/.nvidia-omniverse/data/isaac-sim. Logs: ~/.nvidia-omniverse/logs, ~/.nvidia-omniverse/logs/isaac-sim. Use repository ownership markers and srb clean/srb cache claim-clean-root for supported roots; SimForge cleanup uses simforge clean.

Open in VS Code

  1. Open the repository folder:

    code /path/to/space_robotics_bench
    
  2. Run Dev Containers: Reopen in Container from the Command Palette (Ctrl+Shift+P).

VS Code builds the image if needed and attaches. The first build includes the full SRB image.

Verify Container Setup

After attaching, verify the setup:

nvidia-smi
srb --help
srb cache update
echo "$DISPLAY"

Optional: Open with the Helper Script

If the VS Code CLI is installed, run:

./.devcontainer/open.bash

Other Container Access

The Dev Container requests all GPUs and /dev/dri. .docker/run.bash profiles: safe has no GPU; simulator enables GPU and GUI; trusted-simulator also grants --privileged and all of /dev; ngc runs the NGC Isaac Sim image as UID 1234. For .docker/run.bash, WITH_GPU=false disables GPU passthrough.

For terminal access to a running SRB container, use .docker/join.bash instead of opening another VS Code window.

Testing

SRB tests cover host imports and Isaac Sim CLI workflows.

Scope

The public suite includes host-runnable tests/import_test.py and Isaac Sim-backed tests/cli_ls_test.py and tests/cli_agent_test.py. .github/workflows/python.yml runs import and packaged-CLI checks for same-repository pull requests and pushes to dev or main.

Hint: The unit tier (tests/import_test.py) does not require Isaac Sim or a GPU — run it anywhere with pytest -q tests/import_test.py.

srb test — Run Tests

srb test runs Python (pytest) and/or Rust (cargo test).

srb test [options]

Python runs two pytest processes: unit (tests/import_test.py, run in CI), then workflows (tests/cli_*_test.py, Isaac Sim). A failing tier does not stop the next (an interrupt or incomplete process cleanup does), each run tier gets a report line, and any failure sets a nonzero exit. long_training (end-to-end training matrices) is deselected by default.

Options

ArgumentDescriptionDefault
-l/--language/--langLanguage suites to test[python]
-t/--tierPython tiers to run (all = every tier)[all]

Arguments after -- are forwarded to every pytest tier and to cargo test.

Examples

Forward -vx to pytest:

srb test -- -vx

Run the host unit or Isaac Sim workflow tier:

srb test --tier unit
srb test --tier workflows -- -x

Run the opt-in training matrix (minutes per environment):

srb test --tier workflows -- -m long_training

Run tests for both Python and Rust:

srb test --lang python rust

Documentation

Build SRB’s Markdown documentation with mdBook.

srb doc (alias srb docs) — Local Preview

srb doc (alias srb docs) starts the live-reload preview by default and opens it in a browser.

Sub-subcommandDescription
srb doc serve (default)Run an mdBook live-reload server and open it in a browser
srb doc buildBuild the static site for local preview
srb doc docgenRegenerate auto-introspected asset, task, and catalog pages; launches Isaac Sim headless
srb doc thumbnailRender asset or task thumbnails into docs/src/_graphics/assets/ or docs/src/_graphics/tasks/
srb doc docgen --static-only
srb doc thumbnail --asset-type robot
srb doc thumbnail --task excavation_demo
srb doc thumbnail --task ALL

docgen uses headless Isaac Sim to regenerate asset, task, compatibility, action-space, sensor, stats, and attribution pages. --assets-only and --tasks-only limit writes. --static-only checks schema versions and known sidecar field types in docs/data/assets.toml and docs/data/tasks.toml (unknown keys ignored), plus task GUI themes and ranks. It reports errors or asset/task counts without launching Isaac Sim or writing pages, but cannot verify sidecars name registered assets or tasks.

Preserve hand-written sections with <!-- PRESERVE:<key> --> … <!-- /PRESERVE:<key> -->.

thumbnail accepts --width, --height, --output-dir, --asset, --asset-type, --task, --force (re-render existing images), and --allow-failures (exit successfully when some tasks in a batch fail; failures are still reported). Output defaults to docs/src/_graphics/assets/ or docs/src/_graphics/tasks/. After rendering task thumbnails, it republishes the offline cache with a rebuilt GUI catalog; refresh exceptions are warnings.

Hint: srb doc serve and srb doc build forward tokens after -- directly to mdbook.

Automated Deployment

The docs workflow runs on dev or main pushes that change .github/workflows/docs.yml, docs/**, or a root *.md file; same-repository pull requests; published releases (prereleases skip the build); and manual dispatch. Runs in AndrejOrsula/space_robotics_bench deploy to GitHub Pages on main pushes, published non-prereleases, or manual dispatch; pull requests and dev pushes do not deploy.

Contributing

Report errors or suggest improvements through an issue or pull request.

Development Utilities

Use these utilities to update assets or clean the cache.

Reward-function reference plots

Generate PDF references for implemented reward terms with CPU Torch:

  1. From a source checkout, install the plots extra (Matplotlib, NumPy, Torch, Seaborn).

  2. Run this command to write the PDFs to outputs/reward_terms/:

    MPLBACKEND=Agg uv run --extra plots python - <<'PY'
    from pathlib import Path
    
    import matplotlib.pyplot as plt
    
    from srb.core.reward.scripts.plot_reward_terms import plot_library_final_order
    
    output = Path("outputs/reward_terms")
    output.mkdir(parents=True, exist_ok=True)
    plot_library_final_order(weight=1.0, limit=4.0, output_path=output / "reward_terms.pdf")
    plot_library_final_order(weight=-2.0, limit=64.0, output_path=output / "penalty_terms.pdf")
    plt.close("all")
    PY
    

Agg needs no display. PDFs show reward functions, not task dynamics or learned behavior. Running srb/core/reward/scripts/plot_reward_terms.py directly writes PDFs beside the script; the function above writes to outputs/.

For the manual TF trajectory visualizer, see the ROS integration guide.

Update Assets

Use ./assets/scripts/update.bash to update static content. The script manages two git-backed repositories:

  • assets/srb_assets for asset payloads.
  • docs/src/_graphics for docs/task thumbnails and visuals.

Update assets/srb_assets by default:

./assets/scripts/update.bash

Bootstrap from Hugging Face

If submodules are unavailable, initialize a repository from a Hugging Face mirror. For a private mirror, set HF_TOKEN or run hf auth login.

./assets/scripts/update.bash --source hf --repo-id OWNER/REPO

Set the repository type, revision, and destination with these options. The destination must be inside the repository:

./assets/scripts/update.bash --source hf --repo-id OWNER/REPO --repo-type dataset --revision main --path assets/srb_assets

To initialize the graphics repository instead, set --path to docs/src/_graphics:

./assets/scripts/update.bash --source hf --repo-id OWNER/REPO --repo-type dataset --revision main --path docs/src/_graphics

--repo-type defaults to dataset. Supported values: model, dataset, and space.

For a private mirror, set these environment variables, then run the script:

export SRB_ASSETS_SOURCE=hf
export SRB_ASSETS_HF_REPO_ID=OWNER/PRIVATE_ASSETS_REPO
export SRB_ASSETS_HF_REPO_TYPE=dataset   # or model / space
export SRB_ASSETS_HF_REPO_REVISION=main         # optional

./assets/scripts/update.bash

./.docker/build.bash bootstraps a target directory when it is missing or contains only .git. Set the matching variables:

  • SRB_ASSETS_... for assets/srb_assets
  • SRB_GRAPHICS_... for docs/src/_graphics

Development Utilities — Clean Cache

Use srb clean after framework upgrades or asset changes to remove SRB, Isaac Sim, and SimForge caches. SRB caches are namespaced by Isaac Sim/Lab versions, provider, architecture, and source/asset digests. Isaac Sim vendor caches are shared across versions, so clean them after changing the Isaac Sim pin.

Procedure

  1. Claim the fixed SRB and Isaac cache roots before cleaning. Their versioned ownership markers bind to canonical path, device, and inode. Existing content is adopted only at known roots.

    srb cache claim-clean-root --target srb
    srb cache claim-clean-root --target isaacsim
    
  2. To include the NGC cleanup root, set an absolute SRB_NGC_CACHE_DIR; a relative value selects none.

  3. Run srb clean:

    srb clean
    

    SRB prompts before removing marker-owned directories unless -y/--yes is set. SimForge handles its own confirmation.

Adoption supports the fixed repository .cache, five Isaac vendor roots, and selected NGC profile root. NGC adoption allows only Docker profile mount entries (cache, compute, kit, logs, config, data, pkg, hub); entries need not all exist. After the NGC profile chowns the root to UID 1234, claim it as a user with write access. Populated custom SRB_CACHE_ROOT roots are never adopted; create and claim a new, empty root before writing cache data.

Targets and Options

srb clean [TARGET ...] [-y/--yes]
ArgumentDescriptionDefault
TARGET ...One or more of all, srb, isaacsim, simforge (multiple allowed)[all]
-y/--yesSkip the interactive confirmation promptFalse

all (default) selects srb, isaacsim, and simforge. simforge rejects tokens after -- with exit 2. A missing simforge CLI, SimForge clean failure, timeout, or unexpected state makes srb clean exit 1.

--yes skips the prompt and passes -y to SimForge. Ownership, root-depth, repository/home, mount, symlink, device, and entry-identity checks still apply. Removal uses anchored directory descriptors and preserves the cache root and marker.

What Gets Removed

TargetAffected paths
srbThe selected SRB cache root (registry caches, completion caches, …); by default this is <repository root>/.cache in a source checkout and $XDG_CACHE_HOME/srb (when absolute) or ~/.cache/srb when installed. SRB_CACHE_ROOT overrides it.
isaacsimMarker-owned roots ~/.cache/isaac-sim, ~/.cache/ov, ~/.cache/nvidia/GLCache, ~/.nv/ComputeCache, ~/.cache/packman, and ${SRB_NGC_CACHE_DIR:-~/.cache/space_robotics_bench/ngc/isaac-sim-6.1/<arch>} (where <arch> is amd64 or arm64, as selected by .docker/run.bash)
simforgeDelegated to simforge clean (procedurally generated SimForge assets)

SimForge cleanup follows its own ownership policy; SRB does not recursively remove that directory.

The .docker/run.bash profile writes to these vendor roots, except ~/.cache/packman. srb clean isaacsim warns about present, unclaimed roots; claim them first. The marker remains. ~/.cache/nvidia/GLCache and ~/.nv/ComputeCache are shared with CUDA/OpenGL applications; ~/.cache/ov is shared with Omniverse applications. Marker-owned cleanup is safe, but those applications rebuild their caches on next use, which can take time.

Examples

Remove only SRB caches without prompting:

srb clean srb -y

Remove only the Isaac Sim Omniverse caches:

srb clean isaacsim -y

Clean only SimForge’s generated assets:

srb clean simforge -y

Reference: SimForge CLI — simforge clean

Real Terrain Assets

  1. Add a baked NASA/USGS/ESA digital elevation model (DEM) to a scene. Choose body="moon", "mars", or "earth", then select a manifest site, shortcut, or coordinate region and assign asset_cfg:

    from srb.assets.scenery import RealTerrain
    from srb.assets.scenery.real_terrain_sites import (
        LunarSiteApollo17,
        MartianSiteJezero,
        MartianSiteJezeroV2,
    )
    
    terrain = RealTerrain(body="moon", site="apollo17")
    terrain = LunarSiteApollo17()
    terrain = MartianSiteJezero()
    terrain = MartianSiteJezeroV2()  # Declared HiRISE DTM/ortho
    terrain = RealTerrain(body="moon", lat_deg=-89.66, lon_deg=0.0, size_m=2000.0)
    env_cfg.scene.terrain = terrain.asset_cfg
    

    RealTerrain(body=..., site=...) resolves manifest entries; shortcut classes select specific sites; coordinate regions need no manifest. For curation and offline baking, see Adding Terrain Sites.

  2. Configure companions or per-environment variation (optional):

    terrain = LunarSiteApollo17()
    terrain.attach_companions(env_cfg)  # Manifest defaults; shipped site has none
    terrain = LunarSiteApollo17(lighting="apollo17_noon", rocks=None)
    terrain = RealTerrain(body="moon", site="apollo17", augment="simforge")
    

    By default, BaseEnvCfg._add_scenery attaches companions when attach_companions_enabled=True; set it to False to opt out. Ephemeris and skydome drives arbitrate lighting. Fallback-eligible companion attachment failures skip all companion products and emit one warning; integrity, safety, invalid-input, and unknown failures are re-raised and may abort setup. augment="simforge" adds per-environment variation, such as differently seeded rocks, over the static baked terrain. The default augment preset depends on body (lunar_default for Moon). If simforge_foundry cannot be imported, SimforgeMissingError is raised.

  3. To bake a local DEM, provide the required license attribution:

    terrain = RealTerrain(
        body="moon", dem_path="/data/my_lunar_dem.tif", site_name="my_polar_crater",
        attribution="Acme Surveying, 2026", patch_size_m=300, use_ortho=False,
    )
    

    For a local DEM, clear a shortcut’s site with site=None, or construct RealTerrain(body=..., dem_path=...).

  4. Inspect, download, bake, or manage assets with the CLI:

    srb asset list terrain
    srb asset list terrain --body moon
    srb asset list rocks
    srb asset list hdri
    srb asset list lights
    srb asset info terrain apollo17
    srb asset download terrain apollo17
    srb asset download terrain --all --body moon
    srb asset download terrain --lat -89.66 --lon 0.0 --size-m 2000 --body moon --deshade
    srb asset bake terrain --dem /data/my.tif --body moon --site-name my_local --attribution "Me, 2026"
    srb asset cache-stats
    srb asset clean terrain apollo17 --baked
    srb asset clean terrain --all
    srb asset validate-manifest
    srb asset prefetch-fixtures
    

    Coordinate downloads target arbitrary v2 regions without a manifest. They require all three coordinate flags and reject site targets, --all, and site-specific flags.

OptionDefault or constraint
SelectionExactly one (mixing is rejected): manifest site, local dem_path, or complete lat_deg/lon_deg/size_m region.
lodmedium; valid tiers low, medium, high.
use_orthoTrue; disable with False for a local DEM without ortho.
augment"none" by default; "simforge" requires simforge_foundry.
Auto-fetchOn by default; set SRB_TERRAIN_AUTO_FETCH=0 to require pre-baking.

Ephemeris-driven lighting

Sites with lighting: ephemeris, coords, and curated epoch bake Sun and lunar Earthshine via real SPICE (srb/terrain/lights/ephemeris_bridge.py). A query() uses persisted georef.north_convergence_deg: az_grid = az_true + γ; listed azimuth is raw true-north.

CachePath and invalidation
Ephemeris.../srb_assets/lights/ephemeris/<body>_<site>_<epoch>_<identity>/generations/<generation id>/lights.usd; <identity> is the request SHA-256 prefix (16 hex). Epoch, grid correction, base-preset edits, or lights-writer changes make a new file.
Static preset.../srb_assets/lights/<preset>/<content hash>/generations/<generation id>/lights.usd; keyed by lights-writer version and full catalog content (same 16-character prefix); edits need no cache deletion.

Missing pinned NAIF kernels warn once and use body-default static lighting only when the lighting bridge’s on_missing policy is fallback; on_missing: error fails instead. This fallback does not cover augment="database": a missing or empty augmentation database raises an error. augment="simforge" uses SimForge directly. srb ephemeris download enables SPICE. See Ephemeris → Terrain lighting for manifest fields, fallback, and srb asset list provenance.

Real-terrain v2: source catalog and stack resolution

Preview region coverage offline; an uncovered request returns an empty plan. Text mode prints no v2 source coverage for <body> at (<lat>, <lon>) — falling back to the v1 single-source path; JSON mode returns the empty plan without that message.

srb asset stack --body moon --lat -89.46 --lon 137.3 --size-m 2000
srb asset stack --body moon --lat -89.46 --lon 137.3 --size-m 2000 --json

Manifest dem_stack (optional color_stack) and arbitrary regions use RealTerrain, download, and bake fusion APIs; regions resolve by footprint. Terrain Stacks covers schema, coverage, normalization, fallback, CRS, deshade, cache, companions, and consent; Catalog status per body lists layers/access. Adding Terrain Sites explains layer curation and declared stacks.

Real-terrain v2: the fusion engine

A dem_stack has one gap-free full-patch role: base plus optional finer partial role: inset layers; color_stack follows suit. Fusion produces one DEM and colour raster:

  1. Warp layers to the patch grid with fusion.grid.warp_to_grid.
  2. Co-register DEM insets using catalog shifts or estimates; warn and drop insets with excessive QC residuals.
  3. Feather-blend by priority: finest/highest-priority inset wins within its data boundary, blending to the next layer within blend_len_m of the true boundary. Clamp blend_len_m to 50–200 m; declared footprint without data does not count. No global weighted average.
  4. Composite colour first-finite-wins in sorted-stack order, then normalize radiometry against the anchor layer.

Fused bakes add these beside v1 terrain.usd and textures:

OutputContents
provenance.tifSame-size uint8 GeoTIFF: 0 means no contributor; 1..N is winning layer index matching meta["fusion"] index.
meta.json["fusion"]V2 only: fusion_version; grid (crs, center_xy_m, size_m, gsd_m, pixels); dem_layers/color_layers (layer_id, role, kind, index, area_fraction, native_gsd_m, upsampled, radiometry, alignment, license, attribution); loaded-mask contributors affect colour but own no raster index; provenance_tif/uncertainty_tif filename or null; warnings. V1 has no fusion; meta["georef"] is unchanged.
meta.json["bake_identity"]Versioned fused-cache identity: cache key, canonical DEM and colour/auxiliary stack hashes, fusion version, target GSD, effective deshade. Required for a ready fused generation.
ATTRIBUTION.txtOne layer_id/license/attribution block per contributing base, surviving inset, and loaded mask, in blend order. V1’s single attribution + "\n" applies only to v1 single-source bakes.

Budgets (v2 only). V1 uses stride-based LOD meshes and uncapped textures. V2 quadric-decimates to face budgets and caps texture/AO resolution. Skirts and solid-shell collision geometry remain undecimated, adding a small perimeter-scaled face count; shipped meshes may slightly exceed budget without decimation failure.

LODMax grid facesMax texture side (px)
high4,000,0008192
medium1,000,0004096
low250,0002048

AO is computed at ≤2048 px then upsampled at every LOD. See srb/terrain/fusion/budgets.py.

Caching and reproducibility

Bake identity includes (body, site, patch, lod, seed, materials_version, dem_sha256, ...); matching inputs reuse assets/srb_assets/scenery/terrain/<body>/<site>/<patch_key>/. Set SRB_TERRAIN_CACHE_ROOT=/custom/path to override the root.

Terrain stack augmentation

Augmentation database (srb_augdb/1)

Bake can generate deterministic synthetic crater/rock placements from fused terrain via srb.terrain.augmentation.database.generate_augmentation_db; compressed sidecar augmentation.npz (save_augmentation_db). Schema srb_augdb/1, AUGMENT_DB_VERSION=4, stores float32 arrays:

ArrayShapeColumns
craters(Nc, 4)x_m, y_m, radius_m, depth_m
rocks(Nr, 6)x_m, y_m, z_m, scale, yaw_rad, asset_idx

XY are patch-local mesh-frame metres (grid east/north, patch-center origin; mesh_frame {"center_xy": true}). Rock Z is a bilinear DEM sample or 0.0 without DEM, in mesh Z datum after center-pixel origin subtraction (heightmap_to_mesh(..., z_origin="center"), mesh_frame {"z_origin": "center"}), so rocks lie on the mesh. load_augmentation_db_file upgrades v1 in memory (inserting zero z_m at column 2; meta["upgraded_from"]=1); older versions raise ValueError and require rebaking. Zero-density kinds are empty (0,4)/(0,6), never None. Metadata includes schema/version, seed, slug, body, preset, requested/kept counts, synthetic provenance, and generated_from (patch_size_m, gsd_m, max_slope_deg, dem_stats; the last is None without DEM).

bake_or_load supplies fused dem.heights, dem.gsd_m. Placements are uniform over patch; reject when local np.gradient slope proxy exceeds max_slope_deg (default 25°). Presets define rock_density_per_m2, rock_size_range_m, crater_density_per_m2, crater_radius_range_m; body defaults have zero crater density. RNG is np.random.default_rng([761, AUGMENT_DB_VERSION, seed, *sha256(slug)-ints]), independent of Python hash(), dict order, global np.random; same seed/version/slug/preset/DEM yields byte-identical arrays across machines/processes. Salt, RNG, placement-rule, or schema changes require version bump; version is part of seed. Draw _OVERSAMPLE=4 candidates and keep first N passing in order to fix RNG use; no retries, so steep terrain may yield fewer. meta["counts"] records requested/kept.

Both v1/v2 bakes write sidecar only if effective preset has nonzero rock or crater density. Moon/Mars defaults have rocks; all-zero Earth EARTH_DEFAULT has no sidecar/metadata. _bake writes to temp before atomic promotion publishing provenance.tif; meta.json records augmentation_db: {"file":"augmentation.npz","schema":"srb_augdb/1","db_version":4,"counts":{...}}. Cache hits do not regenerate. With nonzero density, generation/write or stamping failure aborts publication. Explicit preset overrides and stamping params/version enter cache identity. load_augmentation_db(baked_dir) returns AugmentationDb | None; missing metadata/file returns None, invalid present file raises IntegrityFailureError. RealTerrain.augmentation_db_path, like illumination path, is beside primary USD and exposes index 0 for multi-location terrain.

To stamp craters, set TerrainSpec.augment_stamp=True or RealTerrain.augment_stamp. _bake cuts generated craters into DEM after nodata repair and before heightmap_to_mesh: a parabolic bowl to rim R plus a raised-cosine collar returning to grade at 1.4 R, with height 0.06 * depth. Stamping changes the mesh, materials, and collision; rock Z resamples the stamped surface. Stamping is off by default and requires a nonzero crater-density preset. Shipped defaults use zero; lunar_cratered/mars_cratered copy body defaults with density 0.002 and radius (1.0, 8.0), or use a custom preset. Select with RealTerrain.augment_preset, passed as TerrainSpec.augment_preset. _bake uses spec.augment_preset or default_augment_preset_for_body(spec.body) for generation/stamping. An unknown preset raises KeyError; a body mismatch raises ValueError. CacheKey.from_spec resolves via companion_scene.resolve_effective_augment_preset, shared with bake and the companions() SimForge/database layer; errors name the value and choices. hash12() adds augment_stamp={db_version}:{density:g}:{radius_min:g}:{radius_max:g} when stamping or explicitly overriding the preset; the default key is unchanged. Craters deform the DEM, not separate prims; spawn rocks with augment="database".

Explicit rock scatter — augment="database"

RealTerrain.augment: "none" (default), "simforge", "database". SimForge gets count/seed through SimforgeAssetCfg/spawn_simforge_assets and hides transforms. Database reads (Nr,6) sidecar rows [x_m,y_m,z_m,scale,yaw_rad,asset_idx], deterministically spawning one static prim per row.

  • database_scatter generates eight (_ROCK_ASSET_SLOTS=8) variant USDs once via SimForge asset.generator_type(...).generate_subprocess(...), without scattering; subprocess cache stores them. Row variant is asset_idx % len(variants).
  • rock_pose(row) returns (pos, quat_xyzw): position (x_m,y_m,z_m) and yaw-only xyzw quaternion (0,0,sin(yaw/2),cos(yaw/2)) (w-last), matching Isaac Lab AssetBaseCfg.InitialStateCfg.rot; identity (0,0,0,1).
  • RealTerrain.augment_max_rocks: int = 256; select_rows takes first N in draw order, never random sample.
  • With augment="database", missing sidecar/metadata or zero rocks raises an error; terrain companion setup does not silently continue without the requested database scatter.
  • simforge_ext._build_rock_generator raises ValueError outside Moon/Mars. Earth zero-density shortcut in build_real_terrain_augment_cfg and database empty-rock degrade avoid the guard.

Disabling auto-fetch

For pre-baked or air-gapped CI:

export SRB_TERRAIN_AUTO_FETCH=0

Then RealTerrain(...) raises TerrainNotBakedError with the exact srb asset download command.

Troubleshooting

ErrorCauseRemedy
ManifestSiteUnknownErrorBad sitesrb asset list terrain
LicenseMissingErrorMissing attributionPass attribution="..."
ChecksumMismatchErrorUpstream DEM changedsrb asset validate-manifest --check-shas
SimforgeMissingErrorPackage absentpip install simforge_foundry
TerrainNotBakedErrorAuto-fetch off; cache missRun the shown srb asset download command

Units & Conventions

Unit System

Use Isaac Sim/Isaac Lab SI units. sunlight_rpy and domain solar angular diameters may use degrees.

QuantitySI unit
Lengthm
Masskg
Times
Anglerad
ForceN
TorqueN·m
Gravitym/s²

Coordinate Frame

Use right-handed, Z-up coordinates: X forward, Y left, Z up; gravity is negative Z.

Quaternion Format

SRB and Isaac Lab use (x, y, z, w); USD/OpenUSD Gf.Quatf and some external libraries use (w, x, y, z), converted by SRB.

  • srb.core.static_asset_view.XformPrimView.get_world_poses returns and set_world_poses accepts (x, y, z, w); the setter converts to USD.
  • Sensor mount OffsetCfg.rot and event-camera rot_xyzw use it unchanged.

Frame Suffix Convention

Use these frame suffixes:

Use _w for absolute world frames (root_pos_w, body_quat_w) and _b for relative body/base frames (ee_vel_b).

Domain-Specific Gravity

DomainGravity (m/s²)
Earth9.80665
Mars3.72076
Moon1.62496
Asteroid0.14219
Orbit0.0

Spec Authoring (@spec decorator)

Apply @spec from srb.core.spec to concrete ActionGroup, SRB-native SensorBase, and observation-manager classes. Import registers ComponentDescriptor; the environment aggregates them into queryable env.srb_spec (EnvSpec), separate from Gymnasium env.spec.

Two authoring styles

Use fields= for up to five fields and spec_field otherwise. Never combine.

Explicit fields:

from srb.core.spec import spec, TermSpec

@spec(kind="action", fields=[
    TermSpec(name="lin", shape=(1,), dtype="float32",
             units="m/s", min=-2.0, max=2.0),
    TermSpec(name="ang", shape=(1,), dtype="float32",
             units="rad/s", min=-1.0, max=1.0),
])
class WheeledDriveActionGroup(ActionGroup):
    ...

spec_field attributes (long schemas):

from srb.core.spec import spec, spec_field

@spec(kind="action")
class SmoothOSCActionGroup(ActionGroup):
    ee_pos = spec_field("ee_pos", dtype="float32", shape=(3,), units="m")
    ee_rot = spec_field("ee_rot", dtype="float32", shape=(4,), units="quat")
    stiffness = spec_field("stiffness", dtype="float32", shape=(6,),
                           units="N/m, Nm/rad")

What kind= to choose

  • "action" for ActionGroup; "sensor" for SensorBase.
  • "observation" for managers; set extra group="policy" to scope.

Privileged terms

Mark deployed-policy exclusions privileged=True, such as ground-truth particle positions:

TermSpec(name="particles_xyz", shape=(N, 3), dtype="float32",
         privileged=True,
         semantic_label="excavation.particle_positions")

projections.onnx_export_mask(spec.observation) returns privileged or fallback-provenance term names; ONNX export ignores the mask.

Registration requirement

Register concrete subclasses with @spec(...).

Versioned action metadata

Action descriptors are serialized contracts. Increment the schema version if term names, axes, normalization, scaling, frame, or units change.

DescriptorContract
Multicopter cmd_vel (v2)Axes linear_x, linear_y, linear_z, angular_z are normalized and clamped to [-1, 1] before scaling by MulticopterBodyAccelerationActionCfg.scale. The three linear channels use m/s; angular z uses rad/s. Body x/y rotate by yaw only (ignore roll/pitch); z stays world vertical, and angular z is yaw rate.
Orbital body body_acc mode (ISS, Gateway)Descriptor body_vel (v2).
Inverse-kinematics and operational-space groupsOne delta_twist; width is 3 position, 3 axis-angle rotation, plus control-mode impedance channels.

For descriptor versions, runtime widths, and rejected signatures, see the Action Space Catalog.

Contributing — New Assets

Contribute SRB static assets through srb_assets. Isaac Lab also supplies assets.

Choose an asset type

SRB assets fall into three types:

Asset TypeDescription
SceneryTerrain and structures
ObjectsInteractive objects, tools, and payloads
RobotsControllable systems

Add a static asset

  1. Identify its family and interface:

    • Robots: joints and sensors.
    • Terrain: source metadata.
    • Objects: spawn configuration.
  2. Record the source, author, and license in the applicable metadata catalog. For assets in SRB’s catalog, edit docs/data/assets.toml.

  3. Follow the family format and validation rules. The rock pipeline checksum-verifies, decodes, bounds, and cleans terrain rocks. Robot and scenery checks differ.

  4. Check dependencies, payload paths, and references against family conventions.

  5. Add the asset to your srb_assets fork.

  6. Submit a pull request.

Create procedural assets with SimForge

Reference: SimForge

SimForge supplies procedural environments and assets, including robot structures such as the Cubesat. Examples:

See the SimForge documentation, especially:

Next: Contribute a new task

Contributing — New Tasks

Copy a task template, adapt its environment, and test it.

1. Duplicate a Template

Copy a package under srb/tasks. Update its registration and config, give it a unique package name, and keep it under srb.tasks: recursive imports register tasks, and family placement sets their documentation category. Choose a template:

TemplateDescription
_manipulationFixed-base manipulation with robotic arms
_groundGround traversal on planetary surfaces
_aerialAerial navigation above planetary surfaces
_orbitalSpaceflight maneuvers
_ground_manipulationMobile manipulation with ground-based robots
_aerial_manipulationMobile manipulation with flying robots
_orbital_manipulationMobile manipulation with spacecraft

2. Modify the Environment

Adapt the scene and assets, choose a robot category, then implement observations, rewards, and termination conditions. Ask the community for task-specific guidance if needed.

3. Debug the Task

Test the task with teleop, zero, or rand, as its action space permits. Enable debug visualization and check parallel instances. First, update docs/data/tasks.toml. Then regenerate the offline task cache (srb cache update) and task docs (srb doc docgen) to sync the generated catalog and task pages. Run a compatible command:

srb agent teleop -e <your_task_name> env.debug_vis=true env.num_envs=4
srb agent zero -e <your_task_name> env.debug_vis=true env.num_envs=4
srb agent rand -e <your_task_name> env.debug_vis=true env.num_envs=4

4. Use the Task in a Workflow

Reference: Workflows

Use workflows compatible with the task’s config, action space, and runtime interfaces. Check compatibility before training, deployment, or validation.

Share your task with the community.

Next: Adding Terrain Sites

Adding Terrain Sites + Catalog Entries

Adding a new terrain site

  1. Choose a public-domain or compatibly licensed DEM. Record its URL, expected SHA-256, CRS (such as IAU_Moon_2015), and ground sampling distance in meters.

  2. Add an entry to srb/terrain/manifest.yaml:

    sites:
      my_site:
        body: moon  # moon, mars, or earth
        name: "My Site (display name)"
        coords: { lat: 20.5, lon: 30.7 }
        sources:
          dem:
            provider: usgs_astro  # or lroc_pds, pds_geosciences, openplanetary, local
            url: "https://planetarymaps.usgs.gov/mosaic/<product>.tif"  # host must be on the provider's allowlist
            sha256: "<64-char hex>"
            crs: "IAU_Moon_2015"
            gsd_m: 2.0
            license: "Public Domain (NASA/USGS)"
            attribution: "USGS Astrogeology / LROC NAC"
        patches:
          default: { center_xy_m: [256, 256], size_m: 200, lod: medium }
        sky: null  # sky dome name, or null
        lighting: lunar_default  # null disables lighting
        rocks: null  # rock set name, or null
        augment_preset: lunar_default
    
  3. Validate and bake:

    srb asset validate-manifest
    srb asset download terrain my_site
    
  4. In the SRB/Isaac Sim Python environment, verify the import-time shortcut. real_terrain_sites.py imports Isaac Lab and generates LunarSiteMySite, MartianSiteMySite, or EarthSiteMySite:

    from srb.assets.scenery.real_terrain_sites import LunarSiteMySite
    t = LunarSiteMySite()
    assert t.asset_cfg.spawn.usd_path
    

Adding a v2 source layer

Add a reviewed, pinned layer to srb/terrain/catalog/<body>.yaml (for example, moon.yaml), not the v1 manifest. Download the product, calculate its SHA-256, and review its footprint. Shipped layers are listed in Terrain Stacks → Catalog status per body.

For detached PDS3 .LBL/.IMG products such as imbrium_ldam_50s_1000m, set access: download. List every extra file’s URL, exact filename, SHA-256, and size in SourceLayer.sidecars; set primary_size_bytes. Acquisition publishes atomically, and GDAL follows ^IMAGE from the label. See Terrain Stacks for resolver, cache, and acquisition contracts.

Authoring Mars/Earth entries

Mars and Earth use Moon’s SourceLayer schema. Follow Terrain Stacks footprint rules. Region requests need no manifest entry: use RealTerrain(body="<requested body>", lat_deg=..., lon_deg=..., size_m=...) or srb asset download terrain --body mars --lat 18.4 --lon 77.5 --size-m 2000 (add --deshade to deshade). See Terrain Stacks for region identity, normalization, and fallback.

Schema

srb.terrain.catalog_schema.SourceLayer validates srb/terrain/catalog/<body>.yaml:

body: moon
layers:
  - layer_id: ldem_87s # unique within catalog
    body: moon
    kind: dem # dem | color | mask | quality
    product_family: "LOLA/Kaguya merged polar DEM"
    provider: pgda # ProviderName
    urls: ["https://pgda.gsfc.nasa.gov/data/LOLA_GDR/CYLINDRICAL/IMG/ldem_87s_10m.tif"]
    sha256: { "ldem_87s_10m.tif": "<64-char hex>" }
    native_gsd_m: 10.0
    footprint: "cap:83S"
    alignment: { source: assumed_zero }
    license: "Public Domain (NASA/GSFC)"
    attribution: "NASA GSFC PGDA"
    size_bytes: 1_400_000_000
    access: cog_remote # cog_remote | download | zip_member
    priority_class: 1 # lower wins; default 100
    allow_large_download: false

Catalog providers use exact-host allowlists:

ProviderAllowed hostsTypical body
pgdapgda.gsfc.nasa.govmoon
zenodozenodo.org, www.zenodo.organy; zip-member archives
uahirisehirise.lpl.arizona.edu, www.uahirise.org, uahirise.orgmars
copernicus_s3copernicus-dem-30m.s3.amazonaws.com, copernicus-dem-90m.s3.amazonaws.comearth
usgs_3depprd-tnm.s3.amazonaws.comearth
imbriumimbrium.mit.edu (HTTPS only)moon; PDS3 label/image products

V1 providers: usgs_astro, lroc_pds, pds_geosciences, openplanetary, local. Allowlists are closed; add hosts in srb/terrain/sources/*.py. uahirise, copernicus_s3, and usgs_3dep accept unauthenticated public HTTPS GET only; authenticated products need another provider. usgs_astro covers Mars CTX and HRSC-MOLA.

priority_class — lower wins

Set curated priorities (default 100): DEM 1..5, sunlit color 1..4, PSR color 1..4. Resolver sorts (is_synthetic, priority_class, native_gsd_m, layer_id); GSD alone cannot break ties. Lowest fully covering entry is role="base". See synthetic-layer admission and sorting.

radiometry: synthetic — the super-resolution slot

Use only for model-generated DEM/color. Footprint resolution excludes synthetic candidates unless RegionRequest.allow_synthetic=True or TerrainSpec.allow_synthetic=True; admitted candidates sort after real ones. Explicit declared-site dem_stack/color_stack layer IDs bypass synthetic and coverage filtering; body, frame, and max_gsd_m filters still apply. Opt-in adds synthetic=1 to CacheKey.hash12(); default False leaves it unchanged. No shipped layer is synthetic; SRB has no model. See the resolver contract.

access — how a layer’s bytes are fetched

Use cog_remote to fetch/hash the full source before local windowing, download for one whole file, or zip_member for pinned members of a whole Zenodo archive. See Current limits.

sha256 keys — the basename convention (read this exactly)

sha256 keys use urls[0] basename, urllib.parse.urlsplit(url).path.rsplit("/", 1)[-1] (no query/fragment). SourceLayer._validate_sha_map_matches_access requires:

AccessRequired keys
cog_remote or downloadExactly one key equal to basename(urls[0]); missing, extra, or mismatched keys fail catalog loading.
zip_memberArchive key basename(urls[0]) and at least one extracted-member key using its in-zip path.
access: zip_member
urls: ["https://zenodo.org/records/<id>/files/<archive>.zip"]
sha256:
  "<archive>.zip": "<64 hex>"
  "dtm/<region>_dem.tif": "<64 hex>"

Fetch reads CatalogLayerPlan.archive_sha256 via sha256[basename(urls[0])]; malformed keys raise KeyError. srb asset stack rejects invalid catalogs before planning. Placeholder "f" * 64 is refused before archive/member transfer, as in v1 (PLACEHOLDER_SHA256, srb/terrain/sources/acquisition.py). See SHA-256 backfill workflow.

allow_large_download + SRB_TERRAIN_LARGE_OK

Set allow_large_download: true only after reviewing size. A download above 1 GiB also requires SRB_TERRAIN_LARGE_OK=1 at fetch time. See Terrain Stacks → Consent.

mask_encoding — required in practice for every kind: mask layer

Mask values are product-specific DNs. Without mask_encoding, the default None passes raw values to fusion; srb.terrain.fusion.color.psr_mask treats finite nonzero values as masked. A nonzero unmasked DN can cover a region; this once marked the entire lunar south pole permanently shadowed.

The pgda_lpsr_85s_60m example in srb/terrain/catalog/moon.yaml has raw int16 values 20000 (permanently shadowed), -32768 (nodata), and typically -20000 (not shadowed):

  kind: mask
  mask_encoding:
    masked_values: [20000]     # -> 1.0 (inside mask)
    nodata_values: [-32768]    # -> NaN (no observation)
                               # everything else -> 0.0 (outside mask)

Encoding maps -20000 to 0.0; without it, finite nonzero -20000 makes 99.99998% of the raster appear masked. srb.terrain.ingest.mask.decode_mask_dn decodes before arrays reach fusion/.

  • Values use exact equality against pixels read as floats: list actual DNs, not ranges or thresholds. Non-finite and duplicate values fail at load.
  • SourceLayer uses extra="forbid"; a typo such as mask_encodding: fails validation instead of silently restoring the bug.
  • Check URL bytes and histogram. PGDA documents {0, 1, 255} uint8, but the pinned .TIF serves raw int16. Keep values synchronized with srb/core/ephemeris/importers.py::_read_pgda_lpsr, which decodes the product independently.

footprint — three forms, and the CRS requirement

Use cap:<lat><N|S> for spherical caps, WKT POLYGON(...)/MULTIPOLYGON(...) in projected meters for polar layers, or geographic-degree bbox:<lonmin>,<latmin>,<lonmax>,<latmax> for non-polar layers. cap:/WKT and test regions must share a projected CRS; bbox: stays in degrees. Requests at |lat| >= 60 use canonical polar CRSs (moon_south/moon_north, IAU_2015:30135/:30130, plus Mars/Earth equivalents); others use local stereographic. No covering footprint yields an empty plan with a warning; baking that empty DEM plan raises RegionUnresolvedError. See footprint and antimeridian rules and canonical CRSs.

Validate

Preview both plan formats:

srb asset stack --body moon --lat -89.46 --lon 137.3 --size-m 2000
srb asset stack --body moon --lat -89.46 --lon 137.3 --size-m 2000 --json

Malformed SHA-256 shape, footprint, duplicate layer_id, or provider raises pydantic.ValidationError at load, before planning.

Adding a v2 site with a declared stack

  1. Confirm each referenced layer exists in srb/terrain/catalog/<body>.yaml; local testing may use a hand-built catalog. Catalog layers pin data; manifest sites name layers to fuse, like v1 dem/ortho.

  2. Set manifest version: 2 before declaring stacks. Existing v1 sites remain valid: Sources requires exactly one of dem or dem_stack per site regardless of manifest version.

    version: 2
    sites:
      apollo17: { ... }  # existing v1 site, unchanged
    
  3. Declare one role: base and zero or more role: inset entries in dem_stack; optional color_stack uses the same shape. Use these instead of v1 sources.dem/sources.ortho:

    sites:
      connecting_ridge:
        body: moon
        name: "Connecting Ridge (v2 fused)"
        coords: { lat: -89.46, lon: 137.3 }
        sources:
          dem_stack:
            - { layer_id: ldem_87s, role: base }
            - { layer_id: nac_dtm_esall_cr1, role: inset }
          color_stack:
            - { layer_id: cm_avg_87s, role: base }
            - { layer_id: shadowcam_cmosaic_cr1, role: inset }
        patches:
          default: { center_xy_m: [0, 10309.97], size_m: 2000, lod: medium }
          # Or: { center_latlon: [-89.66, 0.0], size_m: 2000, lod: medium }
        sky: null  # sky dome name, or null
        lighting: lunar_default
        rocks: null
        deshade: true # optional; default illumination-corrected color
    

    deshade: true divides sunlit color by fused-DEM hillshade using catalog sun_azimuth_deg/sun_elevation_deg; PSR layers are never deshaded, and missing angles warn and skip. RealTerrain(..., deshade=True) enables undeclared deshading but cannot disable manifest deshade: true; the effective value enters the cache key. See Deshade.

    Each layer_id must exist in its body’s catalog; unknown ids fail at resolve and name the missing layer. role selects the base regardless of list order. StackRef.max_gsd_m excludes coarse candidates with a warning.

  4. Validate and bake as for Adding a new terrain site. The generated shortcut is LunarSiteConnectingRidge; CLI and RealTerrain constructor are unchanged. bake_or_load detects declared stacks (sources.dem is None) and routes to fusion.

  5. Inspect outputs: meta.json contains a fusion block, provenance.tif sits beside terrain.usd, and ATTRIBUTION.txt has one block per contributing layer. Real Terrain Assets → the fusion engine documents contents, mesh/texture budget tiers, and QC/degradation: demoted or unreachable insets warn, drop, and bake succeeds; an unreachable base raises because v1 has no fallback.

The connecting_ridge IDs (ldem_87s, nac_dtm_esall_cr1, cm_avg_87s, shadowcam_cmosaic_cr1) are illustrative, not shipped. See jezero_v2 in srb/terrain/manifest.yaml and Terrain Stacks → Named site: Jezero v2.

Other curated catalogs

Adding a new HDRI skydome

Add an entry to srb/terrain/hdri/catalog.yaml:

skydomes:
  my_dome:
    body: moon
    url: "https://example.org/dome.hdr"
    sha256: "<64-char hex>"
    format: hdr        # or png, exr
    intensity: 1.0
    resize_to: 2048
    license: "Public Domain"
    attribution: "Source name"

EXR requires optional imageio[freeimage] (pip install srb[terrain-extras]); PNG and HDR need no extra.

Adding a new rock set

Add an entry to srb/terrain/rocks/catalog.yaml:

sets:
  my_set:
    body: moon
    rocks:
      rock_a:
        url: "https://example.org/rock_a.glb"
        sha256: "<64-char hex>"
        format: glb       # or obj, ply, stl
        target_face_count: 5000
        license: "Public Domain"
        attribution: "Source"

Pipeline decimates each rock to target_face_count (default 5000), welds vertices, recenters at the centroid, and scales AABB diagonal to 1.0. Caller scales at scatter time.

Adding a new lighting preset

Add a preset to srb/terrain/lights/catalog.yaml (pure config; no fetch):

presets:
  my_preset:
    body: moon
    sun_elevation_deg: 30
    sun_azimuth_deg: 90
    sun_intensity_lux: 130000
    sun_color_temperature_k: 5800
    sun_angular_diameter_deg: 0.53
    earthshine_intensity_lux: 200      # optional
    earthshine_color_temperature_k: 7500
    license: "Public Domain"
    attribution: "Synthesized from ephemeris X"

Derive sun pose from the mission timestamp and site coordinates using an ephemeris, or synthesize an artistic look.

Shared workflows

sha256 backfill workflow

  1. Replace placeholder "f" * 64 with the downloaded file’s real hash:

    curl -L "<url>" | sha256sum
    
  2. Update the manifest, rerun srb asset validate-manifest, and confirm srb asset download terrain <site> succeeds.

Common mistakes

  • Symptom: ingest raises MissingCRSError or DemLoadError. Cause: the CRS string is misspelled. Fix: use IAU_Moon_2015 or IAU_Mars_2015.
  • Symptom: ingest raises EmptyHeightmapError. Cause: the patch lies wholly outside the DEM extent. Samples beyond the DEM edge are clamped. Fix: choose a smaller patch_size_m or another center_xy_m.
  • Symptom: baking is refused for license compliance. Cause: user-supplied DEM has no attribution. Fix: add its attribution.
  • Symptom: a companion catalog reference is stale. Cause: sky:, lighting:, or rocks: names no catalog entry. Fix: use a valid catalog name or null to disable it.

Next: Testing

Modelling Envelope

1. Dynamics

Orbital tasks are microgravity, not orbital mechanics

ORBIT sets gravity magnitude and variation to 0.0. It supports zero-gravity contact, manipulation, and free-flyer tasks.

It omits Clohessy-Wiltshire/Hill relative motion and orbital rate. It cannot support formation flight, rendezvous geometry, or station-keeping fuel budgets.

Manipulator arms do not feel domain gravity

Twenty robot/object files contain 24 disable_gravity=True declarations across manipulators, grippers, tools, floating, and aerial robots.

PhysX gravity is correct to five decimals in all five domains, but affects only free bodies and mobile bases. MOON, MARS, and EARTH change lighting and unattached objects, not arm loads. The excavation shovel is weightless.

Raph’s hardware shovel has one lift joint and no curl joint; it only raises or lowers the blade. These assumptions suit orbital arms, not surface arms. Do not claim cross-domain gravity transfer.

Aerial tasks are kinematic, not aerodynamic

Aerial tasks support navigation and guidance above flight control.

The multicopter term writes root velocity and matching attitude. Nominal-RPM rotors are visual and produce no thrust. There is no aerodynamics, rotor inflow, blade-element model, or airframe gravity. It follows body-frame velocity commands with bounded tilt.

Do not claim flight dynamics, control authority, disturbance or wind response, power, or endurance.

Large spacecraft inertia comes from a uniform bulk density

Large spacecraft without authored mass use uniform 1500 kg/m³ density, several times higher than mostly hollow spacecraft. Scaling corrects mass, not inertia: uniform solids differ from wall-loaded structures, and inertia ratios govern attitude dynamics.

Landers have explicit mass, enabled gravity, and per-thruster body forces via ThrustAction. Do not use large uniform-density spacecraft for attitude-control results.

LanderMass
Starship100,000 kg
SuperHeavy200,000 kg
ApolloLander4,280 kg dry
PeregrineLander825 kg
VikramLander626 kg
ResilienceLander340 kg

mobile/landing supports powered descent.

2. Terrain and contact

There is no terramechanics, and friction is profile-specific

Use wheel-ground contact for navigation, path following, and obstacle negotiation. Do not use it for slip-ratio/sinkage predictions, traction budgets, or regolith trafficability.

BaseEnvCfg defaults to 0.50/0.50 Coulomb friction (static/dynamic), 0.0 restitution, and average combine mode. Wheels use actuator-driven velocity/position targets on rigid surfaces. There are no sinkage, pressure-sinkage, slip-sinkage coupling, bulldozing resistance, drawbar pull, or Bekker/Wong models.

The baked terrain path can apply these unvalidated engineering estimates. The registry has no asteroid entry.

BodyStatic/dynamic frictionRestitution
Moon0.85/0.700.0
Mars0.75/0.600.0
Earth0.80/0.600.1

Without baked material, the global default is a parameter, not calibration. Pre-materials-v3 bakes lack bindings.

To restore bindings:

  • Re-bake with srb asset download terrain <site>.
  • For a region, add --body, --lat, --lon, and --size-m to that command.
  • Alternatively, enable auto-fetch.

With SRB_TERRAIN_AUTO_FETCH=0, direct terrain construction raises TerrainNotBakedError for unbaked terrain; there is no old-bake fallback. Runtime surface selection instead warns and falls back to procedural terrain. Isaac Sim contact effects are unvalidated; asset materials contribute through average combine.

Self-collision is disabled on most articulations

Self-collision is off on roughly 70% of articulations, so robots may pass through themselves in hardware-unreachable configurations. Require an independent collision check before claiming whole-body transfer.

Actuators are implicit PD

Many actuators use implicit PD; some configurations include joint friction. Most omit backlash, gear compliance, current, and thermal limits. Do not claim torque-tracking fidelity or results dependent on actuator dynamics rather than kinematics and contact.

3. Granular material

Cohesion and adhesion settings are ineffective for the current non-fluid particle setup

Excavation particles set cohesion and adhesion to 0.0. Landscaping sets cohesion to 0.0 and inherits adhesion 0.05; other scenes inherit base values 0.01/0.05.

PhysX applies cohesion and adhesion only to fluids, so they do not affect non-fluid PBD particles; friction does. The angle of repose is uncalibrated against lunar regolith and simulants. Without cohesion, particles cannot form bootprints or trench walls or hold scoop loads; another representation is required.

Do not claim excavation forces, scoop fill, trench-wall stability, bootprints/tracks, or simulant comparisons.

Particles are two to three orders of magnitude too large

Excavation particles are about 0.7 cm; landscaping particles are 5 cm. Lunar regolith’s median grain size is about 70 µm (Carrier et al., Lunar Sourcebook, 1991), requiring about 10¹² particles per cubic metre.

Coarsening is unavoidable. The model lacks grain interlocking, fines-scale cohesion, and sub-particle features. Do not claim results below particle diameter, including tool-edge detail or fine texture.

4. Real terrain

Measured terrain resolves at source-specific native GSD; finer detail is synthetic

Use measured terrain for site-specific slope, illumination, and route-scale shape at source GSD. Do not use it for wheel-scale traversability. The real-data path is not fully validated.

Its pipeline records curated, SHA-256-pinned LROC NAC DTMs, IAU_Moon_2015 CRS, per-site GSD, licence, attribution, and SPICE sun-position epochs. Native GSD varies by source:

SourceGSD
Mars HiRISE1.016553302... m
Earth 3DEP1.0 m
Earth Copernicus30.0 m
Moon1.0–1000.0 m

Resampling and fusion add no detail below source GSD. Procedural rocks, craters, and noise supply synthetic rover-scale roughness, even at real sites. See Terrain Stacks for site and multi-source stacks.

5. Sensing

Noise and delay lack target-hardware calibration

Default task configs leave Isaac Lab’s observation_noise_model and action_noise_model unset. Waypoint navigation retains relative observation perturbations. Opt-in waypoint_navigation_synthetic_v1 adds Gaussian action noise and (1, 2)-step action/observation delays.

See randomization profiles for parameters and reset behavior. Noise lacks hardware calibration and realistic IMU/image models. Do not claim target-device robustness without measurements.

Depth noise is modelled on consumer hardware

Heightmap and depth models include quadratic stereo and time-of-flight noise, quantisation, incidence-angle and random dropout. Parameters come from consumer Intel RealSense devices; space-qualified sensors may differ.

Calibrate and re-parameterise for the target device before claiming sensor-specific transfer.

6. Illumination and appearance

Light intensity is documented in W/m² but consumed as a renderer scale

Use configured sun elevation, azimuth, and shadow direction; SPICE supplies these when env.ephemeris is enabled. Uncalibrated rendered radiance gives no absolute photometry or radiometry.

Domain.light_intensity is documented in W/m², but USD DistantLightCfg consumes renderer scale, not irradiance. Nominal intensities are 1361 W/m² for Moon/orbit and 775 W/m² for Earth; Earth’s range reaches 1000 W/m² (ASTM G173 AM1.5 clear-sky surface value). Mars’s 590 W/m² is top-of-atmosphere, despite the docstring; SRB omits typical surface irradiance (~60–70%, dust-dependent).

Ambient sky fill is one undifferentiated constant

All domains, including airless ones, apply DomeLight at 25% of direct intensity, without a derivation for 0.25. It barely affects Moon shadows because stars.exr is near-black. Changing the constant or texture could sharply alter lighting.

Mars sunlight is not reddened

Iron-oxide dust reddens Martian sunlight, producing a butterscotch appearance. SRB uses the Sun’s 5778 K colour temperature and has no calibrated reddening value. Do not claim colour-accurate Mars imagery.

The default lunar surface material is the wrong colour

Upstream simforge_foundry owns the installed MoonSurface material. It renders red-brown to magenta under solar illumination, unlike lunar regolith’s grey with a slight brown cast. Geometry, illumination direction, and shadows are unaffected. Do not use default-path datasets for colour-dependent perception on procedural lunar terrain.

The Earth domain renders a starfield sky

Domain.EARTH uses stars.exr as its skydome, giving daytime scenes a night sky; daylight textures exist in the asset pack. Do not transfer Earth-domain background vision models to real laboratories.

7. Time discretisation

Aerial tasks run at most two physics steps per control step

Do not draw aerial-dynamics conclusions near control-rate frequencies.

Task configPhysics intervalControl intervalDecimation
Aerial family default, including aerial_navigation1/25 s1/25 s1 (40 ms)
flight1/50 s1/25 s2 (two 20 ms physics steps per 40 ms control update)

GPU contact-buffer sizing is on Isaac Lab’s defaults

SRB applies no per-num_envs GPU buffer sizing; PhysX buffers keep Isaac Lab’s defaults. CPU defaults are unaffected; check PhysX overflow warnings on CUDA runs with large num_envs.

8. Domain constants

Asteroid gravity randomisation reaches zero

ASTEROID gravity variation is twice its magnitude, giving a sampled lower bound of 0.0 m/s². Some episodes run in free fall.

No task defaults to the Asteroid domain

srb/core/domain.py declares five domains. Task configs explicitly default to MOON (6), MARS (4), and ORBIT (2), with none for ASTEROID; others inherit their family default. modular_assembly keeps the default domain but sets gravity to EARTH (srb/tasks/manipulation/modular_assembly/task.py:170). Do not treat an ASTEROID switch as validated.

9. Training configuration

Two of the 42 tasks have tuned hyperparameters

hyperparams/ has 28 reinforcement-learning and 11 imitation-learning configs; hyperparams/task/ overrides two of 42 tasks. The other 40 use defaults, not best-achievable settings. Untuned scores are unfair across algorithms; published scores are not tuned or configuration-matched.

Known limitations

AreaLimitation
PDS3 conversionsrb.terrain.sources.pds_img.img_to_geotiff writes raw samples, ignoring SCALING_FACTOR/OFFSET; optional pdr fallback omits CRS, identity transform, and nodata.
Ortho fusionortho_path resizes images to DEM grid by array shape; images must be pixel-aligned. Fused colour is aligned.
ResolutionReads finer than native resolution may not average; elevation can alias.
SpaceMouseUse an independent deadman with a real robot: reads may succeed while reports are lost, keeping the last motion.
DreamerReal-transfer checkpoints save periodically, not on normal stop.
InstallersIsaac Lab, Dreamer, RSL-RL, and Robomimic installers in .docker/install/ retain checkouts and leave pip packages in the Isaac Sim interpreter after failure; recreate that environment to remove them.

Attributions

AssetSourceLicenseAuthor
canadarm3SRB–SRB Contributors
frankaSRB–SRB Contributors
kinova_gen3n7Isaac LabNVIDIANVIDIA
so_arm100_d5SRB–SRB Contributors
so_arm100_d7SRB–SRB Contributors
unitree_z1Isaac LabNVIDIANVIDIA
ur10Isaac LabNVIDIANVIDIA
ur3Isaac SimNVIDIANVIDIA
ur5Isaac SimNVIDIANVIDIA
vispaSRB–SRB Contributors

Fonts

The GUI (crates/srb_gui) bundles the following fonts. Their licence texts are next to the font files in crates/srb_gui/assets/fonts/.

FontSourceLicenseAuthor
Interrsms/interOFL-1.1The Inter Project Authors
Monaspace Neongithubnext/monaspaceOFL-1.1GitHub
Material Icons Roundgoogle/material-design-iconsApache-2.0Google

Contributors

Citation

Cite this publication when using SRB in research:

@article{orsula2025space,
  title   = {{Space Robotics Bench: Robot Learning Beyond Earth}},
  author  = {Orsula, Andrej and Geist, Matthieu and Olivares-Mendez, Miguel and Martinez, Carol},
  year    = {2025},
  journal = {arXiv:2509.23328},
  doi     = {10.48550/arXiv.2509.23328},
}

Community Discord

Join Discord to discuss SRB, share projects, ask questions, and collaborate.

Guidelines

  • Be respectful and considerate to all members
  • Keep your discussions relevant

Troubleshooting

Runtime Errors

Driver or CUDA Compiler Messages

Symptom: Either error appears during startup or compilation:

[Error] [carb.graphics-vulkan.plugin] VkResult: ERROR_INCOMPATIBLE_DRIVER
XlaRuntimeError: UNIMPLEMENTED: /usr/local/lib/python3.12/site-packages/jax_plugins/xla_cuda12/../../nvidia/cuda_nvcc/bin/ptxas ptxas too old. Falling back to the driver to compile.

Cause: ERROR_INCOMPATIBLE_DRIVER indicates Vulkan driver incompatibility. ptxas too old means XLA’s CUDA assembler is old and compilation falls back to the driver; that warning alone does not indicate driver incompatibility.

Fix: Check the Isaac Sim driver requirements and framework requirements. If compilation still fails, check CUDA/ptxas, then driver and framework compatibility.

GLXBadFBConfig Error

Symptom: An srb agent workflow crashes with this message:

X Error of failed request:  GLXBadFBConfig
  Major opcode of failed request:  150 (GLX)
  Minor opcode of failed request:  0 ()
  Serial number of failed request:  133
  Current serial number in output stream:  133
There was an error running python

Cause: The reported OpenGL version may be incompatible.

Fix: On Mesa, MESA_GL_VERSION_OVERRIDE changes the OpenGL version reported to applications. It may help if an application rejects that version, but it does not change the driver or guarantee a fix:

MESA_GL_VERSION_OVERRIDE=4.6 srb agent teleop -e _ground

For simulated workflows in the provided Docker setup, select the simulator profile and pass the variable into the container:

SRB_DOCKER_PROFILE=simulator ./.docker/run.bash -e MESA_GL_VERSION_OVERRIDE=4.6

Slow Startup

Symptom: Isaac Sim’s first launch may take several minutes, or later launches remain slow.

Cause: The first launch compiles shaders and caches assets; later launches are faster.

Fix: Let the first launch finish. For persistent slow startup, try a workaround from this issue.

Slow Startup with Real Terrain

Symptom: Startup is slow with real terrain selected and a cold cache.

Cause: SRB may fetch and bake terrain before launch.

Fix: Disable auto-fetch for interactive runs. SRB warns once and falls back to the procedural surface without contacting remote providers:

SRB_TERRAIN_AUTO_FETCH=0 srb agent teleop -e _ground env.domain=mars env.scenery=mars_surface env.scenery.source=real

With the provided Docker development wrapper and a virtual display:

DISPLAY=:99 DOCKER_TTY=false .docker/dev.bash -e SRB_TERRAIN_AUTO_FETCH=0 srb agent teleop -e _ground env.domain=mars env.scenery=mars_surface env.scenery.source=real

The Docker development wrapper defaults to LOG_LEVEL=info, keeping expected Isaac and SimForge debug logs from hiding actionable warnings. For one verbose run, prefix the command with LOG_LEVEL=debug.

Hidden Isaac Startup Logs

Symptom: Known Isaac Sim and PhysX startup logs are missing during an srb agent workflow.

Cause: SRB filters known noisy startup logs.

Fix: Disable the filters to see raw vendor logs when diagnosing an upstream Isaac or Kit startup issue:

SRB_DISABLE_ISAAC_LOG_FILTERS=1 srb agent teleop -e _ground

With the provided Docker development wrapper and a virtual display, pass the same variable into the command environment:

DISPLAY=:99 DOCKER_TTY=false .docker/dev.bash -e SRB_DISABLE_ISAAC_LOG_FILTERS=1 srb agent teleop -e _ground

Unexpected Behavior

Teleoperation Stuck

Symptom: During keyboard teleoperation, the robot keeps moving in one direction after you change window focus.

Cause: Omniverse may miss a button release when window focus changes.

Fix: Press L to reset the environment.


Need more help? Ask in the Discord community or search GitHub Issues.

Discord GitHub Issues