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
| Component | Requirement |
|---|---|
| CPU | x86_64 Linux |
| GPU | NVIDIA GPU with RT Cores for Isaac Sim workflows |
| RAM | 16 GB (32 GB for simulator; estimates) |
| VRAM | About 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 Space | 50 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:
| Component | NVIDIA tested baseline |
|---|---|
| OS | Ubuntu 22.04/24.04 |
| CPU | 4 cores (Intel Core i7 7th generation or AMD Ryzen 5 minimum) |
| RAM | 32 GB |
| GPU | GeForce RTX 4080 minimum |
| VRAM | 16 GB |
| Storage | 50 GB SSD |
| Linux driver | 595.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.
| Component | Requirement |
|---|---|
| OS (Native Installation) | Ubuntu 22.04/24.04, x86_64 |
| OS (Docker Installation) | Linux (X11 required only for GUI workflows) |
| NVIDIA Driver | Appropriate for the GPU; see NVIDIA’s tested Isaac Sim 6.1 baseline above |
| Python | 3.12.* |
| Isaac Sim | Source VERSION 6.1.0-rc.26, built from commit 7c206f75bdadd9e05fc457f19863ca4c3f0cb693 |
| Isaac Lab | 3.0.0 (release/3.0.0) at fdc650c88dfd86aa158b9a1760b6537fef360555 |
| ROS 2 | Jazzy, 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
| Method | Use when | Limits |
|---|---|---|
| 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). |
| Native | Full system integration (documented path) and a smooth development experience. | Complex setup; potential dependency conflicts; untested. |
| Apptainer/Singularity | HPC 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
| Shell | Configuration file | PATH command | Other exports |
|---|---|---|---|
bash | ~/.bashrc | export 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 | ~/.zshrc | export PATH="$HOME/.local/bin:$PATH" | Same export lines as bash |
fish | universal variables | fish_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 location | Use |
|---|---|
/usr/share/vulkan/icd.d/nvidia_icd.json | Common with Ubuntu driver packages |
/etc/vulkan/icd.d/nvidia_icd.json | Created 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.
| Framework | Command | Behavior / 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.
| Component | Check |
|---|---|
| Isaac Sim | "$ISAACSIM_PYTHON" -c "from isaacsim import SimulationAppsim = SimulationApp({'headless': True})print('Isaac Sim OK — is_running:', sim.is_running())sim.close()" |
| Isaac Lab | "$ISAACSIM_PYTHON" -m pip show isaaclab |
| Blender | blender --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
| Installer | Default / limits |
|---|---|
| Host | Ubuntu 22.04/24.04; amd64/arm64. Verifies Docker (and, when installing the toolkit, NVIDIA) repository key fingerprints; refuses unavailable versions. |
| Docker | Engine/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 Toolkit | 1.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 group | Non-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
| Setting | Behavior |
|---|---|
| Mount / caches | Source 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_GPU | Defaults true (--nv); false omits passthrough but keeps Isaac Sim in the image. |
| Command | Arguments follow run.bash; bash opens an interactive shell. |
For NGC images:
| Setting | Behavior |
|---|---|
IMAGE_PATH | Required for NGC; set it when .sif is outside .docker/hpc/images/. |
| Provenance | Checks the recorded SIF checksum on each run; large files may take longer. |
SRB_NGC_CACHE_OWNERSHIP | user (default) or skip; the invoking user runs Singularity and owns caches. |
| Paths, digest, and RTX | Sets 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.
| Control | Keys |
|---|---|
| Reset | L |
| Gain | O decrease; P increase |
| Event | R / K |
| Translate | W / S: +X / −X; A / D: −Y / +Y; Q / E: +Z / −Z |
| Rotate | Z / 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_uihides 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_trackingshares terrain by default (other tasks may differ). Setenv.stack=falsefor unique terrain geometry and materials per robot. SetSF_BAKER=0to 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+, ormanipulator+) 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]'
| Override | Default | Limit 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.0 | For cameras without an authored period, negative selects the agent rate. |
env.camera_clipping_range | None | Near/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
- ROS 2 - Connect robotics tools and libraries.
- Reinforcement Learning - Train and evaluate policies.
- Hyperparameter Tuning - Tune hyperparameters:
srb agent tune. - Imitation Learning - Collect demonstrations; train offline.
- Sim-to-Real Transfer - Prepare simulation-trained policies for hardware; operation is unvalidated.
- Terrain Landscaping Training - Train three landscaping tasks; review limitations.
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.
| Topic | Message Type | Description |
|---|---|---|
/clock | rosgraph_msgs/Clock | Simulation time |
/tf, /tf_static | tf2_msgs/TFMessage | Scene transforms |
| Control | ||
**/{robot_name}/{action_name} | Robot-specific | Robot control; normalized policy actions (message fields are containers, not SI units) |
**/action/raw | std_msgs/Float64MultiArray | Flat action vector in action-space order |
**/action/cmd_vel | geometry_msgs/Twist | Available when the task action config supports direct commands |
**/action/event | std_msgs/Bool | Available when the task action config supports direct commands |
| Perception | ||
**/[{sensor_name}]/{data} | Sensor-specific | Scene sensors |
**/{robot_name}/joint_states | sensor_msgs/JointState | Articulation joints |
| MDP | ||
**/reward | std_msgs/Float32 | Total reward |
**/reward/{term_name} | std_msgs/Float32 | Reward terms |
**/terminated | std_msgs/Bool | Termination flag |
**/truncated | std_msgs/Bool | Truncation 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
.zipcheckpoints live inckpt/.
3. Try a Different Algorithm
| Type | Framework algorithms |
|---|---|
| Model-based | DreamerV3: dreamer; TD-MPC2: tdmpc2 |
| On-policy | Stable-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-policy | SB3: 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 |
| Evolutionary | SB3: sb3_ars |
skrl: Hyperparameter profiles are untuned starting points.
srb agent train --headless --algo <ALGO> --env landing env.num_envs=1024
Hint:
--headlessand 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
-
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> -
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,1Portfolio: 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:
| Slot | Scope | State | Visual |
|---|---|---|---|
| L0 / L0v | Global | <framework>/<algo>.yaml | <framework>/<algo>_visual.yaml |
| L1 / L1v | Task-specific | task/<task>/<framework>/<algo>.yaml | task/<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
- The Isaac-free driver samples with
study.ask()and launchestrainchildren in process groups: one per seed for single-task trials, and one per task segment per seed for portfolio trials. Each child boots Isaac. - It writes full
agent:config andenv:seed andnum_envstotrial_cfg.yaml. Children report episode statistics as JSONL; the driver counts total environment steps. - 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.
MedianPrunerstops weak trials withkillpg; 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
- Set
--n-workers Nslots per driver;--gpus 0,1round-robins GPUs. Starts stagger to avoid Isaac shader-cache races until metrics arrive. - Share
logs/tune/<study>/journal.logacross nodes; each SLURM array element is one worker, and Optuna assigns trials without scheduler integration. - Rerun to resume; terminal and
RUNNINGtrials count toward--n-trials. Changes to search space, budget, objective, obs mode, or task set need a new--version. - Abrupt driver termination may leave trials
RUNNING; handled cancellation marks active trialsFAIL; repair withsrb agent tune repair --study S --stale-hours H. - Pruned child logdirs are deleted, including checkpoints and TensorBoard events.
--keep-artifactsretains them;trial_cfg.yamlandmetrics.jsonlremain.
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 == 1if configured otherwise. - Evaluation rejects
num_envs != 1withintegration.robomimic.vector_env.unsupported. - Offline
learncreates 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:
- Train RL from scratch on the same task while IL collects demos.
- Resume interrupted RL with
srb agent train --continue_trainingor a same-framework--model. - Prefill
skrl_sac,skrl_ddpg, orskrl_td3replay from canonical export with--demo-dataset,--demo-max-transitions(metadata, limits, resume). - Prefill Dreamer sequence replay from the canonical format. See continuous-action requirements, persistence, capacity, and source-bound resume.
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:
RealEnvchecks 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
RealEnvlatches 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
| Interface | Role and limitation |
|---|---|
ros_depth_heightmap | Projects RealSense depth into a local heightmap grid. |
ros_tf | Supplies TF frame-pair observations; OptiTrack base pose additionally needs omitted ros_optitrack. |
ros_imu | Supplies IMU angular velocity and linear acceleration. |
ros_kortex_cartesian | Cartesian-admittance Kinova arm control, FK, and contact-force readings. |
ros_scoop_target | Supplies policy-required scoop-target command observations. |
ros_mw | Middleware pause/resume services. |
ros_kortex_joint_vel | Sends 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 ID | Target manifest | Generated module |
|---|---|---|
terrain_landscaping_crater | Fixed crater; hash pinned in module | srb/interfaces/sim_to_real/env/terrain_landscaping_crater.py |
terrain_landscaping | Per-episode mission; module sets REQUIRES_RUNTIME_TARGET_MANIFEST = True | srb/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.
| Field | Type | Required | Default / limit |
|---|---|---|---|
spec_id | string or null | no | null |
task | string | yes | required |
algo | string | yes | required |
checkpoint | string | yes | required |
hardware | list[string] | yes | required |
metrics_to_track | list[string] | yes | required |
n_episodes | integer | no | 10 |
max_episode_seconds | float seconds | no | 120.0 |
thresholds | object | no | see below |
rerun | object | no | see below |
sim_baseline | object | no | see below |
drift_window | integer sessions | no | 5 |
storage_root | path | no | logs/real_validation |
notes | string | no | "" |
checkpoint accepts a raw checkpoint or SRB model artifact path; notes is copied to the spec snapshot.
| Threshold option | Type | Default / limit |
|---|---|---|
thresholds.success_rate_min | float | 0.5; minimum real success rate |
thresholds.sim_real_ratio_min | float | 0.7; floor for higher-is-better real/sim ratios |
thresholds.lower_is_better_metrics | list[string] | []; names lower-is-better metrics; error/loss names auto-detected |
thresholds.action_smoothness_max_ratio | float | 1.5; max smoothness ratio |
thresholds.crash_rate_max | float | 0.0; max crash/safety-event rate |
thresholds.drift_z_max | float | 3.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 option | Type | Default |
|---|---|---|
rerun.app_id | string | srb-validation |
rerun.web_port | integer | 9090 |
rerun.grpc_port | integer | 9876 |
rerun.bind_address | string or null | 0.0.0.0 |
rerun.keep_historical_data | bool | true |
rerun.keep_scalar_history | bool | true |
rerun.record_to_rrd | bool | true; saves rollout.rrd |
| Simulation baseline option | Type | Default |
|---|---|---|
sim_baseline.wandb_run_id | string or null | null; W&B run with sim summary scalars |
sim_baseline.local_rrd | path or null | null; not parsed for metrics; as the only source it yields a degraded baseline |
sim_baseline.metrics_json | path or null | null; 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:
- 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. - Crash: no
policy_nan,hardware_event,disk_full, or safety abort (sensor_stale,sensor_incomplete,calibration_mismatch,manifest_mismatch). - Drift: tracked-metric z-scores are at most
thresholds.drift_z_maxover 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 case | Result |
|---|---|
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 comparison | Direction-aware around ` |
| Drift history | Requires 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 baseline | Degraded baseline; (a) fails, exit 1, hardware_evidence: false. success_rate is real-only. |
Exit codes:
| Code | Name / criterion | Meaning |
|---|---|---|
0 | pass / all | Threshold, crash, and drift pass. |
1 | threshold_fail / criterion_a | Threshold metrics fail, e.g. success rate or sim/real ratio. |
2 | crash_fail / criterion_b | Crash or safety-relevant termination. |
3 | drift_fail / criterion_c | Tracked metrics exceed z-score limit. |
4 | preflight_fail / preflight | Rollout 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.yaml | yes | Exit 4 preflight: generated environment cannot construct; see excavation. |
formation_following.yaml | yes | Runs. |
terrain_landscaping_crater.yaml | yes | Exit 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
| Artifact | Scope; writer | Produced when | Purpose |
|---|---|---|---|
spec.yaml | Session; write_spec_snapshot | Preflight | Rebuild-summary input. |
episodes.jsonl | Session; Telemetry | Rollout | Append-only step, event, and episode-end metrics. |
rollout.rrd | Session; Telemetry | rerun.record_to_rrd=true and Rerun starts | Inspection and twin replay. |
tensorboard/ | Session; Telemetry | Enabled and available | Optional scalar logs. |
summary.json, report.md, badge.json | Session; write_session_report | Finalization or rebuild-summary | Machine result, report, Shields.io payload. |
_index.jsonl | Storage root; DriftStore | Finalization | Append-only drift history/dashboard rows. |
index.html | Storage root; write_validation_index | Finalization | Cross-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.
| Task | Episode | Reward |
|---|---|---|
| Crater | 300 steps (30 s) | grading MAE |
| Mound | 300 steps (30 s) | excess volume above target |
| General | 600 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 equalsteps × 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
| Operation | Restores | Does not restore |
|---|---|---|
--continue (same log directory) | step, agent parameters, optimizer, replay | simulator state, partial episodes, recurrent carries, RNG |
| Agent import into new run | agent state; starts at step 0 | everything else |
| Evaluation or policy load | agent state for inference | everything 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:
- Manipulation - Stationary manipulation skills and sequences in various contexts
- Mobile Robotics - Extraterrestrial traversal and navigation
- Mobile Manipulation - Combined mobility and manipulation
- Digital Twins - Facility-inspired simulations; not validated against physical facilities
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>.

| Episode Length | 10.0s (500 steps) |
| Reward Terms | 4 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – |
Debris Capture (debris_capture)
Capture and securement of floating debris in microgravity with a fixed-base manipulator
| Episode Length | 10.0s (500 steps) |
| Reward Terms | 11 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_distance_ee_to_obj | Gaussian | 16 | 0.08 | |
| reward_grasp | SoftThreshold | 16 | – | |
| penalty_debris_velocity_lin | Linear | -3 | – | |
| penalty_debris_velocity_ang | Linear | -1 | – | |
| reward_approach_velocity_alignment | Hyperbolic | 4 | 0.1 | |
| penalty_approach_speed | Linear | -2 | – | |
| penalty_debris_too_far | Linear | -8 | – |
distance_debris_too_farappliespenalty_debris_too_faronly; episodes end by horizon (truncated).- Episode info omits
success; bounded evaluation reports return only.
Excavation (excavation)
Extraction of granular material (regolith)
| Episode Length | 8.0s (400 steps) |
| Reward Terms | 13 |
| Default Robot | Kinova Gen3N7 |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.05 | – | |
| penalty_joint_torque | Linear | -0.00001 | – | |
| penalty_joint_acceleration | Linear | 0 | – | |
| penalty_undesired_robot_contacts | Linear | 0 | – | |
| reward_approach_pile | Gaussian | 1.5 | 0.15 | |
| reward_scoop_depth | Tukey | 2 | – | |
| reward_scoop_orientation | GaussianTracking | 1 | 0.26 | |
| reward_lift | Hyperbolic | 2 | 0.2 | |
| penalty_jerk | Linear | -0.02 | – | |
| penalty_joint_acc | Linear | -0.000001 | – | |
| penalty_undesired_contacts | Linear | -0.5 | – | |
| terminal_particle_count_scaled | Scaled | 10 | – | |
| terminal_success_bonus | Scaled | 50 | – |
- Heightmap bins live regolith positions onto the observation grid at runtime; PhysX particle sets cannot be raycast.
imu_pedestalis active only atenv.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
eventstoenv.active_sensors.
Excavation Demo (excavation_demo)
Manual excavation demo with presentation-oriented lunar regolith defaults

| Episode Length | 1800.0s (90000 steps; truncation disabled) |
| Reward Terms | 13 |
| Default Robot | Kinova Gen3N7 |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.05 | – | |
| penalty_joint_torque | Linear | -0.00001 | – | |
| penalty_joint_acceleration | Linear | 0 | – | |
| penalty_undesired_robot_contacts | Linear | 0 | – | |
| reward_approach_pile | Gaussian | 1.5 | 0.15 | |
| reward_scoop_depth | Tukey | 2 | – | |
| reward_scoop_orientation | GaussianTracking | 1 | 0.26 | |
| reward_lift | Hyperbolic | 2 | 0.2 | |
| penalty_jerk | Linear | -0.02 | – | |
| penalty_joint_acc | Linear | -0.000001 | – | |
| penalty_undesired_contacts | Linear | -0.5 | – | |
| terminal_particle_count_scaled | Scaled | 10 | – | |
| terminal_success_bonus | Scaled | 50 | – |
Modular Assembly (modular_assembly)
Pick-and-place modular elements into an assembly configuration

| Episode Length | 20.0s (1000 steps) |
| Reward Terms | 10 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | 0 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -32 | – | |
| reward_top_down_orientation | GaussianTracking | 16 | 0.25 | |
| reward_pair_position | Linear | 8 | – | |
| reward_pair_orientation | Linear | 2 | – | |
| reward_peg_hole_entrance_alignment | Linear | 8 | – | |
| reward_peg_hole_alignment | Linear | 64 | – | |
| reward_success | Linear | 512 | – |
Multi Peg In Hole (multi_peg_in_hole)
A variation of peg-in-hole assembly with multiple pegs and holes
| Episode Length | 40.0s (2000 steps) |
| Reward Terms | 19 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_top_down_orientation | GaussianTracking | 1 | 0.25 | |
| reward_distance_ee_to_obj | Hyperbolic | 0 | 0.25 | |
| reward_grasp | Linear | 8 | – | |
| reward_lift | Linear | 4 | – | |
| reward_align_peg_to_hole_primary | GaussianTracking | 0 | 0.4 | |
| reward_align_peg_to_hole_secondary | Gaussian | 0 | 0.2 | |
| reward_distance_peg_to_hole_entrance_gradual | Hyperbolic | 0 | 0.16 | |
| reward_distance_peg_to_hole_entrance | Gaussian | 0 | 0.04 | |
| reward_distance_peg_to_hole_bottom | Gaussian | 0 | 0.003 | |
| reward_distance_ee_to_objs | Linear | 2.5 | – | |
| reward_align_pegs_to_holes_primary | Linear | 8 | – | |
| reward_align_pegs_to_holes_secondary | Linear | 4 | – | |
| reward_distance_pegs_to_holes_entrance_gradual | Linear | 8 | – | |
| reward_distance_pegs_to_holes_entrance | Linear | 32 | – | |
| reward_distance_pegs_to_holes_bottom | Linear | 256 | – |
Multi Sample Collection (multi_sample_collection)
A variation of sample collection with multiple samples
| Episode Length | 22.5s (1125 steps) |
| Reward Terms | 12 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_top_down_orientation | GaussianTracking | 1 | 0.25 | |
| reward_distance_ee_to_obj | Gaussian | 0 | 0.15 | |
| reward_grasp | Linear | 4 | – | |
| reward_lift | Linear | 8 | – | |
| reward_distance_obj_to_target | Gaussian | 0 | 0.15 | |
| penalty_obj_fallen | Linear | 0 | – | |
| reward_distance_ee_to_objs | Linear | 2.5 | – | |
| reward_distance_objs_to_target | Linear | 32 | – |
Peg In Hole (peg_in_hole)
Precision assembly task requiring the robot to insert a peg into a hole
| Episode Length | 10.0s (500 steps) |
| Reward Terms | 13 |
| Default Robot | Franka |
| Multi Variant | multi_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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_top_down_orientation | GaussianTracking | 1 | 0.25 | |
| reward_distance_ee_to_obj | Hyperbolic | 4 | 0.25 | |
| reward_grasp | SoftThreshold | 8 | – | |
| reward_lift | GaussianZoneTracking | 4 | 0.08 | |
| reward_align_peg_to_hole_primary | GaussianTracking | 8 | 0.4 | |
| reward_align_peg_to_hole_secondary | Gaussian | 4 | 0.2 | |
| reward_distance_peg_to_hole_entrance_gradual | Hyperbolic | 8 | 0.16 | |
| reward_distance_peg_to_hole_entrance | Gaussian | 32 | 0.04 | |
| reward_distance_peg_to_hole_bottom | Gaussian | 256 | 0.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 Length | 7.5s (375 steps) |
| Reward Terms | 10 |
| Default Robot | Franka |
| Multi Variant | multi_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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_top_down_orientation | GaussianTracking | 1 | 0.25 | |
| reward_distance_ee_to_obj | Gaussian | 4 | 0.15 | |
| reward_grasp | SoftThreshold | 6 | – | |
| reward_lift | GaussianZoneTracking | 12 | 0.15 | |
| reward_distance_obj_to_target | Gaussian | 32 | 0.15 | |
| penalty_obj_fallen | Linear | -16 | – |
obj_floor_zdrivespenalty_obj_fallen; falls do not terminate. Horizon ends astruncated.- Wrist event camera: add
eventstoenv.active_sensors. - Episode info omits
success; bounded evaluation reports return only.
Screwdriving (screwdriving)
Fastening of a pre-inserted bolt
| Episode Length | 15.0s (750 steps) |
| Reward Terms | 13 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_top_down_orientation | GaussianTracking | 8 | 0.04 | |
| penalty_object_top_down_orientation | Linear | -64 | – | |
| reward_distance_ee_to_bolt_driver_slot | Hyperbolic | 12 | 0.4 | |
| reward_distance_ee_to_bolt_driver_slot_close | Hyperbolic | 32 | 0.02 | |
| reward_distance_ee_to_bolt_driver_slot_precision | Hyperbolic | 512 | 0.005 | |
| reward_contact | SoftThreshold | 4 | – | |
| reward_screwing | Scaled | 128 | – | |
| penalty_distance_obj_to_target_too_far | Threshold | -256 | – | |
| reward_distance_obj_to_target | Linear | 2048 | – |
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 Length | 50.0s (2500 steps) |
| Reward Terms | 17 |
| Default Robot | Franka |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – | |
| reward_top_down_orientation | GaussianTracking | 1 | 0.25 | |
| reward_distance_ee_to_objs | Linear | 2.5 | – | |
| reward_grasp | SoftThreshold | 8 | – | |
| reward_lift | Linear | 4 | – | |
| reward_align_pegs_to_holes_primary | Linear | 8 | – | |
| reward_align_pegs_to_holes_secondary | Linear | 4 | – | |
| reward_distance_pegs_to_holes_entrance_gradual | Linear | 8 | – | |
| reward_distance_pegs_to_holes_entrance | Linear | 32 | – | |
| reward_distance_pegs_to_holes_bottom | Linear | 256 | – | |
| reward_distance_ee_to_panel | Hyperbolic | 10 | 0.25 | |
| reward_panel_lift | GaussianZoneTracking | 16 | 0.1 | |
| reward_distance_panel_to_target_gradual | Hyperbolic | 32 | 0.1 | |
| reward_distance_panel_to_target | Gaussian | 1024 | 0.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>.

Simulation only; no trained policy ships.
| Episode Length | 10.0s (250 steps) |
| Reward Terms | 1 |
| Default Robot | Ingenuity |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – |
Ground (_ground)
Template environment for ground mobile robots. Configure via
env.robot=<ground_robot>.

| Episode Length | 10.0s (250 steps) |
| Reward Terms | 1 |
| Default Robot | Cadre |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – |
Orbital (_orbital)
Template environment for orbital mobile robots. Configure via
env.robot=<orbital_robot>.

| Episode Length | 10.0s (250 steps) |
| Reward Terms | 2 |
| Default Robot | Cubesat |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -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.
| Environment | Far plane | Reason or limit |
|---|---|---|
| Orbital default | 100 m ((0.01, 100.0) m) | Orbital robots define no clipping range. |
rendezvous | 50 m | max_target_distance; about 20 cm per uint8 depth step, versus 39 cm at 100 m. |
orbital_evasion | 150 m | 100 m bounds radius plus obstacle field. |
landing, moonfall | 400 m | Nadir 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

Simulation only; no trained policy ships.
| Episode Length | 60.0s (1500 steps) |
| Reward Terms | 7 |
| Default Robot | Ingenuity |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| reward_altitude_tracking | HyperbolicTracking | 4 | 1 | |
| reward_waypoint_approach | Hyperbolic | 16 | 2 | |
| penalty_tilt_angle | OffsetLinear | -2 | – | |
| reward_terrain_clearance | HyperbolicBarrier | 8 | 0.5 | |
| penalty_energy | Linear | -0.5 | – | |
| reward_waypoint_reached | Threshold | 32 | – |
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

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_enabled | Behavior |
|---|---|
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. |
false | Free-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 Length | 30.0s (750 steps) |
| Reward Terms | 15 |
| Default Robot | Spot |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| reward_beam_position | Gaussian | 16 | 1.5 | |
| reward_beam_midpoint_alignment | Gaussian | 10 | 0.25 | |
| reward_robot_support_slots | Gaussian | 12 | 0.2 | |
| reward_beam_progress | Scaled | 8 | – | |
| reward_attachment_balance | Gaussian | 4 | 0.15 | |
| reward_success | Linear | 24 | – | |
| penalty_beam_tilt | Linear | -4 | – | |
| penalty_beam_drop | Linear | -16 | – | |
| penalty_beam_speed | Linear | -2 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.00000025 | – | |
| penalty_undesired_lin_vel_z | Linear | -0.5 | – | |
| penalty_undesired_ang_vel_xy | Linear | -0.1 | – | |
| penalty_gravity_rotation_alignment | Linear | -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: 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 Length | 90.0s (2250 steps) |
| Reward Terms | 8 |
| Default Robot | Ingenuity |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| reward_waypoint_approach | Hyperbolic | 12 | 4 | |
| reward_altitude_tracking | HyperbolicTracking | 6 | 1 | |
| reward_waypoint_reached | Threshold | 20 | – | |
| penalty_tilt_angle | OffsetLinear | -2 | – | |
| reward_terrain_clearance | HyperbolicBarrier | 6 | 0.8 | |
| penalty_energy | Linear | -0.6 | – | |
| reward_mission_progress | Linear | 60 | – |
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

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 Length | 60.0s (1500 steps) |
| Reward Terms | 9 |
| Default Robot | Cadre |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_formation_tracking | Linear | -1 | – | |
| reward_formation_progress | Scaled | 4 | – | |
| reward_formation_velocity | Linear | 2 | – | |
| reward_point_towards_target | Linear | 0.5 | – | |
| reward_formation_precision | Linear | 4 | – | |
| reward_in_zone | Linear | 0 | – | |
| reward_formation_orientation | Linear | 4 | – | |
| reward_action_rate_in_formation | Linear | 32 | – |
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

| Episode Length | 60.0s (1500 steps) |
| Reward Terms | 9 |
| Default Robot | Cadre |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_formation_tracking | Linear | -1 | – | |
| reward_formation_progress | Scaled | 4 | – | |
| reward_formation_velocity | Linear | 2 | – | |
| reward_point_towards_target | Linear | 0.5 | – | |
| reward_formation_precision | Linear | 4 | – | |
| reward_in_zone | Linear | 0 | – | |
| reward_formation_orientation | Linear | 4 | – | |
| reward_action_rate_in_formation | Linear | 32 | – |
Formation Following Orbital (formation_following_orbital)
Orbital formation tracking in microgravity

| Episode Length | 60.0s (600 steps) |
| Reward Terms | 7 |
| Default Robot | Cubesat |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -8 | – | |
| penalty_fuel_consumption | Linear | 0 | – | |
| penalty_action_magnitude | Linear | -8 | – | |
| penalty_formation_tracking | Linear | -2 | – | |
| reward_formation_precision | Linear | 16 | – | |
| reward_formation_orientation | Linear | 48 | – | |
| reward_action_rate_in_formation | Linear | 48 | – |
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 Length | 40.0s (1000 steps) |
| Reward Terms | 11 |
| Default Robot | Peregrine 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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -1 | – | |
| penalty_angular_velocity | Linear | -0.25 | – | |
| penalty_gravity_rotation_alignment | Linear | -1 | – | |
| penalty_horizontal_linear_velocity | Linear | -0.1 | – | |
| reward_vertical_linear_velocity | Hyperbolic | 8 | 1 | |
| reward_landing_angle | Linear | 8 | – | |
| reward_landing_velocity | Linear | 16 | – | |
| reward_landing_fuel | Linear | 4 | – | |
| penalty_crash | Linear | -32 | – | |
| penalty_below_target | Linear | -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 Length | 20.0s (500 steps) |
| Reward Terms | 12 |
| Default Robot | Spot |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| reward_cmd_lin_vel_xy | Linear | 4 | – | |
| reward_cmd_ang_vel_z | Linear | 2 | – | |
| penalty_undesired_lin_vel_z | Linear | -0.5 | – | |
| penalty_undesired_ang_vel_xy | Linear | -0.1 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.00000025 | – | |
| penalty_undesired_robot_contacts | Threshold | -2 | – | |
| penalty_gravity_rotation_alignment | Linear | -2 | – | |
| reward_feet_air_time | Linear | 0.75 | – | |
| reward_quadruped_trot | Linear | 1 | – | |
| penalty_foot_slip | Linear | -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 Length | 60.0s (1500 steps) |
| Reward Terms | 13 |
| Default Robot | Spot |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_position_tracking | Linear | -1 | – | |
| reward_point_towards_target | Linear | 1 | – | |
| reward_position_tracking_precision | Linear | 4 | – | |
| reward_orientation_tracking | Linear | 8 | – | |
| reward_action_rate_at_target | Linear | 16 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.00000025 | – | |
| penalty_undesired_robot_contacts | Threshold | -2 | – | |
| penalty_undesired_lin_vel_z | Linear | -0.5 | – | |
| penalty_undesired_ang_vel_xy | Linear | -0.1 | – | |
| penalty_gravity_rotation_alignment | Linear | -2 | – | |
| reward_feet_air_time | Linear | 0.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

| Episode Length | 70.0s (1750 steps) |
| Reward Terms | 12 |
| Default Robot | Peregrine 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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -1 | – | |
| penalty_angular_velocity | Linear | -0.25 | – | |
| penalty_gravity_rotation_alignment | Linear | -1 | – | |
| penalty_horizontal_linear_velocity | Linear | -0.1 | – | |
| reward_waypoint_progress | Hyperbolic | 4 | 4 | |
| reward_vertical_linear_velocity | Hyperbolic | 8 | 1 | |
| reward_landing_angle | Linear | 8 | – | |
| reward_landing_velocity | Linear | 16 | – | |
| reward_landing_fuel | Linear | 4 | – | |
| penalty_crash | Linear | -32 | – | |
| penalty_below_target | Linear | -16 | – |
See event camera options.
See evaluation note.
Orbital Evasion (orbital_evasion)
Navigation of spacecraft in microgravity while avoiding obstacles
| Episode Length | 30.0s (750 steps) |
| Reward Terms | 7 |
| Default Robot | Cubesat |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -1 | – | |
| penalty_angular_velocity | Linear | -0.25 | – | |
| reward_obstacle_clearance | HyperbolicBarrier | 4 | 2 | |
| penalty_distance_robot_to_target | Linear | -0.32 | – | |
| penalty_out_of_bounds | Linear | -16 | – | |
| reward_target_approach | Hyperbolic | 8 | 5 |
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

| Episode Length | 30.0s (300 steps) |
| Reward Terms | 9 |
| Default Robot | Satellite 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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | LogCosh | -4 | – | |
| penalty_fuel_consumption | Linear | 0 | – | |
| penalty_action_magnitude | LogCosh | -1 | – | |
| penalty_angular_velocity | LogCosh | -2 | – | |
| penalty_position_distance | Linear | -1 | – | |
| penalty_velocity_at_target | LogCosh | -4 | – | |
| reward_position_approach | Hyperbolic | 4 | 2 | |
| reward_position_precision | Scaled | 8 | – | |
| reward_smooth_station_keeping | Scaled | 8 | – |
See evaluation note.
Rendezvous (rendezvous)
Maneuvering of spacecraft in microgravity to rendezvous with an uncooperative target
| Episode Length | 25.0s (625 steps) |
| Reward Terms | 7 |
| Default Robot | Cubesat |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -8 | – | |
| penalty_angular_velocity | Linear | -0.05 | – | |
| penalty_distance_robot_to_target | Linear | -16 | – | |
| penalty_too_far | Linear | -16 | – | |
| reward_precision_position | Gaussian | 128 | 0.025 | |
| reward_precision_orientation | Linear | 128 | – |
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

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
| Input | Action |
|---|---|
W/S, C/V | Forward/reverse; turn. |
Q/E | Raise/lower shovel. Release sends zero velocity; damping resists drift, no auto-retract. |
| SpaceMouse forward/back, vertical | Same 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 Length | 60.0s (600 steps) |
| Default Robot | Raph Rover |
Robots
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 to1287 float32. Elevations use mission-frame+z, matching deployment adapters. No validity mask: all146×146source 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

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 Length | 30.0s (300 steps) |
| Default Robot | Raph Rover |
Robots
| Feature | Defaults |
|---|---|
| Crater | Center (0.45 m, 0.20 m), radius 0.36 m, depth 0.11 m. |
| Pile | Center (-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 to1287 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

No trained policy ships, Dreamer runs with
env.num_envs=1only, TD-MPC2 is not supported, and the task is not validated on Raph hardware. See Terrain Landscaping Training.
| Episode Length | 30.0s (300 steps) |
| Default Robot | Raph Rover |
Robots
Traversal (traversal)
Straight-line path following at a target velocity

| Episode Length | 120.0s (3000 steps) |
| Reward Terms | 5 |
| Default Robot | Nifty |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.05 | – | |
| penalty_lateral_pos_deviation | Linear | -1 | – | |
| reward_vel_progress | Linear | 8 | – | |
| reward_action_rate_at_target | Linear | 32 | – | |
| penalty_rollover | Linear | -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 Length | 20.0s (500 steps) |
| Reward Terms | 5 |
| Default Robot | Cadre |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| reward_cmd_lin_vel_xy | Linear | 4 | – | |
| reward_cmd_ang_vel_z | Linear | 2 | – | |
| penalty_undesired_lin_vel_z | Linear | -0.5 | – | |
| penalty_undesired_ang_vel_xy | Linear | -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 Length | 60.0s (1500 steps) |
| Reward Terms | 6 |
| Default Robot | Cadre |
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
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_position_tracking | Linear | -1 | – | |
| reward_point_towards_target | Linear | 1 | – | |
| reward_position_tracking_precision | Linear | 4 | – | |
| reward_orientation_tracking | Linear | 8 | – | |
| reward_action_rate_at_target | Linear | 16 | – |
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>andenv.robot.manipulator=<manipulator>.

Simulation only; no trained policy ships.
| Episode Length | 10.0s (500 steps) |
| Reward Terms | 2 |
| Default Robot | Generic Aerial Manipulator |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – |
Ground Manipulation (_ground_manipulation)
Template environment for ground mobile manipulators. Configure via
env.robot.mobile_base=<ground_robot>andenv.robot.manipulator=<manipulator>.

| Episode Length | 10.0s (500 steps) |
| Reward Terms | 2 |
| Default Robot | Generic Ground Manipulator |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – |
Orbital Manipulation (_orbital_manipulation)
Template environment for orbital mobile manipulators. Configure via
env.robot.mobile_base=<orbital_robot>andenv.robot.manipulator=<manipulator>.

| Episode Length | 10.0s (500 steps) |
| Reward Terms | 2 |
| Default Robot | Generic Orbital Manipulator |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – |
Mobile Debris Capture (mobile_debris_capture)
Capture of floating debris in microgravity with a floating-base mobile manipulator
| Episode Length | 60.0s (3000 steps) |
| Reward Terms | 10 |
| Default Robot | Generic Orbital Manipulator |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -2 | – | |
| penalty_angular_velocity | Linear | -0.05 | – | |
| penalty_joint_torque | Linear | -0.000025 | – | |
| penalty_joint_acceleration | Linear | -0.0005 | – | |
| reward_distance_end_effector_to_obj | Gaussian | 16 | 0.2 | |
| reward_grasp | SoftThreshold | 32 | – | |
| reward_minimize_rel_lin_vel | Gaussian | 12 | 0.01 | |
| reward_minimize_rel_ang_vel | Gaussian | 24 | 0.03 | |
| penalty_debris_too_far | Linear | -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

Simulation only; no trained policy ships. Thruster-less humanoid traverses waypoints and station-keeps by pushing off spacecraft structure.
| Mode | Select | Scenery and path | Rail observation / contact |
|---|---|---|---|
| EVA (default) | spacewalk / env.mode=eva | Exterior ISS+Gateway; EVA_WAYPOINT_PATH creates handrails | Rail-distance observation |
| IVA | env.mode=iva / spacewalk_iva | Kibou; base retargets to IVA_WAYPOINT_PATH inside rail-free module | Constant 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:
| Metric | Meaning |
|---|---|
success_rate | Fraction reaching/holding final waypoint |
min_distance_to_target | Minimum sampled distance to the active waypoint; may miss waypoint arrivals |
min_distance_to_final_target | Closest final-waypoint distance; completion measure |
waypoint_progress | Path advancement: index / (num_waypoints − 1) |
dist_to_nearest_handrail | Body-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; abovesuccess_radiusmeans goal region not reached, at/below means required hold failed.
EVA scenery. ISSGatewayScenery:
| Setting | Effect / default |
|---|---|
env.scenery.station_template_usd_path | Replace ISS+Gateway with one USD station file |
env.scenery.use_exact_station_mesh_collision | Triangular-mesh collision; default false |
env.scenery.add_handrails, env.scenery.handrail_segment_specs | Control rails aligned to waypoint path |
env.scenery.handrail_specs | X-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 / physics | Constraint |
|---|---|
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 joints | Rate 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 Length | 20.0s (500 steps) |
| Reward Terms | 9 |
| Default Robot | Unitree G1 |
Robots
Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.5 | – | |
| penalty_angular_velocity | Linear | -2 | – | |
| reward_distance_to_target | Gaussian | 16 | 2.5 | |
| reward_progress | Scaled | 8 | – | |
| reward_approach_velocity | GaussianAlignment | 12 | 0.7854 | |
| reward_reaching | SoftThreshold | 32 | – | |
| reward_stability | Gaussian | 8 | 0.1 | |
| reward_success_hold | Linear | 10 | – | |
| penalty_drift_from_spacecraft | SoftThreshold | -6 | – |
| Reward role | Terms / behavior |
|---|---|
| Guidance | reward_distance_to_target Gaussian (scale 2.5); reward_approach_velocity direction alignment; signed per-step reward_progress. |
| Goal | Dominant reward_reaching: sharp soft-threshold at 0.5 m, independent of success_radius except its 0.5 m default. |
| Hold | reward_stability: low-velocity Gaussian in success region; reward_success_hold: success-streak fraction. |
| Safety | Action-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

Simulation only; no trained policy ships. See Spacewalk for training and evaluation.
| Episode Length | 20.0s (500 steps) |
| Reward Terms | 9 |
| Default Robot | Unitree G1 |
Robots
Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.5 | – | |
| penalty_angular_velocity | Linear | -2 | – | |
| reward_distance_to_target | Gaussian | 16 | 2.5 | |
| reward_progress | Scaled | 8 | – | |
| reward_approach_velocity | GaussianAlignment | 12 | 0.7854 | |
| reward_reaching | SoftThreshold | 32 | – | |
| reward_stability | Gaussian | 8 | 0.1 | |
| reward_success_hold | Linear | 10 | – | |
| penalty_drift_from_spacecraft | SoftThreshold | -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

Simulation only; no trained policy ships. See Spacewalk for training and evaluation.
| Episode Length | 20.0s (500 steps) |
| Reward Terms | 9 |
| Default Robot | Unitree G1 |
Robots
Humanoid21 | Humanoid28 | Unitree H1 | Unitree G1
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.5 | – | |
| penalty_angular_velocity | Linear | -2 | – | |
| reward_distance_to_target | Gaussian | 16 | 2.5 | |
| reward_progress | Scaled | 8 | – | |
| reward_approach_velocity | GaussianAlignment | 12 | 0.7854 | |
| reward_reaching | SoftThreshold | 32 | – | |
| reward_stability | Gaussian | 8 | 0.1 | |
| reward_success_hold | Linear | 10 | – | |
| penalty_drift_from_spacecraft | SoftThreshold | -6 | – |
Environments – Digital Twins
Facility-inspired simulator environments, not validated against their physical counterparts.
Lunalab (lunalab)
Digital twin of the LunaLab planetary analogue testbed

| Episode Length | 100000.0s (2500000 steps; truncation disabled) |
| Reward Terms | 2 |
| Default Robot | Generic Ground Manipulator |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_undesired_robot_contacts | Threshold | -0.5 | – |
Zerog Lab (zerog_lab)
Digital twin of a zero-gravity laboratory testbed

| Episode Length | 100000.0s (1000000 steps; truncation disabled) |
| Reward Terms | 2 |
| Default Robot | Generic Orbital Manipulator |
Robots
Rewards
| Term | Type | Weight | Scale | Notes |
|---|---|---|---|---|
| penalty_action_rate | Linear | -0.1 | – | |
| penalty_fuel_consumption | Linear | -1 | – |
Assets

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.

Franka
Franka (franka)
7-DoF torque-controlled research arm from Franka Robotics

| DoF | 7 |
| End Effector | FrankaHand |
| Base Frame | panda_link0 |
| Flange Frame | panda_link7 |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
| Source | SRB |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 7 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| panda_shoulder | panda_joint[1-4] | 87 N·m | 2.175 rad/s | 4000 | 800 |
| panda_forearm | panda_joint[5-7] | 12 N·m | 2.61 rad/s | 4000 | 800 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | panda_link0/camera_base |
| cam_wrist | Camera | panda_link7/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| panda_joint1 | 0.0 rad |
| panda_joint2 | 0.0 rad |
| panda_joint3 | 0.0 rad |
| panda_joint4 | -1.570796 rad (-90 deg) |
| panda_joint5 | 0.0 rad |
| panda_joint6 | 1.570796 rad (90 deg) |
| panda_joint7 | 0.785398 rad (45 deg) |
Kinova
Kinova Gen3N7 (kinova_gen3n7)
7-DoF lightweight research arm from Kinova Robotics

| DoF | 7 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | end_effector_link |
| Sensors | 3 |
| Action Modes | 6 (default: diff_ik) |
| Source | Isaac Lab |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
smooth_osc | Smooth Operational Space Controller | 6 | pos=0.1, ori=0.1 |
joint_pos_rel | Relative Joint Position | 7 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | joint_[1-7] | 540–2340 N·m | 10 rad/s | 500 | 200 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | end_effector_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| joint_1 | 0.0 rad |
| joint_2 | 0.785398 rad (45 deg) |
| joint_3 | 0.0 rad |
| joint_4 | 0.785398 rad (45 deg) |
| joint_5 | 0.0 rad |
| joint_6 | 1.570796 rad (90 deg) |
| joint_7 | 0.0 rad |
Kinova J2N6S (kinova_j2n6s)

| DoF | 6 |
| End Effector | Kinova300 |
| Base Frame | j2n6s_link_base |
| Flange Frame | j2n6s_link_6 |
| Sensors | 3 |
| Action Modes | 2 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | j2n6s_joint_[1-6] | 20–80 N·m | 100 rad/s | 1500–4000 | 500–1000 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | j2n6s_link_base/camera_base |
| cam_wrist | Camera | j2n6s_link_6/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| j2n6s_joint_1 | 0.0 rad |
| j2n6s_joint_2 | 2.617994 rad (150 deg) |
| j2n6s_joint_3 | 5.759587 rad (330 deg) |
| j2n6s_joint_4 | -1.570796 rad (-90 deg) |
| j2n6s_joint_5 | 0.0 rad |
| j2n6s_joint_6 | 0.0 rad |
Kinova J2N7S (kinova_j2n7s)

| DoF | 7 |
| End Effector | Kinova300 |
| Base Frame | j2n7s_link_base |
| Flange Frame | j2n7s_link_7 |
| Sensors | 3 |
| Action Modes | 2 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
joint_pos_rel | Relative Joint Position | 7 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | j2n7s_joint_[1-7] | 20–80 N·m | 100 rad/s | 1000–4000 | 500–1000 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | j2n7s_link_base/camera_base |
| cam_wrist | Camera | j2n7s_link_7/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| j2n7s_joint_1 | 0.0 rad |
| j2n7s_joint_2 | 2.617994 rad (150 deg) |
| j2n7s_joint_3 | 0.0 rad |
| j2n7s_joint_4 | 0.523599 rad (30 deg) |
| j2n7s_joint_5 | 1.570796 rad (90 deg) |
| j2n7s_joint_6 | 0.0 rad |
| j2n7s_joint_7 | 0.0 rad |
Multi-Arm
Levion Arms (levion_arms)

| DoF | 4 |
| End Effector | None |
| Base Frame | base_link |
| Sensors | 0 |
| Action Modes | default: dual_arm_joint_pos_abs |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
dual_arm_joint_pos_abs * | Joint Position To Limits | 4 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| left_arm | left_shoulder_joint, left_elbow_joint | 15 N·m | – | 400 | 80 |
| right_arm | right_shoulder_joint, right_elbow_joint | 15 N·m | – | 400 | 80 |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*shoulder_joint | 0.0 rad |
| right_elbow_joint | 0.4 rad (22.918312 deg) |
| left_elbow_joint | -0.4 rad (-22.918312 deg) |
Zeroglab Arms (zeroglab_arms)

| DoF | 7 |
| End Effector | None |
| Base Frame | _virtual_world |
| Sensors | 0 |
| Action Modes | default: dual_arm_osc |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
dual_arm_osc * | Operational Space Controller | 24 | arm_ceiling: pos=0.1, ori=0.1, stiffness=120.0; arm_wall: pos=0.1, ori=0.1, stiffness=120.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| rail | rail_joint | 400 N·m | 0.2 rad/s | 3000 | 2500 |
| arm | .*shoulder.*, .*elbow.*, .*wrist.* | 87 N·m | 100 rad/s | 800 | 40 |
Initial Joint Configuration
| Joint | Position |
|---|---|
| rail_joint | 2 rad (114.591559 deg) |
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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

| DoF | 5 |
| End Effector | SOArm100Gripper |
| Base Frame | Base |
| Flange Frame | Fixed_Gripper |
| Sensors | 3 |
| Action Modes | 3 (default: diff_ik) |
| Source | SRB |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.05, ori=0.05, stiffness=120.0 |
joint_pos_rel | Relative Joint Position | 5 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 10 N·m | 10 rad/s | 100 | 20 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | Base/camera_base |
| cam_wrist | Camera | Fixed_Gripper/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| Shoulder_Rotation | 0.0 rad |
| Shoulder_Pitch | -0.261799 rad (-15 deg) |
| Elbow | 0.349066 rad (20 deg) |
| Wrist_Pitch | 0.087266 rad (5 deg) |
| Wrist_Roll | 0.0 rad |
So Arm100 D7 (so_arm100_d7)
7-DoF low-cost open-source motor-driven arm

| DoF | 7 |
| End Effector | None |
| Base Frame | Base |
| Flange Frame | End_Servo |
| Sensors | 3 |
| Action Modes | 2 (default: diff_ik) |
| Source | SRB |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
joint_pos_rel | Relative Joint Position | 7 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 10 N·m | 10 rad/s | 100 | 20 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | Base/camera_base |
| cam_wrist | Camera | End_Servo/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| Shoulder_Pitch | 2.094395 rad (120 deg) |
| Shoulder_Yaw | 0.0 rad |
| Humeral_Rotation | 0.0 rad |
| Elbow | -1.570796 rad (-90 deg) |
| Wrist_Roll | 0.0 rad |
| Wrist_Yaw | 0.0 rad |
| Wrist_Pitch | -1.570796 rad (-90 deg) |
Space
Canadarm3 (canadarm3)
Large-scale space manipulator for the Lunar Gateway station

| DoF | 7 |
| End Effector | None |
| Base Frame | canadarm3_large_0 |
| Flange Frame | canadarm3_large_7 |
| Sensors | 3 |
| Action Modes | 2 (default: diff_ik) |
| Source | SRB |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
joint_pos_rel | Relative Joint Position | 7 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| joints | canadarm3_large_joint_[1-7] | 2500 N·m | 5 rad/s | 40000 | 25000 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | canadarm3_large_0/camera_base |
| cam_wrist | Camera | canadarm3_large_7/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| canadarm3_large_joint_1 | 0.872665 rad (50 deg) |
| canadarm3_large_joint_2 | 0.0 rad |
| canadarm3_large_joint_3 | 0.959931 rad (55 deg) |
| canadarm3_large_joint_4 | 1.308997 rad (75 deg) |
| canadarm3_large_joint_5 | -0.523599 rad (-30 deg) |
| canadarm3_large_joint_6 | 0.0 rad |
| canadarm3_large_joint_7 | 0.0 rad |
Vispa (vispa)
Space manipulator designed for planetary surface operations

| DoF | 6 |
| End Effector | None |
| Base Frame | link0 |
| Flange Frame | link6 |
| Sensors | 3 |
| Action Modes | 3 (default: diff_ik) |
| Source | SRB |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| joints | joint[1-6] | 500 N·m | 5 rad/s | 2500 | 500 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | link0/camera_base |
| cam_wrist | Camera | link6/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| joint1 | 0.0 rad |
| joint2 | -0.523599 rad (-30 deg) |
| joint3 | 2.094395 rad (120 deg) |
| joint4 | 0.0 rad |
| joint5 | 1.570796 rad (90 deg) |
| joint6 | 0.0 rad |
Unitree
Unitree Z1 (unitree_z1)
Compact lightweight arm from Unitree Robotics

| DoF | 6 |
| End Effector | None |
| Base Frame | link00 |
| Flange Frame | link06 |
| Sensors | 3 |
| Action Modes | 2 (default: diff_ik) |
| Source | Isaac Lab |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | link00/camera_base |
| cam_wrist | Camera | link06/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| joint1 | 0.0 rad |
| joint2 | 1.570796 rad (90 deg) |
| joint3 | -0.785398 rad (-45 deg) |
| joint4 | 0.785398 rad (45 deg) |
| joint5 | 0.0 rad |
| joint6 | 0.0 rad |
Universal Robots
Random Ur Manipulator (random_ur_manipulator)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | ee_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
| Source | Isaac Lab |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | ee_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
| Source | Isaac Sim |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
| Source | Isaac Sim |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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)

| DoF | 6 |
| End Effector | None |
| Base Frame | base_link |
| Flange Frame | wrist_3_link |
| Sensors | 3 |
| Action Modes | 5 (default: diff_ik) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
joint_pos_rel | Relative Joint Position | 6 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| arm | .* | 87 N·m | 100 rad/s | 800 | 40 |
Sensors
| Name | Type | Location |
|---|---|---|
| contacts_robot | Contact Sensor | .* |
| cam_base | Camera | base_link/camera_base |
| cam_wrist | Camera | wrist_3_link/camera_wrist |
Initial Joint Configuration
| Joint | Position |
|---|---|
| shoulder_pan_joint | 0.0 rad |
| shoulder_lift_joint | -1.570796 rad (-90 deg) |
| elbow_joint | 1.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.

Active
Allegro Hand (allegro_hand)

| Type | tool |
| Variant | Dataset |
| Collision | – |
Electric Screwdriver M3 (electric_screwdriver_m3)

| Type | tool |
| Variant | Dataset |
| Collision | – |
Electric Screwdriver M5 (electric_screwdriver_m5)

| Type | tool |
| Variant | Dataset |
| Collision | – |
Franka Hand (franka_hand)

| Type | tool |
| Variant | Dataset |
| Collision | – |
Kinova300 (kinova300)

| Type | tool |
| Variant | Dataset |
| Collision | – |
Robotiq Hand E (robotiq_hand_e)

| Type | tool |
| Variant | Dataset |
| Collision | convexHull |
Shadow Hand (shadow_hand)

| Type | tool |
| Variant | Dataset |
| Collision | – |
So Arm100 Gripper (so_arm100_gripper)

| Type | tool |
| Variant | Dataset |
| Collision | – |
Passive
Manual Screwdriver M3 (manual_screwdriver_m3)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
| Density | 1500 kg/m³ |
Manual Screwdriver M5 (manual_screwdriver_m5)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
| Density | 1500 kg/m³ |
Random Scoop (random_scoop)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
Scoop (scoop)

| Type | tool |
| Variant | Procedural |
| Collision | sdf |
Scoop Custom1 (scoop_custom1)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
Scoop Custom2 (scoop_custom2)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
Scoop Custom3 (scoop_custom3)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
Scoop Rectangular (scoop_rectangular)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
Scoop Spherical (scoop_spherical)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
Scoop Triangular (scoop_triangular)

| Type | tool |
| Variant | Dataset |
| Collision | sdf |
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.

Landers
Apollo Lander (apollo_lander)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 4280 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 17 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Peregrine Lander (peregrine_lander)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 825 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 17 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Random Lander (random_lander)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 3 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Resilience Lander (resilience_lander)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 340 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 9 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Vikram Lander (vikram_lander)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 626 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 13 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Legged Robots
Anymal C (anymal_c)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| legs | .*HAA, .*HFE, .*KFE | 80 N·m | 7.5 rad/s | – | – |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| contacts_feet | Contact Sensor | .*FOOT |
| cam_front | Camera | base/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*HAA | 0.0 rad |
.*F_HFE | 0.4 rad (22.918312 deg) |
.*H_HFE | -0.4 rad (-22.918312 deg) |
.*F_KFE | -0.8 rad (-45.836624 deg) |
.*H_KFE | 0.8 rad (45.836624 deg) |
Anymal D (anymal_d)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| legs | .*HAA, .*HFE, .*KFE | 80 N·m | 7.5 rad/s | – | – |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| contacts_feet | Contact Sensor | .*FOOT |
| cam_front | Camera | base/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*HAA | 0.0 rad |
.*F_HFE | 0.4 rad (22.918312 deg) |
.*H_HFE | -0.4 rad (-22.918312 deg) |
.*F_KFE | -0.8 rad (-45.836624 deg) |
.*H_KFE | 0.8 rad (45.836624 deg) |
Cassie (cassie)

| DoF | 12 |
| End Effector | None |
| Base Frame | pelvis |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | 12 | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| legs | hip_.*, thigh_.*, ankle_.* | 200 N·m | 10 rad/s | 100–200 | 3–6 |
| toes | toe_.* | 20 N·m | 10 rad/s | 20 | 1 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | pelvis |
| contacts_feet | Contact Sensor | (left|right)_toe |
| cam_front | Camera | pelvis/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
| hip_abduction_left | 0.1 rad (5.729578 deg) |
| hip_rotation_left | 0.0 rad |
| hip_flexion_left | 1 rad (57.29578 deg) |
| thigh_joint_left | -1.8 rad (-103.132403 deg) |
| ankle_joint_left | 1.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_right | 0.0 rad |
| hip_flexion_right | 1 rad (57.29578 deg) |
| thigh_joint_right | -1.8 rad (-103.132403 deg) |
| ankle_joint_right | 1.57 rad (89.954374 deg) |
| toe_joint_right | -1.57 rad (-89.954374 deg) |
Random Anymal Quadruped (random_anymal_quadruped)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| legs | .*HAA, .*HFE, .*KFE | 80 N·m | 7.5 rad/s | – | – |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| contacts_feet | Contact Sensor | .*FOOT |
| cam_front | Camera | base/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*HAA | 0.0 rad |
.*F_HFE | 0.4 rad (22.918312 deg) |
.*H_HFE | -0.4 rad (-22.918312 deg) |
.*F_KFE | -0.8 rad (-45.836624 deg) |
.*H_KFE | 0.8 rad (45.836624 deg) |
Random Unitree Quadruped (random_unitree_quadruped)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | trunk |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| base_legs | .*_hip_joint, .*_thigh_joint, .*_calf_joint | 33.5 N·m | 21 rad/s | 25 | 0.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | trunk |
| contacts_feet | Contact Sensor | .*foot |
| cam_front | Camera | trunk/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*L_hip_joint | 0.1 rad (5.729578 deg) |
.*R_hip_joint | -0.1 rad (-5.729578 deg) |
F[L,R]_thigh_joint | 0.8 rad (45.836624 deg) |
R[L,R]_thigh_joint | 1 rad (57.29578 deg) |
.*_calf_joint | -1.5 rad (-85.943669 deg) |
Spot (spot)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | body |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position | runtime-resolved | 0.2 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| spot_hip | .*_h[xy] | 45 N·m | – | 60 | 1.5 |
| spot_knee | .*_kn | – | – | 60 | 1.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | body |
| contacts_feet | Contact Sensor | .*foot |
| cam_front | Camera | body/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
[fh]l_hx | 0.1 rad (5.729578 deg) |
[fh]r_hx | -0.1 rad (-5.729578 deg) |
f[rl]_hy | 0.9 rad (51.566202 deg) |
h[rl]_hy | 1.1 rad (63.025357 deg) |
.*_kn | -1.5 rad (-85.943669 deg) |
Unitree A1 (unitree_a1)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | trunk |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| base_legs | .*_hip_joint, .*_thigh_joint, .*_calf_joint | 33.5 N·m | 21 rad/s | 25 | 0.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | trunk |
| contacts_feet | Contact Sensor | .*foot |
| cam_front | Camera | trunk/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*L_hip_joint | 0.1 rad (5.729578 deg) |
.*R_hip_joint | -0.1 rad (-5.729578 deg) |
F[L,R]_thigh_joint | 0.8 rad (45.836624 deg) |
R[L,R]_thigh_joint | 1 rad (57.29578 deg) |
.*_calf_joint | -1.5 rad (-85.943669 deg) |
Unitree Go1 (unitree_go1)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | trunk |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| base_legs | .*_hip_joint, .*_thigh_joint, .*_calf_joint | 23.7 N·m | 30 rad/s | – | – |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | trunk |
| contacts_feet | Contact Sensor | .*foot |
| cam_front | Camera | trunk/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*L_hip_joint | 0.1 rad (5.729578 deg) |
.*R_hip_joint | -0.1 rad (-5.729578 deg) |
F[L,R]_thigh_joint | 0.8 rad (45.836624 deg) |
R[L,R]_thigh_joint | 1 rad (57.29578 deg) |
.*_calf_joint | -1.5 rad (-85.943669 deg) |
Unitree Go2 (unitree_go2)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| base_legs | .*_hip_joint, .*_thigh_joint, .*_calf_joint | 33.5 N·m | 21 rad/s | 25 | 0.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| contacts_feet | Contact Sensor | .*foot |
| cam_front | Camera | base/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*L_hip_joint | 0.1 rad (5.729578 deg) |
.*R_hip_joint | -0.1 rad (-5.729578 deg) |
F[L,R]_thigh_joint | 0.8 rad (45.836624 deg) |
R[L,R]_thigh_joint | 1 rad (57.29578 deg) |
.*_calf_joint | -1.5 rad (-85.943669 deg) |
Multicopters
Crazyflie (crazyflie)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | body |
| Sensors | 2 |
| Action Modes | default: body_acc |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
body_acc * | Multicopter Body Acceleration | 4 | 0.5 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| dummy | .* | – | – | 0 | 0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | body |
| cam_onboard | Camera | body/camera_onboard |
Ingenuity (ingenuity)

| DoF | 2 |
| End Effector | None |
| Base Frame | body |
| Sensors | 3 |
| Action Modes | default: body_acc |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
body_acc * | Multicopter Body Acceleration | 4 | 0.5 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| rotors | rotor_joint_[1-2] | 7.5 N·m | 261.799388 rad/s | 0 | 1000 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | body |
| cam_onboard | Camera | body/camera_onboard |
| altimeter | Heightmap Sensor | body |
Orbital Robots
Cubesat (cubesat)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | cubesat |
| Sensors | 2 |
| Action Modes | default: thrust |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 12 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | cubesat |
| cam_onboard | Camera | cubesat/camera_onboard |
Floating Platform (floating_platform)

| DoF | 1 |
| End Effector | None |
| Base Frame | base_link |
| Sensors | 2 |
| Action Modes | 2 (default: thrust_only) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust_only * | Thrust | 8 | 1.0 |
thrust_and_reaction | Thrust | 9 | thrust=1.0; reaction_wheel_torque=0.05 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| reaction_wheel | rw_revolute_joint | 1 N·m | 100 rad/s | 0 | 0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base_link |
| cam_onboard | Camera | base_link/camera_onboard |
Gateway (gateway)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | gateway |
| Sensors | 2 |
| Action Modes | default: body_acc |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
body_acc * | Body Acceleration | 6 | 2.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | gateway |
| cam_onboard | Camera | gateway/camera_onboard |
Int Ball1 (int_ball1)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base_link |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 1 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 6 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base_link |
| cam_onboard | Camera | base_link/camera_onboard |
Int Ball2 (int_ball2)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base_link |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 1.5 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 6 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base_link |
| cam_onboard | Camera | base_link/camera_onboard |
Iss (iss)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: body_acc |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
body_acc * | Body Acceleration | 6 | 2.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Satellite Mockup (satellite_mockup)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | satellite_mockup |
| Sensors | 2 |
| Action Modes | default: thrust |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 12 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | satellite_mockup |
| cam_onboard | Camera | satellite_mockup/camera_onboard |
Starship (starship)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 100000 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 18 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Super Heavy (super_heavy)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
| Mass | 200000 kg |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 59 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Venus Express (venus_express)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base |
| Sensors | 2 |
| Action Modes | default: thrust |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 19 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base |
| cam_onboard | Camera | base/camera_onboard |
Surface Vehicles
Heron (heron)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | base_link |
| Sensors | 2 |
| Action Modes | default: thrust |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
thrust * | Thrust | 2 | 1.0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | base_link |
| cam_onboard | Camera | base_link/camera_onboard |
Wheeled Robots
Cadre (cadre)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | chassis |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.4, ang=0.7853981633974483 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| wheel_joints | wheel_joint_.* | 250 N·m | 6.28 rad/s | 0 | 2000 |
| suspension_joints | suspension_joint.* | 500 N·m | 0.25 rad/s | 400 | 5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | chassis |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | chassis/camera_front |
Husky (husky)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | chassis |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.1, ang=0.7853981633974483 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| wheel_joints | wheel_joint_.* | 250 N·m | 6.28 rad/s | 0 | 2000 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | chassis |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | chassis/camera_front |
Leo Rover (leo_rover)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | chassis |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.4, ang=1.0471975511965976 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| drive | wheel_joint_.* | 80 N·m | 30 rad/s | 0 | 5000 |
| rocker | rocker_joint_.* | 500 N·m | 2 rad/s | 2 | 0.5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | chassis |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | chassis/camera_front |
Mars Rover (mars_rover)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | Body |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.5, ang=0.7853981633974483 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| base_steering | .*Steer.* | 12 N·m | 6 rad/s | 8000 | 1000 |
| base_drive | .*Drive.* | 12 N·m | 6 rad/s | 100 | 4000 |
| passive_joints_boogie | .*RevoluteJoint | 0 N·m | 15 rad/s | 0 | 0 |
| passive_joints_rocker | .*Rocker.* | 0 N·m | 15 rad/s | 0 | 0 |
| passive_joints_differential | .*Differential.* | 0 N·m | 15 rad/s | 0 | 0 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | Body |
| contacts_wheels | Contact Sensor | .*[Dd]rive.* |
| cam_front | Camera | Body/camera_front |
Nifty (nifty)

| DoF | 12 |
| End Effector | None |
| Base Frame | chassis |
| Sensors | 3 |
| Action Modes | default: nifty |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
nifty * | Joint Velocity | 12 | joint_vel_wheel_drive=1.5707963267948966; joint_pos_steer=0.7853981633974483; joint_pos_suspension_yaw=0.5235987755982988; joint_pos_suspension_roll=0.2617993877991494 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| wheel_joints | wheel_joint_fl, wheel_joint_fr, wheel_joint_rl, wheel_joint_rr | 80 N·m | 1.570796 rad/s | 0 | 80 |
| steer_joints | steer_joint_fl, steer_joint_fr, steer_joint_rl, steer_joint_rr | 200 N·m | 0.523599 rad/s | 100 | 50 |
| suspension_joint_yaw | suspension_joint_yaw_f, suspension_joint_yaw_r | 200 N·m | 0.261799 rad/s | 1250 | 750 |
| suspension_joint_roll | suspension_joint_roll_f, suspension_joint_roll_r | 200 N·m | 0.261799 rad/s | 15000 | 5000 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | chassis |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | chassis |
Open Source Rover (open_source_rover)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | chassis |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.2, ang=0.3490658503988659 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| joint_wheel | joint_wheel_.* | 50 N·m | 40 rad/s | 0 | 2000 |
| joints_steer | joint_steer_.* | 500 N·m | 0.5 rad/s | 100 | 80 |
| joints_rocker | joint_rocker_.* | 1500 N·m | 0.3 rad/s | 25 | 2 |
| joints_bogie | joint_bogie_.* | 750 N·m | 0.6 rad/s | 1 | 4 |
| joint_linkage | joint_linkage | 25 N·m | 0.2 rad/s | 0.05 | 0.1 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | chassis |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | chassis/camera_front |
Perseverance (perseverance)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | body |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.7, ang=1.3089969389957472 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| drive_joints | drive_joint.* | 150 N·m | 40 rad/s | 0 | 25000 |
| steer_joints | steer_joint.* | 400 N·m | 2 rad/s | 500 | 200 |
| rocker_joints | suspension_joint_rocker.* | 2500 N·m | 5 rad/s | 4000 | 400 |
| bogie_joints | suspension_joint_bogie.* | 500 N·m | 4 rad/s | 200 | 25 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | body |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | body/camera_front |
Pragyan (pragyan)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | body |
| Sensors | 3 |
| Action Modes | default: drive |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.35, ang=1.3962634015954636 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| drive_joints | wheel_drive_joint_.* | 150 N·m | 40 rad/s | 0 | 5000 |
| rocker_joints | rocker_joint_.* | 2500 N·m | 5 rad/s | 1000 | 400 |
| bogie_joints | boogie_joint_.* | 500 N·m | 4 rad/s | 250 | 200 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | body |
| contacts_wheels | Contact Sensor | .*wheel.* |
| cam_front | Camera | body/camera_front |
Raph Rover (raph_rover)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | chassis |
| Sensors | 3 |
| Action Modes | 2 (default: drive) |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
drive * | Wheeled Drive | 2 | lin=0.4, ang=1.0471975511965976 |
drive_filtered | Filtered Wheeled Drive | 2 | lin=0.4, ang=1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| drive | drive_joint_.* | 80 N·m | 30 rad/s | 0 | 500 |
| steer | steer_joint_.* | 500 N·m | 2 rad/s | 400 | 50 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | chassis |
| contacts_wheels | Contact Sensor | wheel.* |
| cam_front | Camera | chassis/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.

Combined Platforms
Generic Aerial Manipulator (generic_aerial_manipulator)
| DoF | runtime-resolved |
| End Effector | None |
| Sensors | 0 |
| Action Modes | – |
Generic Ground Manipulator (generic_ground_manipulator)
| DoF | runtime-resolved |
| End Effector | None |
| Sensors | 0 |
| Action Modes | – |
Generic Orbital Manipulator (generic_orbital_manipulator)
| DoF | runtime-resolved |
| End Effector | None |
| Sensors | 0 |
| Action Modes | – |
Humanoids
Humanoid21 (humanoid21)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | pelvis |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| body | .* | – | – | 2–20 | 0.1–5 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | pelvis |
| contacts_feet | Contact Sensor | (left|right)_foot |
| cam_front | Camera | pelvis/camera_front |
Humanoid28 (humanoid28)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | pelvis |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| body | .* | – | – | – | – |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | pelvis |
| contacts_feet | Contact Sensor | (left|right)_foot |
| cam_front | Camera | pelvis/camera_front |
Unitree G1 (unitree_g1)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | pelvis |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| legs | .*_hip_yaw_joint, .*_hip_roll_joint, .*_hip_pitch_joint, .*_knee_joint, torso_joint | 300 N·m | 100 rad/s | 150–200 | 5 |
| feet | .*_ankle_pitch_joint, .*_ankle_roll_joint | 20 N·m | – | 20 | 2 |
| 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_joint | 300 N·m | 100 rad/s | 40 | 10 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | pelvis |
| contacts_feet | Contact Sensor | (left|right)_ankle_roll_link |
| cam_front | Camera | pelvis/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*_hip_pitch_joint | -0.2 rad (-11.459156 deg) |
.*_knee_joint | 0.42 rad (24.064227 deg) |
.*_ankle_pitch_joint | -0.23 rad (-13.178029 deg) |
.*_elbow_pitch_joint | 0.87 rad (49.847328 deg) |
| left_shoulder_roll_joint | 0.16 rad (9.167325 deg) |
| left_shoulder_pitch_joint | 0.35 rad (20.053523 deg) |
| right_shoulder_roll_joint | -0.16 rad (-9.167325 deg) |
| right_shoulder_pitch_joint | 0.35 rad (20.053523 deg) |
| left_one_joint | 1 rad (57.29578 deg) |
| right_one_joint | -1 rad (-57.29578 deg) |
| left_two_joint | 0.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)

| DoF | runtime-resolved |
| End Effector | None |
| Base Frame | pelvis |
| Sensors | 3 |
| Action Modes | default: joint_pos |
Action Modes
| Mode | Controller | Dims | Scale |
|---|---|---|---|
joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
Actuators
| Group | Joints | Effort | Velocity | Stiffness | Damping |
|---|---|---|---|---|---|
| legs | .*_hip_yaw, .*_hip_roll, .*_hip_pitch, .*_knee, torso | 300 N·m | 100 rad/s | 150–200 | 5 |
| feet | .*_ankle | 100 N·m | 100 rad/s | 20 | 4 |
| arms | .*_shoulder_pitch, .*_shoulder_roll, .*_shoulder_yaw, .*_elbow | 300 N·m | 100 rad/s | 40 | 10 |
Sensors
| Name | Type | Location |
|---|---|---|
| imu_robot | Imu | pelvis |
| contacts_feet | Contact Sensor | (left|right)_ankle_link |
| cam_front | Camera | pelvis/camera_front |
Initial Joint Configuration
| Joint | Position |
|---|---|
.*_hip_yaw | 0.0 rad |
.*_hip_roll | 0.0 rad |
.*_hip_pitch | -0.28 rad (-16.042818 deg) |
.*_knee | 0.79 rad (45.263666 deg) |
.*_ankle | -0.52 rad (-29.793805 deg) |
| torso | 0.0 rad |
.*_shoulder_pitch | 0.28 rad (16.042818 deg) |
.*_shoulder_roll | 0.0 rad |
.*_shoulder_yaw | 0.0 rad |
.*_elbow | 0.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.

Construction Blocks
Lego Block 1X1 (lego_block_1x1)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Lego Block 1X2 (lego_block_1x2)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Lego Block 1X3 (lego_block_1x3)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Lego Block 1X4 (lego_block_1x4)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Lego Block 2X2 (lego_block_2x2)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Lego Block 2X3 (lego_block_2x3)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Lego Block 2X4 (lego_block_2x4)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Random Lego Block (random_lego_block)

| Type | modular_element |
| Variant | Dataset |
| Collision | sdf |
| Density | 800 kg/m³ |
Geological Samples
Apollo Sample (apollo_sample)

| Type | common |
| Variant | Dataset |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Asteroid (asteroid)

| Type | common |
| Variant | Procedural |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Lunalab Boulder (lunalab_boulder)

| Type | common |
| Variant | Dataset |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Mars Rock (mars_rock)

| Type | common |
| Variant | Procedural |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Moon Rock (moon_rock)

| Type | common |
| Variant | Procedural |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Random Rock (random_rock)

| Type | common |
| Variant | Procedural |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Sample Tube (sample_tube)

| Type | common |
| Variant | Dataset |
| Collision | convexDecomposition |
| Density | 1500 kg/m³ |
Spaceport Moon Rock (spaceport_moon_rock)

| Type | common |
| Variant | Dataset |
| Collision | convexHull |
| Density | 2000 kg/m³ |
Hardware
Bolt M8 (bolt_m8)

| Type | common |
| Variant | Dataset |
| Collision | sdf |
Bolt M8 Tight (bolt_m8_tight)

| Type | common |
| Variant | Dataset |
| Collision | sdf |
Hole (hole)

| Type | common |
| Variant | Procedural |
| Collision | – |
Nut M8 (nut_m8)

| Type | common |
| Variant | Dataset |
| Collision | – |
Nut M8 Tight (nut_m8_tight)

| Type | common |
| Variant | Dataset |
| Collision | – |
Peg (peg)

| Type | common |
| Variant | Procedural |
| Collision | sdf |
| Density | 1000 kg/m³ |
Profile Hole (profile_hole)

| Type | common |
| Variant | Dataset |
| Collision | – |
Profile Peg (profile_peg)

| Type | common |
| Variant | Dataset |
| Collision | boundingCube |
| Density | 1000 kg/m³ |
Short Profile Peg (short_profile_peg)

| Type | common |
| Variant | Dataset |
| Collision | boundingCube |
| Density | 1000 kg/m³ |
Other
Beam (beam)

| Type | common |
| Variant | Primitive |
| Collision | – |
| Density | 250 kg/m³ |
Beneficiation Unit (beneficiation_unit)

| Type | common |
| Variant | Dataset |
| Collision | convexDecomposition |
| Density | 1000 kg/m³ |
Cargo Bay (cargo_bay)

| Type | payload |
| Variant | Dataset |
| Collision | convexDecomposition |
| Density | 1000 kg/m³ |
Husky Payload Lunalab (husky_payload_lunalab)

| Type | payload |
| Variant | Dataset |
| Collision | – |
| Density | 500 kg/m³ |
Industrial Pedestal100 (industrial_pedestal100)

| Type | pedestal |
| Variant | Dataset |
| Collision | – |
Industrial Pedestal25 (industrial_pedestal25)

| Type | pedestal |
| Variant | Dataset |
| Collision | – |
Industrial Pedestal50 (industrial_pedestal50)

| Type | pedestal |
| Variant | Dataset |
| Collision | – |
Projector Light (projector_light)

| Type | light |
| Variant | Dataset |
| Collision | – |
Raph Shovel (raph_shovel)

| Type | payload |
| Variant | Dataset |
| Collision | – |
Primitive Shapes
Random Shape (random_shape)

| Type | common |
| Variant | Primitive |
| Collision | – |
| Density | 1000 kg/m³ |
Structures & Containers
Solar Panel (solar_panel)

| Type | common |
| Variant | Dataset |
| Collision | sdf |
| Density | 500 kg/m³ |
Scenery
Environmental scenery registered in the Space Robotics Bench includes terrains, facilities, and other scene elements.

Facilities
Iss Gateway Scenery (iss_gateway_scenery)

| Type | extravehicular |
| Variant | Dataset |
| Domains | orbit |
| Sub-assets | iss, 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)

| Type | intravehicular |
| Variant | Dataset |
| Domains | orbit |
| Sub-assets | lamp |
Zeroglab (zeroglab)

| Type | intravehicular |
| Variant | Dataset |
| Domains | orbit |
| Sub-assets | lamp |
Terrain
Ground Plane (ground_plane)

| Type | terrain |
| Variant | Primitive |
| Domains | asteroid, earth, mars, moon |
Lunalab (lunalab)

| Type | subterrane |
| Variant | Dataset |
| Domains | asteroid, earth, mars, moon |
| Sub-assets | terrain, lamp, boulder |
Lunar Site Apollo15 (lunar_site_apollo15)
| Type | terrain |
| Domains | moon |
Lunar Site Apollo17 (lunar_site_apollo17)
| Type | terrain |
| Domains | moon |
Mars Surface (mars_surface)

| Type | terrain |
| Domains | mars |
Martian Site Jezero (martian_site_jezero)
| Type | terrain |
| Domains | mars |
Martian Site Jezero V2 (martian_site_jezero_v2)
| Type | terrain |
| Domains | mars |
Moon Surface (moon_surface)

| Type | terrain |
| Domains | moon |
Oberpfaffenhofen (oberpfaffenhofen)

| Type | terrain |
| Variant | Dataset |
| Domains | asteroid, earth, mars, moon |
Plane (plane)

| Type | terrain |
| Variant | Primitive |
| Domains | asteroid, earth, mars, moon |
| Sub-assets | obstacle |
Terrain Generator (terrain_generator)
| Type | terrain |
| Domains | asteroid, earth, mars, moon |
Integrations & Interfaces
Choose an integration to connect SRB to a framework or tool:
- ROS 2 & Space ROS - Connect with robotics tools and libraries.
- Reinforcement Learning (RL) - Train and evaluate policies with popular RL algorithms.
- Imitation Learning (IL) - Learn policies from demonstrations.
- Extended Reality (XR) - Launch and render XR; headset use is not tested.
Next: Reinforcement Learning
Integration — Reinforcement Learning
Start training with these steps:
- Install SRB.
- Complete Basic Usage.
- Follow the RL Workflow to train and evaluate an agent.
- 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 withoptional_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:
- Collect demonstrations with
srb agent collect, or use an existing dataset in the robomimic-compatible HDF5 format. - Train with
srb agent learn --datasetand arobomimic_*algorithm. See the learning reference. - 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, anddonesdatasets, plus a per-episodesuccessattribute. - Observation keys use
<group>/<leaf>paths for SRB observation groups, such asstate/<leaf>,proprio/<leaf>,command/<leaf>, andstate_privileged/<leaf>when those groups are present. - Per-episode success flags support collection-time
--success_onlyfiltering.
Datasets from srb agent collect load directly in srb agent learn.
See Also
srb agent learn— train an IL policy- Reinforcement Learning Integration — complementary paradigm
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--xrcarries XR rendering settings.performance,balanced, andqualityselect 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_envsor set--rendering_mode performanceand use XR for inspection. - When collecting, cap long XR episodes with
srb agent collect --horizonto limit dataset length. - XR controllers are unsupported as teleoperation input.
See Also
srb agent teleop— core teleoperation commandsrb agent collect— record demonstrations- Imitation Learning Workflow
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
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.
-
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 -
Add
target_path(nav_msgs/msg/Path, published insource_frame) as an RViz Path display. -
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 defaultuses the environment default;--cfg ignore,none, ornulldisables the config file.
Tip: Dict-form asset shortcuts expand automatically:
env.robot=frankabecomesenv.robot.name=franka.
Key Parameters
Scenario/Environment
env.domain- Domainenv.ephemeris- Ephemerisenv.robot- Robotenv.scenery- Set a registry asset name, such asenv.scenery=moon_surface.- For asset-instance scenery, set fields such as
env.scenery.flat_area_size=3.0orenv.scenery.boulder_count=0. - If the task accepts a scenery variant (
Scenery | AssetVariant), you can also setbody,lat_deg,lon_deg, andsize_m. Setlat_deg,lon_deg, andsize_mto constructRealTerrain. The defaultbodyisenv.domain(moon,mars, orearth). - Fixed-type scenery, such as
terrain_landscaping’sPlane, accepts only that asset’s fields.
- For asset-instance scenery, set fields such as
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’srandomize_robot_staterange applies.env.num_envs,env.stack- Parallelismenv.particles- Particlesenv.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=trueforcesenv.scene.env_spacing=0.0; otherwise the framework appliesenv.spacingwhen set or inheritsenv.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=trueandenv.num_envs != 1, the framework forcesenv.stack=falseand logs a warning
srb agent rand -e _manipulation env.num_envs=16 env.stack=true
Note: Set
env.stack=falsefor visual observations or independent scenery. Defaults are task-specific. These task IDs useenv.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, andlanding. 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:
| Domain | Description |
|---|---|
moon [default] | Lunar surface |
mars | Martian surface |
earth | Earth surface |
asteroid | Low-gravity body |
orbit | Orbital 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 withsrb 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=...orenv.robot.payload=...in any CLI order. Set a single field with an override such asenv.robot.end_effector.<field>=.... - Set or clear asset fields explicitly when changing selectors.
srb agent evaland--continuereplay embodiment by reapplying.hydra/overrides.yaml, but values supplied in--cfgYAML can remain through a selector change. - Selecting a named top-level asset, such as
env.sample=moon_rock, resets it too. Selectingenv.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 agentorsrb real_agentinvocation rebuilds task config through Hydra.
extract_defaults_from_classserializes assets as{"name": ...}, withaction_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.AssetResolvercalls asset constructors with declared values formodel_post_initand the spawner. It also sends overrides such asenv.scenery.flat_area_size=3.0to 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
- Set
env.particles=true. - 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
| Parameter | Meaning | Default |
|---|---|---|
env.particles | Enable | false |
env.particles_systems | Independent systems per environment | 1 |
env.particles_spawner | Pile kernel: grid, pyramid, crater_pile, or mound_pile | grid |
env.particles_size | Diameter (m) | (0.01, 0.005) |
env.particles_area | Pile width relative to environment spacing | (0.75, 0.5) |
env.particles_ratio | Volume-fill ratio | (0.025, 0.1) |
env.particles_height | Integer stack height per system | (1, 10) |
env.particles_density | PBD density (kg/m³) | 1600.0 |
env.particles_friction | Particle friction coefficient | 1.0 |
env.particles_damping | Velocity damping | 0.2 |
env.particles_cohesion | Particle stickiness | 0.01 |
env.particles_adhesion | Surface stickiness | 0.05 |
env.particles_material | Advanced, non-scalar visual override (VisualMaterialCfg) | None |
env.particles_dim_xy | Grid count per system (dim_x = dim_y) | Derived (None) |
env.particles_init_pos | First-system position (x, y, z) | Derived (None) |
env.particles_freeze | Freeze after settling but keep rendering | false |
env.particles_conform_to_terrain | Snap to terrain without PBD settling | false |
env.particles_conform_jitter | Conforming XY scatter (m); 0 keeps a regular grid | 0.0 |
env.particles_pile_center_jitter | Settled-pile XY offset per reset (m); 0 disables | 0.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
| Randomization | Behavior |
|---|---|
env.particles_pile_center_jitter | Each 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 material | Each 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’sRewardCfgfor 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:
- Calls
advance_step_state()to update per-step state. - Calls
extract_step_return()to return current-state metrics in the task dictionary. - 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; useScaledRewardTermto 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 byweight; 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 byweight(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 Mode | Value | Behavior & Mathematics | Recommended 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.0can 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/config | Randomization | Delay | Noise | Provenance |
|---|---|---|---|---|
waypoint_navigation | target_pose_evolution, a tagged task event at a 0.05 s interval | Action (0, 3) and observation (0, 1) agent steps; per-reset draws use env.seed | Waypoint-relative observation noise: 0.01 m / 2.5° episode bias plus 0.0025 m / 0.5° per-step noise | Task defaults; uncalibrated |
locomotion_waypoint_navigation | Inherits target_pose_evolution | Inherits action (0, 3) and observation (0, 1) agent steps | Inherits waypoint-relative observation noise: 0.01 m / 2.5° episode bias plus 0.0025 m / 0.5° per-step noise | Inherited waypoint task config; uncalibrated |
waypoint_navigation with env.sim_to_real_profile=waypoint_navigation_synthetic_v1 | Same target event | Action and observation (1, 2) agent steps, fixed for each episode; 25 Hz means 40–80 ms | Gaussian action noise, standard deviation 0.02 in normalized policy-action units; the waypoint observation noise above remains in metres and radians | synthetic_unmeasured |
| Other shipped task configs | Many define tagged or untagged event terms | No other task config enables nonzero action or observation delay | No default task config enables Isaac Lab action_noise_model or observation_noise_model | Per-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.
- Install the optional dependency for live queries:
pip install 'srb[spice]'(srb[all]also includes it). Coresrbomits it (wheel ~30 MB); missingspiceypyraisessrb.utils.extras.MissingExtraErrorwith this install command. - Fetch kernels with
srb ephemeris downloador let first use fetch them. Imported table queries need neither kernels norspiceypy; 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.
| File | Purpose | SHA-256 |
|---|---|---|
naif0012.tls | Leap seconds; current through 2016-12-31 | 678e32bdb5a744117a467cd9601cd6b373f0e9bc9bbde1371d5eee39600a039b |
pck00011.tpc | Radii, orientation, IAU_MARS/IAU_EARTH frames | 3dff7b1dbeceaa01f25467767d3fa25816051c85d162d1edf04acb310ee28bb1 |
de440s.bsp | Sun, Earth, Moon, Mars barycenter positions; 1849–2150 | c1c7feeab882263fc493a9d5a5b2ddd71b54826cdf65d8d17a76126b260a49f2 |
moon_pa_de440_200625.bpc | Lunar principal-axis orientation, MOON_ME frame | 60cd55aa401ea2ea97360636f567554bfe4e37bb829f901b4460a455dfaf783f |
moon_de440_250416.tf | Lunar MOON_ME frame aliases | a47c71e9c9f33796bdafb2c9d69a7ee447b6016ecad80f71cd6f3e479f9cf768 |
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
| Variable | Default | Effect |
|---|---|---|
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_FETCH | 1 (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_ID | unset | Hugging Face dataset repo id (org/name) tried before NAIF. Unset uses NAIF directly. |
SRB_EPHEMERIS_TABLE_PRODUCT | unset | Product 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.
-
In a real-terrain site manifest (
srb/terrain/manifest.yaml), setlighting: ephemeris, plus surfacecoordsand a curated UTCepoch:my_site: body: moon coords: { lat: 20.1908, lon: 30.7717 } lighting: ephemeris epoch: "1972-12-11T19:54:57" -
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.usdunderSRB_ASSETS_DIR_SRB_LIGHTS. The 16-hex SHA-256<identity>covers writer version, base/computed presets, coordinates, epoch, and grid-north correction. Immutable generations containlights.usdandidentity.json; identical requests reuse a slot, while changed inputs (includingLIGHTS_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.
-
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 -
Or sample an epoch uniformly on each reset; draws use
env.seedfor 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 option | Default | Behavior |
|---|---|---|
enabled | false | Opt-in gate; disabled path does not query or touch the scene. |
provider | "spice" | Live SPICE or imported "table" data. |
epoch | EpochSpec(utc="2026-11-01T12:00:00") | time_scale=0.0, update_interval_s=600.0. |
site | None | Observer site; precedence below. |
orbit | None | Required on Domain.ORBIT; invalid on surface domains. |
bodies | ("sun",) | Requested bodies; must include Sun. |
drive_sunlight | true | When 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_skydome | false | See Skydome co-drive; requires drive_sunlight=true. |
expose_observations | false | Adds the Direct observation vector; see Observation vector. |
eclipse | false | Scales 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):
- Explicit
env.ephemeris.sitewins. Its body must match surfaceenv.domain(else build raises); in orbit mode it selects the central body. - Otherwise, matching-body
RealTerrainwith a curated manifestsitesuppliescoordsand persisted convergence asSiteSpec.north_yaw_deg = −γ(active/passive equivalent of terrain’saz_grid = az_true + γ). A body mismatch ignores terrain with a warning. - 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 field | Default | Meaning and limit |
|---|---|---|
altitude_m | required | Above mean body radius; must be > 0. |
inclination_deg | 0.0 | Must be in [0, 180]. |
raan_deg | 0.0 | Right ascension of ascending node. |
arg_lat_deg | 0.0 | Angle 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.
| Domain | Occluder / behavior |
|---|---|
ORBIT | Central body synthesized from propagated observer position; no extra SPICE query. |
MOON surface | Earth. Earth geometry is optional unless explicitly listed in env.ephemeris.bodies; absent optional geometry disables eclipse with a warning. |
MARS/EARTH surface | No 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):
| Slots | Values |
|---|---|
0:3 | Sun unit direction in robot base frame (inverse xyzw quaternion rotation). |
3:6 | Occluder unit direction in base frame; zero if no active occluder (eclipse off or none modeled). |
6:7 | Eclipse 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 / behavior | Default or limit |
|---|---|
SRB_TERRAIN_CATALOG_DIR | Replaces shipped catalogs with a hand-built catalog directory. |
SRB_TERRAIN_CACHE_ROOT | Overrides 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 identity | Named 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. |
| Cleanup | Raw 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 admission | YAML 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 values | Antimeridian 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 fetch | Consent 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
| Body | Layers 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/.IMGpair from HTTPS-onlyimbrium;cap:50Sis 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:
| Provider | Body | Allowed hosts | Auth |
|---|---|---|---|
pgda | moon | pgda.gsfc.nasa.gov | none |
lroc_pds | moon | pds.lroc.im-ldi.com, data.lroc.im-ldi.com, pds.shadowcam.im-ldi.com, pds.mcp.nasa.gov | none |
zenodo | moon | zenodo.org, www.zenodo.org | none |
imbrium | moon | imbrium.mit.edu | none |
usgs_astro | moon, mars | astrogeo-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.gov | none |
copernicus_s3 | earth | copernicus-dem-30m.s3.amazonaws.com, copernicus-dem-90m.s3.amazonaws.com | none |
usgs_3dep | earth | prd-tnm.s3.amazonaws.com | none |
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
- Configure
RealTerrainwith all three region fields; see region identity. - Preview coverage using
srb asset stack; see CLI. - Bake with
srb asset download terrainor use the sameRealTerrainconfig 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.
| Body | South polar | North polar | Geographic |
|---|---|---|---|
| moon | IAU_2015:30135 | IAU_2015:30130 | IAU_2015:30100 |
| mars | IAU_2015:49935 | IAU_2015:49930 | IAU_2015:49900 |
| earth | EPSG:3031 | EPSG:3413 | EPSG: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:
| Consumer | Outcome |
|---|---|
RealTerrain environment | Warn 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
| Aspect | Behavior |
|---|---|
| Primary patch | Index 0 is requested center verbatim (or locations[0]). primary_baked_usd_path anchors companions, SimForge augmentation, and other single-path readers. |
| Derivation | Indexes 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 stability | RNG does not depend on K; increasing K preserves earlier derived slugs and cache entries. |
| Uniqueness | All 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. |
| Spawning | K=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 cost | All 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 budget | Region 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.
| Surface | Setting |
|---|---|
| Manifest | Site deshade: true in srb/terrain/manifest.yaml. |
| Python | RealTerrain(..., 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.
Consent
| Request | Requirement 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_remote | Gate full size_bytes, as full source downloads; see Current limits. |
| Region request | Same gate for each source’s bytes. |
| v1 manifest site | Site 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 / condition | Effect |
|---|---|
1. env.ephemeris.enabled and drive_sunlight | Ephemeris owns sun; suppress companion lighting (warn once). If drive_skydome, suppress companion sky. Rocks attach. |
| 2. Otherwise, companion lighting exists | Companion 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 exists | Replace 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:
| Use | Behavior |
|---|---|
| Footprint search, default | Exclude synthetic before candidate selection; real layers resolve without warning. |
| Footprint search, admitted | Candidates 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_stack | Explicit 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
| Limit | Effect / remedy |
|---|---|
| Coverage is narrow | Few pinned products; see Catalog status per body. |
cog_remote | Compatibility 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 readers | Readers 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 lookup | Key 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,
--cfgreplaces the wholeagentmapping. 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.yamlfor 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,
)
| Field | Meaning |
|---|---|
resolution: (W, H) | Render size before crop/downsample; native IMX636 (1280, 720). |
roi_crop: (x, y, w, h)?; downsample: int | Pre-backend crop and integer downsampling factor; affects observations and stored events. |
preset_name: str | IMX636Preset, default imx636_nominal; explicit threshold/noise fields override it. |
sub_render_hz: float | Tick cap, default 250 Hz; see Render-rate guidance. |
representation: str; time_bins: int | voxel_grid, histogram, time_surface, stacked, or raw; grid defaults to T=5. |
event_chunk_rows: int | Transport 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: int | Provider timestamp/event/permutation workspace cap, default 1,048,576; separate from transport chunks. |
backend: str | Registered 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: float | Per-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):
| Preset | pos_thres | neg_thres | sigma_thres | cutoff_hz | shot_noise_rate_hz | Use case |
|---|---|---|---|---|---|---|
imx636_nominal | 0.20 | 0.20 | 0.03 | 50 | 5 | Generic indoor / orbital lighting. |
imx636_low_light | 0.20 | 0.20 | 0.05 | 20 | 20 | Lunar permanently-shadowed regions, deep night. |
imx636_outdoor_sunlit | 0.20 | 0.20 | 0.02 | 70 | 2 | Direct-sun Mars / lunar daylight. |
clean | 0.20 | 0.20 | 0.00 | 0 | 0 | Noise-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>".
| Backend | Module | Extra | License | Notes |
|---|---|---|---|---|
noop | srb.core.sensor.event_camera.backend.NoopBackend | Built-in | MIT | supports_batching=False; emits zero events for tests and does not consume RGB frames. |
v2e | srb.core.sensor.event_camera.backends.v2e.V2eBackend | srb[event-v2e] + pinned source | MIT (v2ecore) | Default, supports_batching=False; IMX636 noise, no interpolation, private RNG, episode-relative time. |
v2e_streaming | srb.core.sensor.event_camera.backends.v2e.V2eStreamingBackend | srb[event-v2e] + pinned source + local patch | MIT (v2ecore) | Bounded signal-only EventEmulator.iter_events; no shot-noise ordering claim. |
metavision | srb.core.sensor.event_camera.backends.metavision.MetavisionBackend | srb[event-metavision] | Apache-2.0 (openeb) | supports_batching=True; GPUEventSimulator from metavision_core_ml.event_simulator. |
v2ce | srb.core.sensor.event_camera.backends.v2ce.V2CEBackend | srb[event-v2ce] | MIT | supports_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:
| Representation | Output shape | Description |
|---|---|---|
voxel_grid | (B, T, H, W) float32 | Polarity-signed time_bins grid (default). |
histogram | (B, 2, H, W) float32 | Polarity-separated event counts. |
time_surface | (B, 2, H, W) float32 | Exponentially decayed age of last event, per polarity. |
stacked | (B, 2T, H, W) float32 | Per-polarity voxel grid stacked along channel. |
raw | (B, N, 4) int64 + (B,) int64 counts | Padded 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 class | Recommended 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 impact | 500 Hz |
| Landing touchdown, docking contact | 1000 Hz |
Recording during rollouts
-
Enable
eventsinenv.active_sensors(alias ofevent_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-eventsfails because the scene has no event camera. -
Run
srb agentwith--record-events(zero,rand,teleop,ros,train,eval,collect).BaseEnvCfgadds the camera,DirectEnvbinds it, and the recorder writes one file per env/episode/sensor under<run logdir>/camera_videos/<timestamp>/unlessenv.camera_record_diris 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:
landingandmoonfall(onboard, downward camera): random rollouts can record episodes without events; v2e logsno signal events generatedon every frame, and a longerlandingrollout 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 defaultobservation_window_eventsbound (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_trackingwithenv.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.
- Pass
--seed INTto 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
EventHDF5BackpressureErrorand 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:
| Check | Command | What it checks |
|---|---|---|
| Statistics | srb dataset validate-events stats | Event rate, polarity ratio, ISI distribution vs. real Gen4. |
| Reconstruction | srb dataset validate-events reconstruction | Reconstructed 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 value | Filename | Consumer |
|---|---|---|---|
| E2VID reconstruction | e2vid (default) | E2VID_lightweight.pth.tar (~41 MiB) | srb.datasets.event_validation.reconstruction.e2vid_reconstruct |
| V2CE learned simulator | v2ce | v2ce_3d.pt | srb.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.
| Mirror | Artifact | SHA256 |
|---|---|---|
hf-andrejorsula-e2vid | E2VID_lightweight.pth.tar | 4cfeb2c850bf48fc9fa907e969cb8a04e3c51314da2d65bdb81145ac96574128 |
hf-andrejorsula-v2ce | v2ce_3d.pt | 97920e0c3f3c1df55f12800c166bf1de11466f7546bdb7b40261c5a14cddef26 |
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:
- Fetch through
urllib.requestwithout consent interstitials or rate-limited redirects; verify withsrb event-camera fetch-weights --url <url> --sha256 <sha> --force. - Serve the exact upstream checkpoint. Give distinct
short_nameandartifact.namevalues for modified or retrained checkpoints. - Use a stable URL, not ephemeral or signed storage.
- Pin the maintainer-verified SHA256 of a known-good download.
- Record the upstream license in
license_note:rpg_e2vidpublished 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:
- Fetch through
urllib.requestwithout consent interstitials or expiring signed URLs; verify withsrb event-camera fetch-fixture --url <url> --sha256 <sha> --force. - Serve EVENT_HDF5 schema v1 with
EventEpisodeMetadatareproducibility attributes. Give modified or resampled captures distinctshort_nameandartifact.namevalues. - Pin the sensor model in
FixtureArtifact.sensor_model. - Use stable hosting (Zenodo, Hugging Face datasets, or an institutional research-data repository), not ephemeral or presigned storage.
- Pin the maintainer-verified SHA256 of a known-good download.
- Record capture licensing in
license_note(oftenCC-BY-4.0for 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
| Subcommand | Description |
|---|---|
agent | Agents |
real_agent | Generate/run sim-to-real bridge |
dataset | Inspect/validate/convert/replay/publish datasets |
model | Package/validate/publish policies |
list/ls | List assets, groups, environments |
asset/assets | Manage surface assets, rocks, sky-domes, lighting presets |
event-camera | Weights/backend metadata |
ephemeris | Query Sun/planet geometry; fetch SPICE kernels; import illumination |
cache | Regenerate caches |
gui | Launch the GUI |
isaac/isaacsim | Isaac Sim utilities (sim, python) |
doc/docs | Build docs; render thumbnails |
test | Run Python/Rust tests |
clean | Remove SRB / Isaac Sim / SimForge caches |
completions | Manage 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]:
| Subcommand | Purpose |
|---|---|
zero | Zero actions |
rand | Random actions |
teleop | Direct/trained-policy teleoperation |
ros | ROS 2 / Space ROS action topics |
train | Train RL policy |
eval | Evaluate policy |
collect | Record demos from human/policy/random/zero controllers |
learn | Offline imitation learning from demos |
tune | Optuna 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.
| Argument | Description | Default / limit |
|---|---|---|
-e/--env/--task ENV | Environment ID | Required |
--cfg PATH | Hydra YAML; DEFAULT/IGNORE/NONE/NULL recognized | DEFAULT |
--headless | No display | False |
--hide_ui | Hide most Isaac Sim UI; fullscreen | False |
--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_demo | unset (auto: demo uses quality) |
--xr | XR for VR/AR | False |
--enable_cameras | Render 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/--xr | False |
--kit_args=VALUE | Forward args to Omniverse Kit | "" |
--interface [IFACE …] | Enable interfaces gui/ros | [] |
--logdir/--logs PATH | Root logs | Checkout: logs/; installed: working-dir logs/ |
--video | Record video | False |
--record-events/--record_events | Record event-camera rollouts with provenance; requires event_camera (alias events) in env.active_sensors; container includes default v2e; see Event Camera | False |
--snapshot PATH | One rendered PNG after initial reset, then exit; implies --enable_cameras | unset |
--snapshot-warmup N | Render passes for path-traced/anti-aliased convergence; needs --snapshot | 16 |
--snapshot-settle N | Robot-settling physics steps; 0 disables; needs --snapshot | 0 |
--perf | Performance test instead of workflow | False |
--perf_output PATH | Report path (STDOUT); needs --perf | STDOUT |
--perf_duration SEC | Maximum duration (seconds); 0 = unlimited; needs --perf | 150.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-subcommand | Description |
|---|---|
srb event-camera fetch-weights | Download E2VID/V2CE weights; verify SHA256 |
srb event-camera list-mirrors | List registered E2VID + V2CE mirrors |
srb event-camera fetch-fixture | Download Gen4 HDF5 fixture; verify SHA256 |
srb event-camera list-fixtures | List registered Gen4 HDF5 mirrors |
srb event-camera backends | List registered generators; --detailed shows metadata |
Cache Subcommands
Offline completion/GUI caches:
| Sub-subcommand | Description |
|---|---|
srb cache update | Regenerate 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-subcommand | Description |
|---|---|
srb completions generate | Regenerate completion cache via srb cache update |
srb completions install | Install 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
| Argument | Description | Default |
|---|---|---|
| *categories | Categories: all, action, asset, env, scenery, object, robot. asset selects scenery, object, and robot. | [all] |
--live | Discover 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.
- After registration changes, run
srb ls --liveto 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 asenv.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,
--livetables 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_accaction 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
| Option | Description | Default |
|---|---|---|
--teleop_device [DEV …] | Interface (keyboard, spacemouse, ros, gamepad, haptic) | env default, else [keyboard] |
--pos_sensitivity VAL | Translation sensitivity | 1.0 |
--rot_sensitivity VAL | Rotation sensitivity (rad/s) | π (≈3.14) |
--invert_controls/--invert | In manipulation mode, flip the first two translational controls. Boolean optional forms --no-invert_controls and --no-invert disable inversion. | True |
| Teleoperation via Policy | ||
--algo ALGO | Algorithm of the policy (RL or IL) | |
--model MODEL | Path 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 checkpoint | state |
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
-
Train Dreamer on
locomotion_velocity_tracking:srb agent train --headless --algo dreamer -e locomotion_velocity_tracking env.num_envs=256 -
Teleoperate with it:
srb agent teleop --algo dreamer -e locomotion_velocity_tracking -
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.
| Option | Default | Behavior |
|---|---|---|
--ros_sync/--ros-sync | false | First 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 SECONDS | Wait indefinitely | Limit fresh-action waits with --ros_sync; on timeout, clear cached commands and apply zero. |
--ros_unthrottled/--ros-unthrottled | false | Disable 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
| Setting | Default | Behavior |
|---|---|---|
| Initial input wait | 5 seconds | Require valid first message before dispatch. |
| Command lifetime | 0.5 seconds | Check age before dispatch and each prepared hardware command. |
--ros_action_timeout SECONDS | Unset | Positive finite value overrides wait and lifetime. |
--ros_sync/--ros-sync | false | First step may use current sample; later steps await newer sample, aborting on expiry. |
--ros_unthrottled/--ros-unthrottled | false | Does not bypass expiry or RealEnv action rate. |
Examples
See ROS 2 Workflow.
srb agent train — Train Agent
Start or Resume a Run
- Choose an algorithm and environment.
- Add environment overrides after options.
- For replay prefill, see SKRL or Dreamer.
- 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
| Option | Default | Limits / behavior |
|---|---|---|
--algo ALGO | REQUIRED | RL algorithms only |
--obs {state,visual} | state | Selects the config and log tree (<algo> or <algo>-visual) and prevents cross-modality loading. visual is unsupported; see Agent Configuration. |
--continue_training, --continue | False | Resumes 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 PATH | unset | Resumes from the specified checkpoint. Support depends on the framework; TD-MPC2 imports weights only. |
--demo-dataset, --demo_dataset PATH | unset | Canonical SRB JSONL for skrl_sac, skrl_ddpg, skrl_td3, or dreamer; requires --demo-max-transitions. |
--demo-max-transitions, --demo_max_transitions N | unset | Positive cap on the complete source; requires --demo-dataset. |
Resume behavior by framework
| Framework | Behavior 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_ppo | Adds 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.
| Option | Default | Limits / behavior |
|---|---|---|
--model-artifact-output PATH | unset | Output artifact directory, after training succeeds |
--model-artifact-checkpoint PATH | unset | Checkpoint to package; absolute or run-directory-relative |
--model-artifact-task TASK | unset | Override task identity |
--model-artifact-embodiment NAME | unset | Override embodiment identity |
--model-artifact-action-mode MODE | unset | Override action-mode identity |
--model-artifact-framework NAME | unset | Override framework metadata |
--model-artifact-dataset PATH | unset | Dataset manifest, artifact directory, or file for provenance and identity inference |
--model-artifact-dataset-repo-id ID | unset | Training dataset repository id |
--model-artifact-dataset-revision REVISION | unset | Training dataset revision |
--model-artifact-repo-id ID | unset | Override 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
| Option | Description | Default |
|---|---|---|
--algo ALGO | Algorithm. Loads latest standard-log checkpoint unless --model is set. | unset |
--model PATH | Checkpoint 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, andn_episodes. - Metrics:
mean_return,success_rate,successes, andfailures. - Run state:
complete,incomplete,steps,max_steps, andstop_reason. - Environment details:
num_envsandepisode_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
| Option | Description | Default |
|---|---|---|
--collector SOURCE | human, policy, random, or zero; defaults to policy with --algo/--model, else human. | inferred |
--num_episodes N | Episodes to collect. | 100 |
--horizon N | Max steps/episode. Horizon cuts and mid-episode simulator closes record the last row as truncated=True, done=True, not terminal success/failure. | 400 |
--success_only | Save successful demos only; see Tips. | False |
--teleop_device [DEV …] | keyboard, spacemouse, ros, gamepad, haptic. | env default, else [keyboard] |
--pos_sensitivity VAL | Translation sensitivity. | 1.0 |
--rot_sensitivity VAL | Rotation sensitivity. | π (≈3.14) |
--invert_controls/--invert | In manipulation, invert only the first two translational controls; --no-invert_controls/--no-invert disable. | True |
--algo ALGO | RL or imitation-learning policy algorithm. | — |
--model MODEL | Raw 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:
| Collection | Dataset directory |
|---|---|
| Human, random, zero | logs/<env_id>/collect/<timestamp>/datasets/ |
| Policy | Resolved 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
| Option | Description | Default |
|---|---|---|
-e/--env/--task ENV | Environment ID for logs/specs | REQUIRED |
--cfg PATH | YAML whose agent section overrides the algorithm config | DEFAULT (none) |
--algo ALGO | Imitation-learning algorithm | REQUIRED |
--dataset PATH | Optional HDF5 demos; omission searches new run directory, errors if none | None |
--num_epochs N | Epoch count | Algo default |
--normalize_actions | Normalize dataset actions | False |
--logdir/--logs | Output root | logs/ 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.
| Algorithm | Description |
|---|---|
robomimic_bc | Behavioral Cloning (MLP) |
robomimic_bc_rnn | BC with RNN policy |
robomimic_bc_transformer | BC with Transformer policy |
robomimic_bcq | Batch-Constrained Q-Learning |
robomimic_cql | Conservative Q-Learning |
robomimic_iql | Implicit Q-Learning |
robomimic_td3_bc | TD3 with BC regularization |
robomimic_gl | Goal-conditioned learning |
robomimic_hbc | Hierarchical BC |
robomimic_iris | IRIS (latent skill discovery) |
robomimic_diffusion_policy | Diffusion Policy |
See Robomimic algorithm documentation for hyperparameters.
Note:
hyperparams/robomimic/bcq.jsonandiris.jsondisable 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:
| Options | Default or limit |
|---|---|
-e/--env/--task, --tasks | Choose one task or portfolio; pass either --env/--task or --tasks, not both. |
--algo | Required. |
--obs, --trial-steps | --trial-steps required. |
--pin, --trial-num-envs, --seed-base, --seeds-per-trial, --normalize, --aggregate, --objective, --fps, --n-trials, --n-workers, --version, --logdir | See 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
| Option | Default or limit |
|---|---|
-e/--env/--task ENV | Single task; mutually exclusive with --tasks |
--tasks T [T …] | Portfolio; mutually exclusive with -e/--env/--task |
--algo ALGO | REQUIRED; e.g. skrl_ppo |
--obs {state,visual} | state; visual is unsupported |
--trial-steps N | REQUIRED; env-step budget per trial and task segment |
--n-trials N | 20; terminal and RUNNING trials count on resume |
--n-workers N | 1 concurrent trial slots |
--gpus 0,1 | Unset inherits environment/framework default; otherwise round-robin |
--trial-num-envs N | 1024; pinned parallel envs, drives budget conversion |
--seed-base N | 42 |
--seeds-per-trial K | 1 |
--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 N | 10; 15 for portfolio |
--boot-stagger S | 30 if --n-workers > 1, else 0; skipped after first child emits metrics |
--keep-artifacts | False; PRUNED child logdirs removed; trial_cfg.yaml and metrics.jsonl survive |
--retry-failed N | 0; retry up to N FAILed sets except reason=timeout; raise --n-trials to run them |
--version N | 1; bump for an incompatible rerun |
--logdir/--logs | logs/tune |
--storage URL | Journal 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.
| Option | Default or limit |
|---|---|
-e/--env/--task, --tasks | —; tasks to baseline |
--algo ALGO | REQUIRED |
--obs {state,visual} | state |
--budget/--ref-steps N | REQUIRED; reference env-steps equal trial budget |
--floor-steps N | 200000 random-rollout env-steps |
--trial-num-envs N | 1024; pinned parallel envs, drives budget conversion |
--seed-base N | 42; task k uses seed-base + k |
--gpus 0,1 | Unset inherits environment/framework default; otherwise round-robin |
--objective {ep_return_mean,success_rate} | ep_return_mean |
--trial-timeout S | — |
--force, --dry-run | False; overwrite entries / compute without writing baselines.yaml |
--logdir/--logs PATH | logs/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.
- Capture floor/ref baselines for the task set.
- Run the portfolio study normalized against those baselines.
- 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:
| Framework | Labels |
|---|---|
| skrl | skrl_ppo; skrl_sac; skrl_ppo_rnn |
| stable-baselines3 | sb3_ppo, sb3_sac, sb3_tqc, sb3_td3, sb3_crossq |
| sbx (JAX SB3) | sbx_ppo, sbx_sac, sbx_tqc, sbx_td3, sbx_crossq |
| rsl_rl | rsl_rl_ppo |
| DreamerV3 | dreamer |
| TD-MPC2 | tdmpc2 |
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).
| Option | Default or limit |
|---|---|
--study NAME | REQUIRED |
--storage URL | journal default; PostgreSQL Optuna URL |
--top-k K | 3 trials by training value |
--seeds S | 3 fresh seeds per candidate, averaged |
--seed-base B | 10000; seed = B + i; keep B through B+S-1 clear of training seeds |
--min-ok N | Majority of --seeds COMPLETEd seeds |
--validate-steps N | Study budget (env-steps); raise for higher fidelity |
--gpus 0,1 | Unset inherits environment/framework default; otherwise round-robin |
--n-workers N | 1 concurrent rerun slots |
--trial-timeout S | —; kill reruns exceeding this many seconds |
--keep-artifacts | False |
--logdir/--logs | logs/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
| Option | Applies to | Default or limit |
|---|---|---|
--study NAME | All | REQUIRED; e.g. srb-skrl_ppo-state-pick-v1 |
--storage URL | status, export, repair | journal default; PostgreSQL Optuna URL |
--logdir/--logs PATH | status, export, repair | logs/tune |
--trial (trial number or best) | export | best |
--to {task,global} | export | Study-dependent: task for single-task, global for portfolio; portfolio --to task is ambiguous and errors |
--dry-run | export | False; print diff without writing |
--force | export | False; overwrite existing file |
--stale-hours H | repair | 24; 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
- Hyperparameter Tuning Workflow — concepts and wall-clock estimates
srb agent train— the per-trial training subprocess- Agent Configuration — config layering and tuned-file locations
srb real_agent — Sim-to-Real Bridge
Subcommands
srb real_agent <action> [options]
| Action | Purpose |
|---|---|
gen, sim2real_gen | Generate Gymnasium counterpart (sim2real_gen alias). |
zero, rand | Zero/random actions. |
teleop, ros | Direct input; ROS 2 / Space ROS topics. |
train, eval | Train/evaluate hardware policy. |
collect | Human, policy, random, zero datasets. |
validate | Run hardware telemetry checks and report pass/fail. |
rebuild-summary | Rebuild summary.json / report.md. |
replay-twin | Compare session with baseline .rrd in Rerun. |
For simulation-side counterparts, see srb agent.
srb real_agent gen
-
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_mwOption Default / limit -e,--env,--taskENV_IDRequired; ALLselects cached non-template environments.--cfgPATHDEFAULT; Hydra valuesDEFAULT,IGNORE,NONE,NULL.--hardware,--hw[HW …][]keeps an existing module’sHARDWARE; e.g.ros_cmd_vel,ros_tf,ros_mw,ros_depth_heightmap,ros_imu.--checkFalse; deterministic freshness gate, described below.RealEnvGeneratorconverts the registered Gymnasium spec tosrb/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. -
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
RealEnvcheck 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:
| Option | Default / limit |
|---|---|
-e, --env, --task ENV | Required; environment under srb_real/. |
--cfg PATH | DEFAULT; Hydra YAML override. |
--hardware, --hw [HW …] | []; runtime hardware interfaces. |
--logdir, --logs PATH | logs/ in a source checkout or current working directory when installed. |
| Command | Options 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. |
train | RL --algo required (e.g. dreamer, tdmpc2, sbx_ppo); --continue_training (False) / --model (None). |
eval | Requires --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
-
Run validation with its YAML spec:
srb real_agent validate --spec SPEC_PATH [options]Option Default / limit --specPATHRequired; e.g. hyperparams/validation/excavation.yaml.--checkpointPATHNone; overridescheckpoint; raw path or SRB artifact.--episodesNNone; overridesn_episodes.--wandbFalse; enable optional Weights & Biases summary sink.--no-tensorboardFalse; disable TensorBoard scalar sink.--no-rerun-webFalse; disable viewer; local.rrdremains ifrerun.record_to_rrd=true(default), Rerun is installed and starts.--post-statusFalse; post pass/fail as a GitHub commit status; requires theghCLI.--storage-rootPATHlogs/real_validationin shipped specs.--dry-runFalse; validates spec and session setup, skips deployment checks and environment/policy factories; on successexit_code: 4(preflight_fail),pass_overall: false.Validation runs the generated environment and available policy reset hooks for each episode. The artifact manifest supplies
algoif the spec omits it or setsREQUIRED_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
-
Rebuild
summary.jsonandreport.mdafter spec, metric, or post-processing changes without rerunning hardware.SESSION_DIRmust containspec.yamland logged.jsonl/.rrdtelemetry:srb real_agent rebuild-summary SESSION_DIR
Replay against a baseline
-
Compare time-aligned hardware (
real solid) with simulation (sim ghost) in local Rerun:srb real_agent replay-twin --session SESSION_DIR --baseline BASELINE_RRD_PATHOption Meaning --sessionSESSION_DIRValidation session containing rollout.rrd.--baselineBASELINE_RRD_PATHBaseline .rrdcaptured 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
listandinfodiscover assets;doctordiagnoses them.downloadfetches assets;bakebakes a local DEM.clean,cache-stats, andprefetch-fixturesmanage caches;validate-manifestchecks manifests;stackpreviews offline.
Kind Choices
KIND | Assets |
|---|---|
terrain | Planetary DEMs/orthophotos. |
rocks | Procedural/photogrammetric sets. |
hdri | High Dynamic Range Image skydomes. |
lights | Curated 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.
| Option | Default or meaning |
|---|---|
--patch PATCH | default. |
--lod {low,medium,high} | medium. |
--patch-size SIZE | Float, meters. |
--center X,Y | Meters, e.g. 100.0,200.0. |
--no-ortho | Skip orthophoto check/generation. |
--seed SEED | Procedural seed, 0. |
--deshade | Corrected 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.
| Option | Default or meaning |
|---|---|
TARGET | Asset; omit with --all or region. |
--all | Fetch/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 PATCH | Default default. |
--lod {low,medium,high} | Default medium. |
--patch-size SIZE | Float, meters. |
--center X,Y | Meters. |
--no-ortho | Skip orthophoto baking. |
--seed SEED | Procedural seed, default 0. |
--lat LAT --lon LON --size-m SIZE | Region: coordinates in degrees, size in meters; require all three; omit TARGET/--all. |
--deshade | Corrected terrain color; manifest deshading applies if omitted. |
--num-locations N | Region patches, default 1; above 1: deterministic offsets. |
--location-spread-m SIZE | Offset radius, meters; for --num-locations > 1, default is region size. |
--force | Re-download/re-bake valid cached entries. |
--debug | Verbose 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]
| Option | Default or meaning |
|---|---|
--dem DEM_PATH | User DEM path, absolute/relative (e.g. GeoTIFF). |
--body {moon,mars,earth} | Body. |
--site-name NAME | Custom-site name. |
--attribution ATTR | Metadata attribution string. |
--patch-size SIZE | Float, meters. |
--lod {low,medium,high} | Mesh LOD, default medium. |
--seed SEED | Procedural rock/displacement seed, default 0. |
--debug | Verbose mesh logs. |
srb asset clean
srb asset clean KIND [TARGET] [options]
| Argument/option | Default or meaning |
|---|---|
KIND | terrain, rocks, hdri, lights; only terrain supported. Others exit 2: clean: unsupported kind: '<kind>'; use 'terrain' |
TARGET | Optional; clean only its baked cache. |
--raw | Remove shared raw archives; omit target. |
--baked | Remove baked cache publications and their required files; raw archives remain unless --raw is also selected. |
--all | Remove 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]
| Option | Default or meaning |
|---|---|
--manifest MANIFEST_PATH | Custom YAML; default: packaged. |
--check-urls | HTTP-check mirrors and links. |
--check-shas | Check 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]
| Option | Default or meaning |
|---|---|
--body {moon,mars,earth} | Required body. |
--lat LAT, --lon LON | Required coordinates, degrees. |
--size-m SIZE (--size) | Region size in meters; max 8000 m; larger requests refused. |
--lod {low,medium,high} | medium. |
--target-gsd GSD | Target ground-sample distance, meters. |
--catalog PATH | YAML catalog override (mainly fixture testing). |
--allow-large | Shows the preview as if large downloads were approved; does not download. |
--deshade | Text preview reports the request; it does not resolve corrected output. |
--json | JSON 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
| Action | Purpose |
|---|---|
info | Print manifest, artifact hash and action-schema summaries (JSON). |
validate | Check manifest, files and declared physical counts; --deep checks rows/tables; --strict makes warnings errors. |
compatibility | Report learning, collection/eval or publication compatibility; --algo ALGO focuses on one algorithm, otherwise reports the matrix. |
export | Convert srb_jsonl to srb_jsonl, robomimic_hdf5 or lerobot, and robomimic_hdf5 to srb_jsonl or lerobot; lerobot is an export target only. |
pull | Download from Hugging Face Hub by --repo-id or --task/--embodiment/--action-mode; --dry-run plans without network access. |
push | Upload to Hugging Face or plan with --dry-run. |
card | Write a Hugging Face README.md dataset card. |
replay | Summarize canonical data or preview in Rerun (--backend rerun). |
from-validation | Convert 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
| Action | Purpose |
|---|---|
create CHECKPOINT --output OUT | Package one checkpoint. Requires --algo, plus --task, --embodiment, and --action-mode unless inferred from --dataset. |
from-run RUN --output OUT | Package 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 PATH | Print manifest JSON. |
validate PATH | Validate manifest, checkpoint, and bundled config paths; --strict makes warnings errors. |
card PATH | Generate a Hugging Face README.md model card; schema 3 artifacts bundle the canonical card without rewriting it. |
push PATH | Upload 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’sagentsection, thenmetadata.json’srun.agent_cfg. - SKRL checks
.hydra/config.yaml’sagentsection, thenmetadata.json’srun.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.
- Normalized runs require inventoried, hashed
- 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 value | Backend |
|---|---|
ptpython, 1, or true (case-insensitive) | ptpython |
bpython | bpython |
| Any other value | REPL stays off |
Explicit --repl takes precedence.
Note: Offline
srb agent learndoes not launch Isaac Sim, so it has no--reploption.
See Also
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
| Action | Purpose |
|---|---|
download | Fetches ~43 MB of pinned kernels (bundle). |
info | Prints body azimuth, elevation, distance, angular diameter, and irradiance scale. |
import | Imports illumination as an srb_illum/2 sidecar (Lunarlab/PGDA details). |
info Options
| Option | Required | Description |
|---|---|---|
--body {moon,mars,earth} | Yes | Observer. |
--lat LAT | Yes | Latitude, [-90, 90]°. |
--lon LON | Yes | Longitude, °. |
--alt ALT | No (default 0.0) | Height above mean radius, m. |
--utc UTC | Yes | ISO-8601 epoch; de440s: 1850–2149. |
--bodies BODIES | No (default sun,earth) | Choices: sun,earth,moon,mars,venus; Sun included; no duplicates/unknowns. |
import Options
| Option | Required | Description |
|---|---|---|
--source {lunarlab-zarr,lunarlab-npz,pgda-lpsr} | Yes | Format. |
--input PATH | Yes | Source. |
--baked-dir PATH | No | Target baked patch. |
--out PATH | Yes* | Output. |
--crs CRS | Yes* | Target CRS. |
--center-xy CX,CY | Yes* | Center. |
--size-m SIZE | Yes* | Patch size. |
--lat LAT / --lon LON | Yes* | Site coordinates. |
--gsd-m GSD | Yes* | Grid spacing. |
--epoch-range T0,T1 | No | UTC range. |
--epoch-stride N | No (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-moverrides it;--outoverrides the output path. Do not pass--lat/--lonwith 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
- Ephemeris Configuration: kernel bundle, environment variables, and the
query()API.
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=valueoverrides. 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:
| Option | Default |
|---|---|
| Rendering mode | quality |
| Teleop devices | keyboard spacemouse |
| Interface | gui |
Task-specific env.stack | Catalog 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-hand--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/srbwhen 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_landscapingtasks, for example, accept onlyRaphRoverwith theRaphShovelpayload and raiseTypeErrorfor 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.
| Task | Manipulator | Mobile Manipulator | Mobile 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.
| Robot | Mode | Controller | Dims | Scale |
|---|---|---|---|---|
| Canadarm3 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Canadarm3 | joint_pos_rel | Relative Joint Position | 7 | 1.0 |
| Franka | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Franka | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Franka | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Franka | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Franka | joint_pos_rel | Relative Joint Position | 7 | 1.0 |
| Kinova J2N6S | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Kinova J2N6S | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Kinova J2N7S | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Kinova J2N7S | joint_pos_rel | Relative Joint Position | 7 | 1.0 |
| Kinova Gen3N7 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Kinova Gen3N7 | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Kinova Gen3N7 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Kinova Gen3N7 | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Kinova Gen3N7 | smooth_osc | Smooth Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Kinova Gen3N7 | joint_pos_rel | Relative Joint Position | 7 | 1.0 |
| Levion Arms | dual_arm_joint_pos_abs * | Joint Position To Limits | 4 | 1.0 |
| So Arm100 D5 | diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
| So Arm100 D5 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.05, ori=0.05, stiffness=120.0 |
| So Arm100 D5 | joint_pos_rel | Relative Joint Position | 5 | 1.0 |
| So Arm100 D7 | diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
| So Arm100 D7 | joint_pos_rel | Relative Joint Position | 7 | 1.0 |
| Unitree Z1 | diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
| Unitree Z1 | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur3 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur3 | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur3 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur3 | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur3 | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur3E | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur3E | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur3E | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur3E | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur3E | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur5 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur5 | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur5 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur5 | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur5 | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur5E | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur5E | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur5E | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur5E | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur5E | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur10 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur10 | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur10 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur10 | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur10 | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur10E | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur10E | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur10E | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur10E | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur10E | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur16E | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur16E | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur16E | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur16E | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur16E | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur20 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur20 | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur20 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur20 | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur20 | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Ur30 | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Ur30 | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Ur30 | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Ur30 | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Ur30 | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Random Ur Manipulator | diff_ik * | Differential Inverse Kinematics | 6 | 0.1 |
| Random Ur Manipulator | osc_fixed | Operational Space Controller | 6 | pos=0.1, ori=0.1 |
| Random Ur Manipulator | osc_var_stiffness | Operational Space Controller | 12 | pos=0.1, ori=0.1, stiffness=120.0 |
| Random Ur Manipulator | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Random Ur Manipulator | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Vispa | diff_ik * | Differential Inverse Kinematics | 6 | 0.05 |
| Vispa | osc_var_full | Operational Space Controller | 18 | pos=0.1, ori=0.1, stiffness=120.0, damping=1.0 |
| Vispa | joint_pos_rel | Relative Joint Position | 6 | 1.0 |
| Zeroglab Arms | dual_arm_osc * | Operational Space Controller | 24 | arm_ceiling: pos=0.1, ori=0.1, stiffness=120.0; arm_wall: pos=0.1, ori=0.1, stiffness=120.0 |
| Humanoid21 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Humanoid28 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Unitree H1 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Unitree G1 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Crazyflie | body_acc * | Multicopter Body Acceleration | 4 | 0.5 |
| Ingenuity | body_acc * | Multicopter Body Acceleration | 4 | 0.5 |
| Heron | thrust * | Thrust | 2 | 1.0 |
| Anymal C | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Anymal D | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Random Anymal Quadruped | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Cadre | drive * | Wheeled Drive | 2 | lin=0.4, ang=0.7853981633974483 |
| Cassie | joint_pos * | Joint Position To Limits | 12 | 1.0 |
| Husky | drive * | Wheeled Drive | 2 | lin=0.1, ang=0.7853981633974483 |
| Leo Rover | drive * | Wheeled Drive | 2 | lin=0.4, ang=1.0471975511965976 |
| Mars Rover | drive * | Wheeled Drive | 2 | lin=0.5, ang=0.7853981633974483 |
| Nifty | nifty * | Joint Velocity | 12 | joint_vel_wheel_drive=1.5707963267948966; joint_pos_steer=0.7853981633974483; joint_pos_suspension_yaw=0.5235987755982988; joint_pos_suspension_roll=0.2617993877991494 |
| Open Source Rover | drive * | Wheeled Drive | 2 | lin=0.2, ang=0.3490658503988659 |
| Perseverance | drive * | Wheeled Drive | 2 | lin=0.7, ang=1.3089969389957472 |
| Pragyan | drive * | Wheeled Drive | 2 | lin=0.35, ang=1.3962634015954636 |
| Raph Rover | drive * | Wheeled Drive | 2 | lin=0.4, ang=1.0471975511965976 |
| Raph Rover | drive_filtered | Filtered Wheeled Drive | 2 | lin=0.4, ang=1.0 |
| Spot | joint_pos * | Joint Position | runtime-resolved | 0.2 |
| Unitree A1 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Unitree Go1 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Unitree Go2 | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Random Unitree Quadruped | joint_pos * | Joint Position To Limits | runtime-resolved | 1.0 |
| Floating Platform | thrust_only * | Thrust | 8 | 1.0 |
| Floating Platform | thrust_and_reaction | Thrust | 9 | thrust=1.0; reaction_wheel_torque=0.05 |
| Int Ball1 | thrust * | Thrust | 6 | 1.0 |
| Int Ball2 | thrust * | Thrust | 6 | 1.0 |
| Apollo Lander | thrust * | Thrust | 17 | 1.0 |
| Peregrine Lander | thrust * | Thrust | 17 | 1.0 |
| Vikram Lander | thrust * | Thrust | 13 | 1.0 |
| Resilience Lander | thrust * | Thrust | 9 | 1.0 |
| Random Lander | thrust * | Thrust | 3 | 1.0 |
| Iss | body_acc * | Body Acceleration | 6 | 2.5 |
| Gateway | body_acc * | Body Acceleration | 6 | 2.5 |
| Cubesat | thrust * | Thrust | 12 | 1.0 |
| Satellite Mockup | thrust * | Thrust | 12 | 1.0 |
| Venus Express | thrust * | Thrust | 19 | 1.0 |
| Starship | thrust * | Thrust | 18 | 1.0 |
| Super Heavy | thrust * | Thrust | 59 | 1.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).
| Robot | Sensor Name | Type | Location |
|---|---|---|---|
| Canadarm3 | contacts_robot | Contact Sensor | .* |
| Canadarm3 | cam_base | Camera | canadarm3_large_0/camera_base |
| Canadarm3 | cam_wrist | Camera | canadarm3_large_7/camera_wrist |
| Franka | contacts_robot | Contact Sensor | .* |
| Franka | cam_base | Camera | panda_link0/camera_base |
| Franka | cam_wrist | Camera | panda_link7/camera_wrist |
| Kinova J2N6S | contacts_robot | Contact Sensor | .* |
| Kinova J2N6S | cam_base | Camera | j2n6s_link_base/camera_base |
| Kinova J2N6S | cam_wrist | Camera | j2n6s_link_6/camera_wrist |
| Kinova J2N7S | contacts_robot | Contact Sensor | .* |
| Kinova J2N7S | cam_base | Camera | j2n7s_link_base/camera_base |
| Kinova J2N7S | cam_wrist | Camera | j2n7s_link_7/camera_wrist |
| Kinova Gen3N7 | contacts_robot | Contact Sensor | .* |
| Kinova Gen3N7 | cam_base | Camera | base_link/camera_base |
| Kinova Gen3N7 | cam_wrist | Camera | end_effector_link/camera_wrist |
| So Arm100 D5 | contacts_robot | Contact Sensor | .* |
| So Arm100 D5 | cam_base | Camera | Base/camera_base |
| So Arm100 D5 | cam_wrist | Camera | Fixed_Gripper/camera_wrist |
| So Arm100 D7 | contacts_robot | Contact Sensor | .* |
| So Arm100 D7 | cam_base | Camera | Base/camera_base |
| So Arm100 D7 | cam_wrist | Camera | End_Servo/camera_wrist |
| Unitree Z1 | contacts_robot | Contact Sensor | .* |
| Unitree Z1 | cam_base | Camera | link00/camera_base |
| Unitree Z1 | cam_wrist | Camera | link06/camera_wrist |
| Ur3 | contacts_robot | Contact Sensor | .* |
| Ur3 | cam_base | Camera | base_link/camera_base |
| Ur3 | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur3E | contacts_robot | Contact Sensor | .* |
| Ur3E | cam_base | Camera | base_link/camera_base |
| Ur3E | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur5 | contacts_robot | Contact Sensor | .* |
| Ur5 | cam_base | Camera | base_link/camera_base |
| Ur5 | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur5E | contacts_robot | Contact Sensor | .* |
| Ur5E | cam_base | Camera | base_link/camera_base |
| Ur5E | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur10 | contacts_robot | Contact Sensor | .* |
| Ur10 | cam_base | Camera | base_link/camera_base |
| Ur10 | cam_wrist | Camera | ee_link/camera_wrist |
| Ur10E | contacts_robot | Contact Sensor | .* |
| Ur10E | cam_base | Camera | base_link/camera_base |
| Ur10E | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur16E | contacts_robot | Contact Sensor | .* |
| Ur16E | cam_base | Camera | base_link/camera_base |
| Ur16E | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur20 | contacts_robot | Contact Sensor | .* |
| Ur20 | cam_base | Camera | base_link/camera_base |
| Ur20 | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Ur30 | contacts_robot | Contact Sensor | .* |
| Ur30 | cam_base | Camera | base_link/camera_base |
| Ur30 | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Random Ur Manipulator | contacts_robot | Contact Sensor | .* |
| Random Ur Manipulator | cam_base | Camera | base_link/camera_base |
| Random Ur Manipulator | cam_wrist | Camera | wrist_3_link/camera_wrist |
| Vispa | contacts_robot | Contact Sensor | .* |
| Vispa | cam_base | Camera | link0/camera_base |
| Vispa | cam_wrist | Camera | link6/camera_wrist |
| Humanoid21 | imu_robot | Imu | pelvis |
| Humanoid21 | contacts_feet | Contact Sensor | (left|right)_foot |
| Humanoid21 | cam_front | Camera | pelvis/camera_front |
| Humanoid28 | imu_robot | Imu | pelvis |
| Humanoid28 | contacts_feet | Contact Sensor | (left|right)_foot |
| Humanoid28 | cam_front | Camera | pelvis/camera_front |
| Unitree H1 | imu_robot | Imu | pelvis |
| Unitree H1 | contacts_feet | Contact Sensor | (left|right)_ankle_link |
| Unitree H1 | cam_front | Camera | pelvis/camera_front |
| Unitree G1 | imu_robot | Imu | pelvis |
| Unitree G1 | contacts_feet | Contact Sensor | (left|right)_ankle_roll_link |
| Unitree G1 | cam_front | Camera | pelvis/camera_front |
| Crazyflie | imu_robot | Imu | body |
| Crazyflie | cam_onboard | Camera | body/camera_onboard |
| Ingenuity | imu_robot | Imu | body |
| Ingenuity | cam_onboard | Camera | body/camera_onboard |
| Ingenuity | altimeter | Heightmap Sensor | body |
| Heron | imu_robot | Imu | base_link |
| Heron | cam_onboard | Camera | base_link/camera_onboard |
| Anymal C | imu_robot | Imu | base |
| Anymal C | contacts_feet | Contact Sensor | .*FOOT |
| Anymal C | cam_front | Camera | base/camera_front |
| Anymal D | imu_robot | Imu | base |
| Anymal D | contacts_feet | Contact Sensor | .*FOOT |
| Anymal D | cam_front | Camera | base/camera_front |
| Random Anymal Quadruped | imu_robot | Imu | base |
| Random Anymal Quadruped | contacts_feet | Contact Sensor | .*FOOT |
| Random Anymal Quadruped | cam_front | Camera | base/camera_front |
| Cadre | imu_robot | Imu | chassis |
| Cadre | contacts_wheels | Contact Sensor | .*wheel.* |
| Cadre | cam_front | Camera | chassis/camera_front |
| Cassie | imu_robot | Imu | pelvis |
| Cassie | contacts_feet | Contact Sensor | (left|right)_toe |
| Cassie | cam_front | Camera | pelvis/camera_front |
| Husky | imu_robot | Imu | chassis |
| Husky | contacts_wheels | Contact Sensor | .*wheel.* |
| Husky | cam_front | Camera | chassis/camera_front |
| Leo Rover | imu_robot | Imu | chassis |
| Leo Rover | contacts_wheels | Contact Sensor | .*wheel.* |
| Leo Rover | cam_front | Camera | chassis/camera_front |
| Mars Rover | imu_robot | Imu | Body |
| Mars Rover | contacts_wheels | Contact Sensor | .*[Dd]rive.* |
| Mars Rover | cam_front | Camera | Body/camera_front |
| Nifty | imu_robot | Imu | chassis |
| Nifty | contacts_wheels | Contact Sensor | .*wheel.* |
| Nifty | cam_front | Camera | chassis |
| Open Source Rover | imu_robot | Imu | chassis |
| Open Source Rover | contacts_wheels | Contact Sensor | .*wheel.* |
| Open Source Rover | cam_front | Camera | chassis/camera_front |
| Perseverance | imu_robot | Imu | body |
| Perseverance | contacts_wheels | Contact Sensor | .*wheel.* |
| Perseverance | cam_front | Camera | body/camera_front |
| Pragyan | imu_robot | Imu | body |
| Pragyan | contacts_wheels | Contact Sensor | .*wheel.* |
| Pragyan | cam_front | Camera | body/camera_front |
| Raph Rover | imu_robot | Imu | chassis |
| Raph Rover | contacts_wheels | Contact Sensor | wheel.* |
| Raph Rover | cam_front | Camera | chassis/camera_front |
| Spot | imu_robot | Imu | body |
| Spot | contacts_feet | Contact Sensor | .*foot |
| Spot | cam_front | Camera | body/camera_front |
| Unitree A1 | imu_robot | Imu | trunk |
| Unitree A1 | contacts_feet | Contact Sensor | .*foot |
| Unitree A1 | cam_front | Camera | trunk/camera_front |
| Unitree Go1 | imu_robot | Imu | trunk |
| Unitree Go1 | contacts_feet | Contact Sensor | .*foot |
| Unitree Go1 | cam_front | Camera | trunk/camera_front |
| Unitree Go2 | imu_robot | Imu | base |
| Unitree Go2 | contacts_feet | Contact Sensor | .*foot |
| Unitree Go2 | cam_front | Camera | base/camera_front |
| Random Unitree Quadruped | imu_robot | Imu | trunk |
| Random Unitree Quadruped | contacts_feet | Contact Sensor | .*foot |
| Random Unitree Quadruped | cam_front | Camera | trunk/camera_front |
| Floating Platform | imu_robot | Imu | base_link |
| Floating Platform | cam_onboard | Camera | base_link/camera_onboard |
| Int Ball1 | imu_robot | Imu | base_link |
| Int Ball1 | cam_onboard | Camera | base_link/camera_onboard |
| Int Ball2 | imu_robot | Imu | base_link |
| Int Ball2 | cam_onboard | Camera | base_link/camera_onboard |
| Apollo Lander | imu_robot | Imu | base |
| Apollo Lander | cam_onboard | Camera | base/camera_onboard |
| Peregrine Lander | imu_robot | Imu | base |
| Peregrine Lander | cam_onboard | Camera | base/camera_onboard |
| Vikram Lander | imu_robot | Imu | base |
| Vikram Lander | cam_onboard | Camera | base/camera_onboard |
| Resilience Lander | imu_robot | Imu | base |
| Resilience Lander | cam_onboard | Camera | base/camera_onboard |
| Random Lander | imu_robot | Imu | base |
| Random Lander | cam_onboard | Camera | base/camera_onboard |
| Iss | imu_robot | Imu | base |
| Iss | cam_onboard | Camera | base/camera_onboard |
| Gateway | imu_robot | Imu | gateway |
| Gateway | cam_onboard | Camera | gateway/camera_onboard |
| Cubesat | imu_robot | Imu | cubesat |
| Cubesat | cam_onboard | Camera | cubesat/camera_onboard |
| Satellite Mockup | imu_robot | Imu | satellite_mockup |
| Satellite Mockup | cam_onboard | Camera | satellite_mockup/camera_onboard |
| Venus Express | imu_robot | Imu | base |
| Venus Express | cam_onboard | Camera | base/camera_onboard |
| Starship | imu_robot | Imu | base |
| Starship | cam_onboard | Camera | base/camera_onboard |
| Super Heavy | imu_robot | Imu | base |
| Super Heavy | cam_onboard | Camera | base/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/key | Dtype and shape | Meaning |
|---|---|---|
Epoch sunlit | bool (T,H,W) | Per-epoch line-of-sight mask. |
Epoch sun_fraction | float32 (T,H,W), NaN holes | Continuous illuminated-disk fraction. |
Epoch times_utc | (T,) ISO-8601 | Epoch axis. |
Epoch sun_azel | (T,2) float64 | True-north compass azimuth and patch-center elevation, degrees. |
Epoch sun_angular_diameter_deg | (T,) float64 | Sun angular diameter. |
Optional epoch earth_los | bool (T,H,W) | Source Earth visibility. |
Optional epoch earth_azel | (T,2) float64 | Source Earth geometry. |
Static psr | uint8 (H,W), {0,1,255} | Permanently-shadowed region; 255 nodata. |
Static lit_fraction | float32 (H,W), NaN holes | Time-averaged illuminated fraction. |
Static max_sun_el | float32 (H,W), NaN holes | Maximum 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.
| Source | Function | Requirements |
|---|---|---|
lunarlab spice_maps epochs.zarr | import_lunarlab_zarr | zarr/numcodecs. |
lunarlab legacy save_masks .npz | import_lunarlab_npz | NumPy only. |
| PGDA product-69 LPSR GeoTIFF | import_pgda_lpsr | Base rasterio; Moon-only, static tier. |
-
Use
--baked-dirto import into a baked patch. It reads the grid, CRS, patch center, and site latitude/longitude from baked-patchmeta.json. Output defaults to<baked-dir>/illumination.npz.New cache generations record an
illuminationblock inmeta.json: filename, schema, SHA-256, source, epoch count/start/step, static keys, and import timestamp. Bake metadata is the georeference authority, so--baked-dirwith--lat/--lonexitsSystemExit(2). -
Without a bake, specify
--crs,--center-xy,--size-m,--gsd-m,--lat,--lon, and--out.--size-mmust 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}, defaultmoon.pgda-lpsris Moon-only and rejects--epoch-range/--epoch-stride(SystemExit(2); stride default1) 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 detail | Behavior |
|---|---|
| Packed masks | lunarlab sunlit/earth_los: np.unpackbits(arr, axis=-1)[..., :W]. |
sun_fraction | uint8 decodes as q / 254.0; q == 255 becomes NaN. |
earth_los | lunarlab’s DSN-union station-view mask, not single-site Earth-center line of sight; imported unchanged. |
| PGDA LPSR | int16: PSR iff DN == 20000; nodata DN == -32768. Canonical uint8 {0,1,255} passes through; other dtypes raise ValueError. |
| PSR fractions | Neither 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/helper | Inputs and behavior |
|---|---|
reset_root_state_uniform_illumination_masked | Reset 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_at | Torch 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 | |
|---|---|
| Robots | 64 |
| - Manipulator | 21 |
| - Mobile Manipulator | 7 |
| - Mobile Robot | 36 |
| Objects | 54 |
| Scenery | 14 |
| Tasks | 43 |
| - Digital Twin | 3 |
| - Manipulation | 11 |
| - Mobile | 22 |
| - Mobile Manipulation | 7 |
| Action Modes (total) | 121 |
| Sensor Types | 4 |
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
../simforgeand../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
- Working Docker Engine and NVIDIA Container Toolkit. The Dev Container requests all GPUs.
xauthand an X11 session for GUI forwarding.- Visual Studio Code (VS Code) and the Dev Containers extension.
- Host
codeCLI to use the optional helper script below.
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
-
Open the repository folder:
code /path/to/space_robotics_bench -
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
unittier (tests/import_test.py) does not require Isaac Sim or a GPU — run it anywhere withpytest -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
| Argument | Description | Default |
|---|---|---|
-l/--language/--lang | Language suites to test | [python] |
-t/--tier | Python tiers to run (all = every tier) | [all] |
Arguments after
--are forwarded to everypytesttier and tocargo 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-subcommand | Description |
|---|---|
srb doc serve (default) | Run an mdBook live-reload server and open it in a browser |
srb doc build | Build the static site for local preview |
srb doc docgen | Regenerate auto-introspected asset, task, and catalog pages; launches Isaac Sim headless |
srb doc thumbnail | Render 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 serveandsrb doc buildforward tokens after--directly tomdbook.
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:
-
From a source checkout, install the
plotsextra (Matplotlib, NumPy, Torch, Seaborn). -
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_assetsfor asset payloads.docs/src/_graphicsfor 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_...forassets/srb_assetsSRB_GRAPHICS_...fordocs/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
-
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 -
To include the NGC cleanup root, set an absolute
SRB_NGC_CACHE_DIR; a relative value selects none. -
Run
srb clean:srb cleanSRB prompts before removing marker-owned directories unless
-y/--yesis 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]
| Argument | Description | Default |
|---|---|---|
TARGET ... | One or more of all, srb, isaacsim, simforge (multiple allowed) | [all] |
-y/--yes | Skip the interactive confirmation prompt | False |
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
| Target | Affected paths |
|---|---|
srb | The 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. |
isaacsim | Marker-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) |
simforge | Delegated 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
-
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 assignasset_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_cfgRealTerrain(body=..., site=...)resolves manifest entries; shortcut classes select specific sites; coordinate regions need no manifest. For curation and offline baking, see Adding Terrain Sites. -
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_sceneryattaches companions whenattach_companions_enabled=True; set it toFalseto 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_defaultfor Moon). Ifsimforge_foundrycannot be imported,SimforgeMissingErroris raised. -
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
sitewithsite=None, or constructRealTerrain(body=..., dem_path=...). -
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-fixturesCoordinate downloads target arbitrary v2 regions without a manifest. They require all three coordinate flags and reject site targets,
--all, and site-specific flags.
| Option | Default or constraint |
|---|---|
| Selection | Exactly one (mixing is rejected): manifest site, local dem_path, or complete lat_deg/lon_deg/size_m region. |
lod | medium; valid tiers low, medium, high. |
use_ortho | True; disable with False for a local DEM without ortho. |
augment | "none" by default; "simforge" requires simforge_foundry. |
| Auto-fetch | On 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.
| Cache | Path 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:
- Warp layers to the patch grid with
fusion.grid.warp_to_grid. - Co-register DEM insets using catalog shifts or estimates; warn and drop insets with excessive QC residuals.
- Feather-blend by priority: finest/highest-priority inset wins within its data boundary, blending to the next layer within
blend_len_mof the true boundary. Clampblend_len_mto 50–200 m; declared footprint without data does not count. No global weighted average. - 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:
| Output | Contents |
|---|---|
provenance.tif | Same-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.txt | One 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.
| LOD | Max grid faces | Max texture side (px) |
|---|---|---|
high | 4,000,000 | 8192 |
medium | 1,000,000 | 4096 |
low | 250,000 | 2048 |
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:
| Array | Shape | Columns |
|---|---|---|
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_scattergenerates eight (_ROCK_ASSET_SLOTS=8) variant USDs once via SimForgeasset.generator_type(...).generate_subprocess(...), without scattering; subprocess cache stores them. Row variant isasset_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 LabAssetBaseCfg.InitialStateCfg.rot; identity(0,0,0,1).RealTerrain.augment_max_rocks: int = 256;select_rowstakes 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_generatorraisesValueErroroutside Moon/Mars. Earth zero-density shortcut inbuild_real_terrain_augment_cfgand 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
| Error | Cause | Remedy |
|---|---|---|
ManifestSiteUnknownError | Bad site | srb asset list terrain |
LicenseMissingError | Missing attribution | Pass attribution="..." |
ChecksumMismatchError | Upstream DEM changed | srb asset validate-manifest --check-shas |
SimforgeMissingError | Package absent | pip install simforge_foundry |
TerrainNotBakedError | Auto-fetch off; cache miss | Run 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.
| Quantity | SI unit |
|---|---|
| Length | m |
| Mass | kg |
| Time | s |
| Angle | rad |
| Force | N |
| Torque | N·m |
| Gravity | m/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_posesreturns andset_world_posesaccepts (x, y, z, w); the setter converts to USD.- Sensor mount
OffsetCfg.rotand event-camerarot_xyzwuse 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
| Domain | Gravity (m/s²) |
|---|---|
| Earth | 9.80665 |
| Mars | 3.72076 |
| Moon | 1.62496 |
| Asteroid | 0.14219 |
| Orbit | 0.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"forActionGroup;"sensor"forSensorBase."observation"for managers; set extragroup="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.
| Descriptor | Contract |
|---|---|
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 groups | One 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 Type | Description |
|---|---|
| Scenery | Terrain and structures |
| Objects | Interactive objects, tools, and payloads |
| Robots | Controllable systems |
Add a static asset
-
Identify its family and interface:
- Robots: joints and sensors.
- Terrain: source metadata.
- Objects: spawn configuration.
-
Record the source, author, and license in the applicable metadata catalog. For assets in SRB’s catalog, edit
docs/data/assets.toml. -
Follow the family format and validation rules. The rock pipeline checksum-verifies, decodes, bounds, and cleans terrain rocks. Robot and scenery checks differ.
-
Check dependencies, payload paths, and references against family conventions.
-
Add the asset to your srb_assets fork.
-
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:
| Template | Description |
|---|---|
_manipulation | Fixed-base manipulation with robotic arms |
_ground | Ground traversal on planetary surfaces |
_aerial | Aerial navigation above planetary surfaces |
_orbital | Spaceflight maneuvers |
_ground_manipulation | Mobile manipulation with ground-based robots |
_aerial_manipulation | Mobile manipulation with flying robots |
_orbital_manipulation | Mobile 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
-
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. -
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 -
Validate and bake:
srb asset validate-manifest srb asset download terrain my_site -
In the SRB/Isaac Sim Python environment, verify the import-time shortcut.
real_terrain_sites.pyimports Isaac Lab and generatesLunarSiteMySite,MartianSiteMySite, orEarthSiteMySite: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:
| Provider | Allowed hosts | Typical body |
|---|---|---|
pgda | pgda.gsfc.nasa.gov | moon |
zenodo | zenodo.org, www.zenodo.org | any; zip-member archives |
uahirise | hirise.lpl.arizona.edu, www.uahirise.org, uahirise.org | mars |
copernicus_s3 | copernicus-dem-30m.s3.amazonaws.com, copernicus-dem-90m.s3.amazonaws.com | earth |
usgs_3dep | prd-tnm.s3.amazonaws.com | earth |
imbrium | imbrium.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:
| Access | Required keys |
|---|---|
cog_remote or download | Exactly one key equal to basename(urls[0]); missing, extra, or mismatched keys fail catalog loading. |
zip_member | Archive 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.
SourceLayerusesextra="forbid"; a typo such asmask_encodding:fails validation instead of silently restoring the bug.- Check URL bytes and histogram. PGDA documents
{0, 1, 255}uint8, but the pinned.TIFserves raw int16. Keep values synchronized withsrb/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
-
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 v1dem/ortho. -
Set manifest
version: 2before declaring stacks. Existing v1 sites remain valid:Sourcesrequires exactly one ofdemordem_stackper site regardless of manifest version.version: 2 sites: apollo17: { ... } # existing v1 site, unchanged -
Declare one
role: baseand zero or morerole: insetentries indem_stack; optionalcolor_stackuses the same shape. Use these instead of v1sources.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 colordeshade: truedivides sunlit color by fused-DEM hillshade using catalogsun_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 manifestdeshade: true; the effective value enters the cache key. See Deshade.Each
layer_idmust exist in its body’s catalog; unknown ids fail at resolve and name the missing layer.roleselects the base regardless of list order.StackRef.max_gsd_mexcludes coarse candidates with a warning. -
Validate and bake as for Adding a new terrain site. The generated shortcut is
LunarSiteConnectingRidge; CLI andRealTerrainconstructor are unchanged.bake_or_loaddetects declared stacks (sources.dem is None) and routes to fusion. -
Inspect outputs:
meta.jsoncontains afusionblock,provenance.tifsits besideterrain.usd, andATTRIBUTION.txthas 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
-
Replace placeholder
"f" * 64with the downloaded file’s real hash:curl -L "<url>" | sha256sum -
Update the manifest, rerun
srb asset validate-manifest, and confirmsrb asset download terrain <site>succeeds.
Common mistakes
- Symptom: ingest raises
MissingCRSErrororDemLoadError. Cause: the CRS string is misspelled. Fix: useIAU_Moon_2015orIAU_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 smallerpatch_size_mor anothercenter_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:, orrocks:names no catalog entry. Fix: use a valid catalog name ornullto 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.
| Lander | Mass |
|---|---|
Starship | 100,000 kg |
SuperHeavy | 200,000 kg |
ApolloLander | 4,280 kg dry |
PeregrineLander | 825 kg |
VikramLander | 626 kg |
ResilienceLander | 340 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.
| Body | Static/dynamic friction | Restitution |
|---|---|---|
| Moon | 0.85/0.70 | 0.0 |
| Mars | 0.75/0.60 | 0.0 |
| Earth | 0.80/0.60 | 0.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-mto 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:
| Source | GSD |
|---|---|
| Mars HiRISE | 1.016553302... m |
| Earth 3DEP | 1.0 m |
| Earth Copernicus | 30.0 m |
| Moon | 1.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 config | Physics interval | Control interval | Decimation |
|---|---|---|---|
Aerial family default, including aerial_navigation | 1/25 s | 1/25 s | 1 (40 ms) |
flight | 1/50 s | 1/25 s | 2 (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
| Area | Limitation |
|---|---|
| PDS3 conversion | srb.terrain.sources.pds_img.img_to_geotiff writes raw samples, ignoring SCALING_FACTOR/OFFSET; optional pdr fallback omits CRS, identity transform, and nodata. |
| Ortho fusion | ortho_path resizes images to DEM grid by array shape; images must be pixel-aligned. Fused colour is aligned. |
| Resolution | Reads finer than native resolution may not average; elevation can alias. |
| SpaceMouse | Use an independent deadman with a real robot: reads may succeed while reports are lost, keeping the last motion. |
| Dreamer | Real-transfer checkpoints save periodically, not on normal stop. |
| Installers | Isaac 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
| Asset | Source | License | Author |
|---|---|---|---|
canadarm3 | SRB | – | SRB Contributors |
franka | SRB | – | SRB Contributors |
kinova_gen3n7 | Isaac Lab | NVIDIA | NVIDIA |
so_arm100_d5 | SRB | – | SRB Contributors |
so_arm100_d7 | SRB | – | SRB Contributors |
unitree_z1 | Isaac Lab | NVIDIA | NVIDIA |
ur10 | Isaac Lab | NVIDIA | NVIDIA |
ur3 | Isaac Sim | NVIDIA | NVIDIA |
ur5 | Isaac Sim | NVIDIA | NVIDIA |
vispa | SRB | – | 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/.
| Font | Source | License | Author |
|---|---|---|---|
| Inter | rsms/inter | OFL-1.1 | The Inter Project Authors |
| Monaspace Neon | githubnext/monaspace | OFL-1.1 | GitHub |
| Material Icons Round | google/material-design-icons | Apache-2.0 |
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 
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.