diff --git a/.dockerignore b/.dockerignore
index b6687c95fa7..51d4ec61a45 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -28,3 +28,4 @@ _isaac_sim?
docker/.isaac-lab-docker-history
# ignore uv environment
env_isaaclab
+tools/wheel_builder/build/
diff --git a/.gitattributes b/.gitattributes
index e3c0ead689d..68372999154 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -12,3 +12,4 @@
*.hdf5 filter=lfs diff=lfs merge=lfs -text
*.bat text eol=crlf
+*.sh text eol=lf
diff --git a/.github/ISSUE_TEMPLATE/proposal.md b/.github/ISSUE_TEMPLATE/proposal.md
index c07d7f56dc8..a6dd4081906 100644
--- a/.github/ISSUE_TEMPLATE/proposal.md
+++ b/.github/ISSUE_TEMPLATE/proposal.md
@@ -26,8 +26,8 @@ A clear and concise description of any alternative solutions or features you've
Describe the versions where you are observing the missing feature in:
-- Isaac Lab Version: [e.g. 2.3.2]
-- Isaac Sim Version: [e.g. 5.1, this can be obtained by `cat ${ISAACSIM_PATH}/VERSION`]
+- Isaac Lab Version: [e.g. 3.0.0]
+- Isaac Sim Version: [e.g. 6.0, this can be obtained by `cat ${ISAACSIM_PATH}/VERSION`]
### Additional context
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
index 6e0582f3737..ff0ac5b8f12 100644
--- a/.github/ISSUE_TEMPLATE/question.md
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -17,5 +17,5 @@ For questions that are related to running and understanding Isaac Sim, please po
Describe the versions that you are currently using:
-- Isaac Lab Version: [e.g. 2.3.2]
-- Isaac Sim Version: [e.g. 5.1, this can be obtained by `cat ${ISAACSIM_PATH}/VERSION`]
+- Isaac Lab Version: [e.g. 3.0.0]
+- Isaac Sim Version: [e.g. 6.0, this can be obtained by `cat ${ISAACSIM_PATH}/VERSION`]
diff --git a/.github/actions/combine-results/action.yml b/.github/actions/combine-results/action.yml
deleted file mode 100644
index 8ed66e3b460..00000000000
--- a/.github/actions/combine-results/action.yml
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
-# All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-
-name: 'Combine XML Test Results'
-description: 'Combines multiple XML test result files into a single file'
-
-inputs:
- tests-dir:
- description: 'Directory containing test result files'
- default: 'tests'
- required: false
- output-file:
- description: 'Output combined XML file path'
- required: true
- reports-dir:
- description: 'Directory to store the combined results'
- default: 'reports'
- required: false
-
-runs:
- using: composite
- steps:
- - name: Combine XML Test Results
- shell: sh
- run: |
- # Function to combine multiple XML test results
- combine_xml_results() {
- local tests_dir="$1"
- local output_file="$2"
- local reports_dir="$3"
-
- echo "Combining test results from: $tests_dir"
- echo "Output file: $output_file"
- echo "Reports directory: $reports_dir"
-
- # Check if reports directory exists
- if [ ! -d "$reports_dir" ]; then
- echo "⚠️ Reports directory does not exist: $reports_dir"
- mkdir -p "$reports_dir"
- fi
-
- # Check if tests directory exists
- if [ ! -d "$tests_dir" ]; then
- echo "⚠️ Tests directory does not exist: $tests_dir"
- echo "Creating fallback XML..."
- echo 'Tests directory was not found' > "$output_file"
- return
- fi
-
- # Find all XML files in the tests directory
- echo "Searching for XML files in: $tests_dir"
- xml_files=$(find "$tests_dir" -name "*.xml" -type f 2>/dev/null | sort)
-
- if [ -z "$xml_files" ]; then
- echo "⚠️ No XML files found in: $tests_dir"
- echo "Creating fallback XML..."
- echo 'No XML test result files were found' > "$output_file"
- return
- fi
-
- # Count XML files found
- file_count=$(echo "$xml_files" | wc -l)
- echo "✅ Found $file_count XML file(s):"
- echo "$xml_files" | while read -r file; do
- echo " - $file ($(wc -c < "$file") bytes)"
- done
-
- # Create combined XML
- echo "🔄 Combining $file_count XML files..."
- echo '' > "$output_file"
- echo '' >> "$output_file"
-
- # Process each XML file
- combined_count=0
- echo "$xml_files" | while read -r file; do
- if [ -f "$file" ]; then
- echo " Processing: $file"
- # Remove XML declaration and outer testsuites wrapper from each file
- # Remove first line (XML declaration) and strip outer / tags
- sed '1d; s/^//; s/<\/testsuites>$//' "$file" >> "$output_file" 2>/dev/null || {
- echo " ⚠️ Warning: Could not process $file, skipping..."
- }
- combined_count=$((combined_count + 1))
- fi
- done
-
- echo '' >> "$output_file"
- echo "✅ Successfully combined $combined_count files into: $output_file"
-
- # Verify output file was created
- if [ -f "$output_file" ]; then
- echo "✅ Final output file created: $output_file"
- echo "📊 Output file size: $(wc -c < "$output_file") bytes"
- else
- echo "❌ Failed to create output file: $output_file"
- exit 1
- fi
- }
-
- # Call the function with provided parameters
- combine_xml_results "${{ inputs.tests-dir }}" "${{ inputs.output-file }}" "${{ inputs.reports-dir }}"
diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml
index 2db402d4204..7f88241cfb8 100644
--- a/.github/actions/docker-build/action.yml
+++ b/.github/actions/docker-build/action.yml
@@ -18,7 +18,7 @@ inputs:
required: true
dockerfile-path:
description: 'Path to Dockerfile'
- default: 'docker/Dockerfile.curobo'
+ default: 'docker/Dockerfile.base'
required: false
context-path:
description: 'Build context path'
@@ -52,13 +52,18 @@ runs:
local dockerfile_path="$4"
local context_path="$5"
+ # Skip build if image already exists locally (e.g. built by a prior job on the same runner)
+ if docker image inspect "$image_tag" > /dev/null 2>&1; then
+ echo "Image $image_tag already exists locally, skipping build."
+ return 0
+ fi
+
echo "Building Docker image: $image_tag"
echo "Using Dockerfile: $dockerfile_path"
echo "Build context: $context_path"
# Build Docker image
docker buildx build --progress=plain --platform linux/amd64 \
- -t isaac-lab-dev \
-t $image_tag \
--build-arg ISAACSIM_BASE_IMAGE_ARG="$isaacsim_base_image" \
--build-arg ISAACSIM_VERSION_ARG="$isaacsim_version" \
@@ -71,7 +76,8 @@ runs:
--load $context_path
echo "✅ Docker image built successfully: $image_tag"
- docker images | grep isaac-lab-dev
+ echo "Current local Docker images:"
+ docker images
}
# Call the function with provided parameters
diff --git a/.github/actions/ecr-build-push-pull/README.md b/.github/actions/ecr-build-push-pull/README.md
new file mode 100644
index 00000000000..2e306c978b8
--- /dev/null
+++ b/.github/actions/ecr-build-push-pull/README.md
@@ -0,0 +1,24 @@
+# ecr-build-push-pull
+
+Builds a Docker image and pushes it to ECR, or pulls it if the tag already exists.
+ECR is also used as the BuildKit layer cache.
+
+## Usage
+
+```yaml
+- uses: ./.github/actions/ecr-build-push-pull
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: nvcr.io/nvidia/isaac-sim
+ isaacsim-version: 6.0.0
+ dockerfile-path: docker/Dockerfile.base
+ cache-tag: cache-base
+ ecr-url: (optional, complete url for ECR storage)
+```
+
+## ECR URL resolution order
+
+1. `ecr-url` input
+2. `ECR_CACHE_URL` environment variable on the runner
+3. SSM parameter `/github-runner//ecr-cache-url`
+4. If none resolve, ECR is skipped and the image is built locally
diff --git a/.github/actions/ecr-build-push-pull/action.yml b/.github/actions/ecr-build-push-pull/action.yml
new file mode 100644
index 00000000000..b661d4b9fd6
--- /dev/null
+++ b/.github/actions/ecr-build-push-pull/action.yml
@@ -0,0 +1,321 @@
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+name: 'ECR Build-Push-Pull'
+description: >
+ Builds a Docker image and pushes it to ECR, using ECR as the layer cache.
+ If the image already exists in ECR (same tag), pulls it instead of building.
+ Drop-in replacement for docker-build/action.yml with ECR-backed caching.
+
+inputs:
+ image-tag:
+ description: 'Tag for the Docker image (e.g. my-image:latest).'
+ required: true
+ isaacsim-base-image:
+ description: 'IsaacSim base image (passed as ISAACSIM_BASE_IMAGE_ARG build-arg).'
+ required: true
+ isaacsim-version:
+ description: 'IsaacSim version (passed as ISAACSIM_VERSION_ARG build-arg).'
+ required: true
+ dockerfile-path:
+ description: 'Path to Dockerfile, relative to the repository root'
+ default: 'docker/Dockerfile.base'
+ required: false
+ ecr-url:
+ description: >
+ ECR repository URL (e.g. "123456789.dkr.ecr.us-west-2.amazonaws.com/my-repo").
+ Resolved in the following order:
+ 1. ecr-url input, if provided.
+ 2. ECR_CACHE_URL environment variable on the runner.
+ 3. SSM parameter /github-runner//ecr-cache-url.
+ 4. If still empty, ECR cache is skipped and the image is built locally.
+ required: false
+ default: ''
+ cache-tag:
+ description: Tag used for the ECR layer cache image (e.g. "cache-base", "cache-curobo").
+ required: false
+ default: 'cache'
+runs:
+ using: composite
+ steps:
+
+ ##### 1: Setup docker config + Login to nvcr.io #####
+
+ # Create a temp docker config with credsStore disabled before any login.
+ # The runner's credential store backend is broken ("not implemented") and
+ # causes all docker login calls to fail unless we bypass it upfront.
+ # The temp config is exported as DOCKER_CONFIG so all subsequent steps
+ # (including ECR login in step 3) inherit it automatically.
+
+ - name: Setup docker config and login to nvcr.io
+ shell: bash
+ run: |
+ DOCKER_CONFIG_DIR=$(mktemp -d)
+ if [ -f "${HOME}/.docker/config.json" ]; then
+ python3 -c "import json; cfg=json.load(open('${HOME}/.docker/config.json')); cfg['credsStore']=''; cfg.pop('credHelpers',None); json.dump(cfg,open('${DOCKER_CONFIG_DIR}/config.json','w'))"
+ else
+ echo '{"credsStore":""}' > "${DOCKER_CONFIG_DIR}/config.json"
+ fi
+ echo "DOCKER_CONFIG=${DOCKER_CONFIG_DIR}" >> "$GITHUB_ENV"
+ export DOCKER_CONFIG="${DOCKER_CONFIG_DIR}"
+
+ if [ -n "${{ env.NGC_API_KEY }}" ]; then
+ echo "🔵 Logging into nvcr.io..."
+ docker login -u \$oauthtoken -p ${{ env.NGC_API_KEY }} nvcr.io
+ else
+ echo "🟠 NGC_API_KEY not set - skipping nvcr.io login (normal for fork PRs)"
+ fi
+
+ ##### 2: Resolve ECR URL #####
+
+ # Tries: explicit input >> ECR_CACHE_URL env var >> SSM parameter on EC2.
+ # Exports ECR_URL to GITHUB_ENV and sets output `available`.
+
+ - name: Resolve ECR URL
+ id: resolve-ecr
+ shell: bash
+ env:
+ INPUT_ECR_URL: ${{ inputs.ecr-url }}
+ run: |
+ ECR_URL="${INPUT_ECR_URL:-}"
+
+ if [ -z "${ECR_URL}" ]; then
+ echo "🔵 ecr-url input not set, trying ECR_CACHE_URL env var..."
+ ECR_URL="${ECR_CACHE_URL:-}"
+ [ -n "${ECR_URL}" ] && echo "🟢 Using ECR_CACHE_URL env var: ${ECR_URL}"
+ fi
+
+ if [ -z "${ECR_URL}" ]; then
+ echo "🔵 ECR_CACHE_URL env var not set, trying SSM..."
+ IMDS_TOKEN=$(curl -sf -X PUT "http://169.254.169.254/latest/api/token" \
+ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") || true
+ INSTANCE_ID=$(curl -sf -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \
+ "http://169.254.169.254/latest/meta-data/instance-id") || true
+ INSTANCE_REGION=$(curl -sf -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \
+ "http://169.254.169.254/latest/meta-data/placement/region") || true
+
+ if [ -n "${INSTANCE_ID}" ]; then
+ ECR_URL=$(aws ssm get-parameter \
+ --name "/github-runner/${INSTANCE_ID}/ecr-cache-url" \
+ --region "${INSTANCE_REGION}" \
+ --query 'Parameter.Value' --output text 2>/dev/null) || ECR_URL=""
+ if [ -n "${ECR_URL}" ]; then
+ echo "🟢 Resolved ECR URL from SSM (/github-runner/${INSTANCE_ID}/ecr-cache-url): ${ECR_URL}"
+ else
+ echo "🔵 SSM parameter not found for instance ${INSTANCE_ID}"
+ fi
+ else
+ echo "🔵 Not running on EC2 or IMDS unavailable, skipping SSM lookup"
+ fi
+ fi
+
+ if [ -n "${ECR_URL}" ]; then
+ echo "ECR_URL=${ECR_URL}" >> "$GITHUB_ENV"
+ echo "available=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "🟠 ECR URL cannot be resolved. Building locally without ECR cache."
+ fi
+
+ ##### 3: Setup ECR authentication #####
+
+ # Validates the ECR URL, derives ECR image tags, and logs into ECR.
+ # DOCKER_CONFIG (with credsStore disabled) is already set by step 1.
+
+ - name: Setup ECR authentication
+ if: steps.resolve-ecr.outputs.available == 'true'
+ shell: bash
+ run: |
+ REGISTRY=$(echo "${ECR_URL}" | cut -d'/' -f1)
+ AWS_REGION=$(echo "${REGISTRY}" | sed 's/.*\.dkr\.ecr\.\(.*\)\.amazonaws\.com/\1/')
+
+ if [ "${AWS_REGION}" = "${REGISTRY}" ]; then
+ echo "🔴 Invalid ECR URL - cannot extract AWS region: ${ECR_URL}"
+ echo "🔴 Expected format: .dkr.ecr..amazonaws.com/"
+ exit 1
+ fi
+
+ ECR_TAG=$(echo "${{ inputs.image-tag }}" | tr ':/' '--')
+ ECR_IMAGE="${ECR_URL}:${ECR_TAG}"
+ CACHE_IMAGE="${ECR_URL}:${{ inputs.cache-tag }}"
+
+ echo "ECR_IMAGE=${ECR_IMAGE}" >> "$GITHUB_ENV"
+ echo "CACHE_IMAGE=${CACHE_IMAGE}" >> "$GITHUB_ENV"
+
+ echo "🔵 Logging into ECR registry..."
+ aws ecr get-login-password --region "${AWS_REGION}" | \
+ docker login --username AWS --password-stdin "${REGISTRY}"
+
+ ##### 4: Check if exact image exists in ECR #####
+
+ # Lightweight manifest check - fetches only the image manifest (~KB),
+ # not the actual layers. If the exact per-commit image already exists
+ # in ECR, sets output `hit: true` to skip all subsequent build/push steps.
+
+ - name: Check exact image in ECR
+ id: pull-exact
+ if: steps.resolve-ecr.outputs.available == 'true'
+ shell: bash
+ run: |
+ echo "🔵 Checking if commit-tagged image exists in ECR >> ${ECR_IMAGE}"
+ if docker manifest inspect "${ECR_IMAGE}" >/dev/null 2>&1; then
+ echo "🟢 Commit-tagged image found in ECR, skipping build!"
+ echo "hit=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "🟠 Image ${ECR_IMAGE} not found in ECR, will try deps-cache strategy..."
+ fi
+
+ # Pull the image when the manifest check succeeded but the image is not
+ # available locally (test jobs need it for `docker run`). Build jobs
+ # that only push to ECR will already have the image or don't need it.
+ - name: Pull exact image from ECR
+ if: steps.pull-exact.outputs.hit == 'true'
+ shell: bash
+ run: |
+ if docker image inspect "${{ inputs.image-tag }}" >/dev/null 2>&1; then
+ echo "🟢 Image already available locally, skipping pull"
+ else
+ echo "🔵 Pulling ${ECR_IMAGE} from ECR..."
+ docker pull "${ECR_IMAGE}"
+ docker tag "${ECR_IMAGE}" "${{ inputs.image-tag }}"
+ echo "🟢 Image pulled and tagged as ${{ inputs.image-tag }}"
+ fi
+
+ ##### 5: Check deps cache #####
+
+ # Hashes installation-relevant files + the base image digest to produce a stable
+ # deps- ECR tag. If the image exists in ECR, the build job succeeds
+ # immediately and test jobs pull the deps image with a source volume mount.
+
+ # Edit DEPS_FILES or DEPS_MANIFEST_PATTERN when install
+ # inputs change (new packages, new manifests, etc.).
+
+ - name: Check deps cache
+ id: deps-cache
+ if: steps.resolve-ecr.outputs.available == 'true' && steps.pull-exact.outputs.hit != 'true'
+ shell: bash
+ run: |
+ ##### Deps-hash configuration #####
+ # Exact files/dirs whose full content is hashed. The Dockerfile is first.
+ DEPS_FILES=(
+ "${{ inputs.dockerfile-path }}"
+ isaaclab.sh
+ environment.yml
+ source/isaaclab/isaaclab/cli
+ )
+ # Manifest files matched repo-wide via git ls-files.
+ DEPS_MANIFEST_PATTERN='(setup\.py|pyproject\.toml|setup\.cfg|extension\.toml|requirements[^/]*\.txt|uv\.lock)$'
+
+ # Resolve the actual base image digest so a new push of a mutable tag
+ # (e.g. latest-develop) invalidates the deps cache automatically.
+ BASE_IMAGE_DIGEST=$(docker buildx imagetools inspect \
+ "${{ inputs.isaacsim-base-image }}:${{ inputs.isaacsim-version }}" \
+ --format '{{json .Manifest.Digest}}' 2>/dev/null | tr -d '"' || true)
+ if [ -n "${BASE_IMAGE_DIGEST}" ]; then
+ BASE_IMAGE_UNIQ_ID="${{ inputs.isaacsim-base-image }}:${{ inputs.isaacsim-version }}:${BASE_IMAGE_DIGEST}"
+ else
+ echo "🟠 Could not resolve base image digest, falling back to tag string"
+ BASE_IMAGE_UNIQ_ID="${{ inputs.isaacsim-base-image }}:${{ inputs.isaacsim-version }}"
+ fi
+
+ echo "🔵 Base image ID: ${BASE_IMAGE_UNIQ_ID}"
+
+ MANIFEST_FILES=$(git ls-files | grep -E "${DEPS_MANIFEST_PATTERN}" || true)
+ FILE_HASH=$(git ls-files -s "${DEPS_FILES[@]}" ${MANIFEST_FILES} 2>/dev/null \
+ | sha256sum | cut -c1-16)
+ DEPS_HASH=$(printf '%s %s' "${FILE_HASH}" "${BASE_IMAGE_UNIQ_ID}" | sha256sum | cut -c1-16)
+ DEPS_ECR_IMAGE="${ECR_URL}:deps-${DEPS_HASH}"
+ echo "🔵 Deps hash: ${DEPS_HASH}"
+ echo "🔵 Checking if deps image ${DEPS_ECR_IMAGE} exists in ECR..."
+
+ # Lightweight manifest check - fetches only the image manifest (~KB),
+ # not the actual layers, so this completes in seconds.
+ if docker manifest inspect "${DEPS_ECR_IMAGE}" >/dev/null 2>&1; then
+ echo "🟢 Deps cache HIT!!! Image exists in ECR: ${DEPS_ECR_IMAGE}"
+ # Create a commit-tagged alias pointing to the same manifest (registry-side,
+ # no layer download). Test jobs will pull this tag normally.
+ echo "🔵 Tagging as commit image ${ECR_IMAGE}..."
+ docker buildx imagetools create -t "${ECR_IMAGE}" "${DEPS_ECR_IMAGE}"
+ echo "🟢 Tagged ${ECR_IMAGE} >> ${DEPS_ECR_IMAGE}"
+ echo "deps-cache-hit=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "🟠 Deps cache MISS 😿😿😿 (${DEPS_HASH}). Will build now. 🐢🐢🐢"
+ echo "DEPS_ECR_IMAGE=${DEPS_ECR_IMAGE}" >> "$GITHUB_ENV"
+ echo "PUSH_DEPS_IMAGE=true" >> "$GITHUB_ENV"
+ fi
+
+ ##### 6: Full build #####
+
+ # Runs when neither the exact image nor the deps cache was available.
+ # Uses ECR layer cache (--cache-from/--cache-to) when ECR is available.
+
+ - name: Full build
+ if: steps.pull-exact.outputs.hit != 'true' && steps.deps-cache.outputs.deps-cache-hit != 'true'
+ shell: bash
+ run: |
+ BUILD_ARGS=(
+ --progress=plain
+ --platform linux/amd64
+ -f "${{ inputs.dockerfile-path }}"
+ --build-arg "ISAACSIM_BASE_IMAGE_ARG=${{ inputs.isaacsim-base-image }}"
+ --build-arg "ISAACSIM_VERSION_ARG=${{ inputs.isaacsim-version }}"
+ --build-arg "ISAACSIM_ROOT_PATH_ARG=/isaac-sim"
+ --build-arg "ISAACLAB_PATH_ARG=/workspace/isaaclab"
+ --build-arg "DOCKER_USER_HOME_ARG=/root"
+ -t "${{ inputs.image-tag }}"
+ )
+ if [ -n "${ECR_URL:-}" ]; then
+ BUILD_ARGS+=(
+ --cache-from "type=registry,ref=${CACHE_IMAGE}"
+ --cache-to "type=registry,ref=${CACHE_IMAGE},mode=max"
+ -t "${ECR_IMAGE}"
+ )
+ fi
+
+ BUILDER_NAME="ci-builder-${{ github.run_id }}-${{ github.job }}"
+ docker buildx create --use --driver docker-container --name "${BUILDER_NAME}" \
+ || docker buildx use "${BUILDER_NAME}"
+ trap 'docker buildx rm "${BUILDER_NAME}" || true' EXIT
+
+ echo "🔵 Building ${{ inputs.image-tag }}..."
+ docker buildx build --load "${BUILD_ARGS[@]}" .
+
+ ##### 7: Push to ECR #####
+
+ # Pushes the per-commit ECR image after a successful full build.
+ # Skipped if the image was pulled in (4).
+
+ - name: Push to ECR
+ if: >
+ steps.resolve-ecr.outputs.available == 'true' &&
+ steps.pull-exact.outputs.hit != 'true' &&
+ steps.deps-cache.outputs.deps-cache-hit != 'true'
+ shell: bash
+ run: |
+ echo "🔵 Pushing ${ECR_IMAGE} to ECR..."
+ docker push "${ECR_IMAGE}"
+ echo "🟢 Pushed ${ECR_IMAGE}"
+
+ ##### 8: Push deps tag #####
+
+ # Tags the freshly built image as deps- so future runs with identical
+ # install inputs hit the fast path (step 5) instead of doing a full build.
+
+ - name: Push deps tag
+ if: env.PUSH_DEPS_IMAGE == 'true'
+ shell: bash
+ run: |
+ echo "🔵 Pushing deps image for future cache hits: ${DEPS_ECR_IMAGE}"
+ docker tag "${{ inputs.image-tag }}" "${DEPS_ECR_IMAGE}"
+ docker push "${DEPS_ECR_IMAGE}"
+
+ ##### 9: Cleanup docker config #####
+
+ - name: Cleanup docker config
+ if: always()
+ shell: bash
+ run: |
+ if [ -n "${DOCKER_CONFIG}" ] && [ -d "${DOCKER_CONFIG}" ]; then
+ rm -rf "${DOCKER_CONFIG}"
+ fi
diff --git a/.github/actions/run-package-tests/action.yml b/.github/actions/run-package-tests/action.yml
new file mode 100644
index 00000000000..50c3d225d63
--- /dev/null
+++ b/.github/actions/run-package-tests/action.yml
@@ -0,0 +1,180 @@
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+name: 'Run Package Tests'
+description: >
+ Pulls the Docker image from ECR, runs pytest inside the container, uploads
+ results as an artifact, and fails fork PRs on test failures.
+ NOTE: The calling job must check out the code before using this action.
+
+inputs:
+ image-tag:
+ description: 'Docker image tag'
+ required: true
+ isaacsim-base-image:
+ description: 'IsaacSim base image'
+ required: true
+ isaacsim-version:
+ description: 'IsaacSim version'
+ required: true
+ dockerfile-path:
+ description: 'Path to Dockerfile'
+ default: 'docker/Dockerfile.base'
+ required: false
+ cache-tag:
+ description: 'ECR cache tag'
+ default: 'cache-base'
+ required: false
+ filter-pattern:
+ description: 'Pattern to filter test files (e.g., isaaclab_tasks)'
+ default: ''
+ required: false
+ shard-index:
+ description: 'Zero-based shard index'
+ default: ''
+ required: false
+ shard-count:
+ description: 'Total number of shards'
+ default: ''
+ required: false
+ curobo-only:
+ description: 'Run only cuRobo and SkillGen tests'
+ default: 'false'
+ required: false
+ quarantined-only:
+ description: 'Run only quarantined tests'
+ default: 'false'
+ required: false
+ include-files:
+ description: 'Comma-separated list of specific test files to include'
+ default: ''
+ required: false
+ pytest-options:
+ description: 'Additional pytest options'
+ default: ''
+ required: false
+ container-name:
+ description: 'Docker container name prefix (run-id is appended automatically)'
+ required: true
+runs:
+ using: composite
+ steps:
+ # Display some details on AWS instance we're running on
+ - name: AWS Instance Info
+ shell: bash
+ run: |
+ # get instance ID for debugging purposes (if running on EC2)
+ IMDS_TOKEN=$(curl -sf -X PUT "http://169.254.169.254/latest/api/token" \
+ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") || true
+ if [ -n "$IMDS_TOKEN" ]; then
+ INSTANCE_ID=$(curl -sf -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \
+ "http://169.254.169.254/latest/meta-data/instance-id") || true
+ INSTANCE_REGION=$(curl -sf -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \
+ "http://169.254.169.254/latest/meta-data/placement/region") || true
+ INSTANCE_TYPE=$(curl -sf -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" \
+ "http://169.254.169.254/latest/meta-data/instance-type") || true
+ echo "⚪ Instance ID: ${INSTANCE_ID:-Not running on EC2}"
+ echo "⚪ Instance Region: ${INSTANCE_REGION:-Not running on EC2}"
+ echo "⚪ Instance Type: ${INSTANCE_TYPE:-Not running on EC2}"
+ echo "⚪ Connect: https://${INSTANCE_REGION}.console.aws.amazon.com/ec2-instance-connect/ssh/home?region=${INSTANCE_REGION}&connType=standard&instanceId=${INSTANCE_ID}&osUser=ubuntu&sshPort=22&addressFamily=ipv4"
+ else
+ echo "🟠 Could not obtain IMDS token, probably not running on EC2"
+ fi
+
+ - name: Record pull start time
+ id: pull-start
+ shell: bash
+ run: echo "time=$(date +%s)" >> "$GITHUB_OUTPUT"
+
+ - name: Pull image from ECR
+ uses: ./.github/actions/ecr-build-push-pull
+ with:
+ image-tag: ${{ inputs.image-tag }}
+ isaacsim-base-image: ${{ inputs.isaacsim-base-image }}
+ isaacsim-version: ${{ inputs.isaacsim-version }}
+ dockerfile-path: ${{ inputs.dockerfile-path }}
+ cache-tag: ${{ inputs.cache-tag }}
+
+ - name: Report pull duration
+ if: always()
+ shell: bash
+ run: |
+ start_time="${{ steps.pull-start.outputs.time }}"
+ if [ -z "$start_time" ]; then
+ echo "🟠 Could not calculate pull duration (start time not recorded)" >> "$GITHUB_STEP_SUMMARY"
+ exit 0
+ fi
+ elapsed=$(( $(date +%s) - start_time ))
+ printf "🔵 Image pull took %dm %ds\n" $((elapsed/60)) $((elapsed%60))
+ echo "🔵 Docker Image Pulled in ${elapsed}s" >> "$GITHUB_STEP_SUMMARY"
+
+ - name: Run Tests
+ uses: ./.github/actions/run-tests
+ with:
+ test-path: "tools"
+ result-file: "${{ github.job }}-report.xml"
+ container-name: "${{ inputs.container-name }}-${{ github.run_id }}-${{ github.run_attempt }}"
+ image-tag: ${{ inputs.image-tag }}
+ pytest-options: ${{ inputs.pytest-options }}
+ filter-pattern: ${{ inputs.filter-pattern }}
+ shard-index: ${{ inputs.shard-index }}
+ shard-count: ${{ inputs.shard-count }}
+ curobo-only: ${{ inputs.curobo-only }}
+ quarantined-only: ${{ inputs.quarantined-only }}
+ include-files: ${{ inputs.include-files }}
+ volume-mount-source: ${{ github.workspace }}
+
+ - name: Check Test Results
+ if: always()
+ shell: bash
+ run: |
+ if [ -f "reports/${{ github.job }}-report.xml" ]; then
+ if grep -qE 'failures="[1-9][0-9]*"' reports/${{ github.job }}-report.xml || grep -qE 'errors="[1-9][0-9]*"' reports/${{ github.job }}-report.xml; then
+ echo "Tests failed for PR from fork. The test report is in the logs. Failing the job."
+ exit 1
+ fi
+ else
+ echo "No test results file found. This might indicate test execution failed."
+ exit 1
+ fi
+
+ - name: Kill container on cancellation
+ if: cancelled()
+ shell: bash
+ run: |
+ CONTAINER="${{ inputs.container-name }}-${{ github.run_id }}-${{ github.run_attempt }}"
+ echo "🟠 Workflow cancelled, force-killing container ${CONTAINER}..."
+ docker kill "${CONTAINER}" 2>/dev/null || true
+ docker rm -f "${CONTAINER}" 2>/dev/null || true
+
+ - name: Cleanup old Docker images
+ if: always()
+ shell: bash
+ run: |
+ # Don't let cleanup errors fail a passing test job
+ set +e
+
+ echo "🔵 Cleaning up old Docker images..."
+
+ echo "⚪ Disk usage before cleanup:"
+ df -h /var/lib/docker
+
+ ISAACSIM_IMAGE="${{ inputs.isaacsim-base-image }}:${{ inputs.isaacsim-version }}"
+
+ # Pin the base IsaacSim image so prune -a doesn't remove it
+ ISAACSIM_IMAGE_PIN_CONTAINER="isaacsim-pin-${{ inputs.container-name }}-${{ github.run_id }}-${{ github.run_attempt }}"
+ echo "🔵 Pinning IsaacSim base image: ${ISAACSIM_IMAGE} to temporary container ${ISAACSIM_IMAGE_PIN_CONTAINER}"
+ docker create --name "${ISAACSIM_IMAGE_PIN_CONTAINER}" "${ISAACSIM_IMAGE}" true 2>/dev/null || true
+
+ echo "🔵 Removing Docker images older than 3 days..."
+ docker image prune -a -f --filter "until=72h"
+
+ echo "🔵 Removing temporary container ${ISAACSIM_IMAGE_PIN_CONTAINER}..."
+ docker rm "${ISAACSIM_IMAGE_PIN_CONTAINER}" 2>/dev/null || true
+
+ echo "🟢 Docker image cleanup complete."
+
+ echo "⚪ Disk usage after cleanup:"
+ df -h /var/lib/docker
diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml
index 46712286014..feafa86d765 100644
--- a/.github/actions/run-tests/action.yml
+++ b/.github/actions/run-tests/action.yml
@@ -31,6 +31,30 @@ inputs:
description: 'Pattern to filter test files (e.g., isaaclab_tasks)'
default: ''
required: false
+ curobo-only:
+ description: 'Run only cuRobo and SkillGen tests (requires the cuRobo Docker image)'
+ default: 'false'
+ required: false
+ quarantined-only:
+ description: 'Run only tests listed in QUARANTINED_TESTS (skipped in normal jobs)'
+ default: 'false'
+ required: false
+ include-files:
+ description: 'Comma-separated list of specific test file paths to include (e.g., source/pkg/test/test_a.py,source/pkg/test/test_b.py)'
+ default: ''
+ required: false
+ shard-index:
+ description: 'Zero-based index of this shard (used with shard-count to split tests across parallel jobs)'
+ default: ''
+ required: false
+ shard-count:
+ description: 'Total number of shards (used with shard-index to split tests across parallel jobs)'
+ default: ''
+ required: false
+ volume-mount-source:
+ description: 'Host path to bind-mount at /workspace/isaaclab (for deps-cache-hit mode)'
+ default: ''
+ required: false
runs:
using: composite
@@ -47,6 +71,12 @@ runs:
local reports_dir="$5"
local pytest_options="$6"
local filter_pattern="$7"
+ local curobo_only="$8"
+ local include_files="$9"
+ local quarantined_only="${10}"
+ local shard_index="${11}"
+ local shard_count="${12}"
+ local volume_mount_source="${13}"
echo "Running tests in: $test_path"
if [ -n "$pytest_options" ]; then
@@ -55,6 +85,15 @@ runs:
if [ -n "$filter_pattern" ]; then
echo "With filter pattern: $filter_pattern"
fi
+ if [ "$curobo_only" = "true" ]; then
+ echo "cuRobo-only mode enabled: running only cuRobo and SkillGen tests"
+ fi
+ if [ -n "$include_files" ]; then
+ echo "Include files: $include_files"
+ fi
+ if [ -n "$shard_index" ] && [ -n "$shard_count" ]; then
+ echo "Shard: $shard_index of $shard_count"
+ fi
# Create reports directory
mkdir -p "$reports_dir"
@@ -73,9 +112,33 @@ runs:
-e PYTHONIOENCODING=utf-8 \
-e TEST_RESULT_FILE=$result_file"
+ if [ "$curobo_only" = "true" ]; then
+ docker_env_vars="$docker_env_vars -e TEST_CUROBO_ONLY=true"
+ echo "Setting TEST_CUROBO_ONLY=true"
+ fi
+
+ if [ "$quarantined_only" = "true" ]; then
+ docker_env_vars="$docker_env_vars -e TEST_QUARANTINED_ONLY=true"
+ echo "Setting TEST_QUARANTINED_ONLY=true"
+ fi
+
+ if [ -n "$include_files" ]; then
+ # Strip spaces so the value is safe to embed in an unquoted docker_env_vars string.
+ # conftest.py splits on commas and strips whitespace, so compact form works fine.
+ include_files_compact="${include_files// /}"
+ docker_env_vars="$docker_env_vars -e TEST_INCLUDE_FILES=$include_files_compact"
+ echo "Setting TEST_INCLUDE_FILES=$include_files_compact"
+ fi
+
+ if [ -n "$shard_index" ] && [ -n "$shard_count" ]; then
+ docker_env_vars="$docker_env_vars -e TEST_SHARD_INDEX=$shard_index -e TEST_SHARD_COUNT=$shard_count"
+ echo "Setting TEST_SHARD_INDEX=$shard_index TEST_SHARD_COUNT=$shard_count"
+ fi
+
if [ -n "$filter_pattern" ]; then
- if [[ "$filter_pattern" == not* ]]; then
- # Handle "not pattern" case
+ if [[ "$filter_pattern" == "not "* ]]; then
+ # Handle "not " case - note the trailing space to avoid
+ # matching words that happen to start with "not".
exclude_pattern="${filter_pattern#not }"
docker_env_vars="$docker_env_vars -e TEST_EXCLUDE_PATTERN=$exclude_pattern"
echo "Setting exclude pattern: $exclude_pattern"
@@ -90,9 +153,22 @@ runs:
echo "Docker environment variables: '$docker_env_vars'"
- # Run tests in container with error handling
- echo "🚀 Starting Docker container for tests..."
- if docker run --name $container_name \
+ # Volume mount for deps-cache-hit mode: bind-mount the checked-out
+ # source code over /workspace/isaaclab instead of baking it into the image.
+ docker_volume_args=""
+ if [ -n "$volume_mount_source" ]; then
+ docker_volume_args="-v ${volume_mount_source}:/workspace/isaaclab"
+ echo "🔵 Volume-mounting ${volume_mount_source} >> /workspace/isaaclab"
+ fi
+
+ # Run tests in a detached container and follow logs. Running detached
+ # means the container lifecycle is independent of the shell - if the
+ # runner kills this step on cancellation, the `if: always()` cleanup
+ # step can still `docker kill` the container reliably.
+ # `docker logs -f` is the foreground process and is trivially killable.
+ echo "🔵 Starting Docker container for tests..."
+ docker run -d --name $container_name \
+ --init --stop-timeout 5 \
--entrypoint bash --gpus all --network=host \
--security-opt=no-new-privileges:true \
--memory=$(echo "$(free -m | awk '/^Mem:/{print $2}') * 0.9 / 1" | bc)m \
@@ -100,58 +176,128 @@ runs:
--oom-kill-disable=false \
--ulimit nofile=65536:65536 \
--ulimit nproc=4096:4096 \
+ $docker_volume_args \
$docker_env_vars \
$image_tag \
-c "
set -e
cd /workspace/isaaclab
mkdir -p tests
+ rm _isaac_sim || true
+ ln -s /isaac-sim _isaac_sim
echo 'Starting pytest with path: $test_path'
- /isaac-sim/python.sh -m pytest --ignore=tools/conftest.py $test_path $pytest_options -v --junitxml=tests/$result_file || echo 'Pytest completed with exit code: $?'
- "; then
- echo "✅ Docker container completed successfully"
+ ./isaaclab.sh -p -m pytest --ignore=tools/conftest.py --ignore=source/isaaclab/test/install_ci $test_path $pytest_options -v --junitxml=tests/$result_file
+ "
+
+ # Stream container logs to CI output (this is the killable foreground process).
+ docker logs -f $container_name &
+ local logs_pid=$!
+
+ # Wait for the container to exit and capture its exit code.
+ DOCKER_EXIT=$(docker wait $container_name) || DOCKER_EXIT=1
+
+ # Stop following logs.
+ kill $logs_pid 2>/dev/null || true
+ wait $logs_pid 2>/dev/null || true
+
+ if [ $DOCKER_EXIT -eq 0 ]; then
+ echo "🟢 Docker container completed successfully"
else
- echo "⚠️ Docker container failed, but continuing to copy results..."
+ echo "🟠 Docker container failed (exit $DOCKER_EXIT), but continuing to copy results..."
fi
- # Copy test results with error handling
- echo "📋 Attempting to copy test results..."
- if docker cp $container_name:/workspace/isaaclab/tests/$result_file "$reports_dir/$result_file" 2>/dev/null; then
- echo "✅ Test results copied successfully"
+ # Copy test results with error handling.
+ # When volume-mounted, test output lands on the host filesystem directly
+ # (docker cp cannot see bind-mounted paths after the container stops).
+ echo "🔵 Attempting to copy test results..."
+ if [ -n "$volume_mount_source" ] && [ -f "${volume_mount_source}/tests/$result_file" ]; then
+ cp "${volume_mount_source}/tests/$result_file" "$reports_dir/$result_file"
+ echo "🟢 Test results copied from volume mount to $reports_dir/$result_file"
+ elif cp_err=$(docker cp $container_name:/workspace/isaaclab/tests/$result_file "$reports_dir/$result_file" 2>&1); then
+ echo "🟢 Test results copied successfully to $reports_dir/$result_file"
else
- echo "❌ Failed to copy specific result file, trying to copy all test results..."
- if docker cp $container_name:/workspace/isaaclab/tests/ "$reports_dir/" 2>/dev/null; then
- echo "✅ All test results copied successfully"
+ echo "🔴 Failed to copy specific result file: $cp_err"
+ echo "🔴 Trying to copy all test results..."
+ if cp_err=$(docker cp $container_name:/workspace/isaaclab/tests/ "$reports_dir/" 2>&1); then
+ echo "🟢 All test results copied successfully to $reports_dir/"
# Look for any XML files and use the first one found
if [ -f "$reports_dir/full_report.xml" ]; then
mv "$reports_dir/full_report.xml" "$reports_dir/$result_file"
- echo "✅ Found and renamed full_report.xml to $result_file"
- elif [ -f "$reports_dir/test-reports-"*".xml" ]; then
- # Combine individual test reports if no full report exists
- echo "📊 Combining individual test reports..."
- echo '' > "$reports_dir/$result_file"
+ echo "🟢 Found and renamed full_report.xml to $result_file"
+ elif ls "$reports_dir"/test-reports-*.xml 1>/dev/null 2>&1; then
+ # Combine individual test reports if no full report exists.
+ # Extract each block intact to produce valid JUnit XML.
+ echo "🔵 Combining individual test reports..."
+ echo '' > "$reports_dir/$result_file"
+ echo '' >> "$reports_dir/$result_file"
for xml_file in "$reports_dir"/test-reports-*.xml; do
if [ -f "$xml_file" ]; then
echo " Processing: $xml_file"
- sed '1d; /^> "$reports_dir/$result_file" 2>/dev/null || true
+ # Copy everything between and (inclusive)
+ sed -n '//p' "$xml_file" >> "$reports_dir/$result_file" || echo "🟠 Warning: failed to extract testsuite from $xml_file"
fi
done
echo '' >> "$reports_dir/$result_file"
- echo "✅ Combined individual test reports into $result_file"
+ echo "🟢 Combined individual test reports into $result_file"
else
- echo "❌ No test result files found, creating fallback"
+ echo "🔴 No test result files found, creating fallback"
echo "Container may have failed to generate any results" > "$reports_dir/$result_file"
fi
else
- echo "❌ Failed to copy any test results, creating fallback"
+ echo "🔴 Failed to copy any test results, creating fallback"
echo "Container may have failed to generate results" > "$reports_dir/$result_file"
fi
fi
+ # Copy comparison images (saved by test_rendering_correctness.py).
+ local img_dir="$reports_dir/comparison-images"
+ if [ -n "$volume_mount_source" ] && [ -d "${volume_mount_source}/tests/comparison-images" ]; then
+ cp -r "${volume_mount_source}/tests/comparison-images" "$img_dir"
+ echo "🟢 Comparison images copied to $img_dir"
+ elif docker cp "$container_name:/workspace/isaaclab/tests/comparison-images" "$img_dir" 2>/dev/null; then
+ echo "🟢 Comparison images copied from container to $img_dir"
+ fi
+
# Clean up container
- echo "🧹 Cleaning up Docker container..."
- docker rm $container_name 2>/dev/null || echo "⚠️ Container cleanup failed, but continuing..."
+ echo "🔵 Cleaning up Docker container..."
+ docker rm $container_name 2>/dev/null || echo "🟠 Container cleanup failed, but continuing..."
+
+ return $DOCKER_EXIT
}
# Call the function with provided parameters
- run_tests "${{ inputs.test-path }}" "${{ inputs.result-file }}" "${{ inputs.container-name }}" "${{ inputs.image-tag }}" "${{ inputs.reports-dir }}" "${{ inputs.pytest-options }}" "${{ inputs.filter-pattern }}"
+ run_tests "${{ inputs.test-path }}" "${{ inputs.result-file }}" "${{ inputs.container-name }}" "${{ inputs.image-tag }}" "${{ inputs.reports-dir }}" "${{ inputs.pytest-options }}" "${{ inputs.filter-pattern }}" "${{ inputs.curobo-only }}" "${{ inputs.include-files }}" "${{ inputs.quarantined-only }}" "${{ inputs.shard-index }}" "${{ inputs.shard-count }}" "${{ inputs.volume-mount-source }}"
+
+ - name: Write job summary
+ if: always()
+ shell: bash
+ run: |
+ report="${{ inputs.reports-dir }}/${{ inputs.result-file }}"
+ if [ ! -f "$report" ]; then
+ echo "🟠 No test report found" >> "$GITHUB_STEP_SUMMARY"
+ exit 0
+ fi
+
+ # Parse JUnit XML and produce a markdown summary.
+ # Exit code 2 means the report was corrupt/unreadable - surface the
+ # error in the summary but don't mask the real test exit code.
+ if ! python3 .github/actions/run-tests/junit_summary.py "$report" >> "$GITHUB_STEP_SUMMARY"; then
+ echo "::warning::junit_summary.py failed to parse $report - test results may be missing from the summary"
+ fi
+
+ - name: Upload comparison images
+ if: always()
+ uses: actions/upload-artifact@v7
+ with:
+ name: comparison-images-${{ inputs.container-name }}
+ path: ${{ inputs.reports-dir }}/comparison-images/
+ if-no-files-found: ignore
+ retention-days: 7
+
+ - name: Clean up Docker container
+ if: always()
+ shell: bash
+ run: |
+ echo "🔵 Cleaning up Docker container..."
+ docker kill "${{ inputs.container-name }}" 2>/dev/null || true
+ docker rm -f "${{ inputs.container-name }}" 2>/dev/null || true
diff --git a/.github/actions/run-tests/junit_summary.py b/.github/actions/run-tests/junit_summary.py
new file mode 100755
index 00000000000..70480acccf7
--- /dev/null
+++ b/.github/actions/run-tests/junit_summary.py
@@ -0,0 +1,134 @@
+#!/usr/bin/env python3
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+"""Parse a JUnit XML report and print a markdown summary (for $GITHUB_STEP_SUMMARY)."""
+
+import sys
+import xml.etree.ElementTree as ET
+
+if len(sys.argv) < 2:
+ print("Usage: junit_summary.py ", file=sys.stderr)
+ sys.exit(1)
+
+try:
+ tree = ET.parse(sys.argv[1])
+ root = tree.getroot()
+except ET.ParseError as exc:
+ print(f"🔴 Failed to parse test report: {exc}")
+ sys.exit(0) # non-fatal so the step summary still renders
+except OSError as exc:
+ print(f"🔴 Failed to read test report: {exc}")
+ sys.exit(0)
+
+passed, failed, errored, skipped = [], [], [], []
+# Keyed by (test_name, label) -> {"diff_pct": str, "ssim": str, "passed": bool}
+comparison_scores = {}
+total_time = 0.0
+
+
+def safe_float(val, default=0.0):
+ try:
+ return float(val)
+ except (ValueError, TypeError):
+ return default
+
+
+for tc in root.iter("testcase"):
+ classname = tc.get("classname", "")
+ tc_name = tc.get("name", "unknown")
+ name = f"{classname}.{tc_name}" if classname else tc_name
+ t = safe_float(tc.get("time", 0))
+ total_time += t
+ tc_failed = tc.find("failure") is not None
+ tc_errored = tc.find("error") is not None
+ if tc_failed:
+ failed.append((name, t, tc.find("failure").get("message", "")))
+ elif tc_errored:
+ errored.append((name, t, tc.find("error").get("message", "")))
+ elif (skip_el := tc.find("skipped")) is not None:
+ skipped.append((name, t, skip_el.get("message", "")))
+ else:
+ passed.append((name, t))
+
+ # Collect diff_pct:*, ssim:*, and img_*:* properties emitted by test_rendering_correctness.
+ props = tc.find("properties")
+ if props is not None:
+ for prop in props.findall("property"):
+ prop_name = prop.get("name", "")
+ for prefix in ("diff_pct:", "ssim:", "threshold:", "img_result:", "img_golden:"):
+ if prop_name.startswith(prefix):
+ label = prop_name[len(prefix) :]
+ key = (name, label)
+ if key not in comparison_scores:
+ comparison_scores[key] = {
+ "diff_pct": "",
+ "ssim": "",
+ "threshold": "",
+ "passed": not (tc_failed or tc_errored),
+ "img_result": "",
+ "img_golden": "",
+ }
+ field = prefix.rstrip(":")
+ comparison_scores[key][field] = prop.get("value", "")
+
+mins, secs = divmod(total_time, 60)
+time_str = f"{int(mins)}m:{secs:.0f}s"
+
+
+def sanitize_msg(msg, max_len=300):
+ """Collapse newlines, escape pipe characters, and truncate for markdown tables."""
+ return msg.replace("\n", " ").replace("\r", "").replace("|", "\\|")[:max_len]
+
+
+def fmt_name(name):
+ """Format a test name for markdown: strip ``source.`` prefix, allow word-breaking."""
+ if name.startswith("source."):
+ name = name[len("source.") :]
+ # Insert zero-width spaces after dots and brackets so tables can wrap.
+ return name.replace(".", ".\u200b").replace("[", "[\u200b").replace("]", "]\u200b")
+
+
+if failed or errored:
+ print(f"🔴 {len(failed) + len(errored)} FAILED, {len(passed)} PASSED ({time_str})")
+elif not passed and not skipped:
+ print("🟠 No test cases found in report")
+
+if failed or errored:
+ print("")
+ print("| Status | Test | Time | Message |")
+ print("|--------|------|------|---------|")
+ for name, t, msg in sorted(failed, key=lambda x: x[1], reverse=True):
+ print(f"| ASSERTION | {fmt_name(name)} | {t:.1f}s | {sanitize_msg(msg)} |")
+ for name, t, msg in sorted(errored, key=lambda x: x[1], reverse=True):
+ print(f"| ERROR | {fmt_name(name)} | {t:.1f}s | {sanitize_msg(msg)} |")
+
+if passed:
+ print(f"\n🟢 {len(passed)} PASSED ({time_str})
")
+ print("")
+ print("
")
+ print("")
+ print("| Test | Time |")
+ print("|------|------|")
+ for name, t in sorted(passed, key=lambda x: x[1], reverse=True):
+ print(f"| {fmt_name(name)} | {t:.1f}s |")
+ print("")
+ print(" ")
+
+if skipped:
+ print(f"\n🟠 {len(skipped)} SKIPPED
")
+ print("")
+ print("
")
+ print("")
+ print("| Test | Reason |")
+ print("|------|--------|")
+ for name, t, msg in skipped:
+ print(f"| {fmt_name(name)} | {sanitize_msg(msg)} |")
+ print("")
+ print(" ")
+
+if comparison_scores:
+ print("\n")
+ print("🔵 GOLDEN vs ACTUAL report is attached as artifact (at the bottom of this page).")
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
new file mode 100644
index 00000000000..0fcef181878
--- /dev/null
+++ b/.github/workflows/build.yaml
@@ -0,0 +1,773 @@
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# region help
+# Test job gating summary
+#
+# +------------------------------------+-----------------------------------------------------+
+# | Job | Gate (any match triggers the job) |
+# +------------------------------------+-----------------------------------------------------+
+# | test-isaaclab-tasks (x3 shards) | isaaclab-tasks | isaaclab-core | infra |
+# | test-isaaclab-core (x3 shards) | isaaclab-core | infra |
+# | test-isaaclab-rl | isaaclab-rl | isaaclab-core | infra |
+# | test-isaaclab-mimic | isaaclab-mimic | isaaclab-core | infra |
+# | test-isaaclab-contrib | isaaclab-contrib | isaaclab-core | infra |
+# | test-isaaclab-teleop | isaaclab-teleop | isaaclab-core | infra |
+# | test-isaaclab-visualizers | isaaclab-visualizers | isaaclab-core | infra |
+# | test-isaaclab-assets | isaaclab-assets | isaaclab-core | infra |
+# | test-isaaclab-newton | isaaclab-newton | isaaclab-core | infra |
+# | test-isaaclab-physx | isaaclab-physx | isaaclab-core | infra |
+# | test-isaaclab-ov | isaaclab-ov | isaaclab-core | infra |
+# | test-environments-training | isaaclab-tasks | isaaclab-core | infra |
+# | test-curobo (needs build-curobo) | isaaclab-mimic | isaaclab-core | infra |
+# | test-skillgen (needs build-curobo) | isaaclab-mimic | isaaclab-tasks | isaaclab-core |
+# | | | infra |
+# | test-quarantined | vars.RUN_QUARANTINED_TESTS == "true" |
+# | build-curobo | isaaclab-mimic | isaaclab-tasks | isaaclab-core |
+# | | | infra |
+# +------------------------------------+-----------------------------------------------------+
+#
+# =============================================================================
+# CI DEBUGGING TIPS
+# =============================================================================
+#
+# 1. DISABLE A TEST JOB (to isolate a specific job):
+# Change the job's `if:` clause to `if: false`
+# Example:
+# test-isaaclab-tasks:
+# ...
+# if: false # TEMP: Disabled for debugging
+#
+# 2. RUN ONLY SPECIFIC TEST FILES (within a job):
+# Add `include-files:` parameter to run-package-tests action
+# Example:
+# - uses: ./.github/actions/run-package-tests
+# with:
+# ...
+# include-files: "test_rigid_object_collection.py" # Comma-separated
+#
+# 3. SKIP CONCURRENCY WAIT (run immediately without waiting for other runs):
+# Comment out the concurrency block:
+# # concurrency:
+# # group: ${{ github.workflow }}-${{ github.ref }}
+# # cancel-in-progress: true
+#
+# 4. TEST LOCALLY LIKE CI:
+# docker run -it --rm --gpus all --network=host --entrypoint bash \
+# -e OMNI_KIT_ACCEPT_EULA=yes -e ACCEPT_EULA=Y -e ISAAC_SIM_HEADLESS=1 \
+# -e TEST_FILTER_PATTERN="isaaclab_physx" \
+# -e TEST_INCLUDE_FILES="test_rigid_object_collection.py" \
+# -v "$PWD":/workspace/isaaclab isaac-lab-base:latest \
+# -c 'cd /workspace/isaaclab && /isaac-sim/python.sh -m pytest tools -v'
+#
+# Remember to REVERT all temporary changes before merging!
+# =============================================================================
+#endregion
+
+name: Docker + Tests
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+ paths:
+ - 'source/**'
+ - 'docker/**'
+ - 'tools/**'
+ - 'apps/**'
+ - '.github/workflows/build.yaml'
+ - '.github/actions/**'
+ branches:
+ - main
+ - develop
+ - 'release/**'
+ workflow_dispatch:
+
+# Concurrency control to prevent parallel runs on the same PR
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+ pull-requests: write
+ checks: write
+ issues: read
+
+env:
+ NGC_API_KEY: ${{ secrets.NGC_API_KEY }}
+ # On merge to main defaults will point to "nvcr.io/nvidia/isaac-sim:6.0.0"
+ ISAACSIM_BASE_IMAGE: 'nvcr.io/nvidian/isaac-sim' # ${{ vars.ISAACSIM_BASE_IMAGE || 'nvcr.io/nvidia/isaac-sim' }}
+ # Pinned to the Apr 8 nightly digest that last passed CI, while latest-develop is broken.
+ # TODO(AntoineRichard): Revert to 'latest-develop' once the nightly is fixed.
+ ISAACSIM_BASE_VERSION: 'latest-develop' # ${{ vars.ISAACSIM_BASE_VERSION || '6.0.0' }}
+ DOCKER_IMAGE_TAG: isaac-lab-dev:${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}-${{ github.sha }}
+ # To run quarantined tests, create a GitHub repo variable named
+ # RUN_QUARANTINED_TESTS and set it to 'true'. The test-quarantined
+ # job is skipped when the variable is absent or not 'true'.
+
+jobs:
+ detect-changes:
+ name: Detect Changes
+ runs-on: ubuntu-latest
+ outputs:
+ isaaclab-core: ${{ steps.check.outputs.isaaclab-core }}
+ isaaclab-physx: ${{ steps.check.outputs.isaaclab-physx }}
+ isaaclab-newton: ${{ steps.check.outputs.isaaclab-newton }}
+ isaaclab-tasks: ${{ steps.check.outputs.isaaclab-tasks }}
+ isaaclab-rl: ${{ steps.check.outputs.isaaclab-rl }}
+ isaaclab-mimic: ${{ steps.check.outputs.isaaclab-mimic }}
+ isaaclab-contrib: ${{ steps.check.outputs.isaaclab-contrib }}
+ isaaclab-teleop: ${{ steps.check.outputs.isaaclab-teleop }}
+ isaaclab-visualizers: ${{ steps.check.outputs.isaaclab-visualizers }}
+ isaaclab-assets: ${{ steps.check.outputs.isaaclab-assets }}
+ isaaclab-ov: ${{ steps.check.outputs.isaaclab-ov }}
+ infra: ${{ steps.check.outputs.infra }}
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+
+ - name: Detect changed files and packages
+ id: check
+ run: |
+ set -euo pipefail
+
+ # For non-PR events, run all tests
+ if [ "${{ github.event_name }}" != "pull_request" ]; then
+ for pkg in isaaclab-core isaaclab-physx isaaclab-newton isaaclab-tasks \
+ isaaclab-rl isaaclab-mimic isaaclab-contrib isaaclab-teleop \
+ isaaclab-visualizers isaaclab-assets isaaclab-ov infra; do
+ echo "$pkg=true" >> "$GITHUB_OUTPUT"
+ done
+ exit 0
+ fi
+
+ # Fetch the PR base branch tip to diff against
+ git fetch --depth=1 origin "${{ github.event.pull_request.base.ref }}"
+ changed=$(git diff --name-only FETCH_HEAD HEAD)
+
+ if [ -z "$changed" ]; then
+ echo "::warning::No changed files detected between FETCH_HEAD and HEAD - running all tests as a safety measure"
+ for pkg in isaaclab-core isaaclab-physx isaaclab-newton isaaclab-tasks \
+ isaaclab-rl isaaclab-mimic isaaclab-contrib isaaclab-teleop \
+ isaaclab-visualizers isaaclab-assets isaaclab-ov infra; do
+ echo "$pkg=true" >> "$GITHUB_OUTPUT"
+ done
+ exit 0
+ fi
+
+ has() {
+ echo "$changed" | grep -qE "$1"
+ local rc=$?
+ if [ $rc -eq 0 ]; then echo true
+ elif [ $rc -eq 1 ]; then echo false
+ else
+ echo "::error::grep failed with exit $rc for pattern: $1"
+ exit 1
+ fi
+ }
+
+ # Detect per-package changes
+ core=$(has '^source/isaaclab/')
+ physx=$(has '^source/isaaclab_physx/')
+ newton=$(has '^source/isaaclab_newton/')
+ tasks=$(has '^source/isaaclab_tasks/')
+
+ # Changes in apps/ trigger: core, physx, newton, tasks
+ apps=$(has '^apps/')
+ if [ "$apps" = "true" ]; then
+ core=true
+ physx=true
+ newton=true
+ tasks=true
+ fi
+
+ echo "isaaclab-core=$core" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-physx=$physx" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-newton=$newton" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-tasks=$tasks" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-rl=$(has '^source/isaaclab_rl/')" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-mimic=$(has '^source/isaaclab_mimic/')" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-contrib=$(has '^source/isaaclab_contrib/')" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-teleop=$(has '^source/isaaclab_teleop/')" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-visualizers=$(has '^source/isaaclab_visualizers/')" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-assets=$(has '^source/isaaclab_assets/')" >> "$GITHUB_OUTPUT"
+ echo "isaaclab-ov=$(has '^source/isaaclab_ov/')" >> "$GITHUB_OUTPUT"
+ echo "infra=$(has '^(\.github/|docker/|tools/|scripts/)')" >> "$GITHUB_OUTPUT"
+
+ echo ""
+ echo "CHANGED FILES:"
+ echo "$changed" | while IFS= read -r f; do
+ case "$f" in
+ source/isaaclab/*) echo "$f (isaaclab-core)" ;;
+ source/isaaclab_physx/*) echo "$f (isaaclab-physx)" ;;
+ source/isaaclab_newton/*) echo "$f (isaaclab-newton)" ;;
+ source/isaaclab_tasks/*) echo "$f (isaaclab-tasks)" ;;
+ source/isaaclab_rl/*) echo "$f (isaaclab-rl)" ;;
+ source/isaaclab_mimic/*) echo "$f (isaaclab-mimic)" ;;
+ source/isaaclab_contrib/*) echo "$f (isaaclab-contrib)" ;;
+ source/isaaclab_teleop/*) echo "$f (isaaclab-teleop)" ;;
+ source/isaaclab_visualizers/*) echo "$f (isaaclab-visualizers)" ;;
+ source/isaaclab_assets/*) echo "$f (isaaclab-assets)" ;;
+ source/isaaclab_ov/*) echo "$f (isaaclab-ov)" ;;
+ .github/*|docker/*|tools/*|scripts/*) echo "$f (infra)" ;;
+ apps/*) echo "$f (apps - core/physx/newton/tasks)" ;;
+ *) echo "$f" ;;
+ esac
+ done
+ echo ""
+ echo "CHANGED PACKAGES:"
+ cat "$GITHUB_OUTPUT"
+
+ # Write job summary visible on the GH Actions UI
+ {
+ echo "| File | Package |"
+ echo "|------|---------|"
+ echo "$changed" | while IFS= read -r f; do
+ case "$f" in
+ source/isaaclab/*) echo "| \`$f\` | isaaclab-core |" ;;
+ source/isaaclab_physx/*) echo "| \`$f\` | isaaclab-physx |" ;;
+ source/isaaclab_newton/*) echo "| \`$f\` | isaaclab-newton |" ;;
+ source/isaaclab_tasks/*) echo "| \`$f\` | isaaclab-tasks |" ;;
+ source/isaaclab_rl/*) echo "| \`$f\` | isaaclab-rl |" ;;
+ source/isaaclab_mimic/*) echo "| \`$f\` | isaaclab-mimic |" ;;
+ source/isaaclab_contrib/*) echo "| \`$f\` | isaaclab-contrib |" ;;
+ source/isaaclab_teleop/*) echo "| \`$f\` | isaaclab-teleop |" ;;
+ source/isaaclab_visualizers/*) echo "| \`$f\` | isaaclab-visualizers |" ;;
+ source/isaaclab_assets/*) echo "| \`$f\` | isaaclab-assets |" ;;
+ source/isaaclab_ov/*) echo "| \`$f\` | isaaclab-ov |" ;;
+ .github/*|docker/*|tools/*|scripts/*) echo "| \`$f\` | infra |" ;;
+ apps/*) echo "| \`$f\` | apps - core/physx/newton/tasks |" ;;
+ *) echo "| \`$f\` | - |" ;;
+ esac
+ done
+ } >> "$GITHUB_STEP_SUMMARY"
+
+ #region build jobs
+ build:
+ name: Build Base Docker Image
+ runs-on: [self-hosted, gpu]
+ needs: [detect-changes]
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+
+ - name: Build and push to ECR
+ uses: ./.github/actions/ecr-build-push-pull
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ dockerfile-path: docker/Dockerfile.base
+ cache-tag: cache-base
+
+ build-curobo:
+ name: Build cuRobo Docker Image
+ runs-on: [self-hosted, gpu]
+ needs: [detect-changes]
+ if: >-
+ needs.detect-changes.outputs.isaaclab-mimic == 'true' ||
+ needs.detect-changes.outputs.isaaclab-tasks == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+
+ - name: Build and push to ECR
+ uses: ./.github/actions/ecr-build-push-pull
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}-curobo
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ dockerfile-path: docker/Dockerfile.curobo
+ cache-tag: cache-curobo
+ #endregion
+
+ #region test jobs
+ test-isaaclab-tasks:
+ name: isaaclab_tasks [1/3]
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ continue-on-error: true
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-tasks == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_tasks"
+ shard-index: "0"
+ shard-count: "3"
+ container-name: isaac-lab-tasks-1-test
+
+ test-isaaclab-tasks-2:
+ name: isaaclab_tasks [2/3]
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ continue-on-error: true
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-tasks == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_tasks"
+ shard-index: "1"
+ shard-count: "3"
+ container-name: isaac-lab-tasks-2-test
+
+ test-isaaclab-tasks-3:
+ name: isaaclab_tasks [3/3]
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ continue-on-error: true
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-tasks == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_tasks"
+ shard-index: "2"
+ shard-count: "3"
+ container-name: isaac-lab-tasks-3-test
+
+ test-isaaclab-core:
+ name: isaaclab (core) [1/3]
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "not isaaclab_"
+ shard-index: "0"
+ shard-count: "3"
+ container-name: isaac-lab-core-1-test
+
+ test-isaaclab-core-2:
+ name: isaaclab (core) [2/3]
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "not isaaclab_"
+ shard-index: "1"
+ shard-count: "3"
+ container-name: isaac-lab-core-2-test
+
+ test-isaaclab-core-3:
+ name: isaaclab (core) [3/3]
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "not isaaclab_"
+ shard-index: "2"
+ shard-count: "3"
+ container-name: isaac-lab-core-3-test
+
+ test-isaaclab-rl:
+ name: isaaclab_rl
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-rl == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_rl"
+ container-name: isaac-lab-rl-test
+
+ test-isaaclab-mimic:
+ name: isaaclab_mimic
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-mimic == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_mimic"
+ container-name: isaac-lab-mimic-test
+
+ test-isaaclab-contrib:
+ name: isaaclab_contrib
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-contrib == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_contrib"
+ container-name: isaac-lab-contrib-test
+
+ test-isaaclab-teleop:
+ name: isaaclab_teleop
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-teleop == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_teleop"
+ container-name: isaac-lab-teleop-test
+
+ test-isaaclab-visualizers:
+ name: isaaclab_visualizers
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-visualizers == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_visualizers"
+ container-name: isaac-lab-visualizers-test
+
+ test-isaaclab-assets:
+ name: isaaclab_assets
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-assets == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_assets"
+ container-name: isaac-lab-assets-test
+
+ test-isaaclab-newton:
+ name: isaaclab_newton
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-newton == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_newton"
+ container-name: isaac-lab-newton-test
+
+ test-isaaclab-physx:
+ name: isaaclab_physx
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-physx == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_physx"
+ container-name: isaac-lab-physx-test
+
+ test-isaaclab-ov:
+ name: isaaclab_ov
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 180
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-ov == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_ov"
+ container-name: isaac-lab-ov-test
+
+ test-curobo:
+ name: test-curobo
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 120
+ continue-on-error: true
+ needs: [build-curobo, detect-changes]
+ if: >-
+ always() && needs.build-curobo.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-mimic == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}-curobo
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ dockerfile-path: docker/Dockerfile.curobo
+ cache-tag: cache-curobo
+ include-files: "test_curobo_planner_franka.py,test_curobo_planner_cube_stack.py,test_pink_ik.py"
+ container-name: isaac-lab-curobo-test
+
+ test-skillgen:
+ name: test-skillgen
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 120
+ continue-on-error: true
+ needs: [build-curobo, detect-changes]
+ if: >-
+ always() && needs.build-curobo.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-mimic == 'true' ||
+ needs.detect-changes.outputs.isaaclab-tasks == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}-curobo
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ dockerfile-path: docker/Dockerfile.curobo
+ cache-tag: cache-curobo
+ include-files: "test_generate_dataset_skillgen.py,test_environments_skillgen.py,test_environments_automate.py"
+ container-name: isaac-lab-skillgen-test
+
+ test-environments-training:
+ name: "environments_training"
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 300
+ continue-on-error: true
+ needs: [build, detect-changes]
+ if: >-
+ always() && needs.build.result == 'success' && (
+ needs.detect-changes.outputs.isaaclab-tasks == 'true' ||
+ needs.detect-changes.outputs.isaaclab-core == 'true' ||
+ needs.detect-changes.outputs.infra == 'true'
+ )
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+ - uses: ./.github/actions/run-package-tests
+ with:
+ image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+ isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+ isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+ filter-pattern: "isaaclab_tasks"
+ include-files: "test_environments_training.py"
+ container-name: isaac-lab-environments-training-test
+ #endregion
+
+#region disabled quarantined tests
+# test-quarantined:
+# name: "Quarantined Tests"
+# runs-on: [self-hosted, gpu]
+# timeout-minutes: 180
+# continue-on-error: true
+# needs: [build, detect-changes]
+# if: >-
+# always() && needs.build.result == 'success' &&
+# vars.RUN_QUARANTINED_TESTS == 'true'
+# steps:
+# - uses: actions/checkout@v6
+# with:
+# fetch-depth: 1
+# lfs: true
+# - uses: ./.github/actions/run-package-tests
+# with:
+# image-tag: ${{ env.DOCKER_IMAGE_TAG }}
+# isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
+# isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
+# quarantined-only: "true"
+# container-name: isaac-lab-quarantined-test
+#endregion
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index cbaa8f7b8e9..00000000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,222 +0,0 @@
-# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
-# All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-
-name: Build and Test
-
-on:
- pull_request:
- branches:
- - devel
- - main
- - 'release/**'
-
-# Concurrency control to prevent parallel runs on the same PR
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-permissions:
- contents: read
- pull-requests: write
- checks: write
- issues: read
-
-env:
- NGC_API_KEY: ${{ secrets.NGC_API_KEY }}
- ISAACSIM_BASE_IMAGE: ${{ vars.ISAACSIM_BASE_IMAGE || 'nvcr.io/nvidia/isaac-sim' }}
- ISAACSIM_BASE_VERSION: ${{ vars.ISAACSIM_BASE_VERSION || '5.1.0' }}
- DOCKER_IMAGE_TAG: isaac-lab-dev:${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}-${{ github.sha }}
-
-jobs:
- test-isaaclab-tasks:
- runs-on: [self-hosted, gpu]
- timeout-minutes: 180
- continue-on-error: true
-
- steps:
- - name: Checkout Code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- lfs: true
-
- - name: Build Docker Image
- uses: ./.github/actions/docker-build
- with:
- image-tag: ${{ env.DOCKER_IMAGE_TAG }}
- isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
- isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
-
- - name: Run IsaacLab Tasks Tests
- uses: ./.github/actions/run-tests
- with:
- test-path: "tools"
- result-file: "isaaclab-tasks-report.xml"
- container-name: "isaac-lab-tasks-test-$$"
- image-tag: ${{ env.DOCKER_IMAGE_TAG }}
- pytest-options: ""
- filter-pattern: "isaaclab_tasks"
-
- - name: Copy Test Results from IsaacLab Tasks Container
- run: |
- CONTAINER_NAME="isaac-lab-tasks-test-$$"
- if docker ps -a | grep -q $CONTAINER_NAME; then
- echo "Copying test results from IsaacLab Tasks container..."
- docker cp $CONTAINER_NAME:/workspace/isaaclab/tests/isaaclab-tasks-report.xml reports/ 2>/dev/null || echo "No test results to copy from IsaacLab Tasks container"
- fi
-
- - name: Upload IsaacLab Tasks Test Results
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: isaaclab-tasks-test-results
- path: reports/isaaclab-tasks-report.xml
- retention-days: 1
- compression-level: 9
-
- - name: Check Test Results for Fork PRs
- if: github.event.pull_request.head.repo.full_name != github.repository
- run: |
- if [ -f "reports/isaaclab-tasks-report.xml" ]; then
- # Check if the test results contain any failures
- if grep -q 'failures="[1-9]' reports/isaaclab-tasks-report.xml || grep -q 'errors="[1-9]' reports/isaaclab-tasks-report.xml; then
- echo "Tests failed for PR from fork. The test report is in the logs. Failing the job."
- exit 1
- fi
- else
- echo "No test results file found. This might indicate test execution failed."
- exit 1
- fi
-
- test-general:
- runs-on: [self-hosted, gpu]
- timeout-minutes: 180
-
- steps:
- - name: Checkout Code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- lfs: true
-
- - name: Build Docker Image
- uses: ./.github/actions/docker-build
- with:
- image-tag: ${{ env.DOCKER_IMAGE_TAG }}
- isaacsim-base-image: ${{ env.ISAACSIM_BASE_IMAGE }}
- isaacsim-version: ${{ env.ISAACSIM_BASE_VERSION }}
-
- - name: Run General Tests
- id: run-general-tests
- uses: ./.github/actions/run-tests
- with:
- test-path: "tools"
- result-file: "general-tests-report.xml"
- container-name: "isaac-lab-general-test-$$"
- image-tag: ${{ env.DOCKER_IMAGE_TAG }}
- pytest-options: ""
- filter-pattern: "not isaaclab_tasks"
-
- - name: Copy Test Results from General Tests Container
- run: |
- CONTAINER_NAME="isaac-lab-general-test-$$"
- if docker ps -a | grep -q $CONTAINER_NAME; then
- echo "Copying test results from General Tests container..."
- docker cp $CONTAINER_NAME:/workspace/isaaclab/tests/general-tests-report.xml reports/ 2>/dev/null || echo "No test results to copy from General Tests container"
- fi
-
- - name: Upload General Test Results
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: general-test-results
- path: reports/general-tests-report.xml
- retention-days: 1
- compression-level: 9
-
- - name: Check Test Results for Fork PRs
- if: github.event.pull_request.head.repo.full_name != github.repository
- run: |
- if [ -f "reports/general-tests-report.xml" ]; then
- # Check if the test results contain any failures
- if grep -q 'failures="[1-9]' reports/general-tests-report.xml || grep -q 'errors="[1-9]' reports/general-tests-report.xml; then
- echo "Tests failed for PR from fork. The test report is in the logs. Failing the job."
- exit 1
- fi
- else
- echo "No test results file found. This might indicate test execution failed."
- exit 1
- fi
-
- combine-results:
- needs: [test-isaaclab-tasks, test-general]
- runs-on: [self-hosted, gpu]
- if: always()
-
- steps:
- - name: Checkout Code
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- lfs: false
-
- - name: Create Reports Directory
- run: |
- mkdir -p reports
-
- - name: Download Test Results
- uses: actions/download-artifact@v4
- with:
- name: isaaclab-tasks-test-results
- path: reports/
- continue-on-error: true
-
- - name: Download General Test Results
- uses: actions/download-artifact@v4
- with:
- name: general-test-results
- path: reports/
-
- - name: Combine All Test Results
- uses: ./.github/actions/combine-results
- with:
- tests-dir: "reports"
- output-file: "reports/combined-results.xml"
-
- - name: Upload Combined Test Results
- uses: actions/upload-artifact@v4
- if: always()
- with:
- name: pr-${{ github.event.pull_request.number }}-combined-test-results
- path: reports/combined-results.xml
- retention-days: 7
- compression-level: 9
-
- - name: Comment on Test Results
- id: test-reporter
- if: github.event.pull_request.head.repo.full_name == github.repository
- uses: EnricoMi/publish-unit-test-result-action@v2
- with:
- files: "reports/combined-results.xml"
- check_name: "Tests Summary"
- comment_mode: changes
- comment_title: "Test Results Summary"
- report_individual_runs: false
- deduplicate_classes_by_file_name: true
- compare_to_earlier_commit: true
- fail_on: errors
- action_fail_on_inconclusive: true
-
- - name: Report Test Results
- if: github.event.pull_request.head.repo.full_name == github.repository
- uses: dorny/test-reporter@v1
- with:
- name: IsaacLab Build and Test Results
- path: reports/combined-results.xml
- reporter: java-junit
- fail-on-error: true
- only-summary: false
- max-annotations: '50'
- report-title: "IsaacLab Test Results - ${{ github.workflow }}"
diff --git a/.github/workflows/check-links.yml b/.github/workflows/check-links.yml
index a5f91e93403..a7843878234 100644
--- a/.github/workflows/check-links.yml
+++ b/.github/workflows/check-links.yml
@@ -3,25 +3,18 @@
#
# SPDX-License-Identifier: BSD-3-Clause
-name: Check Documentation Links
+name: Documentation Links
on:
- # Run on pull requests that modify documentation
+ # Run on all pull requests
pull_request:
- paths:
- - 'docs/**'
- - '**.md'
- - '.github/workflows/check-links.yml'
# Run on pushes to main branches
push:
branches:
- main
- - devel
+ - develop
- 'release/**'
- paths:
- - 'docs/**'
- - '**.md'
- - '.github/workflows/check-links.yml'
+ - 'feature/isaacsim-6-0'
# Allow manual trigger
workflow_dispatch:
# Run weekly to catch external links that break over time
@@ -39,11 +32,34 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
- fetch-depth: 0
+ fetch-depth: 2
+ filter: tree:0
+
+ - name: Check if latest commit touched documentation
+ id: check_docs
+ run: |
+ # Get the files changed by this PR/commit.
+ # For PRs: HEAD is the merge commit, HEAD^1 is the base branch tip.
+ # Diffing HEAD^1..HEAD shows exactly what the PR introduces - files only
+ # changed on the base branch (not by the PR) are identical in both and
+ # won't appear. Works for push events too (last commit vs its parent).
+ CHANGED=$(git diff --name-only HEAD^1 HEAD || true)
+ echo "Files changed:"
+ echo "$CHANGED"
+
+ # Check against doc file types and doc paths
+ if echo "$CHANGED" | grep -qE '\.md$|\.rst$|^docs/|\.github/workflows/check-links\.yml'; then
+ echo "Documentation or workflow files changed. Proceeding..."
+ echo "run_job=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "No documentation files changed in this specific commit. Skipping."
+ echo "run_job=false" >> "$GITHUB_OUTPUT"
+ fi
- name: Restore lychee cache
+ if: steps.check_docs.outputs.run_job == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
uses: actions/cache@v4
with:
path: .lycheecache
@@ -51,9 +67,11 @@ jobs:
restore-keys: cache-lychee-
- name: Run Link Checker
+ if: steps.check_docs.outputs.run_job == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
uses: lycheeverse/lychee-action@v2
with:
# Check all markdown files and documentation
+ # Excluded are known crawl blockers
args: >-
--verbose
--no-progress
@@ -75,9 +93,18 @@ jobs:
--exclude 'user@'
--exclude 'helm\.ngc\.nvidia\.com'
--exclude 'slurm\.schedmd\.com'
- --max-retries 3
- --retry-wait-time 5
- --timeout 30
+ --exclude 'graphics\.pixar\.com'
+ --exclude 'openpbs\.org'
+ --exclude 'docutils\.sourceforge\.io'
+ --exclude 'huggingface\.co/datasets/nvidia/PhysicalAI-Robotics-NuRec'
+ --exclude 'huggingface\.co/nvidia/COMPASS'
+ --exclude 'huggingface\.co/nvidia/X-Mobility'
+ --exclude 'openusd\.org'
+ --exclude 'ubuntu\.com/server/docs'
+ --max-retries 5
+ --retry-wait-time 10
+ --timeout 20
+ --user-agent 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
--accept 200,201,202,203,204,206,301,302,303,307,308,429
--scheme https
--scheme http
@@ -93,7 +120,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Print results to logs
- if: always()
+ if: always() && (steps.check_docs.outputs.run_job == 'true' || github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
run: |
echo "========================================"
echo "Link Checker Results:"
diff --git a/.github/workflows/daily-compatibility.yml b/.github/workflows/daily-compatibility.yml
index bbf59e45160..8e9dcba23a8 100644
--- a/.github/workflows/daily-compatibility.yml
+++ b/.github/workflows/daily-compatibility.yml
@@ -70,9 +70,9 @@ jobs:
steps:
- name: Checkout Code
- uses: actions/checkout@v3
+ uses: actions/checkout@v6
with:
- fetch-depth: 0
+ fetch-depth: 1
lfs: true
- name: Build Docker Image
@@ -101,7 +101,7 @@ jobs:
fi
- name: Upload IsaacLab Tasks Test Results
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
if: always()
with:
name: isaaclab-tasks-compat-results-${{ matrix.isaacsim_version }}
@@ -127,9 +127,9 @@ jobs:
steps:
- name: Checkout Code
- uses: actions/checkout@v3
+ uses: actions/checkout@v6
with:
- fetch-depth: 0
+ fetch-depth: 1
lfs: true
- name: Build Docker Image
@@ -158,7 +158,7 @@ jobs:
fi
- name: Upload General Test Results
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
if: always()
with:
name: general-tests-compat-results-${{ matrix.isaacsim_version }}
@@ -168,22 +168,24 @@ jobs:
combine-compat-results:
needs: [test-isaaclab-tasks-compat, test-general-compat]
- runs-on: [self-hosted, gpu]
+ runs-on: ubuntu-latest
if: always()
steps:
- name: Checkout Code
- uses: actions/checkout@v3
+ uses: actions/checkout@v6
with:
- fetch-depth: 0
+ fetch-depth: 1
lfs: false
+ sparse-checkout: .github/actions
+ sparse-checkout-cone-mode: true
- name: Create Reports Directory
run: |
mkdir -p reports
- name: Download All Test Results
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v8
with:
pattern: '*-compat-results-*'
path: reports/
@@ -197,7 +199,7 @@ jobs:
output-file: "reports/combined-compat-results.xml"
- name: Upload Combined Test Results
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
if: always()
with:
name: daily-compat-${{ github.run_id }}-combined-test-results
@@ -206,7 +208,7 @@ jobs:
compression-level: 9
- name: Report Test Results
- uses: dorny/test-reporter@v1
+ uses: dorny/test-reporter@v2.6.0
if: always()
with:
name: IsaacLab Compatibility Test Results (${{ github.event_name }})
@@ -217,15 +219,17 @@ jobs:
notify-compatibility-status:
needs: [setup-versions, combine-compat-results]
- runs-on: [self-hosted, gpu]
+ runs-on: ubuntu-latest
if: always()
steps:
- name: Checkout Code
- uses: actions/checkout@v3
+ uses: actions/checkout@v6
with:
- fetch-depth: 0
+ fetch-depth: 1
lfs: false
+ sparse-checkout: .github/actions
+ sparse-checkout-cone-mode: true
- name: Create Compatibility Report
run: |
@@ -249,7 +253,7 @@ jobs:
echo "*This report was generated automatically by the daily compatibility workflow.*" >> compatibility-report.md
- name: Upload Compatibility Report
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
if: always()
with:
name: compatibility-report-${{ github.run_id }}
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index 9af2d6e94f0..1be69475745 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -3,15 +3,18 @@
#
# SPDX-License-Identifier: BSD-3-Clause
-name: Build & deploy docs
+name: Docs
on:
push:
branches:
- main
- - devel
+ - develop
- 'release/**'
+ - 'feature/isaacsim-6-0'
pull_request:
+ # we're skipping the branches and paths filter to allow docs to be built on any PR because heredoc is used
+ # additionally, we have a check that determines what version of docs will be built
types: [opened, synchronize, reopened]
concurrency:
@@ -19,50 +22,91 @@ concurrency:
cancel-in-progress: true
jobs:
- check-secrets:
- name: Check secrets
+ doc-build-type:
+ name: Detect Doc Build Type
runs-on: ubuntu-latest
outputs:
trigger-deploy: ${{ steps.trigger-deploy.outputs.defined }}
steps:
+ - id: info
+ run: echo "repo=github.repository=${{ github.repository }}, ref=github.ref=${{ github.ref }}"
- id: trigger-deploy
env:
REPO_NAME: ${{ secrets.REPO_NAME }}
- if: "${{ github.repository == env.REPO_NAME && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/devel' || startsWith(github.ref, 'refs/heads/release/')) }}"
- run: echo "defined=true" >> "$GITHUB_OUTPUT"
+ # develop, main, release/ trigger multi-version build, then deployment to gh-pages
+ # all others - just the current docs without deployment
+ if: "${{ github.repository == env.REPO_NAME && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/heads/release/')) }}"
+ run: echo "defined=true" >> "$GITHUB_OUTPUT"; echo "Docs will be built multi-version and deployed"
- build-docs:
- name: Build Docs
+ build-latest-docs:
+ name: Build Latest Docs
runs-on: ubuntu-latest
- needs: [check-secrets]
+ needs: [doc-build-type]
+ # run on non-deploy branches to build current version docs only
+ if: needs.doc-build-type.outputs.trigger-deploy != 'true'
steps:
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v6
- name: Setup python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v5
with:
- python-version: "3.11"
+ python-version: "3.12"
architecture: x64
- name: Install dev requirements
working-directory: ./docs
run: pip install -r requirements.txt
- - name: Check branch docs building
+ - name: Build current version docs
working-directory: ./docs
- if: needs.check-secrets.outputs.trigger-deploy != 'true'
run: make current-docs
+ - name: Upload docs artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: docs-html
+ path: ./docs/_build
+
+ build-multi-docs:
+ name: Build Multi-Version Docs
+ runs-on: ubuntu-latest
+ needs: [doc-build-type]
+ # run on deploy branches to create multi-version docs
+ if: needs.doc-build-type.outputs.trigger-deploy == 'true'
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v6
+
+ - name: Setup python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ architecture: x64
+
+ - name: Install dev requirements
+ working-directory: ./docs
+ run: pip install -r requirements.txt
+
- name: Generate multi-version docs
working-directory: ./docs
+ env:
+ # "deploy" branches build the full set of versions so every page
+ # has a complete version dropdown: main, develop, tags >= v2.0.0
+ # (including pre-release suffixes like -beta or -rc1). v1.x tags and
+ # release/ branches are excluded.
+ SMV_BRANCH_WHITELIST: '^(main|develop)$'
+ SMV_TAG_WHITELIST: '^v[2-9]\d*\.\d+\.\d+(-[A-Za-z0-9.]+)?$'
run: |
git fetch --prune --unshallow --tags
+ git checkout --detach HEAD
+ git for-each-ref --format="%(refname:short)" refs/heads/ | xargs -r git branch -D
make multi-docs
- name: Upload docs artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: docs-html
path: ./docs/_build
@@ -70,18 +114,21 @@ jobs:
deploy-docs:
name: Deploy Docs
runs-on: ubuntu-latest
- needs: [check-secrets, build-docs]
- if: needs.check-secrets.outputs.trigger-deploy == 'true'
+ needs: [doc-build-type, build-multi-docs]
+ # deploy only on "deploy" branches
+ if: needs.doc-build-type.outputs.trigger-deploy == 'true'
steps:
- name: Download docs artifact
- uses: actions/download-artifact@v4
+ uses: actions/download-artifact@v8
with:
name: docs-html
path: ./docs/_build
- name: Deploy to gh-pages
- uses: peaceiris/actions-gh-pages@v3
+ uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/_build
+ keep_files: false
+ force_orphan: true
diff --git a/.github/workflows/install-ci.yml b/.github/workflows/install-ci.yml
new file mode 100644
index 00000000000..2fcbe66c393
--- /dev/null
+++ b/.github/workflows/install-ci.yml
@@ -0,0 +1,57 @@
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+name: Installation Tests
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+ paths:
+ - 'apps/**'
+ - 'VERSION'
+ - 'tools/**'
+ - 'source/**'
+ - '**/pyproject.toml'
+ - '**/environment.yaml'
+ - '.github/workflows/install-ci.yml'
+ push:
+ branches:
+ - main
+ - develop
+ - release/**
+ workflow_dispatch:
+ inputs:
+ base_image:
+ description: 'Docker base image for the test container'
+ required: false
+ default: 'ubuntu:24.04'
+ type: string
+ test_filter:
+ description: 'pytest -k filter expression (e.g. "uv" or "bugs")'
+ default: ''
+permissions:
+ contents: read
+jobs:
+ install-tests:
+ name: Installation Tests
+ runs-on: [self-hosted, gpu]
+ timeout-minutes: 90
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6 # v6
+ - name: Run installation tests
+ env:
+ BASE_IMAGE: ${{ github.event_name == 'workflow_dispatch' && inputs.base_image || 'ubuntu:24.04' }}
+ TEST_FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.test_filter || '' }}
+ run: |
+ RUNNER_ARGS="--base-image $BASE_IMAGE"
+ RUNNER_ARGS="$RUNNER_ARGS --results-dir ${{ github.workspace }}/results"
+ RUNNER_ARGS="$RUNNER_ARGS --gpu"
+
+ PYTEST_EXTRA_ARGS=(-sv)
+ if [ -n "$TEST_FILTER" ]; then
+ PYTEST_EXTRA_ARGS+=(-k "$TEST_FILTER")
+ fi
+
+ tools/run_install_ci.py docker $RUNNER_ARGS -- --tb=short "${PYTEST_EXTRA_ARGS[@]}"
diff --git a/.github/workflows/license-check.yaml b/.github/workflows/license-check.yaml
index e3753ffcb6b..0b296f9e74e 100644
--- a/.github/workflows/license-check.yaml
+++ b/.github/workflows/license-check.yaml
@@ -3,7 +3,7 @@
#
# SPDX-License-Identifier: BSD-3-Clause
-name: Check Python Dependency Licenses
+name: Python Dependency Licenses Check
on:
pull_request:
@@ -19,40 +19,60 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v6
+ with:
+ filter: tree:0
# - name: Install jq
# run: sudo apt-get update && sudo apt-get install -y jq
- name: Clean up disk space
run: |
+ # Remove pre-installed tools
rm -rf /opt/hostedtoolcache
rm -rf /usr/share/dotnet
rm -rf /opt/ghc
+ sudo rm -rf /usr/local/lib/android
+ rm -rf /usr/share/swift
+ rm -rf /usr/local/share/boost
+ sudo rm -rf /usr/local/.ghcup
+ sudo rm -rf /usr/local/lib/node_modules
+ sudo rm -rf /usr/local/share/chromium
+ sudo rm -rf /usr/local/share/powershell
+ # Clean apt cache
+ sudo apt-get clean
+ sudo rm -rf /var/lib/apt/lists/*
+ # Docker cleanup
docker container prune -f
docker image prune -af
- docker volume prune -f || true
+ docker volume prune -f
+ docker system prune -af
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v5
with:
- python-version: '3.11' # Adjust as needed
+ python-version: '3.12'
- name: Install dependencies using ./isaaclab.sh -i
+ env:
+ DEBUG: 1
+ OMNI_KIT_ACCEPT_EULA: yes
+ ACCEPT_EULA: Y
+ ISAACSIM_ACCEPT_EULA: YES
run: |
# first install isaac sim
pip install --upgrade pip
- pip install 'isaacsim[all,extscache]==${{ vars.ISAACSIM_BASE_VERSION || '5.0.0' }}' --extra-index-url https://pypi.nvidia.com
+ pip install 'isaacsim[all,extscache]==${{ vars.ISAACSIM_BASE_VERSION || '6.0.0' }}' --extra-index-url https://pypi.nvidia.com
chmod +x ./isaaclab.sh # Make sure the script is executable
# install all lab dependencies
./isaaclab.sh -i
- name: Install pip-licenses
run: |
- pip install pip-licenses
- pip install -r tools/template/requirements.txt
- pip install -r docs/requirements.txt
+ pip install --no-cache-dir pip-licenses
+ pip install --no-cache-dir -r tools/template/requirements.txt
+ pip install --no-cache-dir -r docs/requirements.txt
# Optional: Print the license report for visibility
- name: Print License Report
@@ -61,6 +81,8 @@ jobs:
# Print pipdeptree
- name: Print pipdeptree
run: |
+ # clean up pip cache
+ pip cache purge
pip install pipdeptree
pipdeptree
@@ -89,6 +111,11 @@ jobs:
# Loop through the installed packages and their licenses
for pkg in $(jq -r '.[].Name' licenses.json); do
+ # Skip packages starting with nvidia (case-insensitive)
+ if [[ "${pkg,,}" == nvidia* ]]; then
+ continue
+ fi
+
LICENSE=$(jq -r --arg pkg "$pkg" '.[] | select(.Name == $pkg) | .License' licenses.json)
# Check if any of the allowed licenses are a substring of the package's license
diff --git a/.github/workflows/license-exceptions.json b/.github/workflows/license-exceptions.json
index 27b3b9c6552..8ac605547dc 100644
--- a/.github/workflows/license-exceptions.json
+++ b/.github/workflows/license-exceptions.json
@@ -23,6 +23,14 @@
"package": "isaaclab_tasks",
"license": null
},
+ {
+ "package": "isaaclab_tasks_experimental",
+ "license": null
+ },
+ {
+ "package": "isaaclab_teleop",
+ "license": null
+ },
{
"package": "isaacsim",
"license": null
@@ -183,6 +191,11 @@
"package": "omniverse-kit",
"license": null
},
+ {
+ "package": "osqp",
+ "license": "UNKNOWN",
+ "comment": "Apache 2.0"
+ },
{
"package": "warp-lang",
"license": null
@@ -222,6 +235,11 @@
"license": "Zlib",
"comment": "ZLIBL"
},
+ {
+ "package": "cmeel-tinyxml2",
+ "license": "Zlib",
+ "comment": "Zlib"
+ },
{
"package": "cmeel-urdfdom",
"license": "UNKNOWN",
@@ -311,9 +329,9 @@
"comment": "MIT"
},
{
- "package": "typing_extensions",
- "license": "Python Software Foundation License",
- "comment": "PSFL / OSRB"
+ "package": "usd-core",
+ "license": "LicenseRef-TOST-1.0",
+ "comment": "TOST / OSRB"
},
{
"package": "urllib3",
@@ -412,7 +430,7 @@
},
{
"package": "aiohappyeyeballs",
- "license": "Other/Proprietary License; Python Software Foundation License",
+ "license": "Python Software Foundation License",
"comment": "PSFL / OSRB"
},
{
@@ -444,5 +462,40 @@
"package": "matplotlib-inline",
"license": "UNKNOWN",
"comment": "BSD-3"
+ },
+ {
+ "package": "pyglet",
+ "license": "UNKNOWN",
+ "comment": "BSD-3"
+ },
+ {
+ "package": "typing_extensions",
+ "license": "PSF-2.0",
+ "comment": "PSF-2.0 / OSRB"
+ },
+ {
+ "package": "standard-distutils",
+ "license": "Python Software Foundation License",
+ "comment": "PSFL / OSRB"
+ },
+ {
+ "package": "vhacdx",
+ "license": "UNKNOWN",
+ "comment": "BSD/MIT"
+ },
+ {
+ "package": "cuda-bindings",
+ "license": "LicenseRef-NVIDIA-SOFTWARE-LICENSE",
+ "comment": "NVIDIA"
+ },
+ {
+ "package": "omniverseclient",
+ "license": "NVIDIA Proprietary Software, https://www.nvidia.com/en-us/agreements/enterprise-software/nvidia-software-license-agreement/",
+ "comment": "NVIDIA"
+ },
+ {
+ "package": "ovphysx",
+ "license": "LicenseRef-NVIDIA-Omniverse",
+ "comment": "NVIDIA"
}
]
diff --git a/.github/workflows/postmerge-ci.yml b/.github/workflows/postmerge-ci.yml
index 4a1f34d38a1..73ec4ea5c12 100644
--- a/.github/workflows/postmerge-ci.yml
+++ b/.github/workflows/postmerge-ci.yml
@@ -9,8 +9,9 @@ on:
push:
branches:
- main
- - devel
+ - develop
- release/**
+ - feature/isaacsim-6-0
# Concurrency control to prevent parallel runs
concurrency:
@@ -22,8 +23,9 @@ permissions:
env:
NGC_API_KEY: ${{ secrets.NGC_API_KEY }}
- ISAACSIM_BASE_IMAGE: ${{ vars.ISAACSIM_BASE_IMAGE || 'nvcr.io/nvidia/isaac-sim' }}
- ISAACSIM_BASE_VERSIONS_STRING: ${{ vars.ISAACSIM_BASE_VERSIONS_STRING || '5.1.0' }}
+ # On merge to main defaults will point to "nvcr.io/nvidia/isaac-sim:6.0.0"
+ ISAACSIM_BASE_IMAGE: 'nvcr.io/nvidian/isaac-sim' # ${{ vars.ISAACSIM_BASE_IMAGE || 'nvcr.io/nvidia/isaac-sim' }}
+ ISAACSIM_BASE_VERSIONS_STRING: 'latest-develop@sha256:f085fb5b6899511bb19abdf18121bfc469901334aefb029d0def56d4fef79c58' # Pinned to the Apr 8 nightly digest that last passed CI, while latest-develop is broken. TODO: Revert to 'latest-develop' once the nightly is fixed. # ${{ vars.ISAACSIM_BASE_VERSIONS_STRING || '6.0.0' }}
ISAACLAB_IMAGE_NAME: ${{ vars.ISAACLAB_IMAGE_NAME || 'isaac-lab-base' }}
jobs:
@@ -39,9 +41,9 @@ jobs:
steps:
- name: Checkout Code
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
- fetch-depth: 0
+ fetch-depth: 1
lfs: true
- name: Set up QEMU
@@ -109,6 +111,8 @@ jobs:
# Combine repo short name and branch name for the tag
COMBINED_TAG="${REPO_SHORT_NAME}-${SAFE_BRANCH_NAME}-${IMAGE_BASE_VERSION}"
BUILD_TAG="${COMBINED_TAG}-b${{ github.run_number }}"
+ COMMIT_TAG="${COMBINED_TAG}-${{ github.sha }}"
+ SHORT_COMMIT_TAG="${COMBINED_TAG}-${GITHUB_SHA::7}"
# Determine if multiarch is supported by inspecting the base image manifest
echo "Checking if base image supports multiarch..."
@@ -149,12 +153,14 @@ jobs:
echo "Base image: $BASE_IMAGE_FULL"
echo "Target platforms: $BUILD_PLATFORMS"
- # Build Docker image once with both tags for multiple architectures
+ # Build Docker image once with all tags for multiple architectures
docker buildx build \
--platform $BUILD_PLATFORMS \
--progress=plain \
-t ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG \
-t ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG \
+ -t ${{ env.ISAACLAB_IMAGE_NAME }}:$COMMIT_TAG \
+ -t ${{ env.ISAACLAB_IMAGE_NAME }}:$SHORT_COMMIT_TAG \
--build-arg ISAACSIM_BASE_IMAGE_ARG=${{ env.ISAACSIM_BASE_IMAGE }} \
--build-arg ISAACSIM_VERSION_ARG=$IMAGE_BASE_VERSION \
--build-arg ISAACSIM_ROOT_PATH_ARG=/isaac-sim \
@@ -167,4 +173,6 @@ jobs:
echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMBINED_TAG (platforms: $BUILD_PLATFORMS)"
echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$BUILD_TAG (platforms: $BUILD_PLATFORMS)"
+ echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$COMMIT_TAG (platforms: $BUILD_PLATFORMS)"
+ echo "✅ Successfully built and pushed: ${{ env.ISAACLAB_IMAGE_NAME }}:$SHORT_COMMIT_TAG (platforms: $BUILD_PLATFORMS)"
done
diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml
index f71f1f37389..aa3a38dafff 100644
--- a/.github/workflows/pre-commit.yaml
+++ b/.github/workflows/pre-commit.yaml
@@ -3,7 +3,7 @@
#
# SPDX-License-Identifier: BSD-3-Clause
-name: Run linters using pre-commit
+name: Run `pre-commit`
on:
pull_request:
@@ -13,8 +13,8 @@ jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v3
+ - uses: actions/checkout@v6
+ - uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: pre-commit/action@v3.0.0
diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml
new file mode 100644
index 00000000000..41567dde43b
--- /dev/null
+++ b/.github/workflows/wheel.yml
@@ -0,0 +1,58 @@
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+name: Build PIP Wheel
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+ paths:
+ - 'apps/**'
+ - 'VERSION'
+ - 'source/**'
+ - 'tools/wheel_builder/**'
+ - '.github/workflows/wheel.yml'
+ push:
+ branches:
+ - main
+ - develop
+ - 'release/**'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ build-wheel:
+ name: Build Wheel
+ runs-on: ubuntu-latest
+ timeout-minutes: 5
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 1
+ lfs: true
+
+ - name: Setup Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: "3.12"
+ architecture: x64
+
+ - name: Build wheel
+ run: bash tools/wheel_builder/build.sh
+
+ - name: Upload wheel artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: ${{ github.event_name == 'pull_request' && format('isaaclab-wheel-pr-{0}-{1}', github.event.pull_request.number, github.sha) || format('isaaclab-wheel-{0}-{1}', github.ref_name, github.sha) }}
+ path: tools/wheel_builder/build/dist/isaaclab-*.whl
+ if-no-files-found: error
+ retention-days: 30
diff --git a/.gitignore b/.gitignore
index 7afb58e9ee0..4b345b0a7d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,7 +65,7 @@ _build
/datasets/
# Tests
-tests/
+/tests/
# Docker history
.isaac-lab-docker-history
@@ -73,3 +73,15 @@ tests/
# TacSL sensor
**/tactile_record/*
**/gelsight_r15_data/*
+
+# No benchmarks output
+/benchmarks/
+
+# Ruff cache
+**/.ruff_cache/
+
+# Dev-time files, generated stuff
+**/__*
+
+# Isaac Lab CI environments in native mode
+**/_isaaclab_install_ci_*
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 426a84b59b7..5c2a0292de9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -45,7 +45,7 @@ repos:
rev: v1.5.5
hooks:
- id: insert-license
- files: \.(py|ya?ml)$
+ files: \.(pyi?|ya?ml)$
args:
# - --remove-header # Remove existing license headers. Useful when updating license.
- --license-filepath
diff --git a/.vscode/tools/launch.template.json b/.vscode/tools/launch.template.json
index a44f114c822..9cc6c705187 100644
--- a/.vscode/tools/launch.template.json
+++ b/.vscode/tools/launch.template.json
@@ -11,8 +11,14 @@
"program": "${file}",
"console": "integratedTerminal"
},
+ // Attach to listening debugpy
+ // Usage (VSCode but should be similar for other IDEs):
+ // 1. Set your breakpoints
+ // 2. Run your code under debugpy like so:
+ // ./isaaclab.sh -p -m debugpy --listen 3000 --wait-for-client -c "from isaaclab.cli import cli; cli()" [cli_args]
+ // 3. Select this "Python: Debugger Attach" configuration and press green play button or F5
{
- "name": "Python: Attach (windows-x86_64/linux-x86_64)",
+ "name": "Python: Debugger Attach",
"type": "python",
"request": "attach",
"port": 3000,
diff --git a/.vscode/tools/setup_vscode.py b/.vscode/tools/setup_vscode.py
index 9e2c6375ab7..8d29dafee08 100644
--- a/.vscode/tools/setup_vscode.py
+++ b/.vscode/tools/setup_vscode.py
@@ -13,6 +13,7 @@
"""
import re
+import subprocess
import sys
import os
import pathlib
@@ -21,27 +22,28 @@
ISAACLAB_DIR = pathlib.Path(__file__).parents[2]
"""Path to the Isaac Lab directory."""
-try:
- import isaacsim # noqa: F401
-
- isaacsim_dir = os.environ.get("ISAAC_PATH", "")
-except ModuleNotFoundError or ImportError:
+# Try to find IsaacSim dir
+_isaacsim_probe = subprocess.run(
+ [sys.executable, "-c", "import isaacsim; import os; print(os.environ.get('ISAAC_PATH', ''))"],
+ capture_output=True,
+ text=True,
+ check=False,
+ # avoid EULA prompt
+ stdin=subprocess.DEVNULL,
+)
+if _isaacsim_probe.returncode == 0 and _isaacsim_probe.stdout.strip():
+ isaacsim_dir = _isaacsim_probe.stdout.strip()
+else:
isaacsim_dir = os.path.join(ISAACLAB_DIR, "_isaac_sim")
-except EOFError:
- print("Unable to trigger EULA acceptance. This is likely due to the script being run in a non-interactive shell.")
- print("Please run the script in an interactive shell to accept the EULA.")
- print("Skipping the setup of the VSCode settings...")
- sys.exit(0)
# check if the isaac-sim directory exists
if not os.path.exists(isaacsim_dir):
- raise FileNotFoundError(
- f"Could not find the isaac-sim directory: {isaacsim_dir}. There are two possible reasons for this:"
- f"\n\t1. The Isaac Sim directory does not exist as a symlink at: {os.path.join(ISAACLAB_DIR, '_isaac_sim')}"
- "\n\t2. The script could not import the 'isaacsim' package. This could be due to the 'isaacsim' package not "
- "being installed in the Python environment.\n"
- "\nPlease make sure that the Isaac Sim directory exists or that the 'isaacsim' package is installed."
+ print(
+ f"[WARN] Could not find the isaac-sim directory: {isaacsim_dir}."
+ "\n\tIsaac Sim does not appear to be installed. VS Code settings will be generated"
+ "\n\twithout Isaac Sim extra paths."
)
+ isaacsim_dir = ""
ISAACSIM_DIR = isaacsim_dir
"""Path to the isaac-sim directory."""
@@ -66,7 +68,7 @@ def overwrite_python_analysis_extra_paths(isaaclab_settings: str) -> str:
# we use the isaac-sim settings file to get the python.analysis.extraPaths for kit extensions
# if this file does not exist, we will not add any extra paths
- if os.path.exists(isaacsim_vscode_filename):
+ if ISAACSIM_DIR and os.path.exists(isaacsim_vscode_filename):
# read the path names from the isaac-sim settings file
with open(isaacsim_vscode_filename) as f:
vscode_settings = f.read()
@@ -89,13 +91,6 @@ def overwrite_python_analysis_extra_paths(isaaclab_settings: str) -> str:
path_names = ['"${workspaceFolder}/' + rel_path + "/" + path_name + '"' for path_name in path_names]
else:
path_names = []
- print(
- f"[WARN] Could not find Isaac Sim VSCode settings: {isaacsim_vscode_filename}."
- "\n\tThis will result in missing 'python.analysis.extraPaths' in the VSCode"
- "\n\tsettings, which limits the functionality of the Python language server."
- "\n\tHowever, it does not affect the functionality of the Isaac Lab project."
- "\n\tWe are working on a fix for this issue with the Isaac Sim team."
- )
# add the path names that are in the Isaac Lab extensions directory
isaaclab_extensions = os.listdir(os.path.join(ISAACLAB_DIR, "source"))
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000000..70c1d15158a
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,172 @@
+# IsaacLab Guidelines
+
+## Breaking API changes
+
+- **Breaking changes require a deprecation first.** Do not remove or rename public API symbols without deprecating them in a prior release.
+
+## API design rules (naming + structure)
+
+- **Group by common prefix for discoverability (autocomplete).**
+ - **Classes**: group by domain concept — `ActuatorNetLSTM`, `ActuatorNetMLP` (not `LSTMActuatorNet`, `MLPActuatorNet`).
+ - **Methods**: group by noun before modifier — `set_joint_position_target()` (not `set_target_joint_position()`).
+- **Method names are `snake_case`.**
+- **CLI arguments are `snake_case`.**
+- **Prefer nested classes when self-contained.**
+ - If a helper type or an enum is only meaningful inside one parent class and doesn't need a public identity, define it as a nested class instead of creating a new top-level class/module.
+- **Follow PEP 8 for Python code.**
+- **Use modern Python type-hint syntax.**
+ - Prefer PEP 604 unions: `x | y`, `x | None`. Do not use `typing.Union` or `typing.Optional`.
+- **Use specific type hints for public interfaces.**
+ - For torch tensors, annotate with `torch.Tensor`. For Warp arrays, annotate concrete dtypes (e.g., `wp.array(dtype=wp.vec3)`) rather than generic `object`.
+ - Prefer consistent parameter names across base/override APIs (e.g., `xforms`, `scales`, `colors`, `materials`).
+- **Use Google-style docstrings.**
+ - Write clear, concise docstrings that explain what the function does, its parameters, and its return value.
+ - Keep argument/return types in function annotations, not inline in docstrings.
+ - In `Args:` entries, use `name: description` (not `name (Type): description`).
+ - Use Sphinx cross-reference roles for symbol references (e.g. `:class:`, `:meth:`, `:attr:`, `:paramref:`), but keep targets as short as possible.
+ - Within the same class/module, prefer short local references (e.g. `:meth:\`set_joint_position_target\``, `:attr:\`num_joints\``) over fully qualified paths.
+ - If qualification is needed, prefer public API paths (e.g. `isaaclab.assets.Articulation`) and do not use internal `_src` or private module paths in Sphinx role targets.
+- **State SI units for all physical quantities in docstrings.**
+ - Use inline `[unit]` notation, e.g. `"""Particle positions [m], shape [particle_count, 3], float."""`.
+ - For joint-type-dependent quantities use `[m or rad, depending on joint type]`.
+ - For spatial vectors annotate both components, e.g. `[N, N·m]`.
+ - For compound arrays list per-component units, e.g. `[0] k_mu [Pa], [1] k_lambda [Pa], ...`.
+ - When a parameter's interpretation varies across solvers, document each solver's convention instead of a single unit.
+ - Skip non-physical fields (indices, keys, counts, flags).
+ - This rule applies to **public API docstrings only**, not test docstrings.
+- **Keep the documentation up-to-date.**
+ - When adding new files or symbols that are part of the public-facing API, make sure to keep the auto-generated documentation updated by running `./isaaclab.sh -d`.
+
+## Dependencies
+
+- **Avoid adding new required dependencies.** IsaacLab's core should remain lightweight and minimize external requirements.
+- **Strongly prefer not adding new optional dependencies.** If additional functionality requires a new package, carefully consider whether the benefit justifies the added complexity and maintenance burden. When possible, implement functionality using existing dependencies, including Warp functions and kernels, NumPy, or the standard library.
+
+## Tooling: prefer `./isaaclab.sh -p` for running, testing, and benchmarking
+
+We use a wrapped python call within `./isaaclab.sh`.
+
+- **Use `./isaaclab.sh -p -c` for inline Python**: When running one-off Python commands, use `./isaaclab.sh -p -c "..."` instead of `python3 -c "..."`.
+- **Use `./isaaclab.sh -p`** to run standalone Python scripts without a `pyproject.toml` (e.g., in CI after switching to a branch with no project files).
+
+### Run tests
+
+```bash
+# run all tests (extremely heavy, should be avoided).
+./isaaclab.sh -t
+
+# run a specific test file by name
+./isaaclab.sh -p -m pytest PATH_TO_TEST
+
+# run a specific example test
+./isaaclab.sh -p -m pytest PATH_TO_TEST::METHOD
+```
+
+### Pre-commit (lint/format hooks)
+
+**CRITICAL: Always run pre-commit hooks BEFORE committing, not after.**
+
+Proper workflow:
+1. Make your code changes
+2. Run `./isaaclab.sh -f` to check ALL files
+3. If pre-commit modifies any files (e.g., formatting), review the changes
+4. Stage the modified files with `git add`
+5. Run `./isaaclab.sh -f` again to ensure all checks pass
+6. Only then create your commit with `git commit`
+
+```bash
+# Run pre-commit checks on all files
+./isaaclab.sh -f
+```
+
+**Common mistake to avoid:**
+- Don't commit first and then run pre-commit (requires amending commits)
+- Do run pre-commit before committing (clean workflow)
+
+**When reviewing code** (e.g. via a code-reviewer agent), always run `./isaaclab.sh -f` as part of the review to catch formatting or lint issues early.
+
+## Changelog
+
+- **Update `CHANGELOG.rst` for every change** targeting the source directory. Each extension has its own changelog at `source//docs/CHANGELOG.rst` (e.g. `source/isaaclab/docs/CHANGELOG.rst`, `source/isaaclab_physx/docs/CHANGELOG.rst`).
+- **Always create a new version heading.** Never add entries to an existing version — they are released and immutable. Bump the patch version (e.g. `1.5.0` → `1.5.1`) and use today's date.
+- **Bump `config/extension.toml` to match.** When creating a new changelog version, update the `version` field in `source//config/extension.toml` to the same version string.
+- **Determine which changelog(s) to update** by looking at which `source//` directories your changes touch. A single PR may require entries in multiple changelogs.
+- Use **past tense** matching the section header: "Added X", "Fixed Y", "Changed Z".
+- Place entries under the correct category: `Added`, `Changed`, `Deprecated`, `Removed`, or `Fixed`.
+- Avoid internal implementation details users wouldn't understand.
+- **For `Deprecated`, `Changed`, and `Removed` entries, include migration guidance.**
+ - Example: "Deprecated `Articulation.A` in favor of `Articulation.B`."
+- Use Sphinx cross-reference roles for class/method/module names.
+
+### RST formatting reference
+
+```
+X.Y.Z (YYYY-MM-DD)
+~~~~~~~~~~~~~~~~~~
+
+Added
+^^^^^
+
+* Added :class:`~package.ClassName` to support feature X.
+
+Fixed
+^^^^^
+
+* Fixed edge case in :meth:`~package.ClassName.method` where input was
+ not validated, causing ``AttributeError`` at runtime.
+```
+
+Key formatting rules:
+- Version heading: underline with `~` (tildes), must be at least as long as the heading text.
+- Category heading: underline with `^` (carets).
+- Entries: `* ` prefix, continuation lines indented by 2 spaces.
+- Blank line between the last entry and the next version heading.
+
+## Commit and Pull Request Guidelines
+
+Follow conventional commit message practices.
+
+- **Use feature branches**: All development work should be on branches named `/feature-desc` (e.g., `jdoe/docs-versioning`). Do not commit directly to `main`.
+- Keep commits focused and atomic—one logical change per commit.
+- Reference related issues in commit messages when applicable.
+- **When iterating on PR feedback**, prefer adding new commits over amending existing ones. This avoids force-pushing and lets the reviewer easily verify each change request was addressed.
+- **Do not include AI attribution or co-authorship lines** (e.g., "Co-Authored-By: Claude...") in commit messages. Commits should represent human contributions without explicit AI attribution.
+- **Commit message format**:
+ - Separate subject from body with a blank line
+ - Subject: imperative mood, capitalized, ~50 chars, no trailing period
+ - Write as a command: "Fix bug" not "Fixed bug" or "Fixes bug"
+ - Test: "If applied, this commit will _[your subject]_"
+ - Body: wrap at 72 chars, explain _what_ and _why_ (not _how_—the diff shows that)
+
+## File headers and copyright
+
+- New files must use the current year (2026) in the SPDX copyright header:
+ ```
+ # Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+ # All rights reserved.
+ #
+ # SPDX-License-Identifier: BSD-3-Clause
+ ```
+- Do not change the year in existing file headers.
+
+## Sandbox & Networking
+
+- Network access (e.g., `git push`) is blocked by the sandbox. Use `dangerouslyDisableSandbox: true` so the user gets an approval prompt — don't ask them to run it manually.
+
+## GitHub Actions and CI/CD
+
+- IMPORTANT: Pin actions by SHA hash. Use `action@ # vX.Y.Z` format for supply-chain security. Check existing workflows in `.github/workflows/` for the allowlisted hashes. New actions or versions require repo admin approval to be added to the allowlist.
+
+## Testing Guidelines
+
+- **Always verify regression tests fail without the fix.** When writing a regression test for a bug fix, temporarily revert the fix and run the test to confirm it fails. Then reapply the fix and verify the test passes. This ensures the test actually covers the bug.
+
+### Debugging Warp kernels
+
+**Do not add `wp.printf` to kernels in production code.** Debug prints in Warp kernels affect performance and can produce noisy test output. Use them only in standalone reproduction scripts during development, and always remove them before committing.
+
+To debug Warp kernel behavior:
+
+1. **Write a standalone reproduction script** and run it directly with `./isaaclab.sh -p -c "..."` or `./isaaclab.sh -p script.py`. This keeps stdout visible and avoids the test framework entirely.
+2. **Use high-precision format strings** for floating-point debugging (e.g., `wp.printf("val=%.15e\n", x)`) — the default `%f` format hides values smaller than ~1e-6 that can still affect control flow.
+3. **Remove all `wp.printf` calls before committing.**
diff --git a/CITATION.cff b/CITATION.cff
index 70d123b5524..68de43e5ba6 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -1,7 +1,7 @@
cff-version: 1.2.0
message: "If you use this software, please cite the technical report of Isaac Lab."
title: Isaac Lab
-version: 2.3.2
+version: 3.0.0
repository-code: https://github.com/isaac-sim/IsaacLab
type: software
authors:
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 00000000000..43c994c2d36
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1 @@
+@AGENTS.md
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index b637aec7179..252340151d4 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -19,38 +19,45 @@ Guidelines for modifications:
---
+* Antoine Richard
* Antonio Serrano-Muñoz
* Ben Johnston
* Brian McCann
* Clemens Schwarke
* David Hoeller
* Farbod Farshidian
+* Gavriel State
+* Greg Attra
* Hunter Hansen
* James Smith
* James Tigue
* Kelly (Yunrong) Guo
* Matthew Trepte
* Mayank Mittal
+* Mike Yan Michelis
+* Mikhail Yurasov
* Nikita Rudin
* Octi (Zhengyu) Zhang
+* Ossama Ahmed
* Pascal Roth
* Sheikh Dawood
-* Ossama Ahmed
-* Greg Attra
## Contributors
* Alessandro Assirelli
* Alex Omar
+* Alexander Millane
* Alice Zhou
* Amr Mousa
* Andrej Orsula
+* Anke Zhao
* Anton Bjørndahl Mortensen
* Antonin Raffin
* Arjun Bhardwaj
* Ashwin Varghese Kuruttukulam
* Bikram Pandit
* Bingjie Tang
+* Bocheng Zou
* Brayden Zhang
* Brian Bingham
* Brian McCann
@@ -62,10 +69,13 @@ Guidelines for modifications:
* Chenyu Yang
* Connor Smith
* CY (Chien-Ying) Chen
+* David Leon
* David Yang
* Dhananjay Shendre
+* Dhyan Thakkar
* Dongxuan Fan
* Dorsa Rohani
+* Ege Sekkin
* Emily Sturman
* Emmanuel Ferdman
* Fabian Jenelten
@@ -80,14 +90,18 @@ Guidelines for modifications:
* Hongwei Xiong
* Hongyu Li
* Hougant Chen
+* HuiDong Chen
* Huihua Zhao
* Iretiayo Akinola
* Jack Zeng
* Jan Kerner
* Jean Tampon
* Jeonghwan Kim
+* Jessica Martinez
+* Ji Yuan Feng
* Jia Lin Yuan
* Jiakai Zhang
+* Jichuan Hu
* Jinghuan Shang
* Jingzhou Liu
* Jinqi Wei
@@ -95,22 +109,22 @@ Guidelines for modifications:
* Johnson Sun
* Juana Du
* Kaixi Bao
-* Kris Wilson
-* Krishna Lakhi
* Kourosh Darvish
* Kousheek Chakraborty
+* Kris Wilson
+* Krishna Lakhi
* Lionel Gulich
+* Lorenz Wellhausen
* Lotus Li
* Louis Le Lay
-* Lorenz Wellhausen
* Lukas Fröhlich
* Manuel Schweiger
* Masoud Moghani
* Mateo Guaman Castro
* Maurice Rahme
* Michael Gussert
-* Michael Noseworthy
* Michael Lin
+* Michael Noseworthy
* Miguel Alonso Jr
* Mihir Kulkarni
* Mingxue Gu
@@ -126,8 +140,10 @@ Guidelines for modifications:
* Oyindamola Omotuyi
* Özhan Özen
* Patrick Yin
+* Paul Reeves
* Peter Du
* Philipp Reist
+* Piotr Barejko
* Pulkit Goyal
* Qian Wan
* Qingyang Jiang
@@ -138,6 +154,7 @@ Guidelines for modifications:
* RinZ27
* Ritvik Singh
* Rosario Scalise
+* Ruben D'Sa
* Ryan Gresia
* Ryley McCarroll
* Sahara Yuta
@@ -146,17 +163,20 @@ Guidelines for modifications:
* Shane Reetz
* Shaoshu Su
* Shaurya Dewan
-* Sixiang Chen
* Shundo Kishi
+* Sixiang Chen
+* Song Yi
* Stefan Van de Mosselaer
* Stephan Pleines
* Tiffany Chen
* Trushant Adeshara
+* Tsz Ki GAO
* Tyler Lum
* Victor Khaustov
* Virgilio Gómez Lambo
* Vladimir Fokow
* Wei Yang
+* Weihua Zhang
* Welf Rehberg
* Xavier Nal
* Xiaodi Yuan
@@ -168,22 +188,17 @@ Guidelines for modifications:
* Yohan Choi
* Yujian Zhang
* Yun Liu
+* YuTeh Shen
* Zehao Wang
* Zijian Li
* Ziqi Fan
* Zoe McCarthy
-* David Leon
-* Song Yi
-* Weihua Zhang
-* Tsz Ki GAO
-* Anke Zhao
## Acknowledgements
* Ajay Mandlekar
* Animesh Garg
* Buck Babich
-* Gavriel State
* Hammad Mazhar
* Marco Hutter
* Yan Chang
diff --git a/README.md b/README.md
index ca5dc349d67..a2f2cfd766a 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,8 @@
# Isaac Lab
-[](https://docs.isaacsim.omniverse.nvidia.com/latest/index.html)
-[](https://docs.python.org/3/whatsnew/3.11.html)
+[](https://docs.isaacsim.omniverse.nvidia.com/latest/index.html)
+[](https://docs.python.org/3/whatsnew/3.12.html)
[](https://releases.ubuntu.com/22.04/)
[](https://www.microsoft.com/en-us/)
[](https://github.com/isaac-sim/IsaacLab/actions/workflows/pre-commit.yaml)
@@ -14,6 +14,14 @@
[](https://opensource.org/license/apache-2-0)
+This branch is a development branch for Isaac Sim 6.0, which is currently only available through the Isaac Sim [GitHub repo](https://github.com/isaac-sim/IsaacSim).
+For installation, please refer to the Isaac Sim GitHub repo to build the latest Isaac Sim branch, and follow the binary installation method in the
+Isaac Lab documentation for Isaac Lab installation.
+
+Note that this branch is currently under active development and may experience breaking changes or error messages.
+Performance issues and regressions may also be observed in some use cases.
+
+
**Isaac Lab** is a GPU-accelerated, open-source framework designed to unify and simplify robotics research workflows,
such as reinforcement learning, imitation learning, and motion planning. Built on [NVIDIA Isaac Sim](https://docs.isaacsim.omniverse.nvidia.com/latest/index.html),
it combines fast and accurate physics and sensor simulation, making it an ideal choice for sim-to-real
@@ -48,6 +56,12 @@ detailed tutorials and step-by-step guides. Follow these links to learn more abo
- [Tutorials](https://isaac-sim.github.io/IsaacLab/main/source/tutorials/index.html)
- [Available environments](https://isaac-sim.github.io/IsaacLab/main/source/overview/environments.html)
+## Performance Dashboard
+
+We continuously benchmark Isaac Lab across different physics backends, renderers, and data types.
+The **[Isaac Lab Performance Dashboard](https://nvidia.github.io/omniperf/)** provides interactive
+charts showing preset comparison results, performance history, and environment scaling data from
+our internal CI/CD benchmarks.
## Isaac Sim Version Dependency
@@ -57,12 +71,17 @@ dependency versions for Isaac Sim.
| Isaac Lab Version | Isaac Sim Version |
| ----------------------------- | ------------------------- |
+| `develop` branch | Isaac Sim 6.0 |
| `main` branch | Isaac Sim 4.5 / 5.0 / 5.1 |
| `v2.3.X` | Isaac Sim 4.5 / 5.0 / 5.1 |
| `v2.2.X` | Isaac Sim 4.5 / 5.0 |
| `v2.1.X` | Isaac Sim 4.5 |
| `v2.0.X` | Isaac Sim 4.5 |
+## Limitations
+
+The `develop` branch of Isaac Lab 3.0-Beta is currently available on Ubuntu. Windows
+support and Isaac Lab pip wheels will be available soon.
## Contributing to Isaac Lab
diff --git a/VERSION b/VERSION
index f90b1afc082..4a36342fcab 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.3.2
+3.0.0
diff --git a/apps/isaaclab.python.headless.kit b/apps/isaaclab.python.headless.kit
index 03a6bf196d0..12b9e14946d 100644
--- a/apps/isaaclab.python.headless.kit
+++ b/apps/isaaclab.python.headless.kit
@@ -5,7 +5,7 @@
[package]
title = "Isaac Lab Python Headless"
description = "An app for running Isaac Lab headlessly"
-version = "2.3.2"
+version = "3.0.0"
# That makes it browsable in UI with "experience" filter
keywords = ["experience", "app", "isaaclab", "python", "headless"]
@@ -14,8 +14,10 @@ keywords = ["experience", "app", "isaaclab", "python", "headless"]
# Note: This path was adapted to be respective to the kit-exe file location
app.versionFile = "${exe-path}/VERSION"
app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "5.1.0"
+app.name = "IsaacLab"
+app.version = "3.0.0"
+log.level = "Warn" # Suppress third-party debug/info noise
+log.outputStreamLevel = "Warn"
##################################
# Omniverse related dependencies #
@@ -24,7 +26,6 @@ app.version = "5.1.0"
"omni.physx" = {}
"omni.physx.tensors" = {}
"omni.physx.fabric" = {}
-"omni.warp.core" = {}
"usdrt.scenegraph" = {}
"omni.kit.telemetry" = {}
"omni.kit.loop" = {}
@@ -104,15 +105,11 @@ isaac.startup.ros_bridge_extension = ""
# disable the metrics assembler change listener, we don't want to do any runtime changes
metricsAssembler.changeListenerEnabled = false
+# explicitly disable omni.kit.pip_archive to prevent conflicting dependencies
+app.extensions.excluded = ["omni.kit.pip_archive", "omni.isaac.ml_archive", "isaacsim.pip.newton", "omni.warp.core"]
+
# Extensions
###############################
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/107/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
[settings.app.extensions]
skipPublishVerification = false
registryEnabled = true
@@ -206,6 +203,8 @@ enabled=true # Enable this for DLSS
# Load Isaac Lab extensions last
"isaaclab" = {order = 1000}
+"isaaclab_physx" = {order = 1000}
+"isaaclab_newton" = {order = 1000}
"isaaclab_assets" = {order = 1000}
"isaaclab_tasks" = {order = 1000}
"isaaclab_mimic" = {order = 1000}
@@ -215,6 +214,6 @@ enabled=true # Enable this for DLSS
# set the S3 directory manually to the latest published S3
# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
[settings]
-persistent.isaac.asset_root.default = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.cloud = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.nvidia = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
+persistent.isaac.asset_root.default = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.cloud = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.nvidia = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
diff --git a/apps/isaaclab.python.headless.rendering.kit b/apps/isaaclab.python.headless.rendering.kit
index 870c65bb4bf..90fee65f77e 100644
--- a/apps/isaaclab.python.headless.rendering.kit
+++ b/apps/isaaclab.python.headless.rendering.kit
@@ -9,7 +9,7 @@
[package]
title = "Isaac Lab Python Headless Camera"
description = "An app for running Isaac Lab headlessly with rendering enabled"
-version = "2.3.2"
+version = "3.0.0"
# That makes it browsable in UI with "experience" filter
keywords = ["experience", "app", "isaaclab", "python", "camera", "minimal"]
@@ -31,8 +31,8 @@ cameras_enabled = true
# Note: This path was adapted to be respective to the kit-exe file location
app.versionFile = "${exe-path}/VERSION"
app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "5.1.0"
+app.name = "IsaacLab"
+app.version = "3.0.0"
### FSD
app.useFabricSceneDelegate = true
@@ -83,6 +83,9 @@ app.updateOrder.checkForHydraRenderComplete = 1000
app.renderer.waitIdle=true
app.hydraEngine.waitIdle=true
+# NuRec
+omni.rtx.nre.compositing.rendererHints = 3
+
# Forces serial processing for omni graph to avoid NCCL timeout hangs in distributed training
app.execution.debug.forceSerial = true
@@ -103,12 +106,8 @@ exts."omni.replicator.core".Orchestrator.enabled = false
# disable the metrics assembler change listener, we don't want to do any runtime changes
metricsAssembler.changeListenerEnabled = false
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/107/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
+# explicitly disable omni.kit.pip_archive to prevent conflicting dependencies
+app.extensions.excluded = ["omni.kit.pip_archive", "omni.isaac.ml_archive", "isaacsim.pip.newton", "omni.warp.core"]
[settings.app.python]
# These disable the kit app from also printing out python output, which gets confusing
@@ -152,10 +151,14 @@ folders = [
"${app}/../source", # needed to find extensions in Isaac Lab
]
+[settings.persistent]
+UJITSO.geometry = true
+UJITSO.enabled = true
+
# Asset path
# set the S3 directory manually to the latest published S3
# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
[settings]
-persistent.isaac.asset_root.default = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.cloud = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.nvidia = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
+persistent.isaac.asset_root.default = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.cloud = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.nvidia = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
diff --git a/apps/isaaclab.python.kit b/apps/isaaclab.python.kit
index 2435019c89c..a5330cd1944 100644
--- a/apps/isaaclab.python.kit
+++ b/apps/isaaclab.python.kit
@@ -3,9 +3,9 @@
##
[package]
-title = "Isaac Lab Python"
+title = "Isaac Lab"
description = "An app for running Isaac Lab"
-version = "2.3.2"
+version = "3.0.0"
# That makes it browsable in UI with "experience" filter
keywords = ["experience", "app", "usd"]
@@ -13,11 +13,10 @@ keywords = ["experience", "app", "usd"]
[dependencies]
# Isaac Sim extensions
"isaacsim.app.about" = {}
-"isaacsim.asset.browser" = {}
+"isaacsim.examples.browser" = {}
"isaacsim.core.api" = {}
"isaacsim.core.cloner" = {}
"isaacsim.core.nodes" = {}
-"isaacsim.core.simulation_manager" = {}
"isaacsim.core.throttling" = {}
"isaacsim.core.utils" = {}
"isaacsim.core.version" = {}
@@ -38,7 +37,7 @@ keywords = ["experience", "app", "usd"]
# Isaac Sim Extra
"isaacsim.asset.importer.mjcf" = {}
-"isaacsim.asset.importer.urdf" = {version = "2.4.31", exact = true}
+"isaacsim.asset.importer.urdf" = {}
"omni.physx.bundle" = {}
"omni.physx.tensors" = {}
"omni.replicator.core" = {}
@@ -93,7 +92,6 @@ keywords = ["experience", "app", "usd"]
"omni.uiaudio" = {}
"omni.usd.metrics.assembler.ui" = {}
"omni.usd.schema.metrics.assembler" = {}
-"omni.warp.core" = {}
########################
# Isaac Lab Extensions #
@@ -101,6 +99,8 @@ keywords = ["experience", "app", "usd"]
# Load Isaac Lab extensions last
"isaaclab" = {order = 1000}
+"isaaclab_physx" = {order = 1000}
+"isaaclab_newton" = {order = 1000}
"isaaclab_assets" = {order = 1000}
"isaaclab_tasks" = {order = 1000}
"isaaclab_mimic" = {order = 1000}
@@ -126,6 +126,8 @@ rtx.hydra.mdlMaterialWarmup = true # start loading the MDL shaders needed before
omni.replicator.asyncRendering = false # Async rendering must be disabled for SDG
exts."omni.kit.test".includeTests = ["*isaac*"] # Add isaac tests to test runner
foundation.verifyOsVersion.enabled = false
+log.level = "Warn" # Suppress third-party debug/info noise
+log.outputStreamLevel = "Warn"
# disable the metrics assembler change listener, we don't want to do any runtime changes
metricsAssembler.changeListenerEnabled = false
@@ -160,8 +162,8 @@ indent_all_ticks = false
show_menu_titles = true
[settings.app]
-name = "Isaac-Sim"
-version = "5.1.0"
+name = "IsaacLab"
+version = "3.0.0"
versionFile = "${exe-path}/VERSION"
content.emptyStageOnStart = true
fastShutdown = true
@@ -182,7 +184,7 @@ asyncRenderingLowLatency = false
[settings.app.window]
iconPath = "${isaacsim.simulation_app}/data/omni.isaac.sim.png"
-title = "Isaac Sim"
+title = "Isaac Lab"
[settings.app.python]
# These disable the kit app from also printing out python output, which gets confusing
@@ -234,6 +236,8 @@ renderer.startupMessageDisplayed = true # hides the IOMMU popup window
resourcemonitor.timeBetweenQueries = 100 # improves performance
simulation.defaultMetersPerUnit = 1.0 # Meters default
omni.replicator.captureOnPlay = true
+UJITSO.geometry = true
+UJITSO.enabled = true
[settings]
### async rendering settings
@@ -248,18 +252,17 @@ rtx.hydra.readTransformsFromFabricInRenderDelegate = true
# disable replicator orchestrator for better runtime perf
exts."omni.replicator.core".Orchestrator.enabled = false
+# NuRec
+omni.rtx.nre.compositing.rendererHints = 3
+
+# explicitly disable omni.kit.pip_archive to prevent conflicting dependencies
+app.extensions.excluded = ["omni.kit.pip_archive", "omni.isaac.ml_archive", "isaacsim.pip.newton", "omni.warp.core"]
+
[settings.app.livestream]
outDirectory = "${data}"
# Extensions
###############################
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/107/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
[settings.app.extensions]
skipPublishVerification = false
registryEnabled = true
@@ -302,6 +305,6 @@ fabricUseGPUInterop = true
# set the S3 directory manually to the latest published S3
# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
[settings]
-persistent.isaac.asset_root.default = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.cloud = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.nvidia = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
+persistent.isaac.asset_root.default = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.cloud = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.nvidia = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
diff --git a/apps/isaaclab.python.rendering.kit b/apps/isaaclab.python.rendering.kit
index d27498bd405..d3414b21190 100644
--- a/apps/isaaclab.python.rendering.kit
+++ b/apps/isaaclab.python.rendering.kit
@@ -9,7 +9,7 @@
[package]
title = "Isaac Lab Python Camera"
description = "An app for running Isaac Lab with rendering enabled"
-version = "2.3.2"
+version = "3.0.0"
# That makes it browsable in UI with "experience" filter
keywords = ["experience", "app", "isaaclab", "python", "camera", "minimal"]
@@ -18,9 +18,6 @@ keywords = ["experience", "app", "isaaclab", "python", "camera", "minimal"]
# Isaac Lab minimal app
"isaaclab.python" = {}
-# PhysX
-"omni.kit.property.physx" = {}
-
# Rendering
"omni.kit.material.library" = {}
@@ -32,8 +29,8 @@ cameras_enabled = true
# Note: This path was adapted to be respective to the kit-exe file location
app.versionFile = "${exe-path}/VERSION"
app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "5.1.0"
+app.name = "IsaacLab"
+app.version = "3.0.0"
### FSD
app.useFabricSceneDelegate = true
@@ -79,6 +76,9 @@ renderer.multiGpu.maxGpuCount=1
# Force synchronous rendering to improve training results
omni.replicator.asyncRendering = false
+# NuRec
+omni.rtx.nre.compositing.rendererHints = 3
+
# Avoids frame offset issue
app.updateOrder.checkForHydraRenderComplete = 1000
app.renderer.waitIdle=true
@@ -92,6 +92,9 @@ exts."omni.replicator.core".Orchestrator.enabled = false
# disable the metrics assembler change listener, we don't want to do any runtime changes
metricsAssembler.changeListenerEnabled = false
+# explicitly disable omni.kit.pip_archive to prevent conflicting dependencies
+app.extensions.excluded = ["omni.kit.pip_archive", "omni.isaac.ml_archive", "isaacsim.pip.newton", "omni.warp.core"]
+
[settings.physics]
updateToUsd = false
updateParticlesToUsd = false
@@ -107,13 +110,6 @@ fabricUpdateJointStates = false
### When Direct GPU mode is enabled (suppressReadback=true) use direct interop between PhysX GPU and Fabric
fabricUseGPUInterop = true
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/107/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
[settings.app.python]
# These disable the kit app from also printing out python output, which gets confusing
interceptSysStdOutput = false
@@ -141,10 +137,14 @@ folders = [
"${app}/../source", # needed to find extensions in Isaac Lab
]
+[settings.persistent]
+UJITSO.geometry = true
+UJITSO.enabled = true
+
# Asset path
# set the S3 directory manually to the latest published S3
# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
[settings]
-persistent.isaac.asset_root.default = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.cloud = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.nvidia = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
+persistent.isaac.asset_root.default = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.cloud = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.nvidia = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
diff --git a/apps/isaaclab.python.xr.openxr.headless.kit b/apps/isaaclab.python.xr.openxr.headless.kit
index 57b78c1b290..75f3ae63712 100644
--- a/apps/isaaclab.python.xr.openxr.headless.kit
+++ b/apps/isaaclab.python.xr.openxr.headless.kit
@@ -5,7 +5,7 @@
[package]
title = "Isaac Lab Python OpenXR Headless"
description = "An app for running Isaac Lab with OpenXR in headless mode"
-version = "2.3.2"
+version = "3.0.0"
# That makes it browsable in UI with "experience" filter
keywords = ["experience", "app", "usd", "headless"]
@@ -14,8 +14,8 @@ keywords = ["experience", "app", "usd", "headless"]
# Note: This path was adapted to be respective to the kit-exe file location
app.versionFile = "${exe-path}/VERSION"
app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "5.1.0"
+app.name = "IsaacLab"
+app.version = "3.0.0"
### FSD
app.useFabricSceneDelegate = true
@@ -33,8 +33,16 @@ cameras_enabled = true
[dependencies]
"isaaclab.python.xr.openxr" = {}
+# NOTE: xr.profile.ar.enabled is intentionally NOT set here.
+# Setting it in the .kit file causes Kit's XR system to create the OpenXR
+# instance before the teleop bridge extension loads, so the BridgeComponent
+# misses its lifecycle callbacks (getRequiredExtensions, initialize).
+# Instead, TeleopSessionLifecycle._ensure_xr_ar_profile_enabled() sets it
+# via carb.settings after extensions have loaded.
+
[settings]
-xr.profile.ar.enabled = true
+# explicitly disable omni.kit.pip_archive to prevent conflicting dependencies
+app.extensions.excluded = ["omni.kit.pip_archive", "omni.isaac.ml_archive", "isaacsim.pip.newton", "omni.warp.core"]
[settings.app.python]
# These disable the kit app from also printing out python output, which gets confusing
@@ -47,6 +55,7 @@ folders = [
"${exe-path}/exts", # kit extensions
"${exe-path}/extscore", # kit core extensions
"${exe-path}/../exts", # isaac extensions
+ "${exe-path}/../extsInternal", # isaac internal extensions
"${exe-path}/../extsDeprecated", # deprecated isaac extensions
"${exe-path}/../extscache", # isaac cache extensions
"${exe-path}/../extsPhysics", # isaac physics extensions
@@ -58,7 +67,11 @@ folders = [
"${app}/../source", # needed to find extensions in Isaac Lab
]
+[settings.persistent]
+UJITSO.geometry = true
+UJITSO.enabled = true
+
[settings]
-persistent.isaac.asset_root.default = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.cloud = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.nvidia = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
+persistent.isaac.asset_root.default = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.cloud = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.nvidia = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
diff --git a/apps/isaaclab.python.xr.openxr.kit b/apps/isaaclab.python.xr.openxr.kit
index 8fe9980e50b..62782ba0661 100644
--- a/apps/isaaclab.python.xr.openxr.kit
+++ b/apps/isaaclab.python.xr.openxr.kit
@@ -5,7 +5,7 @@
[package]
title = "Isaac Lab Python OpenXR"
description = "An app for running Isaac Lab with OpenXR"
-version = "2.3.2"
+version = "3.0.0"
# That makes it browsable in UI with "experience" filter
keywords = ["experience", "app", "usd"]
@@ -14,8 +14,8 @@ keywords = ["experience", "app", "usd"]
# Note: This path was adapted to be respective to the kit-exe file location
app.versionFile = "${exe-path}/VERSION"
app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "5.1.0"
+app.name = "IsaacLab"
+app.version = "3.0.0"
### async rendering settings
# omni.replicator.asyncRendering needs to be false for external camera rendering
@@ -39,9 +39,10 @@ xr.skipInputDeviceUSDWrites = true
[dependencies]
"isaaclab.python" = {}
-# Kit extensions
+# Required for XR instruction widget (CopyFabricPrim)
+"omni.fabric.commands" = {}
"omni.kit.xr.system.openxr" = {}
-"omni.kit.xr.profile.ar" = {}
+"omni.kit.xr.bundle.generic" = {}
[settings.isaaclab]
# This is used to check that this experience file is loaded when using cameras
@@ -54,13 +55,18 @@ app.profilerBackend = "nvtx"
# xr settings
xr.ui.enabled = false
-xr.depth.aov = "GBufferDepth"
defaults.xr.profile.ar.anchorMode = "custom anchor"
+# Enable AR by default
+defaults.xr.activeProfile = "ar"
rtx.rendermode = "RaytracedLighting"
persistent.xr.profile.ar.renderQuality = "performance"
persistent.xr.profile.ar.render.nearPlane = 0.15
xr.openxr.components."omni.kit.xr.openxr.ext.hand_tracking".enabled = true
xr.openxr.components."isaacsim.xr.openxr.hand_tracking".enabled = true
+xr.openxr.components."isaacsim.kit.xr.teleop.bridge".enabled = true
+
+# explicitly disable omni.kit.pip_archive to prevent conflicting dependencies
+app.extensions.excluded = ["omni.kit.pip_archive", "omni.isaac.ml_archive", "isaacsim.pip.newton", "omni.warp.core"]
[settings.app.python]
# These disable the kit app from also printing out python output, which gets confusing
@@ -73,6 +79,7 @@ folders = [
"${exe-path}/exts", # kit extensions
"${exe-path}/extscore", # kit core extensions
"${exe-path}/../exts", # isaac extensions
+ "${exe-path}/../extsInternal", # isaac internal extensions
"${exe-path}/../extsDeprecated", # deprecated isaac extensions
"${exe-path}/../extscache", # isaac cache extensions
"${exe-path}/../extsPhysics", # isaac physics extensions
@@ -84,10 +91,14 @@ folders = [
"${app}/../source", # needed to find extensions in Isaac Lab
]
+[settings.persistent]
+UJITSO.geometry = true
+UJITSO.enabled = true
+
# Asset path
# set the S3 directory manually to the latest published S3
# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
[settings]
-persistent.isaac.asset_root.default = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.cloud = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
-persistent.isaac.asset_root.nvidia = "https://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/5.1"
+persistent.isaac.asset_root.default = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.cloud = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
+persistent.isaac.asset_root.nvidia = "https://omniverse-content-staging.s3-us-west-2.amazonaws.com/Assets/Isaac/6.0"
diff --git a/apps/isaacsim_4_5/extension.toml b/apps/isaacsim_4_5/extension.toml
deleted file mode 100644
index f0668b9184d..00000000000
--- a/apps/isaacsim_4_5/extension.toml
+++ /dev/null
@@ -1 +0,0 @@
-# This is not an extension
diff --git a/apps/isaacsim_4_5/isaaclab.python.headless.kit b/apps/isaacsim_4_5/isaaclab.python.headless.kit
deleted file mode 100644
index 0fb9eaeffff..00000000000
--- a/apps/isaacsim_4_5/isaaclab.python.headless.kit
+++ /dev/null
@@ -1,202 +0,0 @@
-##
-# Adapted from: _isaac_sim/apps/omni.isaac.sim.python.gym.headless.kit
-##
-
-[package]
-title = "Isaac Lab Python Headless"
-description = "An app for running Isaac Lab headlessly"
-version = "2.3.2"
-
-# That makes it browsable in UI with "experience" filter
-keywords = ["experience", "app", "isaaclab", "python", "headless"]
-
-[settings]
-# Note: This path was adapted to be respective to the kit-exe file location
-app.versionFile = "${exe-path}/VERSION"
-app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "4.5.0"
-
-##################################
-# Omniverse related dependencies #
-##################################
-[dependencies]
-"omni.physx" = {}
-"omni.physx.tensors" = {}
-"omni.physx.fabric" = {}
-"omni.warp.core" = {}
-"usdrt.scenegraph" = {}
-"omni.kit.telemetry" = {}
-"omni.kit.loop" = {}
-
-[settings]
-app.content.emptyStageOnStart = false
-
-# Disable print outs on extension startup information
-# this only disables the app print_and_log function
-app.enableStdoutOutput = false
-
-# default viewport is fill
-app.runLoops.rendering_0.fillResolution = false
-exts."omni.kit.window.viewport".blockingGetViewportDrawable = false
-
-# Fix PlayButtonGroup error
-exts."omni.kit.widget.toolbar".PlayButton.enabled = false
-
-# disable replicator orchestrator for better runtime perf
-exts."omni.replicator.core".Orchestrator.enabled = false
-
-[settings.app.settings]
-persistent = true
-dev_build = false
-fabricDefaultStageFrameHistoryCount = 3 # needed for omni.syntheticdata TODO105 still true?
-
-[settings.app.python]
-# These disable the kit app from also printing out python output, which gets confusing
-interceptSysStdOutput = false
-logSysStdOutput = false
-
-[settings]
-# MGPU is always on, you can turn it from the settings, and force this off to save even more resource if you
-# only want to use a single GPU on your MGPU system
-# False for Isaac Sim
-renderer.multiGpu.enabled = true
-renderer.multiGpu.autoEnable = true
-'rtx-transient'.resourcemanager.enableTextureStreaming = true
-app.asyncRendering = false
-app.asyncRenderingLowLatency = false
-app.hydraEngine.waitIdle = false
-# app.hydra.aperture.conform = 4 # in 105.1 pixels are square by default
-omni.replicator.asyncRendering = false
-
-# Enable Iray and pxr by setting this to "rtx,iray,pxr"
-renderer.enabled = "rtx"
-
-# Avoid warning on shutdown from audio context
-app.audio.enabled = false
-
-# Enable Vulkan - avoids torch+cu12 error on windows
-app.vulkan = true
-
-# Set profiler backend to NVTX by default
-app.profilerBackend = "nvtx"
-
-# hide NonToggleable Exts
-exts."omni.kit.window.extensions".hideNonToggleableExts = true
-exts."omni.kit.window.extensions".showFeatureOnly = false
-
-# set the default ros bridge to disable on startup
-isaac.startup.ros_bridge_extension = ""
-
-# Extensions
-###############################
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/106/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
-[settings.app.extensions]
-skipPublishVerification = false
-registryEnabled = true
-
-[settings.crashreporter.data]
-experience = "Isaac Sim"
-
-[settings.persistent]
-app.file.recentFiles = []
-app.stage.upAxis = "Z"
-app.stage.movePrimInPlace = false
-app.stage.instanceableOnCreatingReference = false
-app.stage.materialStrength = "weakerThanDescendants"
-
-app.transform.gizmoUseSRT = true
-app.viewport.grid.scale = 1.0
-app.viewport.pickingMode = "kind:model.ALL"
-app.viewport.camMoveVelocity = 0.05 # 5 m/s
-app.viewport.gizmo.scale = 0.01 # scaled to meters
-app.viewport.previewOnPeek = false
-app.viewport.snapToSurface = false
-app.viewport.displayOptions = 31951 # Disable Frame Rate and Resolution by default
-app.window.uiStyle = "NvidiaDark"
-app.primCreation.DefaultXformOpType = "Scale, Orient, Translate"
-app.primCreation.DefaultXformOpOrder="xformOp:translate, xformOp:orient, xformOp:scale"
-app.primCreation.typedDefaults.camera.clippingRange = [0.01, 10000000.0]
-simulation.minFrameRate = 15
-simulation.defaultMetersPerUnit = 1.0
-omnigraph.updateToUsd = false
-omnigraph.useSchemaPrims = true
-omnigraph.disablePrimNodes = true
-omni.replicator.captureOnPlay = true
-omnihydra.useSceneGraphInstancing = true
-renderer.startupMessageDisplayed = true # hides the IOMMU popup window
-
-# Make Detail panel visible by default
-app.omniverse.content_browser.options_menu.show_details = true
-app.omniverse.filepicker.options_menu.show_details = true
-
-[settings.physics]
-updateToUsd = false
-updateParticlesToUsd = false
-updateVelocitiesToUsd = false
-updateForceSensorsToUsd = false
-outputVelocitiesLocalSpace = false
-useFastCache = false
-visualizationDisplayJoints = false
-fabricUpdateTransformations = false
-fabricUpdateVelocities = false
-fabricUpdateForceSensors = false
-fabricUpdateJointStates = false
-
-# Performance improvement
-resourcemonitor.timeBetweenQueries = 100
-
-# Register extension folder from this repo in kit
-[settings.app.exts]
-folders = [
- "${exe-path}/exts", # kit extensions
- "${exe-path}/extscore", # kit core extensions
- "${exe-path}/../exts", # isaac extensions
- "${exe-path}/../extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../extscache", # isaac cache extensions
- "${exe-path}/../extsPhysics", # isaac physics extensions
- "${exe-path}/../isaacsim/exts", # isaac extensions for pip
- "${exe-path}/../isaacsim/extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../isaacsim/extscache", # isaac cache extensions for pip
- "${exe-path}/../isaacsim/extsPhysics", # isaac physics extensions for pip
- "${app}", # needed to find other app files
- "${app}/../../source", # needed to find extensions in Isaac Lab
-]
-
-[settings.ngx]
-enabled=true # Enable this for DLSS
-
-########################
-# Isaac Sim Extensions #
-########################
-[dependencies]
-"isaacsim.simulation_app" = {}
-"isaacsim.core.api" = {}
-"isaacsim.core.cloner" = {}
-"isaacsim.core.utils" = {}
-"isaacsim.core.version" = {}
-
-########################
-# Isaac Lab Extensions #
-########################
-
-# Load Isaac Lab extensions last
-"isaaclab" = {order = 1000}
-"isaaclab_assets" = {order = 1000}
-"isaaclab_tasks" = {order = 1000}
-"isaaclab_mimic" = {order = 1000}
-"isaaclab_rl" = {order = 1000}
-
-# Asset path
-# set the S3 directory manually to the latest published S3
-# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
-[settings]
-persistent.isaac.asset_root.default = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.cloud = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.nvidia = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
diff --git a/apps/isaacsim_4_5/isaaclab.python.headless.rendering.kit b/apps/isaacsim_4_5/isaaclab.python.headless.rendering.kit
deleted file mode 100644
index 10b3efc84bf..00000000000
--- a/apps/isaacsim_4_5/isaaclab.python.headless.rendering.kit
+++ /dev/null
@@ -1,145 +0,0 @@
-##
-# Adapted from: https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs/blob/main/apps/omni.isaac.sim.python.gym.camera.kit
-#
-# This app file designed specifically towards vision-based RL tasks. It provides necessary settings to enable
-# multiple cameras to be rendered each frame. Additional settings are also applied to increase performance when
-# rendering cameras across multiple environments.
-##
-
-[package]
-title = "Isaac Lab Python Headless Camera"
-description = "An app for running Isaac Lab headlessly with rendering enabled"
-version = "2.3.2"
-
-# That makes it browsable in UI with "experience" filter
-keywords = ["experience", "app", "isaaclab", "python", "camera", "minimal"]
-
-[dependencies]
-# Isaac Lab minimal app
-"isaaclab.python.headless" = {}
-"omni.replicator.core" = {}
-
-# Rendering
-"omni.kit.material.library" = {}
-"omni.kit.viewport.rtx" = {}
-
-[settings.isaaclab]
-# This is used to check that this experience file is loaded when using cameras
-cameras_enabled = true
-
-[settings]
-# Note: This path was adapted to be respective to the kit-exe file location
-app.versionFile = "${exe-path}/VERSION"
-app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "4.5.0"
-
-# Disable print outs on extension startup information
-# this only disables the app print_and_log function
-app.enableStdoutOutput = false
-
-# set the default ros bridge to disable on startup
-isaac.startup.ros_bridge_extension = ""
-
-# Flags for better rendering performance
-# Disabling these settings reduces renderer VRAM usage and improves rendering performance, but at some quality cost
-rtx.translucency.enabled = false
-rtx.reflections.enabled = false
-rtx.indirectDiffuse.enabled = false
-rtx-transient.dlssg.enabled = false
-rtx.directLighting.sampledLighting.enabled = true
-rtx.directLighting.sampledLighting.samplesPerPixel = 1
-rtx.sceneDb.ambientLightIntensity = 1.0
-# rtx.shadows.enabled = false
-
-# Avoids replicator warning
-rtx.pathtracing.maxSamplesPerLaunch = 1000000
-# Avoids silent trimming of tiles
-rtx.viewTile.limit = 1000000
-
-# Disable present thread to improve performance
-exts."omni.renderer.core".present.enabled=false
-
-# Disabling these settings reduces renderer VRAM usage and improves rendering performance, but at some quality cost
-rtx.raytracing.cached.enabled = false
-rtx.ambientOcclusion.enabled = false
-
-# Set the DLSS model
-rtx.post.dlss.execMode = 0 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
-
-# Avoids unnecessary GPU context initialization
-renderer.multiGpu.maxGpuCount=1
-
-# Force synchronous rendering to improve training results
-omni.replicator.asyncRendering = false
-
-# Avoids frame offset issue
-app.updateOrder.checkForHydraRenderComplete = 1000
-app.renderer.waitIdle=true
-app.hydraEngine.waitIdle=true
-
-app.audio.enabled = false
-
-# Enable Vulkan - avoids torch+cu12 error on windows
-app.vulkan = true
-
-# Set profiler backend to NVTX by default
-app.profilerBackend = "nvtx"
-
-# disable replicator orchestrator for better runtime perf
-exts."omni.replicator.core".Orchestrator.enabled = false
-
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/106/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
-[settings.app.python]
-# These disable the kit app from also printing out python output, which gets confusing
-interceptSysStdOutput = false
-logSysStdOutput = false
-
-[settings.app.renderer]
-skipWhileMinimized = false
-sleepMsOnFocus = 0
-sleepMsOutOfFocus = 0
-
-[settings.physics]
-updateToUsd = false
-updateParticlesToUsd = false
-updateVelocitiesToUsd = false
-updateForceSensorsToUsd = false
-outputVelocitiesLocalSpace = false
-useFastCache = false
-visualizationDisplayJoints = false
-fabricUpdateTransformations = false
-fabricUpdateVelocities = false
-fabricUpdateForceSensors = false
-fabricUpdateJointStates = false
-
-# Register extension folder from this repo in kit
-[settings.app.exts]
-folders = [
- "${exe-path}/exts", # kit extensions
- "${exe-path}/extscore", # kit core extensions
- "${exe-path}/../exts", # isaac extensions
- "${exe-path}/../extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../extscache", # isaac cache extensions
- "${exe-path}/../extsPhysics", # isaac physics extensions
- "${exe-path}/../isaacsim/exts", # isaac extensions for pip
- "${exe-path}/../isaacsim/extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../isaacsim/extscache", # isaac cache extensions for pip
- "${exe-path}/../isaacsim/extsPhysics", # isaac physics extensions for pip
- "${app}", # needed to find other app files
- "${app}/../../source", # needed to find extensions in Isaac Lab
-]
-
-# Asset path
-# set the S3 directory manually to the latest published S3
-# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
-[settings]
-persistent.isaac.asset_root.default = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.cloud = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.nvidia = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
diff --git a/apps/isaacsim_4_5/isaaclab.python.kit b/apps/isaacsim_4_5/isaaclab.python.kit
deleted file mode 100644
index 5fc9b1effd9..00000000000
--- a/apps/isaacsim_4_5/isaaclab.python.kit
+++ /dev/null
@@ -1,301 +0,0 @@
-##
-# Adapted from: _isaac_sim/apps/isaacsim.exp.base.kit
-##
-
-[package]
-title = "Isaac Lab Python"
-description = "An app for running Isaac Lab"
-version = "2.3.2"
-
-# That makes it browsable in UI with "experience" filter
-keywords = ["experience", "app", "usd"]
-
-[dependencies]
-# Isaac Sim extensions
-"isaacsim.app.about" = {}
-"isaacsim.asset.browser" = {}
-"isaacsim.core.api" = {}
-"isaacsim.core.cloner" = {}
-"isaacsim.core.nodes" = {}
-"isaacsim.core.simulation_manager" = {}
-"isaacsim.core.throttling" = {}
-"isaacsim.core.utils" = {}
-"isaacsim.core.version" = {}
-"isaacsim.gui.menu" = {}
-"isaacsim.gui.property" = {}
-"isaacsim.replicator.behavior" = {}
-"isaacsim.robot.manipulators" = {}
-"isaacsim.robot.policy.examples" = {}
-"isaacsim.robot.schema" = {}
-"isaacsim.robot.surface_gripper" = {}
-"isaacsim.robot.wheeled_robots" = {}
-"isaacsim.sensors.camera" = {}
-"isaacsim.sensors.physics" = {}
-"isaacsim.sensors.physx" = {}
-"isaacsim.sensors.rtx" = {}
-"isaacsim.simulation_app" = {}
-"isaacsim.storage.native" = {}
-"isaacsim.util.debug_draw" = {}
-
-# Isaac Sim Extra
-"isaacsim.asset.importer.mjcf" = {}
-"isaacsim.asset.importer.urdf" = {}
-"omni.physx.bundle" = {}
-"omni.physx.tensors" = {}
-"omni.replicator.core" = {}
-"omni.replicator.replicator_yaml" = {}
-"omni.syntheticdata" = {}
-"semantics.schema.editor" = {}
-"semantics.schema.property" = {}
-
-# Kit based editor extensions
-"omni.anim.curve.core" = {}
-"omni.graph.action" = {}
-"omni.graph.core" = {}
-"omni.graph.nodes" = {}
-"omni.graph.scriptnode" = {}
-"omni.graph.ui_nodes" = {}
-"omni.hydra.engine.stats" = {}
-"omni.hydra.rtx" = {}
-"omni.kit.loop" = {}
-"omni.kit.mainwindow" = {}
-"omni.kit.manipulator.camera" = {}
-"omni.kit.manipulator.prim" = {}
-"omni.kit.manipulator.selection" = {}
-"omni.kit.material.library" = {}
-"omni.kit.menu.common" = { order = 1000 }
-"omni.kit.menu.create" = {}
-"omni.kit.menu.edit" = {}
-"omni.kit.menu.file" = {}
-"omni.kit.menu.stage" = {}
-"omni.kit.menu.utils" = {}
-"omni.kit.primitive.mesh" = {}
-"omni.kit.property.bundle" = {}
-"omni.kit.raycast.query" = {}
-"omni.kit.stage_template.core" = {}
-"omni.kit.stagerecorder.bundle" = {}
-"omni.kit.telemetry" = {}
-"omni.kit.tool.asset_importer" = {}
-"omni.kit.tool.collect" = {}
-"omni.kit.viewport.legacy_gizmos" = {}
-"omni.kit.viewport.menubar.camera" = {}
-"omni.kit.viewport.menubar.display" = {}
-"omni.kit.viewport.menubar.lighting" = {}
-"omni.kit.viewport.menubar.render" = {}
-"omni.kit.viewport.menubar.settings" = {}
-"omni.kit.viewport.scene_camera_model" = {}
-"omni.kit.viewport.window" = {}
-"omni.kit.window.console" = {}
-"omni.kit.window.content_browser" = {}
-"omni.kit.window.property" = {}
-"omni.kit.window.stage" = {}
-"omni.kit.window.status_bar" = {}
-"omni.kit.window.toolbar" = {}
-"omni.physx.stageupdate" = {}
-"omni.rtx.settings.core" = {}
-"omni.uiaudio" = {}
-"omni.usd.metrics.assembler.ui" = {}
-"omni.usd.schema.metrics.assembler" = {}
-"omni.warp.core" = {}
-
-########################
-# Isaac Lab Extensions #
-########################
-
-# Load Isaac Lab extensions last
-"isaaclab" = {order = 1000}
-"isaaclab_assets" = {order = 1000}
-"isaaclab_tasks" = {order = 1000}
-"isaaclab_mimic" = {order = 1000}
-"isaaclab_rl" = {order = 1000}
-
-[settings]
-exts."omni.kit.material.library".ui_show_list = [
- "OmniPBR",
- "OmniGlass",
- "OmniSurface",
- "USD Preview Surface",
-]
-exts."omni.kit.renderer.core".present.enabled = false # Fixes MGPU stability issue
-exts."omni.kit.viewport.window".windowMenu.entryCount = 2 # Allow user to create two viewports by default
-exts."omni.kit.viewport.window".windowMenu.label = "" # Put Viewport menuitem under Window menu
-exts."omni.rtx.window.settings".window_menu = "Window" # Where to put the render settings menuitem
-exts."omni.usd".locking.onClose = false # reduce time it takes to close/create stage
-renderer.asyncInit = true # Don't block while renderer inits
-renderer.gpuEnumeration.glInterop.enabled = false # Improves startup speed.
-rendergraph.mgpu.backend = "copyQueue" # In MGPU configurations, This setting can be removed if IOMMU is disabled for better performance, copyQueue improves stability and performance when IOMMU is enabled
-rtx-transient.dlssg.enabled = false # DLSSG frame generation is not compatible with synthetic data generation
-rtx.hydra.mdlMaterialWarmup = true # start loading the MDL shaders needed before any delegate is actually created.
-omni.replicator.asyncRendering = false # Async rendering must be disabled for SDG
-exts."omni.kit.test".includeTests = ["*isaac*"] # Add isaac tests to test runner
-foundation.verifyOsVersion.enabled = false
-
-# set the default ros bridge to disable on startup
-isaac.startup.ros_bridge_extension = ""
-
-# Disable for base application
-[settings."filter:platform"."windows-x86_64"]
-isaac.startup.ros_bridge_extension = ""
-[settings."filter:platform"."linux-x86_64"]
-isaac.startup.ros_bridge_extension = ""
-
-# menu styling
-[settings.exts."omni.kit.menu.utils"]
-logDeprecated = false
-margin_size = [18, 3]
-tick_spacing = [10, 6]
-margin_size_posttick = [0, 3]
-separator_size = [14, 10]
-root_spacing = 3
-post_label_spaces = 6
-color_tick_enabled = 0xFFFAC434
-color_separator = 0xFF7E7E7E
-color_label_enabled = 0xFFEEEEEE
-menu_title_color = 0xFF202020
-menu_title_line_color = 0xFF5E5E5E
-menu_title_text_color = 0xFF8F8F8F
-menu_title_text_height = 24
-menu_title_close_color = 0xFFC6C6C6
-indent_all_ticks = false
-show_menu_titles = true
-
-[settings.app]
-name = "Isaac-Sim"
-version = "4.5.0"
-versionFile = "${exe-path}/VERSION"
-content.emptyStageOnStart = true
-fastShutdown = true
-file.ignoreUnsavedOnExit = true
-font.file = "${fonts}/OpenSans-SemiBold.ttf"
-font.size = 16
-gatherRenderResults = true # True to prevent artifacts in multiple viewport configurations, can be set to false for better performance in some cases
-hangDetector.enabled = true
-hangDetector.timeout = 120
-player.useFixedTimeStepping = true
-settings.fabricDefaultStageFrameHistoryCount = 3 # needed for omni.syntheticdata TODO105 still true?
-settings.persistent = true # settings are persistent for this app
-
-vulkan = true # Explicitly enable Vulkan (on by default on Linux, off by default on Windows)
-### async rendering settings
-asyncRendering = false
-asyncRenderingLowLatency = false
-
-[settings.app.window]
-iconPath = "${isaacsim.simulation_app}/data/omni.isaac.sim.png"
-title = "Isaac Sim"
-
-[settings.app.python]
-# These disable the kit app from also printing out python output, which gets confusing
-interceptSysStdOutput = false
-logSysStdOutput = false
-
-[settings.app.renderer]
-resolution.height = 720
-resolution.width = 1280
-skipWhileMinimized = false # python app does not throttle
-sleepMsOnFocus = 0 # python app does not throttle
-sleepMsOutOfFocus = 0 # python app does not throttle
-
-[settings.app.viewport]
-defaultCamPos.x = 5
-defaultCamPos.y = 5
-defaultCamPos.z = 5
-defaults.fillViewport = false # default to not fill viewport
-grid.enabled = true
-outline.enabled = true
-boundingBoxes.enabled = false
-show.camera=false
-show.lights=false
-
-[settings.telemetry]
-enableAnonymousAppName = true # Anonymous Kit application usage telemetry
-enableAnonymousData = true # Anonymous Kit application usage telemetry
-
-[settings.persistent]
-app.primCreation.DefaultXformOpOrder = "xformOp:translate, xformOp:orient, xformOp:scale"
-app.primCreation.DefaultXformOpType = "Scale, Orient, Translate"
-app.primCreation.typedDefaults.camera.clippingRange = [0.01, 10000000.0] # Meters default
-app.primCreation.DefaultXformOpPrecision = "Double"
-app.primCreation.DefaultRotationOrder = "ZYX"
-app.primCreation.PrimCreationWithDefaultXformOps = true
-app.stage.timeCodeRange = [0, 1000000]
-app.stage.upAxis = "Z" # Isaac Sim default Z up
-app.viewport.camMoveVelocity = 0.05 # Meters default
-app.viewport.gizmo.scale = 0.01 # Meters default
-app.viewport.grid.scale = 1.0 # Meters default
-app.viewport.camShowSpeedOnStart = false # Hide camera speed on startup
-app.omniverse.gamepadCameraControl = false # Disable gamepad control for camera by default
-exts."omni.anim.navigation.core".navMesh.config.autoRebakeOnChanges = false
-exts."omni.anim.navigation.core".navMesh.viewNavMesh = false
-physics.visualizationDisplayJoints = false # improves performance
-physics.visualizationSimulationOutput = false # improves performance
-physics.resetOnStop = true # Physics state is reset on stop
-renderer.startupMessageDisplayed = true # hides the IOMMU popup window
-resourcemonitor.timeBetweenQueries = 100 # improves performance
-simulation.defaultMetersPerUnit = 1.0 # Meters default
-omni.replicator.captureOnPlay = true
-
-[settings]
-### async rendering settings
-omni.replicator.asyncRendering = false
-app.asyncRendering = false
-app.asyncRenderingLowLatency = false
-
-# disable replicator orchestrator for better runtime perf
-exts."omni.replicator.core".Orchestrator.enabled = false
-
-[settings.app.livestream]
-outDirectory = "${data}"
-
-# Extensions
-###############################
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/106/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
-[settings.app.extensions]
-skipPublishVerification = false
-registryEnabled = true
-
-# Register extension folder from this repo in kit
-[settings.app.exts]
-folders = [
- "${exe-path}/exts", # kit extensions
- "${exe-path}/extscore", # kit core extensions
- "${exe-path}/../exts", # isaac extensions
- "${exe-path}/../extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../extscache", # isaac cache extensions
- "${exe-path}/../extsPhysics", # isaac physics extensions
- "${exe-path}/../isaacsim/exts", # isaac extensions for pip
- "${exe-path}/../isaacsim/extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../isaacsim/extscache", # isaac cache extensions for pip
- "${exe-path}/../isaacsim/extsPhysics", # isaac physics extensions for pip
- "${app}", # needed to find other app files
- "${app}/../../source", # needed to find extensions in Isaac Lab
-]
-
-[settings.physics]
-autoPopupSimulationOutputWindow = false
-updateToUsd = false
-updateVelocitiesToUsd = false
-updateParticlesToUsd = false
-updateVelocitiesToUsd = false
-updateForceSensorsToUsd = false
-outputVelocitiesLocalSpace = false
-useFastCache = false
-visualizationDisplayJoints = false
-fabricUpdateTransformations = false
-fabricUpdateVelocities = false
-fabricUpdateForceSensors = false
-fabricUpdateJointStates = false
-
-# Asset path
-# set the S3 directory manually to the latest published S3
-# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
-[settings]
-persistent.isaac.asset_root.default = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.cloud = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.nvidia = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
diff --git a/apps/isaacsim_4_5/isaaclab.python.rendering.kit b/apps/isaacsim_4_5/isaaclab.python.rendering.kit
deleted file mode 100644
index ad234141fd9..00000000000
--- a/apps/isaacsim_4_5/isaaclab.python.rendering.kit
+++ /dev/null
@@ -1,140 +0,0 @@
-##
-# Adapted from: https://github.com/NVIDIA-Omniverse/OmniIsaacGymEnvs/blob/main/apps/omni.isaac.sim.python.gym.camera.kit
-#
-# This app file designed specifically towards vision-based RL tasks. It provides necessary settings to enable
-# multiple cameras to be rendered each frame. Additional settings are also applied to increase performance when
-# rendering cameras across multiple environments.
-##
-
-[package]
-title = "Isaac Lab Python Camera"
-description = "An app for running Isaac Lab with rendering enabled"
-version = "2.3.2"
-
-# That makes it browsable in UI with "experience" filter
-keywords = ["experience", "app", "isaaclab", "python", "camera", "minimal"]
-
-[dependencies]
-# Isaac Lab minimal app
-"isaaclab.python" = {}
-
-# PhysX
-"omni.kit.property.physx" = {}
-
-# Rendering
-"omni.kit.material.library" = {}
-
-[settings.isaaclab]
-# This is used to check that this experience file is loaded when using cameras
-cameras_enabled = true
-
-[settings]
-# Note: This path was adapted to be respective to the kit-exe file location
-app.versionFile = "${exe-path}/VERSION"
-app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "4.5.0"
-
-# Disable print outs on extension startup information
-# this only disables the app print_and_log function
-app.enableStdoutOutput = false
-
-# set the default ros bridge to disable on startup
-isaac.startup.ros_bridge_extension = ""
-
-# Flags for better rendering performance
-# Disabling these settings reduces renderer VRAM usage and improves rendering performance, but at some quality cost
-rtx.translucency.enabled = false
-rtx.reflections.enabled = false
-rtx.indirectDiffuse.enabled = false
-rtx-transient.dlssg.enabled = false
-rtx.directLighting.sampledLighting.enabled = true
-rtx.directLighting.sampledLighting.samplesPerPixel = 1
-rtx.sceneDb.ambientLightIntensity = 1.0
-# rtx.shadows.enabled = false
-
-# Avoids replicator warning
-rtx.pathtracing.maxSamplesPerLaunch = 1000000
-# Avoids silent trimming of tiles
-rtx.viewTile.limit = 1000000
-
-# Disable present thread to improve performance
-exts."omni.renderer.core".present.enabled=false
-
-# Disabling these settings reduces renderer VRAM usage and improves rendering performance, but at some quality cost
-rtx.raytracing.cached.enabled = false
-rtx.ambientOcclusion.enabled = false
-
-# Set the DLSS model
-rtx.post.dlss.execMode = 0 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
-
-# Avoids unnecessary GPU context initialization
-renderer.multiGpu.maxGpuCount=1
-
-# Force synchronous rendering to improve training results
-omni.replicator.asyncRendering = false
-
-# Avoids frame offset issue
-app.updateOrder.checkForHydraRenderComplete = 1000
-app.renderer.waitIdle=true
-app.hydraEngine.waitIdle=true
-
-app.audio.enabled = false
-
-# disable replicator orchestrator for better runtime perf
-exts."omni.replicator.core".Orchestrator.enabled = false
-
-[settings.physics]
-updateToUsd = false
-updateParticlesToUsd = false
-updateVelocitiesToUsd = false
-updateForceSensorsToUsd = false
-outputVelocitiesLocalSpace = false
-useFastCache = false
-visualizationDisplayJoints = false
-fabricUpdateTransformations = false
-fabricUpdateVelocities = false
-fabricUpdateForceSensors = false
-fabricUpdateJointStates = false
-
-[settings.exts."omni.kit.registry.nucleus"]
-registries = [
- { name = "kit/default", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/106/shared" },
- { name = "kit/sdk", url = "https://ovextensionsprod.blob.core.windows.net/exts/kit/prod/sdk/${kit_version_short}/${kit_git_hash}" },
- { name = "kit/community", url = "https://dw290v42wisod.cloudfront.net/exts/kit/community" },
-]
-
-[settings.app.python]
-# These disable the kit app from also printing out python output, which gets confusing
-interceptSysStdOutput = false
-logSysStdOutput = false
-
-[settings.app.renderer]
-skipWhileMinimized = false
-sleepMsOnFocus = 0
-sleepMsOutOfFocus = 0
-
-# Register extension folder from this repo in kit
-[settings.app.exts]
-folders = [
- "${exe-path}/exts", # kit extensions
- "${exe-path}/extscore", # kit core extensions
- "${exe-path}/../exts", # isaac extensions
- "${exe-path}/../extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../extscache", # isaac cache extensions
- "${exe-path}/../extsPhysics", # isaac physics extensions
- "${exe-path}/../isaacsim/exts", # isaac extensions for pip
- "${exe-path}/../isaacsim/extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../isaacsim/extscache", # isaac cache extensions for pip
- "${exe-path}/../isaacsim/extsPhysics", # isaac physics extensions for pip
- "${app}", # needed to find other app files
- "${app}/../../source", # needed to find extensions in Isaac Lab
-]
-
-# Asset path
-# set the S3 directory manually to the latest published S3
-# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
-[settings]
-persistent.isaac.asset_root.default = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.cloud = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.nvidia = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
diff --git a/apps/isaacsim_4_5/isaaclab.python.xr.openxr.headless.kit b/apps/isaacsim_4_5/isaaclab.python.xr.openxr.headless.kit
deleted file mode 100644
index 82f7e5cd62a..00000000000
--- a/apps/isaacsim_4_5/isaaclab.python.xr.openxr.headless.kit
+++ /dev/null
@@ -1,41 +0,0 @@
-##
-# Adapted from: apps/isaaclab.python.xr.openxr.kit
-##
-
-[package]
-title = "Isaac Lab Python OpenXR Headless"
-description = "An app for running Isaac Lab with OpenXR in headless mode"
-version = "2.3.2"
-
-# That makes it browsable in UI with "experience" filter
-keywords = ["experience", "app", "usd", "headless"]
-
-[settings]
-# Note: This path was adapted to be respective to the kit-exe file location
-app.versionFile = "${exe-path}/VERSION"
-app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "4.5.0"
-
-[dependencies]
-"isaaclab.python.xr.openxr" = {}
-
-[settings]
-xr.profile.ar.enabled = true
-
-# Register extension folder from this repo in kit
-[settings.app.exts]
-folders = [
- "${exe-path}/exts", # kit extensions
- "${exe-path}/extscore", # kit core extensions
- "${exe-path}/../exts", # isaac extensions
- "${exe-path}/../extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../extscache", # isaac cache extensions
- "${exe-path}/../extsPhysics", # isaac physics extensions
- "${exe-path}/../isaacsim/exts", # isaac extensions for pip
- "${exe-path}/../isaacsim/extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../isaacsim/extscache", # isaac cache extensions for pip
- "${exe-path}/../isaacsim/extsPhysics", # isaac physics extensions for pip
- "${app}", # needed to find other app files
- "${app}/../../source", # needed to find extensions in Isaac Lab
-]
diff --git a/apps/isaacsim_4_5/isaaclab.python.xr.openxr.kit b/apps/isaacsim_4_5/isaaclab.python.xr.openxr.kit
deleted file mode 100644
index d27e5c444c2..00000000000
--- a/apps/isaacsim_4_5/isaaclab.python.xr.openxr.kit
+++ /dev/null
@@ -1,71 +0,0 @@
-##
-# Adapted from: _isaac_sim/apps/isaacsim.exp.xr.openxr.kit
-##
-
-[package]
-title = "Isaac Lab Python OpenXR"
-description = "An app for running Isaac Lab with OpenXR"
-version = "2.3.2"
-
-# That makes it browsable in UI with "experience" filter
-keywords = ["experience", "app", "usd"]
-
-[settings]
-# Note: This path was adapted to be respective to the kit-exe file location
-app.versionFile = "${exe-path}/VERSION"
-app.folder = "${exe-path}/"
-app.name = "Isaac-Sim"
-app.version = "4.5.0"
-
-### async rendering settings
-omni.replicator.asyncRendering = true
-app.asyncRendering = true
-app.asyncRenderingLowLatency = true
-
-# For XR, set this back to default "#define OMNI_MAX_DEVICE_GROUP_DEVICE_COUNT 16"
-renderer.multiGpu.maxGpuCount = 16
-renderer.gpuEnumeration.glInterop.enabled = true # Allow Kit XR OpenXR to render headless
-
-[dependencies]
-"isaaclab.python" = {}
-"isaacsim.xr.openxr" = {}
-
-# Kit extensions
-"omni.kit.xr.system.openxr" = {}
-"omni.kit.xr.profile.ar" = {}
-
-[settings]
-app.xr.enabled = true
-
-# xr settings
-xr.ui.enabled = false
-xr.depth.aov = "GBufferDepth"
-defaults.xr.profile.ar.renderQuality = "off"
-defaults.xr.profile.ar.anchorMode = "custom anchor"
-rtx.rendermode = "RaytracedLighting"
-persistent.xr.profile.ar.render.nearPlane = 0.15
-
-# Register extension folder from this repo in kit
-[settings.app.exts]
-folders = [
- "${exe-path}/exts", # kit extensions
- "${exe-path}/extscore", # kit core extensions
- "${exe-path}/../exts", # isaac extensions
- "${exe-path}/../extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../extscache", # isaac cache extensions
- "${exe-path}/../extsPhysics", # isaac physics extensions
- "${exe-path}/../isaacsim/exts", # isaac extensions for pip
- "${exe-path}/../isaacsim/extsDeprecated", # deprecated isaac extensions
- "${exe-path}/../isaacsim/extscache", # isaac cache extensions for pip
- "${exe-path}/../isaacsim/extsPhysics", # isaac physics extensions for pip
- "${app}", # needed to find other app files
- "${app}/../../source", # needed to find extensions in Isaac Lab
-]
-
-# Asset path
-# set the S3 directory manually to the latest published S3
-# note: this is done to ensure prior versions of Isaac Sim still use the latest assets
-[settings]
-persistent.isaac.asset_root.default = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.cloud = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
-persistent.isaac.asset_root.nvidia = "http://omniverse-content-production.s3-us-west-2.amazonaws.com/Assets/Isaac/4.5"
diff --git a/apps/isaacsim_4_5/rendering_modes/balanced.kit b/apps/isaacsim_4_5/rendering_modes/balanced.kit
deleted file mode 100644
index ee92625fd7e..00000000000
--- a/apps/isaacsim_4_5/rendering_modes/balanced.kit
+++ /dev/null
@@ -1,36 +0,0 @@
-rtx.translucency.enabled = false
-
-rtx.reflections.enabled = false
-rtx.reflections.denoiser.enabled = true
-
-# this will be ignored when RR (dldenoiser) is enabled
-# rtx.directLighting.sampledLighting.denoisingTechnique = 0
-rtx.directLighting.sampledLighting.enabled = true
-
-rtx.sceneDb.ambientLightIntensity = 1.0
-
-rtx.shadows.enabled = true
-
-rtx.indirectDiffuse.enabled = false
-rtx.indirectDiffuse.denoiser.enabled = true
-
-# rtx.domeLight.upperLowerStrategy = 3
-
-rtx.ambientOcclusion.enabled = false
-rtx.ambientOcclusion.denoiserMode = 1
-
-rtx.raytracing.subpixel.mode = 0
-rtx.raytracing.cached.enabled = true
-
-# DLSS frame gen does not yet support tiled camera well
-rtx-transient.dlssg.enabled = false
-rtx-transient.dldenoiser.enabled = true
-
-# Set the DLSS model
-rtx.post.dlss.execMode = 1 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
-
-# Avoids replicator warning
-rtx.pathtracing.maxSamplesPerLaunch = 1000000
-
-# Avoids silent trimming of tiles
-rtx.viewTile.limit = 1000000
diff --git a/apps/isaacsim_4_5/rendering_modes/performance.kit b/apps/isaacsim_4_5/rendering_modes/performance.kit
deleted file mode 100644
index 3cfe6e8c0e2..00000000000
--- a/apps/isaacsim_4_5/rendering_modes/performance.kit
+++ /dev/null
@@ -1,35 +0,0 @@
-rtx.translucency.enabled = false
-
-rtx.reflections.enabled = false
-rtx.reflections.denoiser.enabled = false
-
-rtx.directLighting.sampledLighting.denoisingTechnique = 0
-rtx.directLighting.sampledLighting.enabled = false
-
-rtx.sceneDb.ambientLightIntensity = 1.0
-
-rtx.shadows.enabled = true
-
-rtx.indirectDiffuse.enabled = false
-rtx.indirectDiffuse.denoiser.enabled = false
-
-rtx.domeLight.upperLowerStrategy = 3
-
-rtx.ambientOcclusion.enabled = false
-rtx.ambientOcclusion.denoiserMode = 1
-
-rtx.raytracing.subpixel.mode = 0
-rtx.raytracing.cached.enabled = false
-
-# DLSS frame gen does not yet support tiled camera well
-rtx-transient.dlssg.enabled = false
-rtx-transient.dldenoiser.enabled = false
-
-# Set the DLSS model
-rtx.post.dlss.execMode = 0 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
-
-# Avoids replicator warning
-rtx.pathtracing.maxSamplesPerLaunch = 1000000
-
-# Avoids silent trimming of tiles
-rtx.viewTile.limit = 1000000
diff --git a/apps/isaacsim_4_5/rendering_modes/quality.kit b/apps/isaacsim_4_5/rendering_modes/quality.kit
deleted file mode 100644
index 8e966ddfd3b..00000000000
--- a/apps/isaacsim_4_5/rendering_modes/quality.kit
+++ /dev/null
@@ -1,36 +0,0 @@
-rtx.translucency.enabled = true
-
-rtx.reflections.enabled = true
-rtx.reflections.denoiser.enabled = true
-
-# this will be ignored when RR (dldenoiser) is enabled
-# rtx.directLighting.sampledLighting.denoisingTechnique = 0
-rtx.directLighting.sampledLighting.enabled = true
-
-rtx.sceneDb.ambientLightIntensity = 1.0
-
-rtx.shadows.enabled = true
-
-rtx.indirectDiffuse.enabled = true
-rtx.indirectDiffuse.denoiser.enabled = true
-
-# rtx.domeLight.upperLowerStrategy = 4
-
-rtx.ambientOcclusion.enabled = true
-rtx.ambientOcclusion.denoiserMode = 0
-
-rtx.raytracing.subpixel.mode = 1
-rtx.raytracing.cached.enabled = true
-
-# DLSS frame gen does not yet support tiled camera well
-rtx-transient.dlssg.enabled = false
-rtx-transient.dldenoiser.enabled = true
-
-# Set the DLSS model
-rtx.post.dlss.execMode = 2 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
-
-# Avoids replicator warning
-rtx.pathtracing.maxSamplesPerLaunch = 1000000
-
-# Avoids silent trimming of tiles
-rtx.viewTile.limit = 1000000
diff --git a/apps/isaacsim_4_5/rendering_modes/xr.kit b/apps/isaacsim_4_5/rendering_modes/xr.kit
deleted file mode 100644
index 8cfc2c988d7..00000000000
--- a/apps/isaacsim_4_5/rendering_modes/xr.kit
+++ /dev/null
@@ -1,35 +0,0 @@
-rtx.translucency.enabled = true
-
-rtx.reflections.enabled = true
-rtx.reflections.denoiser.enabled = true
-
-rtx.directLighting.sampledLighting.denoisingTechnique = 5
-rtx.directLighting.sampledLighting.enabled = true
-
-rtx.sceneDb.ambientLightIntensity = 1.0
-
-rtx.shadows.enabled = true
-
-rtx.indirectDiffuse.enabled = true
-rtx.indirectDiffuse.denoiser.enabled = true
-
-rtx.domeLight.upperLowerStrategy = 4
-
-rtx.ambientOcclusion.enabled = true
-rtx.ambientOcclusion.denoiserMode = 0
-
-rtx.raytracing.subpixel.mode = 1
-rtx.raytracing.cached.enabled = true
-
-# DLSS frame gen does not yet support tiled camera well
-rtx-transient.dlssg.enabled = false
-rtx-transient.dldenoiser.enabled = true
-
-# Set the DLSS model
-rtx.post.dlss.execMode = 2 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
-
-# Avoids replicator warning
-rtx.pathtracing.maxSamplesPerLaunch = 1000000
-
-# Avoids silent trimming of tiles
-rtx.viewTile.limit = 1000000
diff --git a/apps/rendering_modes/balanced.kit b/apps/rendering_modes/balanced.kit
index ee92625fd7e..be2b03c0323 100644
--- a/apps/rendering_modes/balanced.kit
+++ b/apps/rendering_modes/balanced.kit
@@ -1,19 +1,31 @@
-rtx.translucency.enabled = false
-
-rtx.reflections.enabled = false
-rtx.reflections.denoiser.enabled = true
-
-# this will be ignored when RR (dldenoiser) is enabled
-# rtx.directLighting.sampledLighting.denoisingTechnique = 0
-rtx.directLighting.sampledLighting.enabled = true
+### THESE ARE RT1 SETTINGS ONLY ###
+# rtx.translucency.enabled = false
+# rtx.reflections.enabled = false
+# rtx.reflections.denoiser.enabled = true
+## this will be ignored when RR (dldenoiser) is enabled
+## rtx.directLighting.sampledLighting.denoisingTechnique = 0
+# rtx.directLighting.sampledLighting.enabled = true
+# rtx.indirectDiffuse.enabled = false
+# rtx.indirectDiffuse.denoiser.enabled = true
+##############################################
+
+### THESE ARE RT2 SETTINGS TO MATCH ABOVE PERFORMANCE SETTINGS ###
+# these are needed if indirectDiffuse = false (this means GI false) - maxBounces needs to be 2
+rtx.rtpt.cached.enabled = false
+rtx.rtpt.lightcache.cached.enabled = false
+rtx.rtpt.translucency.virtualMotion.enabled = false
+rtx.rtpt.maxBounces = 2
+rtx.rtpt.splitGlass = false
+rtx.rtpt.splitClearcoat = false
+rtx.rtpt.splitRoughReflection = true
+# this gives slightly brighter image
+rtx.rtpt.useAmbientOcclusionForAmbientLight = false
+##############################################
rtx.sceneDb.ambientLightIntensity = 1.0
rtx.shadows.enabled = true
-rtx.indirectDiffuse.enabled = false
-rtx.indirectDiffuse.denoiser.enabled = true
-
# rtx.domeLight.upperLowerStrategy = 3
rtx.ambientOcclusion.enabled = false
@@ -24,6 +36,7 @@ rtx.raytracing.cached.enabled = true
# DLSS frame gen does not yet support tiled camera well
rtx-transient.dlssg.enabled = false
+
rtx-transient.dldenoiser.enabled = true
# Set the DLSS model
diff --git a/apps/rendering_modes/performance.kit b/apps/rendering_modes/performance.kit
index 3cfe6e8c0e2..f991bd372bd 100644
--- a/apps/rendering_modes/performance.kit
+++ b/apps/rendering_modes/performance.kit
@@ -1,18 +1,30 @@
-rtx.translucency.enabled = false
-
-rtx.reflections.enabled = false
-rtx.reflections.denoiser.enabled = false
-
-rtx.directLighting.sampledLighting.denoisingTechnique = 0
-rtx.directLighting.sampledLighting.enabled = false
+### THESE ARE RT1 SETTINGS ONLY ###
+# rtx.translucency.enabled = false
+# rtx.reflections.enabled = false
+# rtx.reflections.denoiser.enabled = false
+# rtx.directLighting.sampledLighting.denoisingTechnique = 0
+# rtx.directLighting.sampledLighting.enabled = false
+# rtx.indirectDiffuse.enabled = false
+# rtx.indirectDiffuse.denoiser.enabled = false
+##############################################
+
+### THESE ARE RT2 SETTINGS TO MATCH ABOVE PERFORMANCE SETTINGS ###
+# these are needed if indirectDiffuse = false (this means GI false) - maxBounces needs to be 2
+rtx.rtpt.cached.enabled = false
+rtx.rtpt.lightcache.cached.enabled = false
+rtx.rtpt.translucency.virtualMotion.enabled = false
+rtx.rtpt.maxBounces = 2
+rtx.rtpt.splitGlass = false
+rtx.rtpt.splitClearcoat = false
+rtx.rtpt.splitRoughReflection = true
+# this gives slightly brighter image
+rtx.rtpt.useAmbientOcclusionForAmbientLight = false
+##############################################
rtx.sceneDb.ambientLightIntensity = 1.0
rtx.shadows.enabled = true
-rtx.indirectDiffuse.enabled = false
-rtx.indirectDiffuse.denoiser.enabled = false
-
rtx.domeLight.upperLowerStrategy = 3
rtx.ambientOcclusion.enabled = false
@@ -23,6 +35,7 @@ rtx.raytracing.cached.enabled = false
# DLSS frame gen does not yet support tiled camera well
rtx-transient.dlssg.enabled = false
+
rtx-transient.dldenoiser.enabled = false
# Set the DLSS model
diff --git a/apps/rendering_modes/quality.kit b/apps/rendering_modes/quality.kit
index 8e966ddfd3b..56073b84c67 100644
--- a/apps/rendering_modes/quality.kit
+++ b/apps/rendering_modes/quality.kit
@@ -1,19 +1,34 @@
-rtx.translucency.enabled = true
-
-rtx.reflections.enabled = true
-rtx.reflections.denoiser.enabled = true
-
-# this will be ignored when RR (dldenoiser) is enabled
-# rtx.directLighting.sampledLighting.denoisingTechnique = 0
-rtx.directLighting.sampledLighting.enabled = true
+### THESE ARE RT1 SETTINGS ONLY ###
+# rtx.translucency.enabled = true
+# rtx.reflections.enabled = true
+# rtx.reflections.denoiser.enabled = true
+## this will be ignored when RR (dldenoiser) is enabled
+## rtx.directLighting.sampledLighting.denoisingTechnique = 0
+# rtx.directLighting.sampledLighting.enabled = true
+# rtx.indirectDiffuse.enabled = true
+# rtx.indirectDiffuse.denoiser.enabled = true
+##############################################
+
+### THESE ARE RT2 SETTINGS ###
+# maxBounces should be 3 if indirectDiffuse was true
+rtx.rtpt.maxBounces = 3
+rtx.rtpt.cached.enabled = false
+rtx.rtpt.lightcache.cached.enabled = false
+rtx.rtpt.translucency.virtualMotion.enabled = false
+rtx.rtpt.splitRoughReflection = true
+# these are even more costly, we should only set them to true if noise is observed
+# rtx.rtpt.splitGlass = true
+# rtx.rtpt.splitClearcoat = true
+
+# Improved adaptive sampling for disocclusion (reduces ghosting/temporal artifacts)
+rtx.rtpt.adaptiveSampling.disocclusion.enabled = true
+rtx.rtpt.adaptiveSampling.disocclusion.spp = 4
+##############################################
rtx.sceneDb.ambientLightIntensity = 1.0
rtx.shadows.enabled = true
-rtx.indirectDiffuse.enabled = true
-rtx.indirectDiffuse.denoiser.enabled = true
-
# rtx.domeLight.upperLowerStrategy = 4
rtx.ambientOcclusion.enabled = true
@@ -24,7 +39,9 @@ rtx.raytracing.cached.enabled = true
# DLSS frame gen does not yet support tiled camera well
rtx-transient.dlssg.enabled = false
-rtx-transient.dldenoiser.enabled = true
+
+# RT2 only supports DLSS-RR
+# rtx-transient.dldenoiser.enabled = true
# Set the DLSS model
rtx.post.dlss.execMode = 2 # can be 0 (Performance), 1 (Balanced), 2 (Quality), or 3 (Auto)
diff --git a/docker/.env.base b/docker/.env.base
index be1dd4f6221..c2b7bbc14c6 100644
--- a/docker/.env.base
+++ b/docker/.env.base
@@ -6,8 +6,9 @@
ACCEPT_EULA=Y
# NVIDIA Isaac Sim base image
ISAACSIM_BASE_IMAGE=nvcr.io/nvidia/isaac-sim
-# NVIDIA Isaac Sim version to use (e.g. 5.1.0)
-ISAACSIM_VERSION=5.1.0
+# NVIDIA Isaac Sim version to use (e.g. 6.0.0-dev2)
+# TODO(AntoineRichard): Revert to stable 6.0.0 tag once it ships on NGC
+ISAACSIM_VERSION=6.0.0-dev2
# Derived from the default path in the NVIDIA provided Isaac Sim container
DOCKER_ISAACSIM_ROOT_PATH=/isaac-sim
# The Isaac Lab path in the container
diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base
index 9aff6b165c9..f13d7918c9a 100644
--- a/docker/Dockerfile.base
+++ b/docker/Dockerfile.base
@@ -36,20 +36,32 @@ ENV DEBIAN_FRONTEND=noninteractive
USER root
-# Install dependencies and remove cache
-RUN --mount=type=cache,target=/var/cache/apt \
- apt-get update && apt-get install -y --no-install-recommends \
+# Install dependencies
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
build-essential \
- cmake \
- git \
libglib2.0-0 \
ncurses-term \
- wget && \
- apt -y autoremove && apt clean autoclean && \
- rm -rf /var/lib/apt/lists/*
+ cmake \
+ git \
+ wget
+
+# Install packages needed to build imgui-bundle on arm64 as no prebuilt pip wheel is provided
+RUN if [ "$(dpkg --print-architecture)" = "arm64" ]; then \
+ apt-get update && \
+ apt-get install -y --no-install-recommends \
+ libgl1-mesa-dev libopengl-dev libglx-dev \
+ libx11-dev libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev; \
+ fi
-# Copy the Isaac Lab directory (files to exclude are defined in .dockerignore)
-COPY ../ ${ISAACLAB_PATH}
+# copy files necessary for installing Isaac Lab and its dependencies
+# this way we minimize the chance of cache invalidation on file edits
+COPY ../isaaclab.* ../environment.yml ../pyproject.toml ${ISAACLAB_PATH}/
+COPY ../tools/ ${ISAACLAB_PATH}/tools/
+COPY ../source/ ${ISAACLAB_PATH}/source/
+
+# Fix the line endings for the shell scripts (Windows git may add \r)
+RUN find ${ISAACLAB_PATH} -type f -name "*.sh" -exec sed -i 's/\r$//' {} +
# Ensure isaaclab.sh has execute permissions
RUN chmod +x ${ISAACLAB_PATH}/isaaclab.sh
@@ -60,10 +72,9 @@ RUN ln -sf ${ISAACSIM_ROOT_PATH} ${ISAACLAB_PATH}/_isaac_sim
# Install toml dependency
RUN ${ISAACLAB_PATH}/isaaclab.sh -p -m pip install toml
-# Install apt dependencies for extensions that declare them in their extension.toml
-RUN --mount=type=cache,target=/var/cache/apt \
- ${ISAACLAB_PATH}/isaaclab.sh -p ${ISAACLAB_PATH}/tools/install_deps.py apt ${ISAACLAB_PATH}/source && \
- apt -y autoremove && apt clean autoclean && \
+# Install apt dependencies for extensions that declare them in their extension.toml,
+RUN ${ISAACLAB_PATH}/isaaclab.sh -p ${ISAACLAB_PATH}/tools/install_deps.py apt ${ISAACLAB_PATH}/source && \
+ apt-get -y autoremove && apt-get clean && \
rm -rf /var/lib/apt/lists/*
# for singularity usage, have to create the directories that will binded
@@ -106,6 +117,9 @@ RUN echo "export ISAACLAB_PATH=${ISAACLAB_PATH}" >> ${HOME}/.bashrc && \
echo "shopt -s histappend" >> /root/.bashrc && \
echo "PROMPT_COMMAND='history -a'" >> /root/.bashrc
+# copy the rest of the files
+COPY ../ ${ISAACLAB_PATH}/
+
# make working directory as the Isaac Lab directory
# this is the default directory when the container is run
WORKDIR ${ISAACLAB_PATH}
diff --git a/docker/Dockerfile.curobo b/docker/Dockerfile.curobo
index 0830adebf18..36072612f57 100644
--- a/docker/Dockerfile.curobo
+++ b/docker/Dockerfile.curobo
@@ -36,17 +36,23 @@ ENV DEBIAN_FRONTEND=noninteractive
USER root
-# Install dependencies and remove cache
-RUN --mount=type=cache,target=/var/cache/apt \
- apt-get update && apt-get install -y --no-install-recommends \
+# Install dependencies
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
build-essential \
- cmake \
- git \
libglib2.0-0 \
ncurses-term \
- wget && \
- apt -y autoremove && apt clean autoclean && \
- rm -rf /var/lib/apt/lists/*
+ cmake \
+ git \
+ wget
+
+# Install packages needed to build imgui-bundle on arm64 as no prebuilt pip wheel is provided
+RUN if [ "$(dpkg --print-architecture)" = "arm64" ]; then \
+ apt-get update && \
+ apt-get install -y --no-install-recommends \
+ libgl1-mesa-dev libopengl-dev libglx-dev \
+ libx11-dev libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev; \
+ fi
# Detect Ubuntu version and install CUDA 12.8 via NVIDIA network repo (cuda-keyring)
RUN set -euo pipefail && \
@@ -83,8 +89,14 @@ ENV PATH=${CUDA_HOME}/bin:${PATH}
ENV LD_LIBRARY_PATH=${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}
ENV TORCH_CUDA_ARCH_LIST=8.0+PTX
-# Copy the Isaac Lab directory (files to exclude are defined in .dockerignore)
-COPY ../ ${ISAACLAB_PATH}
+# copy files necessary for installing Isaac Lab and its dependencies
+# this way we minimize the chance of cache invalidation on file edits
+COPY ../isaaclab.* ../environment.yml ../pyproject.toml ${ISAACLAB_PATH}/
+COPY ../tools/ ${ISAACLAB_PATH}/tools/
+COPY ../source/ ${ISAACLAB_PATH}/source/
+
+# Fix the line endings for the shell scripts (Windows git may add \r)
+RUN find ${ISAACLAB_PATH} -type f -name "*.sh" -exec sed -i 's/\r$//' {} +
# Ensure isaaclab.sh has execute permissions
RUN chmod +x ${ISAACLAB_PATH}/isaaclab.sh
@@ -95,10 +107,9 @@ RUN ln -sf ${ISAACSIM_ROOT_PATH} ${ISAACLAB_PATH}/_isaac_sim
# Install toml dependency
RUN ${ISAACLAB_PATH}/isaaclab.sh -p -m pip install toml
-# Install apt dependencies for extensions that declare them in their extension.toml
-RUN --mount=type=cache,target=/var/cache/apt \
- ${ISAACLAB_PATH}/isaaclab.sh -p ${ISAACLAB_PATH}/tools/install_deps.py apt ${ISAACLAB_PATH}/source && \
- apt -y autoremove && apt clean autoclean && \
+# Install apt dependencies for extensions that declare them in their extension.toml,
+RUN ${ISAACLAB_PATH}/isaaclab.sh -p ${ISAACLAB_PATH}/tools/install_deps.py apt ${ISAACLAB_PATH}/source && \
+ apt-get -y autoremove && apt-get clean && \
rm -rf /var/lib/apt/lists/*
# for singularity usage, have to create the directories that will binded
@@ -126,6 +137,14 @@ RUN touch /bin/nvidia-smi && \
# rather than skipping because it detects the pre-bundled version.
RUN rm -rf ${ISAACSIM_ROOT_PATH}/exts/omni.isaac.ml_archive/pip_prebundle/torch*
+# HACK: Reinstall pip properly after removing prebundled packages
+# The removal of torch* corrupts pip's vendor packages (_structures.py is deleted).
+# We must completely remove pip first, then do a clean install.
+RUN rm -rf ${ISAACSIM_ROOT_PATH}/kit/python/lib/python3.12/site-packages/pip* && \
+ wget -q https://bootstrap.pypa.io/get-pip.py && \
+ ${ISAACLAB_PATH}/_isaac_sim/kit/python/bin/python3 get-pip.py && \
+ rm get-pip.py
+
# installing Isaac Lab dependencies
# use pip caching to avoid reinstalling large packages
RUN --mount=type=cache,target=${DOCKER_USER_HOME}/.cache/pip \
@@ -138,6 +157,9 @@ RUN ${ISAACLAB_PATH}/isaaclab.sh -p -m pip uninstall -y quadprog
RUN ${ISAACLAB_PATH}/isaaclab.sh -p -m pip install --no-build-isolation \
"nvidia-curobo @ git+https://github.com/NVlabs/curobo.git@ebb71702f3f70e767f40fd8e050674af0288abe8"
+# Install isaaclab_teleop (needed by Pink IK tests and related env configs)
+RUN ${ISAACLAB_PATH}/isaaclab.sh -p -m pip install --editable ${ISAACLAB_PATH}/source/isaaclab_teleop
+
# aliasing isaaclab.sh and python for convenience
RUN echo "export ISAACLAB_PATH=${ISAACLAB_PATH}" >> ${HOME}/.bashrc && \
echo "alias isaaclab=${ISAACLAB_PATH}/isaaclab.sh" >> ${HOME}/.bashrc && \
@@ -150,6 +172,9 @@ RUN echo "export ISAACLAB_PATH=${ISAACLAB_PATH}" >> ${HOME}/.bashrc && \
echo "shopt -s histappend" >> /root/.bashrc && \
echo "PROMPT_COMMAND='history -a'" >> /root/.bashrc
+# copy the rest of the files
+COPY ../ ${ISAACLAB_PATH}/
+
# make working directory as the Isaac Lab directory
# this is the default directory when the container is run
WORKDIR ${ISAACLAB_PATH}
diff --git a/docker/Dockerfile.installci b/docker/Dockerfile.installci
new file mode 100644
index 00000000000..30da2b55b82
--- /dev/null
+++ b/docker/Dockerfile.installci
@@ -0,0 +1,67 @@
+# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Minimal container for testing Isaac Lab installation scenarios.
+#
+# Usage:
+# docker build --build-arg BASE_IMAGE=ubuntu:24.04 -t isaaclab-install-ci .
+# docker run --rm isaaclab-install-ci -v -k "test_pip"
+
+ARG BASE_IMAGE=ubuntu:24.04
+FROM ${BASE_IMAGE}
+
+SHELL ["/bin/bash", "-c"]
+
+LABEL description="Container for installation CI tests."
+
+ENV LANG=C.UTF-8
+ENV DEBIAN_FRONTEND=noninteractive
+ENV PYTHONDONTWRITEBYTECODE=1
+ENV PYTHONUNBUFFERED=1
+
+# Install system dependencies needed for building Py packages
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ git \
+ curl \
+ cmake \
+ python3 \
+ python3-dev \
+ python3-pip \
+ libglib2.0-0 \
+ python3-venv \
+ build-essential \
+ && rm -rf /var/lib/apt/lists/*
+
+# Make python3 the default python
+RUN ln -sf /usr/bin/python3 /usr/bin/python
+
+# Install test runner dependencies
+RUN pip install --break-system-packages \
+ pytest>=8.0 \
+ pytest-timeout>=2.0
+
+# Install uv
+RUN curl -LsSf https://astral.sh/uv/install.sh | sh
+ENV PATH="/root/.local/bin:${PATH}"
+
+# Copy the repo
+ARG ISAACLAB_PATH=/workspace/isaaclab
+ENV ISAACLAB_PATH=${ISAACLAB_PATH}
+COPY . ${ISAACLAB_PATH}
+
+# Fix line endings in .sh files (Win git may add \r)
+# This hack need to be in the main Dockerfiles too
+RUN find ${ISAACLAB_PATH} -type f -name "*.sh" -exec sed -i 's/\r$//' {} +
+RUN chmod +x ${ISAACLAB_PATH}/isaaclab.sh
+
+WORKDIR ${ISAACLAB_PATH}
+
+# isaaclab.x debug mode
+ENV DEBUG=1
+
+# Run all installation CI tests by default
+ENTRYPOINT ["python", "-m", "pytest", "-c", "source/isaaclab/test/install_ci/pytest.ini", "source/isaaclab/test/install_ci"]
+CMD ["-v", "--tb=short"]
diff --git a/docs/conf.py b/docs/conf.py
index 248e14c3f89..510fa3bc928 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -24,12 +24,22 @@
sys.path.insert(0, os.path.abspath("../source/isaaclab_assets/isaaclab_assets"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_tasks"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_tasks/isaaclab_tasks"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_physx"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_physx/isaaclab_physx"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_newton"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_newton/isaaclab_newton"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_rl"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_rl/isaaclab_rl"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_mimic"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_mimic/isaaclab_mimic"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_contrib"))
sys.path.insert(0, os.path.abspath("../source/isaaclab_contrib/isaaclab_contrib"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_teleop"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_teleop/isaaclab_teleop"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_ov"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_ov/isaaclab_ov"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_visualizers"))
+sys.path.insert(0, os.path.abspath("../source/isaaclab_visualizers/isaaclab_visualizers"))
# -- Project information -----------------------------------------------------
@@ -127,7 +137,7 @@
"numpy": ("https://numpy.org/doc/stable/", None),
"trimesh": ("https://trimesh.org/", None),
"torch": ("https://docs.pytorch.org/docs/stable/", None),
- "isaacsim": ("https://docs.isaacsim.omniverse.nvidia.com/5.1.0/py/", None),
+ "isaacsim": ("https://docs.isaacsim.omniverse.nvidia.com/6.0.0/py/", None),
"gymnasium": ("https://gymnasium.farama.org/", None),
"warp": ("https://nvidia.github.io/warp/", None),
"omniverse": ("https://docs.omniverse.nvidia.com/dev-guide/latest", None),
@@ -139,7 +149,7 @@
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ["_build", "_redirect", "_templates", "Thumbs.db", ".DS_Store", "README.md", "licenses/*"]
+exclude_patterns = ["_build", "_redirect", "_templates", "Thumbs.db", ".DS_Store", "README.md", "licenses/*", "plans"]
# Mock out modules that are not available on RTD
autodoc_mock_imports = [
@@ -176,6 +186,7 @@
"omni.timeline",
"omni.ui",
"gym",
+ "gymnasium",
"skrl",
"stable_baselines3",
"rsl_rl",
@@ -197,6 +208,12 @@
"imageio",
"ipywidgets",
"mpl_toolkits",
+ "isaacteleop",
+ "scipy",
+ "hydra",
+ "hydra.core",
+ "hydra.core.config_store",
+ "omegaconf",
]
# List of zero or more Sphinx-specific warning categories to be squelched (i.e.,
@@ -267,7 +284,7 @@
{
"name": "Isaac Sim",
"url": "https://developer.nvidia.com/isaac-sim",
- "icon": "https://img.shields.io/badge/IsaacSim-5.1.0-silver.svg",
+ "icon": "https://img.shields.io/badge/IsaacSim-6.0.0-silver.svg",
"type": "url",
},
{
@@ -287,9 +304,11 @@
# Whitelist pattern for remotes
smv_remote_whitelist = r"^.*$"
# Whitelist pattern for branches (set to None to ignore all branches)
-smv_branch_whitelist = os.getenv("SMV_BRANCH_WHITELIST", r"^(main|devel|release/.*)$")
-# Whitelist pattern for tags (set to None to ignore all tags)
-smv_tag_whitelist = os.getenv("SMV_TAG_WHITELIST", r"^v[1-9]\d*\.\d+\.\d+$")
+smv_branch_whitelist = os.getenv("SMV_BRANCH_WHITELIST", r"^(main|develop|release/.*)$")
+# Whitelist pattern for tags (set to None to ignore all tags).
+# Matches vMAJOR.MINOR.PATCH with an optional pre-release suffix like -beta or -rc1,
+# so tags like v3.0.0-beta show up in the version selector.
+smv_tag_whitelist = os.getenv("SMV_TAG_WHITELIST", r"^v[1-9]\d*\.\d+\.\d+(-[A-Za-z0-9.]+)?$")
html_sidebars = {
"**": ["navbar-logo.html", "versioning.html", "icon-links.html", "search-field.html", "sbt-sidebar-nav.html"]
}
diff --git a/docs/index.rst b/docs/index.rst
index 97b5f851e08..6c8e6ba9ac4 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -6,9 +6,9 @@ Welcome to Isaac Lab!
:alt: H1 Humanoid example using Isaac Lab
**Isaac Lab** is a unified and modular framework for robot learning that aims to simplify common workflows
-in robotics research (such as reinforcement learning, learning from demonstrations, and motion planning). It is built on
-`NVIDIA Isaac Sim`_ to leverage the latest simulation capabilities for photo-realistic scenes, and fast
-and efficient simulation.
+in robotics research (such as reinforcement learning, learning from demonstrations, and motion planning). It supports
+`NVIDIA Isaac Sim`_ for photo-realistic scenes and RTX rendering, and can also run standalone with the Newton physics backend
+for fast and efficient simulation without requiring a full Isaac Sim installation.
The core objectives of the framework are:
@@ -17,9 +17,15 @@ The core objectives of the framework are:
- **Openness**: Remain open-sourced to allow the community to contribute and extend the framework.
- **Batteries-included**: Include a number of environments, sensors, and tasks that are ready to use.
-Key features available in Isaac Lab include fast and accurate physics simulation provided by PhysX,
-tiled rendering APIs for vectorized rendering, domain randomization for improving robustness and adaptability,
-and support for running in the cloud.
+Key features available in Isaac Lab include fast and accurate physics simulation powered by both the
+**PhysX** and **Newton** backends, tiled rendering APIs for vectorized rendering with support for both
+**RTX** and **Newton** camera sensors, domain randomization for improving robustness and
+adaptability, and support for running in the cloud.
+
+.. note::
+
+ **Upgrading from Isaac Lab 2.x?** See the :ref:`migrating-to-isaaclab-3-0` guide for a full list
+ of breaking changes and the new multi-backend architecture introduced in Isaac Lab 3.0.
Additionally, Isaac Lab provides a variety of environments, and we are actively working on adding more environments
to the list. These include classic control tasks, fixed-arm and dexterous manipulation tasks, legged locomotion tasks,
@@ -46,7 +52,7 @@ For more information about the framework, please refer to the `technical report
License
-=======
+========
The Isaac Lab framework is open-sourced under the BSD-3-Clause license,
with certain parts under Apache-2.0 license. Please refer to :ref:`license` for more details.
@@ -94,11 +100,13 @@ Table of Contents
:titlesonly:
source/setup/quickstart
+ source/setup/quick_installation
source/overview/own-project/index
source/setup/walkthrough/index
source/tutorials/index
source/how-to/index
source/overview/developer-guide/index
+ source/testing/index
.. toctree::
@@ -119,12 +127,14 @@ Table of Contents
:maxdepth: 2
:caption: Features
+ source/features/isaac_teleop
source/features/hydra
source/features/multi_gpu
source/features/population_based_training
Tiled Rendering
source/features/ray
source/features/reproducibility
+ source/features/visualization
.. toctree::
@@ -139,7 +149,6 @@ Table of Contents
:caption: Resources
:titlesonly:
- source/setup/installation/cloud_installation
source/policy_deployment/index
.. toctree::
@@ -147,6 +156,8 @@ Table of Contents
:caption: Migration Guides
:titlesonly:
+ source/migration/migrating_to_isaaclab_3-0
+ source/migration/migrating_deformables
source/migration/migrating_from_isaacgymenvs
source/migration/migrating_from_omniisaacgymenvs
source/migration/migrating_from_orbit
@@ -179,6 +190,7 @@ Table of Contents
GitHub
NVIDIA Isaac Sim
NVIDIA PhysX
+ NVIDIA Newton
Indices and tables
==================
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 13b2bfe9d69..392951b0a8e 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,5 +1,6 @@
# for building the docs
-sphinx-book-theme==1.0.1
+sphinx>=7.0,<9
+sphinx-book-theme>=1.1
myst-parser
sphinxcontrib-bibtex==2.5.0
autodocsumm
@@ -14,5 +15,6 @@ sphinx-multiversion==0.2.4
numpy
matplotlib
warp-lang
+lazy_loader>=0.4
# learning
gymnasium
diff --git a/docs/source/_static/mimic/franka_datagen.jpg b/docs/source/_static/mimic/franka_datagen.jpg
new file mode 100644
index 00000000000..fa0a0c8203f
Binary files /dev/null and b/docs/source/_static/mimic/franka_datagen.jpg differ
diff --git a/docs/source/_static/mimic/franka_mimic_imitation_learning.jpg b/docs/source/_static/mimic/franka_mimic_imitation_learning.jpg
new file mode 100644
index 00000000000..3653f9b5e32
Binary files /dev/null and b/docs/source/_static/mimic/franka_mimic_imitation_learning.jpg differ
diff --git a/docs/source/_static/policy_deployment/04_reach/reach_train.png b/docs/source/_static/policy_deployment/04_reach/reach_train.png
new file mode 100644
index 00000000000..850c733729a
Binary files /dev/null and b/docs/source/_static/policy_deployment/04_reach/reach_train.png differ
diff --git a/docs/source/_static/setup/cloudxr_accept_cert.jpg b/docs/source/_static/setup/cloudxr_accept_cert.jpg
new file mode 100644
index 00000000000..4ffbe35f830
Binary files /dev/null and b/docs/source/_static/setup/cloudxr_accept_cert.jpg differ
diff --git a/docs/source/_static/setup/cloudxr_accept_cert_accepted.jpg b/docs/source/_static/setup/cloudxr_accept_cert_accepted.jpg
new file mode 100644
index 00000000000..837fa3255f9
Binary files /dev/null and b/docs/source/_static/setup/cloudxr_accept_cert_accepted.jpg differ
diff --git a/docs/source/_static/setup/cloudxr_accept_cert_not_private.jpg b/docs/source/_static/setup/cloudxr_accept_cert_not_private.jpg
new file mode 100644
index 00000000000..13493dcea25
Binary files /dev/null and b/docs/source/_static/setup/cloudxr_accept_cert_not_private.jpg differ
diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst
index 92eec5ed6f3..cea73de6802 100644
--- a/docs/source/api/index.rst
+++ b/docs/source/api/index.rst
@@ -16,16 +16,20 @@ The following modules are available in the ``isaaclab`` extension:
app
actuators
assets
+ cloner
controllers
devices
envs
managers
markers
+ physics
+ renderers
scene
sensors
sim
terrains
utils
+ visualizers
.. toctree::
:hidden:
@@ -79,6 +83,7 @@ The following modules are available in the ``isaaclab_contrib`` extension:
actuators
assets
mdp
+ rl
sensors
isaaclab_tasks extension
@@ -95,3 +100,132 @@ It includes the following modules:
:toctree: lab_tasks
utils
+
+isaaclab_teleop extension
+-------------------------
+
+The following modules are available in the ``isaaclab_teleop`` extension:
+
+.. currentmodule:: isaaclab_teleop
+
+.. toctree::
+ :maxdepth: 2
+
+ lab_teleop/isaaclab_teleop
+
+isaaclab_physx extension
+------------------------
+
+The following modules are available in the ``isaaclab_physx`` extension:
+
+.. currentmodule:: isaaclab_physx
+
+.. autosummary::
+ :toctree: lab_physx
+
+ assets
+ cloner
+ physics
+ renderers
+ scene_data_providers
+ sensors
+ sim.schemas
+ sim.spawners
+
+.. toctree::
+ :hidden:
+
+ lab_physx/isaaclab_physx.assets
+ lab_physx/isaaclab_physx.cloner
+ lab_physx/isaaclab_physx.physics
+ lab_physx/isaaclab_physx.renderers
+ lab_physx/isaaclab_physx.scene_data_providers
+ lab_physx/isaaclab_physx.sensors
+ lab_physx/isaaclab_physx.sim.schemas
+ lab_physx/isaaclab_physx.sim.spawners
+
+isaaclab_newton extension
+-------------------------
+
+The following modules are available in the ``isaaclab_newton`` extension:
+
+.. currentmodule:: isaaclab_newton
+
+.. autosummary::
+ :toctree: lab_newton
+
+ assets
+ cloner
+ physics
+ renderers
+ scene_data_providers
+ sensors
+
+.. toctree::
+ :hidden:
+
+ lab_newton/isaaclab_newton.assets
+ lab_newton/isaaclab_newton.cloner
+ lab_newton/isaaclab_newton.physics
+ lab_newton/isaaclab_newton.renderers
+ lab_newton/isaaclab_newton.scene_data_providers
+ lab_newton/isaaclab_newton.sensors
+
+isaaclab_ov extension
+---------------------
+
+The following modules are available in the ``isaaclab_ov`` extension:
+
+.. currentmodule:: isaaclab_ov
+
+.. autosummary::
+ :toctree: lab_ov
+
+ renderers
+
+.. toctree::
+ :hidden:
+
+ lab_ov/isaaclab_ov.renderers
+
+isaaclab_assets extension
+-------------------------
+
+The following modules are available in the ``isaaclab_assets`` extension:
+
+.. currentmodule:: isaaclab_assets
+
+.. autosummary::
+ :toctree: lab_assets
+
+ robots
+ sensors
+
+.. toctree::
+ :hidden:
+
+ lab_assets/isaaclab_assets.robots
+ lab_assets/isaaclab_assets.sensors
+
+isaaclab_visualizers extension
+------------------------------
+
+The following modules are available in the ``isaaclab_visualizers`` extension:
+
+.. currentmodule:: isaaclab_visualizers
+
+.. autosummary::
+ :toctree: lab_visualizers
+
+ kit
+ newton
+ rerun
+ viser
+
+.. toctree::
+ :hidden:
+
+ lab_visualizers/isaaclab_visualizers.kit
+ lab_visualizers/isaaclab_visualizers.newton
+ lab_visualizers/isaaclab_visualizers.rerun
+ lab_visualizers/isaaclab_visualizers.viser
diff --git a/docs/source/api/lab/isaaclab.app.rst b/docs/source/api/lab/isaaclab.app.rst
index b170fa8fa8f..c1440dd631a 100644
--- a/docs/source/api/lab/isaaclab.app.rst
+++ b/docs/source/api/lab/isaaclab.app.rst
@@ -111,5 +111,5 @@ Simulation App Launcher
:members:
-.. _livestream: https://docs.omniverse.nvidia.com/app_isaacsim/app_isaacsim/manual_livestream_clients.html
+.. _livestream: https://docs.isaacsim.omniverse.nvidia.com/latest/installation/manual_livestream_clients.html
.. _`WebRTC Livestream`: https://docs.isaacsim.omniverse.nvidia.com/latest/installation/manual_livestream_clients.html#isaac-sim-short-webrtc-streaming-client
diff --git a/docs/source/api/lab/isaaclab.assets.rst b/docs/source/api/lab/isaaclab.assets.rst
index c91066966e8..28356330b60 100644
--- a/docs/source/api/lab/isaaclab.assets.rst
+++ b/docs/source/api/lab/isaaclab.assets.rst
@@ -18,9 +18,6 @@
Articulation
ArticulationData
ArticulationCfg
- DeformableObject
- DeformableObjectData
- DeformableObjectCfg
.. currentmodule:: isaaclab.assets
@@ -93,23 +90,3 @@ Articulation
:inherited-members:
:show-inheritance:
:exclude-members: __init__, class_type
-
-Deformable Object
------------------
-
-.. autoclass:: DeformableObject
- :members:
- :inherited-members:
- :show-inheritance:
-
-.. autoclass:: DeformableObjectData
- :members:
- :inherited-members:
- :show-inheritance:
- :exclude-members: __init__
-
-.. autoclass:: DeformableObjectCfg
- :members:
- :inherited-members:
- :show-inheritance:
- :exclude-members: __init__, class_type
diff --git a/docs/source/api/lab/isaaclab.cloner.rst b/docs/source/api/lab/isaaclab.cloner.rst
new file mode 100644
index 00000000000..66cf2bedf58
--- /dev/null
+++ b/docs/source/api/lab/isaaclab.cloner.rst
@@ -0,0 +1,4 @@
+isaaclab.cloner
+===============
+
+.. automodule:: isaaclab.cloner
diff --git a/docs/source/api/lab/isaaclab.devices.rst b/docs/source/api/lab/isaaclab.devices.rst
index 5f04c4733cf..9a75d562403 100644
--- a/docs/source/api/lab/isaaclab.devices.rst
+++ b/docs/source/api/lab/isaaclab.devices.rst
@@ -18,16 +18,16 @@
HaplyDevice
OpenXRDevice
ManusVive
- isaaclab.devices.openxr.retargeters.GripperRetargeter
- isaaclab.devices.openxr.retargeters.Se3AbsRetargeter
- isaaclab.devices.openxr.retargeters.Se3RelRetargeter
- isaaclab.devices.openxr.retargeters.GR1T2Retargeter
+ openxr.retargeters.GripperRetargeter
+ openxr.retargeters.Se3AbsRetargeter
+ openxr.retargeters.Se3RelRetargeter
+ openxr.retargeters.GR1T2Retargeter
.. rubric:: Modules
.. autosummary::
- isaaclab.devices.openxr.retargeters
+ openxr.retargeters
Device Base
-----------
diff --git a/docs/source/api/lab/isaaclab.physics.rst b/docs/source/api/lab/isaaclab.physics.rst
new file mode 100644
index 00000000000..4a2fbfd8d70
--- /dev/null
+++ b/docs/source/api/lab/isaaclab.physics.rst
@@ -0,0 +1,4 @@
+isaaclab.physics
+================
+
+.. automodule:: isaaclab.physics
diff --git a/docs/source/api/lab/isaaclab.renderers.rst b/docs/source/api/lab/isaaclab.renderers.rst
new file mode 100644
index 00000000000..94eae9b5524
--- /dev/null
+++ b/docs/source/api/lab/isaaclab.renderers.rst
@@ -0,0 +1,36 @@
+isaaclab.renderers
+==================
+
+.. automodule:: isaaclab.renderers
+
+ .. rubric:: Classes
+
+ .. autosummary::
+
+ BaseRenderer
+ Renderer
+ RendererCfg
+
+Base Renderer
+-------------
+
+.. autoclass:: BaseRenderer
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+Renderer Factory
+----------------
+
+.. autoclass:: Renderer
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+Renderer Configuration
+-----------------------
+
+.. autoclass:: RendererCfg
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__
diff --git a/docs/source/api/lab/isaaclab.sim.rst b/docs/source/api/lab/isaaclab.sim.rst
index b6b5c372bc1..96816b6a522 100644
--- a/docs/source/api/lab/isaaclab.sim.rst
+++ b/docs/source/api/lab/isaaclab.sim.rst
@@ -1,4 +1,4 @@
-isaaclab.sim
+isaaclab.sim
============
.. automodule:: isaaclab.sim
@@ -18,7 +18,6 @@
SimulationContext
SimulationCfg
- PhysxCfg
RenderCfg
.. rubric:: Functions
@@ -42,11 +41,6 @@ Simulation Configuration
:show-inheritance:
:exclude-members: __init__
-.. autoclass:: PhysxCfg
- :members:
- :show-inheritance:
- :exclude-members: __init__
-
.. autoclass:: RenderCfg
:members:
:show-inheritance:
diff --git a/docs/source/api/lab/isaaclab.sim.schemas.rst b/docs/source/api/lab/isaaclab.sim.schemas.rst
index 77ac6512dbc..263e3152e59 100644
--- a/docs/source/api/lab/isaaclab.sim.schemas.rst
+++ b/docs/source/api/lab/isaaclab.sim.schemas.rst
@@ -13,7 +13,6 @@
MassPropertiesCfg
JointDrivePropertiesCfg
FixedTendonPropertiesCfg
- DeformableBodyPropertiesCfg
.. rubric:: Functions
@@ -30,8 +29,6 @@
modify_mass_properties
modify_joint_drive_properties
modify_fixed_tendon_properties
- define_deformable_body_properties
- modify_deformable_body_properties
Articulation Root
-----------------
@@ -95,9 +92,11 @@ Fixed Tendon
Deformable Body
---------------
-.. autoclass:: DeformableBodyPropertiesCfg
- :members:
- :exclude-members: __init__
+.. note::
+
+ Deformable body schemas have moved to the PhysX backend extension. See
+ :class:`isaaclab_physx.sim.schemas.DeformableBodyPropertiesCfg`,
+ :func:`isaaclab_physx.sim.schemas.define_deformable_body_properties`, and
+ :func:`isaaclab_physx.sim.schemas.modify_deformable_body_properties`.
-.. autofunction:: define_deformable_body_properties
-.. autofunction:: modify_deformable_body_properties
+ For migration details, see :ref:`migrating-deformables`.
diff --git a/docs/source/api/lab/isaaclab.sim.spawners.rst b/docs/source/api/lab/isaaclab.sim.spawners.rst
index 701efda84e1..a31968edfe0 100644
--- a/docs/source/api/lab/isaaclab.sim.spawners.rst
+++ b/docs/source/api/lab/isaaclab.sim.spawners.rst
@@ -21,7 +21,6 @@
SpawnerCfg
RigidObjectSpawnerCfg
- DeformableObjectSpawnerCfg
Spawners
--------
@@ -35,10 +34,12 @@ Spawners
:show-inheritance:
:exclude-members: __init__
-.. autoclass:: DeformableObjectSpawnerCfg
- :members:
- :show-inheritance:
- :exclude-members: __init__
+.. note::
+
+ ``DeformableObjectSpawnerCfg`` has moved to the PhysX backend extension. See
+ :class:`isaaclab_physx.sim.spawners.DeformableObjectSpawnerCfg`.
+
+ For migration details, see :ref:`migrating-deformables`.
Shapes
------
@@ -260,7 +261,6 @@ Materials
GlassMdlCfg
PhysicsMaterialCfg
RigidBodyMaterialCfg
- DeformableBodyMaterialCfg
Visual Materials
~~~~~~~~~~~~~~~~
@@ -298,11 +298,15 @@ Physical Materials
:members:
:exclude-members: __init__, func
-.. autofunction:: spawn_deformable_body_material
+.. note::
-.. autoclass:: DeformableBodyMaterialCfg
- :members:
- :exclude-members: __init__, func
+ ``DeformableBodyMaterialCfg``, ``SurfaceDeformableBodyMaterialCfg``, and
+ ``spawn_deformable_body_material`` have moved to the PhysX backend extension. See
+ :class:`isaaclab_physx.sim.spawners.materials.DeformableBodyMaterialCfg`,
+ :class:`isaaclab_physx.sim.spawners.materials.SurfaceDeformableBodyMaterialCfg`, and
+ :func:`isaaclab_physx.sim.spawners.materials.spawn_deformable_body_material`.
+
+ For migration details, see :ref:`migrating-deformables`.
Wrappers
--------
diff --git a/docs/source/api/lab/isaaclab.sim.views.rst b/docs/source/api/lab/isaaclab.sim.views.rst
index 3a5f9bdecfe..e06c4e54a24 100644
--- a/docs/source/api/lab/isaaclab.sim.views.rst
+++ b/docs/source/api/lab/isaaclab.sim.views.rst
@@ -7,11 +7,27 @@
.. autosummary::
- XformPrimView
+ BaseFrameView
+ UsdFrameView
+ FrameView
-XForm Prim View
+Base Frame View
---------------
-.. autoclass:: XformPrimView
+.. autoclass:: BaseFrameView
+ :members:
+ :show-inheritance:
+
+USD Frame View
+--------------
+
+.. autoclass:: UsdFrameView
+ :members:
+ :show-inheritance:
+
+Frame View
+----------
+
+.. autoclass:: FrameView
:members:
:show-inheritance:
diff --git a/docs/source/api/lab/isaaclab.visualizers.rst b/docs/source/api/lab/isaaclab.visualizers.rst
new file mode 100644
index 00000000000..d526a331375
--- /dev/null
+++ b/docs/source/api/lab/isaaclab.visualizers.rst
@@ -0,0 +1,4 @@
+isaaclab.visualizers
+====================
+
+.. automodule:: isaaclab.visualizers
diff --git a/docs/source/api/lab_assets/isaaclab_assets.robots.rst b/docs/source/api/lab_assets/isaaclab_assets.robots.rst
new file mode 100644
index 00000000000..91e2e96ae65
--- /dev/null
+++ b/docs/source/api/lab_assets/isaaclab_assets.robots.rst
@@ -0,0 +1,4 @@
+isaaclab\_assets.robots
+=======================
+
+.. automodule:: isaaclab_assets.robots
diff --git a/docs/source/api/lab_assets/isaaclab_assets.sensors.rst b/docs/source/api/lab_assets/isaaclab_assets.sensors.rst
new file mode 100644
index 00000000000..aa54f42a4e9
--- /dev/null
+++ b/docs/source/api/lab_assets/isaaclab_assets.sensors.rst
@@ -0,0 +1,4 @@
+isaaclab\_assets.sensors
+========================
+
+.. automodule:: isaaclab_assets.sensors
diff --git a/docs/source/api/lab_contrib/isaaclab_contrib.rl.rst b/docs/source/api/lab_contrib/isaaclab_contrib.rl.rst
new file mode 100644
index 00000000000..408443ef46b
--- /dev/null
+++ b/docs/source/api/lab_contrib/isaaclab_contrib.rl.rst
@@ -0,0 +1,63 @@
+isaaclab\_contrib.rl
+====================
+
+.. automodule:: isaaclab_contrib.rl
+
+Submodules
+----------
+
+isaaclab\_contrib.rl.rlinf
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. automodule:: isaaclab_contrib.rl.rlinf
+
+.. note::
+
+ The extension module requires the external ``rlinf`` package and cannot be
+ introspected at documentation build time. The API is described textually below.
+
+Extension Module
+^^^^^^^^^^^^^^^^
+
+The extension module (``isaaclab_contrib.rl.rlinf.extension``) is loaded by RLinf's
+worker framework via the ``RLINF_EXT_MODULE`` environment variable. It is not imported
+directly by user code.
+
+**Setup:**
+
+.. code-block:: bash
+
+ export RLINF_EXT_MODULE="isaaclab_contrib.rl.rlinf.extension"
+ export RLINF_CONFIG_FILE="/path/to/config.yaml"
+
+**Public entry point:**
+
+- ``register()`` -- Called by RLinf's worker to perform all setup. It:
+
+ 1. Registers GR00T observation and action converters.
+ 2. Patches GR00T's ``get_model`` for custom embodiment tags.
+ 3. Registers IsaacLab tasks into RLinf's ``REGISTER_ISAACLAB_ENVS`` registry.
+
+**Expected YAML configuration** (under ``env.train.isaaclab``):
+
+.. code-block:: yaml
+
+ env:
+ train:
+ isaaclab: &isaaclab_config
+ task_description: "Assemble trocar with dual-arm robot"
+ main_images: "front_camera"
+ extra_view_images: ["left_wrist_camera", "right_wrist_camera"]
+ states:
+ - key: "robot_joint_state"
+ slice: [15, 29]
+ gr00t_mapping:
+ video:
+ main_images: "video.room_view"
+ action_mapping:
+ prefix_pad: 15
+ eval:
+ isaaclab: *isaaclab_config # Reuse via YAML anchor
+
+Task IDs are read automatically from ``env.train.init_params.id`` and
+``env.eval.init_params.id`` in the YAML config.
diff --git a/docs/source/api/lab_mimic/isaaclab_mimic.envs.rst b/docs/source/api/lab_mimic/isaaclab_mimic.envs.rst
index ea8dc82d161..9b04d4c0066 100644
--- a/docs/source/api/lab_mimic/isaaclab_mimic.envs.rst
+++ b/docs/source/api/lab_mimic/isaaclab_mimic.envs.rst
@@ -7,20 +7,20 @@
.. autosummary::
- isaaclab_mimic.envs.franka_stack_ik_rel_mimic_env.FrankaCubeStackIKRelMimicEnv
- isaaclab_mimic.envs.franka_stack_ik_rel_mimic_env_cfg.FrankaCubeStackIKRelMimicEnvCfg
- isaaclab_mimic.envs.franka_stack_ik_abs_mimic_env.FrankaCubeStackIKAbsMimicEnv
- isaaclab_mimic.envs.franka_stack_ik_abs_mimic_env_cfg.FrankaCubeStackIKAbsMimicEnvCfg
- isaaclab_mimic.envs.galbot_stack_rmp_rel_mimic_env.RmpFlowGalbotCubeStackRelMimicEnv
- isaaclab_mimic.envs.galbot_stack_rmp_rel_mimic_env_cfg.RmpFlowGalbotLeftArmGripperCubeStackRelMimicEnvCfg
- isaaclab_mimic.envs.galbot_stack_rmp_rel_mimic_env_cfg.RmpFlowGalbotRightArmSuctionCubeStackRelMimicEnvCfg
- isaaclab_mimic.envs.galbot_stack_rmp_abs_mimic_env.RmpFlowGalbotCubeStackAbsMimicEnv
- isaaclab_mimic.envs.galbot_stack_rmp_abs_mimic_env_cfg.RmpFlowGalbotLeftArmGripperCubeStackAbsMimicEnvCfg
- isaaclab_mimic.envs.galbot_stack_rmp_abs_mimic_env_cfg.RmpFlowGalbotRightArmSuctionCubeStackAbsMimicEnvCfg
- isaaclab_mimic.envs.pick_place_mimic_env.PickPlaceRelMimicEnv
- isaaclab_mimic.envs.pick_place_mimic_env.PickPlaceAbsMimicEnv
- isaaclab_mimic.envs.agibot_place_upright_mug_mimic_env_cfg.RmpFlowAgibotPlaceUprightMugMimicEnvCfg
- isaaclab_mimic.envs.agibot_place_toy2box_mimic_env_cfg.RmpFlowAgibotPlaceToy2BoxMimicEnvCfg
+ franka_stack_ik_rel_mimic_env.FrankaCubeStackIKRelMimicEnv
+ franka_stack_ik_rel_mimic_env_cfg.FrankaCubeStackIKRelMimicEnvCfg
+ franka_stack_ik_abs_mimic_env.FrankaCubeStackIKAbsMimicEnv
+ franka_stack_ik_abs_mimic_env_cfg.FrankaCubeStackIKAbsMimicEnvCfg
+ galbot_stack_rmp_rel_mimic_env.RmpFlowGalbotCubeStackRelMimicEnv
+ galbot_stack_rmp_rel_mimic_env_cfg.RmpFlowGalbotLeftArmGripperCubeStackRelMimicEnvCfg
+ galbot_stack_rmp_rel_mimic_env_cfg.RmpFlowGalbotRightArmSuctionCubeStackRelMimicEnvCfg
+ galbot_stack_rmp_abs_mimic_env.RmpFlowGalbotCubeStackAbsMimicEnv
+ galbot_stack_rmp_abs_mimic_env_cfg.RmpFlowGalbotLeftArmGripperCubeStackAbsMimicEnvCfg
+ galbot_stack_rmp_abs_mimic_env_cfg.RmpFlowGalbotRightArmSuctionCubeStackAbsMimicEnvCfg
+ pick_place_mimic_env.PickPlaceRelMimicEnv
+ pick_place_mimic_env.PickPlaceAbsMimicEnv
+ agibot_place_upright_mug_mimic_env_cfg.RmpFlowAgibotPlaceUprightMugMimicEnvCfg
+ agibot_place_toy2box_mimic_env_cfg.RmpFlowAgibotPlaceToy2BoxMimicEnvCfg
Franka Environments
-------------------
diff --git a/docs/source/api/lab_newton/isaaclab_newton.assets.rst b/docs/source/api/lab_newton/isaaclab_newton.assets.rst
new file mode 100644
index 00000000000..8dc6f9b8f58
--- /dev/null
+++ b/docs/source/api/lab_newton/isaaclab_newton.assets.rst
@@ -0,0 +1,4 @@
+isaaclab\_newton.assets
+=======================
+
+.. automodule:: isaaclab_newton.assets
diff --git a/docs/source/api/lab_newton/isaaclab_newton.cloner.rst b/docs/source/api/lab_newton/isaaclab_newton.cloner.rst
new file mode 100644
index 00000000000..721d95f375b
--- /dev/null
+++ b/docs/source/api/lab_newton/isaaclab_newton.cloner.rst
@@ -0,0 +1,4 @@
+isaaclab\_newton.cloner
+=======================
+
+.. automodule:: isaaclab_newton.cloner
diff --git a/docs/source/api/lab_newton/isaaclab_newton.physics.rst b/docs/source/api/lab_newton/isaaclab_newton.physics.rst
new file mode 100644
index 00000000000..692293ce88e
--- /dev/null
+++ b/docs/source/api/lab_newton/isaaclab_newton.physics.rst
@@ -0,0 +1,4 @@
+isaaclab\_newton.physics
+========================
+
+.. automodule:: isaaclab_newton.physics
diff --git a/docs/source/api/lab_newton/isaaclab_newton.renderers.rst b/docs/source/api/lab_newton/isaaclab_newton.renderers.rst
new file mode 100644
index 00000000000..ca22ed5e835
--- /dev/null
+++ b/docs/source/api/lab_newton/isaaclab_newton.renderers.rst
@@ -0,0 +1,4 @@
+isaaclab\_newton.renderers
+==========================
+
+.. automodule:: isaaclab_newton.renderers
diff --git a/docs/source/api/lab_newton/isaaclab_newton.scene_data_providers.rst b/docs/source/api/lab_newton/isaaclab_newton.scene_data_providers.rst
new file mode 100644
index 00000000000..746a0e62ff6
--- /dev/null
+++ b/docs/source/api/lab_newton/isaaclab_newton.scene_data_providers.rst
@@ -0,0 +1,4 @@
+isaaclab\_newton.scene\_data\_providers
+=======================================
+
+.. automodule:: isaaclab_newton.scene_data_providers
diff --git a/docs/source/api/lab_newton/isaaclab_newton.sensors.rst b/docs/source/api/lab_newton/isaaclab_newton.sensors.rst
new file mode 100644
index 00000000000..f2c7ff5dacc
--- /dev/null
+++ b/docs/source/api/lab_newton/isaaclab_newton.sensors.rst
@@ -0,0 +1,4 @@
+isaaclab\_newton.sensors
+========================
+
+.. automodule:: isaaclab_newton.sensors
diff --git a/docs/source/api/lab_ov/isaaclab_ov.renderers.rst b/docs/source/api/lab_ov/isaaclab_ov.renderers.rst
new file mode 100644
index 00000000000..13a0212dec4
--- /dev/null
+++ b/docs/source/api/lab_ov/isaaclab_ov.renderers.rst
@@ -0,0 +1,4 @@
+isaaclab\_ov.renderers
+======================
+
+.. automodule:: isaaclab_ov.renderers
diff --git a/docs/source/api/lab_physx/isaaclab_physx.assets.rst b/docs/source/api/lab_physx/isaaclab_physx.assets.rst
new file mode 100644
index 00000000000..b631dcbcb7b
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.assets.rst
@@ -0,0 +1,99 @@
+isaaclab_physx.assets
+=====================
+
+.. automodule:: isaaclab_physx.assets
+ :noindex:
+
+ .. rubric:: Classes
+
+ .. autosummary::
+
+ Articulation
+ ArticulationData
+ RigidObject
+ RigidObjectData
+ RigidObjectCollection
+ RigidObjectCollectionData
+ DeformableObject
+ DeformableObjectData
+ DeformableObjectCfg
+ SurfaceGripper
+ SurfaceGripperCfg
+
+.. currentmodule:: isaaclab_physx.assets
+
+Articulation
+------------
+
+.. autoclass:: Articulation
+ :members:
+ :inherited-members:
+ :show-inheritance:
+
+.. autoclass:: ArticulationData
+ :members:
+ :inherited-members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+Rigid Object
+------------
+
+.. autoclass:: RigidObject
+ :members:
+ :inherited-members:
+ :show-inheritance:
+
+.. autoclass:: RigidObjectData
+ :members:
+ :inherited-members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+Rigid Object Collection
+-----------------------
+
+.. autoclass:: RigidObjectCollection
+ :members:
+ :inherited-members:
+ :show-inheritance:
+
+.. autoclass:: RigidObjectCollectionData
+ :members:
+ :inherited-members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+Deformable Object
+-----------------
+
+.. autoclass:: DeformableObject
+ :members:
+ :inherited-members:
+ :show-inheritance:
+
+.. autoclass:: DeformableObjectData
+ :members:
+ :inherited-members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+.. autoclass:: DeformableObjectCfg
+ :members:
+ :inherited-members:
+ :show-inheritance:
+ :exclude-members: __init__, class_type, InitialStateCfg
+
+Surface Gripper
+---------------
+
+.. autoclass:: SurfaceGripper
+ :members:
+ :inherited-members:
+ :show-inheritance:
+
+.. autoclass:: SurfaceGripperCfg
+ :members:
+ :inherited-members:
+ :show-inheritance:
+ :exclude-members: __init__, class_type, InitialStateCfg
diff --git a/docs/source/api/lab_physx/isaaclab_physx.cloner.rst b/docs/source/api/lab_physx/isaaclab_physx.cloner.rst
new file mode 100644
index 00000000000..9a179cf1fb4
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.cloner.rst
@@ -0,0 +1,4 @@
+isaaclab\_physx.cloner
+======================
+
+.. automodule:: isaaclab_physx.cloner
diff --git a/docs/source/api/lab_physx/isaaclab_physx.physics.rst b/docs/source/api/lab_physx/isaaclab_physx.physics.rst
new file mode 100644
index 00000000000..7e3017a7ee8
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.physics.rst
@@ -0,0 +1,4 @@
+isaaclab\_physx.physics
+=======================
+
+.. automodule:: isaaclab_physx.physics
diff --git a/docs/source/api/lab_physx/isaaclab_physx.renderers.rst b/docs/source/api/lab_physx/isaaclab_physx.renderers.rst
new file mode 100644
index 00000000000..66f6a340f2e
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.renderers.rst
@@ -0,0 +1,4 @@
+isaaclab\_physx.renderers
+=========================
+
+.. automodule:: isaaclab_physx.renderers
diff --git a/docs/source/api/lab_physx/isaaclab_physx.scene_data_providers.rst b/docs/source/api/lab_physx/isaaclab_physx.scene_data_providers.rst
new file mode 100644
index 00000000000..937ef16b530
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.scene_data_providers.rst
@@ -0,0 +1,4 @@
+isaaclab\_physx.scene\_data\_providers
+======================================
+
+.. automodule:: isaaclab_physx.scene_data_providers
diff --git a/docs/source/api/lab_physx/isaaclab_physx.sensors.rst b/docs/source/api/lab_physx/isaaclab_physx.sensors.rst
new file mode 100644
index 00000000000..506d35bc056
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.sensors.rst
@@ -0,0 +1,4 @@
+isaaclab\_physx.sensors
+=======================
+
+.. automodule:: isaaclab_physx.sensors
diff --git a/docs/source/api/lab_physx/isaaclab_physx.sim.schemas.rst b/docs/source/api/lab_physx/isaaclab_physx.sim.schemas.rst
new file mode 100644
index 00000000000..40fb3addb27
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.sim.schemas.rst
@@ -0,0 +1,30 @@
+isaaclab_physx.sim.schemas
+==========================
+
+.. automodule:: isaaclab_physx.sim.schemas
+
+ .. rubric:: Classes
+
+ .. autosummary::
+
+ DeformableBodyPropertiesCfg
+
+ .. rubric:: Functions
+
+ .. autosummary::
+
+ define_deformable_body_properties
+ modify_deformable_body_properties
+
+.. currentmodule:: isaaclab_physx.sim.schemas
+
+Deformable Body
+---------------
+
+.. autoclass:: DeformableBodyPropertiesCfg
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+.. autofunction:: define_deformable_body_properties
+.. autofunction:: modify_deformable_body_properties
diff --git a/docs/source/api/lab_physx/isaaclab_physx.sim.spawners.rst b/docs/source/api/lab_physx/isaaclab_physx.sim.spawners.rst
new file mode 100644
index 00000000000..27463a44425
--- /dev/null
+++ b/docs/source/api/lab_physx/isaaclab_physx.sim.spawners.rst
@@ -0,0 +1,52 @@
+isaaclab_physx.sim.spawners
+===========================
+
+.. automodule:: isaaclab_physx.sim.spawners
+
+ .. rubric:: Submodules
+
+ .. autosummary::
+
+ materials
+
+ .. rubric:: Classes
+
+ .. autosummary::
+
+ DeformableObjectSpawnerCfg
+
+.. currentmodule:: isaaclab_physx.sim.spawners
+
+Spawners
+--------
+
+.. autoclass:: DeformableObjectSpawnerCfg
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__
+
+Materials
+---------
+
+.. automodule:: isaaclab_physx.sim.spawners.materials
+
+ .. rubric:: Classes
+
+ .. autosummary::
+
+ DeformableBodyMaterialCfg
+ SurfaceDeformableBodyMaterialCfg
+
+.. currentmodule:: isaaclab_physx.sim.spawners.materials
+
+.. autofunction:: spawn_deformable_body_material
+
+.. autoclass:: DeformableBodyMaterialCfg
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__, func
+
+.. autoclass:: SurfaceDeformableBodyMaterialCfg
+ :members:
+ :show-inheritance:
+ :exclude-members: __init__, func
diff --git a/docs/source/api/lab_teleop/isaaclab_teleop.rst b/docs/source/api/lab_teleop/isaaclab_teleop.rst
new file mode 100644
index 00000000000..e45e0193210
--- /dev/null
+++ b/docs/source/api/lab_teleop/isaaclab_teleop.rst
@@ -0,0 +1,52 @@
+.. _isaaclab_teleop-api:
+
+isaaclab_teleop
+===============
+
+.. automodule:: isaaclab_teleop
+
+ .. rubric:: Classes
+
+ .. autosummary::
+
+ IsaacTeleopCfg
+ IsaacTeleopDevice
+ XrCfg
+ XrAnchorRotationMode
+ XrAnchorSynchronizer
+
+ .. rubric:: Functions
+
+ .. autosummary::
+
+ create_isaac_teleop_device
+ remove_camera_configs
+
+Configuration
+-------------
+
+.. autoclass:: IsaacTeleopCfg
+ :members:
+
+.. autoclass:: XrCfg
+ :members:
+
+.. autoclass:: XrAnchorRotationMode
+ :members:
+
+Device
+------
+
+.. autoclass:: IsaacTeleopDevice
+ :members:
+ :show-inheritance:
+
+.. autofunction:: create_isaac_teleop_device
+
+XR Anchor
+---------
+
+.. autoclass:: XrAnchorSynchronizer
+ :members:
+
+.. autofunction:: remove_camera_configs
diff --git a/docs/source/api/lab_visualizers/isaaclab_visualizers.kit.rst b/docs/source/api/lab_visualizers/isaaclab_visualizers.kit.rst
new file mode 100644
index 00000000000..d53ec1c30e5
--- /dev/null
+++ b/docs/source/api/lab_visualizers/isaaclab_visualizers.kit.rst
@@ -0,0 +1,4 @@
+isaaclab\_visualizers.kit
+=========================
+
+.. automodule:: isaaclab_visualizers.kit
diff --git a/docs/source/api/lab_visualizers/isaaclab_visualizers.newton.rst b/docs/source/api/lab_visualizers/isaaclab_visualizers.newton.rst
new file mode 100644
index 00000000000..c3725bd2786
--- /dev/null
+++ b/docs/source/api/lab_visualizers/isaaclab_visualizers.newton.rst
@@ -0,0 +1,4 @@
+isaaclab\_visualizers.newton
+============================
+
+.. automodule:: isaaclab_visualizers.newton
diff --git a/docs/source/api/lab_visualizers/isaaclab_visualizers.rerun.rst b/docs/source/api/lab_visualizers/isaaclab_visualizers.rerun.rst
new file mode 100644
index 00000000000..1906ba7d97a
--- /dev/null
+++ b/docs/source/api/lab_visualizers/isaaclab_visualizers.rerun.rst
@@ -0,0 +1,4 @@
+isaaclab\_visualizers.rerun
+===========================
+
+.. automodule:: isaaclab_visualizers.rerun
diff --git a/docs/source/api/lab_visualizers/isaaclab_visualizers.viser.rst b/docs/source/api/lab_visualizers/isaaclab_visualizers.viser.rst
new file mode 100644
index 00000000000..94631b4a7ea
--- /dev/null
+++ b/docs/source/api/lab_visualizers/isaaclab_visualizers.viser.rst
@@ -0,0 +1,4 @@
+isaaclab\_visualizers.viser
+===========================
+
+.. automodule:: isaaclab_visualizers.viser
diff --git a/docs/source/deployment/cloudxr_teleoperation_cluster.rst b/docs/source/deployment/cloudxr_teleoperation_cluster.rst
deleted file mode 100644
index 2b374bcbe54..00000000000
--- a/docs/source/deployment/cloudxr_teleoperation_cluster.rst
+++ /dev/null
@@ -1,207 +0,0 @@
-.. _cloudxr-teleoperation-cluster:
-
-Deploying CloudXR Teleoperation on Kubernetes
-=============================================
-
-.. currentmodule:: isaaclab
-
-This section explains how to deploy CloudXR Teleoperation for Isaac Lab on a Kubernetes (K8s) cluster.
-
-.. _k8s-system-requirements:
-
-System Requirements
--------------------
-
-* **Minimum requirement**: Kubernetes cluster with a node that has at least 1 NVIDIA RTX PRO 6000 / L40 GPU or equivalent
-* **Recommended requirement**: Kubernetes cluster with a node that has at least 2 RTX PRO 6000 / L40 GPUs or equivalent
-
-.. note::
- If you are using DGX Spark, check `DGX Spark Limitations `_ for compatibility.
-
-Software Dependencies
----------------------
-
-* ``kubectl`` on your host computer
-
- * If you use MicroK8s, you already have ``microk8s kubectl``
- * Otherwise follow the `official kubectl installation guide `_
-
-* ``helm`` on your host computer
-
- * If you use MicroK8s, you already have ``microk8s helm``
- * Otherwise follow the `official Helm installation guide `_
-
-* Access to NGC public registry from your Kubernetes cluster, in particular these container images:
-
- * ``https://catalog.ngc.nvidia.com/orgs/nvidia/containers/isaac-lab``
- * ``https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cloudxr-runtime``
-
-* NVIDIA GPU Operator or equivalent installed in your Kubernetes cluster to expose NVIDIA GPUs
-* NVIDIA Container Toolkit installed on the nodes of your Kubernetes cluster
-
-Preparation
------------
-
-On your host computer, you should have already configured ``kubectl`` to access your Kubernetes cluster. To validate, run the following command and verify it returns your nodes correctly:
-
-.. code:: bash
-
- kubectl get node
-
-If you are installing this to your own Kubernetes cluster instead of using the setup described in the :ref:`k8s-appendix`, your role in the K8s cluster should have at least the following RBAC permissions:
-
-.. code:: yaml
-
- rules:
- - apiGroups: [""]
- resources: ["configmaps"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- - apiGroups: ["apps"]
- resources: ["deployments", "replicasets"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- - apiGroups: [""]
- resources: ["pods"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- - apiGroups: [""]
- resources: ["services"]
- verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
-
-.. _k8s-installation:
-
-Installation
-------------
-
-.. note::
-
- The following steps are verified on a MicroK8s cluster with GPU Operator installed (see configurations in the :ref:`k8s-appendix`). You can configure your own K8s cluster accordingly if you encounter issues.
-
-#. Download the Helm chart from NGC (get your NGC API key based on the `public guide `_):
-
- .. code:: bash
-
- helm fetch https://helm.ngc.nvidia.com/nvidia/charts/isaac-lab-teleop-2.3.0.tgz \
- --username='$oauthtoken' \
- --password=
-
-#. Install and run the CloudXR Teleoperation for Isaac Lab pod in the default namespace, consuming all host GPUs:
-
- .. code:: bash
-
- helm upgrade --install hello-isaac-teleop isaac-lab-teleop-2.3.0.tgz \
- --set fullnameOverride=hello-isaac-teleop \
- --set hostNetwork="true"
-
- .. note::
-
- You can remove the need for host network by creating an external LoadBalancer VIP (e.g., with MetalLB), and setting the environment variable ``NV_CXR_ENDPOINT_IP`` when deploying the Helm chart:
-
- .. code:: yaml
-
- # local_values.yml file example:
- fullnameOverride: hello-isaac-teleop
- streamer:
- extraEnvs:
- - name: NV_CXR_ENDPOINT_IP
- value: ""
- - name: ACCEPT_EULA
- value: "Y"
-
- .. code:: bash
-
- # command
- helm upgrade --install --values local_values.yml \
- hello-isaac-teleop isaac-lab-teleop-2.3.0.tgz
-
-#. Verify the deployment is completed:
-
- .. code:: bash
-
- kubectl wait --for=condition=available --timeout=300s \
- deployment/hello-isaac-teleop
-
- After the pod is running, it might take approximately 5-8 minutes to complete loading assets and start streaming.
-
-Uninstallation
---------------
-
-You can uninstall by simply running:
-
-.. code:: bash
-
- helm uninstall hello-isaac-teleop
-
-.. _k8s-appendix:
-
-Appendix: Setting Up a Local K8s Cluster with MicroK8s
-------------------------------------------------------
-
-Your local workstation should have the NVIDIA Container Toolkit and its dependencies installed. Otherwise, the following setup will not work.
-
-Cleaning Up Existing Installations (Optional)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code:: bash
-
- # Clean up the system to ensure we start fresh
- sudo snap remove microk8s
- sudo snap remove helm
- sudo apt-get remove docker-ce docker-ce-cli containerd.io
- # If you have snap docker installed, remove it as well
- sudo snap remove docker
-
-Installing MicroK8s
-~~~~~~~~~~~~~~~~~~~
-
-.. code:: bash
-
- sudo snap install microk8s --classic
-
-Installing NVIDIA GPU Operator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. code:: bash
-
- microk8s helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
- microk8s helm repo update
- microk8s helm install gpu-operator \
- -n gpu-operator \
- --create-namespace nvidia/gpu-operator \
- --set toolkit.env[0].name=CONTAINERD_CONFIG \
- --set toolkit.env[0].value=/var/snap/microk8s/current/args/containerd-template.toml \
- --set toolkit.env[1].name=CONTAINERD_SOCKET \
- --set toolkit.env[1].value=/var/snap/microk8s/common/run/containerd.sock \
- --set toolkit.env[2].name=CONTAINERD_RUNTIME_CLASS \
- --set toolkit.env[2].value=nvidia \
- --set toolkit.env[3].name=CONTAINERD_SET_AS_DEFAULT \
- --set-string toolkit.env[3].value=true
-
-.. note::
-
- If you have configured the GPU operator to use volume mounts for ``DEVICE_LIST_STRATEGY`` on the device plugin and disabled ``ACCEPT_NVIDIA_VISIBLE_DEVICES_ENVVAR_WHEN_UNPRIVILEGED`` on the toolkit, this configuration is currently unsupported, as there is no method to ensure the assigned GPU resource is consistently shared between containers of the same pod.
-
-Verifying Installation
-~~~~~~~~~~~~~~~~~~~~~~
-
-Run the following command to verify that all pods are running correctly:
-
-.. code:: bash
-
- microk8s kubectl get pods -n gpu-operator
-
-You should see output similar to:
-
-.. code:: text
-
- NAMESPACE NAME READY STATUS RESTARTS AGE
- gpu-operator gpu-operator-node-feature-discovery-gc-76dc6664b8-npkdg 1/1 Running 0 77m
- gpu-operator gpu-operator-node-feature-discovery-master-7d6b448f6d-76fqj 1/1 Running 0 77m
- gpu-operator gpu-operator-node-feature-discovery-worker-8wr4n 1/1 Running 0 77m
- gpu-operator gpu-operator-86656466d6-wjqf4 1/1 Running 0 77m
- gpu-operator nvidia-container-toolkit-daemonset-qffh6 1/1 Running 0 77m
- gpu-operator nvidia-dcgm-exporter-vcxsf 1/1 Running 0 77m
- gpu-operator nvidia-cuda-validator-x9qn4 0/1 Completed 0 76m
- gpu-operator nvidia-device-plugin-daemonset-t4j4k 1/1 Running 0 77m
- gpu-operator gpu-feature-discovery-8dms9 1/1 Running 0 77m
- gpu-operator nvidia-operator-validator-gjs9m 1/1 Running 0 77m
-
-Once all pods are running, you can proceed to the :ref:`k8s-installation` section.
diff --git a/docs/source/deployment/docker.rst b/docs/source/deployment/docker.rst
index 9dad372c9c7..65e22e2aef7 100644
--- a/docs/source/deployment/docker.rst
+++ b/docs/source/deployment/docker.rst
@@ -308,7 +308,7 @@ To pull the minimal Isaac Lab container, run:
.. code:: bash
- docker pull nvcr.io/nvidia/isaac-lab:2.3.2
+ docker pull nvcr.io/nvidia/isaac-lab:3.0.0-beta1
To run the Isaac Lab container with an interactive bash session, run:
@@ -324,7 +324,7 @@ To run the Isaac Lab container with an interactive bash session, run:
-v ~/docker/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw \
-v ~/docker/isaac-sim/data:/root/.local/share/ov/data:rw \
-v ~/docker/isaac-sim/documents:/root/Documents:rw \
- nvcr.io/nvidia/isaac-lab:2.3.2
+ nvcr.io/nvidia/isaac-lab:3.0.0-beta1
To enable rendering through X11 forwarding, run:
@@ -343,7 +343,7 @@ To enable rendering through X11 forwarding, run:
-v ~/docker/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw \
-v ~/docker/isaac-sim/data:/root/.local/share/ov/data:rw \
-v ~/docker/isaac-sim/documents:/root/Documents:rw \
- nvcr.io/nvidia/isaac-lab:2.3.2
+ nvcr.io/nvidia/isaac-lab:3.0.0-beta1
To run an example within the container, run:
diff --git a/docs/source/deployment/index.rst b/docs/source/deployment/index.rst
index 235a23c9d75..3b65acfe094 100644
--- a/docs/source/deployment/index.rst
+++ b/docs/source/deployment/index.rst
@@ -60,13 +60,6 @@ After cloning, you can choose the deployment workflow that fits your needs:
- Includes tested workflows for ETH Zurich's Euler cluster and IIT Genoa's Franklin cluster,
with notes on adapting to other environments.
-- :doc:`cloudxr_teleoperation_cluster`
-
- - Deploy CloudXR Teleoperation for Isaac Lab on a Kubernetes cluster.
- - Covers system requirements, software dependencies, and preparation steps including RBAC permissions.
- - Demonstrates how to install and verify the Helm chart, run the pod, and uninstall it.
-
-
.. toctree::
:maxdepth: 1
:hidden:
@@ -74,4 +67,3 @@ After cloning, you can choose the deployment workflow that fits your needs:
docker
run_docker_example
cluster
- cloudxr_teleoperation_cluster
diff --git a/docs/source/experimental-features/newton-physics-integration/index.rst b/docs/source/experimental-features/newton-physics-integration/index.rst
index e56eee5bbb0..f40de231834 100644
--- a/docs/source/experimental-features/newton-physics-integration/index.rst
+++ b/docs/source/experimental-features/newton-physics-integration/index.rst
@@ -17,7 +17,7 @@ features for other reinforcement learning and imitation learning workflows in th
a good lens through which to understand how Newton integration works in Isaac Lab.
We have validated Newton simulation against PhysX by transferring learned policies from Newton to PhysX and vice versa
-Furthermore, we have also successfully deployed a Newton-trained locomotion policy to a G1 robot. Please see :ref:`here ` for more information.
+Furthermore, we have also successfully deployed a Newton-trained locomotion policy to a G1 robot.
Newton can support `multiple solvers `_ for handling different types of physics simulation, but for the moment, the Isaac
Lab integration focuses primarily on the MuJoCo-Warp solver.
@@ -29,16 +29,14 @@ During the development phase of both Newton and this Isaac Lab integration, you
changes as well as limited documentation. We do not expect to be able to provide official support or debugging assistance
until the framework has reached an official release. We appreciate your understanding and patience as we work to deliver a robust and polished framework!
+For an overview of how the multi-backend architecture works, including how to add a new backend, see
+:doc:`/source/overview/core-concepts/multi_backend_architecture`.
+
.. toctree::
:maxdepth: 2
:titlesonly:
installation
- isaaclab_newton-beta-2
- training-environments
- visualization
limitations-and-known-bugs
solver-transitioning
- sim-to-sim
- sim-to-real
diff --git a/docs/source/experimental-features/newton-physics-integration/sim-to-real.rst b/docs/source/experimental-features/newton-physics-integration/sim-to-real.rst
deleted file mode 100644
index 6b7a952a76c..00000000000
--- a/docs/source/experimental-features/newton-physics-integration/sim-to-real.rst
+++ /dev/null
@@ -1,92 +0,0 @@
-.. _sim2real:
-
-Sim-to-Real Policy Transfer
-===========================
-Deploying policies from simulation to real robots involves important nuances that must be addressed.
-This section provides a high-level guide for training policies that can be deployed on a real Unitree G1 robot.
-The key challenge is that not all observations available in simulation can be directly measured by real robot sensors.
-This means RL-trained policies cannot be directly deployed unless they use only sensor-available observations. For example, while real robot IMU sensors provide angular acceleration (which can be integrated to get angular velocity), they cannot directly measure linear velocity. Therefore, if a policy relies on base linear velocity during training, this information must be removed before real robot deployment.
-
-
-Requirements
-~~~~~~~~~~~~
-
-We assume that policies from this workflow are first verified through sim-to-sim transfer before real robot deployment.
-Please see :ref:`here ` for more information.
-
-
-Overview
---------
-
-This section demonstrates a sim-to-real workflow using teacher–student distillation for the Unitree G1
-velocity-tracking task with the Newton backend.
-
-The teacher–student distillation workflow consists of three stages:
-
-1. Train a teacher policy with privileged observations that are not available in real-world sensors.
-2. Distill a student policy that excludes privileged terms (e.g., root linear velocity) by behavior cloning from the teacher policy.
-3. Fine-tune the student policy with RL using only real-sensor observations.
-
-The teacher and student observation groups are implemented in the velocity task configuration. See the following source for details:
-
-- Teacher observations: ``PolicyCfg(ObsGroup)`` in `velocity_env_cfg.py `__
-- Student observations: ``StudentPolicyCfg(ObsGroup)`` in `velocity_env_cfg.py `__
-
-
-1. Train the teacher policy
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Train the teacher policy for the G1 velocity task using the Newton backend. The task ID is ``Isaac-Velocity-Flat-G1-v1``
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py --task=Isaac-Velocity-Flat-G1-v1 --num_envs=4096
-
-The teacher policy includes privileged observations (e.g., root linear velocity) defined in ``PolicyCfg(ObsGroup)``.
-
-
-2. Distill the student policy (remove privileged terms)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-During distillation, the student policy learns to mimic the teacher through behavior cloning by minimizing the mean squared error
-between their actions: :math:`loss = MSE(\pi(O_{teacher}), \pi(O_{student}))`.
-
-The student policy only uses observations available from real sensors (see ``StudentPolicyCfg(ObsGroup)``
-in `velocity_env_cfg.py `__).
-Specifically: **Root angular velocity** and **Projected gravity** come from the IMU sensor, **Joint positions and velocities** come from joint encoders, and **Actions** are the joint torques applied by the controller.
-
-Run the student distillation task ``Velocity-G1-Distillation-v1`` using ``--load_run`` and ``--checkpoint`` to specify the teacher policy you want to distill from.
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py --task=Velocity-G1-Distillation-v1 --num_envs=4096 --load_run 2025-08-13_23-53-28 --checkpoint model_1499.pt
-
-.. note::
-
- Use the correct ``--load_run`` and ``--checkpoint`` to ensure you distill from the intended teacher policy.
-
-
-3. Fine-tune the student policy with RL
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Fine-tune the distilled student policy using RL with the ``Velocity-G1-Student-Finetune-v1`` task.
-Use ``--load_run`` and ``--checkpoint`` to initialize from the distilled policy.
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/train.py --task=Velocity-G1-Student-Finetune-v1 --num_envs=4096 --load_run 2025-08-20_16-06-52_distillation --checkpoint model_1499.pt
-
-This starts from the distilled student policy and improves it further with RL training.
-
-.. note::
-
- Make sure ``--load_run`` and ``--checkpoint`` point to the correct initial policy (usually the latest checkpoint from the distillation step).
-
-You can replay the student policy via:
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/reinforcement_learning/rsl_rl/play.py --task=Velocity-G1-Student-Finetune-v1 --num_envs=32 --visualizer newton
-
-
-This exports the policy as ``.pt`` and ``.onnx`` files in the run's export directory, ready for real robot deployment.
diff --git a/docs/source/experimental-features/newton-physics-integration/sim-to-sim.rst b/docs/source/experimental-features/newton-physics-integration/sim-to-sim.rst
deleted file mode 100644
index 8eebbdffac3..00000000000
--- a/docs/source/experimental-features/newton-physics-integration/sim-to-sim.rst
+++ /dev/null
@@ -1,171 +0,0 @@
-.. _sim2sim:
-
-Sim-to-Sim Policy Transfer
-==========================
-This section provides examples of sim-to-sim policy transfer between PhysX and Newton backends. Sim-to-sim transfer is an essential step before real robot deployment because it verifies that policies work across different simulators. Policies that pass sim-to-sim verification are much more likely to succeed on real robots.
-
-
-Overview
---------
-
-This guide shows how to transfer policies between PhysX and Newton backends in both directions. The main challenge is that different physics engines may parse the same robot model with different joint and link ordering.
-
-Policies trained in one backend expect joints and links in a specific order determined by how that backend parses the robot model. When transferring to another backend, the joint ordering may be different, requiring remapping of observations and actions.
-
-In the future, we plan to solve this using **robot schema** that standardizes joint and link ordering across different backends.
-
-Currently, we solve this by remapping observations and actions using joint mappings defined in YAML files. These files specify joint names in both source and target backend orders. During policy execution, we use this mapping to reorder observations and actions so they work correctly with the target backend.
-
-The method has been tested with Unitree G1, Unitree Go2, Unitree H1, and ANYmal-D robots for both transfer directions.
-
-
-What you need
-~~~~~~~~~~~~~
-
-- A policy checkpoint trained with either PhysX or Newton (RSL-RL).
-- A joint mapping YAML for your robot under ``scripts/sim2sim_transfer/config/``.
-- The provided player script: ``scripts/sim2sim_transfer/rsl_rl_transfer.py``.
-
-To add a new robot, create a YAML file with two lists where each joint name appears exactly once in both:
-
-.. code-block:: yaml
-
- # Example structure
- source_joint_names: # Source backend joint order
- - joint_1
- - joint_2
- # ...
- target_joint_names: # Target backend joint order
- - joint_1
- - joint_2
- # ...
-
-The script automatically computes the necessary mappings for locomotion tasks.
-
-
-PhysX-to-Newton Transfer
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-To run a PhysX-trained policy with the Newton backend, use this command template:
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task= \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file \
- --visualizer newton
-
-Here are examples for different robots:
-
-1. Unitree G1
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-G1-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/physx_to_newton_g1.yaml \
- --visualizer newton
-
-2. Unitree H1
-
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-H1-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/physx_to_newton_h1.yaml \
- --visualizer newton
-
-
-3. Unitree Go2
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-Go2-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/physx_to_newton_go2.yaml \
- --visualizer newton
-
-
-4. ANYmal-D
-
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-Anymal-D-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/physx_to_newton_anymal_d.yaml \
- --visualizer newton
-
-Note that to run this, you need to checkout the Newton-based branch of IsaacLab such as ``feature/newton``.
-
-Newton-to-PhysX Transfer
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-To transfer Newton-trained policies to PhysX-based IsaacLab, use the reverse mapping files:
-
-Here are examples for different robots:
-
-1. Unitree G1
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-G1-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/newton_to_physx_g1.yaml
-
-
-2. Unitree H1
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-H1-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/newton_to_physx_h1.yaml
-
-
-3. Unitree Go2
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-Go2-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/newton_to_physx_go2.yaml
-
-
-4. ANYmal-D
-
-.. code-block:: bash
-
- ./isaaclab.sh -p scripts/sim2sim_transfer/rsl_rl_transfer.py \
- --task=Isaac-Velocity-Flat-Anymal-D-v0 \
- --num_envs=32 \
- --checkpoint \
- --policy_transfer_file scripts/sim2sim_transfer/config/newton_to_physx_anymal_d.yaml
-
-The key difference is using the ``newton_to_physx_*.yaml`` mapping files instead of ``physx_to_newton_*.yaml`` files. Also note that you need to checkout a PhysX-based IsaacLab branch such as ``main``.
-
-Notes and Limitations
-~~~~~~~~~~~~~~~~~~~~~
-
-- Both transfer directions have been tested with Unitree G1, Unitree Go2, Unitree H1, and ANYmal-D robots.
-- PhysX-to-Newton transfer uses ``physx_to_newton_*.yaml`` mapping files.
-- Newton-to-PhysX transfer requires the corresponding ``newton_to_physx_*.yaml`` mapping files and the PhysX branch of IsaacLab.
-- The observation remapping assumes a locomotion layout with base observations followed by joint observations. For different observation layouts, you'll need to modify the ``get_joint_mappings`` function in ``scripts/sim2sim_transfer/rsl_rl_transfer.py``.
-- When adding new robots or backends, make sure both source and target have identical joint names, and that the YAML lists reflect how each backend orders these joints.
diff --git a/docs/source/features/hydra.rst b/docs/source/features/hydra.rst
index 47e84fb328c..0e3ddc34181 100644
--- a/docs/source/features/hydra.rst
+++ b/docs/source/features/hydra.rst
@@ -108,7 +108,7 @@ are modified.
For example, for the configuration of the Cartpole camera depth environment:
-.. literalinclude:: ../../../source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_camera_env.py
+.. literalinclude:: ../../../source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_camera_env_cfg.py
:language: python
:start-at: class CartpoleDepthCameraEnvCfg
:end-at: tiled_camera.width
@@ -127,3 +127,255 @@ the post init update is as follows:
Here, when modifying ``env.decimation`` or ``env.sim.dt``, the user needs to give the updated ``env.sim.render_interval``,
``env.scene.height_scanner.update_period``, and ``env.scene.contact_forces.update_period`` as input as well.
+
+
+Custom Configuration Validation
+--------------------------------
+
+Configclass objects can define a ``validate_config()`` method to perform domain-specific
+validation after all fields have been resolved. This hook is called automatically after preset
+resolution and MISSING-field checks succeed, allowing you to catch invalid parameter
+combinations early with clear error messages.
+
+**Defining a validation hook:**
+
+.. code-block:: python
+
+ from isaaclab.utils import configclass
+
+ @configclass
+ class MyEnvCfg:
+ physics_backend: str = "physx"
+ use_multi_asset: bool = False
+
+ def validate_config(self):
+ if self.physics_backend == "newton" and self.use_multi_asset:
+ raise ValueError(
+ "Newton physics does not support multi-asset spawning."
+ " Use a single-geometry object preset instead."
+ )
+
+**When it runs:**
+
+1. All ``MISSING`` fields are checked first — if any remain, ``TypeError`` is raised.
+2. Only then is ``validate_config()`` called on the **top-level** config object.
+3. The hook should raise ``ValueError`` with a clear message and migration guidance.
+
+**Common validation patterns:**
+
+- Physics backend compatibility (e.g., Newton does not support multi-asset spawning)
+- Renderer and camera data type compatibility (e.g., Newton Warp only supports ``rgb`` and ``depth``)
+- Feature extractor compatibility with camera configuration
+
+
+Preset System
+-------------
+
+The preset system lets you swap out entire config sections -- or individual scalar
+values -- with a single command line argument. Instead of overriding individual
+fields, you select a named preset that **completely replaces** the config section
+(no field merging).
+
+Presets are declared by subclassing :class:`~isaaclab_tasks.utils.hydra.PresetCfg`
+or by using the :func:`~isaaclab_tasks.utils.hydra.preset` convenience factory. The
+system recursively discovers all presets from nested configs automatically,
+including presets inside dict-valued fields (e.g. ``actuators``).
+
+
+Override Order
+^^^^^^^^^^^^^^
+
+Overrides are applied in sequence:
+
+1. **Auto-default**: Configs with a ``"default"`` field auto-apply without CLI args
+2. **Global presets**: ``presets=newton,inference`` applies to ALL matching configs
+3. **Path presets**: ``env.backend=newton`` replaces a specific section
+4. **Scalar overrides**: ``env.sim.dt=0.001`` modifies individual fields
+
+
+Defining Presets with PresetCfg
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Create a :class:`~isaaclab_tasks.utils.hydra.PresetCfg` subclass where each field
+is a named alternative. The ``default`` field is the config used when no CLI
+override is given:
+
+.. code-block:: python
+
+ from isaaclab_tasks.utils import PresetCfg
+
+ @configclass
+ class PhysicsCfg(PresetCfg):
+ default: PhysxCfg = PhysxCfg()
+ newton: NewtonCfg = NewtonCfg()
+
+ @configclass
+ class MyEnvCfg:
+ physics: PhysicsCfg = PhysicsCfg()
+
+.. code-block:: bash
+
+ # Use Newton physics backend
+ python train.py --task=Isaac-Reach-Franka-v0 env.physics=newton
+
+The ``default`` field can be set to ``None`` to make an optional feature that is
+disabled unless explicitly selected:
+
+.. code-block:: python
+
+ @configclass
+ class CameraPresetCfg(PresetCfg):
+ default = None
+ small: CameraCfg = CameraCfg(width=64, height=64)
+ large: CameraCfg = CameraCfg(width=256, height=256)
+
+ @configclass
+ class SceneCfg:
+ camera: CameraPresetCfg = CameraPresetCfg()
+
+.. code-block:: bash
+
+ # camera is None -- no camera overhead
+ python train.py --task=Isaac-Reach-Franka-v0
+
+ # activate camera with the "large" preset
+ python train.py --task=Isaac-Reach-Franka-v0 env.scene.camera=large
+
+
+Inline Presets with preset()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For simple values (scalars, lists) that don't warrant a full subclass, use the
+:func:`~isaaclab_tasks.utils.hydra.preset` factory. It dynamically creates a
+``PresetCfg`` instance from keyword arguments:
+
+.. code-block:: python
+
+ from isaaclab_tasks.utils.hydra import preset
+
+ # Scalar preset -- one line, no boilerplate class
+ self.scene.robot.actuators["legs"].armature = preset(default=0.0, newton=0.01, physx=0.0)
+
+This is equivalent to defining a ``PresetCfg`` subclass with three ``float``
+fields, but without the ceremony. The ``default`` keyword is required.
+
+``preset()`` works for any value type -- scalars, lists, or even config
+instances:
+
+.. code-block:: python
+
+ # Resolution preset on a camera config field
+ width = preset(default=64, res128=128, res256=256)
+
+ # List preset for camera data types
+ @configclass
+ class DataTypeCfg(PresetCfg):
+ default: list = ["rgb"]
+ depth: list = ["depth"]
+ albedo: list = ["albedo"]
+
+Use ``preset()`` when the definition fits on a single line. Use a
+``PresetCfg`` subclass when the options are verbose enough to benefit from
+type annotations and multiline formatting.
+
+The preset system discovers ``preset()`` values anywhere in the config tree,
+including inside dict-valued fields such as ``actuators``:
+
+.. code-block:: bash
+
+ # Select newton preset globally -- sets armature to 0.01
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0 presets=newton
+
+
+Using Presets
+^^^^^^^^^^^^^
+
+**Path presets** -- select a specific preset for one config path:
+
+.. code-block:: bash
+
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0 \
+ env.events=newton
+
+**Global presets** -- apply the same preset name everywhere it exists:
+
+.. code-block:: bash
+
+ # Apply "newton" preset to all configs that define it
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0 \
+ presets=newton
+
+**Multiple global presets** -- apply several non-conflicting presets:
+
+.. code-block:: bash
+
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0 \
+ presets=newton,inference
+
+**Combined** -- global presets + scalar overrides:
+
+.. code-block:: bash
+
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0 \
+ presets=newton \
+ env.sim.dt=0.002
+
+
+Global Preset Conflict Detection
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If two global presets both match the same config path, an error is raised
+so the ambiguity is caught early:
+
+.. code-block:: text
+
+ ValueError: Conflicting global presets: 'foo' and 'bar'
+ both define preset for 'env.events'
+
+
+Real-World Example
+^^^^^^^^^^^^^^^^^^
+
+The ANYmal-C locomotion environment shows both ``PresetCfg`` and ``preset()``
+working together:
+
+.. literalinclude:: ../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_c/rough_env_cfg.py
+ :language: python
+ :lines: 21-42
+
+A single ``presets=newton`` on the command line resolves every ``PresetCfg``
+and ``preset()`` that defines a ``newton`` field: the physics engine is swapped
+to Newton, ``AnymalCEventsCfg`` selects Newton-compatible events, and the
+actuator armature is set to ``0.01``.
+
+.. code-block:: bash
+
+ # Default (PhysX events, armature=0.0)
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0
+
+ # Newton (Newton events, armature=0.01)
+ python train.py --task=Isaac-Velocity-Rough-Anymal-C-v0 presets=newton
+
+
+Summary
+^^^^^^^
+
+.. list-table::
+ :widths: 25 35 40
+ :header-rows: 1
+
+ * - Override Type
+ - Syntax
+ - Effect
+ * - Scalar
+ - ``env.sim.dt=0.001``
+ - Modify single field
+ * - Path preset
+ - ``env.events=newton``
+ - Replace entire section
+ * - Global preset
+ - ``presets=newton``
+ - Apply everywhere matching
+ * - Combined
+ - ``presets=newton env.sim.dt=0.001``
+ - Global + scalar overrides
diff --git a/docs/source/features/isaac_teleop.rst b/docs/source/features/isaac_teleop.rst
new file mode 100644
index 00000000000..73315025958
--- /dev/null
+++ b/docs/source/features/isaac_teleop.rst
@@ -0,0 +1,1021 @@
+.. _isaac-teleop-feature:
+
+Isaac Teleop
+============
+
+.. currentmodule:: isaaclab
+
+`Isaac Teleop `_ is the unified framework for high-fidelity
+egocentric and robot data collection. It provides a standardized device interface, a flexible
+graph-based retargeting pipeline, and works seamlessly across simulated and real-world robots.
+
+Isaac Teleop replaces the previous native XR teleop stack (``isaaclab.devices.openxr``) in Isaac
+Lab. For migration details see :ref:`migrating-to-isaaclab-3-0`.
+
+.. tip::
+
+ **Just want to get running?** Follow the :ref:`cloudxr-teleoperation` how-to guide for
+ installation and first-run steps, then come back here for deeper topics.
+
+
+.. _isaac-teleop-supported-devices:
+
+Supported Devices
+-----------------
+
+Isaac Teleop supports multiple XR headsets and tracking peripherals. Each device provides different
+input modes, which determine which retargeters and control schemes are available.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 20 25 25 30
+
+ * - Device
+ - Input Modes
+ - Client / Connection
+ - Notes
+ * - Apple Vision Pro
+ - Hand tracking (26 joints), spatial controllers
+ - Native visionOS app (`Isaac XR Teleop Sample Client`_)
+ - Build from source; see :ref:`build-apple-vision-pro`
+ * - Meta Quest 3
+ - Motion controllers (triggers, thumbsticks, squeeze), hand tracking
+ - CloudXR.js WebXR client (browser)
+ - `CloudXR client `__; see :ref:`connection guide `
+ * - Pico 4 Ultra
+ - Motion controllers, hand tracking
+ - CloudXR.js WebXR client (browser)
+ - Requires Pico OS 15.4.4U+; must use HTTPS mode
+ * - Manus Gloves
+ - High-fidelity finger tracking (Manus SDK)
+ - Isaac Teleop plugin (bundled)
+ - Migrated from the now-deprecated ``isaac-teleop-device-plugins`` repo.
+ Combine with an external wrist-tracking source for wrist positioning. See :ref:`manus-vive-handtracking`.
+
+
+.. _isaac-teleop-control-schemes:
+
+Choose a Control Scheme
+-----------------------
+
+The right combination of input device and retargeters depends on your task. Use this table as a
+starting point, then see the detailed pipeline examples below.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 22 18 30 10 20
+
+ * - Task Type
+ - Recommended Input
+ - Retargeters
+ - Action Dim
+ - Reference Config
+ * - Manipulation (e.g. Franka)
+ - Motion controllers
+ - ``Se3AbsRetargeter`` + ``GripperRetargeter``
+ - 8
+ - ``stack_ik_abs_env_cfg.py``
+ * - Bimanual dex + locomotion (e.g. G1 TriHand)
+ - Motion controllers
+ - Bimanual ``Se3AbsRetargeter`` + ``TriHandMotionControllerRetargeter`` + ``LocomotionRootCmdRetargeter``
+ - 32
+ - ``locomanipulation_g1_env_cfg.py``
+ * - Bimanual dex, fixed base (e.g. G1)
+ - Motion controllers
+ - Bimanual ``Se3AbsRetargeter`` + ``TriHandMotionControllerRetargeter``
+ - 28
+ - ``fixed_base_upper_body_ik_g1_env_cfg.py``
+ * - Complex dex hand (e.g. GR1T2, G1 Inspire)
+ - Hand tracking / Manus gloves
+ - Bimanual ``Se3AbsRetargeter`` + ``DexBiManualRetargeter``
+ - 36+
+ - ``pickplace_gr1t2_env_cfg.py``
+
+**Why motion controllers for manipulation?** Controllers provide precise spatial control via a grip
+pose and a physical trigger for gripper actuation, making them ideal for pick-and-place tasks.
+
+**Why hand tracking for complex dex hands?** Hand tracking captures the full 26-joint hand pose
+required for high-fidelity dexterous retargeting. This is essential when individual finger control
+matters.
+
+
+.. _isaac-teleop-architecture:
+
+How It Works
+------------
+
+The :class:`~isaaclab_teleop.IsaacTeleopDevice` is the main integration point between Isaac Teleop
+and Isaac Lab. It composes three collaborators:
+
+* **XrAnchorManager** -- creates and synchronizes an XR anchor prim in the simulation, and
+ computes the ``world_T_anchor`` transform matrix that maps XR tracking data into the simulation
+ coordinate frame.
+
+* **TeleopSessionLifecycle** -- builds the retargeting pipeline, acquires OpenXR handles from
+ Isaac Sim's XR bridge, creates the ``TeleopSession``, and steps it each frame to produce an
+ action tensor.
+
+* **CommandHandler** -- lightweight callback registry for START / STOP / RESET commands. Scripts
+ can register callbacks via :meth:`~isaaclab_teleop.IsaacTeleopDevice.add_callback`, but the
+ primary control path uses :func:`~isaaclab_teleop.poll_control_events` (see
+ :ref:`isaac-teleop-control-states`).
+
+.. dropdown:: Session lifecycle details
+
+ The session uses **deferred creation**: if the user has not yet clicked "Start AR" in the Isaac
+ Sim UI, the session is not created immediately. Instead, each call to ``advance()`` retries
+ session creation until OpenXR handles become available. Once connected, ``advance()`` returns a
+ flattened action tensor (``torch.Tensor``) on the configured device. It returns ``None`` when
+ the session is not yet ready or has been torn down.
+
+
+.. _isaac-teleop-control-states:
+
+Teleop Control States (Start / Stop / Reset)
+---------------------------------------------
+
+Isaac Lab supports remote teleop control commands -- **start**, **stop**, and **reset** -- sent
+from the XR headset to the simulation. These are used to begin and end demonstration recording,
+pause the robot, or reset the environment without touching the simulation host.
+
+How it works
+~~~~~~~~~~~~
+
+By default, every :class:`~isaaclab_teleop.IsaacTeleopCfg` enables a control message channel
+using the well-known UUID ``uuid5(NAMESPACE_DNS, "teleop_command")``. The channel is created as
+a ``teleop_control_pipeline`` inside TeleopCore's :class:`TeleopSession`, which means:
+
+1. A :class:`~isaacteleop.retargeting_engine.deviceio_source_nodes.MessageChannelSource` opens an
+ OpenXR opaque data channel (``XR_NV_opaque_data_channel``) with the agreed-upon UUID.
+2. The CloudXR JS client (or any other client) discovers the channel by UUID and sends UTF-8
+ JSON commands::
+
+ {"type": "teleop_command", "message": {"command": "start teleop"}}
+ {"type": "teleop_command", "message": {"command": "stop teleop"}}
+ {"type": "teleop_command", "message": {"command": "reset teleop"}}
+
+3. A :class:`~isaaclab_teleop.teleop_message_processor.TeleopMessageProcessor` parses these
+ payloads and produces boolean pulse signals (``run_toggle``, ``kill``, ``reset``).
+4. :class:`~isaacteleop.teleop_session_manager.DefaultTeleopStateManager` consumes the
+ boolean signals, runs its state machine (edge detection, fail-safe), and produces
+ ``teleop_state`` (one-hot) and ``reset_event`` (bool pulse) outputs.
+5. TeleopCore decodes these outputs into ``ExecutionEvents`` and injects them into every
+ retargeter's ``ComputeContext``, so stateful retargeters can react to state changes
+ (e.g. reinitializing cross-step state on reset).
+
+Polling control events in your script
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :func:`~isaaclab_teleop.poll_control_events` to read the latest control state each frame:
+
+.. code-block:: python
+
+ from isaaclab_teleop import poll_control_events
+
+ with IsaacTeleopDevice(cfg) as device:
+ running = False
+ while sim_app.is_running():
+ action = device.advance()
+
+ ctrl = poll_control_events(device)
+ if ctrl.is_active is not None:
+ running = ctrl.is_active # True after "start", False after "stop"
+ if ctrl.should_reset:
+ env.reset() # "reset" command received this frame
+
+ if action is not None and running:
+ env.step(action.repeat(num_envs, 1))
+ else:
+ env.sim.render()
+
+:class:`~isaaclab_teleop.ControlEvents` has two fields:
+
+* ``is_active`` -- ``True`` after a "start" command, ``False`` after "stop", ``None`` when no
+ command has been received yet (callers should leave their own flag unchanged).
+* ``should_reset`` -- ``True`` for exactly one frame after a "reset" command.
+
+Disabling the control channel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you do not need headset-driven start/stop/reset (e.g. keyboard-only workflows), set
+``control_channel_uuid=None`` in your config:
+
+.. code-block:: python
+
+ IsaacTeleopCfg(
+ pipeline_builder=_build_my_pipeline,
+ control_channel_uuid=None, # no opaque data channel created
+ )
+
+Using a custom channel UUID
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To use a different channel UUID (e.g. for a separate control protocol), pass any 16-byte
+``bytes`` value:
+
+.. code-block:: python
+
+ import uuid
+
+ MY_UUID = uuid.uuid5(uuid.NAMESPACE_DNS, "my_custom_control").bytes
+
+ IsaacTeleopCfg(
+ pipeline_builder=_build_my_pipeline,
+ control_channel_uuid=MY_UUID,
+ )
+
+The CloudXR JS client must be updated to discover this UUID when sending commands.
+
+
+.. _isaac-teleop-retargeting:
+
+Retargeting Framework
+---------------------
+
+Isaac Teleop uses a graph-based retargeting pipeline. Data flows from **source nodes** through
+**retargeters** and is combined into a single action tensor.
+
+Source Nodes
+~~~~~~~~~~~~
+
+* ``HandsSource`` -- provides hand tracking data (left/right, 26 joints each).
+* ``ControllersSource`` -- provides motion controller data (grip pose, trigger, thumbstick, etc.).
+
+Available Retargeters
+~~~~~~~~~~~~~~~~~~~~~
+
+Retargeters are provided by the ``isaacteleop`` package from the
+`Isaac Teleop `_ repository. The retargeters listed below
+are those used by the built-in Isaac Lab environments. Isaac Teleop may offer additional
+retargeters not listed here -- refer to the
+`Isaac Teleop repository `_ for the full set.
+
+.. dropdown:: Se3AbsRetargeter / Se3RelRetargeter
+
+ Maps hand or controller tracking to end-effector pose. ``Se3AbsRetargeter`` outputs a 7D
+ absolute pose (position + quaternion). ``Se3RelRetargeter`` outputs a 6D delta.
+ Configurable rotation offsets (roll, pitch, yaw in degrees).
+
+.. dropdown:: GripperRetargeter
+
+ Outputs a single float (-1.0 closed, 1.0 open). Uses controller trigger (priority) or
+ thumb-index pinch distance from hand tracking.
+
+.. dropdown:: DexHandRetargeter / DexBiManualRetargeter
+
+ Retargets full hand tracking (26 joints) to robot-specific hand joint angles using the
+ ``dex-retargeting`` library. Requires a robot hand URDF and a YAML configuration file.
+
+ .. warning::
+
+ The links used for retargeting must be defined at the actual fingertips, not in the middle
+ of the fingers, to ensure accurate optimization.
+
+.. dropdown:: TriHandMotionControllerRetargeter
+
+ Maps VR controller buttons (trigger, squeeze) to G1 TriHand joints (7 DOF per hand). Simple
+ mapping: trigger controls the index finger, squeeze controls the middle finger, and both
+ together control the thumb.
+
+.. dropdown:: LocomotionRootCmdRetargeter
+
+ Maps controller thumbsticks to a 4D locomotion command:
+ ``[vel_x, vel_y, rot_vel_z, hip_height]``.
+
+.. dropdown:: TensorReorderer
+
+ Utility that flattens and reorders outputs from multiple retargeters into a single 1D action
+ tensor. The ``output_order`` must match the action space expected by the environment.
+
+The built-in Isaac Lab environments use these retargeters as follows:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 40 60
+
+ * - Environment
+ - Retargeters Used
+ * - Franka manipulation (stack, pick-place)
+ - ``Se3AbsRetargeter``, ``GripperRetargeter``, ``TensorReorderer``
+ * - G1 Inspire dexterous pick-place
+ - ``Se3AbsRetargeter``, ``DexHandRetargeter``, ``TensorReorderer``
+ * - GR1-T2 dexterous pick-place
+ - ``Se3AbsRetargeter``, ``DexHandRetargeter``, ``TensorReorderer``
+ * - G1 upper-body (fixed base)
+ - ``Se3AbsRetargeter``, ``TriHandMotionControllerRetargeter``, ``TensorReorderer``
+ * - G1 loco-manipulation
+ - ``Se3AbsRetargeter``, ``TriHandMotionControllerRetargeter``, ``LocomotionRootCmdRetargeter``, ``TensorReorderer``
+
+
+.. _isaac-teleop-env-control-reference:
+
+Teleoperation Environment Reference
+-----------------------------------
+
+The tables below list every built-in Isaac Lab environment that supports teleoperation,
+organized by input method. Environments whose Task ID ends in ``-Play`` are designed for
+closed-loop policy evaluation and are not included here.
+
+Isaac Teleop (XR Headset) Environments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These environments use the Isaac Teleop XR pipeline with motion controllers or hand tracking.
+
+.. list-table::
+ :header-rows: 1
+ :widths: 28 14 14 44
+
+ * - Task ID
+ - Input Mode
+ - Hands
+ - Operator Interaction
+ * - ``Isaac-Stack-Cube-Franka-IK-Abs-v0``
+ - Controllers
+ - Right
+ - **Arm:** right controller grip pose drives end-effector.
+ **Gripper:** right trigger.
+ * - ``Isaac-PickPlace-GR1T2-Abs-v0``
+ - Hand tracking
+ - Both
+ - **Arms:** left/right hand wrist pose drives each end-effector.
+ **Hands:** full 26-joint hand tracking retargeted to 11 DOF per Fourier hand via ``DexHandRetargeter``.
+ * - ``Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0``
+ - Hand tracking
+ - Both
+ - Same as ``Isaac-PickPlace-GR1T2-Abs-v0`` with waist DOFs enabled.
+ * - ``Isaac-NutPour-GR1T2-Pink-IK-Abs-v0``
+ - Hand tracking
+ - Both
+ - Same retargeting pipeline as ``Isaac-PickPlace-GR1T2-Abs-v0`` (different task scene).
+ * - ``Isaac-ExhaustPipe-GR1T2-Pink-IK-Abs-v0``
+ - Hand tracking
+ - Both
+ - Same retargeting pipeline as ``Isaac-PickPlace-GR1T2-Abs-v0`` (different task scene).
+ * - ``Isaac-PickPlace-G1-InspireFTP-Abs-v0``
+ - Hand tracking
+ - Both
+ - **Arms:** left/right hand wrist pose drives each end-effector.
+ **Hands:** full 26-joint hand tracking retargeted to 12 DOF per Inspire hand via ``DexHandRetargeter``.
+ * - ``Isaac-PickPlace-FixedBaseUpperBodyIK-G1-Abs-v0``
+ - Controllers
+ - Both
+ - **Arms:** left/right controller grip pose drives each end-effector.
+ **Hands:** trigger closes index, squeeze closes middle, both together close thumb (7 DOF TriHand per hand).
+ * - ``Isaac-PickPlace-Locomanipulation-G1-Abs-v0``
+ - Controllers
+ - Both
+ - **Arms:** same as fixed-base G1 above.
+ **Hands:** same TriHand mapping.
+ **Locomotion:** left thumbstick = linear velocity (x/y), right thumbstick X = rotational velocity, right thumbstick Y = hip height.
+
+.. tip::
+
+ **Controllers** provide a grip pose plus physical buttons (trigger, squeeze, thumbstick),
+ ideal for tasks that need a gripper or simple hand mapping. **Hand tracking** captures 26
+ wrist and finger joints per hand, required for dexterous retargeting to complex robot hands.
+
+Keyboard and SpaceMouse Environments
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. note::
+
+ Keyboard and SpaceMouse teleoperation uses the legacy native Isaac Lab teleop stack
+ (``isaaclab.devices``), not Isaac Teleop. These environments do not require an XR headset.
+
+The device button layouts below apply to all environments in this section. Per-environment
+differences (gripper enabled/disabled, sensitivity) are noted in the environment table that
+follows.
+
+**Keyboard**
+
+.. list-table::
+ :header-rows: 1
+ :widths: 20 20 60
+
+ * - Function
+ - Keys
+ - Description
+ * - Position X
+ - ``W`` / ``S``
+ - Move end-effector forward / backward.
+ * - Position Y
+ - ``A`` / ``D``
+ - Move end-effector left / right.
+ * - Position Z
+ - ``Q`` / ``E``
+ - Move end-effector up / down.
+ * - Roll
+ - ``Z`` / ``X``
+ - Rotate about X axis.
+ * - Pitch
+ - ``T`` / ``G``
+ - Rotate about Y axis.
+ * - Yaw
+ - ``C`` / ``V``
+ - Rotate about Z axis.
+ * - Gripper toggle
+ - ``K``
+ - Open / close gripper or suction (disabled in Reach envs).
+ * - Reset
+ - ``L``
+ - Clear accumulated delta pose and gripper state.
+
+**SpaceMouse**
+
+.. list-table::
+ :header-rows: 1
+ :widths: 20 20 60
+
+ * - Function
+ - Control
+ - Description
+ * - Translation
+ - 6-DOF knob
+ - Push/pull/slide the knob to move the end-effector in X/Y/Z.
+ * - Rotation
+ - 6-DOF knob
+ - Tilt/twist the knob to rotate the end-effector in roll/pitch/yaw.
+ * - Gripper toggle
+ - Left button
+ - Open / close gripper or suction (disabled in Reach envs).
+ * - Reset
+ - Right button
+ - Clear accumulated delta pose and gripper state.
+
+**Gamepad** (Reach environments only)
+
+.. list-table::
+ :header-rows: 1
+ :widths: 20 20 60
+
+ * - Function
+ - Control
+ - Description
+ * - Position X / Y
+ - Left stick
+ - Move end-effector forward/backward and left/right.
+ * - Position Z
+ - Right stick (up/down)
+ - Move end-effector up / down.
+ * - Roll / Pitch
+ - D-Pad
+ - Left/right for roll, up/down for pitch.
+ * - Yaw
+ - Right stick (left/right)
+ - Rotate about Z axis.
+ * - Gripper toggle
+ - X button
+ - Open / close gripper (disabled in Reach envs).
+
+.. list-table::
+ :header-rows: 1
+ :widths: 34 18 48
+
+ * - Task ID
+ - Devices
+ - Operator Interaction
+ * - ``Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow-v0``
+ - Keyboard, SpaceMouse
+ - **Arm:** end-effector pose via RMPFlow.
+ **Gripper:** ``K`` on keyboard, left button on SpaceMouse.
+ * - ``Isaac-Stack-Cube-Galbot-Right-Arm-Suction-RmpFlow-v0``
+ - Keyboard, SpaceMouse
+ - **Arm:** end-effector pose via RMPFlow.
+ **Suction:** ``K`` on keyboard, left button on SpaceMouse.
+ * - ``Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-Visuomotor-v0``
+ - Keyboard, SpaceMouse
+ - Same as left-arm gripper above with camera observations.
+ * - ``Isaac-Stack-Cube-UR10-Long-Suction-IK-Rel-v0``
+ - Keyboard, SpaceMouse
+ - **Arm:** relative IK end-effector control.
+ **Suction:** ``K`` on keyboard, left button on SpaceMouse.
+ * - ``Isaac-Stack-Cube-UR10-Short-Suction-IK-Rel-v0``
+ - Keyboard, SpaceMouse
+ - Same as long-suction UR10 above with a shorter suction cup.
+ * - ``Isaac-Reach-Franka-IK-Abs-v0``
+ - Keyboard, Gamepad, SpaceMouse
+ - **Arm:** absolute IK end-effector control. Gripper disabled.
+ * - ``Isaac-Reach-Franka-IK-Rel-v0``
+ - Keyboard, Gamepad, SpaceMouse
+ - **Arm:** relative IK end-effector control. Gripper disabled.
+
+
+.. _isaac-teleop-switching-input-mode:
+
+Switch Between Controllers and Hand Tracking
+---------------------------------------------
+
+The retargeting pipeline determines whether an environment uses motion controllers or hand
+tracking. Switching input modes requires changing the ``pipeline_builder`` function in your
+environment config. No other environment-level changes are needed as long as the action
+space (``TensorReorderer`` output order) stays the same.
+
+**Controller to hand tracking**
+
+The key changes are:
+
+#. Create a ``HandsSource`` and apply the world-to-anchor transform to it (instead of
+ ``ControllersSource``).
+#. Point the ``Se3RetargeterConfig.input_device`` at the appropriate ``HandsSource`` key.
+#. Set ``use_wrist_rotation=True`` and ``use_wrist_position=True`` so that the SE3 retargeter
+ reads from the hand wrist joint rather than the controller grip pose.
+#. The ``GripperRetargeter`` already supports both inputs -- it uses the controller trigger
+ when connected to a ``ControllersSource`` or thumb-index pinch when connected to a
+ ``HandsSource``.
+
+Here is the Franka stack environment's controller-based pipeline alongside a hand-tracking
+variant for comparison.
+
+**Original (controller-based):**
+
+.. code-block:: python
+ :emphasize-lines: 4-5,10-12
+
+ # SE3: tracks right controller grip pose
+ se3_cfg = Se3RetargeterConfig(
+ input_device=ControllersSource.RIGHT,
+ use_wrist_rotation=False,
+ use_wrist_position=False,
+ target_offset_roll=90.0,
+ )
+ se3 = Se3AbsRetargeter(se3_cfg, name="ee_pose")
+ connected_se3 = se3.connect({
+ ControllersSource.RIGHT: transformed_controllers.output(
+ ControllersSource.RIGHT
+ ),
+ })
+
+**Modified (hand-tracking-based):**
+
+.. code-block:: python
+ :emphasize-lines: 2-5,9-11
+
+ se3_cfg = Se3RetargeterConfig(
+ input_device=HandsSource.RIGHT,
+ use_wrist_rotation=True,
+ use_wrist_position=True,
+ target_offset_roll=0.0,
+ )
+ se3 = Se3AbsRetargeter(se3_cfg, name="ee_pose")
+
+ transformed_hands = hands.transformed(transform_input.output(ValueInput.VALUE))
+ connected_se3 = se3.connect({
+ HandsSource.RIGHT: transformed_hands.output(HandsSource.RIGHT),
+ })
+
+The ``GripperRetargeter`` needs no changes -- it accepts both controller and hand inputs and
+uses whichever source is connected.
+
+**Hand tracking to controller**
+
+Reverse the steps above: set ``input_device`` to a ``ControllersSource`` key, transform the
+controllers instead of the hands, and set ``use_wrist_rotation=False`` and
+``use_wrist_position=False``. Adjust ``target_offset_roll/pitch/yaw`` to account for the
+controller grip frame orientation (typically 90 degrees roll for Franka-style grippers).
+
+.. note::
+
+ When switching between input modes, you may need to tune the ``target_offset_roll``,
+ ``target_offset_pitch``, and ``target_offset_yaw`` values. Controller grip frames and hand
+ wrist frames have different default orientations relative to the robot end-effector.
+
+
+.. _isaac-teleop-pipeline-builder:
+
+Build a Retargeting Pipeline
+----------------------------
+
+A pipeline builder is a callable that constructs the retargeting graph and returns an
+``OutputCombiner`` with a single ``"action"`` key. Here is a complete example for a Franka
+manipulator (from ``stack_ik_abs_env_cfg.py``):
+
+.. code-block:: python
+
+ def _build_franka_stack_pipeline():
+ from isaacteleop.retargeting_engine.deviceio_source_nodes import ControllersSource, HandsSource
+ from isaacteleop.retargeting_engine.interface import OutputCombiner, ValueInput
+ from isaacteleop.retargeters import (
+ GripperRetargeter, GripperRetargeterConfig,
+ Se3AbsRetargeter, Se3RetargeterConfig,
+ TensorReorderer,
+ )
+ from isaacteleop.retargeting_engine.tensor_types import TransformMatrix
+
+ # 1. Create input sources
+ controllers = ControllersSource(name="controllers")
+ hands = HandsSource(name="hands")
+
+ # 2. Apply coordinate-frame transform (world_T_anchor provided by IsaacTeleopDevice)
+ transform_input = ValueInput("world_T_anchor", TransformMatrix())
+ transformed_controllers = controllers.transformed(
+ transform_input.output(ValueInput.VALUE)
+ )
+
+ # 3. Create and connect retargeters
+ se3_cfg = Se3RetargeterConfig(
+ input_device=ControllersSource.RIGHT,
+ target_offset_roll=90.0,
+ )
+ se3 = Se3AbsRetargeter(se3_cfg, name="ee_pose")
+ connected_se3 = se3.connect({
+ ControllersSource.RIGHT: transformed_controllers.output(ControllersSource.RIGHT),
+ })
+
+ gripper_cfg = GripperRetargeterConfig(hand_side="right")
+ gripper = GripperRetargeter(gripper_cfg, name="gripper")
+ connected_gripper = gripper.connect({
+ ControllersSource.RIGHT: transformed_controllers.output(ControllersSource.RIGHT),
+ HandsSource.RIGHT: hands.output(HandsSource.RIGHT),
+ })
+
+ # 4. Flatten into a single action tensor with TensorReorderer
+ ee_elements = ["pos_x", "pos_y", "pos_z", "quat_x", "quat_y", "quat_z", "quat_w"]
+ reorderer = TensorReorderer(
+ input_config={
+ "ee_pose": ee_elements,
+ "gripper_command": ["gripper_value"],
+ },
+ output_order=ee_elements + ["gripper_value"],
+ name="action_reorderer",
+ input_types={"ee_pose": "array", "gripper_command": "scalar"},
+ )
+ connected_reorderer = reorderer.connect({
+ "ee_pose": connected_se3.output("ee_pose"),
+ "gripper_command": connected_gripper.output("gripper_command"),
+ })
+
+ # 5. Return OutputCombiner with "action" key
+ return OutputCombiner({"action": connected_reorderer.output("output")})
+
+.. tip::
+
+ The ``output_order`` of the ``TensorReorderer`` must match the action space of your environment.
+ Mismatches will cause silent control errors.
+
+
+.. _isaac-teleop-env-config:
+
+Configure Your Environment
+--------------------------
+
+Register the pipeline in your environment configuration using :class:`~isaaclab_teleop.IsaacTeleopCfg`:
+
+.. code-block:: python
+
+ from isaaclab_teleop import IsaacTeleopCfg, XrCfg
+
+ @configclass
+ class MyTeleopEnvCfg(ManagerBasedRLEnvCfg):
+
+ xr: XrCfg = XrCfg(anchor_pos=(0.5, 0.0, 0.5))
+
+ def __post_init__(self):
+ super().__post_init__()
+
+ self.isaac_teleop = IsaacTeleopCfg(
+ pipeline_builder=_build_my_pipeline,
+ sim_device=self.sim.device,
+ xr_cfg=self.xr,
+ )
+
+Key ``IsaacTeleopCfg`` fields:
+
+* ``pipeline_builder`` -- callable that returns an ``OutputCombiner`` with an ``"action"`` output.
+* ``retargeters_to_tune`` -- optional callable returning retargeters to expose in the live tuning UI.
+* ``xr_cfg`` -- :class:`~isaaclab_teleop.XrCfg` for anchor configuration (see below).
+* ``plugins`` -- list of Isaac Teleop plugin configurations (e.g. Manus).
+* ``sim_device`` -- torch device string (default ``"cuda:0"``).
+
+.. warning::
+
+ ``pipeline_builder`` and ``retargeters_to_tune`` must be **callables** (functions or lambdas),
+ not pre-built objects. The ``@configclass`` decorator deep-copies mutable attributes, which
+ would break pre-built pipeline graphs.
+
+
+.. _isaac-teleop-cloudxr-profiles:
+
+CloudXR Environment Profiles
+-----------------------------
+
+Isaac Lab ships two ``.env`` profiles that configure the CloudXR runtime for different XR devices.
+These are bundled inside the ``isaaclab_teleop`` package and can be referenced via constants:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 25 25 20
+
+ * - Constant
+ - File
+ - ``NV_DEVICE_PROFILE``
+ - ``NV_CXR_ENABLE_PUSH_DEVICES``
+ * - :data:`~isaaclab_teleop.CLOUDXR_JS_ENV`
+ - ``cloudxrjs-cloudxr.env``
+ - ``auto-webrtc``
+ - ``0``
+ * - :data:`~isaaclab_teleop.CLOUDXR_AVP_ENV`
+ - ``avp-cloudxr.env``
+ - ``auto-native``
+ - ``0``
+
+Both profiles set ``NV_CXR_ENABLE_PUSH_DEVICES=0``, which is correct for headset optical hand
+tracking (the most common setup). For external push-device peripherals such as Manus gloves, set
+this to ``1`` in a custom profile (see below).
+
+Override at launch time
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``--cloudxr_env`` flag on ``teleop_se3_agent.py`` and ``record_demos.py`` selects which
+``.env`` profile to use. The default is ``cloudxrjs`` (Quest/Pico). Use the ``avp`` shorthand
+for Apple Vision Pro, or pass a full file path for a custom profile:
+
+.. code-block:: bash
+
+ # Use the AVP profile
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit --xr \
+ --cloudxr_env avp
+
+Create a custom profile
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Copy a shipped profile and edit it:
+
+.. code-block:: bash
+
+ # Start from the Quest/Pico profile
+ cp $(python -c "from isaaclab_teleop import CLOUDXR_JS_ENV; print(CLOUDXR_JS_ENV)") ~/my-cloudxr.env
+
+Edit ``~/my-cloudxr.env`` to change any values (e.g. ``NV_CXR_ENABLE_PUSH_DEVICES=1`` for
+Manus gloves), then pass it via ``--cloudxr_env ~/my-cloudxr.env``.
+
+Disable auto-launch
+~~~~~~~~~~~~~~~~~~~
+
+If you prefer to run the CloudXR runtime manually in a separate terminal
+(``python -m isaacteleop.cloudxr``), you can disable auto-launch in several ways:
+
+* **CLI flag**: ``--no-auto_launch_cloudxr`` on the teleop script.
+* **Disable CloudXR entirely**: ``--cloudxr_env none``.
+* **Environment variable**: ``ISAACLAB_CXR_SKIP_AUTOLAUNCH=1`` overrides the CLI flag at runtime.
+
+.. code-block:: bash
+
+ # Disable via CLI flag
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit --xr \
+ --no-auto_launch_cloudxr
+
+ # Or disable via environment variable
+ ISAACLAB_CXR_SKIP_AUTOLAUNCH=1 ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit --xr
+
+
+.. _isaac-teleop-xr-anchor:
+
+Configure the XR Anchor
+------------------------
+
+The :class:`~isaaclab_teleop.XrCfg` controls how the simulation is positioned and oriented in the
+XR device's view.
+
+``anchor_pos`` / ``anchor_rot``
+ Static anchor placement. The simulation point at these coordinates appears at the XR device's
+ local origin (floor level). Set to a point on the floor beneath the robot to position it in
+ front of the user.
+
+``anchor_prim_path``
+ Attach the anchor to a USD prim for dynamic positioning. Use this for locomotion tasks where
+ the robot moves and the XR camera should follow.
+
+``anchor_rotation_mode``
+ Controls how anchor rotation behaves:
+
+ .. list-table::
+ :header-rows: 1
+ :widths: 30 70
+
+ * - Mode
+ - Description
+ * - ``FIXED``
+ - Sets rotation once from ``anchor_rot``. Best for static manipulation setups.
+ * - ``FOLLOW_PRIM``
+ - Rotation continuously tracks the attached prim. Best for locomotion where the user
+ should face the robot's heading direction.
+ * - ``FOLLOW_PRIM_SMOOTHED``
+ - Same as ``FOLLOW_PRIM`` with slerp interpolation. Controlled by
+ ``anchor_rotation_smoothing_time`` (seconds, default 1.0). Reduces motion sickness from
+ abrupt rotation changes. Typical range: 0.3--1.5 s.
+ * - ``CUSTOM``
+ - User-provided callable
+ ``anchor_rotation_custom_func(headpose, primpose) -> quaternion`` for fully custom logic.
+
+``fixed_anchor_height``
+ When ``True`` (default), keeps the anchor height at its initial value. Prevents vertical
+ bobbing during locomotion.
+
+``near_plane``
+ Closest render distance for the XR device (default 0.15 m).
+
+.. note::
+
+ On Apple Vision Pro, the local coordinate frame can be reset to a point on the floor beneath
+ the user by holding the digital crown.
+
+.. tip::
+
+ When using XR, call :func:`~isaaclab_teleop.remove_camera_configs` on your env config to strip
+ camera sensors. Additional cameras cause GPU contention and degrade XR performance.
+
+
+.. _isaac-teleop-imitation-learning:
+
+Record Demonstrations for Imitation Learning
+---------------------------------------------
+
+Isaac Teleop integrates with Isaac Lab's ``record_demos.py`` script for recording teleoperated
+demonstrations.
+
+When your environment configuration has an ``isaac_teleop`` attribute, the script automatically
+uses ``create_isaac_teleop_device()`` -- no ``--teleop_device`` flag is needed:
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p scripts/tools/record_demos.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit \
+ --xr
+
+Some environments use the legacy ``teleop_devices`` configuration instead of ``isaac_teleop``
+(e.g. the Galbot RmpFlow relative-mode tasks). For these, pass ``--teleop_device`` to select
+the input device:
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p scripts/tools/record_demos.py \
+ --task Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow-v0 \
+ --visualizer kit \
+ --teleop_device keyboard
+
+The workflow is:
+
+#. Configure your environment with ``IsaacTeleopCfg`` (see :ref:`isaac-teleop-env-config`)
+ or ``teleop_devices`` for legacy devices (keyboard, spacemouse).
+#. Run ``record_demos.py`` with the task name.
+#. For XR tasks: start AR, connect your XR device, and teleoperate.
+ For legacy tasks: use the configured input device directly.
+#. Demonstrations are recorded to HDF5 files.
+#. Use the recorded data with Isaac Lab Mimic or other imitation learning frameworks.
+
+For the broader imitation learning pipeline (replay, augmentation, policy training), see
+:ref:`teleoperation-imitation-learning`.
+
+
+.. _isaac-teleop-new-embodiment:
+
+Add a New Robot
+---------------
+
+To add teleoperation support for a new robot in Isaac Lab:
+
+#. **Choose a control scheme.** Refer to the :ref:`isaac-teleop-control-schemes` table to determine
+ which retargeters match your robot's capabilities.
+
+#. **Build the pipeline.** If existing retargeters are sufficient (e.g. ``Se3AbsRetargeter`` +
+ ``GripperRetargeter`` for a new manipulator), write a pipeline builder function following the
+ pattern in :ref:`isaac-teleop-pipeline-builder`. Configure the ``TensorReorderer`` output order
+ to match your environment's action space.
+
+#. **For dexterous hands**: create a robot hand URDF and YAML config for ``DexHandRetargeter``.
+ Ensure fingertip links are positioned at the actual fingertips, not mid-finger.
+
+#. **For a custom retargeter**: see :ref:`isaac-teleop-new-retargeter` below.
+
+#. **Configure the XR anchor** for your robot (static for manipulation, dynamic for locomotion).
+ See :ref:`isaac-teleop-xr-anchor`.
+
+#. **Register in env config** via ``IsaacTeleopCfg`` (see :ref:`isaac-teleop-env-config`).
+
+
+.. _isaac-teleop-new-retargeter:
+
+Add a New Retargeter
+--------------------
+
+If the built-in retargeters do not cover your use case, you can implement a custom one in the
+`Isaac Teleop repository `_:
+
+#. Inherit from ``BaseRetargeter`` and implement ``input_spec()``, ``output_spec()``, and
+ ``compute()``.
+#. Optionally add a ``ParameterState`` for parameters that should be live-tunable via the
+ retargeter tuning UI.
+#. Connect to existing source nodes (``HandsSource``, ``ControllersSource``) or create a new
+ ``IDeviceIOSource`` subclass for custom input devices.
+
+See the `Isaac Teleop repository `_
+and `Contributing Guide `_ for details.
+
+
+.. _isaac-teleop-new-device:
+
+Add a New Device
+----------------
+
+There are two levels of device integration:
+
+**Isaac Teleop plugin (C++ level)**
+ For new hardware that requires a custom driver or SDK. Plugins push data via OpenXR tensor
+ collections. Existing plugins include Manus gloves, OAK-D camera, controller synthetic hands,
+ and foot pedals. After creating the plugin, update the retargeting pipeline config to consume
+ data from the new plugin's source node.
+
+ See the `Plugins directory `_ for examples.
+
+**Pipeline configuration only**
+ For devices already supported by Isaac Teleop (or whose data is available as hand / controller
+ tracking). Simply update your ``pipeline_builder`` to use the appropriate source nodes and
+ retargeters for the device's data format.
+
+
+.. _isaac-teleop-performance:
+
+Optimize XR Performance
+-----------------------
+
+.. dropdown:: Configure the physics and render time step
+ :open:
+
+ Ensure the simulation render time step roughly matches the XR device display time step and can
+ be sustained in real time. Apple Vision Pro runs at 90 Hz; we recommend a simulation dt of 90 Hz
+ with a render interval of 2 (rendering at 45 Hz):
+
+ .. code-block:: python
+
+ @configclass
+ class XrTeleopEnvCfg(ManagerBasedRLEnvCfg):
+
+ def __post_init__(self):
+ self.sim.dt = 1.0 / 90
+ self.sim.render_interval = 2
+
+ If render times are highly variable, set ``NV_PACER_FIXED_TIME_STEP_MS`` as an environment
+ variable when starting the CloudXR runtime to use fixed pacing.
+
+.. dropdown:: Try running physics on CPU
+ :open:
+
+ Running teleoperation scripts with ``--device cpu`` may reduce latency when only a single
+ environment is present, since it avoids GPU contention with rendering.
+
+
+.. _isaac-teleop-known-issues:
+
+Known Issues
+------------
+
+* ``XR_ERROR_VALIDATION_FAILURE: xrWaitFrame(frameState->type == 0)`` when stopping AR Mode
+
+ Can be safely ignored. Caused by a race condition in the exit handler.
+
+* ``XR_ERROR_INSTANCE_LOST in xrPollEvent``
+
+ Occurs if the CloudXR runtime exits before Isaac Lab. Restart the runtime to resume.
+
+* ``[omni.usd] TF_PYTHON_EXCEPTION`` when starting/stopping AR Mode
+
+ Can be safely ignored. Caused by a race condition in the enter/exit handler.
+
+* ``Invalid version string in _ParseVersionString``
+
+ Caused by shader assets authored with older USD versions. Typically safe to ignore.
+
+* XR device connects but no video is displayed (viewport responds to tracking)
+
+ The GPU index may differ between host and container. Set ``NV_GPU_INDEX`` to ``0``, ``1``, or
+ ``2`` in the runtime to match the host GPU.
+
+
+.. _isaac-teleop-api-ref:
+
+API Reference
+-------------
+
+See the :ref:`isaaclab_teleop-api` for full class and function documentation:
+
+* :class:`~isaaclab_teleop.IsaacTeleopCfg`
+* :class:`~isaaclab_teleop.IsaacTeleopDevice`
+* :func:`~isaaclab_teleop.create_isaac_teleop_device`
+* :class:`~isaaclab_teleop.ControlEvents`
+* :class:`~isaaclab_teleop.SupportsControlEvents`
+* :func:`~isaaclab_teleop.poll_control_events`
+* :data:`~isaaclab_teleop.TELEOP_CONTROL_CHANNEL_UUID`
+* :class:`~isaaclab_teleop.XrCfg`
+* :class:`~isaaclab_teleop.XrAnchorRotationMode`
+
+
+..
+ References
+.. _`Isaac XR Teleop Sample Client`: https://github.com/isaac-sim/isaac-xr-teleop-sample-client-apple
diff --git a/docs/source/features/population_based_training.rst b/docs/source/features/population_based_training.rst
index d88b8195bc7..1de85bb57c5 100644
--- a/docs/source/features/population_based_training.rst
+++ b/docs/source/features/population_based_training.rst
@@ -49,7 +49,7 @@ Example Config
num_policies: 8
directory: .
workspace: "pbt_workspace"
- objective: episode.Curriculum/difficulty_level
+ objective: episode.consecutive_successes
interval_steps: 50000000
threshold_std: 0.1
threshold_abs: 0.025
@@ -66,8 +66,13 @@ Example Config
agent.params.config.tau: "mutate_discount"
-``objective: episode.Curriculum/difficulty_level`` is the dotted expression that uses
-``infos["episode"]["Curriculum/difficulty_level"]`` as the scalar to **rank policies** (higher is better).
+``objective: episode.consecutive_successes`` is a dotted expression that resolves to
+``infos["episode"]["consecutive_successes"]`` as the scalar to **rank policies** (higher is better).
+
+.. note::
+ The rl_games wrapper remaps ``extras["log"]`` to ``extras["episode"]``, so objectives
+ should use the ``episode.`` prefix even though the environment writes to ``extras["log"]``.
+
With ``num_policies: 8``, launch eight processes sharing the same ``workspace`` and unique ``policy_idx`` (0-7).
@@ -101,7 +106,7 @@ Training Example
----------------
We provide a reference PPO config here for task:
-`Isaac-Dexsuite-Kuka-Allegro-Lift-v0 `_.
+`Isaac-Repose-Cube-Shadow-Direct-v0 `_.
For the best logging experience, we recommend using wandb for the logging in the script.
Launch *N* workers, where *n* indicates each worker index:
@@ -111,7 +116,7 @@ Launch *N* workers, where *n* indicates each worker index:
# Run this once per worker (n = 0..N-1), all pointing to the same directory/workspace
./isaaclab.sh -p scripts/reinforcement_learning/rl_games/train.py \
--seed= \
- --task=Isaac-Dexsuite-Kuka-Allegro-Lift-v0 \
+ --task=Isaac-Repose-Cube-Shadow-Direct-v0 \
--num_envs=8192 \
--headless \
--track \
diff --git a/docs/source/features/visualization.rst b/docs/source/features/visualization.rst
new file mode 100644
index 00000000000..c093fe18f00
--- /dev/null
+++ b/docs/source/features/visualization.rst
@@ -0,0 +1,453 @@
+Visualization
+=============
+
+.. currentmodule:: isaaclab
+
+Isaac Lab offers several lightweight visualizers for real-time simulation inspection and debugging. Unlike renderers that process sensor data, visualizers are meant for fast, interactive feedback.
+
+You can use any visualizer regardless of your chosen physics engine or rendering backend.
+
+
+Overview
+--------
+
+Isaac Lab supports four visualizer backends, each optimized for different use cases:
+
+.. list-table:: Visualizer Comparison
+ :widths: 15 35 50
+ :header-rows: 1
+
+ * - Visualizer
+ - Best For
+ - Key Features
+ * - **Omniverse**
+ - High-fidelity, Isaac Sim integration
+ - USD, visual markers, live plots
+ * - **Newton**
+ - Fast iteration
+ - Low overhead, visual markers
+ * - **Rerun**
+ - Remote viewing, replay
+ - Webviewer, time scrubbing, recording export
+ * - **Viser**
+ - Web-based remote visualization, sharing, recording
+ - Warp-based rendering, browser-based, share URL
+
+
+*The following visualizers are shown training the Isaac-Velocity-Flat-Anymal-D-v0 environment.*
+
+.. figure:: ../_static/visualizers/ov_viz.jpg
+ :width: 100%
+ :alt: Omniverse Visualizer
+
+ Omniverse Visualizer
+
+.. figure:: ../_static/visualizers/newton_viz.jpg
+ :width: 100%
+ :alt: Newton Visualizer
+
+ Newton Visualizer
+
+.. figure:: ../_static/visualizers/rerun_viz.jpg
+ :width: 100%
+ :alt: Rerun Visualizer
+
+ Rerun Visualizer
+
+
+Quick Start
+-----------
+
+Launch visualizers from the command line with ``--visualizer`` (or ``--viz`` alias):
+
+.. code-block:: bash
+
+ # Launch all visualizers (comma-delimited list, no spaces)
+ python scripts/reinforcement_learning/rsl_rl/train.py --task Isaac-Cartpole-v0 --viz kit,newton,rerun
+
+ # Launch only the Newton visualizer
+ python scripts/reinforcement_learning/rsl_rl/train.py --task Isaac-Cartpole-v0 --viz newton
+
+ # Launch the Viser web-based visualizer
+ python scripts/reinforcement_learning/rsl_rl/train.py --task Isaac-Cartpole-v0 --viz viser
+
+
+To run in headless mode, omit the ``--viz`` argument:
+
+.. code-block:: bash
+
+ python scripts/reinforcement_learning/rsl_rl/train.py --task Isaac-Cartpole-v0
+
+.. note::
+
+ The ``--headless`` argument is deprecated.
+ For compatibility, ``--headless`` still takes precedence and disables all visualizers.
+
+
+.. _visualization-configuration:
+
+Configuration
+~~~~~~~~~~~~~
+
+Launching visualizers with the command line will use default visualizer configurations. Visualizer backends live in the ``isaaclab_visualizers`` package (e.g. ``source/isaaclab_visualizers/isaaclab_visualizers/kit``, ``newton``, ``rerun``, ``viser``).
+
+You can also configure custom visualizers in the code by defining ``VisualizerCfg`` instances for the ``SimulationCfg``, for example:
+
+.. code-block:: python
+
+ from isaaclab.sim import SimulationCfg
+ from isaaclab_visualizers.kit import KitVisualizerCfg
+ from isaaclab_visualizers.newton import NewtonVisualizerCfg
+ from isaaclab_visualizers.rerun import RerunVisualizerCfg
+ from isaaclab_visualizers.viser import ViserVisualizerCfg
+
+ sim_cfg = SimulationCfg(
+ visualizer_cfgs=[
+ KitVisualizerCfg(
+ # Omit create_viewport (default False) to use the active viewport; set
+ # create_viewport=True and optionally viewport_name to add a dedicated window.
+ eye=(0.0, 0.0, 20.0), # high top down view
+ lookat=(0.0, 0.0, 0.0),
+ ),
+ NewtonVisualizerCfg(
+ eye=(5.0, 5.0, 5.0), # closer quarter view
+ lookat=(0.0, 0.0, 0.0),
+ show_joints=True,
+ ),
+ RerunVisualizerCfg(
+ keep_historical_data=True,
+ keep_scalar_history=True,
+ record_to_rrd="my_training.rrd",
+ ),
+ ViserVisualizerCfg(
+ port=8080,
+ share=False,
+ ),
+ ]
+ )
+
+Resolution Rules (CLI + Config)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The effective visualizer mode is resolved from both CLI and ``SimulationCfg.visualizer_cfgs``:
+
+- ``--viz`` (alias: ``--visualizer``) uses comma-separated values (for example ``--viz kit,newton``).
+- If ``--viz`` is omitted, Isaac Lab falls back to ``SimulationCfg.visualizer_cfgs`` (see :ref:`visualization-configuration`).
+- ``--viz none`` explicitly disables all visualizers.
+- If ``--headless`` is passed, it overrides ``--viz`` and disables visualizers.
+
+For the migration-focused summary and deprecation context, see
+:doc:`/source/migration/migrating_to_isaaclab_3-0`.
+
+.. _visualization-common-modes:
+
+.. list-table:: Common modes
+ :header-rows: 1
+ :widths: 30 35 35
+
+ * - CLI args
+ - visualizer configs
+ - Effective behavior
+ * - no ``--viz``
+ - ``[]``
+ - Run headless.
+ * - ``--viz kit,newton``
+ - ``[]``
+ - Launch default Kit and default Newton visualizers.
+ * - ``--viz kit,newton``
+ - ``[NewtonVisualizerCfg(...), RerunVisualizerCfg(...)]``
+ - Launch default Kit and custom Newton; Rerun is not launched.
+ * - no ``--viz``
+ - ``[NewtonVisualizerCfg(...), RerunVisualizerCfg(...)]``
+ - Launch custom Newton and custom Rerun visualizers from config.
+ * - ``--viz none``
+ - ``[NewtonVisualizerCfg(...), RerunVisualizerCfg(...)]``
+ - Run headless with all visualizers disabled.
+ * - ``--headless``
+ - any
+ - Run headless with deprecation warning.
+ * - ``--headless --viz ``
+ - any
+ - Run headless; ``--headless`` takes precedence.
+
+Visualizer Backends
+-------------------
+
+Omniverse Visualizer
+~~~~~~~~~~~~~~~~~~~~
+
+**Main Features:**
+
+- Native USD stage integration
+- Visualization markers for debugging (arrows, frames, points, etc.)
+- Live plots for monitoring training metrics
+- Full Isaac Sim rendering capabilities and tooling
+
+**Core Configuration:**
+
+.. code-block:: python
+
+ from isaaclab_visualizers.kit import KitVisualizerCfg
+
+ visualizer_cfg = KitVisualizerCfg(
+ # Viewport: default is create_viewport=False (use active viewport).
+ # Set create_viewport=True to create a docked window; viewport_name=None uses the default name.
+ create_viewport=False,
+ dock_position="SAME",
+ window_width=1280,
+ window_height=720,
+
+ eye=(8.0, 8.0, 3.0),
+ lookat=(0.0, 0.0, 0.0),
+
+ enable_markers=True,
+ enable_live_plots=True,
+ )
+
+
+Newton Visualizer
+~~~~~~~~~~~~~~~~~
+
+**Main Features:**
+
+- Lightweight OpenGL rendering with low overhead
+- Visualization markers (joints, contacts, springs, COM)
+- Simulation and rendering pause controls
+- Adjustable update frequency for performance tuning
+- Some customizable rendering options (shadows, sky, wireframe)
+
+
+**Interactive Controls:**
+
+.. list-table::
+ :widths: 30 70
+ :header-rows: 1
+
+ * - Key/Input
+ - Action
+ * - **W, A, S, D** or **Arrow Keys**
+ - Forward / Left / Back / Right
+ * - **Q, E**
+ - Down / Up
+ * - **Left Click + Drag**
+ - Look around
+ * - **Mouse Scroll**
+ - Zoom in/out
+ * - **H**
+ - Toggle UI sidebar
+ * - **ESC**
+ - Exit viewer
+
+**Core Configuration:**
+
+.. code-block:: python
+
+ from isaaclab_visualizers.newton import NewtonVisualizerCfg
+
+ visualizer_cfg = NewtonVisualizerCfg(
+ # Window settings
+ window_width=1920, # Window width in pixels
+ window_height=1080, # Window height in pixels
+
+ # Camera settings
+ eye=(8.0, 8.0, 3.0), # Initial camera position (x, y, z)
+ lookat=(0.0, 0.0, 0.0), # Camera look-at target
+
+ # Performance tuning
+ update_frequency=1, # Update every N frames (1=every frame)
+
+ # Physics debug visualization
+ show_joints=False, # Show joint visualizations
+ show_contacts=False, # Show contact points and normals
+ show_springs=False, # Show spring constraints
+ show_com=False, # Show center of mass markers
+
+ # Rendering options
+ enable_shadows=True, # Enable shadow rendering
+ enable_sky=True, # Enable sky rendering
+ enable_wireframe=False, # Enable wireframe mode
+
+ # Color customization
+ background_color=(0.53, 0.81, 0.92), # Sky/background color (RGB [0,1])
+ ground_color=(0.18, 0.20, 0.25), # Ground plane color (RGB [0,1])
+ light_color=(1.0, 1.0, 1.0), # Directional light color (RGB [0,1])
+ )
+
+
+Rerun Visualizer
+~~~~~~~~~~~~~~~~
+
+**Main Features:**
+
+- Web viewer interface accessible from local or remote browser
+- Metadata logging and filtering
+- Recording to .rrd files for offline replay (.rrd files can be opened with ctrl+O from the web viewer)
+- Timeline scrubbing and playback controls of recordings
+
+**Core Configuration:**
+
+.. code-block:: python
+
+ from isaaclab_visualizers.rerun import RerunVisualizerCfg
+
+ visualizer_cfg = RerunVisualizerCfg(
+ # Server settings
+ app_id="isaaclab-simulation", # Application identifier for viewer
+ grpc_port=9876, # gRPC endpoint for logging SDK connection
+ web_port=9090, # Port for local web viewer (launched in browser)
+ bind_address="0.0.0.0", # Endpoint host formatting/reuse checks
+
+ # Camera settings
+ eye=(8.0, 8.0, 3.0), # Initial camera position (x, y, z)
+ lookat=(0.0, 0.0, 0.0), # Camera look-at target
+
+ # History settings
+ keep_historical_data=False, # Keep transforms for time scrubbing
+ keep_scalar_history=False, # Keep scalar/plot history
+
+ # Recording
+ record_to_rrd="recording.rrd", # Path to save .rrd file (None = no recording)
+ )
+
+Rerun startup uses the Python SDK through ``newton.viewer.ViewerRerun`` (no external ``rerun`` CLI process
+management). If ``grpc_port`` is already active, Isaac Lab reuses that server. If ``web_port`` is occupied while
+starting a new server, initialization fails with a clear port-conflict error.
+
+
+Viser Visualizer
+~~~~~~~~~~~~~~~~
+
+The `Viser `_ visualizer provides a **web-based** 3D viewer for Isaac Lab
+simulations powered by the Newton Warp renderer. It streams the simulation state to a local web
+server, allowing you to view and interact with the scene from any browser.
+
+**Key features:**
+
+- Browser-based visualization accessible at ``http://localhost:8080`` by default
+- Optional public share URL for remote viewing
+- Recording to ``.viser`` format for replay
+- Environment filtering to control which environments are rendered
+
+**Launch with Viser:**
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_env.py --viz viser
+
+**Configuration example:**
+
+.. code-block:: python
+
+ from isaaclab_visualizers.viser import ViserVisualizerCfg
+
+ visualizer_cfg = ViserVisualizerCfg(
+ port=8080,
+ open_browser=True,
+ label="Isaac Lab Simulation",
+ share=False,
+ max_worlds=64,
+ )
+
+**Configuration options:**
+
+- ``port`` (int, default ``8080``): Port of the local Viser web server.
+- ``open_browser`` (bool, default ``True``): Automatically open the viewer URL in a browser.
+- ``label`` (str or None, default ``"Isaac Lab Simulation"``): Page title shown in the viewer.
+- ``share`` (bool, default ``False``): Request a public share URL from Viser for remote viewing.
+- ``record_to_viser`` (str or None, default ``None``): Path to save a ``.viser`` recording file.
+- ``verbose`` (bool, default ``True``): Print viewer server startup information.
+- ``max_worlds`` (int or None, default ``None``): Maximum number of environments rendered.
+
+.. note::
+
+ The Viser visualizer does not currently support markers or live plots.
+
+
+Performance Note
+----------------
+
+To reduce overhead when visualizing large-scale environments, consider:
+
+- Using Newton instead of Omniverse or Rerun
+- Reducing window sizes
+- Lower update frequencies
+- Pausing visualizers while they are not being used
+
+
+Limitations
+-----------
+
+**Rerun Visualizer Performance**
+
+The Rerun web-based visualizer may experience performance issues or crashes when visualizing large-scale
+environments. For large-scale simulations, the Newton visualizer is recommended. Alternatively, to reduce load,
+the num of environments can be overwritten and decreased using ``--num_envs``:
+
+.. code-block:: bash
+
+ python scripts/reinforcement_learning/rsl_rl/train.py --task Isaac-Cartpole-v0 --viz rerun --num_envs 512
+
+
+**Rerun Visualizer FPS Control**
+
+The FPS control in the Rerun visualizer UI may not affect the visualization frame rate in all configurations.
+
+
+**Newton Visualizer Contact and Center of Mass Markers**
+
+Contact and center of mass markers are not yet supported in the Newton visualizer. This will be addressed in a future release.
+
+
+**Viser Visualizer Markers and Live Plots**
+
+The Viser visualizer does not currently support visualization markers or live plots. For these features, use the
+Omniverse or Newton visualizers.
+
+
+**Viser Visualizer Renderer Requirement**
+
+The Viser visualizer requires a Newton model, which is provided automatically by
+:class:`~isaaclab.physics.SceneDataProvider` regardless of the active physics backend or
+renderer. It is compatible with all rendering backends (RTX, Newton Warp, OVRTX).
+
+
+**Newton Visualizer CUDA/OpenGL Interoperability Warnings**
+
+On some system configurations, the Newton visualizer may display warnings about CUDA/OpenGL interoperability:
+
+.. code-block:: text
+
+ Warning: Could not get MSAA config, falling back to non-AA.
+ Warp CUDA error 999: unknown error (in function wp_cuda_graphics_register_gl_buffer)
+ Warp UserWarning: Could not register GL buffer since CUDA/OpenGL interoperability
+ is not available. Falling back to copy operations between the Warp array and the
+ OpenGL buffer.
+
+The visualizer will still function correctly but may experience reduced performance due to falling back to
+CPU copy operations instead of direct GPU memory sharing.
+
+
+**Newton Visualizer on Spark with Conda**
+
+When running the Newton visualizer on Spark inside a conda environment, conda-installed X11 libraries
+may conflict with the system libraries required by pyglet, causing the following error:
+
+.. code-block:: text
+
+ pyglet.window.xlib.XlibException: Could not create UTF8 text property
+
+To resolve this, remove the conflicting conda packages so that the system-provided libraries are used
+instead:
+
+.. code-block:: bash
+
+ conda remove --force xorg-libx11 libxcb
+
+
+See Also
+--------
+
+- :doc:`/source/overview/core-concepts/renderers` — renderer backends (RTX, Newton Warp, OVRTX)
+- :doc:`/source/overview/core-concepts/scene_data_providers` — how scene data flows from physics to visualizers
+- :doc:`/source/experimental-features/newton-physics-integration/index` — Newton physics integration guide
+- :doc:`/source/migration/migrating_to_isaaclab_3-0` — migration guide with ``--headless`` deprecation details
diff --git a/docs/source/how-to/add_own_library.rst b/docs/source/how-to/add_own_library.rst
index 8a0347d6597..d5aa8aa0515 100644
--- a/docs/source/how-to/add_own_library.rst
+++ b/docs/source/how-to/add_own_library.rst
@@ -6,8 +6,8 @@ Adding your own learning library
Isaac Lab comes pre-integrated with a number of libraries (such as RSL-RL, RL-Games, SKRL, Stable Baselines, etc.).
However, you may want to integrate your own library with Isaac Lab or use a different version of the libraries than
the one installed by Isaac Lab. This is possible as long as the library is available as Python package that supports
-the Python version used by the underlying simulator. For instance, if you are using Isaac Sim 4.0.0 onwards, you need
-to ensure that the library is available for Python 3.11.
+the Python version used by the underlying simulator. For instance, if you are using Isaac Sim 6.0.0 onwards, you need
+to ensure that the library is available for Python 3.12.
Using a different version of a library
--------------------------------------
diff --git a/docs/source/how-to/cloning.rst b/docs/source/how-to/cloning.rst
new file mode 100644
index 00000000000..bad0ff8a502
--- /dev/null
+++ b/docs/source/how-to/cloning.rst
@@ -0,0 +1,267 @@
+.. _cloning-environments:
+
+Cloning Environments
+====================
+
+.. currentmodule:: isaaclab
+
+Isaac Lab uses a **template-based cloning** system to efficiently replicate environments for
+parallel simulation. Instead of authoring each environment individually on the USD stage,
+you define a single template and let the cloner stamp out copies with optional per-environment
+variation.
+
+This guide covers the cloning API and how to customize environment creation.
+
+How Cloning Works
+-----------------
+
+The cloning pipeline has three stages:
+
+1. **Template authoring** -- You place one or more *prototype* prims under a template root
+ (default ``/World/template``). Each prototype is a variant of an asset (e.g., different robot
+ configurations or object meshes).
+
+2. **Clone plan** -- The cloner discovers prototypes, enumerates all possible combinations (one
+ per prototype group), and assigns a combination to each environment using a *strategy*.
+
+3. **Replication** -- The selected prototypes are replicated to per-environment prim paths via
+ USD spec copying and physics-backend-specific replication.
+
+Most users interact with cloning indirectly through
+:class:`~isaaclab.scene.InteractiveScene`, which calls
+:func:`~isaaclab.cloner.clone_from_template` during ``clone_environments()``.
+For advanced use cases, you can call the cloning utilities directly.
+
+
+Basic Usage
+-----------
+
+The simplest case is homogeneous cloning -- every environment gets the same assets:
+
+.. code-block:: python
+
+ from isaaclab.cloner import TemplateCloneCfg, clone_from_template
+ from isaaclab.sim import SimulationContext
+
+ sim = SimulationContext()
+ stage = sim.stage
+
+ # Spawn a single prototype under the template root using a spawner
+ import isaaclab.sim as sim_utils
+
+ spawn_cfg = sim_utils.UsdFileCfg(usd_path="path/to/robot.usd")
+ spawn_cfg.func("/World/template/Robot/proto_asset_0", spawn_cfg)
+
+ # Configure and clone
+ clone_cfg = TemplateCloneCfg(device=sim.cfg.device)
+ clone_from_template(stage, num_clones=128, template_clone_cfg=clone_cfg)
+
+This creates 128 environments at ``/World/envs/env_0`` through ``/World/envs/env_127``,
+each containing a copy of the robot.
+
+
+Configuration Reference
+-----------------------
+
+:class:`~isaaclab.cloner.TemplateCloneCfg` controls the cloning behavior:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 25 15 60
+
+ * - Field
+ - Default
+ - Description
+ * - ``template_root``
+ - ``"/World/template"``
+ - Root path under which prototype prims are authored.
+ * - ``template_prototype_identifier``
+ - ``"proto_asset"``
+ - Name prefix used to discover prototype prims. The cloner finds all prims whose
+ base name starts with this identifier (e.g., ``proto_asset_0``, ``proto_asset_1``).
+ * - ``clone_regex``
+ - ``"/World/envs/env_.*"``
+ - Destination path template. The ``.*`` is replaced with the environment index.
+ * - ``clone_usd``
+ - ``True``
+ - Whether to replicate USD prim specs to destination paths.
+ * - ``clone_physics``
+ - ``True``
+ - Whether to perform physics-backend-specific replication.
+ * - ``physics_clone_fn``
+ - ``None``
+ - Backend-specific physics replication function. Set automatically by
+ :class:`~isaaclab.scene.InteractiveScene`.
+ * - ``visualizer_clone_fn``
+ - ``None``
+ - Optional callback to prebuild visualizer artifacts from the clone plan.
+ * - ``clone_strategy``
+ - ``random``
+ - Strategy function for assigning prototypes to environments. See
+ :ref:`cloning-strategies` below.
+ * - ``device``
+ - ``"cpu"``
+ - Torch device for mapping buffers.
+ * - ``clone_in_fabric``
+ - ``False``
+ - Enable cloning in Fabric (PhysX only, experimental).
+
+
+.. _cloning-strategies:
+
+Cloning Strategies
+------------------
+
+When multiple prototypes exist in the template, the **clone strategy** determines which
+prototype each environment receives. Isaac Lab provides two built-in strategies:
+
+**Random** (default)
+
+Each environment receives a randomly sampled prototype combination:
+
+.. code-block:: python
+
+ from isaaclab.cloner import TemplateCloneCfg, random
+
+ clone_cfg = TemplateCloneCfg(
+ clone_strategy=random,
+ device="cuda:0",
+ )
+
+This is useful for domain randomization and curriculum learning where you want diverse
+environments.
+
+**Sequential**
+
+Prototypes are assigned in round-robin order (``env_id % num_combinations``):
+
+.. code-block:: python
+
+ from isaaclab.cloner import TemplateCloneCfg, sequential
+
+ clone_cfg = TemplateCloneCfg(
+ clone_strategy=sequential,
+ device="cuda:0",
+ )
+
+This produces a deterministic, balanced distribution -- useful for reproducible experiments.
+
+**Custom strategies** can be written as any callable matching the signature
+``(combinations: torch.Tensor, num_clones: int, device: str) -> torch.Tensor``,
+where ``combinations`` has shape ``(num_combinations, num_groups)`` and the return
+value has shape ``(num_clones, num_groups)``.
+
+
+Heterogeneous Environments
+--------------------------
+
+To create environments with different assets, place multiple prototypes under the same
+group in the template:
+
+.. code-block:: python
+
+ # Spawn three different object prototypes under the same group
+ import isaaclab.sim as sim_utils
+
+ sim_utils.CuboidCfg(size=(0.5, 0.5, 0.5)).func(
+ "/World/template/Object/proto_asset_0", sim_utils.CuboidCfg(size=(0.5, 0.5, 0.5))
+ )
+ sim_utils.ConeCfg(radius=0.25, height=0.5).func(
+ "/World/template/Object/proto_asset_1", sim_utils.ConeCfg(radius=0.25, height=0.5)
+ )
+ sim_utils.SphereCfg(radius=0.25).func(
+ "/World/template/Object/proto_asset_2", sim_utils.SphereCfg(radius=0.25)
+ )
+
+ clone_cfg = TemplateCloneCfg(
+ clone_strategy=sequential,
+ device="cuda:0",
+ )
+ clone_from_template(stage, num_clones=128, template_clone_cfg=clone_cfg)
+ # env_0 gets Cuboid, env_1 gets Cone, env_2 gets Sphere, env_3 gets Cuboid, ...
+
+When prototypes span multiple groups (e.g., different robots *and* different objects),
+the cloner enumerates the Cartesian product of all groups and assigns combinations
+using the selected strategy.
+
+
+Environment Positioning
+-----------------------
+
+Environments are arranged in a grid layout using :func:`~isaaclab.cloner.grid_transforms`:
+
+.. code-block:: python
+
+ from isaaclab.cloner import grid_transforms
+
+ positions, orientations = grid_transforms(
+ N=128, # number of environments
+ spacing=2.0, # meters between neighbors
+ up_axis="Z",
+ device="cuda:0",
+ )
+ # positions: (128, 3), orientations: (128, 4) identity quaternions
+
+:class:`~isaaclab.scene.InteractiveScene` calls this automatically based on
+``InteractiveSceneCfg.env_spacing``.
+
+
+Collision Filtering
+-------------------
+
+By default, assets in different environments can collide with each other. To prevent
+cross-environment collisions (the typical setup for parallel RL), use
+:func:`~isaaclab.cloner.filter_collisions`:
+
+.. code-block:: python
+
+ from isaaclab.cloner import filter_collisions
+
+ filter_collisions(
+ stage=stage,
+ physicsscene_path="/physicsScene",
+ collision_root_path="/World/collisions",
+ prim_paths=[f"/World/envs/env_{i}" for i in range(128)],
+ global_paths=["/World/defaultGroundPlane"], # collides with all envs
+ )
+
+.. note::
+
+ Collision filtering uses PhysX collision groups and is only applicable to the PhysX backend.
+ The Newton backend handles per-environment isolation through its world system.
+
+
+Physics Backend Replication
+---------------------------
+
+Each physics backend has its own replication function that registers cloned prims with the
+physics engine:
+
+- **PhysX**: :func:`~isaaclab_physx.cloner.physx_replicate` -- Uses the PhysX replicator
+ interface for fast physics body registration.
+- **Newton**: :func:`~isaaclab_newton.cloner.newton_physics_replicate` -- Builds a Newton
+ ``ModelBuilder`` with per-environment worlds, supporting heterogeneous spawning.
+
+These functions are set automatically when using :class:`~isaaclab.scene.InteractiveScene`.
+For direct usage:
+
+.. code-block:: python
+
+ import torch
+ from isaaclab_physx.cloner import physx_replicate
+
+ physx_replicate(
+ stage=stage,
+ sources=["/World/envs/env_0/Robot"],
+ destinations=["/World/envs/env_{}/Robot"], # {} is replaced with env index
+ env_ids=torch.arange(128),
+ mapping=torch.ones(1, 128, dtype=torch.bool),
+ device="cuda:0",
+ )
+
+
+See Also
+--------
+
+- :doc:`multi_asset_spawning` -- spawning different assets per environment
+- :doc:`optimize_stage_creation` -- fabric cloning and stage-in-memory optimizations
diff --git a/docs/source/how-to/cloudxr_teleoperation.rst b/docs/source/how-to/cloudxr_teleoperation.rst
index e13b76305dc..12be66a2617 100644
--- a/docs/source/how-to/cloudxr_teleoperation.rst
+++ b/docs/source/how-to/cloudxr_teleoperation.rst
@@ -1,270 +1,144 @@
.. _cloudxr-teleoperation:
-Setting up CloudXR Teleoperation
-================================
+Setting up Isaac Teleop with CloudXR
+=====================================
.. currentmodule:: isaaclab
-`NVIDIA CloudXR`_ enables seamless, high-fidelity immersive streaming to extended reality (XR)
-devices over any network.
+`Isaac Teleop `_ (https://github.com/NVIDIA/IsaacTeleop) is the unified framework for high-fidelity
+teleoperation in Isaac Lab. It provides standardized device interfaces, a flexible retargeting
+pipeline, and bundled `NVIDIA CloudXR`_ streaming for immersive XR-based teleoperation.
-Isaac Lab developers can use CloudXR with Isaac Lab to build teleoperation workflows that require
-immersive XR rendering for increased spatial acuity and/or hand tracking for teleoperation of
-dextrous robots.
-
-In these workflows, Isaac Lab renders and submits stereo views of the robot simulation to CloudXR,
-which then encodes and streams the rendered views to a compatible XR device in realtime using a
-low-latency, GPU-accelerated pipeline. Control inputs such as hand tracking data are sent from the
-XR device back to Isaac Lab through CloudXR, where they can be used to control the robot.
-
-This guide explains how to use CloudXR and `Apple Vision Pro`_ for immersive streaming and
-teleoperation in Isaac Lab.
-
-.. note::
-
- See :ref:`manus-vive-handtracking` for more information on supported hand-tracking peripherals.
-
-.. note::
-
- **Meta Quest 3 and Pico 4 Ultra Support (Early Access)**
-
- Meta Quest 3 and Pico 4 Ultra are now supported via the `CloudXR Early Access program`_.
- Join the program by mentioning isaac use cases. Once approved, you'll receive email to set up NGC,
- then download `CloudXR.js with Isaac Teleop samples`_ and follow its guide.
- Pico 4 Ultra must use HTTPS mode (see NGC documentation for details). General availability
- will be provided in a future version of Isaac Lab.
-
-.. _`CloudXR Early Access program`: https://developer.nvidia.com/cloudxr-sdk-early-access-program/join
-.. _`CloudXR.js with Isaac Teleop samples`: https://catalog.ngc.nvidia.com/orgs/nvidia/resources/cloudxr-js-early-access?version=6.0.0-beta
-
-Overview
---------
-
-Using CloudXR with Isaac Lab involves the following components:
-
-* **Isaac Lab** is used to simulate the robot environment and apply control data received from the
- teleoperator.
-
-* The **NVIDIA CloudXR Runtime** runs on the Isaac Lab workstation in a Docker container, and streams
- the virtual simulation from Isaac Lab to compatible XR devices.
-
-* The **Isaac XR Teleop Sample Client** is a sample app for Apple Vision Pro which enables
- immersive streaming and teleoperation of an Isaac Lab simulation using CloudXR.
-
-This guide will walk you through how to:
-
-* :ref:`run-isaac-lab-with-the-cloudxr-runtime`
-
-* :ref:`use-apple-vision-pro`, including how to :ref:`build-apple-vision-pro`,
- :ref:`teleoperate-apple-vision-pro`, and :ref:`manus-vive-handtracking`.
-
-* :ref:`develop-xr-isaac-lab`, including how to :ref:`run-isaac-lab-with-xr`,
- :ref:`configure-scene-placement`, and :ref:`optimize-xr-performance`.
-
-* :ref:`control-robot-with-xr`, including the :ref:`openxr-device-architecture`,
- :ref:`control-robot-with-xr-retargeters`, and how to implement :ref:`control-robot-with-xr-callbacks`.
-
-As well as :ref:`xr-known-issues`.
+This guide walks you through setting up CloudXR, connecting an XR device, and running your first
+teleoperation session. For additional details see the `Isaac Teleop Quick Start
+`_.
+.. tip::
-System Requirements
--------------------
+ For architecture details, retargeting pipelines, control scheme recommendations, and how to
+ add new embodiments or devices, see the :ref:`isaac-teleop-feature` page.
-Prior to using CloudXR with Isaac Lab, please review the following system requirements:
- * Isaac Lab workstation
+Prerequisites
+-------------
- * Ubuntu 22.04 or Ubuntu 24.04
- * Hardware requirements to sustain 45 FPS with a 120Hz physics simulation:
- * CPU: 16-Cores AMD Ryzen Threadripper Pro 5955WX or higher
- * Memory: 64GB RAM
- * GPU: 1x RTX PRO 6000 GPUs (or equivalent e.g. 1x RTX 5090) or higher
- * For details on driver requirements, please see the `Technical Requirements `_ guide
- * `Docker`_ 26.0.0+, `Docker Compose`_ 2.25.0+, and the `NVIDIA Container Toolkit`_. Refer to
- the Isaac Lab :ref:`deployment-docker` for how to install.
+* **Isaac Lab** installed and working (see :ref:`isaaclab-installation-root`).
- * Apple Vision Pro
+* **Isaac Lab workstation**
- * visionOS 26
- * Apple M3 Pro chip with an 11-core CPU with at least 5 performance cores and 6 efficiency cores
- * 16GB unified memory
- * 256 GB SSD
+ * Ubuntu 22.04 or Ubuntu 24.04
+ * CPU: x86_64 (ARM support coming soon)
+ * GPU: NVIDIA GPU required. For 45 FPS with 120 Hz physics:
- * Apple Silicon based Mac (for building the Isaac XR Teleop Sample Client App for Apple Vision Pro
- with Xcode)
+ * CPU: AMD Ryzen Threadripper 7960x or higher
+ * GPU: 1x RTX PRO 6000 (or equivalent, e.g. 1x RTX 5090) or higher
+ * Memory: 64 GB RAM
- * macOS Sequoia 15.6 or later
- * Xcode 26.0
+ * For driver requirements see the `Technical Requirements `_ guide.
+ * Python 3.12 or newer
+ * CUDA 12.8 (recommended)
+ * NVIDIA Driver 580.95.05 (recommended)
- * Wifi 6 capable router
+* **Wifi 6 capable router**
- * A strong wireless connection is essential for a high-quality streaming experience. Refer to the
- requirements of `Omniverse Spatial Streaming`_ for more details.
- * We recommend using a dedicated router, as concurrent usage will degrade quality
- * The Apple Vision Pro and Isaac Lab workstation must be IP-reachable from one another (note:
- many institutional wireless networks will prevent devices from reaching each other, resulting
- in the Apple Vision Pro being unable to find the Isaac Lab workstation on the network)
+ * A strong wireless connection is essential for a high-quality streaming experience. Refer to
+ the `CloudXR Network Setup`_ guide for detailed requirements, router configuration, and
+ troubleshooting.
+ * We recommend a dedicated router; concurrent usage will degrade quality.
+ * The XR device and Isaac Lab workstation must be IP-reachable from one another. Many
+ institutional wireless networks prevent device-to-device connectivity.
.. note::
- If you are using DGX Spark, check `DGX Spark Limitations `_ for compatibility.
-
-
-.. _`Omniverse Spatial Streaming`: https://docs.omniverse.nvidia.com/avp/latest/setup-network.html
-
-
-.. _run-isaac-lab-with-the-cloudxr-runtime:
-
-Run Isaac Lab with the CloudXR Runtime
---------------------------------------
-
-The CloudXR Runtime runs in a Docker container on your Isaac Lab workstation, and is responsible for
-streaming the Isaac Lab simulation to a compatible XR device.
-
-Ensure that `Docker`_, `Docker Compose`_, and the `NVIDIA Container Toolkit`_ are installed on your
-Isaac Lab workstation as described in the Isaac Lab :ref:`deployment-docker`.
-
-Also ensure that your firewall allows connections to the ports used by CloudXR by running:
-
-.. code:: bash
-
- sudo ufw allow 47998:48000,48005,48008,48012/udp
- sudo ufw allow 48010/tcp
-There are two options to run the CloudXR Runtime Docker container:
+ Teleoperation is not currently supported on DGX Spark.
-.. dropdown:: Option 1 (Recommended): Use Docker Compose to run the Isaac Lab and CloudXR Runtime
- containers together
- :open:
- On your Isaac Lab workstation:
+.. _install-isaac-teleop:
- #. From the root of the Isaac Lab repository, start the Isaac Lab and CloudXR Runtime containers
- using the Isaac Lab ``container.py`` script
+Install Isaac Teleop
+--------------------
- .. code:: bash
+#. Install the system libraries required by the CloudXR runtime:
- ./docker/container.py start \
- --files docker-compose.cloudxr-runtime.patch.yaml \
- --env-file .env.cloudxr-runtime
-
- If prompted, elect to activate X11 forwarding, which is necessary to see the Isaac Sim UI.
-
- .. note::
-
- The ``container.py`` script is a thin wrapper around Docker Compose. The additional
- ``--files`` and ``--env-file`` arguments augment the base Docker Compose configuration to
- additionally run the CloudXR Runtime
-
- For more details on ``container.py`` and running Isaac Lab with Docker Compose, see the
- :ref:`deployment-docker`.
-
- #. Enter the Isaac Lab base container with:
-
- .. code:: bash
-
- ./docker/container.py enter base
-
- From within the Isaac Lab base container, you can run Isaac Lab scripts that use XR.
-
- #. Run an example teleop task with:
-
- .. code:: bash
-
- ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
- --task Isaac-PickPlace-GR1T2-Abs-v0 \
- --teleop_device handtracking \
- --enable_pinocchio
-
- #. You'll want to leave the container running for the next steps. But once you are finished, you can
- stop the containers with:
-
- .. code:: bash
-
- ./docker/container.py stop \
- --files docker-compose.cloudxr-runtime.patch.yaml \
- --env-file .env.cloudxr-runtime
-
- .. tip::
-
- If you encounter issues on restart, you can run the following command to clean up orphaned
- containers:
-
- .. code:: bash
-
- docker system prune -f
-
-.. dropdown:: Option 2: Run Isaac Lab as a local process and CloudXR Runtime container with Docker
+ .. code-block:: bash
- Isaac Lab can be run as a local process that connects to the CloudXR Runtime Docker container.
- However, this method requires manually specifying a shared directory for communication between
- the Isaac Lab instance and the CloudXR Runtime.
+ sudo apt-get update && sudo apt-get install -y libvulkan1 libbsd0
- On your Isaac Lab workstation:
+ The CloudXR runtime links against Vulkan at runtime. If your system already has the
+ NVIDIA driver installed, ``libvulkan1`` may already be present.
- #. From the root of the Isaac Lab repository, create a local folder for temporary cache files:
+#. ``isaacteleop`` is installed automatically as a dependency of ``isaaclab_teleop``.
+ No separate pip install step is required. For building from source or plugin
+ development, see the `Isaac Teleop GitHub `_.
- .. code:: bash
+#. Configure the firewall to allow CloudXR traffic. The required ports depend on the
+ client type.
- mkdir -p $(pwd)/openxr
+ **For Apple native clients** (CloudXR Framework):
- #. Start the CloudXR Runtime, mounting the directory created above to the ``/openxr`` directory in
- the container:
+ .. code-block:: bash
- .. code:: bash
+ # Signaling (use one based on connection mode)
+ sudo ufw allow 48010/tcp # Standard mode
+ sudo ufw allow 48322/tcp # Secure mode
+ # Video
+ sudo ufw allow 47998/udp
+ sudo ufw allow 48005/udp
+ sudo ufw allow 48008/udp
+ sudo ufw allow 48012/udp
+ # Input
+ sudo ufw allow 47999/udp
+ # Audio
+ sudo ufw allow 48000/udp
+ sudo ufw allow 48002/udp
+
+ **For web clients** (CloudXR.js via the built-in WSS proxy):
- docker run -it --rm --name cloudxr-runtime \
- --user $(id -u):$(id -g) \
- --gpus=all \
- -e "ACCEPT_EULA=Y" \
- --mount type=bind,src=$(pwd)/openxr,dst=/openxr \
- -p 48010:48010 \
- -p 47998:47998/udp \
- -p 47999:47999/udp \
- -p 48000:48000/udp \
- -p 48005:48005/udp \
- -p 48008:48008/udp \
- -p 48012:48012/udp \
- nvcr.io/nvidia/cloudxr-runtime:5.0.1
+ .. code-block:: bash
- .. note::
- If you choose a particular GPU instead of ``all``, you need to make sure Isaac Lab also runs
- on that GPU.
+ sudo ufw allow 49100/tcp # Signaling (WebRTC)
+ sudo ufw allow 47998/udp # Media stream
+ sudo ufw allow 48322/tcp # WSS proxy (HTTPS)
- .. tip::
+ For full network requirements and Windows firewall instructions, see the
+ `CloudXR Network Setup `__
+ documentation.
- If you encounter issues on running cloudxr-runtime container, you can run the following
- command to clean up the orphaned container:
- .. code:: bash
+.. _run-isaac-lab-with-the-cloudxr-runtime:
- docker stop cloudxr-runtime
- docker rm cloudxr-runtime
+Run Isaac Lab with CloudXR
+--------------------------
- #. In a new terminal where you intend to run Isaac Lab, export the following environment
- variables, which reference the directory created above:
+The CloudXR runtime launches automatically when a teleop script is started. No separate
+terminal or ``source`` step is needed. Launch a teleoperation script directly:
- .. code:: bash
+.. code-block:: bash
- export XDG_RUNTIME_DIR=$(pwd)/openxr/run
- export XR_RUNTIME_JSON=$(pwd)/openxr/share/openxr/1/openxr_cloudxr.json
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit \
+ --xr
- You can now run Isaac Lab scripts that use XR.
+To switch the CloudXR device profile at launch time (e.g. from Quest to Apple Vision Pro),
+use the ``--cloudxr_env`` flag:
- #. Run an example teleop task with:
+.. code-block:: bash
- .. code:: bash
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit \
+ --xr \
+ --cloudxr_env avp
- ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
- --task Isaac-PickPlace-GR1T2-Abs-v0 \
- --teleop_device handtracking \
- --enable_pinocchio
+For details on the shipped ``.env`` profiles and how to customise them, see
+:ref:`isaac-teleop-cloudxr-profiles` in the feature guide.
-With Isaac Lab and the CloudXR Runtime running:
+Then in the Isaac Sim UI:
-#. In the Isaac Sim UI: locate the Panel named **AR** and choose the following options:
+#. Locate the panel named **AR** and choose the following options:
* Selected Output Plugin: **OpenXR**
-
* OpenXR Runtime: **System OpenXR Runtime**
.. figure:: ../_static/setup/cloudxr_ar_panel.jpg
@@ -272,861 +146,301 @@ With Isaac Lab and the CloudXR Runtime running:
:figwidth: 50%
:alt: Isaac Sim UI: AR Panel
- .. note::
- Isaac Sim lets you choose from several OpenXR runtime options:
-
- * **System OpenXR Runtime**: Use a runtime installed outside of Isaac Lab, such as the CloudXR Runtime set up via Docker in this tutorial.
-
- * **CloudXR Runtime (5.0)**: Use the built-in CloudXR Runtime.
-
- * **Custom**: Allow you to specify and run any custom OpenXR Runtime of your choice.
-
#. Click **Start AR**.
-The Viewport should show two eyes being rendered, and you should see the status "AR profile is
-active".
+The viewport should show two eyes being rendered and the status "AR profile is active".
.. figure:: ../_static/setup/cloudxr_viewport.jpg
:align: center
:figwidth: 100%
:alt: Isaac Lab viewport rendering two eyes
-Isaac Lab is now ready to receive connections from a CloudXR client. The next sections will walk
-you through building and connecting a CloudXR client.
-
-.. admonition:: Learn More about Teleoperation and Imitation Learning in Isaac Lab
-
- To learn more about the Isaac Lab teleoperation scripts, and how to build new teleoperation and
- imitation learning workflows in Isaac Lab, see :ref:`teleoperation-imitation-learning`.
-
-
-.. _use-apple-vision-pro:
-
-Use Apple Vision Pro for Teleoperation
---------------------------------------
-
-This section will walk you through building and installing the Isaac XR Teleop Sample Client for
-Apple Vision Pro, connecting to Isaac Lab, and teleoperating a simulated robot.
-
-
-.. _build-apple-vision-pro:
-
-Build and Install the Isaac XR Teleop Sample Client App for Apple Vision Pro
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-On your Mac:
-
-#. Clone the `Isaac XR Teleop Sample Client`_ GitHub repository:
-
- .. code-block:: bash
-
- git clone git@github.com:isaac-sim/isaac-xr-teleop-sample-client-apple.git
-
-#. Check out the App version that matches your Isaac Lab version:
-
- +-------------------+---------------------+
- | Isaac Lab Version | Client App Version |
- +-------------------+---------------------+
- | 2.3 | v2.3.0 |
- +-------------------+---------------------+
- | 2.2 | v2.2.0 |
- +-------------------+---------------------+
- | 2.1 | v1.0.0 |
- +-------------------+---------------------+
-
- .. code-block:: bash
-
- git checkout
-
-#. Follow the README in the repository to build and install the app on your Apple Vision Pro.
-
-
-.. _teleoperate-apple-vision-pro:
-
-Teleoperate an Isaac Lab Robot with Apple Vision Pro
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-With the Isaac XR Teleop Sample Client installed on your Apple Vision Pro, you are ready to connect
-to Isaac Lab.
-
-.. tip::
-
- **Before wearing the headset**, you can first verify connectivity from your Mac:
+Isaac Lab is now ready to receive connections from a CloudXR client.
- .. code:: bash
- # Test signaling port (replace with your workstation IP)
- nc -vz 48010
+.. _connect-xr-device:
- Expected output: ``Connection to port 48010 [tcp/*] succeeded!``
+Connect an XR Device
+--------------------
- If the connection fails, check that the runtime container is running (``docker ps``) and no stale
- runtime container is blocking ports.
+Isaac Teleop supports several XR headsets. You only need **one** of the devices below --
+choose the tab that matches your hardware.
-On your Isaac Lab workstation:
+.. tab-set::
-#. Ensure that Isaac Lab and CloudXR are both running as described in
- :ref:`run-isaac-lab-with-the-cloudxr-runtime`, including starting Isaac Lab with a script that
- supports teleoperation. For example:
+ .. tab-item:: Meta Quest 3 / Pico 4 Ultra
+ :selected:
- .. code-block:: bash
+ .. _connect-quest-pico:
- ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
- --task Isaac-PickPlace-GR1T2-Abs-v0 \
- --teleop_device handtracking \
- --enable_pinocchio
+ Meta Quest 3 and Pico 4 Ultra connect to Isaac Lab via the
+ `CloudXR.js `_
+ WebXR client. The built-in environments default to the ``cloudxrjs-cloudxr.env`` profile
+ (``auto-webrtc``), which is the correct setting for these devices.
- .. note::
- Recall that the script above should either be run within the Isaac Lab Docker container
- (Option 1, recommended), or with environment variables configured to a directory shared by a
- running CloudXR Runtime Docker container (Option 2).
+ .. note::
-#. Locate the Panel named **AR**.
+ Pico 4 Ultra requires Pico OS 15.4.4U or later and must use HTTPS mode.
-#. Click **Start AR** and ensure that the Viewport shows two eyes being rendered.
+ #. Launch the teleop script as shown in
+ :ref:`run-isaac-lab-with-the-cloudxr-runtime`. The CloudXR runtime and WSS proxy
+ start automatically.
-Back on your Apple Vision Pro:
+ #. Open the browser on your headset and navigate to the hosted CloudXR.js client:
+ ``_.
-#. Open the Isaac XR Teleop Sample Client. You should see a UI window:
+ .. tip::
- .. figure:: ../_static/setup/cloudxr_avp_connect_ui.jpg
- :align: center
- :figwidth: 50%
- :alt: Isaac Sim UI: AR Panel
+ For rapid development, you can test the CloudXR.js client on a desktop browser
+ before deploying to headsets.
-#. Enter the IP address of your Isaac Lab workstation.
+ #. Enter the IP address of your Isaac Lab host machine in the **Server IP** field.
- .. note::
- The Apple Vision Pro and Isaac Lab machine must be IP-reachable from one another.
+ #. Because the WSS proxy uses a self-signed certificate, you must accept it before
+ connecting. Click the **Click https://:48322/ to accept cert** link that
+ appears on the page.
- We recommend using a dedicated Wifi 6 router for this process, as many institutional wireless
- networks will prevent devices from reaching each other, resulting in the Apple Vision Pro
- being unable to find the Isaac Lab workstation on the network.
+ .. image:: ../_static/setup/cloudxr_accept_cert.jpg
+ :alt: CloudXR.js certificate acceptance link
+ :align: center
+ :width: 400
-#. Click **Connect**.
+ A new tab opens with a **"Your connection is not private"** warning. Click
+ **Advanced**, then click **Proceed to (unsafe)**.
- The first time you attempt to connect, you may need to allow the application access to
- permissions such as hand tracking and local network usage, and then connect again.
+ .. image:: ../_static/setup/cloudxr_accept_cert_not_private.jpg
+ :alt: Browser privacy warning for self-signed certificate
+ :align: center
+ :width: 500
-#. After a brief period, you should see the Isaac Lab simulation rendered in the Apple Vision Pro,
- as well as a set of controls for teleoperation.
+ The browser will show a **"Certificate Accepted"** page confirming the certificate
+ has been accepted. Close this tab and return to the CloudXR.js client page.
- .. figure:: ../_static/setup/cloudxr_avp_teleop_ui.jpg
- :align: center
- :figwidth: 50%
- :alt: Isaac Sim UI: AR Panel
+ .. image:: ../_static/setup/cloudxr_accept_cert_accepted.jpg
+ :alt: Certificate accepted confirmation page
+ :align: center
+ :width: 400
-#. Click **Play** to begin teleoperating the simulated robot. The robot motion should now be
- directed by your hand movements.
+ #. Click **Connect** to begin teleoperation.
- You may repeatedly **Play**, **Stop**, and **Reset** the teleoperation session using the UI
- controls.
+ For advanced configuration, troubleshooting, and additional details, see the
+ `CloudXR.js User Guide
+ `_.
- .. tip::
- For teleoperation tasks that require bimanual manipulation, visionOS accessibility features
- can be used to control teleoperation without the use of hand gestures. For example, in order
- to enable voice control of the UI:
+ .. tab-item:: Apple Vision Pro
- #. In **Settings** > **Accessibility** > **Voice Control**, Turn on **Voice Control**
+ .. _use-apple-vision-pro:
- #. In **Settings** > **Accessibility** > **Voice Control** > **Commands** > **Basic
- Navigation** > Turn on **- **
+ Apple Vision Pro connects to Isaac Lab via the native `Isaac XR Teleop Sample Client`_ app.
- #. Now you can say "Play", "Stop", and "Reset" to control teleoperation while the app is
- connected.
+ .. important::
-#. Teleoperate the simulated robot by moving your hands.
+ Apple Vision Pro requires the ``auto-native`` device profile. Pass the ``avp``
+ shorthand when launching the teleop script:
- .. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/cloudxr_bimanual_teleop.gif
- :align: center
- :alt: Isaac Lab teleoperation of a bimanual dexterous robot with CloudXR
-
- .. note::
-
- The red dots represent the tracked position of the hand joints. Latency or offset between the
- motion of the dots and the robot may be caused by the limits of the robot joints and/or robot
- controller.
-
- .. note::
- When the inverse kinematics solver fails to find a valid solution, an error message will appear
- in the XR device display. To recover from this state, click the **Reset** button to return
- the robot to its original pose and continue teleoperation.
+ .. code-block:: bash
- .. figure:: ../_static/setup/cloudxr_avp_ik_error.jpg
- :align: center
- :figwidth: 80%
- :alt: IK Error Message Display in XR Device
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit --xr \
+ --cloudxr_env avp
+ See :ref:`isaac-teleop-cloudxr-profiles` for details on the shipped profiles.
+ .. _build-apple-vision-pro:
-#. When you are finished with the example, click **Disconnect** to disconnect from Isaac Lab.
+ .. rubric:: Build and Install the Client App
-.. admonition:: Learn More about Teleoperation and Imitation Learning in Isaac Lab
+ Requirements:
- See :ref:`teleoperation-imitation-learning` to learn how to record teleoperated demonstrations
- and build teleoperation and imitation learning workflows with Isaac Lab.
+ * Apple Vision Pro with visionOS 26, Apple M3 Pro chip (11-core CPU), 16 GB unified memory
+ * Apple Silicon Mac with macOS Sequoia 15.6+ and Xcode 26.0
+ On your Mac:
-.. _manus-vive-handtracking:
-
-Manus + Vive Hand Tracking
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+ #. Clone the `Isaac XR Teleop Sample Client`_ repository:
-Manus gloves and HTC Vive trackers can provide hand tracking when optical hand tracking from a headset is occluded.
-This setup expects Manus gloves with a Manus SDK license and Vive trackers attached to the gloves.
-Requires Isaac Sim 5.1 or later.
+ .. code-block:: bash
-Run the teleoperation example with Manus + Vive tracking:
+ git clone git@github.com:isaac-sim/isaac-xr-teleop-sample-client-apple.git
-.. dropdown:: Installation instructions
- :open:
+ #. Check out the version that matches your Isaac Lab version:
- Vive tracker integration is provided through the libsurvive library.
+ +-------------------+---------------------+
+ | Isaac Lab Version | Client App Version |
+ +-------------------+---------------------+
+ | 3.0 | v3.0.0 |
+ +-------------------+---------------------+
+ | 2.3 | v2.3.0 |
+ +-------------------+---------------------+
- To install, clone the repository, build the python package, and install the required udev rules.
- In your Isaac Lab virtual environment, run the following commands:
+ .. code-block:: bash
- .. code-block:: bash
+ git checkout
- git clone https://github.com/collabora/libsurvive.git
- cd libsurvive
- pip install scikit-build
- python setup.py install
+ #. Follow the README in the repository to build and install the app on your Apple Vision
+ Pro.
- sudo cp ./useful_files/81-vive.rules /etc/udev/rules.d/
- sudo udevadm control --reload-rules && sudo udevadm trigger
+ .. _teleoperate-apple-vision-pro:
+ .. rubric:: Teleoperate with Apple Vision Pro
- The Manus integration is provided through the Isaac Sim teleoperation input plugin framework.
- Install the plugin by following the build and installation steps in `isaac-teleop-device-plugins `_.
+ .. tip::
-In the same terminal from which you will launch Isaac Lab, set:
+ **Before wearing the headset**, verify connectivity from your Mac:
-.. code-block:: bash
+ .. code:: bash
- export ISAACSIM_HANDTRACKER_LIB=/build-manus-default/lib/libIsaacSimManusHandTracking.so
+ nc -vz 48010
-Once the plugin is installed, run the teleoperation example:
+ Expected output: ``Connection to port 48010 [tcp/*] succeeded!``
-.. code-block:: bash
+ On your Isaac Lab workstation, ensure Isaac Lab and CloudXR are running as described in
+ :ref:`run-isaac-lab-with-the-cloudxr-runtime`.
- ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
- --task Isaac-PickPlace-GR1T2-Abs-v0 \
- --teleop_device manusvive \
- --xr \
- --enable_pinocchio
+ On your Apple Vision Pro:
-The recommended workflow, is to start Isaac Lab, click **Start AR**, and then put on the Manus gloves, vive trackers, and
-headset. Once you are ready to begin the session, use voice commands to launch the Isaac XR teleop sample client and
-connect to Isaac Lab.
+ #. Open the Isaac XR Teleop Sample Client.
-Isaac Lab automatically calibrates the Vive trackers using wrist pose data from the Apple Vision Pro during the initial
-frames of the session. If calibration fails, for example, if the red dots do not accurately follow the teleoperator's
-hands, restart Isaac Lab and begin with your hands in a palm-up position to improve calibration reliability.
+ .. figure:: ../_static/setup/cloudxr_avp_connect_ui.jpg
+ :align: center
+ :figwidth: 50%
+ :alt: Apple Vision Pro connect UI
-For optimal performance, position the lighthouse above the hands, tilted slightly downward.
-Ensure the lighthouse remains stable; a stand is recommended to prevent wobbling.
+ #. Enter the IP address of your Isaac Lab workstation and click **Connect**.
-Ensure that while the task is being teleoperated, the hands remain stable and visible to the lighthouse at all times.
-See: `Installing the Base Stations `_
-and `Tips for Setting Up the Base Stations `_
+ .. note::
-.. note::
+ The Apple Vision Pro and workstation must be IP-reachable from one another. We
+ recommend a dedicated Wifi 6 router.
- On first launch of the Manus Vive device, the Vive lighthouses may take a few seconds to calibrate. Keep the Vive trackers
- stable and visible to the lighthouse during this time. If the light houses are moved or if tracking fails or is unstable,
- calibration can be forced by deleting the calibration file at: ``$XDG_RUNTIME_DIR/libsurvive/config.json``. If XDG_RUNTIME_DIR
- is not set, the default directory is ``~/.config/libsurvive``.
+ #. After a brief period you should see the simulation rendered in the headset along with
+ teleoperation controls.
- For more information consult the libsurvive documentation: `libsurvive `_.
+ .. figure:: ../_static/setup/cloudxr_avp_teleop_ui.jpg
+ :align: center
+ :figwidth: 50%
+ :alt: Apple Vision Pro teleop UI
-For optimal performance, position the lighthouse above the hands, tilted slightly downward.
-One lighthouse is sufficient if both hands are visible.
-Ensure the lighthouse remains stable; a stand is recommended to prevent wobbling.
+ #. Click **Play** to begin teleoperating. Use **Play**, **Stop**, and **Reset** to control
+ the session.
-.. note::
+ .. tip::
- To avoid resource contention and crashes, ensure Manus and Vive devices are connected to different USB controllers/buses.
- Use ``lsusb -t`` to identify different buses and connect devices accordingly.
+ For bimanual tasks, visionOS voice control enables hands-free UI:
- Vive trackers are automatically calculated to map to the left and right wrist joints obtained from a stable
- OpenXR hand tracking wrist pose.
- This auto-mapping calculation supports up to 2 Vive trackers;
- if more than 2 Vive trackers are detected, it uses the first two trackers detected for calibration, which may not be correct.
+ #. **Settings** > **Accessibility** > **Voice Control** > Turn on **Voice Control**
+ #. Enable **
- ** under **Commands** > **Basic Navigation**
+ #. Say "Play", "Stop", or "Reset" while the app is connected.
-.. _develop-xr-isaac-lab:
+ #. Teleoperate the robot by moving your hands.
-Develop for XR in Isaac Lab
----------------------------
+ .. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/cloudxr_bimanual_teleop.gif
+ :align: center
+ :alt: Bimanual dexterous teleoperation with CloudXR
-This section will walk you through how to develop XR environments in Isaac Lab for building
-teleoperation workflows.
+ .. note::
+ If the IK solver fails, an error message appears in the headset. Click **Reset** to
+ return the robot to its original pose and continue.
-.. _run-isaac-lab-with-xr:
+ .. figure:: ../_static/setup/cloudxr_avp_ik_error.jpg
+ :align: center
+ :figwidth: 80%
+ :alt: IK error message in XR device
-Run Isaac Lab with XR Extensions Enabled
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ #. Click **Disconnect** when finished.
-In order to enable extensions necessary for XR, and to see the AR Panel in the UI, Isaac Lab must be
-loaded with an XR experience file. This can be done automatically by passing the ``--xr`` flag to
-any Isaac Lab script that uses :class:`app.AppLauncher`.
-For example: you can enable and use XR in any of the :ref:`tutorials` by invoking them with the
-additional ``--xr`` flag.
+.. _manus-vive-handtracking:
+Manus Gloves
+------------
-.. _configure-scene-placement:
+Manus gloves provide high-fidelity finger tracking via the Manus SDK. This is useful when optical
+hand tracking from the headset is occluded or when higher-precision finger data is needed.
-Configure XR Scene Placement
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. important::
-Placement of the robot simulation within the XR device's local coordinate frame can be achieved
-using an XR anchor, and is configurable using the ``xr`` field (type :class:`openxr.XrCfg`) in the
-environment configuration.
+ Manus gloves and other external push-device peripherals require
+ ``NV_CXR_ENABLE_PUSH_DEVICES=1``. The shipped ``.env`` profiles set this to ``0``
+ (optimised for headset optical hand tracking). To use Manus gloves, create a custom
+ ``.env`` file with the value set to ``1`` and pass it via ``--cloudxr_env``:
-Specifically: the pose specified by the ``anchor_pos`` and ``anchor_rot`` fields of the
-:class:`openxr.XrCfg` will appear at the origin of the XR device's local coordinate frame, which
-should be on the floor.
+ .. code-block:: bash
-.. note::
+ # Copy a shipped profile and enable push devices
+ cp $(python -c "from isaaclab_teleop import CLOUDXR_JS_ENV; print(CLOUDXR_JS_ENV)") ~/manus.env
+ sed -i 's/NV_CXR_ENABLE_PUSH_DEVICES=0/NV_CXR_ENABLE_PUSH_DEVICES=1/' ~/manus.env
- On Apple Vision Pro, the local coordinate frame can be reset to a point on the floor beneath the
- user by holding the digital crown.
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py \
+ --task Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 \
+ --visualizer kit --xr \
+ --cloudxr_env ~/manus.env
-For example: if a robot should appear at the position of the user, the ``anchor_pos`` and
-``anchor_rot`` properties should be set to a pose on the floor directly beneath the robot.
+ See :ref:`isaac-teleop-cloudxr-profiles` for full details on customising profiles.
.. note::
- The XR anchor configuration is applied in :class:`openxr.OpenXRDevice` by creating a prim at the
- position of the anchor, and modifying the ``xr/profile/ar/anchorMode`` and
- ``/xrstage/profile/ar/customAnchor`` settings.
-
- If you are running a script that does not use :class:`openxr.OpenXRDevice`, you will need to do
- this explicitly.
-
-
-.. _optimize-xr-performance:
-
-Optimize XR Performance
-~~~~~~~~~~~~~~~~~~~~~~~
+ Manus glove support has been migrated into Isaac Teleop as a native plugin. The previous
+ ``isaac-teleop-device-plugins`` repository and the ``libsurvive``-based Vive tracker integration
+ are no longer required.
-.. dropdown:: Configure the physics and render time step
- :open:
+Requirements:
- In order to provide a high-fidelity immersive experience, it is recommended to ensure that the
- simulation render time step roughly matches the XR device display time step.
+* Manus gloves with a Manus SDK license
- It is also important to ensure that this time step can be simulated and rendered in real time.
+The Manus plugin is included in the ``isaacteleop`` package and activated automatically when
+configured in the environment's retargeting pipeline. Manus tracking data flows through the same
+API as headset-based optical hand tracking in Isaac Teleop, so the same retargeters and pipelines
+work with both input sources.
- The Apple Vision Pro display runs at 90Hz, but many Isaac Lab simulations will not achieve 90Hz
- performance when rendering stereo views for XR; so for best experience on Apple Vision Pro, we
- suggest running with a simulation dt of 90Hz and a render interval of 2, meaning that the
- simulation is rendered once for every two simulation steps, or at 45Hz, if performance allows.
+For plugin configuration details, see the `Manus plugin documentation
+`_.
- You can still set the simulation dt lower or higher depending on your requirements, but this may
- result in the simulation appearing faster or slower when rendered in XR.
+The recommended workflow:
- Overriding the time step configuration for an environment can be done by modifying the
- :class:`sim.SimulationCfg` in the environment's ``__post_init__`` function. For instance:
+#. Start Isaac Lab and click **Start AR**.
+#. Put on the Manus gloves and headset.
+#. Use voice commands to launch the Isaac XR Teleop Sample Client and connect to Isaac Lab.
- .. code-block:: python
- @configclass
- class XrTeleopEnvCfg(ManagerBasedRLEnvCfg):
+Run with Docker
+---------------
- def __post_init__(self):
- self.sim.dt = 1.0 / 90
- self.sim.render_interval = 2
+Teleoperation runs in a **single container**. Build the image yourself and run a single container.
+Do **not** use Docker Compose, which is a multi-container setup as we had in Isaac Lab 2.x. All
+components run inside one container with Isaac Lab in this release.
- Also note that by default the CloudXR Runtime attempts to dynamically adjust its pacing based on
- how long Isaac Lab takes to render. If render times are highly variable, this can lead to the
- simulation appearing to speed up or slow down when rendered in XR. If this is an issue, the
- CloudXR Runtime can be configured to use a fixed time step by setting the environment variable
- ``NV_PACER_FIXED_TIME_STEP_MS`` to an integer quantity when starting the CloudXR Runtime Docker
- containere.
+The CloudXR runtime auto-launches when a teleop script is started, so no separate
+runtime command is needed.
+Run the teleop script (e.g. ``record_demos.py`` to record demonstrations):
-.. dropdown:: Try running physics on CPU
- :open:
-
- It is currently recommended to try running Isaac Lab teleoperation scripts with the ``--device
- cpu`` flag. This will cause Physics calculations to be done on the CPU, which may be reduce
- latency when only a single environment is present in the simulation.
-
-
-.. _control-robot-with-xr:
-
-Control the Robot with XR Device Inputs
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Isaac Lab provides a flexible architecture for using XR tracking data to control
-simulated robots. This section explains the components of this architecture and how they work together.
-
-.. _openxr-device-architecture:
-
-OpenXR Device
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The :class:`isaaclab.devices.OpenXRDevice` is the core component that enables XR-based teleoperation in Isaac Lab.
-This device interfaces with CloudXR to receive tracking data from the XR headset and transform it into robot control
-commands.
-
-At its heart, XR teleoperation requires mapping (or "retargeting") user inputs, such as hand movements and poses,
-into robot control signals. Isaac Lab makes this straightforward through its OpenXRDevice and Retargeter architecture.
-The OpenXRDevice captures hand tracking data via Isaac Sim's OpenXR API, then passes this data through one or more
-Retargeters that convert it into robot actions.
-
-The OpenXRDevice also integrates with the XR device's user interface when using CloudXR, allowing users to trigger
-simulation events directly from their XR environment.
-
-.. _control-robot-with-xr-retargeters:
-
-Retargeting Architecture
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Retargeters are specialized components that convert raw tracking data into meaningful control signals
-for robots. They implement the :class:`isaaclab.devices.RetargeterBase` interface and are passed to
-the OpenXRDevice during initialization.
-
-Isaac Lab provides three main retargeters for hand tracking:
-
-.. dropdown:: Se3RelRetargeter (:class:`isaaclab.devices.openxr.retargeters.Se3RelRetargeter`)
-
- * Generates incremental robot commands from relative hand movements
- * Best for precise manipulation tasks
-
-.. dropdown:: Se3AbsRetargeter (:class:`isaaclab.devices.openxr.retargeters.Se3AbsRetargeter`)
-
- * Maps hand position directly to robot end-effector position
- * Enables 1:1 spatial control
-
-.. dropdown:: GripperRetargeter (:class:`isaaclab.devices.openxr.retargeters.GripperRetargeter`)
-
- * Controls gripper state based on thumb-index finger distance
- * Used alongside position retargeters for full robot control
-
-.. dropdown:: GR1T2Retargeter (:class:`isaaclab.devices.openxr.retargeters.GR1T2Retargeter`)
-
- * Retargets OpenXR hand tracking data to GR1T2 hand end-effector commands
- * Handles both left and right hands, converting hand poses to joint angles for the GR1T2 robot's hands
- * Supports visualization of tracked hand joints
-
-.. dropdown:: UnitreeG1Retargeter (:class:`isaaclab.devices.openxr.retargeters.UnitreeG1Retargeter`)
-
- * Retargets OpenXR hand tracking data to Unitree G1 using Inspire 5-finger hand end-effector commands
- * Handles both left and right hands, converting hand poses to joint angles for the G1 robot's hands
- * Supports visualization of tracked hand joints
-
-Retargeters can be combined to control different robot functions simultaneously.
-
-Using Retargeters with Hand Tracking
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Here's an example of setting up hand tracking:
-
-.. code-block:: python
-
- from isaaclab.devices import OpenXRDevice, OpenXRDeviceCfg
- from isaaclab.devices.openxr.retargeters import Se3AbsRetargeter, GripperRetargeter
-
- # Create retargeters
- position_retargeter = Se3AbsRetargeter(
- bound_hand=DeviceBase.TrackingTarget.HAND_RIGHT,
- zero_out_xy_rotation=True,
- use_wrist_position=False # Use pinch position (thumb-index midpoint) instead of wrist
- )
- gripper_retargeter = GripperRetargeter(bound_hand=DeviceBase.TrackingTarget.HAND_RIGHT)
-
- # Create OpenXR device with hand tracking and both retargeters
- device = OpenXRDevice(
- OpenXRDeviceCfg(xr_cfg=env_cfg.xr),
- retargeters=[position_retargeter, gripper_retargeter],
- )
-
- # Main control loop
- while True:
- # Get the latest commands from the XR device
- commands = device.advance()
- if commands is None:
- continue
-
- # Apply the commands to the environment
- obs, reward, terminated, truncated, info = env.step(commands)
-
- if terminated or truncated:
- break
-
-Here's a diagram for the dataflow and algorithm used in humanoid teleoperation. Using Apple Vision Pro, we collect 26 keypoints for each hand.
-The wrist keypoint is used to control the hand end-effector, while the remaining hand keypoints are used for hand retargeting.
-
-.. figure:: ../_static/teleop/teleop_diagram.jpg
- :align: center
- :figwidth: 80%
- :alt: teleop_diagram
-
-For dex-retargeting, we are currently using the Dexpilot optimizer, which relies on the five fingertips and the palm for retargeting. It is essential
-that the links used for retargeting are defined exactly at the fingertips—not in the middle of the fingers—to ensure accurate optimization.Please refer
-to the image below for hand asset selection, find a suitable hand asset, or add fingertip links in IsaacLab as needed.
-
-.. figure:: ../_static/teleop/hand_asset.jpg
- :align: center
- :figwidth: 60%
- :alt: hand_asset
-
-.. _control-robot-with-xr-callbacks:
-
-Adding Callbacks for XR UI Events
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The OpenXRDevice can handle events triggered by user interactions with XR UI elements like buttons and menus.
-When a user interacts with these elements, the device triggers registered callback functions:
-
-.. code-block:: python
-
- # Register callbacks for teleop control events
- device.add_callback("RESET", reset_callback)
- device.add_callback("START", start_callback)
- device.add_callback("STOP", stop_callback)
-
-When the user interacts with the XR UI, these callbacks will be triggered to control the simulation
-or recording process. You can also add custom messages from the client side using custom keys that will
-trigger these callbacks, allowing for programmatic control of the simulation alongside direct user interaction.
-The custom keys can be any string value that matches the callback registration.
-
-
-Teleop Environment Configuration
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-XR-based teleoperation can be integrated with Isaac Lab's environment configuration system using the
-``teleop_devices`` field in your environment configuration:
-
-.. code-block:: python
-
- from dataclasses import field
- from isaaclab.envs import ManagerBasedEnvCfg
- from isaaclab.devices import DevicesCfg, OpenXRDeviceCfg
- from isaaclab.devices.openxr import XrCfg
- from isaaclab.devices.openxr.retargeters import Se3AbsRetargeterCfg, GripperRetargeterCfg
-
- @configclass
- class MyEnvironmentCfg(ManagerBasedEnvCfg):
- """Configuration for a teleoperation-enabled environment."""
-
- # Add XR configuration with custom anchor position
- xr: XrCfg = XrCfg(
- anchor_pos=[0.0, 0.0, 0.0],
- anchor_rot=[1.0, 0.0, 0.0, 0.0]
- )
-
- # Define teleoperation devices
- teleop_devices: DevicesCfg = field(default_factory=lambda: DevicesCfg(
- # Configuration for hand tracking with absolute position control
- handtracking=OpenXRDeviceCfg(
- xr_cfg=None, # Will use environment's xr config
- retargeters=[
- Se3AbsRetargeterCfg(
- bound_hand=0, # HAND_LEFT enum value
- zero_out_xy_rotation=True,
- use_wrist_position=False,
- ),
- GripperRetargeterCfg(bound_hand=0),
- ]
- ),
- # Add other device configurations as needed
- ))
-
-
-Teleop Device Factory
-^^^^^^^^^^^^^^^^^^^^^
-
-To create a teleoperation device from your environment configuration, use the ``create_teleop_device`` factory function:
-
-.. code-block:: python
-
- from isaaclab.devices import create_teleop_device
- from isaaclab.envs import ManagerBasedEnv
-
- # Create environment from configuration
- env_cfg = MyEnvironmentCfg()
- env = ManagerBasedEnv(env_cfg)
-
- # Define callbacks for teleop events
- callbacks = {
- "RESET": lambda: print("Reset simulation"),
- "START": lambda: print("Start teleoperation"),
- "STOP": lambda: print("Stop teleoperation"),
- }
-
- # Create teleop device from configuration with callbacks
- device_name = "handtracking" # Must match a key in teleop_devices
- device = create_teleop_device(
- device_name,
- env_cfg.teleop_devices,
- callbacks=callbacks
- )
-
- # Use device in control loop
- while True:
- # Get the latest commands from the device
- commands = device.advance()
- if commands is None:
- continue
-
- # Apply commands to environment
- obs, reward, terminated, truncated, info = env.step(commands)
-
-
-Extending the Retargeting System
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The retargeting system is designed to be extensible. You can create custom retargeters by following these steps:
-
-1. Create a configuration dataclass for your retargeter:
-
-.. code-block:: python
-
- from dataclasses import dataclass
- from isaaclab.devices.retargeter_base import RetargeterCfg
-
- @dataclass
- class MyCustomRetargeterCfg(RetargeterCfg):
- """Configuration for my custom retargeter."""
- scaling_factor: float = 1.0
- filter_strength: float = 0.5
- # Add any other configuration parameters your retargeter needs
-
-2. Implement your retargeter class by extending the RetargeterBase:
-
-.. code-block:: python
-
- from isaaclab.devices.retargeter_base import RetargeterBase
- from isaaclab.devices import OpenXRDevice
- import torch
- from typing import Any
-
- class MyCustomRetargeter(RetargeterBase):
- """A custom retargeter that processes OpenXR tracking data."""
-
- def __init__(self, cfg: MyCustomRetargeterCfg):
- """Initialize retargeter with configuration.
-
- Args:
- cfg: Configuration object for retargeter settings.
- """
- super().__init__()
- self.scaling_factor = cfg.scaling_factor
- self.filter_strength = cfg.filter_strength
- # Initialize any other required attributes
-
- def retarget(self, data: dict) -> Any:
- """Transform raw tracking data into robot control commands.
-
- Args:
- data: Dictionary containing tracking data from OpenXRDevice.
- Keys are TrackingTarget enum values, values are joint pose dictionaries.
-
- Returns:
- Any: The transformed control commands for the robot.
- """
- # Access hand tracking data using TrackingTarget enum
- right_hand_data = data[DeviceBase.TrackingTarget.HAND_RIGHT]
-
- # Extract specific joint positions and orientations
- wrist_pose = right_hand_data.get("wrist")
- thumb_tip_pose = right_hand_data.get("thumb_tip")
- index_tip_pose = right_hand_data.get("index_tip")
-
- # Access head tracking data
- head_pose = data[DeviceBase.TrackingTarget.HEAD]
-
- # Process the tracking data and apply your custom logic
- # ...
-
- # Return control commands in appropriate format
- return torch.tensor([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]) # Example output
-
-3. Register your retargeter by setting ``retargeter_type`` on the config class:
-
-.. code-block:: python
-
- # Import your retargeter at the top of your module
- from my_package.retargeters import MyCustomRetargeter, MyCustomRetargeterCfg
-
- # Link the config to the implementation for factory construction
- MyCustomRetargeterCfg.retargeter_type = MyCustomRetargeter
-
-4. Now you can use your custom retargeter in teleop device configurations:
-
-.. code-block:: python
-
- from isaaclab.devices import OpenXRDeviceCfg, DevicesCfg
- from isaaclab.devices.openxr import XrCfg
- from my_package.retargeters import MyCustomRetargeterCfg
-
- # Create XR configuration for proper scene placement
- xr_config = XrCfg(anchor_pos=[0.0, 0.0, 0.0], anchor_rot=[1.0, 0.0, 0.0, 0.0])
-
- # Define teleop devices with custom retargeter
- teleop_devices = DevicesCfg(
- handtracking=OpenXRDeviceCfg(
- xr_cfg=xr_config,
- retargeters=[
- MyCustomRetargeterCfg(
- scaling_factor=1.5,
- filter_strength=0.7,
- ),
- ]
- ),
- )
-
-As the OpenXR capabilities expand beyond hand tracking to include head tracking and other features,
-additional retargeters can be developed to map this data to various robot control paradigms.
-
-
-Creating Custom Teleop Devices
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can create and register your own custom teleoperation devices by following these steps:
-
-1. Create a configuration dataclass for your device:
-
-.. code-block:: python
-
- from dataclasses import dataclass
- from isaaclab.devices import DeviceCfg
-
- @dataclass
- class MyCustomDeviceCfg(DeviceCfg):
- """Configuration for my custom device."""
- sensitivity: float = 1.0
- invert_controls: bool = False
- # Add any other configuration parameters your device needs
-
-2. Implement your device class by inheriting from DeviceBase:
-
-.. code-block:: python
-
- from isaaclab.devices import DeviceBase
- import torch
-
- class MyCustomDevice(DeviceBase):
- """A custom teleoperation device."""
-
- def __init__(self, cfg: MyCustomDeviceCfg):
- """Initialize the device with configuration.
-
- Args:
- cfg: Configuration object for device settings.
- """
- super().__init__()
- self.sensitivity = cfg.sensitivity
- self.invert_controls = cfg.invert_controls
- # Initialize any other required attributes
- self._device_input = torch.zeros(7) # Example: 6D pose + gripper
-
- def reset(self):
- """Reset the device state."""
- self._device_input.zero_()
- # Reset any other state variables
-
- def add_callback(self, key: str, func):
- """Add callback function for a button/event.
-
- Args:
- key: Button or event name.
- func: Callback function to be called when event occurs.
- """
- # Implement callback registration
- pass
-
- def advance(self) -> torch.Tensor:
- """Get the latest commands from the device.
-
- Returns:
- torch.Tensor: Control commands (e.g., delta pose + gripper).
- """
- # Update internal state based on device input
- # Return command tensor
- return self._device_input
-
-3. Register your device with the teleoperation device factory by adding it to the ``DEVICE_MAP``:
-
-.. code-block:: python
-
- # Import your device at the top of your module
- from my_package.devices import MyCustomDevice, MyCustomDeviceCfg
-
- # Add your device to the factory
- from isaaclab.devices.teleop_device_factory import DEVICE_MAP
-
- # Register your device type with its constructor
- DEVICE_MAP[MyCustomDeviceCfg] = MyCustomDevice
-
-4. Now you can use your custom device in environment configurations:
-
-.. code-block:: python
-
- from dataclasses import field
- from isaaclab.envs import ManagerBasedEnvCfg
- from isaaclab.devices import DevicesCfg
- from my_package.devices import MyCustomDeviceCfg
-
- @configclass
- class MyEnvironmentCfg(ManagerBasedEnvCfg):
- """Environment configuration with custom teleop device."""
-
- teleop_devices: DevicesCfg = field(default_factory=lambda: DevicesCfg(
- my_custom_device=MyCustomDeviceCfg(
- sensitivity=1.5,
- invert_controls=True,
- ),
- ))
-
-
-.. _xr-known-issues:
-
-Known Issues
-------------
-
-* ``XR_ERROR_VALIDATION_FAILURE: xrWaitFrame(frameState->type == 0)`` when stopping AR Mode
-
- This error message can be safely ignored. It is caused by a race condition in the exit handler for
- AR Mode.
-
-* ``XR_ERROR_INSTANCE_LOST in xrPollEvent: Call to "xrt_session_poll_events" failed``
-
- This error may occur if the CloudXR runtime exits before Isaac Lab. Restart the CloudXR
- runtime to resume teleoperation.
-
-* ``[omni.usd] TF_PYTHON_EXCEPTION`` when starting/stopping AR Mode
-
- This error message can be safely ignored. It is caused by a race condition in the enter/exit
- handler for AR Mode.
-
-* ``Invalid version string in _ParseVersionString``
+.. code-block:: bash
- This error message can be caused by shader assets authored with older versions of USD, and can
- typically be ignored.
+ ./isaaclab.sh -p scripts/tools/record_demos.py \
+ --task Isaac-PickPlace-Locomanipulation-G1-Abs-v0 \
+ --num_demos 5 \
+ --dataset_file ./datasets/dataset.hdf5 \
+ --xr --visualizer kit
-* The XR device connects successfully, but no video is displayed, even though the Isaac Lab viewport responds to tracking.
+Then in the Isaac Sim UI, set the AR panel to **System OpenXR Runtime** and click **Start XR**.
- This error occurs when the GPU index differs between the host and the container, causing CUDA
- to load on the wrong GPU. To fix this, set ``NV_GPU_INDEX`` in the runtime container to ``0``, ``1``,
- or ``2`` to ensure the GPU selected by CUDA matches the host.
+For a fully headless experience, replace ``--visualizer kit`` with ``--headless`` and the XR
+teleop session will run automatically.
+.. admonition:: Next Steps
-Kubernetes Deployment
----------------------
+ * **Architecture, retargeting, and control schemes**: :ref:`isaac-teleop-feature`
+ * **Teleoperation for imitation learning**: :ref:`teleoperation-imitation-learning`
+ * **API reference**: :ref:`isaaclab_teleop-api`
-For information on deploying XR Teleop for Isaac Lab on a Kubernetes cluster, see :ref:`cloudxr-teleoperation-cluster`.
..
References
.. _`Apple Vision Pro`: https://www.apple.com/apple-vision-pro/
-.. _`Docker Compose`: https://docs.docker.com/compose/install/linux/#install-using-the-repository
-.. _`Docker`: https://docs.docker.com/desktop/install/linux-install/
.. _`NVIDIA CloudXR`: https://developer.nvidia.com/cloudxr-sdk
-.. _`NVIDIA Container Toolkit`: https://github.com/NVIDIA/nvidia-container-toolkit
.. _`Isaac XR Teleop Sample Client`: https://github.com/isaac-sim/isaac-xr-teleop-sample-client-apple
+.. _`CloudXR Network Setup`: https://docs.nvidia.com/cloudxr-sdk/latest/requirement/network_setup.html
+.. _`CloudXR.js`: https://docs.nvidia.com/cloudxr-sdk/latest/usr_guide/cloudxr_js/index.html
diff --git a/docs/source/how-to/configure_rendering.rst b/docs/source/how-to/configure_rendering.rst
index adfa8b5556c..ee2510fdc44 100644
--- a/docs/source/how-to/configure_rendering.rst
+++ b/docs/source/how-to/configure_rendering.rst
@@ -1,7 +1,16 @@
-Configuring Rendering Settings
-==============================
+Configuring RTX Rendering Settings
+====================================
-Isaac Lab offers 3 preset rendering modes: performance, balanced, and quality.
+.. note::
+
+ This guide covers the **RTX renderer** settings, which are used when running Isaac Lab with
+ Isaac Sim. The RTX renderer is based on NVIDIA's Omniverse RTX rendering pipeline and is
+ available for all camera sensors in the PhysX backend.
+
+ For the **Newton renderer** (used with the Newton backend or in kit-less mode), see
+ :ref:`overview_renderers` for the pluggable renderer architecture and available backends.
+
+Isaac Lab's RTX renderer offers 3 preset rendering modes: performance, balanced, and quality.
You can select a mode via a command line argument or from within a script, and customize settings as needed.
Adjust and fine-tune rendering to achieve the ideal balance for your workflow.
@@ -123,7 +132,8 @@ There are 2 ways to provide settings that overwrite presets.
Examples of RTX settings can be found from within the repo, in the render mode preset files located in ``apps/rendering_modes``.
- In addition, the RTX documentation can be found here - https://docs.omniverse.nvidia.com/materials-and-rendering/latest/rtx-renderer.html.
+ In addition, the full NVIDIA RTX renderer documentation can be found at
+ https://docs.omniverse.nvidia.com/materials-and-rendering/latest/rtx-renderer.html.
An example usage of ``carb_settings``.
@@ -149,3 +159,43 @@ Due to this, we recommend using per-tile or per-camera resolution of at least 10
For renders at lower resolutions, we advice setting the ``antialiasing_mode`` attribute in :class:`~sim.RenderCfg` to
``DLAA``, and also potentially enabling ``enable_dl_denoiser``. Both of these settings should help improve render
quality, but also comes at a cost of performance. Additional rendering parameters can also be specified in :class:`~sim.RenderCfg`.
+
+
+If you observe visual artifacts such as ghosting or disocclusion issues when using tiled rendering, you can try
+adjusting the ``disocclusionScale`` parameter. This setting controls how aggressively the renderer handles
+areas that become newly visible between frames:
+
+.. code-block:: python
+
+ render_cfg = sim_utils.RenderCfg(
+ carb_settings={
+ "/rtx/aovConverter/disocclusionScale": 10000,
+ }
+ )
+
+.. note::
+
+ This parameter is not commonly exposed as it may have side effects in certain scenarios.
+ Only use it as a last resort if other quality settings do not resolve the visual artifacts.
+ The value can be adjusted to a very high value to reduce disocclusion artifacts.
+
+
+Rendering UsdVol 3D Gaussian Scenes in Multiple Environments
+------------------------------------------------------------
+
+When using UsdVol volumes with 3D Gaussian particles (e.g. exported from
+`3DGRUT `_)
+in **multiple environments**, you must set the following so the renderer uses the correct compositing path:
+
+.. code-block:: python
+
+ render_cfg = sim_utils.RenderCfg(
+ carb_settings={
+ "omni.rtx.nre.compositing.rendererHints": 3,
+ }
+ )
+
+.. warning::
+
+ With multiple environments, each environment holds its own copy of the scene, increasing device memory use,
+ and environments are rendered one after another, which can substantially slow down rendering.
diff --git a/docs/source/how-to/haply_teleoperation.rst b/docs/source/how-to/haply_teleoperation.rst
index 1f8d1d6e252..46651077e33 100644
--- a/docs/source/how-to/haply_teleoperation.rst
+++ b/docs/source/how-to/haply_teleoperation.rst
@@ -70,7 +70,7 @@ Software Requirements
* Isaac Lab (follow the :ref:`installation guide `)
* Haply SDK (provided by Haply Robotics)
-* Python 3.10+
+* Python 3.12+
* ``websockets`` Python package (automatically installed with Isaac Lab)
diff --git a/docs/source/how-to/import_new_asset.rst b/docs/source/how-to/import_new_asset.rst
index 41eacc48673..e241be44e96 100644
--- a/docs/source/how-to/import_new_asset.rst
+++ b/docs/source/how-to/import_new_asset.rst
@@ -37,6 +37,12 @@ Using URDF Importer
For using the URDF importer in the GUI, please check the documentation at `URDF importer`_. For using the URDF importer from Python scripts, we include a utility tool called ``convert_urdf.py``. This script creates an instance of :class:`~sim.converters.UrdfConverterCfg` which
is then passed to the :class:`~sim.converters.UrdfConverter` class.
+.. note::
+ The URDF importer was upgraded to version 3.0 in Isaac Sim 6, replacing the previous C++
+ binding-based API with a Python pipeline (``urdf-usd-converter``). Assets are now made
+ instanceable by default — ``make_instanceable`` is no longer a configuration option.
+ See the :doc:`/source/migration/migrating_to_isaaclab_3-0` for a full list of breaking changes.
+
The URDF importer has various configuration parameters that can be set to control the behavior of the importer.
The default values for the importer's configuration parameters are specified are in the :class:`~sim.converters.UrdfConverterCfg` class, and they are listed below. We made a few commonly modified settings to be available as command-line arguments when calling the ``convert_urdf.py``, and they are marked with ``*`` in the list. For a comprehensive list of the configuration parameters, please check the the documentation at `URDF importer`_.
@@ -44,6 +50,7 @@ The default values for the importer's configuration parameters are specified are
This depends on whether you have a floating-base or fixed-base robot. The command-line flag is
``--fix-base`` where when set, the importer will fix the base of the robot, otherwise it will default to floating-base.
* :attr:`~sim.converters.UrdfConverterCfg.root_link_name` - The link on which the PhysX articulation root is placed.
+ **Deprecated in URDF importer 3.0** — this option is ignored.
* :attr:`~sim.converters.UrdfConverterCfg.merge_fixed_joints` * - Whether to merge the fixed joints.
Usually, this should be set to ``True`` to reduce the asset complexity. The command-line flag is
``--merge-joints`` where when set, the importer will merge the fixed joints, otherwise it will default to not merging the fixed joints.
@@ -59,7 +66,8 @@ The default values for the importer's configuration parameters are specified are
* :attr:`~sim.converters.UrdfConverterCfg.JointDriveCfg.PDGainsCfg` - To directly set the stiffness and damping.
* :attr:`~sim.converters.UrdfConverterCfg.JointDriveCfg.NaturalFrequencyGainsCfg` - To set the gains using the
- desired natural frequency response of the system.
+ desired natural frequency response of the system. **Deprecated in URDF importer 3.0** — use
+ ``PDGainsCfg`` instead.
For more detailed information on the configuration parameters, please check the documentation for :class:`~sim.converters.UrdfConverterCfg`.
@@ -75,8 +83,11 @@ pre-processed URDF and the original URDF are:
* We removed various collision bodies from the URDF to reduce the complexity of the asset.
* We changed all the joint's damping and friction parameters to ``0.0``. This ensures that we can perform
effort-control on the joints without PhysX adding additional damping.
-* We added the ```` tag to fixed joints. This ensures that the importer does
- not merge these fixed joints.
+* The ```` URDF tag is **no longer supported** in URDF importer 3.0. Fixed joint
+ merging is now a Python pre-processing step that merges all fixed joints when
+ ``merge_fixed_joints`` is enabled. If you need to preserve a specific fixed joint, disable
+ ``merge_fixed_joints`` entirely or restructure the URDF to use a non-fixed joint type
+ (e.g. revolute with zero-range limits).
The following shows the steps to clone the repository and run the converter:
@@ -97,7 +108,7 @@ The following shows the steps to clone the repository and run the converter:
# run the converter
./isaaclab.sh -p scripts/tools/convert_urdf.py \
../anymal_d_simple_description/urdf/anymal.urdf \
- source/isaaclab_assets/data/Robots/ANYbotics/anymal_d.usd \
+ source/isaaclab_assets/data/Robots/ANYbotics/ \
--merge-joints \
--joint-stiffness 0.0 \
--joint-damping 0.0 \
@@ -116,16 +127,17 @@ The following shows the steps to clone the repository and run the converter:
:: run the converter
isaaclab.bat -p scripts\tools\convert_urdf.py ^
..\anymal_d_simple_description\urdf\anymal.urdf ^
- source\isaaclab_assets\data\Robots\ANYbotics\anymal_d.usd ^
+ source\isaaclab_assets\data\Robots\ANYbotics\ ^
--merge-joints ^
--joint-stiffness 0.0 ^
--joint-damping 0.0 ^
--joint-target-type none
Executing the above script will create a USD file inside the
-``source/isaaclab_assets/data/Robots/ANYbotics/`` directory:
+``source/isaaclab_assets/data/Robots/ANYbotics/anymal/`` directory (the subdirectory name
+is derived automatically from the robot name in the URDF):
-* ``anymal_d.usd`` - This is the main asset file.
+* ``anymal.usda`` - This is the main asset file.
To run the script headless, you can add the ``--headless`` flag. This will not open the GUI and
@@ -155,15 +167,23 @@ We made a few commonly modified settings to be available as command-line argumen
``convert_mjcf.py``, and they are marked with ``*`` in the list. For a comprehensive list of the configuration
parameters, please check the the documentation at `MJCF importer`_.
-
-* :attr:`~sim.converters.MjcfConverterCfg.fix_base*` - Whether to fix the base of the robot.
- This depends on whether you have a floating-base or fixed-base robot. The command-line flag is
- ``--fix-base`` where when set, the importer will fix the base of the robot, otherwise it will default to floating-base.
-* :attr:`~sim.converters.MjcfConverterCfg.make_instanceable*` - Whether to create instanceable assets.
- Usually, this should be set to ``True``. The command-line flag is ``--make-instanceable`` where
- when set, the importer will create instanceable assets, otherwise it will default to non-instanceable.
-* :attr:`~sim.converters.MjcfConverterCfg.import_sites*` - Whether to parse the tag in the MJCF.
- Usually, this should be set to ``True``. The command-line flag is ``--import-sites`` where when set, the importer will parse the tag, otherwise it will default to not parsing the tag.
+.. note::
+ The MJCF importer was rewritten in Isaac Sim 5.0 to use the ``mujoco-usd-converter`` library.
+ Settings such as ``fix_base``, ``import_sites``, ``import_inertia_tensor``, and ``make_instanceable``
+ are no longer needed — the converter now handles these automatically based on the MJCF file content.
+
+* :attr:`~sim.converters.MjcfConverterCfg.merge_mesh` * - Whether to merge meshes where possible to
+ optimize the model. The command-line flag is ``--merge-mesh``.
+* :attr:`~sim.converters.MjcfConverterCfg.collision_from_visuals` * - Whether to generate collision
+ geometry from visual geometries. The command-line flag is ``--collision-from-visuals``.
+* :attr:`~sim.converters.MjcfConverterCfg.collision_type` * - Type of collision geometry to use
+ (e.g. ``"default"``, ``"Convex Hull"``, ``"Convex Decomposition"``). The command-line flag is
+ ``--collision-type``.
+* :attr:`~sim.converters.MjcfConverterCfg.self_collision` * - Whether to activate self-collisions
+ between links of the articulation. The command-line flag is ``--self-collision``.
+* :attr:`~sim.converters.MjcfConverterCfg.import_physics_scene` * - Import physics scene properties
+ (gravity, time step, etc.) from the MJCF file. Defaults to ``False``. The command-line flag is
+ ``--import-physics-scene``.
Example Usage
@@ -182,7 +202,7 @@ The following shows the steps to clone the repository and run the converter:
.. code-block:: bash
- # clone a repository with URDF files
+ # clone a repository with MJCF files
git clone git@github.com:google-deepmind/mujoco_menagerie.git
# go to top of the Isaac Lab repository
@@ -191,15 +211,14 @@ The following shows the steps to clone the repository and run the converter:
./isaaclab.sh -p scripts/tools/convert_mjcf.py \
../mujoco_menagerie/unitree_h1/h1.xml \
source/isaaclab_assets/data/Robots/Unitree/h1.usd \
- --import-sites \
- --make-instanceable
+ --merge-mesh
.. tab-item:: :icon:`fa-brands fa-windows` Windows
:sync: windows
.. code-block:: batch
- :: clone a repository with URDF files
+ :: clone a repository with MJCF files
git clone git@github.com:google-deepmind/mujoco_menagerie.git
:: go to top of the Isaac Lab repository
@@ -208,14 +227,12 @@ The following shows the steps to clone the repository and run the converter:
isaaclab.bat -p scripts\tools\convert_mjcf.py ^
..\mujoco_menagerie\unitree_h1\h1.xml ^
source\isaaclab_assets\data\Robots\Unitree\h1.usd ^
- --import-sites ^
- --make-instanceable
+ --merge-mesh
-Executing the above script will create USD files inside the
+Executing the above script will create the USD file inside the
``source/isaaclab_assets/data/Robots/Unitree/`` directory:
-* ``h1.usd`` - This is the main asset file. It contains all the non-mesh data.
-* ``Props/instanceable_assets.usd`` - This is the mesh data file.
+* ``h1.usd`` - This is the converted USD asset file.
.. figure:: ../_static/tutorials/tutorial_convert_mjcf.jpg
:align: center
diff --git a/docs/source/how-to/index.rst b/docs/source/how-to/index.rst
index 02c0ff99ae1..278e88c4b6c 100644
--- a/docs/source/how-to/index.rst
+++ b/docs/source/how-to/index.rst
@@ -24,6 +24,7 @@ how to import a new asset into Isaac Lab.
import_new_asset
write_articulation_cfg
+ robots
Creating a Fixed Asset
----------------------
@@ -47,6 +48,17 @@ useful when you want to create diverse environments with different objects.
multi_asset_spawning
+Cloning Environments
+--------------------
+
+This guide explains how Isaac Lab's template-based cloning system works, including
+cloning strategies, heterogeneous environments, and collision filtering.
+
+.. toctree::
+ :maxdepth: 1
+
+ cloning
+
Saving Camera Output
--------------------
@@ -137,11 +149,11 @@ additional resources that help you use Omniverse features in Isaac Lab.
master_omniverse
-Setting up CloudXR Teleoperation
---------------------------------
+Setting up Isaac Teleop with CloudXR
+------------------------------------
-This guide explains how to use CloudXR and Apple Vision Pro for immersive streaming and
-teleoperation in Isaac Lab.
+This guide explains how to install Isaac Teleop, start the CloudXR runtime, and connect XR
+devices for immersive teleoperation in Isaac Lab.
.. toctree::
:maxdepth: 1
diff --git a/docs/source/how-to/make_fixed_prim.rst b/docs/source/how-to/make_fixed_prim.rst
index 6d9d50232dc..5726eff2668 100644
--- a/docs/source/how-to/make_fixed_prim.rst
+++ b/docs/source/how-to/make_fixed_prim.rst
@@ -100,7 +100,7 @@ For instance, to spawn an ANYmal robot and make it static in the simulation worl
),
)
anymal_spawn_cfg.func(
- "/World/ANYmal", anymal_spawn_cfg, translation=(0.0, 0.0, 0.8), orientation=(1.0, 0.0, 0.0, 0.0)
+ "/World/ANYmal", anymal_spawn_cfg, translation=(0.0, 0.0, 0.8), orientation=(0.0, 0.0, 0.0, 1.0)
)
diff --git a/docs/source/how-to/multi_asset_spawning.rst b/docs/source/how-to/multi_asset_spawning.rst
index 0dbcf48ba78..650b641bd68 100644
--- a/docs/source/how-to/multi_asset_spawning.rst
+++ b/docs/source/how-to/multi_asset_spawning.rst
@@ -110,6 +110,8 @@ to understand the entire simulation scene. This helps speed up the simulation sc
However, in the case of spawning different assets in different environments, this assumption does not hold
anymore. Hence the flag :attr:`scene.InteractiveScene.replicate_physics` must be disabled.
+For a full guide on the template-based cloning system including strategies and collision filtering,
+see :doc:`cloning`.
.. literalinclude:: ../../../scripts/demos/multi_asset.py
:language: python
diff --git a/docs/source/how-to/optimize_stage_creation.rst b/docs/source/how-to/optimize_stage_creation.rst
index b262878d667..567b635405e 100644
--- a/docs/source/how-to/optimize_stage_creation.rst
+++ b/docs/source/how-to/optimize_stage_creation.rst
@@ -9,7 +9,7 @@ What These Features Do
**Fabric Cloning**
-- Clones environments using Fabric library (see `USD Fabric USDRT Documentation `_)
+- Clones environments using Fabric library (see `USD Fabric USDRT Documentation `_)
- Partially supported and enabled by default on some environments (see `Limitations`_ section for a list)
**Stage in Memory**
@@ -22,6 +22,7 @@ Usage Examples
--------------
Fabric cloning can be toggled by setting the :attr:`isaaclab.scene.InteractiveSceneCfg.clone_in_fabric` flag.
+For a full guide on the template-based cloning system, see :doc:`cloning`.
**Using Fabric Cloning with a RL environment**
@@ -47,26 +48,23 @@ Stage in memory can be toggled by setting the :attr:`isaaclab.sim.SimulationCfg.
# create env with stage in memory
env = ManagerBasedRLEnv(cfg=cfg)
-Note, if stage in memory is enabled without using an existing RL environment class, a few more steps are need.
-The stage creation steps should be wrapped in a :py:keyword:`with` statement to set the stage context.
-If the stage needs to be attached, the :meth:`~isaaclab.sim.utils.attach_stage_to_usd_context` function should
-be called after the stage is created.
+When using stage in memory without an existing RL environment class, wrap the stage creation steps
+in a :py:keyword:`with` statement to set the stage context. The stage is automatically attached
+to the USD context when ``SimulationContext`` is created with ``create_stage_in_memory=True``.
**Using Stage in Memory with a manual scene setup**
.. code-block:: python
# init simulation context with stage in memory
+ # Note: stage is automatically attached to USD context
sim = SimulationContext(cfg=SimulationCfg(create_stage_in_memory=True))
- # grab stage in memory and set stage context
- stage_in_memory = sim.get_initial_stage()
- with stage_utils.use_stage(stage_in_memory):
+ # grab stage and set stage context
+ with stage_utils.use_stage(sim.stage):
# create cartpole scene
scene_cfg = CartpoleSceneCfg(num_envs=1024)
scene = InteractiveScene(scene_cfg)
- # attach stage to memory after stage is created
- sim_utils.attach_stage_to_usd_context()
sim.play()
@@ -118,13 +116,11 @@ Limitations
- Cannot be currently enabled at the same time as **Fabric Cloning**.
-- Attaching stage in memory to the USD context can be slow, offsetting some or all of the performance benefits.
-
- - Note, attaching is only necessary when rendering is enabled. For example, in headless mode, attachment is not required.
+- The stage is automatically attached to the USD context at ``SimulationContext`` creation, ensuring proper
+ lifecycle events for viewport and physics systems.
- Certain low-level Kit APIs do not yet support stage in memory.
- - In most cases, when these APIs are hit, existing scripts will automatically early attach the stage and print a warning message.
- In one particular case, for some environments, the API call to color the ground plane is skipped, when stage in memory is enabled.
diff --git a/docs/source/how-to/record_animation.rst b/docs/source/how-to/record_animation.rst
index 2d675684fbf..61b4ca823d2 100644
--- a/docs/source/how-to/record_animation.rst
+++ b/docs/source/how-to/record_animation.rst
@@ -122,6 +122,6 @@ After the stop time is reached, a file will be saved to:
.. _Stage Recorder: https://docs.omniverse.nvidia.com/extensions/latest/ext_animation_stage-recorder.html
-.. _Fabric: https://docs.omniverse.nvidia.com/kit/docs/usdrt/latest/docs/usd_fabric_usdrt.html
+.. _Fabric: https://docs.omniverse.nvidia.com/kit/docs/usdrt.scenegraph/latest/usd_fabric_usdrt.html
.. _Omniverse Launcher: https://docs.omniverse.nvidia.com/launcher/latest/index.html
.. _tutorial on layering in Omniverse: https://www.youtube.com/watch?v=LTwmNkSDh-c&ab_channel=NVIDIAOmniverse
diff --git a/docs/source/how-to/record_video.rst b/docs/source/how-to/record_video.rst
index aba74363129..01ee6240bb0 100644
--- a/docs/source/how-to/record_video.rst
+++ b/docs/source/how-to/record_video.rst
@@ -3,6 +3,9 @@ Recording video clips during training
Isaac Lab supports recording video clips during training using the
`gymnasium.wrappers.RecordVideo `_ class.
+When the ``--video`` flag is enabled, Isaac Lab captures a perspective view of the scene. The backend
+is chosen automatically from the active physics and renderer stack: an Isaac Sim Kit camera or a
+Newton GL headless viewer.
This feature can be enabled by installing ``ffmpeg`` and using the following command line arguments with the training
script:
@@ -11,7 +14,6 @@ script:
* ``--video_length``: length of each recorded video (in steps)
* ``--video_interval``: interval between each video recording (in steps)
-Make sure to also add the ``--enable_cameras`` argument when running headless.
Note that enabling recording is equivalent to enabling rendering during training, which will slow down both startup and runtime performance.
Example usage:
@@ -23,3 +25,128 @@ Example usage:
The recorded videos will be saved in the same directory as the training checkpoints, under
``IsaacLab/logs////videos/train``.
+
+
+Overview
+--------
+
+The video recording feature is implemented using the ``VideoRecorder`` class. This class is responsible for resolving the video backend from the scene, capturing the video frames, and saving them to a file.
+
+* ``VideoRecorderCfg`` (``isaaclab.envs.utils.video_recorder_cfg``) holds resolution and world-space
+ perspective parameters ``camera_position`` and ``camera_target`` (defaults to a diagonal view of the
+ scene).
+* ``VideoRecorder`` (``isaaclab.envs.utils.video_recorder``) picks a video backend from the scene
+ (Kit vs Newton GL), builds the matching low-level capture object, and returns RGB frames via
+ ``render_rgb_array()``.
+* Direct RL, Direct MARL and manager-based RL environments copy the task's
+ :class:`~isaaclab.envs.common.ViewerCfg` ``eye`` and ``lookat`` into those fields before the
+ recorder is constructed, so training clips align with the task's intended viewport when
+ ``origin_type`` is ``"world"``.
+
+
+Configuration: ``VideoRecorderCfg``
+------------------------------------
+
+The dataclass lives in ``isaaclab.envs.utils.video_recorder_cfg``. Fields ``camera_position`` and
+``camera_target`` are the perspective ``eye`` and ``lookat`` points in meters.
+
+.. literalinclude:: ../../../source/isaaclab/isaaclab/envs/utils/video_recorder_cfg.py
+ :language: python
+ :lines: 20-48
+
+
+Task framing: ``ViewerCfg``
+----------------------------
+
+Tasks define the interactive viewer with :class:`~isaaclab.envs.common.ViewerCfg`. The ``eye`` and
+``lookat`` tuples are the same values the RL base classes copy into ``VideoRecorderCfg`` (see below).
+If your task uses ``origin_type="world"``, those tuples are world-space positions and match what the
+perspective recorder expects.
+
+.. literalinclude:: ../../../source/isaaclab/isaaclab/envs/common.py
+ :language: python
+ :lines: 20-28
+
+
+Backend selection: Kit vs Newton GL
+-------------------------------------
+
+``VideoRecorder`` resolves the implementation from the live :class:`~isaaclab.scene.InteractiveScene`.
+If the user provides the PhysX physics (``presets=physx,...``) or Isaac RTX (``presets=isaac_rtx_renderer,...``) in the sensor stack, the Kit path is selected (``omni.replicator`` on
+``/OmniverseKit_Persp``). The Newton GL path is selected when Newton physics is active (``presets=newton,...``) or the Newton
+Warp renderer (``presets=newton_renderer,...``) appears in the sensor stack - and neither PhysX nor Isaac RTX is present to claim the
+Kit path. OVRTX (``presets=ovrtx_renderer,...`` from ``isaaclab_ov``) can pair with IsaacSim or Newton physics; in that case the video backend is
+selected via the physics preset. If both Kit and Newton GL signals are present (e.g., ``presets=physx,isaac_rtx_renderer,...`` or ``presets=newton,newton_renderer,...``), the Kit path is chosen.
+
+.. literalinclude:: ../../../source/isaaclab/isaaclab/envs/utils/video_recorder.py
+ :language: python
+ :lines: 38-59
+
+
+Construction and dispatch
+--------------------------
+
+When ``env_render_mode`` is ``"rgb_array"`` (as when wrappers or scripts request RGB frames for
+video), the recorder instantiates the backend-specific helper and passes through ``camera_position``,
+``camera_target``, and window size.
+
+.. literalinclude:: ../../../source/isaaclab/isaaclab/envs/utils/video_recorder.py
+ :language: python
+ :lines: 70-114
+
+
+Customising the camera view
+----------------------------
+
+When ``--video`` is passed, the recording camera uses the same
+position and look-at target as the interactive viewer. The defaults come from
+:class:`~isaaclab.envs.common.ViewerCfg`:
+
+* ``eye = (7.5, 7.5, 7.5)`` — camera position in world space (metres)
+* ``lookat = (0.0, 0.0, 0.0)`` — camera look-at target in world space (metres)
+* Resolution ``1280x720``
+
+To change the recording angle, override the ``viewer`` field in your task's environment config.
+The RL base classes automatically copy ``eye`` and ``lookat`` into ``VideoRecorderCfg`` before
+recording starts (when ``origin_type`` is ``"world"``), so the video clip uses the same viewpoint
+as the interactive viewport:
+
+.. code-block:: python
+
+ from isaaclab.envs import ManagerBasedRLEnvCfg
+ from isaaclab.envs.common import ViewerCfg
+ from isaaclab.utils import configclass
+
+ @configclass
+ class MyTaskCfg(ManagerBasedRLEnvCfg):
+ viewer: ViewerCfg = ViewerCfg(
+ eye=(5.0, 5.0, 5.0),
+ lookat=(0.0, 0.0, 1.0),
+ )
+
+
+Summary
+-------
+
+.. list-table::
+ :widths: 40 22 38
+ :header-rows: 1
+
+ * - Stack example (``presets=...``)
+ - Video backend
+ - Capture mechanism
+ * - ``physx,...`` or ``isaac_rtx_renderer,...``
+ - Kit (``"kit"``)
+ - ``/OmniverseKit_Persp`` + Replicator RGB
+ * - ``newton,...`` or ``newton_renderer,...`` (no Kit signals)
+ - Newton GL (``"newton_gl"``)
+ - ``newton.viewer.ViewerGL`` on the SDP Newton model
+ * - ``newton,...,ovrtx_renderer,...`` (OVRTX + Newton physics)
+ - Newton GL (``"newton_gl"``)
+ - ``newton.viewer.ViewerGL`` on the SDP Newton model
+
+
+See also
+--------
+
+* :doc:`/source/features/visualization` - interactive visualizers
diff --git a/docs/source/how-to/robots.rst b/docs/source/how-to/robots.rst
new file mode 100644
index 00000000000..39b011156b5
--- /dev/null
+++ b/docs/source/how-to/robots.rst
@@ -0,0 +1,67 @@
+.. _isaac-lab-robots:
+
+Robot Configurations
+=======================
+
+Robots are entirely defined as instances of configurations within Isaac Lab. If you examine ``source/isaaclab_assets/isaaclab_assets/robots``, you will see a number of files, each of which
+contains configurations for the robot in question. The purpose of these individual files is to better define scope for all the different robots, but there is nothing preventing
+you from :ref:`adding your own ` to your project or even to the ``isaaclab`` repository! For example, consider the following configuration for
+the Dofbot
+
+.. code-block:: python
+
+ import isaaclab.sim as sim_utils
+ from isaaclab.actuators import ImplicitActuatorCfg
+ from isaaclab.assets.articulation import ArticulationCfg
+ from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
+
+ DOFBOT_CONFIG = ArticulationCfg(
+ spawn=sim_utils.UsdFileCfg(
+ usd_path=f"{ISAAC_NUCLEUS_DIR}/Robots/Dofbot/dofbot.usd",
+ rigid_props=sim_utils.RigidBodyPropertiesCfg(
+ disable_gravity=False,
+ max_depenetration_velocity=5.0,
+ ),
+ articulation_props=sim_utils.ArticulationRootPropertiesCfg(
+ enabled_self_collisions=True, solver_position_iteration_count=8, solver_velocity_iteration_count=0
+ ),
+ ),
+ init_state=ArticulationCfg.InitialStateCfg(
+ joint_pos={
+ "joint1": 0.0,
+ "joint2": 0.0,
+ "joint3": 0.0,
+ "joint4": 0.0,
+ },
+ pos=(0.25, -0.25, 0.0),
+ ),
+ actuators={
+ "front_joints": ImplicitActuatorCfg(
+ joint_names_expr=["joint[1-2]"],
+ effort_limit_sim=100.0,
+ velocity_limit_sim=100.0,
+ stiffness=10000.0,
+ damping=100.0,
+ ),
+ "joint3_act": ImplicitActuatorCfg(
+ joint_names_expr=["joint3"],
+ effort_limit_sim=100.0,
+ velocity_limit_sim=100.0,
+ stiffness=10000.0,
+ damping=100.0,
+ ),
+ "joint4_act": ImplicitActuatorCfg(
+ joint_names_expr=["joint4"],
+ effort_limit_sim=100.0,
+ velocity_limit_sim=100.0,
+ stiffness=10000.0,
+ damping=100.0,
+ ),
+ },
+ )
+
+This completely defines the dofbot! You could copy this into a ``.py`` file and import it as a module and you would be able to use the dofbot in
+your own lab sims. One common feature you will see in any config defining things with state is the presence of an ``InitialStateCfg``. Remember, the configurations
+are what informs vectorization, and it's the ``InitialStateCfg`` that describes the state of the joints of our robot when it gets created in each environment. The
+``ImplicitActuatorCfg`` defines the joints of the robot using the default actuation model determined by the joint type. Not all joints need to be actuated, but you
+will get warnings if you don't. If you aren't planning on using those undefined joints, you can generally ignore these.
diff --git a/docs/source/how-to/save_camera_output.rst b/docs/source/how-to/save_camera_output.rst
index f92f9bcc93d..1c050afaa17 100644
--- a/docs/source/how-to/save_camera_output.rst
+++ b/docs/source/how-to/save_camera_output.rst
@@ -21,6 +21,10 @@ directory.
Saving using Replicator Basic Writer
------------------------------------
+.. note::
+ The BasicWriter is part of the Omniverse Replicator ecosystem and is specific to the default
+ Isaac RTX renderer backend. Other renderer backends may require different save workflows.
+
To save camera outputs, we use the basic write class from Omniverse Replicator. This class allows us to save the
images in a numpy format. For more information on the basic writer, please check the
`documentation `_.
@@ -32,18 +36,11 @@ images in a numpy format. For more information on the basic writer, please check
While stepping the simulator, the images can be saved to the defined folder. Since the BasicWriter only supports
saving data using NumPy format, we first need to convert the PyTorch sensors to NumPy arrays before packing
-them in a dictionary.
+them in a dictionary and writing with the BasicWriter.
.. literalinclude:: ../../../scripts/tutorials/04_sensors/run_usd_camera.py
:language: python
:start-at: # Save images from camera at camera_index
- :end-at: single_cam_info = camera.data.info[camera_index]
-
-After this step, we can save the images using the BasicWriter.
-
-.. literalinclude:: ../../../scripts/tutorials/04_sensors/run_usd_camera.py
- :language: python
- :start-at: # Pack data back into replicator format to save them using its writer
:end-at: rep_writer.write(rep_output)
diff --git a/docs/source/how-to/simulation_performance.rst b/docs/source/how-to/simulation_performance.rst
index 3dd113a1285..bab04b6e8c1 100644
--- a/docs/source/how-to/simulation_performance.rst
+++ b/docs/source/how-to/simulation_performance.rst
@@ -1,8 +1,16 @@
-Simulation Performance and Tuning
-====================================
+PhysX Simulation Performance and Tuning
+=========================================
-The performance of the simulation can be affected by various factors, including the number of objects in the scene,
-the complexity of the physics simulation, and the hardware being used. Here are some tips to improve performance:
+.. note::
+
+ This guide covers performance tuning for the **PhysX** backend, which is the default when
+ running Isaac Lab with Isaac Sim. For the **Newton** backend solver parameters (e.g.
+ ``njmax``, ``nconmax``, ``ls_iterations``), see the
+ :ref:`migrating-to-isaaclab-3-0` migration guide and the Newton physics documentation.
+
+The performance of the PhysX simulation can be affected by various factors, including the number
+of objects in the scene, the complexity of the physics simulation, and the hardware being used.
+Here are some tips to improve performance:
1. **Use Headless Mode**: Running the simulation in headless mode can significantly improve performance, especially
when rendering is not required. You can enable headless mode by using the ``--headless`` flag when running the
@@ -62,8 +70,8 @@ Additional Performance Guides
-----------------------------
There are many ways to "tune" the performance of the simulation, but the way you choose largely depends on what you are trying to simulate. In general, the first place
-you will want to look for performance gains is with the `physics engine `_. Next to rendering
-and running deep learning models, the physics engine is the most computationally costly. Tuning the physics sim to limit the scope to only the task of interest is a great place to
+you will want to look for performance gains is with the `PhysX engine `_. Next to rendering
+and running deep learning models, the PhysX engine is the most computationally costly. Tuning the PhysX sim to limit the scope to only the task of interest is a great place to
start hunting for performance gains.
We have recently released a new `gripper tuning guide `_ , specific to contact and grasp tuning. Please check it first if you intend to use robot grippers. For additional details, you should also checkout these guides!
diff --git a/docs/source/migration/migrating_deformables.rst b/docs/source/migration/migrating_deformables.rst
new file mode 100644
index 00000000000..efb7f7da689
--- /dev/null
+++ b/docs/source/migration/migrating_deformables.rst
@@ -0,0 +1,224 @@
+.. _migrating-deformables:
+
+Migration of Deformables
+========================
+
+.. currentmodule:: isaaclab
+
+In the newer versions of Omni Physics (107.0 and later), the old deformable body functionality has become deprecated.
+The following sections describe the changes to migrate to the new Omni Physics API, specifically moving away from
+Soft Bodies and towards Surface and Volume Deformables. We currently only support deformable bodies in the PhysX
+backend, hence these features are implemented in ``isaaclab_physx``.
+
+.. note::
+
+ The following changes are with respect to Isaac Lab v3.0.0 and Omni Physics v110.0. Please refer to the
+ `release notes`_ for any changes in the future releases.
+
+
+Surface and Volume Deformables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+With the new Omni Physics API, deformable bodies are split into two distinct types, as described in the
+`Omni Physics documentation`_:
+
+- **Volume deformables**: 3D objects simulated with a tetrahedral FEM mesh (e.g., soft cubes, spheres, capsules).
+ These support kinematic targets on individual vertices. The simulation operates on a tetrahedral mesh internally,
+ while a separate triangle surface mesh handles rendering.
+- **Surface deformables**: 2D surfaces simulated directly on a triangle mesh (e.g., cloth, fabric, membranes).
+ These have additional material properties for controlling stretch, shear, and bend stiffness, but do not support
+ kinematic vertex targets.
+
+The type of deformable is determined by the **physics material** assigned to the object:
+
+- :class:`~isaaclab_physx.sim.DeformableBodyMaterialCfg` creates a **volume** deformable.
+- :class:`~isaaclab_physx.sim.SurfaceDeformableBodyMaterialCfg` creates a **surface** deformable.
+
+
+Migration from the Old API
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Import Changes
+^^^^^^^^^^^^^^
+
+All deformable-related classes have moved from ``isaaclab`` to ``isaaclab_physx``. The table below summarizes the
+import changes:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Old Import
+ - New Import
+ * - ``from isaaclab.sim import DeformableBodyPropertiesCfg``
+ - ``from isaaclab_physx.sim import DeformableBodyPropertiesCfg``
+ * - ``from isaaclab.sim import DeformableBodyMaterialCfg``
+ - ``from isaaclab_physx.sim import DeformableBodyMaterialCfg``
+
+
+Removed Properties
+^^^^^^^^^^^^^^^^^^
+
+The following properties have been **removed** from :class:`~isaaclab_physx.sim.DeformableBodyPropertiesCfg`:
+
+- ``collision_simplification`` and related parameters (``collision_simplification_remeshing``,
+ ``collision_simplification_target_triangle_count``, ``collision_simplification_force_conforming``,
+ ``collision_simplification_remove_open_edges``) — collision mesh generation is now handled automatically by
+ PhysX through ``deformableUtils.create_auto_volume_deformable_hierarchy()`` and
+ ``deformableUtils.create_auto_surface_deformable_hierarchy()``.
+- ``simulation_hexahedral_resolution`` — the simulation mesh resolution is no longer user-configurable;
+ PhysX determines it automatically.
+- ``vertex_velocity_damping`` — replaced by the more general ``linear_damping`` property from the
+ `PhysX deformable schema`_.
+- ``sleep_damping`` — replaced by ``settling_damping`` in the `PhysX deformable schema`_.
+
+Added Properties
+^^^^^^^^^^^^^^^^
+
+The following properties have been **added** to :class:`~isaaclab_physx.sim.DeformableBodyPropertiesCfg`:
+
+- ``linear_damping`` — linear damping coefficient [1/s].
+- ``max_linear_velocity`` — maximum allowable linear velocity [m/s]. A negative value lets the simulation choose
+ a per-vertex value dynamically (currently only supported for surface deformables).
+- ``settling_damping`` — additional damping applied when vertex velocity falls below ``settling_threshold`` [1/s].
+- ``enable_speculative_c_c_d`` — enables speculative continuous collision detection.
+- ``disable_gravity`` — per-deformable gravity control.
+- ``collision_pair_update_frequency`` — how often surface-to-surface collision pairs are updated per time step
+ (surface deformables only).
+- ``collision_iteration_multiplier`` — collision subiterations per solver iteration (surface deformables only).
+
+For a full description of all available properties, refer to the `PhysX deformable schema`_ and
+`OmniPhysics deformable schema`_ documentation.
+
+Material Changes
+^^^^^^^^^^^^^^^^
+
+The old :class:`DeformableBodyMaterialCfg` (from ``isaaclab.sim``) has been replaced by a new hierarchy in
+``isaaclab_physx``:
+
+- :class:`~isaaclab_physx.sim.DeformableBodyMaterialCfg` — for volume deformables. Contains ``density``,
+ ``static_friction``, ``dynamic_friction``, ``youngs_modulus``, ``poissons_ratio``, and ``elasticity_damping``.
+- :class:`~isaaclab_physx.sim.SurfaceDeformableBodyMaterialCfg` — extends the volume material config with
+ surface-specific properties: ``surface_thickness``, ``surface_stretch_stiffness``, ``surface_shear_stiffness``,
+ ``surface_bend_stiffness``, and ``bend_damping``.
+
+The old ``damping_scale`` property has been removed. Use ``elasticity_damping`` directly instead.
+
+DeformableObject View Change
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The internal PhysX view type has changed from ``physx.SoftBodyView`` to ``physx.DeformableBodyView``.
+The property ``root_physx_view`` has been deprecated in favor of ``root_view``.
+
+
+Code Examples
+~~~~~~~~~~~~~
+
+Volume Deformable (Before and After)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**Before**:
+
+.. code-block:: python
+ :emphasize-lines: 1,2
+
+ import isaaclab.sim as sim_utils
+ from isaaclab.assets import DeformableObject, DeformableObjectCfg
+
+ cfg = DeformableObjectCfg(
+ prim_path="/World/Origin.*/Cube",
+ spawn=sim_utils.MeshCuboidCfg(
+ size=(0.2, 0.2, 0.2),
+ deformable_props=sim_utils.DeformableBodyPropertiesCfg(),
+ visual_material=sim_utils.PreviewSurfaceCfg(),
+ physics_material=sim_utils.DeformableBodyMaterialCfg(poissons_ratio=0.4, youngs_modulus=1e5),
+ ),
+ )
+ cube_object = DeformableObject(cfg=cfg)
+
+**After**:
+
+.. code-block:: python
+ :emphasize-lines: 1,2,3
+
+ import isaaclab.sim as sim_utils
+ from isaaclab_physx.assets import DeformableObject, DeformableObjectCfg
+ from isaaclab_physx.sim import DeformableBodyPropertiesCfg, DeformableBodyMaterialCfg
+
+ cfg = DeformableObjectCfg(
+ prim_path="/World/Origin.*/Cube",
+ spawn=sim_utils.MeshCuboidCfg(
+ size=(0.2, 0.2, 0.2),
+ deformable_props=DeformableBodyPropertiesCfg(),
+ visual_material=sim_utils.PreviewSurfaceCfg(),
+ physics_material=DeformableBodyMaterialCfg(poissons_ratio=0.4, youngs_modulus=1e5),
+ ),
+ )
+ cube_object = DeformableObject(cfg=cfg)
+
+Surface Deformable (New)
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Surface deformables use :class:`~isaaclab.sim.spawners.meshes.MeshSquareCfg` for 2D meshes, combined with
+:class:`~isaaclab_physx.sim.SurfaceDeformableBodyMaterialCfg`:
+
+.. code-block:: python
+
+ import isaaclab.sim as sim_utils
+ from isaaclab_physx.assets import DeformableObject, DeformableObjectCfg
+ from isaaclab_physx.sim import DeformableBodyPropertiesCfg, SurfaceDeformableBodyMaterialCfg
+
+ cfg = DeformableObjectCfg(
+ prim_path="/World/Origin.*/Cloth",
+ spawn=sim_utils.MeshSquareCfg(
+ size=1.5,
+ resolution=(21, 21),
+ deformable_props=DeformableBodyPropertiesCfg(),
+ visual_material=sim_utils.PreviewSurfaceCfg(),
+ physics_material=SurfaceDeformableBodyMaterialCfg(poissons_ratio=0.4, youngs_modulus=1e5),
+ ),
+ )
+ cloth_object = DeformableObject(cfg=cfg)
+
+USD File Deformable
+^^^^^^^^^^^^^^^^^^^
+
+Deformable properties can also be applied to imported USD assets using
+:class:`~isaaclab.sim.spawners.from_files.UsdFileCfg`:
+
+.. code-block:: python
+
+ import isaaclab.sim as sim_utils
+ from isaaclab_physx.assets import DeformableObject, DeformableObjectCfg
+ from isaaclab_physx.sim import DeformableBodyPropertiesCfg, DeformableBodyMaterialCfg
+
+ from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR
+
+ cfg = DeformableObjectCfg(
+ prim_path="/World/Origin.*/Teddy",
+ spawn=sim_utils.UsdFileCfg(
+ usd_path=f"{ISAACLAB_NUCLEUS_DIR}/Objects/Teddy_Bear/teddy_bear.usd",
+ deformable_props=DeformableBodyPropertiesCfg(),
+ physics_material=DeformableBodyMaterialCfg(poissons_ratio=0.4, youngs_modulus=1e5),
+ scale=[0.05, 0.05, 0.05],
+ ),
+ )
+ teddy_object = DeformableObject(cfg=cfg)
+
+
+Limitations
+~~~~~~~~~~~
+
+- **Kinematic targets are volume-only.** Calling
+ :meth:`~isaaclab_physx.assets.DeformableObject.write_nodal_kinematic_target_to_sim_index` on a surface
+ deformable will raise a ``ValueError``.
+- **Surface-specific solver properties** (``collision_pair_update_frequency``,
+ ``collision_iteration_multiplier``) have no effect on volume deformables.
+- **Deformables are PhysX-only.** The ``isaaclab_physx`` extension is required; other physics backends
+ do not support deformable bodies through Isaac Lab yet.
+
+
+.. _Omni Physics documentation: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/110.0/dev_guide/deformables/deformable_bodies.html
+.. _PhysX deformable schema: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/110.0/dev_guide/deformables/physx_deformable_schema.html#physxbasedeformablebodyapi
+.. _OmniPhysics deformable schema: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/110.0/dev_guide/deformables/omniphysics_deformable_schema.html
+.. _release notes: https://github.com/isaac-sim/IsaacLab/releases
diff --git a/docs/source/migration/migrating_to_isaaclab_3-0.rst b/docs/source/migration/migrating_to_isaaclab_3-0.rst
new file mode 100644
index 00000000000..6787a42766e
--- /dev/null
+++ b/docs/source/migration/migrating_to_isaaclab_3-0.rst
@@ -0,0 +1,1709 @@
+.. _migrating-to-isaaclab-3-0:
+
+Migrating to Isaac Lab 3.0
+==========================
+
+.. currentmodule:: isaaclab
+
+Isaac Lab 3.0 introduces a multi-backend architecture that separates simulation backend-specific code
+from the core Isaac Lab API. This allows for future support of different physics backends while
+maintaining a consistent user-facing API.
+
+This guide covers the main breaking changes and deprecations you need to address when migrating
+from Isaac Lab 2.x to Isaac Lab 3.0.
+
+
+Visualizer CLI and Headless Behavior
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In Isaac Lab 3.0, the ``--headless`` argument is deprecated. Instead, use ``--visualizer`` / ``--viz``
+to determine whether viewer apps are launched with an Isaac Lab command.
+
+Visualizers are lightweight viewer apps for monitoring, debugging, and recording workflows
+(see :doc:`/source/features/visualization`).
+
+The details below describe how CLI visualizer arguments resolve together with
+``SimulationCfg.visualizer_cfgs``.
+
+- ``--viz`` accepts **comma-separated** values (for example ``--viz kit,newton``).
+- If omitted, visualizers are resolved from ``SimulationCfg.visualizer_cfgs``.
+- ``--viz none`` explicitly disables all visualizers, including config-defined ones.
+- ``--headless`` is deprecated (still supported) and overrides ``--viz`` by forcing headless mode.
+
+For the full behavior of visualizer resolution, with the visualizer CLI arg, visualizer configs,
+and ``--headless``, see :ref:`visualization-common-modes`.
+
+
+Multi-Backend Architecture
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Isaac Lab 3.0 introduces a **factory-based multi-backend architecture** that allows asset classes
+to be backed by different physics engines — currently **PhysX** and **Newton**.
+
+When you instantiate an asset class from the ``isaaclab`` package (e.g., ``Articulation``,
+``RigidObject``), a factory automatically resolves and loads the correct backend implementation:
+
+.. code-block:: python
+
+ from isaaclab.assets import Articulation, ArticulationCfg
+
+ # The factory pattern creates the appropriate backend implementation.
+ # No import changes are needed — the same isaaclab imports work regardless of backend.
+ robot = Articulation(cfg=ArticulationCfg(...))
+
+The factory works by convention: for a class defined in ``isaaclab.assets.articulation``, it
+imports the matching class from ``isaaclab_{backend}.assets.articulation``. This means the
+``isaaclab_physx`` and ``isaaclab_newton`` packages mirror the ``isaaclab`` module structure.
+
+.. note::
+
+ The backend is currently set to ``"physx"`` by default. Newton backend support is being
+ actively developed. When backend selection is fully configurable, you will be able to
+ switch backends without changing any asset import paths.
+
+For a comprehensive overview of the factory pattern, backend selection, and how to add a new
+backend, see :doc:`/source/overview/core-concepts/multi_backend_architecture`.
+
+New ``isaaclab_physx`` and ``isaaclab_newton`` Extensions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two new backend extensions have been introduced:
+
+- **``isaaclab_physx``** — PhysX-specific implementations of all asset and sensor classes.
+- **``isaaclab_newton``** — Newton-specific implementations of asset classes (Articulation and
+ RigidObject).
+
+The following classes have been moved to ``isaaclab_physx``:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Isaac Lab 2.x
+ - Isaac Lab 3.0
+ * - ``from isaaclab.assets import DeformableObject``
+ - ``from isaaclab_physx.assets import DeformableObject``
+ * - ``from isaaclab.assets import DeformableObjectCfg``
+ - ``from isaaclab_physx.assets import DeformableObjectCfg``
+ * - ``from isaaclab.assets import DeformableObjectData``
+ - ``from isaaclab_physx.assets import DeformableObjectData``
+ * - ``from isaaclab.assets import SurfaceGripper``
+ - ``from isaaclab_physx.assets import SurfaceGripper``
+ * - ``from isaaclab.assets import SurfaceGripperCfg``
+ - ``from isaaclab_physx.assets import SurfaceGripperCfg``
+
+.. note::
+
+ The ``isaaclab_physx`` extension is installed automatically with Isaac Lab. No additional
+ installation steps are required.
+
+
+Renaming of ``XformPrimView`` to ``FrameView``
+-----------------------------------------------
+
+Isaac Lab's ``XformPrimView`` and related classes have been renamed to ``FrameView`` to
+better reflect their purpose and avoid confusion with Isaac Sim's ``XFormPrim`` class
+hierarchy. The old ``XformPrimView`` name is kept as a deprecated alias.
+
+The rename applies across all backends:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Isaac Lab 2.x
+ - Isaac Lab 3.0
+ * - ``BaseXformPrimView``
+ - :class:`~isaaclab.sim.views.BaseFrameView`
+ * - ``UsdXformPrimView``
+ - :class:`~isaaclab.sim.views.UsdFrameView`
+ * - ``XformPrimView``
+ - :class:`~isaaclab.sim.views.FrameView`
+ * - ``FabricXformPrimView``
+ - :class:`~isaaclab_physx.sim.views.FabricFrameView`
+ * - ``NewtonSiteXformPrimView``
+ - :class:`~isaaclab_newton.sim.views.NewtonSiteFrameView`
+
+For most users, the only change needed is updating imports:
+
+.. code-block:: python
+
+ # Before
+ from isaaclab.sim.views import XformPrimView
+
+ # After
+ from isaaclab.sim.views import FrameView
+
+The :class:`~isaaclab.sim.views.FrameView` factory automatically dispatches to the correct
+backend (:class:`~isaaclab_physx.sim.views.FabricFrameView` for PhysX,
+:class:`~isaaclab_newton.sim.views.NewtonSiteFrameView` for Newton) based on the active
+physics backend. The deprecated ``XformPrimView`` alias continues to work but will be
+removed in a future release.
+
+
+Unchanged Imports
+-----------------
+
+The following asset classes remain in the ``isaaclab`` package and can still be imported as before:
+
+- :class:`~isaaclab.assets.Articulation`, :class:`~isaaclab.assets.ArticulationCfg`, :class:`~isaaclab.assets.ArticulationData`
+- :class:`~isaaclab.assets.RigidObject`, :class:`~isaaclab.assets.RigidObjectCfg`, :class:`~isaaclab.assets.RigidObjectData`
+- :class:`~isaaclab.assets.RigidObjectCollection`, :class:`~isaaclab.assets.RigidObjectCollectionCfg`, :class:`~isaaclab.assets.RigidObjectCollectionData`
+
+These classes now inherit from new abstract base classes but maintain full backward compatibility.
+
+The following sensor classes also remain in the ``isaaclab`` package with unchanged imports:
+
+- :class:`~isaaclab.sensors.ContactSensor`, :class:`~isaaclab.sensors.ContactSensorCfg`, :class:`~isaaclab.sensors.ContactSensorData`
+- :class:`~isaaclab.sensors.Imu`, :class:`~isaaclab.sensors.ImuCfg`, :class:`~isaaclab.sensors.ImuData`
+- :class:`~isaaclab.sensors.Pva`, :class:`~isaaclab.sensors.PvaCfg`, :class:`~isaaclab.sensors.PvaData`
+- :class:`~isaaclab.sensors.FrameTransformer`, :class:`~isaaclab.sensors.FrameTransformerCfg`, :class:`~isaaclab.sensors.FrameTransformerData`
+
+These sensor classes now use factory patterns that automatically instantiate the appropriate backend
+implementation (PhysX by default), maintaining full backward compatibility.
+
+.. note::
+
+ The ``Imu`` sensor in Isaac Lab 3.0 is **not** the same as the ``Imu`` sensor in 2.x.
+ The old ``Imu`` (full state sensor) has been renamed to :class:`~isaaclab.sensors.Pva`.
+ The new :class:`~isaaclab.sensors.Imu` is a lightweight sensor that only provides angular velocity
+ and linear acceleration. See :ref:`imu-to-pva-migration` below for details.
+
+If you need to import the PhysX sensor implementations directly (e.g., for type hints or subclassing),
+you can import from ``isaaclab_physx.sensors``:
+
+.. code-block:: python
+
+ # Direct PhysX implementation imports
+ from isaaclab_physx.sensors import ContactSensor, ContactSensorData
+ from isaaclab_physx.sensors import Imu, ImuData
+ from isaaclab_physx.sensors import Pva, PvaData
+ from isaaclab_physx.sensors import FrameTransformer, FrameTransformerData
+
+
+New ``isaaclab_newton`` Extension
+---------------------------------
+
+A new extension ``isaaclab_newton`` provides Newton physics backend implementations for:
+
+- :class:`~isaaclab_newton.assets.Articulation` and :class:`~isaaclab_newton.assets.ArticulationData`
+- :class:`~isaaclab_newton.assets.RigidObject` and :class:`~isaaclab_newton.assets.RigidObjectData`
+
+These classes implement the same base interfaces as their PhysX counterparts
+(:class:`~isaaclab.assets.BaseArticulation`, :class:`~isaaclab.assets.BaseRigidObject`),
+ensuring a consistent API across backends. They use the same warp-based data conventions
+(``wp.array`` with structured types, ``_index`` / ``_mask`` write methods).
+
+.. note::
+
+ The ``isaaclab_newton`` extension requires the ``newton`` package and its dependencies
+ (``mujoco``, ``mujoco-warp``). These are installed automatically when installing the
+ ``isaaclab_newton`` package.
+
+If you need to import Newton implementations directly (e.g., for type hints or subclassing):
+
+.. code-block:: python
+
+ from isaaclab_newton.assets import Articulation as NewtonArticulation
+ from isaaclab_newton.assets import RigidObject as NewtonRigidObject
+
+
+Deformable Object API Changes
+------------------------------
+
+Isaac Lab 3.0 updates the deformable body API to align with the current Omni Physics 110.0
+release. The old soft body API has been deprecated and replaced by two distinct deformable
+types: **volume deformables** (3D FEM tetrahedral meshes) and **surface deformables** (2D
+triangle cloth meshes). The deformable type is determined by the physics material assigned:
+
+- :class:`~isaaclab_physx.sim.DeformableBodyMaterialCfg` for volume deformables.
+- :class:`~isaaclab_physx.sim.SurfaceDeformableBodyMaterialCfg` for surface deformables.
+
+All deformable-related classes have moved from ``isaaclab`` to ``isaaclab_physx``, as shown
+in the import table above. Several properties on
+:class:`~isaaclab_physx.sim.DeformableBodyPropertiesCfg` have been removed or added to match
+the new Omni Physics schema.
+
+For a comprehensive guide covering the full deformable API migration — including removed and
+added properties, material changes, code examples for both volume and surface deformables, and
+current limitations — see :ref:`migrating-deformables`.
+
+
+.. _imu-to-pva-migration:
+
+IMU Sensor Renamed to PVA; New Lightweight IMU Sensor
+-----------------------------------------------------
+
+The old ``Imu`` sensor has been renamed to **PVA** (Pose Velocity Acceleration) because it provided
+full pose, velocity, and acceleration data — far more than a real inertial measurement unit measures.
+A new lightweight **IMU** sensor has been introduced that only provides the two physical quantities
+a real IMU measures: angular velocity (gyroscope) and linear acceleration (accelerometer).
+
+If you were using the old ``Imu`` sensor, you need to decide which new sensor to use:
+
+- Use :class:`~isaaclab.sensors.Pva` / :class:`~isaaclab.sensors.PvaCfg` if you need full state
+ data (pose, linear velocity, angular velocity, linear and angular acceleration, projected gravity).
+- Use :class:`~isaaclab.sensors.Imu` / :class:`~isaaclab.sensors.ImuCfg` if you only need angular
+ velocity and linear acceleration (as a real IMU provides).
+
+**Import changes:**
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x) — the old IMU provided full state
+ from isaaclab.sensors import Imu, ImuCfg, ImuData
+
+ # After (Isaac Lab 3.x) — use PVA for the same full-state sensor
+ from isaaclab.sensors import Pva, PvaCfg, PvaData
+
+ # Or use the new lightweight IMU for angular velocity + linear acceleration only
+ from isaaclab.sensors import Imu, ImuCfg, ImuData
+
+**Configuration changes:**
+
+The ``gravity_bias`` configuration parameter has been removed from both sensors:
+
+- **PVA** reports raw kinematic acceleration (no gravity contribution), as the acceleration
+ is derived from finite differencing of velocities which do not include gravity.
+- **IMU** unconditionally includes gravity in its accelerometer readings, matching the behavior
+ of a real accelerometer. The gravity vector is automatically queried from the simulation.
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x)
+ imu_cfg = ImuCfg(
+ prim_path="{ENV_REGEX_NS}/Robot/base",
+ gravity_bias=(0.0, 0.0, 9.81), # had to be configured manually
+ )
+
+ # After (Isaac Lab 3.x) — PVA (no gravity in acceleration)
+ pva_cfg = PvaCfg(prim_path="{ENV_REGEX_NS}/Robot/base")
+
+ # After (Isaac Lab 3.x) — IMU (gravity always included automatically)
+ imu_cfg = ImuCfg(prim_path="{ENV_REGEX_NS}/Robot/base")
+
+**Observation function changes:**
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x)
+ from isaaclab.envs.mdp import imu_orientation, imu_projected_gravity
+
+ # After (Isaac Lab 3.x)
+ from isaaclab.envs.mdp import pva_orientation, pva_projected_gravity
+
+**Data property changes:**
+
+The new ``ImuData`` only provides ``ang_vel_b`` and ``lin_acc_b``. If you were accessing other
+properties (``pos_w``, ``quat_w``, ``lin_vel_b``, ``ang_acc_b``, ``projected_gravity_b``), switch
+to :class:`~isaaclab.sensors.PvaData` which provides all of them.
+
+
+Sensor Pose Properties Deprecation
+----------------------------------
+
+The ``pose_w``, ``pos_w``, and ``quat_w`` properties on :class:`~isaaclab.sensors.ContactSensorData`
+are deprecated and will be removed in a future release.
+
+If you need to track sensor poses in world frame, please use a dedicated sensor such as
+:class:`~isaaclab.sensors.FrameTransformer` instead.
+
+**Before (deprecated):**
+
+.. code-block:: python
+
+ # Using pose properties directly on sensor data
+ sensor_pos = contact_sensor.data.pos_w
+ sensor_quat = contact_sensor.data.quat_w
+
+**After (recommended):**
+
+.. code-block:: python
+
+ # Use FrameTransformer to track sensor pose
+ frame_transformer = FrameTransformer(FrameTransformerCfg(
+ prim_path="{ENV_REGEX_NS}/Robot/base",
+ target_frames=[
+ FrameTransformerCfg.FrameCfg(prim_path="{ENV_REGEX_NS}/Robot/sensor_link"),
+ ],
+ ))
+ sensor_pos = frame_transformer.data.target_pos_w
+ sensor_quat = frame_transformer.data.target_quat_w
+
+
+Multi-Backend Support: PresetCfg Pattern
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Isaac Lab 3.0 introduces a **PresetCfg pattern** for writing environment configurations
+that work with both the PhysX and Newton backends. Instead of hard-coding a single
+physics config, environments declare named configuration variants. The active variant
+is selected at launch via a Hydra CLI override.
+
+What is PresetCfg?
+------------------
+
+:class:`~isaaclab_tasks.utils.PresetCfg` is a base ``@configclass`` whose typed fields
+represent named variants of a configuration section. The field named ``default`` is used
+when no CLI override is given. Other fields are named presets selectable with
+``presets=`` on the command line:
+
+.. code-block:: python
+
+ from isaaclab_tasks.utils import PresetCfg
+ from isaaclab.utils import configclass
+
+ @configclass
+ class MyPhysicsCfg(PresetCfg):
+ default: PhysxCfg = PhysxCfg(...) # used when no override is given
+ physx: PhysxCfg = PhysxCfg(...) # selected by presets=physx
+ newton: NewtonCfg = NewtonCfg(...) # selected by presets=newton
+
+Selecting a preset at launch
+-----------------------------
+
+Pass ``presets=newton`` (or ``presets=physx``) on the CLI to swap the entire config section:
+
+.. code-block:: bash
+
+ # Run with Newton backend
+ python train.py task=Isaac-Franka-Cabinet-v0 presets=newton
+
+ # Run with default (PhysX) backend
+ python train.py task=Isaac-Franka-Cabinet-v0
+
+Adding Multi-Backend Support to an Environment
+-----------------------------------------------
+
+**Step 1 — Physics config**
+
+Replace a plain ``PhysxCfg(...)`` assignment in ``__post_init__`` with a ``PresetCfg``
+subclass that carries both a PhysX and a Newton variant.
+
+*Before:*
+
+.. code-block:: python
+
+ def __post_init__(self):
+ self.sim.dt = 1 / 60
+ self.sim.physics = PhysxCfg(bounce_threshold_velocity=0.2)
+
+*After:*
+
+.. code-block:: python
+
+ from isaaclab_newton.physics import MJWarpSolverCfg, NewtonCfg
+ from isaaclab_physx.physics import PhysxCfg
+ from isaaclab_tasks.utils import PresetCfg
+
+ @configclass
+ class ReachPhysicsCfg(PresetCfg):
+ default: PhysxCfg = PhysxCfg(bounce_threshold_velocity=0.2)
+ physx: PhysxCfg = PhysxCfg(bounce_threshold_velocity=0.2)
+ newton: NewtonCfg = NewtonCfg(
+ solver_cfg=MJWarpSolverCfg(
+ njmax=20, nconmax=20, ls_iterations=20,
+ cone="pyramidal", ls_parallel=True,
+ integrator="implicitfast", impratio=1,
+ ),
+ num_substeps=1,
+ debug_mode=False,
+ )
+
+ # In the env cfg __post_init__:
+ def __post_init__(self):
+ self.sim.dt = 1 / 60
+ self.sim.physics = ReachPhysicsCfg()
+
+Key Newton solver parameters:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 25 75
+
+ * - Parameter
+ - Effect
+ * - ``njmax``
+ - Max constraint rows; set ≥ expected contact count per env
+ * - ``nconmax``
+ - Max contacts per env
+ * - ``ls_iterations``
+ - Linear solver iterations (higher = more stable, slower)
+ * - ``cone``
+ - ``"pyramidal"`` (fast) or ``"elliptic"`` (more accurate)
+ * - ``integrator``
+ - ``"implicitfast"`` (recommended) or ``"euler"``
+ * - ``impratio``
+ - Impedance ratio; >1 improves soft contact stability
+ * - ``num_substeps``
+ - Physics substeps per environment step
+
+**Step 2 — Differentiating Newton and PhysX Configs**
+
+Not all configurations may be the same between Newton and PhysX simulations.
+We can provide a Newton-specific config such as:
+
+.. code-block:: python
+
+ @configclass
+ class EventCfg:
+ """Full event config (PhysX-compatible)."""
+ robot_physics_material = EventTerm(
+ func=mdp.randomize_rigid_body_material,
+ mode="startup",
+ params={...},
+ )
+ reset_all = EventTerm(func=mdp.reset_scene_to_default, mode="reset")
+ reset_robot_joints = EventTerm(
+ func=mdp.reset_joints_by_offset, mode="reset", params={...}
+ )
+
+
+ @configclass
+ class _EnvNewtonEventCfg:
+ """Newton-compatible events."""
+ reset_all = EventTerm(func=mdp.reset_scene_to_default, mode="reset")
+ reset_robot_joints = EventTerm(
+ func=mdp.reset_joints_by_offset, mode="reset", params={...}
+ )
+
+
+ @configclass
+ class EnvEventCfg(PresetCfg):
+ default: EventCfg = EventCfg()
+ physx: EventCfg = EventCfg()
+ newton: _EnvNewtonEventCfg = _EnvNewtonEventCfg()
+
+Then change the ``events`` field in your env cfg from ``EventCfg`` to ``EnvEventCfg``:
+
+.. code-block:: python
+
+ @configclass
+ class MyEnvCfg(ManagerBasedRLEnvCfg):
+ events: EnvEventCfg = EnvEventCfg() # was: EventCfg = EventCfg()
+
+
+RigidObjectCollection API Renaming
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :class:`~isaaclab_physx.assets.RigidObjectCollection` and
+:class:`~isaaclab_physx.assets.RigidObjectCollectionData` classes have undergone an API rename
+to provide consistency with other asset classes. The ``object_*`` naming convention has been
+deprecated in favor of ``body_*``.
+
+
+Method Renames
+--------------
+
+The following methods have been renamed. The old methods are deprecated and will be removed in a
+future release:
+
++------------------------------------------+------------------------------------------+
+| Deprecated (2.x) | New (3.0) |
++==========================================+==========================================+
+| ``write_object_state_to_sim()`` | ``write_body_state_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_link_state_to_sim()`` | ``write_body_link_state_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_pose_to_sim()`` | ``write_body_pose_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_link_pose_to_sim()`` | ``write_body_link_pose_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_com_pose_to_sim()`` | ``write_body_com_pose_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_velocity_to_sim()`` | ``write_body_com_velocity_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_com_velocity_to_sim()`` | ``write_body_com_velocity_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``write_object_link_velocity_to_sim()`` | ``write_body_link_velocity_to_sim()`` |
++------------------------------------------+------------------------------------------+
+| ``find_objects()`` | ``find_bodies()`` |
++------------------------------------------+------------------------------------------+
+
+
+Property Renames (Data Class)
+-----------------------------
+
+The following properties on :class:`~isaaclab_physx.assets.RigidObjectCollectionData` have been
+renamed. The old properties are deprecated and will be removed in a future release:
+
++------------------------------------------+------------------------------------------+
+| Deprecated (2.x) | New (3.0) |
++==========================================+==========================================+
+| ``default_object_state`` | ``default_body_state`` |
++------------------------------------------+------------------------------------------+
+| ``object_names`` | ``body_names`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_pose_w`` | ``body_link_pose_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_vel_w`` | ``body_link_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_pose_w`` | ``body_com_pose_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_vel_w`` | ``body_com_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_state_w`` | ``body_state_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_state_w`` | ``body_link_state_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_state_w`` | ``body_com_state_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_acc_w`` | ``body_com_acc_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_pose_b`` | ``body_com_pose_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_pos_w`` | ``body_link_pos_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_quat_w`` | ``body_link_quat_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_lin_vel_w`` | ``body_link_lin_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_ang_vel_w`` | ``body_link_ang_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_pos_w`` | ``body_com_pos_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_quat_w`` | ``body_com_quat_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_lin_vel_w`` | ``body_com_lin_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_ang_vel_w`` | ``body_com_ang_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_lin_acc_w`` | ``body_com_lin_acc_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_ang_acc_w`` | ``body_com_ang_acc_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_pos_b`` | ``body_com_pos_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_quat_b`` | ``body_com_quat_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_lin_vel_b`` | ``body_link_lin_vel_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_link_ang_vel_b`` | ``body_link_ang_vel_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_lin_vel_b`` | ``body_com_lin_vel_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_com_ang_vel_b`` | ``body_com_ang_vel_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_pose_w`` | ``body_pose_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_pos_w`` | ``body_pos_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_quat_w`` | ``body_quat_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_vel_w`` | ``body_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_lin_vel_w`` | ``body_lin_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_ang_vel_w`` | ``body_ang_vel_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_lin_vel_b`` | ``body_lin_vel_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_ang_vel_b`` | ``body_ang_vel_b`` |
++------------------------------------------+------------------------------------------+
+| ``object_acc_w`` | ``body_acc_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_lin_acc_w`` | ``body_lin_acc_w`` |
++------------------------------------------+------------------------------------------+
+| ``object_ang_acc_w`` | ``body_ang_acc_w`` |
++------------------------------------------+------------------------------------------+
+
+.. note::
+
+ All deprecated methods and properties will issue a deprecation warning when used. Your existing
+ code will continue to work, but you should migrate to the new API to avoid issues in future releases.
+
+
+Migration Example
+-----------------
+
+Here's a complete example showing how to update your code:
+
+**Before (Isaac Lab 2.x):**
+
+.. code-block:: python
+
+ from isaaclab.assets import DeformableObject, DeformableObjectCfg
+ from isaaclab.assets import SurfaceGripper, SurfaceGripperCfg
+ from isaaclab.assets import RigidObjectCollection
+
+ # Using deprecated root_physx_view
+ robot = scene["robot"]
+ masses = robot.root_physx_view.get_masses()
+
+ # Using deprecated object_* API
+ collection = scene["object_collection"]
+ poses = collection.data.object_pose_w
+ collection.write_object_state_to_sim(state, env_ids=env_ids, object_ids=object_ids)
+
+**After (Isaac Lab 3.0):**
+
+.. code-block:: python
+
+ from isaaclab_physx.assets import DeformableObject, DeformableObjectCfg
+ from isaaclab_physx.assets import SurfaceGripper, SurfaceGripperCfg
+ from isaaclab.assets import RigidObjectCollection # unchanged
+
+ # Using new root_view property
+ robot = scene["robot"]
+ masses = robot.root_view.get_masses()
+
+ # Using new body_* API
+ collection = scene["object_collection"]
+ poses = collection.data.body_pose_w
+ collection.write_body_state_to_sim(state, env_ids=env_ids, body_ids=object_ids)
+
+
+Quaternion Format
+~~~~~~~~~~~~~~~~~
+
+**The quaternion format changed from WXYZ to XYZW.**
+
++------------------+----------------------------------+----------------------------------+
+| Component | Old Format (WXYZ) | New Format (XYZW) |
++==================+==================================+==================================+
+| Order | ``(w, x, y, z)`` | ``(x, y, z, w)`` |
++------------------+----------------------------------+----------------------------------+
+| Identity | ``(1.0, 0.0, 0.0, 0.0)`` | ``(0.0, 0.0, 0.0, 1.0)`` |
++------------------+----------------------------------+----------------------------------+
+
+
+Why This Change?
+----------------
+
+The new XYZW format aligns with:
+
+- **Warp**: NVIDIA's spatial computing framework
+- **PhysX**: PhysX physics engine
+- **Newton**: Newton multi-solver framework
+
+This alignment removes the need for internal quaternion conversions, making the code simpler,
+faster, and less error-prone.
+
+
+What You Need to Update
+-----------------------
+
+Any hard-coded quaternion values in your code need to be converted from WXYZ to XYZW.
+This includes:
+
+1. **Configuration files** - ``rot`` parameters in asset configs
+2. **Task definitions** - Goal poses, initial states
+3. **Controller parameters** - Target orientations
+4. **Documentation** - Code examples with quaternions
+
+Also, if you were relying on the :func:`~isaaclab.utils.math.convert_quat` function to convert quaternions, this should
+no longer be needed. (This would happen if you were pulling values from the views directly.)
+
+Example: Updating Asset Configuration
+-------------------------------------
+
+**Before (WXYZ):**
+
+.. code-block:: python
+
+ from isaaclab.assets import AssetBaseCfg
+
+ cfg = AssetBaseCfg(
+ init_state=AssetBaseCfg.InitialStateCfg(
+ pos=(0.0, 0.0, 0.5),
+ rot=(1.0, 0.0, 0.0, 0.0), # OLD: w, x, y, z
+ ),
+ )
+
+**After (XYZW):**
+
+.. code-block:: python
+
+ from isaaclab.assets import AssetBaseCfg
+
+ cfg = AssetBaseCfg(
+ init_state=AssetBaseCfg.InitialStateCfg(
+ pos=(0.0, 0.0, 0.5),
+ rot=(0.0, 0.0, 0.0, 1.0), # NEW: x, y, z, w
+ ),
+ )
+
+
+Using the Quaternion Finder Tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We provide a tool to help you find and fix quaternions in your codebase automatically. This is not a bulletproof tool,
+but it should help you find most of the quaternions that need to be updated. You *should* review the results manually.
+
+.. warning::
+ Do not run the tool on the whole codebase! If you run the tool on our own packages (isaaclab, or isaaclab_tasks for
+ instance) it will find all the quaternions that we already converted. This tool is only meant to be used on your own
+ codebase with no overlap with our own packages.
+
+Finding Quaternions
+-------------------
+
+Run the tool to scan your code for potential quaternions:
+
+.. code-block:: bash
+
+ # Scan the 'source' directory (default)
+ python scripts/tools/find_quaternions.py
+
+ # Scan a specific path
+ python scripts/tools/find_quaternions.py --path my_project/
+
+ # Compare against a different branch
+ python scripts/tools/find_quaternions.py --base develop
+
+.. tip::
+ We recommend always running the tool with a custom base branch *and* a specific path.
+
+
+The tool will show you:
+
+- Quaternions that haven't been updated (marked as ``UNCHANGED``)
+- Whether each looks like a WXYZ identity quaternion (``WXYZ_IDENTITY``)
+- Whether the format is likely WXYZ (``LIKELY_WXYZ``)
+
+
+Understanding the Output
+------------------------
+
+.. code-block:: text
+
+ my_project/robot_cfg.py:42:8 ⚠ UNCHANGED [WXYZ_IDENTITY]
+ Values: [1.0, 0.0, 0.0, 0.0]
+ Source: rot=(1.0, 0.0, 0.0, 0.0),
+
+This tells you:
+
+- **File and line**: ``my_project/robot_cfg.py:42``
+- **Status**: ``UNCHANGED`` means this line hasn't been modified yet
+- **Flag**: ``WXYZ_IDENTITY`` means it's the identity quaternion in old WXYZ format
+- **Values**: The actual quaternion values found
+- **Source**: The line of code for context
+
+
+Filtering Results
+-----------------
+
+Focus on specific types of quaternions:
+
+.. code-block:: bash
+
+ # Only show identity quaternions [1, 0, 0, 0]
+ python scripts/tools/find_quaternions.py --check-identity
+
+ # Only show quaternions likely in WXYZ format
+ python scripts/tools/find_quaternions.py --likely-wxyz
+
+ # Show ALL potential quaternions (ignore format heuristics)
+ python scripts/tools/find_quaternions.py --all-quats
+
+
+Fixing Quaternions Automatically
+--------------------------------
+
+The tool can automatically convert quaternions from WXYZ to XYZW:
+
+.. code-block:: bash
+
+ # Interactive mode: prompts before each fix
+ python scripts/tools/find_quaternions.py --fix
+
+ # Only fix identity quaternions (safest option)
+ python scripts/tools/find_quaternions.py --fix-identity-only
+
+ # Preview changes without applying them
+ python scripts/tools/find_quaternions.py --fix --dry-run
+
+ # Apply all fixes without prompting
+ python scripts/tools/find_quaternions.py --fix --force
+
+
+Interactive Fix Example
+-----------------------
+
+When running with ``--fix``, you'll see something like:
+
+.. code-block:: text
+
+ ────────────────────────────────────────────────────────────────────────────────
+ 📍 my_project/robot_cfg.py:42 [WXYZ_IDENTITY]
+ ────────────────────────────────────────────────────────────────────────────────
+ 40 | init_state=AssetBaseCfg.InitialStateCfg(
+ 41 | pos=(0.0, 0.0, 0.5),
+ >>> 42 | rot=(1.0, 0.0, 0.0, 0.0),
+ 43 | ),
+ 44 | )
+ ────────────────────────────────────────────────────────────────────────────────
+ Change: [1.0, 0.0, 0.0, 0.0] → [0.0, 0.0, 0.0, 1.0]
+ Result: rot=(0.0, 0.0, 0.0, 1.0),
+ Apply this fix? [Y/n/a/q]:
+
+Options:
+
+- **Y** (yes): Apply this fix
+- **n** (no): Skip this one
+- **a** (all): Apply all remaining fixes without asking
+- **q** (quit): Stop fixing
+
+
+How the Tool Works
+------------------
+
+The tool uses several techniques to find quaternions:
+
+1. **Python files**: Parses the code using AST (Abstract Syntax Tree) to find
+ 4-element tuples and lists with numeric values.
+
+2. **JSON files**: Uses regex to find 4-element arrays.
+
+3. **RST documentation**: Searches for quaternion-like patterns in docs.
+
+To identify if something is a quaternion, the tool checks:
+
+- Is it exactly 4 numeric values?
+- Does the sum of squares ≈ 1? (unit quaternion property)
+- Does it match known patterns like identity quaternions?
+
+To determine if it's in WXYZ format:
+
+- Is the first value 1.0 and rest are 0? (WXYZ identity)
+- Is the first value a common cos(θ/2) value like 0.707, 0.866, etc.?
+- Is the pattern consistent with first-element being the scalar part?
+
+
+Best Practices for Migration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+1. **Start with a clean git state** - Commit your work before running fixes.
+
+2. **Run the tool first without ``--fix``** - Review what will be changed.
+
+3. **Fix identity quaternions first** - They're the most common and safest:
+
+ .. code-block:: bash
+
+ python scripts/tools/find_quaternions.py --fix-identity-only
+
+4. **Review non-identity quaternions manually** - Some 4-element lists might
+ not be quaternions (e.g., RGBA colors, bounding boxes).
+
+5. **Test your code** - Run your simulations to verify everything works correctly.
+
+6. **Check documentation** - Update any docs or comments that mention quaternion format.
+
+API Changes
+~~~~~~~~~~~
+
+The ``convert_quat`` function has been removed
+----------------------------------------------
+
+Previously, IsaacLab had a utility function to convert between quaternion formats:
+
+.. code-block:: python
+
+ # OLD - No longer needed
+ from isaaclab.utils.math import convert_quat
+ quat_xyzw = convert_quat(quat_wxyz, "xyzw")
+
+Since everything now uses XYZW natively, this function is no longer needed.
+If you were using it, simply remove the conversion calls.
+
+
+Math utility functions now expect XYZW
+--------------------------------------
+
+All quaternion functions in :mod:`isaaclab.utils.math` now expect and return
+quaternions in XYZW format:
+
+- :func:`~isaaclab.utils.math.quat_mul`
+- :func:`~isaaclab.utils.math.quat_apply`
+- :func:`~isaaclab.utils.math.quat_from_euler_xyz`
+- :func:`~isaaclab.utils.math.euler_xyz_from_quat`
+- :func:`~isaaclab.utils.math.quat_from_matrix`
+- :func:`~isaaclab.utils.math.matrix_from_quat`
+- And all other quaternion utilities
+
+
+Warp Backend for Asset and Sensor Data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All ``.data.*`` properties on asset and sensor classes now return ``wp.array`` instead of
+``torch.Tensor``. This change applies to all asset classes (:class:`~isaaclab.assets.Articulation`,
+:class:`~isaaclab.assets.RigidObject`, :class:`~isaaclab.assets.RigidObjectCollection`,
+:class:`~isaaclab_physx.assets.DeformableObject`) and all sensor classes
+(:class:`~isaaclab_physx.sensors.ContactSensor`, :class:`~isaaclab_physx.sensors.Imu`,
+:class:`~isaaclab_physx.sensors.Pva`, :class:`~isaaclab_physx.sensors.FrameTransformer`).
+
+To convert back to ``torch.Tensor`` for use with PyTorch operations, wrap the property
+access with ``wp.to_torch()``:
+
+.. code-block:: python
+
+ import warp as wp
+
+ # Before (Isaac Lab 2.x)
+ root_pos = robot.data.root_pos_w # torch.Tensor
+ joint_pos = robot.data.joint_pos # torch.Tensor
+ contact_forces = sensor.data.net_forces_w # torch.Tensor
+
+ # After (Isaac Lab 3.x)
+ root_pos = robot.data.root_pos_w # wp.array
+ joint_pos = robot.data.joint_pos # wp.array
+ contact_forces = sensor.data.net_forces_w # wp.array
+
+ # To use with torch operations, wrap with wp.to_torch()
+ root_pos_torch = wp.to_torch(robot.data.root_pos_w) # torch.Tensor
+ joint_pos_torch = wp.to_torch(robot.data.joint_pos) # torch.Tensor
+ contact_torch = wp.to_torch(sensor.data.net_forces_w) # torch.Tensor
+
+Common patterns that need updating:
+
+.. code-block:: python
+
+ # Cloning data
+ # Before:
+ pos = robot.data.root_pos_w.clone()
+ # After:
+ pos = wp.to_torch(robot.data.root_pos_w).clone()
+
+ # Creating zero tensors with matching shape
+ # Before:
+ zeros = torch.zeros_like(robot.data.root_pos_w)
+ # After:
+ zeros = torch.zeros_like(wp.to_torch(robot.data.root_pos_w))
+
+ # Assertions in tests
+ # Before:
+ torch.testing.assert_close(robot.data.root_pos_w, expected)
+ # After:
+ torch.testing.assert_close(wp.to_torch(robot.data.root_pos_w), expected)
+
+.. list-table:: Affected classes
+ :header-rows: 1
+ :widths: 40 60
+
+ * - Class
+ - Package
+ * - :class:`~isaaclab.assets.Articulation`
+ - ``isaaclab`` / ``isaaclab_physx``
+ * - :class:`~isaaclab.assets.RigidObject`
+ - ``isaaclab`` / ``isaaclab_physx``
+ * - :class:`~isaaclab.assets.RigidObjectCollection`
+ - ``isaaclab`` / ``isaaclab_physx``
+ * - :class:`~isaaclab_physx.assets.DeformableObject`
+ - ``isaaclab_physx``
+ * - :class:`~isaaclab_physx.sensors.ContactSensor`
+ - ``isaaclab_physx``
+ * - :class:`~isaaclab_physx.sensors.Imu`
+ - ``isaaclab_physx``
+ * - :class:`~isaaclab_physx.sensors.Pva`
+ - ``isaaclab_physx``
+ * - :class:`~isaaclab_physx.sensors.FrameTransformer`
+ - ``isaaclab_physx``
+ * - :class:`~isaaclab.sensors.RayCaster`
+ - ``isaaclab``
+ * - :class:`~isaaclab.sensors.RayCasterCamera`
+ - ``isaaclab``
+ * - :class:`~isaaclab.sensors.MultiMeshRayCaster`
+ - ``isaaclab``
+ * - :class:`~isaaclab.sensors.MultiMeshRayCasterCamera`
+ - ``isaaclab``
+
+.. note::
+
+ An automated migration tool is provided at ``scripts/tools/wrap_warp_to_torch.py``.
+ It scans Python files for ``.data.`` accesses and wraps them with
+ ``wp.to_torch()``. Usage:
+
+ .. code-block:: bash
+
+ # Dry run (preview changes)
+ python scripts/tools/wrap_warp_to_torch.py path/to/your/code --dry-run
+
+ # Apply changes in-place
+ python scripts/tools/wrap_warp_to_torch.py path/to/your/code
+
+ Always review the changes after running the tool, as some accesses (e.g., those
+ already passed to warp-native functions) should not be wrapped.
+
+
+Ray Caster Warp Backend
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The :class:`~isaaclab.sensors.RayCaster`, :class:`~isaaclab.sensors.RayCasterCamera`,
+:class:`~isaaclab.sensors.MultiMeshRayCaster`, and
+:class:`~isaaclab.sensors.MultiMeshRayCasterCamera` sensors have been transitioned from a
+PyTorch/USD-based backend to a native Warp kernel pipeline. This improves performance by
+eliminating per-step tensor allocations and torch-to-warp conversions, but introduces several
+breaking changes.
+
+
+RayCasterData Return Types
+--------------------------
+
+The :attr:`~isaaclab.sensors.RayCasterData.pos_w`,
+:attr:`~isaaclab.sensors.RayCasterData.quat_w`, and
+:attr:`~isaaclab.sensors.RayCasterData.ray_hits_w` properties now return ``wp.array`` instead of
+``torch.Tensor``. This follows the same pattern as the general warp backend migration described
+above.
+
+.. code-block:: python
+
+ import warp as wp
+
+ # Before (Isaac Lab 2.x)
+ ray_hits = ray_caster.data.ray_hits_w # torch.Tensor
+ sensor_pos = ray_caster.data.pos_w # torch.Tensor
+
+ # After (Isaac Lab 3.x)
+ ray_hits = ray_caster.data.ray_hits_w # wp.array
+ sensor_pos = ray_caster.data.pos_w # wp.array
+
+ # To use with torch operations, wrap with wp.to_torch()
+ ray_hits_torch = wp.to_torch(ray_caster.data.ray_hits_w)
+ sensor_pos_torch = wp.to_torch(ray_caster.data.pos_w)
+
+
+Ray Alignment Configuration
+----------------------------
+
+The ``attach_yaw_only`` boolean parameter on :class:`~isaaclab.sensors.RayCasterCfg` has been
+deprecated in favor of the new ``ray_alignment`` parameter, which accepts one of three string
+values:
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 30 40
+
+ * - Old (2.x)
+ - New (3.0)
+ - Behavior
+ * - ``attach_yaw_only=False``
+ - ``ray_alignment="base"``
+ - Rays follow the full sensor orientation.
+ * - ``attach_yaw_only=True``
+ - ``ray_alignment="yaw"``
+ - Rays follow only the yaw component of the sensor orientation.
+ * - *(not available)*
+ - ``ray_alignment="world"``
+ - Rays are always cast in the world frame (no rotation applied).
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x)
+ cfg = RayCasterCfg(attach_yaw_only=True, ...)
+
+ # After (Isaac Lab 3.x)
+ cfg = RayCasterCfg(ray_alignment="yaw", ...)
+
+
+Raycasting Kernel Signature Change
+-----------------------------------
+
+The :func:`~isaaclab.utils.warp.kernels.raycast_dynamic_meshes_kernel` Warp kernel now requires
+an ``env_mask`` parameter as its first argument. This is a ``wp.array(dtype=wp.bool)`` that
+controls which environments are updated. The public Python wrapper
+:func:`~isaaclab.utils.warp.ops.raycast_dynamic_meshes` has been updated to inject an all-True
+mask automatically, so code using the wrapper is unaffected.
+
+If you call the kernel directly, update your launch call:
+
+.. code-block:: python
+
+ import warp as wp
+
+ # Before (Isaac Lab 2.x)
+ wp.launch(
+ raycast_dynamic_meshes_kernel,
+ dim=(num_meshes, num_envs, num_rays),
+ inputs=[ray_starts, ray_directions, mesh_ids, ...],
+ )
+
+ # After (Isaac Lab 3.x) -- env_mask is now the first input
+ env_mask = wp.ones(num_envs, dtype=wp.bool, device=device)
+ wp.launch(
+ raycast_dynamic_meshes_kernel,
+ dim=(num_meshes, num_envs, num_rays),
+ inputs=[env_mask, ray_starts, ray_directions, mesh_ids, ...],
+ )
+
+
+RayCaster.meshes Cache Key
+--------------------------
+
+The :attr:`~isaaclab.sensors.RayCaster.meshes` class variable, which caches warp meshes across
+all :class:`~isaaclab.sensors.RayCaster` instances, is now keyed by ``(prim_path, device)`` tuples
+instead of by ``prim_path`` alone. This prevents a mesh that was built on one device (e.g. CPU)
+from being reused by a sensor running on a different device (e.g. CUDA), which caused illegal
+memory accesses on systems without unified memory.
+
+Code that reads or writes this cache directly must update both the type annotation and the key:
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x)
+ meshes: ClassVar[dict[str, wp.Mesh]] = {}
+ wp_mesh = RayCaster.meshes[prim_path]
+
+ # After (Isaac Lab 3.x)
+ meshes: ClassVar[dict[tuple[str, str], wp.Mesh]] = {}
+ wp_mesh = RayCaster.meshes[(prim_path, device)]
+
+
+Write Method Index/Mask Split
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All asset write methods have been split into two explicit variants:
+
+- ``write_*_to_sim_index(data, env_ids)`` — accepts partial data for a sparse set of
+ environment indices. The ``data`` tensor has shape ``(len(env_ids), ...)``.
+- ``write_*_to_sim_mask(data, env_mask)`` — accepts full data for all environments with a
+ boolean mask selecting which environments to update. The ``data`` tensor has shape
+ ``(num_envs, ...)``.
+
+The previous ``write_*_to_sim(data, env_ids)`` methods have been removed.
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x)
+ robot.write_root_pose_to_sim(pose_data, env_ids)
+
+ # After (Isaac Lab 3.x) — indexed variant (partial data)
+ robot.write_root_pose_to_sim_index(root_pose=pose_data, env_ids=env_ids)
+
+ # After (Isaac Lab 3.x) — mask variant (full data, boolean mask)
+ robot.write_root_pose_to_sim_mask(root_pose=pose_data, env_mask=env_mask)
+
+.. list-table:: Affected write methods (RigidObject / Articulation)
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Old method
+ - New methods
+ * - ``write_root_pose_to_sim``
+ - ``write_root_pose_to_sim_index`` / ``write_root_pose_to_sim_mask``
+ * - ``write_root_link_pose_to_sim``
+ - ``write_root_link_pose_to_sim_index`` / ``write_root_link_pose_to_sim_mask``
+ * - ``write_root_com_pose_to_sim``
+ - ``write_root_com_pose_to_sim_index`` / ``write_root_com_pose_to_sim_mask``
+ * - ``write_root_velocity_to_sim``
+ - ``write_root_velocity_to_sim_index`` / ``write_root_velocity_to_sim_mask``
+ * - ``write_root_com_velocity_to_sim``
+ - ``write_root_com_velocity_to_sim_index`` / ``write_root_com_velocity_to_sim_mask``
+ * - ``write_root_link_velocity_to_sim``
+ - ``write_root_link_velocity_to_sim_index`` / ``write_root_link_velocity_to_sim_mask``
+
+.. list-table:: Additional Articulation-specific write methods
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Old method
+ - New methods
+ * - ``write_joint_position_to_sim``
+ - ``write_joint_position_to_sim_index`` / ``write_joint_position_to_sim_mask``
+ * - ``write_joint_velocity_to_sim``
+ - ``write_joint_velocity_to_sim_index`` / ``write_joint_velocity_to_sim_mask``
+ * - ``write_joint_stiffness_to_sim``
+ - ``write_joint_stiffness_to_sim_index`` / ``write_joint_stiffness_to_sim_mask``
+ * - ``write_joint_damping_to_sim``
+ - ``write_joint_damping_to_sim_index`` / ``write_joint_damping_to_sim_mask``
+ * - ``write_joint_position_limit_to_sim``
+ - ``write_joint_position_limit_to_sim_index`` / ``write_joint_position_limit_to_sim_mask``
+ * - ``write_joint_velocity_limit_to_sim``
+ - ``write_joint_velocity_limit_to_sim_index`` / ``write_joint_velocity_limit_to_sim_mask``
+ * - ``write_joint_effort_limit_to_sim``
+ - ``write_joint_effort_limit_to_sim_index`` / ``write_joint_effort_limit_to_sim_mask``
+ * - ``write_joint_armature_to_sim``
+ - ``write_joint_armature_to_sim_index`` / ``write_joint_armature_to_sim_mask``
+ * - ``write_joint_friction_coefficient_to_sim``
+ - ``write_joint_friction_coefficient_to_sim_index`` / ``write_joint_friction_coefficient_to_sim_mask``
+
+.. list-table:: RigidObjectCollection write methods
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Old method
+ - New methods
+ * - ``write_body_pose_to_sim``
+ - ``write_body_pose_to_sim_index`` / ``write_body_pose_to_sim_mask``
+ * - ``write_body_link_pose_to_sim``
+ - ``write_body_link_pose_to_sim_index`` / ``write_body_link_pose_to_sim_mask``
+ * - ``write_body_com_pose_to_sim``
+ - ``write_body_com_pose_to_sim_index`` / ``write_body_com_pose_to_sim_mask``
+ * - ``write_body_velocity_to_sim``
+ - ``write_body_velocity_to_sim_index`` / ``write_body_velocity_to_sim_mask``
+ * - ``write_body_com_velocity_to_sim``
+ - ``write_body_com_velocity_to_sim_index`` / ``write_body_com_velocity_to_sim_mask``
+ * - ``write_body_link_velocity_to_sim``
+ - ``write_body_link_velocity_to_sim_index`` / ``write_body_link_velocity_to_sim_mask``
+
+
+TimestampedBufferWarp
+~~~~~~~~~~~~~~~~~~~~~
+
+If you have custom asset or sensor data classes that subclass the Isaac Lab base data classes,
+note that internal buffers have changed from :class:`~isaaclab.utils.buffers.TimestampedBuffer`
+to :class:`~isaaclab.utils.buffers.TimestampedBufferWarp`. The new class takes ``(shape, device,
+wp_dtype)`` as constructor arguments instead of a ``torch.Tensor``:
+
+.. code-block:: python
+
+ import warp as wp
+ from isaaclab.utils.buffers import TimestampedBufferWarp
+
+ # Before (Isaac Lab 2.x)
+ self._data.root_pos_w = TimestampedBuffer(torch.zeros(num_envs, 3, device=device))
+
+ # After (Isaac Lab 3.x)
+ self._data.root_pos_w = TimestampedBufferWarp(
+ shape=(num_envs,), device=device, wp_dtype=wp.vec3f
+ )
+
+
+URDF Importer
+~~~~~~~~~~~~~
+
+The URDF importer in Isaac Sim was rewritten to version 3.0, using the ``urdf-usd-converter``
+library and the ``isaacsim.asset.transformer.rules`` extension to produce structured USD output.
+The old C++ binding-based API (using Kit commands ``URDFParseFile``/``URDFImportRobot`` and the
+``_urdf`` interface from ``acquire_urdf_interface()``) has been replaced with a new Python-based
+pipeline.
+
+The IsaacLab :class:`~sim.converters.UrdfConverter` has been updated to replicate the new
+``URDFImporter.import_urdf()`` pipeline, inserting IsaacLab-specific post-processing (fix base,
+joint drives, link density) on the intermediate USD stage before the asset transformer
+restructures the output.
+
+.. important::
+
+ The previous version-pinning mechanism that locked the URDF importer extension to
+ ``isaacsim.asset.importer.urdf-2.4.31`` has been removed. The converter now uses whichever
+ version of the extension is available in your Isaac Sim installation.
+
+
+Deprecated Settings
+-------------------
+
+The following :class:`~sim.converters.UrdfConverterCfg` settings are **deprecated** because
+the new URDF importer 3.0 no longer supports them. They are kept for backward compatibility
+but will log warnings if enabled:
+
++-----------------------------------------------------------+-----------------------------------------------------+
+| Setting | Notes |
++===========================================================+=====================================================+
+| ``convert_mimic_joints_to_normal_joints`` | No longer supported by the importer. |
++-----------------------------------------------------------+-----------------------------------------------------+
+| ``replace_cylinders_with_capsules`` | No longer supported by the importer. |
++-----------------------------------------------------------+-----------------------------------------------------+
+| ``root_link_name`` | No longer supported by the importer. |
++-----------------------------------------------------------+-----------------------------------------------------+
+
+.. note::
+
+ The ``merge_fixed_joints`` setting is **still supported**. It is now implemented as a URDF XML
+ pre-processing step that runs before the USD conversion. Fixed joints are removed and child
+ link elements (visual, collision, inertial) are merged into the parent link with correct
+ transform composition.
+
+Additionally, the :class:`~sim.converters.UrdfConverterCfg.JointDriveCfg.NaturalFrequencyGainsCfg`
+gains mode is **deprecated**. The ``compute_natural_stiffness`` function that it depended on has
+been removed from the importer. If ``NaturalFrequencyGainsCfg`` is used, a
+:exc:`DeprecationWarning` is emitted and joint drive gains are left at the values produced by the
+URDF importer. Use :class:`~sim.converters.UrdfConverterCfg.JointDriveCfg.PDGainsCfg` instead.
+
+The :attr:`~sim.converters.AssetConverterBaseCfg.make_instanceable` setting from the base class
+is also no longer supported and will be ignored. Assets will be made instanceable by default.
+
+
+Updated CLI Tool
+----------------
+
+The ``convert_urdf.py`` script has been updated. The ``usd_file_name`` is now determined
+automatically by the importer based on the robot name and cannot be overridden.
+
+**Before (Isaac Lab 2.x):**
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p scripts/tools/convert_urdf.py \
+ robot.urdf \
+ /output/dir/robot.usd \
+ --fix-base \
+ --merge-joints
+
+**After (Isaac Lab 3.0):**
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p scripts/tools/convert_urdf.py \
+ robot.urdf \
+ /output/dir \
+ --fix-base \
+ --joint-stiffness 100.0 \
+ --joint-damping 1.0
+
+.. note::
+
+ The ``--merge-joints`` flag is still accepted and correctly triggers the pre-processing
+ step to merge fixed joints.
+
+
+Updated Python API
+------------------
+
+If you use :class:`~sim.converters.UrdfConverter` or :class:`~sim.converters.UrdfConverterCfg`
+directly in your code, note the following changes:
+
+1. The ``usd_file_name`` is now set automatically by the converter based on the URDF file name.
+ The importer generates output at ``{usd_dir}/{robot_name}/{robot_name}.usda``.
+
+2. The ``make_instanceable`` setting is no longer supported. Assets will be made instanceable
+ by default.
+
+3. The ``merge_fixed_joints`` parameter is now implemented as a pre-processing step.
+
+**Before (Isaac Lab 2.x):**
+
+.. code-block:: python
+
+ from isaaclab.sim.converters import UrdfConverter, UrdfConverterCfg
+
+ cfg = UrdfConverterCfg(
+ asset_path="robot.urdf",
+ usd_dir="/output/dir",
+ usd_file_name="robot.usd",
+ fix_base=True,
+ merge_fixed_joints=True,
+ make_instanceable=True,
+ joint_drive=UrdfConverterCfg.JointDriveCfg(
+ gains=UrdfConverterCfg.JointDriveCfg.PDGainsCfg(
+ stiffness=None, # use URDF values
+ damping=None,
+ ),
+ ),
+ )
+
+**After (Isaac Lab 3.0):**
+
+.. code-block:: python
+
+ from isaaclab.sim.converters import UrdfConverter, UrdfConverterCfg
+
+ cfg = UrdfConverterCfg(
+ asset_path="robot.urdf",
+ usd_dir="/output/dir",
+ # usd_file_name is determined automatically from the robot name
+ fix_base=True,
+ merge_fixed_joints=True, # supported via pre-processing
+ joint_drive=UrdfConverterCfg.JointDriveCfg(
+ gains=UrdfConverterCfg.JointDriveCfg.PDGainsCfg(
+ stiffness=None, # use URDF values
+ damping=None,
+ ),
+ ),
+ )
+
+
+MJCF Importer
+~~~~~~~~~~~~~
+
+The MJCF importer in Isaac Sim was rewritten to use the ``mujoco-usd-converter`` library.
+The old C++ binding-based API (using Kit commands ``MJCFCreateAsset``/``MJCFCreateImportConfig``
+and the ``ImportConfig`` class) has been replaced with a new pure-Python ``MJCFImporter`` class
+and ``MJCFImporterConfig`` dataclass.
+
+.. important::
+
+ The new MJCF importer produces USD assets with **nested rigid bodies** (i.e., ``RigidBodyAPI``
+ is applied to each link prim individually) instead of a single articulation root with rigid
+ body applied only at the top level. This matches how MuJoCo represents bodies and is
+ physically more accurate, but it may affect code that assumes a flat rigid body hierarchy.
+ If you have downstream logic that traverses the USD structure of MJCF-imported assets,
+ verify that it handles nested rigid body prims correctly.
+
+Removed Settings
+----------------
+
+The following :class:`~sim.converters.MjcfConverterCfg` settings have been **removed** because
+the new converter handles them automatically based on the MJCF file content:
+
+- ``fix_base`` — base fixedness is now inferred from the MJCF ```` tag.
+- ``link_density`` — density is now read directly from the MJCF model.
+- ``import_inertia_tensor`` — inertia tensors are always imported.
+- ``import_sites`` — sites are always imported.
+
+The :attr:`~sim.converters.AssetConverterBaseCfg.make_instanceable` setting from the base class
+is also no longer supported and will be ignored.
+
+
+New Settings
+------------
+
+The following new settings were added to :class:`~sim.converters.MjcfConverterCfg`:
+
++-----------------------------------------------------------------+------------------------------------------------------+
+| Setting | Description |
++=================================================================+======================================================+
+| :attr:`~sim.converters.MjcfConverterCfg.merge_mesh` | Merge meshes where possible to optimize the model. |
++-----------------------------------------------------------------+------------------------------------------------------+
+| :attr:`~sim.converters.MjcfConverterCfg.collision_from_visuals` | Generate collision geometry from visuals. |
++-----------------------------------------------------------------+------------------------------------------------------+
+| :attr:`~sim.converters.MjcfConverterCfg.collision_type` | Type of collision geometry (e.g. ``"default"``, |
+| | ``"Convex Hull"``, ``"Convex Decomposition"``). |
++-----------------------------------------------------------------+------------------------------------------------------+
+
+
+Renamed Settings
+----------------
+
++------------------------------------------+------------------------------------------+
+| Old (2.x) | New (3.0) |
++==========================================+==========================================+
+| ``self_collision`` | ``self_collision`` (unchanged) |
++------------------------------------------+------------------------------------------+
+
+.. note::
+
+ The underlying Isaac Sim API renamed ``self_collision`` to ``allow_self_collision``.
+ The IsaacLab :class:`~sim.converters.MjcfConverterCfg` keeps using ``self_collision``
+ for backward compatibility and maps it to the new name internally.
+
+
+Updated CLI Tool
+----------------
+
+The ``convert_mjcf.py`` script has been updated to match the new importer settings.
+Old command-line flags (``--fix-base``, ``--make-instanceable``, ``--import-sites``)
+are no longer available.
+
+**Before (Isaac Lab 2.x):**
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p scripts/tools/convert_mjcf.py \
+ ../mujoco_menagerie/unitree_h1/h1.xml \
+ source/isaaclab_assets/data/Robots/Unitree/h1.usd \
+ --import-sites \
+ --make-instanceable
+
+**After (Isaac Lab 3.0):**
+
+.. code-block:: bash
+
+ ./isaaclab.sh -p scripts/tools/convert_mjcf.py \
+ ../mujoco_menagerie/unitree_h1/h1.xml \
+ source/isaaclab_assets/data/Robots/Unitree/h1.usd \
+ --merge-mesh \
+ --self-collision
+
+New flags: ``--merge-mesh``, ``--collision-from-visuals``, ``--collision-type``, ``--self-collision``.
+
+
+Updated Python API
+------------------
+
+If you use :class:`~sim.converters.MjcfConverter` or :class:`~sim.converters.MjcfConverterCfg`
+directly in your code, update your configuration:
+
+**Before (Isaac Lab 2.x):**
+
+.. code-block:: python
+
+ from isaaclab.sim.converters import MjcfConverter, MjcfConverterCfg
+
+ cfg = MjcfConverterCfg(
+ asset_path="robot.xml",
+ usd_dir="/output/dir",
+ fix_base=True,
+ import_sites=True,
+ make_instanceable=True,
+ )
+
+**After (Isaac Lab 3.0):**
+
+.. code-block:: python
+
+ from isaaclab.sim.converters import MjcfConverter, MjcfConverterCfg
+
+ cfg = MjcfConverterCfg(
+ asset_path="robot.xml",
+ usd_dir="/output/dir",
+ merge_mesh=True,
+ collision_from_visuals=False,
+ self_collision=False,
+ )
+
+
+XR Teleoperation: Isaac Teleop Integration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The native XR teleoperation stack in ``isaaclab.devices.openxr`` has been deprecated and replaced
+by `Isaac Teleop `_, integrated via the ``isaaclab_teleop``
+extension. The ``isaac-teleop-device-plugins`` repository has also been deprecated; all device
+plugin support is now in Isaac Teleop.
+
+For full documentation on the new stack, see :ref:`isaac-teleop-feature`.
+
+
+Installation Requirement
+------------------------
+
+Isaac Teleop must now be installed in your Isaac Lab environment:
+
+.. code-block:: bash
+
+ pip install isaacteleop~=1.0 --extra-index-url https://pypi.nvidia.com
+
+See :ref:`install-isaac-teleop` for complete installation instructions.
+
+
+Import Changes
+--------------
+
+.. list-table::
+ :header-rows: 1
+ :widths: 50 50
+
+ * - Deprecated (2.x)
+ - New (3.0)
+ * - ``from isaaclab.devices.openxr import OpenXRDevice``
+ - ``from isaaclab_teleop import IsaacTeleopDevice``
+ * - ``from isaaclab.devices.openxr import OpenXRDeviceCfg``
+ - ``from isaaclab_teleop import IsaacTeleopCfg``
+ * - ``from isaaclab.devices.openxr import XrCfg``
+ - ``from isaaclab_teleop import XrCfg``
+ * - ``from isaaclab.devices.openxr import ManusVive``
+ - ``from isaaclab_teleop import IsaacTeleopDevice`` (with Manus plugin configured)
+ * - ``from isaaclab.devices import RetargeterBase``
+ - Use Isaac Teleop ``BaseRetargeter`` and pipeline builder pattern
+ * - ``from isaaclab.devices.openxr.retargeters import Se3AbsRetargeter``
+ - ``from isaacteleop.retargeters import Se3AbsRetargeter``
+
+
+Environment Configuration Changes
+----------------------------------
+
+The ``teleop_devices`` field with ``OpenXRDeviceCfg`` has been replaced by the ``isaac_teleop``
+field with ``IsaacTeleopCfg`` and a pipeline builder callable.
+
+**Before (Isaac Lab 2.x):**
+
+.. code-block:: python
+
+ from isaaclab.devices import DevicesCfg, OpenXRDeviceCfg
+ from isaaclab.devices.openxr import XrCfg
+ from isaaclab.devices.openxr.retargeters import Se3AbsRetargeterCfg, GripperRetargeterCfg
+
+ @configclass
+ class MyEnvCfg(ManagerBasedRLEnvCfg):
+
+ xr: XrCfg = XrCfg(anchor_pos=[0.0, 0.0, 0.0])
+
+ teleop_devices: DevicesCfg = field(default_factory=lambda: DevicesCfg(
+ handtracking=OpenXRDeviceCfg(
+ xr_cfg=None,
+ retargeters=[
+ Se3AbsRetargeterCfg(bound_hand=0, zero_out_xy_rotation=True),
+ GripperRetargeterCfg(bound_hand=0),
+ ]
+ ),
+ ))
+
+**After (Isaac Lab 3.0):**
+
+.. code-block:: python
+
+ from isaaclab_teleop import IsaacTeleopCfg, XrCfg
+
+ def _build_pipeline():
+ from isaacteleop.retargeting_engine.deviceio_source_nodes import ControllersSource, HandsSource
+ from isaacteleop.retargeting_engine.interface import OutputCombiner, ValueInput
+ from isaacteleop.retargeters import (
+ GripperRetargeter, GripperRetargeterConfig,
+ Se3AbsRetargeter, Se3RetargeterConfig, TensorReorderer,
+ )
+ from isaacteleop.retargeting_engine.tensor_types import TransformMatrix
+
+ controllers = ControllersSource(name="controllers")
+ hands = HandsSource(name="hands")
+ transform = ValueInput("world_T_anchor", TransformMatrix())
+ t_controllers = controllers.transformed(transform.output(ValueInput.VALUE))
+
+ se3 = Se3AbsRetargeter(Se3RetargeterConfig(input_device=ControllersSource.RIGHT), name="ee")
+ c_se3 = se3.connect({ControllersSource.RIGHT: t_controllers.output(ControllersSource.RIGHT)})
+
+ grip = GripperRetargeter(GripperRetargeterConfig(hand_side="right"), name="grip")
+ c_grip = grip.connect({
+ ControllersSource.RIGHT: t_controllers.output(ControllersSource.RIGHT),
+ HandsSource.RIGHT: hands.output(HandsSource.RIGHT),
+ })
+
+ reorder = TensorReorderer(
+ input_config={"ee": ["pos_x","pos_y","pos_z","quat_x","quat_y","quat_z","quat_w"],
+ "grip": ["gripper_value"]},
+ output_order=["pos_x","pos_y","pos_z","quat_x","quat_y","quat_z","quat_w","gripper_value"],
+ name="reorder", input_types={"ee": "array", "grip": "scalar"},
+ )
+ c_reorder = reorder.connect({"ee": c_se3.output("ee_pose"), "grip": c_grip.output("gripper_command")})
+ return OutputCombiner({"action": c_reorder.output("output")})
+
+ @configclass
+ class MyEnvCfg(ManagerBasedRLEnvCfg):
+
+ xr: XrCfg = XrCfg(anchor_pos=(0.0, 0.0, 0.0))
+
+ def __post_init__(self):
+ super().__post_init__()
+ self.isaac_teleop = IsaacTeleopCfg(
+ pipeline_builder=_build_pipeline,
+ sim_device=self.sim.device,
+ xr_cfg=self.xr,
+ )
+
+
+Backward Compatibility
+----------------------
+
+The old classes still exist and will issue ``DeprecationWarning`` when used:
+
+* ``isaaclab.devices.openxr.OpenXRDevice`` and ``OpenXRDeviceCfg``
+* ``isaaclab.devices.openxr.ManusVive`` and ``ManusViveCfg``
+* All retargeters under ``isaaclab.devices.openxr.retargeters``
+
+Deprecated retargeters have been moved to ``isaaclab_teleop.deprecated.openxr.retargeters`` for
+compatibility. These will be removed in a future release.
+
+
+PhysX Tensors API Module Path
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Recent Isaac Sim releases removed the internal ``impl`` submodule of
+``omni.physics.tensors`` and now expose the PhysX Tensor API types
+(``ArticulationView``, ``RigidBodyView``, ``SimulationView``, etc.) directly
+under ``omni.physics.tensors.api``. Importing from the old path raises
+``ModuleNotFoundError: No module named 'omni.physics.tensors.impl'`` at import
+time.
+
+Isaac Lab has been updated to import from the new path. Downstream code
+(custom assets, sensors, or scripts) that imported from the old path must be
+updated:
+
+.. code-block:: python
+
+ # Before (Isaac Lab 2.x / older Isaac Sim)
+ import omni.physics.tensors.impl.api as physx
+
+ # After (Isaac Lab 3.x / current Isaac Sim)
+ import omni.physics.tensors.api as physx
+
+The class identities are unchanged — only the module path moved. Type hints
+referencing the old path (``omni.physics.tensors.impl.api.ArticulationView``)
+should be similarly updated to ``omni.physics.tensors.api.ArticulationView``.
+
+
+Need Help?
+~~~~~~~~~~
+
+If you encounter issues during migration:
+
+1. Check the `IsaacLab GitHub Issues `_
+2. Review the `CHANGELOG `_
+3. Join the community on `Discord `_
diff --git a/docs/source/overview/core-concepts/index.rst b/docs/source/overview/core-concepts/index.rst
index 930ab665c18..10fdf8935fb 100644
--- a/docs/source/overview/core-concepts/index.rst
+++ b/docs/source/overview/core-concepts/index.rst
@@ -7,7 +7,10 @@ This section we introduce core concepts in Isaac Lab.
:maxdepth: 1
+ multi_backend_architecture
task_workflows
actuators
sensors/index.rst
+ renderers
motion_generators
+ scene_data_providers
diff --git a/docs/source/overview/core-concepts/multi_backend_architecture.rst b/docs/source/overview/core-concepts/multi_backend_architecture.rst
new file mode 100644
index 00000000000..c9821ebf4a6
--- /dev/null
+++ b/docs/source/overview/core-concepts/multi_backend_architecture.rst
@@ -0,0 +1,357 @@
+Multi-Backend Architecture
+==========================
+
+Isaac Lab 3.0 introduced a multi-backend architecture that enables running simulations with
+different physics engines (PhysX and Newton) while maintaining a unified API. This page explains
+how the backend system works and how to extend it.
+
+Overview
+--------
+
+Instead of hard-coding a single physics engine, Isaac Lab uses a **factory pattern** to
+dispatch object creation to backend-specific implementations at runtime. When you write:
+
+.. code-block:: python
+
+ from isaaclab.assets import Articulation
+
+ robot = Articulation(cfg)
+
+The ``Articulation`` class is a factory that automatically creates a
+:class:`~isaaclab_physx.assets.articulation.Articulation` or
+:class:`~isaaclab_newton.assets.articulation.Articulation` depending on which physics backend
+is active. Your code never needs to import backend-specific modules directly.
+
+This pattern applies to all simulation components:
+
+.. list-table::
+ :header-rows: 1
+
+ * - Component
+ - Core API (``isaaclab``)
+ - PhysX (``isaaclab_physx``)
+ - Newton (``isaaclab_newton``)
+ * - Physics Manager
+ - :class:`~isaaclab.physics.PhysicsManager`
+ - :class:`~isaaclab_physx.physics.PhysxManager`
+ - :class:`~isaaclab_newton.physics.NewtonManager`
+ * - Articulation
+ - :class:`~isaaclab.assets.Articulation`
+ - :class:`~isaaclab_physx.assets.Articulation`
+ - :class:`~isaaclab_newton.assets.Articulation`
+ * - Rigid Object
+ - :class:`~isaaclab.assets.RigidObject`
+ - :class:`~isaaclab_physx.assets.RigidObject`
+ - :class:`~isaaclab_newton.assets.RigidObject`
+ * - Contact Sensor
+ - :class:`~isaaclab.sensors.ContactSensor`
+ - :class:`~isaaclab_physx.sensors.ContactSensor`
+ - :class:`~isaaclab_newton.sensors.ContactSensor`
+ * - Renderer
+ - :class:`~isaaclab.renderers.Renderer`
+ - :class:`~isaaclab_physx.renderers.IsaacRtxRenderer`
+ - :class:`~isaaclab_newton.renderers.NewtonWarpRenderer`
+ * - Scene Data Provider
+ - :class:`~isaaclab.physics.SceneDataProvider`
+ - :class:`~isaaclab_physx.scene_data_providers.PhysxSceneDataProvider`
+ - :class:`~isaaclab_newton.scene_data_providers.NewtonSceneDataProvider`
+ * - Cloner
+ - :func:`~isaaclab.cloner.clone_from_template`
+ - :func:`~isaaclab_physx.cloner.physx_replicate`
+ - :func:`~isaaclab_newton.cloner.newton_physics_replicate`
+
+The Factory Pattern
+-------------------
+
+All factories inherit from :class:`~isaaclab.utils.backend_utils.FactoryBase`, which uses a
+**convention-over-configuration** approach to locate backend implementations:
+
+1. The active physics backend is determined by inspecting
+ ``SimulationContext.physics_manager``.
+2. The factory's module path is used to derive the backend module path by replacing ``isaaclab``
+ with ``isaaclab_{backend}``. For example, ``isaaclab.assets.articulation`` maps to
+ ``isaaclab_physx.assets.articulation`` or ``isaaclab_newton.assets.articulation``.
+3. The backend module is lazily imported and the implementation class is cached in a registry.
+
+.. code-block:: text
+
+ User code: Articulation(cfg)
+ │
+ ▼
+ FactoryBase.__new__()
+ │
+ ├─ _get_backend() → "physx" or "newton"
+ │ (reads SimulationContext.physics_manager)
+ │
+ ├─ _get_module_name() → "isaaclab_physx.assets.articulation"
+ │ (convention: isaaclab.X.Y → isaaclab_{backend}.X.Y)
+ │
+ ├─ importlib.import_module()
+ │ (lazy load — only on first use)
+ │
+ └─ Return backend-specific instance
+
+**Custom backend resolution:** Some factories override the default resolution. For example, the
+:class:`~isaaclab.renderers.Renderer` factory selects backends based on the renderer config type
+rather than the physics manager, because renderers and physics backends are independent:
+
+.. code-block:: python
+
+ class Renderer(FactoryBase, BaseRenderer):
+ _backend_class_names = {
+ "physx": "IsaacRtxRenderer",
+ "newton": "NewtonWarpRenderer",
+ "ov": "OVRTXRenderer",
+ }
+
+Similarly, visualizers select backends based on the ``visualizer_type`` field in their config,
+allowing any visualizer to work with any physics backend.
+
+Backend Selection
+-----------------
+
+The physics backend is selected via the ``physics`` field in
+:class:`~isaaclab.sim.SimulationCfg`:
+
+.. code-block:: python
+
+ from isaaclab.sim import SimulationCfg
+ from isaaclab_physx.physics import PhysxCfg
+ from isaaclab_newton.physics import NewtonCfg, MJWarpSolverCfg
+
+ # Use PhysX (default)
+ sim_cfg = SimulationCfg(physics=PhysxCfg())
+
+ # Use Newton with MuJoCo-Warp solver
+ sim_cfg = SimulationCfg(physics=NewtonCfg(
+ solver_cfg=MJWarpSolverCfg(),
+ num_substeps=4,
+ ))
+
+Once the :class:`~isaaclab.sim.SimulationContext` is initialized, all subsequent factory
+instantiations automatically use the selected backend.
+
+Multi-Backend Environments with Presets
+---------------------------------------
+
+Environments can support multiple backends simultaneously using the :doc:`preset system
+`. Each backend gets its own configuration variant:
+
+.. code-block:: python
+
+ from isaaclab.utils import configclass
+ from isaaclab_tasks.utils import PresetCfg
+ from isaaclab_physx.physics import PhysxCfg
+ from isaaclab_newton.physics import NewtonCfg, MJWarpSolverCfg
+
+ @configclass
+ class CartpolePhysicsCfg(PresetCfg):
+ default: PhysxCfg = PhysxCfg()
+ physx: PhysxCfg = PhysxCfg()
+ newton: NewtonCfg = NewtonCfg(
+ solver_cfg=MJWarpSolverCfg(njmax=5, nconmax=3)
+ )
+
+ @configclass
+ class CartpoleEnvCfg(ManagerBasedRLEnvCfg):
+ sim: SimulationCfg = SimulationCfg(physics=CartpolePhysicsCfg())
+
+Users then select a backend at the command line:
+
+.. code-block:: bash
+
+ # Default (PhysX)
+ python train.py --task Isaac-Cartpole-v0
+
+ # Newton
+ python train.py --task Isaac-Cartpole-v0 presets=newton
+
+The Physics Manager
+-------------------
+
+Each backend implements :class:`~isaaclab.physics.PhysicsManager`, the abstract base class
+that drives the simulation loop:
+
+.. code-block:: python
+
+ class PhysicsManager(ABC):
+ @classmethod
+ @abstractmethod
+ def initialize(cls, sim_context: SimulationContext) -> None: ...
+
+ @classmethod
+ @abstractmethod
+ def reset(cls, soft: bool = False) -> None: ...
+
+ @classmethod
+ @abstractmethod
+ def forward(cls) -> None: ...
+
+ @classmethod
+ @abstractmethod
+ def step(cls) -> None: ...
+
+ @classmethod
+ def close(cls) -> None: ... # concrete; dispatches STOP event
+
+The physics manager also provides a **callback system** via
+:class:`~isaaclab.physics.PhysicsEvent` for cross-backend event handling:
+
+.. code-block:: python
+
+ from isaaclab.physics import PhysicsManager, PhysicsEvent
+
+ handle = PhysicsManager.register_callback(
+ callback=my_setup_fn,
+ event=PhysicsEvent.PHYSICS_READY,
+ order=0,
+ name="my_callback",
+ )
+
+Available events: ``MODEL_INIT`` (during scene building), ``PHYSICS_READY`` (after physics
+initialization), and ``STOP`` (on simulation shutdown).
+
+Asset and Sensor Interfaces
+---------------------------
+
+Assets and sensors follow the same pattern. Each has:
+
+1. **A base class** in ``isaaclab`` defining the interface (e.g., ``BaseArticulation``,
+ ``BaseContactSensor``)
+2. **A factory class** that inherits from both ``FactoryBase`` and the base class
+3. **Backend implementations** in ``isaaclab_physx`` and ``isaaclab_newton``
+
+The base classes define the public API contract — properties, methods, and data accessors
+that all backends must provide. Both backends use ``wp.array`` (Warp arrays) as their
+primary data type for asset and sensor data.
+
+Data classes follow the same pattern with their own factories (e.g.,
+``ArticulationData(FactoryBase, BaseArticulationData)``).
+
+Adding a New Physics Backend
+----------------------------
+
+To add a new physics backend (e.g., ``mybackend``), create a new extension package following
+the established conventions:
+
+**1. Package structure:**
+
+.. code-block:: text
+
+ source/isaaclab_mybackend/
+ └── isaaclab_mybackend/
+ ├── __init__.py
+ ├── physics/
+ │ ├── __init__.py # lazy_export()
+ │ ├── __init__.pyi # public exports
+ │ ├── mybackend_manager.py
+ │ └── mybackend_manager_cfg.py
+ ├── assets/
+ │ ├── articulation/
+ │ │ ├── __init__.py
+ │ │ ├── __init__.pyi
+ │ │ ├── articulation.py
+ │ │ └── articulation_data.py
+ │ ├── rigid_object/
+ │ │ └── ...
+ │ └── rigid_object_collection/
+ │ └── ...
+ ├── sensors/
+ │ ├── contact_sensor/
+ │ └── ...
+ ├── renderers/
+ │ └── ...
+ ├── cloner/
+ │ └── ...
+ └── scene_data_providers/
+ └── ...
+
+**2. Implement the physics manager:**
+
+.. code-block:: python
+
+ # isaaclab_mybackend/physics/mybackend_manager.py
+ from isaaclab.physics import PhysicsManager
+
+ class MyBackendManager(PhysicsManager):
+ @classmethod
+ def initialize(cls, sim_context):
+ super().initialize(sim_context)
+ # Initialize your physics engine
+
+ @classmethod
+ def step(cls):
+ # Advance simulation by one timestep
+
+ @classmethod
+ def forward(cls):
+ # Update kinematics without stepping
+
+ @classmethod
+ def reset(cls, soft=False):
+ if not soft:
+ cls.dispatch_event(PhysicsEvent.PHYSICS_READY)
+ # Reset simulation state
+
+ @classmethod
+ def close(cls):
+ super().close()
+ # Clean up resources
+
+**3. Create the physics config:**
+
+.. code-block:: python
+
+ # isaaclab_mybackend/physics/mybackend_manager_cfg.py
+ from isaaclab.physics import PhysicsCfg
+ from isaaclab.utils import configclass
+
+ @configclass
+ class MyBackendCfg(PhysicsCfg):
+ class_type = "{DIR}.mybackend_manager:MyBackendManager"
+ # Backend-specific settings here
+
+**4. Implement assets and sensors:**
+
+Each asset/sensor must extend the corresponding base class from ``isaaclab``. The class name
+must match the factory's expected name (by convention, the same name as the factory class).
+Use ``lazy_export()`` in ``__init__.py`` files — no manual registration needed.
+
+.. code-block:: python
+
+ # isaaclab_mybackend/assets/articulation/articulation.py
+ from isaaclab.assets.articulation import BaseArticulation
+
+ class Articulation(BaseArticulation):
+ def __init__(self, cfg):
+ super().__init__(cfg)
+ # Set up backend-specific simulation structures
+
+**5. Module discovery is automatic.** The ``FactoryBase`` convention maps
+``isaaclab.assets.articulation`` to ``isaaclab_mybackend.assets.articulation`` based on the
+active physics manager name. As long as you follow the package structure above, your backend
+classes will be discovered automatically.
+
+Key Design Principles
+---------------------
+
+- **Lazy loading**: Backend modules are imported only when first instantiated, keeping startup
+ fast and avoiding hard dependencies on unused backends.
+- **Convention over configuration**: Module paths follow a strict pattern
+ (``isaaclab.X.Y`` → ``isaaclab_{backend}.X.Y``), so no manual registration is needed.
+- **Independent selection**: Physics backend, renderer, and visualizer are selected
+ independently — you can use any combination.
+- **Warp-native data types**: Both backends return ``wp.array`` for asset and sensor data.
+ Use ``wp.to_torch()`` when interoperating with PyTorch-based code.
+- **Zero runtime overhead**: Backend selection happens at instantiation time. There are no
+ if-statements or dispatch logic on the hot path.
+
+See Also
+--------
+
+- :doc:`/source/migration/migrating_to_isaaclab_3-0` — migration guide from Isaac Lab 2.x to the
+ multi-backend architecture
+- :doc:`/source/features/hydra` — preset system for multi-backend environment configurations
+- :doc:`/source/experimental-features/newton-physics-integration/index` — Newton physics integration
+ guide
+- :doc:`renderers` — renderer backend architecture
diff --git a/docs/source/overview/core-concepts/renderers.rst b/docs/source/overview/core-concepts/renderers.rst
new file mode 100644
index 00000000000..4971e7a1d0c
--- /dev/null
+++ b/docs/source/overview/core-concepts/renderers.rst
@@ -0,0 +1,117 @@
+.. _overview_renderers:
+
+Renderers
+=========
+
+Isaac Lab uses a pluggable renderer architecture to support different rendering backends for camera sensors.
+The :class:`~isaaclab.renderers.BaseRenderer` abstract base class defines the interface that all renderer
+implementations must follow.
+
+Isaac Lab supports two rendering backends:
+
+- **RTX renderer** (``IsaacRtxRendererCfg`` / ``OVRTXRendererCfg``) — NVIDIA's Omniverse RTX
+ rendering pipeline. Requires Isaac Sim. Best for photorealistic rendering, full camera sensor
+ support (RGB, depth, semantic segmentation, etc.), and production quality outputs.
+- **Newton Warp renderer** (``NewtonWarpRendererCfg``) — A lightweight GPU-accelerated renderer
+ built on NVIDIA Warp. Works with the Newton physics backend and does **not** require Isaac Sim
+ (kit-less mode). Ideal for training workflows where full RTX fidelity is not needed.
+
+Choosing a renderer backend
+----------------------------
+
++---------------------+-------------------------------+---------------------------------+
+| Backend | Requires Isaac Sim? | Best For |
++=====================+===============================+=================================+
+| Isaac RTX | Yes | Full sensor fidelity, RTX |
+| | | photorealism, PhysX backend |
++---------------------+-------------------------------+---------------------------------+
+| OVRTX | Yes (+ ``isaaclab_ov``) | Alternative RTX pipeline |
++---------------------+-------------------------------+---------------------------------+
+| Newton Warp | No (kit-less) | Newton backend, fast training |
++---------------------+-------------------------------+---------------------------------+
+
+Architecture Overview
+---------------------
+
+The renderer system consists of:
+
+1. **BaseRenderer** — Abstract base class defining the rendering lifecycle and interface
+2. **Renderer** — Factory that instantiates the appropriate backend based on renderer configuration class
+3. **RendererCfg** — Base configuration; each backend extends it with backend-specific options
+4. **Concrete implementations** — Backend-specific renderers in extension packages
+
+.. code-block:: python
+
+ from isaaclab.renderers import BaseRenderer, Renderer
+ from isaaclab_newton.renderers import NewtonWarpRendererCfg
+
+ # Create a Newton Warp renderer (no Isaac Sim required)
+ renderer: BaseRenderer = Renderer(NewtonWarpRendererCfg())
+ assert isinstance(renderer, BaseRenderer)
+
+For the RTX renderer (requires Isaac Sim):
+
+.. code-block:: python
+
+ from isaaclab.renderers import Renderer
+ from isaaclab.renderers import IsaacRtxRendererCfg # or OVRTXRendererCfg
+
+ # Create an RTX renderer
+ renderer: BaseRenderer = Renderer(IsaacRtxRendererCfg())
+
+For RTX renderer settings and presets (quality, balanced, performance), see
+:doc:`/source/how-to/configure_rendering`.
+
+Core concepts
+-------------
+
+- **Use the factory**: Always instantiate renderers via the factory with a renderer-specific config class
+ (e.g. ``Renderer(IsaacRtxRendererCfg())``). Do not import or instantiate concrete backend classes
+ (e.g. ``IsaacRtxRenderer``, ``OVRTXRenderer``) directly—their names and package locations are
+ implementation details and may change without notice.
+
+- **Lightweight config imports**: Importing a renderer configuration class does not pull in backend-specific
+ dependencies. The backend is lazily loaded when the renderer is instantiated, and instantiation may fail
+ if the backend is not installed.
+
+ .. code-block:: python
+
+ # Lightweight: does not import OVRTX backend dependencies
+ from isaaclab_ov.renderers import OVRTXRendererCfg
+
+ # Lazily loads ovrtx when instantiated; may fail if isaaclab_ov / ovrtx is not installed
+ renderer: BaseRenderer = Renderer(OVRTXRendererCfg())
+
+Installing the OVRTX renderer
+------------------------------
+
+The OVRTX renderer is provided by the ``isaaclab_ov`` extension and requires the
+`ovrtx `_ package (hosted on
+``pypi.nvidia.com``).
+
+Install via the Isaac Lab CLI:
+
+.. code-block:: bash
+
+ # Install isaaclab_ov (and its ovrtx dependency) alongside the core package
+ ./isaaclab.sh -i ov
+
+Or install manually with pip:
+
+.. code-block:: bash
+
+ pip install --extra-index-url https://pypi.nvidia.com -e source/isaaclab_ov
+
+- **Opaque render data**: The render data object returned by :meth:`~isaaclab.renderers.BaseRenderer.create_render_data` is passed to
+ subsequent renderer methods. It should be completely opaque to the caller: inspecting or modifying it
+ via get/set attributes is an anti-pattern and breaks the API contract.
+
+.. note::
+
+ The :class:`~isaaclab.renderers.BaseRenderer` class is under active development and may change without notice.
+
+See Also
+--------
+
+- :doc:`scene_data_providers` — how scene data flows from physics backends to renderers
+- :doc:`/source/features/visualization` — lightweight visualizer backends for interactive feedback
diff --git a/docs/source/overview/core-concepts/scene_data_providers.rst b/docs/source/overview/core-concepts/scene_data_providers.rst
new file mode 100644
index 00000000000..46244317ba2
--- /dev/null
+++ b/docs/source/overview/core-concepts/scene_data_providers.rst
@@ -0,0 +1,109 @@
+Scene Data Providers
+====================
+
+Scene Data Providers bridge physics simulation backends and visualization/rendering systems in
+Isaac Lab. They provide a unified interface for accessing scene data (transforms, velocities,
+Newton model/state) regardless of which physics backend is active.
+
+Overview
+--------
+
+Isaac Lab supports multiple physics backends (PhysX and Newton) and multiple visualizers
+(Omniverse Kit, Newton, Rerun, Viser). Each combination requires scene data to flow from the
+physics engine to the renderer. Scene Data Providers handle this translation automatically
+through a factory pattern.
+
+.. code-block:: python
+
+ from isaaclab.physics import SceneDataProvider
+
+ # Factory auto-selects the correct implementation based on active physics backend
+ provider = SceneDataProvider(stage, simulation_context)
+
+Architecture
+------------
+
+The system has three layers:
+
+1. **BaseSceneDataProvider** — abstract interface defining the contract:
+
+ - ``update(env_ids)`` — refresh cached scene data
+ - ``get_newton_model()`` — return Newton model handle (if available)
+ - ``get_newton_state(env_ids)`` — return Newton state handle (if available)
+ - ``get_usd_stage()`` — return USD stage handle (if available)
+ - ``get_transforms()`` — return body transforms
+ - ``get_velocities()`` — return body velocities
+ - ``get_contacts()`` — return contact data
+ - ``get_camera_transforms()`` — return per-camera, per-env transforms
+ - ``get_metadata()`` — return backend metadata (num_envs, gravity, etc.)
+
+2. **SceneDataProvider** — factory that auto-selects the backend-specific implementation
+ based on the active :class:`~isaaclab.physics.PhysicsManager`.
+
+3. **Backend implementations:**
+
+ - :class:`~isaaclab_physx.scene_data_providers.PhysxSceneDataProvider`
+ - :class:`~isaaclab_newton.scene_data_providers.NewtonSceneDataProvider`
+
+PhysX Scene Data Provider
+-------------------------
+
+When PhysX is the active physics backend, the provider **builds and maintains a Newton model
+from the USD stage**, then syncs PhysX transforms into it each frame. This is necessary because
+Newton-based visualizers (Newton, Rerun, Viser) require a Newton model/state to render.
+
+The sync pipeline:
+
+1. Reads transforms from PhysX ``RigidBodyView`` (fast tensor API)
+2. Falls back to :class:`~isaaclab.sim.views.FrameView` for bodies not covered by the rigid body view
+3. Converts and writes merged poses into the Newton state via Warp kernels
+
+Newton Scene Data Provider
+--------------------------
+
+When Newton is the active physics backend, the provider **delegates directly to the Newton
+manager** — no building or syncing required. Newton already owns the authoritative model and
+state.
+
+The only additional work is **optional USD sync**: when an Omniverse Kit visualizer is active,
+the provider syncs Newton transforms to the USD stage so Kit can render them. For Newton-only
+or Rerun/Viser visualizers, this sync is skipped.
+
+Data Requirements
+-----------------
+
+Visualizers and renderers declare their data needs, and the provider is configured accordingly:
+
+.. list-table::
+ :header-rows: 1
+
+ * - Component
+ - Requires Newton Model
+ - Requires USD Stage
+ * - Kit visualizer
+ - No
+ - Yes
+ * - Newton visualizer
+ - Yes
+ - No
+ * - Rerun visualizer
+ - Yes
+ - No
+ * - Viser visualizer
+ - Yes
+ - No
+ * - RTX renderer
+ - No
+ - Yes
+ * - Newton Warp renderer
+ - Yes
+ - No
+ * - OVRTX renderer
+ - Yes
+ - Yes
+
+See Also
+--------
+
+- :doc:`renderers` — renderer backends that consume scene data
+- :doc:`/source/features/visualization` — visualizer backends that consume scene data
diff --git a/docs/source/overview/core-concepts/sensors/camera.rst b/docs/source/overview/core-concepts/sensors/camera.rst
index 6a34c6fab30..917022b6cb4 100644
--- a/docs/source/overview/core-concepts/sensors/camera.rst
+++ b/docs/source/overview/core-concepts/sensors/camera.rst
@@ -5,26 +5,132 @@
Camera
======
-Camera sensors are uniquely defined by the use of the ``render_product``, a structure for managing data generated by the rendering pipeline (images). Isaac Lab provides the ability to fully control how these renderings are created through camera parameters like focal length, pose, type, etc... and what kind of data you want to render through the use of Annotators, allowing you to record not only RGB, but also Instance segmentation, object pose, object ID, etc...
+Camera sensors in Isaac Lab are renderer-backed sensors: each :class:`~sensors.TiledCamera` instance
+is coupled to a **renderer** that produces the image data. The renderer and camera are intentionally
+isolated from each other — the camera defines *what* to capture (pose, resolution, field of view,
+data types), while the renderer defines *how* to render it (RTX ray-tracing, Newton Warp rasterizer,
+etc.). This separation allows the same camera configuration to run across different physics and
+rendering backends without code changes.
+
+For an overview of the available renderer backends and how to choose between them, see
+:ref:`overview_renderers`.
+
+Rendered images are unique among supported sensor data types due to their large bandwidth requirements.
+A single 800 × 600 image with 32-bit color clocks in at just under 2 MB. At 60 fps across thousands
+of parallel environments, this grows quickly. Isaac Lab's tiled rendering API specifically addresses
+these scaling challenges by batching all cameras into a single render pass.
+
+
+Renderer Backends
+-----------------
+
+The renderer used by a camera is configured via the ``renderer_cfg`` field on
+:class:`~sensors.TiledCameraCfg`. The default is :class:`~isaaclab_physx.renderers.IsaacRtxRendererCfg`
+(NVIDIA RTX, requires Isaac Sim).
+
+.. list-table::
+ :header-rows: 1
+ :widths: 30 30 40
+
+ * - ``renderer_cfg``
+ - Requires Isaac Sim?
+ - Supported data types
+ * - ``IsaacRtxRendererCfg`` *(default)*
+ - Yes
+ - rgb, rgba, depth, normals, motion vectors, semantic/instance segmentation, and all other annotators
+ * - ``NewtonWarpRendererCfg``
+ - No (kit-less)
+ - ``rgb``, ``depth`` only
+ * - ``OVRTXRendererCfg``
+ - No (+ ``isaaclab_ov``)
+ - ``rgb``, ``depth`` only
+
+.. note::
+
+ The Newton Warp renderer currently supports only **``rgb``** and **``depth``** data types.
+ Annotators such as segmentation, normals, and motion vectors are Isaac RTX-specific features and
+ require :class:`~isaaclab_physx.renderers.IsaacRtxRendererCfg`.
-Rendered images are unique among the supported data types in Isaac Lab due to the inherently large bandwidth requirements for moving those data. A single 800 x 600 image with 32-bit color (a single float per pixel) clocks in at just under 2 MB. If we render at 60 fps and record every frame, that camera needs to move 120 MB/s. Multiply this by the number of cameras in an environment and environments in a simulation, and you can quickly see how scaling a naive vectorization of camera data could lead to bandwidth challenges. NVIDIA's Isaac Lab leverages our expertise in GPU hardware to provide an API that specifically addresses these scaling challenges in the rendering pipeline.
Tiled Rendering
~~~~~~~~~~~~~~~
.. note::
- This feature is only available from Isaac Sim version 4.2.0 onwards.
+ This feature is available from Isaac Sim version 4.2.0 onwards (for the RTX renderer).
+ The Newton Warp renderer supports tiled rendering in kit-less mode.
+
+ Tiled rendering in combination with image processing networks require heavy memory resources,
+ especially at larger resolutions. We recommend running 512 cameras on RTX 4090 GPUs or similar
+ when using the RTX renderer.
+
+The Tiled Rendering API provides a vectorized interface for collecting image data from all environment
+clones in a single batched render pass. Instead of one render call per camera, all copies of a camera
+are composited into a single large tiled image, dramatically reducing host-device transfer overhead.
+
+Isaac Lab provides tiled rendering through :class:`~sensors.TiledCamera`, configured via
+:class:`~sensors.TiledCameraCfg`. The ``renderer_cfg`` field selects the rendering backend.
+
+
+TiledCameraCfg with renderer_cfg
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Tiled rendering in combination with image processing networks require heavy memory resources, especially
- at larger resolutions. We recommend running 512 cameras in the scene on RTX 4090 GPUs or similar.
+The renderer is specified via ``renderer_cfg`` on :class:`~sensors.TiledCameraCfg`. The camera and
+renderer configurations are fully decoupled: you can swap renderers without changing any other camera
+parameters.
+
+**Default (RTX, requires Isaac Sim):**
+
+.. code-block:: python
+
+ from isaaclab.sensors import TiledCameraCfg
+ import isaaclab.sim as sim_utils
+ # IsaacRtxRendererCfg is the default, no explicit import needed
+
+ tiled_camera: TiledCameraCfg = TiledCameraCfg(
+ prim_path="/World/envs/env_.*/Camera",
+ offset=TiledCameraCfg.OffsetCfg(pos=(-7.0, 0.0, 3.0), rot=(0.9945, 0.0, 0.1045, 0.0), convention="world"),
+ data_types=["rgb"],
+ spawn=sim_utils.PinholeCameraCfg(
+ focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 20.0)
+ ),
+ width=80,
+ height=80,
+ # renderer_cfg defaults to IsaacRtxRendererCfg()
+ )
+
+**Newton Warp renderer (kit-less, no Isaac Sim required):**
+
+.. code-block:: python
+
+ from isaaclab.sensors import TiledCameraCfg
+ from isaaclab_newton.renderers import NewtonWarpRendererCfg
+ import isaaclab.sim as sim_utils
+
+ tiled_camera: TiledCameraCfg = TiledCameraCfg(
+ prim_path="/World/envs/env_.*/Camera",
+ offset=TiledCameraCfg.OffsetCfg(pos=(-7.0, 0.0, 3.0), rot=(0.9945, 0.0, 0.1045, 0.0), convention="world"),
+ data_types=["rgb", "depth"], # only rgb and depth supported with Newton renderer
+ spawn=sim_utils.PinholeCameraCfg(
+ focal_length=24.0, focus_distance=400.0, horizontal_aperture=20.955, clipping_range=(0.1, 20.0)
+ ),
+ width=80,
+ height=80,
+ renderer_cfg=NewtonWarpRendererCfg(),
+ )
-The Tiled Rendering APIs provide a vectorized interface for collecting data from camera sensors. This is useful for reinforcement learning environments where parallelization can be exploited to accelerate data collection and thus the training loop. Tiled rendering works by using a single ``render_product`` for **all** clones of a single camera in the scene. The desired dimensions of a single image and the number of environments are used to compute a much larger ``render_product``, consisting of the tiled individual renders from the separate clones of the camera. When all cameras have populated their buffers the render product is "completed" and can be moved around as a single, large image, dramatically reducing the overhead for moving the data from the host to the device, for example. Only a single call is used to synchronize the device data, instead of one call per camera, and this is a big part of what makes the Tiled Rendering API more efficient for working with vision data.
+**Multi-backend preset (switches renderer alongside physics backend):**
-Isaac Lab provides tiled rendering APIs for RGB, depth, along with other annotators through the :class:`~sensors.TiledCamera` class. Configurations for the tiled rendering APIs can be defined through the :class:`~sensors.TiledCameraCfg` class, specifying parameters such as the regex expression for all camera paths, the transform for the cameras, the desired data type, the type of cameras to add to the scene, and the camera resolution.
+For environments that need to support both backends, use
+:class:`~isaaclab_tasks.utils.presets.MultiBackendRendererCfg` together with the
+:ref:`PresetCfg pattern `:
.. code-block:: python
+ from isaaclab.sensors import TiledCameraCfg
+ from isaaclab_tasks.utils.presets import MultiBackendRendererCfg
+ import isaaclab.sim as sim_utils
+
tiled_camera: TiledCameraCfg = TiledCameraCfg(
prim_path="/World/envs/env_.*/Camera",
offset=TiledCameraCfg.OffsetCfg(pos=(-7.0, 0.0, 3.0), rot=(0.9945, 0.0, 0.1045, 0.0), convention="world"),
@@ -34,40 +140,64 @@ Isaac Lab provides tiled rendering APIs for RGB, depth, along with other annotat
),
width=80,
height=80,
+ renderer_cfg=MultiBackendRendererCfg(), # selects RTX or Newton Warp via presets= CLI arg
)
-To access the tiled rendering interface, a :class:`~sensors.TiledCamera` object can be created and used to retrieve data from the cameras.
+The active preset is selected at launch via the ``presets=`` CLI argument:
+
+.. code-block:: bash
+
+ # Use Newton Warp renderer
+ python train.py task=Isaac-Cartpole-RGB-Camera-Direct-v0 presets=newton_renderer
+
+ # Use OVRTX renderer
+ python train.py task=Isaac-Cartpole-RGB-Camera-Direct-v0 presets=ovrtx_renderer
+
+ # Use default (Isaac RTX)
+ python train.py task=Isaac-Cartpole-RGB-Camera-Direct-v0
+
+
+Accessing camera data
+~~~~~~~~~~~~~~~~~~~~~
.. code-block:: python
tiled_camera = TiledCamera(cfg.tiled_camera)
- data_type = "rgb"
- data = tiled_camera.data.output[data_type]
+ data = tiled_camera.data.output["rgb"] # shape: (num_cameras, H, W, 3), torch.uint8
-The returned data will be transformed into the shape (num_cameras, height, width, num_channels), which can be used directly as observation for reinforcement learning.
+The returned data has shape ``(num_cameras, height, width, num_channels)``, ready to use directly
+as an observation in RL training.
-When working with rendering, make sure to add the ``--enable_cameras`` argument when launching the environment. For example:
+When using the RTX renderer, add ``--enable_cameras`` when launching:
.. code-block:: shell
- python scripts/reinforcement_learning/rl_games/train.py --task=Isaac-Cartpole-RGB-Camera-Direct-v0 --headless --enable_cameras
+ python scripts/reinforcement_learning/rl_games/train.py \
+ --task=Isaac-Cartpole-RGB-Camera-Direct-v0 --headless --enable_cameras
+
+Annotators (RTX only)
+~~~~~~~~~~~~~~~~~~~~~
-Annotators
-~~~~~~~~~~
+.. note::
-Both :class:`~sensors.TiledCamera` and :class:`~sensors.Camera` classes provide APIs for retrieving various types annotator data from replicator:
+ Annotators are a feature of the **Isaac RTX renderer** (``IsaacRtxRendererCfg``).
+ They are **not** available with the Newton Warp renderer or ovrtx, which
+ support only ``rgb`` and ``depth``.
+
+:class:`~sensors.TiledCamera` exposes the following annotator
+data types when using the RTX renderer:
* ``"rgb"``: A 3-channel rendered color image.
* ``"rgba"``: A 4-channel rendered color image with alpha channel.
-* ``"distance_to_camera"``: An image containing the distance to camera optical center.
-* ``"distance_to_image_plane"``: An image containing distances of 3D points from camera plane along camera's z-axis.
-* ``"depth"``: The same as ``"distance_to_image_plane"``.
-* ``"normals"``: An image containing the local surface normal vectors at each pixel.
-* ``"motion_vectors"``: An image containing the motion vector data at each pixel.
-* ``"semantic_segmentation"``: The semantic segmentation data.
-* ``"instance_segmentation_fast"``: The instance segmentation data.
-* ``"instance_id_segmentation_fast"``: The instance id segmentation data.
+* ``"distance_to_camera"``: Distance to the camera optical center per pixel.
+* ``"distance_to_image_plane"``: Distance along the camera's Z-axis per pixel.
+* ``"depth"``: Alias for ``"distance_to_image_plane"``.
+* ``"normals"``: Local surface normal vectors at each pixel.
+* ``"motion_vectors"``: Per-pixel motion vectors in image space.
+* ``"semantic_segmentation"``: Semantic segmentation labels.
+* ``"instance_segmentation_fast"``: Instance segmentation data.
+* ``"instance_id_segmentation_fast"``: Instance ID segmentation data.
RGB and RGBA
~~~~~~~~~~~~
@@ -77,11 +207,11 @@ RGB and RGBA
:figwidth: 100%
:alt: A scene captured in RGB
-``rgb`` data type returns a 3-channel RGB colored image of type ``torch.uint8``, with dimension (B, H, W, 3).
+``rgb`` returns a 3-channel RGB image of type ``torch.uint8``, shape ``(B, H, W, 3)``.
-``rgba`` data type returns a 4-channel RGBA colored image of type ``torch.uint8``, with dimension (B, H, W, 4).
+``rgba`` returns a 4-channel RGBA image of type ``torch.uint8``, shape ``(B, H, W, 4)``.
-To convert the ``torch.uint8`` data to ``torch.float32``, divide the buffer by 255.0 to obtain a ``torch.float32`` buffer containing data from 0 to 1.
+To convert to ``torch.float32``, divide by 255.0.
Depth and Distances
~~~~~~~~~~~~~~~~~~~
@@ -89,13 +219,15 @@ Depth and Distances
.. figure:: ../../../_static/overview/sensors/camera_depth.jpg
:align: center
:figwidth: 100%
- :alt: A scene captured in RGB
+ :alt: A scene captured as depth
-``distance_to_camera`` returns a single-channel depth image with distance to the camera optical center. The dimension for this annotator is (B, H, W, 1) and has type ``torch.float32``.
+``distance_to_camera`` returns a single-channel depth image with distance to the camera optical
+center, shape ``(B, H, W, 1)``, type ``torch.float32``.
-``distance_to_image_plane`` returns a single-channel depth image with distances of 3D points from the camera plane along the camera's Z-axis. The dimension for this annotator is (B, H, W, 1) and has type ``torch.float32``.
+``distance_to_image_plane`` returns distances of 3D points from the camera plane along the Z-axis,
+shape ``(B, H, W, 1)``, type ``torch.float32``.
-``depth`` is provided as an alias for ``distance_to_image_plane`` and will return the same data as the ``distance_to_image_plane`` annotator, with dimension (B, H, W, 1) and type ``torch.float32``.
+``depth`` is an alias for ``distance_to_image_plane``.
Normals
~~~~~~~
@@ -103,14 +235,17 @@ Normals
.. figure:: ../../../_static/overview/sensors/camera_normals.jpg
:align: center
:figwidth: 100%
- :alt: A scene captured in RGB
+ :alt: A scene captured with surface normals
-``normals`` returns an image containing the local surface normal vectors at each pixel. The buffer has dimension (B, H, W, 3), containing the (x, y, z) information for each vector, and has data type ``torch.float32``.
+``normals`` returns local surface normal vectors at each pixel, shape ``(B, H, W, 3)`` containing
+``(x, y, z)``, type ``torch.float32``.
Motion Vectors
~~~~~~~~~~~~~~
-``motion_vectors`` returns the per-pixel motion vectors in image space, with a 2D array of motion vectors representing the relative motion of a pixel in the camera’s viewport between frames. The buffer has dimension (B, H, W, 2), representing x - the motion distance in the horizontal axis (image width) with movement to the left of the image being positive and movement to the right being negative and y - motion distance in the vertical axis (image height) with movement towards the top of the image being positive and movement to the bottom being negative. The data type is ``torch.float32``.
+``motion_vectors`` returns per-pixel motion vectors in image space between frames.
+Shape ``(B, H, W, 2)``: ``x`` is horizontal motion (positive = left), ``y`` is vertical motion
+(positive = up). Type ``torch.float32``.
Semantic Segmentation
~~~~~~~~~~~~~~~~~~~~~
@@ -118,13 +253,15 @@ Semantic Segmentation
.. figure:: ../../../_static/overview/sensors/camera_semantic.jpg
:align: center
:figwidth: 100%
- :alt: A scene captured in RGB
-
-``semantic_segmentation`` outputs semantic segmentation of each entity in the camera’s viewport that has semantic labels. In addition to the image buffer, an ``info`` dictionary can be retrieved with ``tiled_camera.data.info['semantic_segmentation']`` containing ID to labels information.
+ :alt: A scene with semantic segmentation
-- If ``colorize_semantic_segmentation=True`` in the camera config, a 4-channel RGBA image will be returned with dimension (B, H, W, 4) and type ``torch.uint8``. The info ``idToLabels`` dictionary will be the mapping from color to semantic labels.
+``semantic_segmentation`` outputs per-pixel semantic labels for entities with semantic annotations.
+An ``info`` dictionary is available via ``tiled_camera.data.info['semantic_segmentation']``.
-- If ``colorize_semantic_segmentation=False``, a buffer of dimension (B, H, W, 1) of type ``torch.int32`` will be returned, containing the semantic ID of each pixel. The info ``idToLabels`` dictionary will be the mapping from semantic ID to semantic labels.
+- If ``colorize_semantic_segmentation=True``: 4-channel RGBA image, shape ``(B, H, W, 4)``,
+ type ``torch.uint8``. The ``idToLabels`` dict maps color to semantic label.
+- If ``colorize_semantic_segmentation=False``: shape ``(B, H, W, 1)``, type ``torch.int32``,
+ containing semantic IDs. The ``idToLabels`` dict maps ID to label.
Instance ID Segmentation
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -132,15 +269,15 @@ Instance ID Segmentation
.. figure:: ../../../_static/overview/sensors/camera_instanceID.jpg
:align: center
:figwidth: 100%
- :alt: A scene captured in RGB
-
-``instance_id_segmentation_fast`` outputs instance ID segmentation of each entity in the camera’s viewport. The instance ID is unique for each prim in the scene with different paths. In addition to the image buffer, an ``info`` dictionary can be retrieved with ``tiled_camera.data.info['instance_id_segmentation_fast']`` containing ID to labels information.
+ :alt: A scene with instance ID segmentation
-The main difference between ``instance_id_segmentation_fast`` and ``instance_segmentation_fast`` are that instance segmentation annotator goes down the hierarchy to the lowest level prim which has semantic labels, where instance ID segmentation always goes down to the leaf prim.
+``instance_id_segmentation_fast`` outputs per-pixel instance IDs, unique per USD prim path.
+An ``info`` dictionary is available via ``tiled_camera.data.info['instance_id_segmentation_fast']``.
-- If ``colorize_instance_id_segmentation=True`` in the camera config, a 4-channel RGBA image will be returned with dimension (B, H, W, 4) and type ``torch.uint8``. The info ``idToLabels`` dictionary will be the mapping from color to USD prim path of that entity.
-
-- If ``colorize_instance_id_segmentation=False``, a buffer of dimension (B, H, W, 1) of type ``torch.int32`` will be returned, containing the instance ID of each pixel. The info ``idToLabels`` dictionary will be the mapping from instance ID to USD prim path of that entity.
+- If ``colorize_instance_id_segmentation=True``: shape ``(B, H, W, 4)``, type ``torch.uint8``.
+ The ``idToLabels`` dict maps color to USD prim path.
+- If ``colorize_instance_id_segmentation=False``: shape ``(B, H, W, 1)``, type ``torch.int32``.
+ The ``idToLabels`` dict maps instance ID to USD prim path.
Instance Segmentation
"""""""""""""""""""""
@@ -148,12 +285,15 @@ Instance Segmentation
.. figure:: ../../../_static/overview/sensors/camera_instance.jpg
:align: center
:figwidth: 100%
- :alt: A scene captured in RGB
-
-``instance_segmentation_fast`` outputs instance segmentation of each entity in the camera’s viewport. In addition to the image buffer, an ``info`` dictionary can be retrieved with ``tiled_camera.data.info['instance_segmentation_fast']`` containing ID to labels and ID to semantic information.
+ :alt: A scene with instance segmentation
-- If ``colorize_instance_segmentation=True`` in the camera config, a 4-channel RGBA image will be returned with dimension (B, H, W, 4) and type ``torch.uint8``.
+``instance_segmentation_fast`` outputs instance segmentation, traversing down the prim hierarchy
+to the lowest level with semantic labels (unlike ``instance_id_segmentation_fast``, which always
+goes to the leaf prim).
+An ``info`` dictionary is available via ``tiled_camera.data.info['instance_segmentation_fast']``.
-- If ``colorize_instance_segmentation=False``, a buffer of dimension (B, H, W, 1) of type ``torch.int32`` will be returned, containing the instance ID of each pixel.
+- If ``colorize_instance_segmentation=True``: shape ``(B, H, W, 4)``, type ``torch.uint8``.
+- If ``colorize_instance_segmentation=False``: shape ``(B, H, W, 1)``, type ``torch.int32``.
-The info ``idToLabels`` dictionary will be the mapping from color to USD prim path of that semantic entity. The info ``idToSemantics`` dictionary will be the mapping from color to semantic labels of that semantic entity.
+The ``idToLabels`` dict maps color to USD prim path. The ``idToSemantics`` dict maps color to
+semantic label.
diff --git a/docs/source/overview/core-concepts/sensors/contact_sensor.rst b/docs/source/overview/core-concepts/sensors/contact_sensor.rst
index 4ddd2d10c07..ebd81e60a54 100644
--- a/docs/source/overview/core-concepts/sensors/contact_sensor.rst
+++ b/docs/source/overview/core-concepts/sensors/contact_sensor.rst
@@ -55,7 +55,7 @@ Here, we print both the net contact force and the filtered force matrix for each
-------------------------------
Contact sensor @ '/World/envs/env_.*/Robot/LF_FOOT':
- view type :
+ view type :
update period (s) : 0.0
number of bodies : 1
body names : ['LF_FOOT']
@@ -64,7 +64,7 @@ Here, we print both the net contact force and the filtered force matrix for each
Received contact force of: tensor([[[-1.3923e-05, 1.5727e-04, 1.1032e+02]]], device='cuda:0')
-------------------------------
Contact sensor @ '/World/envs/env_.*/Robot/RF_FOOT':
- view type :
+ view type :
update period (s) : 0.0
number of bodies : 1
body names : ['RF_FOOT']
@@ -85,7 +85,7 @@ Notice that even with filtering, both sensors report the net contact force actin
-------------------------------
Contact sensor @ '/World/envs/env_.*/Robot/.*H_FOOT':
- view type :
+ view type :
update period (s) : 0.0
number of bodies : 2
body names : ['LH_FOOT', 'RH_FOOT']
diff --git a/docs/source/overview/core-concepts/sensors/imu.rst b/docs/source/overview/core-concepts/sensors/imu.rst
index fe429f77a2b..5435bf227f5 100644
--- a/docs/source/overview/core-concepts/sensors/imu.rst
+++ b/docs/source/overview/core-concepts/sensors/imu.rst
@@ -61,7 +61,7 @@ The oscillations in the values reported by the sensor are a direct result of of
.. code-block:: bash
Imu sensor @ '/World/envs/env_.*/Robot/LF_FOOT':
- view type :
+ view type :
update period (s) : 0.0
number of sensors : 1
@@ -71,7 +71,7 @@ The oscillations in the values reported by the sensor are a direct result of of
Received angular acceleration: tensor([[-0.0389, -0.0262, -0.0045]], device='cuda:0')
-------------------------------
Imu sensor @ '/World/envs/env_.*/Robot/RF_FOOT':
- view type :
+ view type :
update period (s) : 0.0
number of sensors : 1
diff --git a/docs/source/overview/developer-guide/development.rst b/docs/source/overview/developer-guide/development.rst
index 48a5019609f..3d9ddbf014a 100644
--- a/docs/source/overview/developer-guide/development.rst
+++ b/docs/source/overview/developer-guide/development.rst
@@ -61,19 +61,19 @@ More specifically, when an extension is enabled, the python module specified in
While loading extensions into Omniverse happens automatically, using the python package
in standalone applications requires additional steps. To simplify the build process and
avoid the need to understand the `premake `__
-build system used by Omniverse, we directly use the `setuptools `__
+build system used by Omniverse, we directly use the `setuptools `__
python package to build the python module provided by the extensions. This is done by the
``setup.py`` file in the extension directory.
.. note::
The ``setup.py`` file is not required for extensions that are only loaded into Omniverse
- using the `Extension Manager `__.
+ using the `Extension Manager `__.
Lastly, the ``tests`` directory contains the unit tests for the extension. These are written
using the `unittest `__ framework. It is
important to note that Omniverse also provides a similar
-`testing framework `__.
+`testing framework `__.
However, it requires going through the build process and does not support testing of the python module in
standalone applications.
@@ -81,7 +81,7 @@ Custom Extension Dependency Management
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Certain extensions may have dependencies which require the installation of additional packages before the extension
-can be used. While Python dependencies are handled by the `setuptools `__
+can be used. While Python dependencies are handled by the `setuptools `__
package and specified in the ``setup.py`` file, non-Python dependencies such as `ROS `__
packages or `apt `__ packages are not handled by setuptools.
Handling these kinds of dependencies requires an additional procedure.
diff --git a/docs/source/overview/developer-guide/vs_code.rst b/docs/source/overview/developer-guide/vs_code.rst
index a19889d1bdb..11946a71c76 100644
--- a/docs/source/overview/developer-guide/vs_code.rst
+++ b/docs/source/overview/developer-guide/vs_code.rst
@@ -55,6 +55,25 @@ following links:
* `Isaac Sim VSCode support `__
+Attach to a Running ``debugpy`` Session
+---------------------------------------
+
+The generated ``.vscode/launch.json`` includes a ``Python: Debugger Attach``
+configuration that starts to listen on port ``localhost:3000`` for the debugpy session.
+
+To use it:
+
+1. Set your breakpoints.
+2. Run your code under debugpy like so:
+
+ .. code-block:: bash
+
+ ./isaaclab.sh -p -m debugpy --listen 3000 --wait-for-client -c "from isaaclab.cli import cli; cli()" [cli_args]
+
+3. In VS Code, select the ``Python: Debugger Attach`` configuration from the Run and Debug panel
+ and press the green play button or ``F5``. VS Code will connect to the debugpy server
+ running on ``localhost:3000``.
+
Configuring the python interpreter
----------------------------------
diff --git a/docs/source/overview/environments.rst b/docs/source/overview/environments.rst
index c1cfb7dcb2c..80c12abb522 100644
--- a/docs/source/overview/environments.rst
+++ b/docs/source/overview/environments.rst
@@ -43,54 +43,52 @@ Classic
Classic environments that are based on IsaacGymEnvs implementation of MuJoCo-style environments.
.. table::
- :widths: 33 37 30
-
- +------------------+-----------------------------+-------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +==================+=============================+=========================================================================+
- | |humanoid| | |humanoid-link| | Move towards a direction with the MuJoCo humanoid robot |
- | | | |
- | | |humanoid-direct-link| | |
- +------------------+-----------------------------+-------------------------------------------------------------------------+
- | |ant| | |ant-link| | Move towards a direction with the MuJoCo ant robot |
- | | | |
- | | |ant-direct-link| | |
- +------------------+-----------------------------+-------------------------------------------------------------------------+
- | |cartpole| | |cartpole-link| | Move the cart to keep the pole upwards in the classic cartpole control |
- | | | |
- | | |cartpole-direct-link| | |
- +------------------+-----------------------------+-------------------------------------------------------------------------+
- | |cartpole| | |cartpole-rgb-link| | Move the cart to keep the pole upwards in the classic cartpole control |
- | | | and perceptive inputs. Requires running with ``--enable_cameras``. |
- | | |cartpole-depth-link| | |
- | | | |
- | | |cartpole-rgb-direct-link| | |
- | | | |
- | | |cartpole-depth-direct-link|| |
- +------------------+-----------------------------+-------------------------------------------------------------------------+
- | |cartpole| | |cartpole-resnet-link| | Move the cart to keep the pole upwards in the classic cartpole control |
- | | | based off of features extracted from perceptive inputs with pre-trained |
- | | |cartpole-theia-link| | frozen vision encoders. Requires running with ``--enable_cameras``. |
- +------------------+-----------------------------+-------------------------------------------------------------------------+
+ :widths: 25 30 25 20
+
+ +------------------+-----------------------------+-------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +==================+=============================+=========================================================================+=======================+
+ | |humanoid| | |humanoid-link| | Move towards a direction with the MuJoCo humanoid robot | ``newton``, ``physx`` |
+ | | | | ``ovphysx`` |
+ | | |humanoid-direct-link| | | |
+ +------------------+-----------------------------+-------------------------------------------------------------------------+-----------------------+
+ | |ant| | |ant-link| | Move towards a direction with the MuJoCo ant robot | ``newton``, ``physx`` |
+ | | | | ``ovphysx`` |
+ | | |ant-direct-link| | | |
+ +------------------+-----------------------------+-------------------------------------------------------------------------+-----------------------+
+ | |cartpole| | |cartpole-link| | Move the cart to keep the pole upwards in the classic cartpole control | ``newton``, ``physx`` |
+ | | | | ``ovphysx`` |
+ | | |cartpole-direct-link| | | |
+ +------------------+-----------------------------+-------------------------------------------------------------------------+-----------------------+
+ | |cartpole| | |cartpole-camera-presets| | Move the cart to keep the pole upwards in the classic cartpole control | ``newton``, ``physx`` |
+ | | | and perceptive inputs. Select data type via ``presets=``. Requires | ``newton_renderer``, |
+ | | | running with ``--enable_cameras``. | ``ovrtx_renderer``, |
+ | | | | ``rgb``, ``depth``, |
+ | | | | ``albedo``, |
+ | | | | ``semantic_`` |
+ | | | | ``segmentation``, |
+ | | | | ``simple_shading_*`` |
+ +------------------+-----------------------------+-------------------------------------------------------------------------+-----------------------+
+ | |cartpole| | |cartpole-resnet-link| | Move the cart to keep the pole upwards in the classic cartpole control | ``newton``, ``physx`` |
+ | | | based off of features extracted from perceptive inputs with pre-trained | |
+ | | |cartpole-theia-link| | frozen vision encoders. Requires running with ``--enable_cameras``. | |
+ +------------------+-----------------------------+-------------------------------------------------------------------------+-----------------------+
.. |humanoid| image:: ../_static/tasks/classic/humanoid.jpg
.. |ant| image:: ../_static/tasks/classic/ant.jpg
.. |cartpole| image:: ../_static/tasks/classic/cartpole.jpg
-.. |humanoid-link| replace:: `Isaac-Humanoid-v0 `__
-.. |ant-link| replace:: `Isaac-Ant-v0 `__
-.. |cartpole-link| replace:: `Isaac-Cartpole-v0 `__
-.. |cartpole-rgb-link| replace:: `Isaac-Cartpole-RGB-v0 `__
-.. |cartpole-depth-link| replace:: `Isaac-Cartpole-Depth-v0 `__
-.. |cartpole-resnet-link| replace:: `Isaac-Cartpole-RGB-ResNet18-v0 `__
-.. |cartpole-theia-link| replace:: `Isaac-Cartpole-RGB-TheiaTiny-v0 `__
+.. |humanoid-link| replace:: `Isaac-Humanoid-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/humanoid/humanoid_env_cfg.py>`__
+.. |ant-link| replace:: `Isaac-Ant-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/ant/ant_env_cfg.py>`__
+.. |cartpole-link| replace:: `Isaac-Cartpole-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/cartpole/cartpole_env_cfg.py>`__
+.. |cartpole-camera-presets| replace:: `Isaac-Cartpole-Camera-Presets-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_camera_presets_env_cfg.py>`__
+.. |cartpole-resnet-link| replace:: `Isaac-Cartpole-RGB-ResNet18-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py>`__
+.. |cartpole-theia-link| replace:: `Isaac-Cartpole-RGB-TheiaTiny-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/classic/cartpole/cartpole_camera_env_cfg.py>`__
-.. |humanoid-direct-link| replace:: `Isaac-Humanoid-Direct-v0 `__
-.. |ant-direct-link| replace:: `Isaac-Ant-Direct-v0 `__
-.. |cartpole-direct-link| replace:: `Isaac-Cartpole-Direct-v0 `__
-.. |cartpole-rgb-direct-link| replace:: `Isaac-Cartpole-RGB-Camera-Direct-v0 `__
-.. |cartpole-depth-direct-link| replace:: `Isaac-Cartpole-Depth-Camera-Direct-v0 `__
+.. |humanoid-direct-link| replace:: `Isaac-Humanoid-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/humanoid/humanoid_env.py>`__
+.. |ant-direct-link| replace:: `Isaac-Ant-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/ant/ant_env.py>`__
+.. |cartpole-direct-link| replace:: `Isaac-Cartpole-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_env.py>`__
Manipulation
~~~~~~~~~~~~
@@ -105,79 +103,107 @@ for the lift-cube environment:
* |lift-cube-ik-rel-link|: Franka arm with relative IK control
.. table::
- :widths: 33 37 30
-
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +=========================+==============================+=============================================================================+
- | |reach-franka| | |reach-franka-link| | Move the end-effector to a sampled target pose with the Franka robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |reach-ur10| | |reach-ur10-link| | Move the end-effector to a sampled target pose with the UR10 robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |deploy-reach-ur10e| | |deploy-reach-ur10e-link| | Move the end-effector to a sampled target pose with the UR10e robot |
- | | | This policy has been deployed to a real robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |lift-cube| | |lift-cube-link| | Pick a cube and bring it to a sampled target position with the Franka robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |stack-cube| | |stack-cube-link| | Stack three cubes (bottom to top: blue, red, green) with the Franka robot. |
- | | | Blueprint env used for the NVIDIA Isaac GR00T blueprint for synthetic |
- | | |stack-cube-bp-link| | manipulation motion generation |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |surface-gripper| | |long-suction-link| | Stack three cubes (bottom to top: blue, red, green) |
- | | | with the UR10 arm and long surface gripper |
- | | |short-suction-link| | or short surface gripper. |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |cabi-franka| | |cabi-franka-link| | Grasp the handle of a cabinet's drawer and open it with the Franka robot |
- | | | |
- | | |franka-direct-link| | |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |cube-allegro| | |cube-allegro-link| | In-hand reorientation of a cube using Allegro hand |
- | | | |
- | | |allegro-direct-link| | |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |cube-shadow| | |cube-shadow-link| | In-hand reorientation of a cube using Shadow hand |
- | | | |
- | | |cube-shadow-ff-link| | |
- | | | |
- | | |cube-shadow-lstm-link| | |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |cube-shadow| | |cube-shadow-vis-link| | In-hand reorientation of a cube using Shadow hand using perceptive inputs. |
- | | | Requires running with ``--enable_cameras``. |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |gr1_pick_place| | |gr1_pick_place-link| | Pick up and place an object in a basket with a GR-1 humanoid robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |gr1_pp_waist| | |gr1_pp_waist-link| | Pick up and place an object in a basket with a GR-1 humanoid robot |
- | | | with waist degrees-of-freedom enables that provides a wider reach space. |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |g1_pick_place| | |g1_pick_place-link| | Pick up and place an object in a basket with a Unitree G1 humanoid robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |g1_pick_place_fixed| | |g1_pick_place_fixed-link| | Pick up and place an object in a basket with a Unitree G1 humanoid robot |
- | | | with three-fingered hands. Robot is set up with the base fixed in place. |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |g1_pick_place_lm| | |g1_pick_place_lm-link| | Pick up and place an object in a basket with a Unitree G1 humanoid robot |
- | | | with three-fingered hands and in-place locomanipulation capabilities |
- | | | enabled (i.e. Robot lower body balances in-place while upper body is |
- | | | controlled via Inverse Kinematics). |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |kuka-allegro-lift| | |kuka-allegro-lift-link| | Pick up a primitive shape on the table and lift it to target position |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |kuka-allegro-reorient| | |kuka-allegro-reorient-link| | Pick up a primitive shape on the table and orient it to target pose |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |galbot_stack| | |galbot_stack-link| | Stack three cubes (bottom to top: blue, red, green) with the left arm of |
- | | | a Galbot humanoid robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |agibot_place_mug| | |agibot_place_mug-link| | Pick up and place a mug upright with a Agibot A2D humanoid robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |agibot_place_toy| | |agibot_place_toy-link| | Pick up and place an object in a box with a Agibot A2D humanoid robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |reach_openarm_bi| | |reach_openarm_bi-link| | Move the end-effector to sampled target poses with the OpenArm robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |reach_openarm_uni| | |reach_openarm_uni-link| | Move the end-effector to a sampled target pose with the OpenArm robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |lift_openarm_uni| | |lift_openarm_uni-link| | Pick a cube and bring it to a sampled target position with the OpenArm robot|
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
- | |cabi_openarm_uni| | |cabi_openarm_uni-link| | Grasp the handle of a cabinet's drawer and open it with the OpenArm robot |
- +-------------------------+------------------------------+-----------------------------------------------------------------------------+
+ :widths: 25 30 25 20
+
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +=========================+==============================+=============================================================================+=======================+
+ | |reach-franka| | |reach-franka-link| | Move the end-effector to a sampled target pose with the Franka robot | ``newton``, ``physx`` |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |reach-ur10| | |reach-ur10-link| | Move the end-effector to a sampled target pose with the UR10 robot | ``newton``, ``physx`` |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |deploy-reach-ur10e| | |deploy-reach-ur10e-link| | Move the end-effector to a sampled target pose with the UR10e robot | |
+ | | | This policy has been deployed to a real robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |lift-cube| | |lift-cube-link| | Pick a cube and bring it to a sampled target position with the Franka robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |stack-cube| | |stack-cube-link| | Stack three cubes (bottom to top: blue, red, green) with the Franka robot. | |
+ | | | Blueprint env used for the NVIDIA Isaac GR00T blueprint for synthetic | |
+ | | |stack-cube-bp-link| | manipulation motion generation | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |surface-gripper| | |long-suction-link| | Stack three cubes (bottom to top: blue, red, green) | |
+ | | | with the UR10 arm and long surface gripper | |
+ | | |short-suction-link| | or short surface gripper. | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |cabi-franka| | |cabi-franka-link| | Grasp the handle of a cabinet's drawer and open it with the Franka robot | ``newton``, ``physx`` |
+ | | | | |
+ | | |franka-direct-link| | | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |cube-allegro| | |cube-allegro-link| | In-hand reorientation of a cube using Allegro hand | ``newton``, ``physx`` |
+ | | | | |
+ | | |allegro-direct-link| | | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |cube-shadow| | |cube-shadow-link| | In-hand reorientation of a cube using Shadow hand | ``newton``, ``physx`` |
+ | | | | |
+ | | |cube-shadow-ff-link| | | |
+ | | | | |
+ | | |cube-shadow-lstm-link| | | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |cube-shadow| | |cube-shadow-vis-link| | In-hand reorientation of a cube using Shadow hand using perceptive inputs. | ``newton``, ``physx`` |
+ | | | Requires running with ``--enable_cameras``. | ``newton_renderer``, |
+ | | | | ``ovrtx_renderer``, |
+ | | | | ``rgb``, ``depth``, |
+ | | | | ``albedo``, ``full``, |
+ | | | | ``semantic_`` |
+ | | | | ``segmentation``, |
+ | | | | ``simple_shading_*`` |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |gr1_pick_place| | |gr1_pick_place-link| | Pick up and place an object in a basket with a GR-1 humanoid robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |gr1_pp_waist| | |gr1_pp_waist-link| | Pick up and place an object in a basket with a GR-1 humanoid robot | |
+ | | | with waist degrees-of-freedom enables that provides a wider reach space. | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |g1_pick_place| | |g1_pick_place-link| | Pick up and place an object in a basket with a Unitree G1 humanoid robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |g1_pick_place_fixed| | |g1_pick_place_fixed-link| | Pick up and place an object in a basket with a Unitree G1 humanoid robot | |
+ | | | with three-fingered hands. Robot is set up with the base fixed in place. | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |g1_pick_place_lm| | |g1_pick_place_lm-link| | Pick up and place an object in a basket with a Unitree G1 humanoid robot | |
+ | | | with three-fingered hands and in-place locomanipulation capabilities | |
+ | | | enabled (i.e. Robot lower body balances in-place while upper body is | |
+ | | | controlled via Inverse Kinematics). | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |kuka-allegro-lift| | |kuka-allegro-lift-link| | Pick up a primitive shape on the table and lift it to target position. | ``newton``, ``physx`` |
+ | | | Supports state, single-camera, and dual-camera observation modes via | ``single_camera``, |
+ | | | ``presets=single_camera`` / ``presets=duo_camera`` (see RL table below). | ``duo_camera``, |
+ | | | | ``newton_renderer``, |
+ | | | | ``ovrtx_renderer``, |
+ | | | | ``rgb{64,128,256}``, |
+ | | | | ``depth{..}``, |
+ | | | | ``albedo{..}``, |
+ | | | | ``semantic_`` |
+ | | | | ``segmentation{..}``, |
+ | | | | ``simple_shading_*`` |
+ | | | | ``{64,128,256}`` |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |kuka-allegro-reorient| | |kuka-allegro-reorient-link| | Pick up a primitive shape on the table and orient it to target pose. | ``newton``, ``physx`` |
+ | | | Supports state, single-camera, and dual-camera observation modes via | ``single_camera``, |
+ | | | ``presets=single_camera`` / ``presets=duo_camera`` (see RL table below). | ``duo_camera``, |
+ | | | | ``newton_renderer``, |
+ | | | | ``ovrtx_renderer``, |
+ | | | | ``rgb{64,128,256}``, |
+ | | | | ``depth{..}``, |
+ | | | | ``albedo{..}``, |
+ | | | | ``semantic_`` |
+ | | | | ``segmentation{..}``, |
+ | | | | ``simple_shading_*`` |
+ | | | | ``{64,128,256}`` |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |galbot_stack| | |galbot_stack-link| | Stack three cubes (bottom to top: blue, red, green) with the left arm of | |
+ | | | a Galbot humanoid robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |agibot_place_mug| | |agibot_place_mug-link| | Pick up and place a mug upright with a Agibot A2D humanoid robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |agibot_place_toy| | |agibot_place_toy-link| | Pick up and place an object in a box with a Agibot A2D humanoid robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |reach_openarm_bi| | |reach_openarm_bi-link| | Move the end-effector to sampled target poses with the OpenArm robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |reach_openarm_uni| | |reach_openarm_uni-link| | Move the end-effector to a sampled target pose with the OpenArm robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |lift_openarm_uni| | |lift_openarm_uni-link| | Pick a cube and bring it to a sampled target position with the OpenArm robot| |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |cabi_openarm_uni| | |cabi_openarm_uni-link| | Grasp the handle of a cabinet's drawer and open it with the OpenArm robot | |
+ +-------------------------+------------------------------+-----------------------------------------------------------------------------+-----------------------+
.. |reach-franka| image:: ../_static/tasks/manipulation/franka_reach.jpg
.. |reach-ur10| image:: ../_static/tasks/manipulation/ur10_reach.jpg
@@ -203,38 +229,38 @@ for the lift-cube environment:
.. |lift_openarm_uni| image:: ../_static/tasks/manipulation/openarm_uni_lift.jpg
.. |cabi_openarm_uni| image:: ../_static/tasks/manipulation/openarm_uni_open_drawer.jpg
-.. |reach-franka-link| replace:: `Isaac-Reach-Franka-v0 `__
-.. |reach-ur10-link| replace:: `Isaac-Reach-UR10-v0 `__
-.. |deploy-reach-ur10e-link| replace:: `Isaac-Deploy-Reach-UR10e-v0 `__
-.. |lift-cube-link| replace:: `Isaac-Lift-Cube-Franka-v0 `__
-.. |lift-cube-ik-abs-link| replace:: `Isaac-Lift-Cube-Franka-IK-Abs-v0 `__
-.. |lift-cube-ik-rel-link| replace:: `Isaac-Lift-Cube-Franka-IK-Rel-v0 `__
-.. |cabi-franka-link| replace:: `Isaac-Open-Drawer-Franka-v0 `__
-.. |franka-direct-link| replace:: `Isaac-Franka-Cabinet-Direct-v0 `__
-.. |cube-allegro-link| replace:: `Isaac-Repose-Cube-Allegro-v0 `__
-.. |allegro-direct-link| replace:: `Isaac-Repose-Cube-Allegro-Direct-v0 `__
-.. |stack-cube-link| replace:: `Isaac-Stack-Cube-Franka-v0 `__
-.. |stack-cube-bp-link| replace:: `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0 `__
-.. |gr1_pick_place-link| replace:: `Isaac-PickPlace-GR1T2-Abs-v0 `__
-.. |g1_pick_place-link| replace:: `Isaac-PickPlace-G1-InspireFTP-Abs-v0 `__
-.. |g1_pick_place_fixed-link| replace:: `Isaac-PickPlace-FixedBaseUpperBodyIK-G1-Abs-v0 `__
-.. |g1_pick_place_lm-link| replace:: `Isaac-PickPlace-Locomanipulation-G1-Abs-v0 `__
-.. |long-suction-link| replace:: `Isaac-Stack-Cube-UR10-Long-Suction-IK-Rel-v0 `__
-.. |short-suction-link| replace:: `Isaac-Stack-Cube-UR10-Short-Suction-IK-Rel-v0 `__
-.. |gr1_pp_waist-link| replace:: `Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 `__
-.. |galbot_stack-link| replace:: `Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow-v0 `__
-.. |kuka-allegro-lift-link| replace:: `Isaac-Dexsuite-Kuka-Allegro-Lift-v0 `__
-.. |kuka-allegro-reorient-link| replace:: `Isaac-Dexsuite-Kuka-Allegro-Reorient-v0 `__
-.. |cube-shadow-link| replace:: `Isaac-Repose-Cube-Shadow-Direct-v0 `__
-.. |cube-shadow-ff-link| replace:: `Isaac-Repose-Cube-Shadow-OpenAI-FF-Direct-v0 `__
-.. |cube-shadow-lstm-link| replace:: `Isaac-Repose-Cube-Shadow-OpenAI-LSTM-Direct-v0 `__
-.. |cube-shadow-vis-link| replace:: `Isaac-Repose-Cube-Shadow-Vision-Direct-v0 `__
-.. |agibot_place_mug-link| replace:: `Isaac-Place-Mug-Agibot-Left-Arm-RmpFlow-v0 `__
-.. |agibot_place_toy-link| replace:: `Isaac-Place-Toy2Box-Agibot-Right-Arm-RmpFlow-v0 `__
-.. |reach_openarm_bi-link| replace:: `Isaac-Reach-OpenArm-Bi-v0 `__
-.. |reach_openarm_uni-link| replace:: `Isaac-Reach-OpenArm-v0 `__
-.. |lift_openarm_uni-link| replace:: `Isaac-Lift-Cube-OpenArm-v0 `__
-.. |cabi_openarm_uni-link| replace:: `Isaac-Open-Drawer-OpenArm-v0 `__
+.. |reach-franka-link| replace:: `Isaac-Reach-Franka-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/reach/config/franka/joint_pos_env_cfg.py>`__
+.. |reach-ur10-link| replace:: `Isaac-Reach-UR10-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/reach/config/ur_10/joint_pos_env_cfg.py>`__
+.. |deploy-reach-ur10e-link| replace:: `Isaac-Deploy-Reach-UR10e-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/deploy/reach/config/ur_10e/joint_pos_env_cfg.py>`__
+.. |lift-cube-link| replace:: `Isaac-Lift-Cube-Franka-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/lift/config/franka/joint_pos_env_cfg.py>`__
+.. |lift-cube-ik-abs-link| replace:: `Isaac-Lift-Cube-Franka-IK-Abs-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/lift/config/franka/ik_abs_env_cfg.py>`__
+.. |lift-cube-ik-rel-link| replace:: `Isaac-Lift-Cube-Franka-IK-Rel-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/lift/config/franka/ik_rel_env_cfg.py>`__
+.. |cabi-franka-link| replace:: `Isaac-Open-Drawer-Franka-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/cabinet/config/franka/joint_pos_env_cfg.py>`__
+.. |franka-direct-link| replace:: `Isaac-Franka-Cabinet-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/franka_cabinet/franka_cabinet_env.py>`__
+.. |cube-allegro-link| replace:: `Isaac-Repose-Cube-Allegro-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/inhand/config/allegro_hand/allegro_env_cfg.py>`__
+.. |allegro-direct-link| replace:: `Isaac-Repose-Cube-Allegro-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/allegro_hand/allegro_hand_env_cfg.py>`__
+.. |stack-cube-link| replace:: `Isaac-Stack-Cube-Franka-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/stack/config/franka/stack_joint_pos_env_cfg.py>`__
+.. |stack-cube-bp-link| replace:: `Isaac-Stack-Cube-Franka-IK-Rel-Blueprint-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/stack/config/franka/stack_ik_rel_blueprint_env_cfg.py>`__
+.. |gr1_pick_place-link| replace:: `Isaac-PickPlace-GR1T2-Abs-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_env_cfg.py>`__
+.. |g1_pick_place-link| replace:: `Isaac-PickPlace-G1-InspireFTP-Abs-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_unitree_g1_inspire_hand_env_cfg.py>`__
+.. |g1_pick_place_fixed-link| replace:: `Isaac-PickPlace-FixedBaseUpperBodyIK-G1-Abs-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/fixed_base_upper_body_ik_g1_env_cfg.py>`__
+.. |g1_pick_place_lm-link| replace:: `Isaac-PickPlace-Locomanipulation-G1-Abs-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/pick_place/locomanipulation_g1_env_cfg.py>`__
+.. |long-suction-link| replace:: `Isaac-Stack-Cube-UR10-Long-Suction-IK-Rel-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/stack/config/ur10_gripper/stack_ik_rel_env_cfg.py>`__
+.. |short-suction-link| replace:: `Isaac-Stack-Cube-UR10-Short-Suction-IK-Rel-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/stack/config/ur10_gripper/stack_ik_rel_env_cfg.py>`__
+.. |gr1_pp_waist-link| replace:: `Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/pick_place/pickplace_gr1t2_waist_enabled_env_cfg.py>`__
+.. |galbot_stack-link| replace:: `Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/stack/config/galbot/stack_rmp_rel_env_cfg.py>`__
+.. |kuka-allegro-lift-link| replace:: `Isaac-Dexsuite-Kuka-Allegro-Lift-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_env_cfg.py>`__
+.. |kuka-allegro-reorient-link| replace:: `Isaac-Dexsuite-Kuka-Allegro-Reorient-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/dexsuite/config/kuka_allegro/dexsuite_kuka_allegro_env_cfg.py>`__
+.. |cube-shadow-link| replace:: `Isaac-Repose-Cube-Shadow-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/shadow_hand/shadow_hand_env_cfg.py>`__
+.. |cube-shadow-ff-link| replace:: `Isaac-Repose-Cube-Shadow-OpenAI-FF-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/shadow_hand/shadow_hand_env_cfg.py>`__
+.. |cube-shadow-lstm-link| replace:: `Isaac-Repose-Cube-Shadow-OpenAI-LSTM-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/shadow_hand/shadow_hand_env_cfg.py>`__
+.. |cube-shadow-vis-link| replace:: `Isaac-Repose-Cube-Shadow-Vision-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/shadow_hand/shadow_hand_vision_env.py>`__
+.. |agibot_place_mug-link| replace:: `Isaac-Place-Mug-Agibot-Left-Arm-RmpFlow-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/place/config/agibot/place_upright_mug_rmp_rel_env_cfg.py>`__
+.. |agibot_place_toy-link| replace:: `Isaac-Place-Toy2Box-Agibot-Right-Arm-RmpFlow-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/place/config/agibot/place_toy2box_rmp_rel_env_cfg.py>`__
+.. |reach_openarm_bi-link| replace:: `Isaac-Reach-OpenArm-Bi-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/reach/config/openarm/bimanual/joint_pos_env_cfg.py>`__
+.. |reach_openarm_uni-link| replace:: `Isaac-Reach-OpenArm-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/reach/config/openarm/unimanual/joint_pos_env_cfg.py>`__
+.. |lift_openarm_uni-link| replace:: `Isaac-Lift-Cube-OpenArm-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/lift/config/openarm/joint_pos_env_cfg.py>`__
+.. |cabi_openarm_uni-link| replace:: `Isaac-Open-Drawer-OpenArm-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/manipulation/cabinet/config/openarm/joint_pos_env_cfg.py>`__
Contact-rich Manipulation
@@ -250,25 +276,25 @@ For example:
* |factory-nut-link|: Nut-Bolt fastening with the Franka arm
.. table::
- :widths: 33 37 30
-
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +====================+=========================+=============================================================================+
- | |factory-peg| | |factory-peg-link| | Insert peg into the socket with the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | |factory-gear| | |factory-gear-link| | Insert and mesh gear into the base with other gears, using the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | |factory-nut| | |factory-nut-link| | Thread the nut onto the first 2 threads of the bolt, using the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
+ :widths: 25 30 25 20
+
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +====================+=========================+=============================================================================+=======================+
+ | |factory-peg| | |factory-peg-link| | Insert peg into the socket with the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |factory-gear| | |factory-gear-link| | Insert and mesh gear into the base with other gears, using the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |factory-nut| | |factory-nut-link| | Thread the nut onto the first 2 threads of the bolt, using the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
.. |factory-peg| image:: ../_static/tasks/factory/peg_insert.jpg
.. |factory-gear| image:: ../_static/tasks/factory/gear_mesh.jpg
.. |factory-nut| image:: ../_static/tasks/factory/nut_thread.jpg
-.. |factory-peg-link| replace:: `Isaac-Factory-PegInsert-Direct-v0 `__
-.. |factory-gear-link| replace:: `Isaac-Factory-GearMesh-Direct-v0 `__
-.. |factory-nut-link| replace:: `Isaac-Factory-NutThread-Direct-v0 `__
+.. |factory-peg-link| replace:: `Isaac-Factory-PegInsert-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/factory/factory_env_cfg.py>`__
+.. |factory-gear-link| replace:: `Isaac-Factory-GearMesh-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/factory/factory_env_cfg.py>`__
+.. |factory-nut-link| replace:: `Isaac-Factory-NutThread-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/factory/factory_env_cfg.py>`__
AutoMate
~~~~~~~~
@@ -283,7 +309,7 @@ We provide environments for both disassembly and assembly.
.. attention::
- CUDA is recommended for running the AutoMate environments with 570 drivers. If running with Nvidia driver 570 on Linux with architecture x86_64, we follow the below steps to install CUDA 12.8. This allows for computing rewards in AutoMate environments with CUDA. If you have a different operation system or architecture, please refer to the `CUDA installation page `_ for additional instruction.
+ CUDA is recommended for running the AutoMate environments. If running with Nvidia driver 570 on Linux with architecture x86_64, we follow the below steps to install CUDA 12.8. This allows for computing rewards in AutoMate environments with CUDA. If you have a different operation system or architecture, please refer to the `CUDA installation page `_ for additional instruction.
.. code-block:: bash
@@ -296,7 +322,14 @@ We provide environments for both disassembly and assembly.
conda install cudatoolkit
- With 580 drivers and CUDA 13, we are currently unable to enable CUDA for computing the rewards. The code automatically fallbacks to CPU, resulting in slightly slower performance.
+ With 580 drivers on Linux with architecture x86_64, we install CUDA 13 and additionally install several packages. Please ensure that the pytorch version is compatible with the CUDA version.
+
+ .. code-block:: bash
+
+ wget https://developer.download.nvidia.com/compute/cuda/13.0.2/local_installers/cuda_13.0.2_580.95.05_linux.run
+ sudo sh cuda_13.0.2_580.95.05_linux.run --toolkit
+ pip install numba-cuda[cu13] coverage==7.6.1
+
* |disassembly-link|: The plug starts inserted in the socket. A low-level controller lifts the plug out and moves it to a random position. This process is purely scripted and does not involve any learned policy. Therefore, it does not require policy training or evaluation. The resulting trajectories serve as demonstrations for the reverse process, i.e., learning to assemble. To run disassembly for a specific task: ``python source/isaaclab_tasks/isaaclab_tasks/direct/automate/run_disassembly_w_id.py --assembly_id=ASSEMBLY_ID --disassembly_dir=DISASSEMBLY_DIR``. All generated trajectories are saved to a local directory ``DISASSEMBLY_DIR``.
* |assembly-link|: The goal is to insert the plug into the socket. You can use this environment to train a policy via reinforcement learning or evaluate a pre-trained checkpoint.
@@ -305,21 +338,21 @@ We provide environments for both disassembly and assembly.
* To evaluate an assembly policy, we run the command ``python source/isaaclab_tasks/isaaclab_tasks/direct/automate/run_w_id.py --assembly_id=ASSEMBLY_ID --checkpoint=CHECKPOINT --log_eval``. The evaluation results are stored in ``evaluation_{ASSEMBLY_ID}.h5``.
.. table::
- :widths: 33 37 30
+ :widths: 25 30 25 20
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +====================+=========================+=============================================================================+
- | |disassembly| | |disassembly-link| | Lift a plug out of the socket with the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | |assembly| | |assembly-link| | Insert a plug into its corresponding socket with the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +====================+=========================+=============================================================================+=======================+
+ | |disassembly| | |disassembly-link| | Lift a plug out of the socket with the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |assembly| | |assembly-link| | Insert a plug into its corresponding socket with the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
.. |assembly| image:: ../_static/tasks/automate/00004.jpg
.. |disassembly| image:: ../_static/tasks/automate/01053_disassembly.jpg
-.. |assembly-link| replace:: `Isaac-AutoMate-Assembly-Direct-v0 `__
-.. |disassembly-link| replace:: `Isaac-AutoMate-Disassembly-Direct-v0 `__
+.. |assembly-link| replace:: `Isaac-AutoMate-Assembly-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/automate/assembly_env_cfg.py>`__
+.. |disassembly-link| replace:: `Isaac-AutoMate-Disassembly-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/automate/disassembly_env_cfg.py>`__
FORGE
~~~~~~~~
@@ -338,25 +371,25 @@ These tasks share the same task configurations and control options. You can swit
* |forge-nut-link|: Nut-Bolt fastening with the Franka arm
.. table::
- :widths: 33 37 30
-
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +====================+=========================+=============================================================================+
- | |forge-peg| | |forge-peg-link| | Insert peg into the socket with the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | |forge-gear| | |forge-gear-link| | Insert and mesh gear into the base with other gears, using the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
- | |forge-nut| | |forge-nut-link| | Thread the nut onto the first 2 threads of the bolt, using the Franka robot |
- +--------------------+-------------------------+-----------------------------------------------------------------------------+
+ :widths: 25 30 25 20
+
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +====================+=========================+=============================================================================+=======================+
+ | |forge-peg| | |forge-peg-link| | Insert peg into the socket with the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |forge-gear| | |forge-gear-link| | Insert and mesh gear into the base with other gears, using the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |forge-nut| | |forge-nut-link| | Thread the nut onto the first 2 threads of the bolt, using the Franka robot | |
+ +--------------------+-------------------------+-----------------------------------------------------------------------------+-----------------------+
.. |forge-peg| image:: ../_static/tasks/factory/peg_insert.jpg
.. |forge-gear| image:: ../_static/tasks/factory/gear_mesh.jpg
.. |forge-nut| image:: ../_static/tasks/factory/nut_thread.jpg
-.. |forge-peg-link| replace:: `Isaac-Forge-PegInsert-Direct-v0 `__
-.. |forge-gear-link| replace:: `Isaac-Forge-GearMesh-Direct-v0 `__
-.. |forge-nut-link| replace:: `Isaac-Forge-NutThread-Direct-v0 `__
+.. |forge-peg-link| replace:: `Isaac-Forge-PegInsert-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/forge/forge_env_cfg.py>`__
+.. |forge-gear-link| replace:: `Isaac-Forge-GearMesh-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/forge/forge_env_cfg.py>`__
+.. |forge-nut-link| replace:: `Isaac-Forge-NutThread-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/forge/forge_env_cfg.py>`__
Locomotion
@@ -365,88 +398,88 @@ Locomotion
Environments based on legged locomotion tasks.
.. table::
- :widths: 33 37 30
-
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +==============================+==============================================+==============================================================================+
- | |velocity-flat-anymal-b| | |velocity-flat-anymal-b-link| | Track a velocity command on flat terrain with the Anymal B robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-anymal-b| | |velocity-rough-anymal-b-link| | Track a velocity command on rough terrain with the Anymal B robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-anymal-c| | |velocity-flat-anymal-c-link| | Track a velocity command on flat terrain with the Anymal C robot |
- | | | |
- | | |velocity-flat-anymal-c-direct-link| | |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-anymal-c| | |velocity-rough-anymal-c-link| | Track a velocity command on rough terrain with the Anymal C robot |
- | | | |
- | | |velocity-rough-anymal-c-direct-link| | |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-anymal-d| | |velocity-flat-anymal-d-link| | Track a velocity command on flat terrain with the Anymal D robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-anymal-d| | |velocity-rough-anymal-d-link| | Track a velocity command on rough terrain with the Anymal D robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-unitree-a1| | |velocity-flat-unitree-a1-link| | Track a velocity command on flat terrain with the Unitree A1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-unitree-a1| | |velocity-rough-unitree-a1-link| | Track a velocity command on rough terrain with the Unitree A1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-unitree-go1| | |velocity-flat-unitree-go1-link| | Track a velocity command on flat terrain with the Unitree Go1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-unitree-go1| | |velocity-rough-unitree-go1-link| | Track a velocity command on rough terrain with the Unitree Go1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-unitree-go2| | |velocity-flat-unitree-go2-link| | Track a velocity command on flat terrain with the Unitree Go2 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-unitree-go2| | |velocity-rough-unitree-go2-link| | Track a velocity command on rough terrain with the Unitree Go2 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-spot| | |velocity-flat-spot-link| | Track a velocity command on flat terrain with the Boston Dynamics Spot robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-h1| | |velocity-flat-h1-link| | Track a velocity command on flat terrain with the Unitree H1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-h1| | |velocity-rough-h1-link| | Track a velocity command on rough terrain with the Unitree H1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-g1| | |velocity-flat-g1-link| | Track a velocity command on flat terrain with the Unitree G1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-g1| | |velocity-rough-g1-link| | Track a velocity command on rough terrain with the Unitree G1 robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-flat-digit| | |velocity-flat-digit-link| | Track a velocity command on flat terrain with the Agility Digit robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |velocity-rough-digit| | |velocity-rough-digit-link| | Track a velocity command on rough terrain with the Agility Digit robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
- | |tracking-loco-manip-digit| | |tracking-loco-manip-digit-link| | Track a root velocity and hand pose command with the Agility Digit robot |
- +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+
-
-.. |velocity-flat-anymal-b-link| replace:: `Isaac-Velocity-Flat-Anymal-B-v0 `__
-.. |velocity-rough-anymal-b-link| replace:: `Isaac-Velocity-Rough-Anymal-B-v0 `__
-
-.. |velocity-flat-anymal-c-link| replace:: `Isaac-Velocity-Flat-Anymal-C-v0 `__
-.. |velocity-rough-anymal-c-link| replace:: `Isaac-Velocity-Rough-Anymal-C-v0 `__
-
-.. |velocity-flat-anymal-c-direct-link| replace:: `Isaac-Velocity-Flat-Anymal-C-Direct-v0 `__
-.. |velocity-rough-anymal-c-direct-link| replace:: `Isaac-Velocity-Rough-Anymal-C-Direct-v0 `__
-
-.. |velocity-flat-anymal-d-link| replace:: `Isaac-Velocity-Flat-Anymal-D-v0 `__
-.. |velocity-rough-anymal-d-link| replace:: `Isaac-Velocity-Rough-Anymal-D-v0 `__
-
-.. |velocity-flat-unitree-a1-link| replace:: `Isaac-Velocity-Flat-Unitree-A1-v0 `__
-.. |velocity-rough-unitree-a1-link| replace:: `Isaac-Velocity-Rough-Unitree-A1-v0 `__
-
-.. |velocity-flat-unitree-go1-link| replace:: `Isaac-Velocity-Flat-Unitree-Go1-v0 `__
-.. |velocity-rough-unitree-go1-link| replace:: `Isaac-Velocity-Rough-Unitree-Go1-v0 `__
-
-.. |velocity-flat-unitree-go2-link| replace:: `Isaac-Velocity-Flat-Unitree-Go2-v0 `__
-.. |velocity-rough-unitree-go2-link| replace:: `Isaac-Velocity-Rough-Unitree-Go2-v0 `__
-
-.. |velocity-flat-spot-link| replace:: `Isaac-Velocity-Flat-Spot-v0 `__
-
-.. |velocity-flat-h1-link| replace:: `Isaac-Velocity-Flat-H1-v0 `__
-.. |velocity-rough-h1-link| replace:: `Isaac-Velocity-Rough-H1-v0 `__
-
-.. |velocity-flat-g1-link| replace:: `Isaac-Velocity-Flat-G1-v0 `__
-.. |velocity-rough-g1-link| replace:: `Isaac-Velocity-Rough-G1-v0 `__
-
-.. |velocity-flat-digit-link| replace:: `Isaac-Velocity-Flat-Digit-v0 `__
-.. |velocity-rough-digit-link| replace:: `Isaac-Velocity-Rough-Digit-v0 `__
-.. |tracking-loco-manip-digit-link| replace:: `Isaac-Tracking-LocoManip-Digit-v0 `__
+ :widths: 25 30 25 20
+
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +==============================+==============================================+==============================================================================+=======================+
+ | |velocity-flat-anymal-b| | |velocity-flat-anymal-b-link| | Track a velocity command on flat terrain with the Anymal B robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-anymal-b| | |velocity-rough-anymal-b-link| | Track a velocity command on rough terrain with the Anymal B robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-anymal-c| | |velocity-flat-anymal-c-link| | Track a velocity command on flat terrain with the Anymal C robot | ``newton``, ``physx`` |
+ | | | | |
+ | | |velocity-flat-anymal-c-direct-link| | | |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-anymal-c| | |velocity-rough-anymal-c-link| | Track a velocity command on rough terrain with the Anymal C robot | ``newton``, ``physx`` |
+ | | | | |
+ | | |velocity-rough-anymal-c-direct-link| | | |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-anymal-d| | |velocity-flat-anymal-d-link| | Track a velocity command on flat terrain with the Anymal D robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-anymal-d| | |velocity-rough-anymal-d-link| | Track a velocity command on rough terrain with the Anymal D robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-unitree-a1| | |velocity-flat-unitree-a1-link| | Track a velocity command on flat terrain with the Unitree A1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-unitree-a1| | |velocity-rough-unitree-a1-link| | Track a velocity command on rough terrain with the Unitree A1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-unitree-go1| | |velocity-flat-unitree-go1-link| | Track a velocity command on flat terrain with the Unitree Go1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-unitree-go1| | |velocity-rough-unitree-go1-link| | Track a velocity command on rough terrain with the Unitree Go1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-unitree-go2| | |velocity-flat-unitree-go2-link| | Track a velocity command on flat terrain with the Unitree Go2 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-unitree-go2| | |velocity-rough-unitree-go2-link| | Track a velocity command on rough terrain with the Unitree Go2 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-spot| | |velocity-flat-spot-link| | Track a velocity command on flat terrain with the Boston Dynamics Spot robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-h1| | |velocity-flat-h1-link| | Track a velocity command on flat terrain with the Unitree H1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-h1| | |velocity-rough-h1-link| | Track a velocity command on rough terrain with the Unitree H1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-g1| | |velocity-flat-g1-link| | Track a velocity command on flat terrain with the Unitree G1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-g1| | |velocity-rough-g1-link| | Track a velocity command on rough terrain with the Unitree G1 robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-flat-digit| | |velocity-flat-digit-link| | Track a velocity command on flat terrain with the Agility Digit robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |velocity-rough-digit| | |velocity-rough-digit-link| | Track a velocity command on rough terrain with the Agility Digit robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+ | |tracking-loco-manip-digit| | |tracking-loco-manip-digit-link| | Track a root velocity and hand pose command with the Agility Digit robot | ``newton``, ``physx`` |
+ +------------------------------+----------------------------------------------+------------------------------------------------------------------------------+-----------------------+
+
+.. |velocity-flat-anymal-b-link| replace:: `Isaac-Velocity-Flat-Anymal-B-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_b/flat_env_cfg.py>`__
+.. |velocity-rough-anymal-b-link| replace:: `Isaac-Velocity-Rough-Anymal-B-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_b/rough_env_cfg.py>`__
+
+.. |velocity-flat-anymal-c-link| replace:: `Isaac-Velocity-Flat-Anymal-C-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_c/flat_env_cfg.py>`__
+.. |velocity-rough-anymal-c-link| replace:: `Isaac-Velocity-Rough-Anymal-C-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_c/rough_env_cfg.py>`__
+
+.. |velocity-flat-anymal-c-direct-link| replace:: `Isaac-Velocity-Flat-Anymal-C-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/anymal_c/anymal_c_env.py>`__
+.. |velocity-rough-anymal-c-direct-link| replace:: `Isaac-Velocity-Rough-Anymal-C-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/anymal_c/anymal_c_env.py>`__
+
+.. |velocity-flat-anymal-d-link| replace:: `Isaac-Velocity-Flat-Anymal-D-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_d/flat_env_cfg.py>`__
+.. |velocity-rough-anymal-d-link| replace:: `Isaac-Velocity-Rough-Anymal-D-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/anymal_d/rough_env_cfg.py>`__
+
+.. |velocity-flat-unitree-a1-link| replace:: `Isaac-Velocity-Flat-Unitree-A1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/a1/flat_env_cfg.py>`__
+.. |velocity-rough-unitree-a1-link| replace:: `Isaac-Velocity-Rough-Unitree-A1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/a1/rough_env_cfg.py>`__
+
+.. |velocity-flat-unitree-go1-link| replace:: `Isaac-Velocity-Flat-Unitree-Go1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/go1/flat_env_cfg.py>`__
+.. |velocity-rough-unitree-go1-link| replace:: `Isaac-Velocity-Rough-Unitree-Go1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/go1/rough_env_cfg.py>`__
+
+.. |velocity-flat-unitree-go2-link| replace:: `Isaac-Velocity-Flat-Unitree-Go2-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/go2/flat_env_cfg.py>`__
+.. |velocity-rough-unitree-go2-link| replace:: `Isaac-Velocity-Rough-Unitree-Go2-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/go2/rough_env_cfg.py>`__
+
+.. |velocity-flat-spot-link| replace:: `Isaac-Velocity-Flat-Spot-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/spot/flat_env_cfg.py>`__
+
+.. |velocity-flat-h1-link| replace:: `Isaac-Velocity-Flat-H1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/h1/flat_env_cfg.py>`__
+.. |velocity-rough-h1-link| replace:: `Isaac-Velocity-Rough-H1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/h1/rough_env_cfg.py>`__
+
+.. |velocity-flat-g1-link| replace:: `Isaac-Velocity-Flat-G1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/g1/flat_env_cfg.py>`__
+.. |velocity-rough-g1-link| replace:: `Isaac-Velocity-Rough-G1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/g1/rough_env_cfg.py>`__
+
+.. |velocity-flat-digit-link| replace:: `Isaac-Velocity-Flat-Digit-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/digit/flat_env_cfg.py>`__
+.. |velocity-rough-digit-link| replace:: `Isaac-Velocity-Rough-Digit-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomotion/velocity/config/digit/rough_env_cfg.py>`__
+.. |tracking-loco-manip-digit-link| replace:: `Isaac-Tracking-LocoManip-Digit-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/locomanipulation/tracking/config/digit/loco_manip_env_cfg.py>`__
.. |velocity-flat-anymal-b| image:: ../_static/tasks/locomotion/anymal_b_flat.jpg
.. |velocity-rough-anymal-b| image:: ../_static/tasks/locomotion/anymal_b_rough.jpg
@@ -473,15 +506,15 @@ Navigation
~~~~~~~~~~
.. table::
- :widths: 33 37 30
+ :widths: 25 30 25 20
- +----------------+---------------------+-----------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +================+=====================+=============================================================================+
- | |anymal_c_nav| | |anymal_c_nav-link| | Navigate towards a target x-y position and heading with the ANYmal C robot. |
- +----------------+---------------------+-----------------------------------------------------------------------------+
+ +----------------+---------------------+-----------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +================+=====================+=============================================================================+=======================+
+ | |anymal_c_nav| | |anymal_c_nav-link| | Navigate towards a target x-y position and heading with the ANYmal C robot. | ``newton``, ``physx`` |
+ +----------------+---------------------+-----------------------------------------------------------------------------+-----------------------+
-.. |anymal_c_nav-link| replace:: `Isaac-Navigation-Flat-Anymal-C-v0 `__
+.. |anymal_c_nav-link| replace:: `Isaac-Navigation-Flat-Anymal-C-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/navigation/config/anymal_c/navigation_env_cfg.py>`__
.. |anymal_c_nav| image:: ../_static/tasks/navigation/anymal_c_nav.jpg
@@ -494,18 +527,18 @@ Multirotor
See the `drone_arl` folder and the ARL robot config
(`ARL_ROBOT_1_CFG`) in the codebase for details.
-.. |arl_robot_track_position_state_based-link| replace:: `Isaac-TrackPositionNoObstacles-ARL-Robot-1-v0 `__
+.. |arl_robot_track_position_state_based-link| replace:: `Isaac-TrackPositionNoObstacles-ARL-Robot-1-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/manager_based/drone_arl/track_position_state_based/config/arl_robot_1/track_position_state_based_env_cfg.py>`__
.. |arl_robot_track_position_state_based| image:: ../_static/tasks/drone_arl/arl_robot_1_track_position_state_based.jpg
.. table::
- :widths: 33 37 30
+ :widths: 25 30 25 20
- +----------------------------------------+---------------------------------------------+----------------------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +========================================+=============================================+========================================================================================+
- | |arl_robot_track_position_state_based| | |arl_robot_track_position_state_based-link| | Setpoint position control for the ARL robot using the track_position_state_based task. |
- +----------------------------------------+---------------------------------------------+----------------------------------------------------------------------------------------+
+ +----------------------------------------+---------------------------------------------+----------------------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +========================================+=============================================+========================================================================================+=======================+
+ | |arl_robot_track_position_state_based| | |arl_robot_track_position_state_based-link| | Setpoint position control for the ARL robot using the track_position_state_based task. | |
+ +----------------------------------------+---------------------------------------------+----------------------------------------------------------------------------------------+-----------------------+
Others
@@ -521,24 +554,24 @@ Others
For evaluation, the play script's command line input ``--real-time`` allows the interaction loop between the environment and the agent to run in real time, if possible.
.. table::
- :widths: 33 37 30
-
- +----------------+---------------------------+-----------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +================+===========================+=============================================================================+
- | |quadcopter| | |quadcopter-link| | Fly and hover the Crazyflie copter at a goal point by applying thrust. |
- +----------------+---------------------------+-----------------------------------------------------------------------------+
- | |humanoid_amp| | |humanoid_amp_dance-link| | Move a humanoid robot by imitating different pre-recorded human animations |
- | | | (Adversarial Motion Priors). |
- | | |humanoid_amp_run-link| | |
- | | | |
- | | |humanoid_amp_walk-link| | |
- +----------------+---------------------------+-----------------------------------------------------------------------------+
-
-.. |quadcopter-link| replace:: `Isaac-Quadcopter-Direct-v0 `__
-.. |humanoid_amp_dance-link| replace:: `Isaac-Humanoid-AMP-Dance-Direct-v0 `__
-.. |humanoid_amp_run-link| replace:: `Isaac-Humanoid-AMP-Run-Direct-v0 `__
-.. |humanoid_amp_walk-link| replace:: `Isaac-Humanoid-AMP-Walk-Direct-v0 `__
+ :widths: 25 30 25 20
+
+ +----------------+---------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +================+===========================+=============================================================================+=======================+
+ | |quadcopter| | |quadcopter-link| | Fly and hover the Crazyflie copter at a goal point by applying thrust. | |
+ +----------------+---------------------------+-----------------------------------------------------------------------------+-----------------------+
+ | |humanoid_amp| | |humanoid_amp_dance-link| | Move a humanoid robot by imitating different pre-recorded human animations | |
+ | | | (Adversarial Motion Priors). | |
+ | | |humanoid_amp_run-link| | | |
+ | | | | |
+ | | |humanoid_amp_walk-link| | | |
+ +----------------+---------------------------+-----------------------------------------------------------------------------+-----------------------+
+
+.. |quadcopter-link| replace:: `Isaac-Quadcopter-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/quadcopter/quadcopter_env.py>`__
+.. |humanoid_amp_dance-link| replace:: `Isaac-Humanoid-AMP-Dance-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/humanoid_amp/humanoid_amp_env_cfg.py>`__
+.. |humanoid_amp_run-link| replace:: `Isaac-Humanoid-AMP-Run-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/humanoid_amp/humanoid_amp_env_cfg.py>`__
+.. |humanoid_amp_walk-link| replace:: `Isaac-Humanoid-AMP-Walk-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/humanoid_amp/humanoid_amp_env_cfg.py>`__
.. |quadcopter| image:: ../_static/tasks/others/quadcopter.jpg
.. |humanoid_amp| image:: ../_static/tasks/others/humanoid_amp.jpg
@@ -673,17 +706,17 @@ Classic
~~~~~~~
.. table::
- :widths: 33 37 30
+ :widths: 25 30 25 20
- +------------------------+------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
- | World | Environment ID | Description |
- +========================+====================================+=======================================================================================================================+
- | |cart-double-pendulum| | |cart-double-pendulum-direct-link| | Move the cart and the pendulum to keep the last one upwards in the classic inverted double pendulum on a cart control |
- +------------------------+------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
+ +------------------------+------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +========================+====================================+=======================================================================================================================+=======================+
+ | |cart-double-pendulum| | |cart-double-pendulum-direct-link| | Move the cart and the pendulum to keep the last one upwards in the classic inverted double pendulum on a cart control | |
+ +------------------------+------------------------------------+-----------------------------------------------------------------------------------------------------------------------+-----------------------+
.. |cart-double-pendulum| image:: ../_static/tasks/classic/cart_double_pendulum.jpg
-.. |cart-double-pendulum-direct-link| replace:: `Isaac-Cart-Double-Pendulum-Direct-v0 `__
+.. |cart-double-pendulum-direct-link| replace:: `Isaac-Cart-Double-Pendulum-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/cart_double_pendulum/cart_double_pendulum_env.py>`__
Manipulation
~~~~~~~~~~~~
@@ -691,17 +724,17 @@ Manipulation
Environments based on fixed-arm manipulation tasks.
.. table::
- :widths: 33 37 30
+ :widths: 25 30 25 20
- +----------------------+--------------------------------+--------------------------------------------------------+
- | World | Environment ID | Description |
- +======================+================================+========================================================+
- | |shadow-hand-over| | |shadow-hand-over-direct-link| | Passing an object from one hand over to the other hand |
- +----------------------+--------------------------------+--------------------------------------------------------+
+ +----------------------+--------------------------------+--------------------------------------------------------+-----------------------+
+ | World | Environment ID | Description | Presets |
+ +======================+================================+========================================================+=======================+
+ | |shadow-hand-over| | |shadow-hand-over-direct-link| | Passing an object from one hand over to the other hand | |
+ +----------------------+--------------------------------+--------------------------------------------------------+-----------------------+
.. |shadow-hand-over| image:: ../_static/tasks/manipulation/shadow_hand_over.jpg
-.. |shadow-hand-over-direct-link| replace:: `Isaac-Shadow-Hand-Over-Direct-v0 `__
+.. |shadow-hand-over-direct-link| replace:: `Isaac-Shadow-Hand-Over-Direct-v0 <../../../source/isaaclab_tasks/isaaclab_tasks/direct/shadow_hand_over/shadow_hand_over_env.py>`__
|
@@ -713,486 +746,610 @@ provided when running ``play.py`` or any inferencing workflows. These tasks prov
inferencing, including reading from an already trained checkpoint and disabling runtime perturbations used for training.
.. list-table::
- :widths: 33 25 19 25
+ :widths: 28 20 13 22 17
* - **Task Name**
- **Inference Task Name**
- **Workflow**
- **RL Library**
+ - **Presets**
* - Isaac-Ant-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Ant-v0
-
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO), **skrl** (PPO), **sb3** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Cart-Double-Pendulum-Direct-v0
-
- Direct
- **rl_games** (PPO), **skrl** (IPPO, PPO, MAPPO)
+ -
* - Isaac-Cartpole-Camera-Showcase-Box-Box-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Box-Discrete-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Box-MultiDiscrete-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Dict-Box-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Dict-Discrete-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Dict-MultiDiscrete-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Tuple-Box-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Tuple-Discrete-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
* - Isaac-Cartpole-Camera-Showcase-Tuple-MultiDiscrete-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **skrl** (PPO)
- * - Isaac-Cartpole-Depth-Camera-Direct-v0 (Requires running with ``--enable_cameras``)
+ - ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``
+ * - Isaac-Cartpole-Camera-Presets-Direct-v0 (Requires running with ``--enable_cameras``)
-
- Direct
- **rl_games** (PPO), **skrl** (PPO)
- * - Isaac-Cartpole-Depth-v0 (Requires running with ``--enable_cameras``)
- -
- - Manager Based
- - **rl_games** (PPO)
+ - ``newton``, ``physx``, ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``, ``rgb``, ``depth``, ``albedo``, ``semantic_segmentation``, ``simple_shading_constant_diffuse``, ``simple_shading_diffuse_mdl``, ``simple_shading_full_mdl``
* - Isaac-Cartpole-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO), **sb3** (PPO)
- * - Isaac-Cartpole-RGB-Camera-Direct-v0 (Requires running with ``--enable_cameras``)
- -
- - Direct
- - **rl_games** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-RGB-ResNet18-v0 (Requires running with ``--enable_cameras``)
-
- Manager Based
- **rl_games** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Cartpole-RGB-TheiaTiny-v0 (Requires running with ``--enable_cameras``)
-
- Manager Based
- **rl_games** (PPO)
- * - Isaac-Cartpole-RGB-v0 (Requires running with ``--enable_cameras``)
- -
- - Manager Based
- - **rl_games** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Cartpole-Showcase-Box-Box-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Box-Discrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Box-MultiDiscrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Dict-Box-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Dict-Discrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Dict-MultiDiscrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Discrete-Box-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Discrete-Discrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Discrete-MultiDiscrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-MultiDiscrete-Box-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-MultiDiscrete-Discrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-MultiDiscrete-MultiDiscrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Tuple-Box-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Tuple-Discrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-Showcase-Tuple-MultiDiscrete-Direct-v0
-
- Direct
- **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Cartpole-v0
-
- Manager Based
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO), **sb3** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Factory-GearMesh-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-Factory-NutThread-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-Factory-PegInsert-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-AutoMate-Assembly-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-AutoMate-Disassembly-Direct-v0
-
- Direct
-
+ -
* - Isaac-Forge-GearMesh-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-Forge-NutThread-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-Forge-PegInsert-Direct-v0
-
- Direct
- **rl_games** (PPO)
+ -
* - Isaac-Franka-Cabinet-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ -
* - Isaac-Humanoid-AMP-Dance-Direct-v0
-
- Direct
- **skrl** (AMP)
+ -
* - Isaac-Humanoid-AMP-Run-Direct-v0
-
- Direct
- **skrl** (AMP)
+ -
* - Isaac-Humanoid-AMP-Walk-Direct-v0
-
- Direct
- **skrl** (AMP)
+ -
* - Isaac-Humanoid-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``, ``ovphysx``
* - Isaac-Humanoid-v0
-
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO), **skrl** (PPO), **sb3** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Lift-Cube-Franka-IK-Abs-v0
-
- Manager Based
-
+ -
* - Isaac-Lift-Cube-Franka-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Lift-Cube-Franka-v0
- Isaac-Lift-Cube-Franka-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO), **rl_games** (PPO), **sb3** (PPO)
+ -
* - Isaac-Lift-Teddy-Bear-Franka-IK-Abs-v0
-
- Manager Based
-
+ -
* - Isaac-Tracking-LocoManip-Digit-v0
- Isaac-Tracking-LocoManip-Digit-Play-v0
- Manager Based
- **rsl_rl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Navigation-Flat-Anymal-C-v0
- Isaac-Navigation-Flat-Anymal-C-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Open-Drawer-Franka-IK-Abs-v0
-
- Manager Based
-
+ -
* - Isaac-Open-Drawer-Franka-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Open-Drawer-Franka-v0
- Isaac-Open-Drawer-Franka-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Quadcopter-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ -
* - Isaac-Reach-Franka-IK-Abs-v0
-
- Manager Based
-
+ -
* - Isaac-Reach-Franka-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Reach-Franka-OSC-v0
- Isaac-Reach-Franka-OSC-Play-v0
- Manager Based
- **rsl_rl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Reach-Franka-v0
- Isaac-Reach-Franka-Play-v0
- Manager Based
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Reach-UR10-v0
- Isaac-Reach-UR10-Play-v0
- Manager Based
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Deploy-Reach-UR10e-v0
- Isaac-Deploy-Reach-UR10e-Play-v0
- Manager Based
- **rsl_rl** (PPO)
+ -
* - Isaac-Repose-Cube-Allegro-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Repose-Cube-Allegro-NoVelObs-v0
- Isaac-Repose-Cube-Allegro-NoVelObs-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO), **skrl** (PPO)
+ -
* - Isaac-Repose-Cube-Allegro-v0
- Isaac-Repose-Cube-Allegro-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO), **skrl** (PPO)
+ -
* - Isaac-Repose-Cube-Shadow-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Repose-Cube-Shadow-OpenAI-FF-Direct-v0
-
- Direct
- **rl_games** (FF), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Repose-Cube-Shadow-OpenAI-LSTM-Direct-v0
-
- Direct
- **rl_games** (LSTM)
+ - ``newton``, ``physx``
* - Isaac-Repose-Cube-Shadow-Vision-Direct-v0 (Requires running with ``--enable_cameras``)
- Isaac-Repose-Cube-Shadow-Vision-Direct-Play-v0 (Requires running with ``--enable_cameras``)
- Direct
- **rsl_rl** (PPO), **rl_games** (VISION)
+ - ``newton``, ``physx``, ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``, ``rgb``, ``depth``, ``albedo``, ``full``, ``semantic_segmentation``, ``simple_shading_constant_diffuse``, ``simple_shading_diffuse_mdl``, ``simple_shading_full_mdl``
* - Isaac-Shadow-Hand-Over-Direct-v0
-
- Direct
- **rl_games** (PPO), **skrl** (IPPO, PPO, MAPPO)
+ -
* - Isaac-Stack-Cube-Franka-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Dexsuite-Kuka-Allegro-Lift-v0
+
+ Camera variants (requires ``--enable_cameras``):
+
+ - single-camera: append ``presets=single_camera,isaacsim_rtx_renderer``
+ - dual-camera: append ``presets=duo_camera,isaacsim_rtx_renderer``
+
+ The same ``presets=`` flags must be passed to both the training and
+ play scripts. There is no separately registered
+ ``Isaac-Dexsuite-Kuka-Allegro-Lift-Single-Camera-v0`` environment;
+ all observation-mode variants share the base task name and are
+ selected via the preset system.
- Isaac-Dexsuite-Kuka-Allegro-Lift-Play-v0
- Manager Based
- **rl_games** (PPO), **rsl_rl** (PPO)
+ - ``newton``, ``physx``, ``single_camera``, ``duo_camera``, ``state``, ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``, ``rgb64``, ``rgb128``, ``rgb256``, ``depth64``, ``depth128``, ``depth256``, ``albedo64``, ``albedo128``, ``albedo256``, ``semantic_segmentation64``, ``semantic_segmentation128``, ``semantic_segmentation256``, ``simple_shading_constant_diffuse64``, ``simple_shading_constant_diffuse128``, ``simple_shading_constant_diffuse256``, ``simple_shading_diffuse_mdl64``, ``simple_shading_diffuse_mdl128``, ``simple_shading_diffuse_mdl256``, ``simple_shading_full_mdl64``, ``simple_shading_full_mdl128``, ``simple_shading_full_mdl256``
* - Isaac-Dexsuite-Kuka-Allegro-Reorient-v0
+
+ Camera variants (requires ``--enable_cameras``):
+
+ - single-camera: append ``presets=single_camera,isaacsim_rtx_renderer``
+ - dual-camera: append ``presets=duo_camera,isaacsim_rtx_renderer``
+
+ The same ``presets=`` flags must be passed to both the training and
+ play scripts.
- Isaac-Dexsuite-Kuka-Allegro-Reorient-Play-v0
- Manager Based
- **rl_games** (PPO), **rsl_rl** (PPO)
+ - ``newton``, ``physx``, ``single_camera``, ``duo_camera``, ``state``, ``newton_renderer``, ``ovrtx_renderer``, ``isaacsim_rtx_renderer``, ``rgb64``, ``rgb128``, ``rgb256``, ``depth64``, ``depth128``, ``depth256``, ``albedo64``, ``albedo128``, ``albedo256``, ``semantic_segmentation64``, ``semantic_segmentation128``, ``semantic_segmentation256``, ``simple_shading_constant_diffuse64``, ``simple_shading_constant_diffuse128``, ``simple_shading_constant_diffuse256``, ``simple_shading_diffuse_mdl64``, ``simple_shading_diffuse_mdl128``, ``simple_shading_diffuse_mdl256``, ``simple_shading_full_mdl64``, ``simple_shading_full_mdl128``, ``simple_shading_full_mdl256``
* - Isaac-Stack-Cube-Franka-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Instance-Randomize-Franka-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Instance-Randomize-Franka-v0
-
- Manager Based
-
+ -
* - Isaac-PickPlace-G1-InspireFTP-Abs-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-UR10-Long-Suction-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-UR10-Short-Suction-IK-Rel-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Galbot-Right-Arm-Suction-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-Visuomotor-v0
- Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-Visuomotor-Play-v0
- Manager Based
-
+ -
* - Isaac-Place-Mug-Agibot-Left-Arm-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Place-Toy2Box-Agibot-Right-Arm-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Galbot-Right-Arm-Suction-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-Visuomotor-v0
- Isaac-Stack-Cube-Galbot-Left-Arm-Gripper-Visuomotor-Play-v0
- Manager Based
-
+ -
* - Isaac-Place-Mug-Agibot-Left-Arm-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Place-Toy2Box-Agibot-Right-Arm-RmpFlow-v0
-
- Manager Based
-
+ -
* - Isaac-Velocity-Flat-Anymal-B-v0
- Isaac-Velocity-Flat-Anymal-B-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Anymal-C-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ -
* - Isaac-Velocity-Flat-Anymal-C-v0
- Isaac-Velocity-Flat-Anymal-C-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Anymal-D-v0
- Isaac-Velocity-Flat-Anymal-D-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Cassie-v0
- Isaac-Velocity-Flat-Cassie-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ -
* - Isaac-Velocity-Flat-Digit-v0
- Isaac-Velocity-Flat-Digit-Play-v0
- Manager Based
- **rsl_rl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-G1-v0
- Isaac-Velocity-Flat-G1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-H1-v0
- Isaac-Velocity-Flat-H1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Spot-v0
- Isaac-Velocity-Flat-Spot-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Unitree-A1-v0
- Isaac-Velocity-Flat-Unitree-A1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO), **sb3** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Unitree-Go1-v0
- Isaac-Velocity-Flat-Unitree-Go1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Flat-Unitree-Go2-v0
- Isaac-Velocity-Flat-Unitree-Go2-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Anymal-B-v0
- Isaac-Velocity-Rough-Anymal-B-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Anymal-C-Direct-v0
-
- Direct
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ -
* - Isaac-Velocity-Rough-Anymal-C-v0
- Isaac-Velocity-Rough-Anymal-C-Play-v0
- Manager Based
- **rl_games** (PPO), **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Anymal-D-v0
- Isaac-Velocity-Rough-Anymal-D-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Cassie-v0
- Isaac-Velocity-Rough-Cassie-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ -
* - Isaac-Velocity-Rough-Digit-v0
- Isaac-Velocity-Rough-Digit-Play-v0
- Manager Based
- **rsl_rl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-G1-v0
- Isaac-Velocity-Rough-G1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-H1-v0
- Isaac-Velocity-Rough-H1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Unitree-A1-v0
- Isaac-Velocity-Rough-Unitree-A1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO), **sb3** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Unitree-Go1-v0
- Isaac-Velocity-Rough-Unitree-Go1-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Velocity-Rough-Unitree-Go2-v0
- Isaac-Velocity-Rough-Unitree-Go2-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO)
+ - ``newton``, ``physx``
* - Isaac-Reach-OpenArm-Bi-v0
- Isaac-Reach-OpenArm-Bi-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO)
+ -
* - Isaac-Reach-OpenArm-v0
- Isaac-Reach-OpenArm-Play-v0
- Manager Based
- **rsl_rl** (PPO), **skrl** (PPO), **rl_games** (PPO)
+ -
* - Isaac-Lift-Cube-OpenArm-v0
- Isaac-Lift-Cube-OpenArm-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO)
+ -
* - Isaac-Open-Drawer-OpenArm-v0
- Isaac-Open-Drawer-OpenArm-Play-v0
- Manager Based
- **rsl_rl** (PPO), **rl_games** (PPO)
+ -
diff --git a/docs/source/overview/imitation-learning/augmented_imitation.rst b/docs/source/overview/imitation-learning/augmented_imitation.rst
index b3593f22e62..376f447f97a 100644
--- a/docs/source/overview/imitation-learning/augmented_imitation.rst
+++ b/docs/source/overview/imitation-learning/augmented_imitation.rst
@@ -373,8 +373,6 @@ Below is an explanation of the different settings used for evaluation:
- Maximum value of the action space normalization factor.
* - ``--disable_fabric``
- Whether to disable fabric and use USD I/O operations.
- * - ``--enable_pinocchio``
- - Whether to enable Pinocchio for IK controllers.
.. note::
The evaluation results will help you understand if the visual augmentation has improved the policy's performance and robustness. Compare these results with evaluations on the original dataset to measure the impact of augmentation.
diff --git a/docs/source/overview/imitation-learning/humanoids_imitation.rst b/docs/source/overview/imitation-learning/humanoids_imitation.rst
new file mode 100644
index 00000000000..d4782b14ab6
--- /dev/null
+++ b/docs/source/overview/imitation-learning/humanoids_imitation.rst
@@ -0,0 +1,777 @@
+.. _data-generation-imitation-learning-humanoids:
+
+Examples: Data Generation and Imitation Learning for Humanoids
+==============================================================
+
+This page covers data generation and imitation learning workflows for humanoid robots (GR-1, G1) with Isaac Lab Mimic:
+
+* **Demo 1:** Data generation and policy training for a humanoid robot (GR-1 pick and place)
+* **Demo 2:** Visuomotor policy for a humanoid robot (GR-1 nut pouring)
+* **Demo 3:** Data generation and policy training for humanoid robot locomanipulation (Unitree G1)
+
+.. important::
+
+ Complete the tutorial in :ref:`Teleoperation and Imitation Learning with Isaac Lab Mimic `
+ before proceeding with the following demonstrations to
+ understand the data collection, annotation, and generation steps of Isaac Lab Mimic.
+
+
+Demo 1: Data Generation and Policy Training for a Humanoid Robot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/gr-1_steering_wheel_pick_place.gif
+ :width: 100%
+ :align: center
+ :alt: GR-1 humanoid robot performing a pick and place task
+ :figclass: align-center
+
+
+Isaac Lab Mimic supports data generation for robots with multiple end effectors. In the following demonstration, we will show how to generate data
+to train a Fourier GR-1 humanoid robot to perform a pick and place task.
+
+Optional: Collect and annotate demonstrations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Collect human demonstrations
+""""""""""""""""""""""""""""
+.. note::
+
+ Data collection for the GR-1 humanoid robot environment requires use of an Apple Vision Pro headset. If you do not have access to
+ an Apple Vision Pro, you may skip this step and continue on to the next step: :ref:`Generate the dataset `.
+ A pre-recorded annotated dataset is provided in the next step.
+
+.. tip::
+ The GR1 scene utilizes the wrist poses from the Apple Vision Pro (AVP) as setpoints for a differential IK controller (Pink-IK).
+ The differential IK controller requires the user's wrist pose to be close to the robot's initial or current pose for optimal performance.
+ Rapid movements of the user's wrist may cause it to deviate significantly from the goal state, which could prevent the IK controller from finding the optimal solution.
+ This may result in a mismatch between the user's wrist and the robot's wrist.
+ You can increase the gain of all the `Pink-IK controller's FrameTasks `__ to track the AVP wrist poses with lower latency.
+ However, this may lead to more jerky motion.
+ Separately, the finger joints of the robot are retargeted to the user's finger joints using the `dex-retargeting `_ library.
+
+Set up the CloudXR Runtime and Apple Vision Pro for teleoperation by following the steps in :ref:`cloudxr-teleoperation`.
+CPU simulation is used in the following steps for better XR performance when running a single environment.
+
+Collect a set of human demonstrations.
+A success demo requires the object to be placed in the bin and for the robot's right arm to be retracted to the starting position.
+
+The Isaac Lab Mimic Env GR-1 humanoid robot is set up such that the left hand has a single subtask, while the right hand has two subtasks.
+The first subtask involves the right hand remaining idle while the left hand picks up and moves the object to the position where the right hand will grasp it.
+This setup allows Isaac Lab Mimic to interpolate the right hand's trajectory accurately by using the object's pose, especially when poses are randomized during data generation.
+Therefore, avoid moving the right hand while the left hand picks up the object and brings it to a stable position.
+
+
+.. |good_demo| image:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/gr-1_steering_wheel_pick_place_good_demo.gif
+ :width: 49%
+ :alt: GR-1 humanoid robot performing a good pick and place demonstration
+
+.. |bad_demo| image:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/gr-1_steering_wheel_pick_place_bad_demo.gif
+ :width: 49%
+ :alt: GR-1 humanoid robot performing a bad pick and place demonstration
+
+|good_demo| |bad_demo|
+
+.. centered:: Left: A good human demonstration with smooth and steady motion. Right: A bad demonstration with jerky and exaggerated motion.
+
+
+Collect five demonstrations by running the following command:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/tools/record_demos.py \
+ --task Isaac-PickPlace-GR1T2-Abs-v0 \
+ --visualizer kit \
+ --xr \
+ --device cpu \
+ --xr \
+ --num_demos 5 \
+ --dataset_file ./datasets/dataset_gr1.hdf5
+
+
+.. note::
+ We also provide a GR-1 pick and place task with waist degrees-of-freedom enabled ``Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0`` (see :ref:`environments` for details on the available environments, including the GR1 Waist Enabled variant). The same command above applies but with the task name changed to ``Isaac-PickPlace-GR1T2-WaistEnabled-Abs-v0``.
+
+.. tip::
+ If a demo fails during data collection, the environment can be reset using the teleoperation controls panel in the XR teleop client
+ on the Apple Vision Pro or via voice control by saying "reset". See :ref:`teleoperate-apple-vision-pro` for more details.
+
+ The robot uses simplified collision meshes for physics calculations that differ from the detailed visual meshes displayed in the simulation. Due to this difference, you may occasionally observe visual artifacts where parts of the robot appear to penetrate other objects or itself, even though proper collision handling is occurring in the physics simulation.
+
+You can replay the collected demonstrations by running the following command:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/tools/replay_demos.py \
+ --task Isaac-PickPlace-GR1T2-Abs-v0 \
+ --visualizer kit \
+ --device cpu \
+ --dataset_file ./datasets/dataset_gr1.hdf5
+
+.. note::
+ Non-determinism may be observed during replay as physics in IsaacLab are not determimnistically reproducible when using ``env.reset``.
+
+
+Annotate the demonstrations
+"""""""""""""""""""""""""""
+
+Unlike the :ref:`Franka stacking task `, the GR-1 pick and place task uses manual annotation to define subtasks.
+
+The pick and place task has one subtask for the left arm (pick) and two subtasks for the right arm (idle, place).
+Annotations denote the end of a subtask. For the pick and place task, this means there are no annotations for the left arm and one annotation for the right arm (the end of the final subtask is always implicit).
+
+Each demo requires a single annotation between the first and second subtask of the right arm. This annotation ("S" button press) should be done when the right robot arm finishes the "idle" subtask and begins to
+move towards the target object. An example of a correct annotation is shown below:
+
+.. figure:: ../../_static/tasks/manipulation/gr-1_pick_place_annotation.jpg
+ :width: 100%
+ :align: center
+
+Annotate the demonstrations by running the following command:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/annotate_demos.py \
+ --task Isaac-PickPlace-GR1T2-Abs-Mimic-v0 \
+ --visualizer kit \
+ --device cpu \
+ --input_file ./datasets/dataset_gr1.hdf5 \
+ --output_file ./datasets/dataset_annotated_gr1.hdf5
+
+.. note::
+
+ The script prints the keyboard commands for manual annotation and the current subtask being annotated:
+
+ .. code:: text
+
+ Annotating episode #0 (demo_0)
+ Playing the episode for subtask annotations for eef "right".
+ Subtask signals to annotate:
+ - Termination: ['idle_right']
+
+ Press "N" to begin.
+ Press "B" to pause.
+ Press "S" to annotate subtask signals.
+ Press "Q" to skip the episode.
+
+.. tip::
+
+ If the object does not get placed in the bin during annotation, you can press "N" to replay the episode and annotate again. Or you can press "Q" to skip the episode and annotate the next one.
+
+.. _generate-the-dataset:
+
+Generate the dataset
+^^^^^^^^^^^^^^^^^^^^
+
+If you skipped the prior collection and annotation step, download the pre-recorded annotated dataset ``dataset_annotated_gr1.hdf5`` from
+here: `[Annotated GR1 Dataset] `_.
+Place the file under ``IsaacLab/datasets`` and run the following command to generate a new dataset with 1000 demonstrations.
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/generate_dataset.py \
+ --device cpu \
+ --headless \
+ --num_envs 20 \
+ --generation_num_trials 1000 \
+ --input_file ./datasets/dataset_annotated_gr1.hdf5 \
+ --output_file ./datasets/generated_dataset_gr1.hdf5
+
+Train a policy
+^^^^^^^^^^^^^^
+
+Use `Robomimic `__ to train a policy for the generated dataset.
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/robomimic/train.py \
+ --task Isaac-PickPlace-GR1T2-Abs-v0 \
+ --algo bc \
+ --normalize_training_actions \
+ --dataset ./datasets/generated_dataset_gr1.hdf5
+
+The training script will normalize the actions in the dataset to the range [-1, 1].
+The normalization parameters are saved in the model directory under ``PATH_TO_MODEL_DIRECTORY/logs/normalization_params.txt``.
+Record the normalization parameters for later use in the visualization step.
+
+.. note::
+ By default the trained models and logs will be saved to ``IssacLab/logs/robomimic``.
+
+Visualize the results
+^^^^^^^^^^^^^^^^^^^^^
+
+Visualize the results of the trained policy by running the following command, using the normalization parameters recorded in the prior training step:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/robomimic/play.py \
+ --task Isaac-PickPlace-GR1T2-Abs-v0 \
+ --visualizer kit \
+ --device cpu \
+ --num_rollouts 50 \
+ --horizon 400 \
+ --norm_factor_min \
+ --norm_factor_max \
+ --checkpoint /PATH/TO/desired_model_checkpoint.pth
+
+.. note::
+ Change the ``NORM_FACTOR`` in the above command with the values generated in the training step.
+
+.. tip::
+
+ **If you don't see expected performance results:** It is critical to test policies from various checkpoint epochs.
+ Performance can vary significantly between epochs, and the best-performing checkpoint is often not the final one.
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/gr-1_steering_wheel_pick_place_policy.gif
+ :width: 100%
+ :align: center
+ :alt: GR-1 humanoid robot performing a pick and place task
+ :figclass: align-center
+
+ The trained policy performing the pick and place task in Isaac Lab.
+
+.. note::
+
+ **Expected Success Rates and Timings for Pick and Place GR1T2 Task**
+
+ * Success rate for data generation depends on the quality of human demonstrations (how well the user performs them) and dataset annotation quality. Both data generation and downstream policy success are sensitive to these factors and can show high variance. See :ref:`Common Pitfalls when Generating Data ` for tips to improve your dataset.
+ * Data generation success for this task is typically 65-80% over 1000 demonstrations, taking 18-40 minutes depending on GPU hardware and success rate (19 minutes on a RTX ADA 6000 @ 80% success rate).
+ * Behavior Cloning (BC) policy success is typically 75-86% (evaluated on 50 rollouts) when trained on 1000 generated demonstrations for 2000 epochs (default), depending on demonstration quality. Training takes approximately 29 minutes on a RTX ADA 6000.
+ * **Recommendation:** Train for 2000 epochs with 1000 generated demonstrations, and **evaluate multiple checkpoints saved between the 1000th and 2000th epochs** to select the best-performing policy. Testing various epochs is essential for finding optimal performance.
+
+
+Demo 2: Visuomotor Policy for a Humanoid Robot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/gr-1_nut_pouring_policy.gif
+ :width: 100%
+ :align: center
+ :alt: GR-1 humanoid robot performing a pouring task
+ :figclass: align-center
+
+Download the Dataset
+^^^^^^^^^^^^^^^^^^^^
+
+Download the pre-generated dataset from `here `__ and place it under ``IsaacLab/datasets/generated_dataset_gr1_nut_pouring.hdf5``
+(**Note: The dataset size is approximately 15GB**). The dataset contains 1000 demonstrations of a humanoid robot performing a pouring/placing task that was
+generated using Isaac Lab Mimic for the ``Isaac-NutPour-GR1T2-Pink-IK-Abs-Mimic-v0`` task.
+
+.. hint::
+
+ If desired, data collection, annotation, and generation can be done using the same commands as the prior examples.
+
+ The robot first picks up the red beaker and pours the contents into the yellow bowl.
+ Then, it drops the red beaker into the blue bin. Lastly, it places the yellow bowl onto the white scale.
+ See the video in the :ref:`visualize-results-demo-2` section below for a visual demonstration of the task.
+
+ **The success criteria for this task requires the red beaker to be placed in the blue bin, the green nut to be in the yellow bowl,
+ and the yellow bowl to be placed on top of the white scale.**
+
+ .. attention::
+ **The following commands are only for your reference and are not required for this demo.**
+
+ To collect demonstrations:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/tools/record_demos.py \
+ --task Isaac-NutPour-GR1T2-Pink-IK-Abs-v0 \
+ --visualizer kit \
+ --device cpu \
+ --xr \
+ --num_demos 5 \
+ --dataset_file ./datasets/dataset_gr1_nut_pouring.hdf5
+
+ To annotate the demonstrations:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/annotate_demos.py \
+ --task Isaac-NutPour-GR1T2-Pink-IK-Abs-Mimic-v0 \
+ --visualizer kit \
+ --enable_cameras \
+ --device cpu \
+ --input_file ./datasets/dataset_gr1_nut_pouring.hdf5 \
+ --output_file ./datasets/dataset_annotated_gr1_nut_pouring.hdf5
+
+ .. warning::
+ There are multiple right eef annotations for this task. Annotations for subtasks for the same eef cannot have the same action index.
+ Make sure to annotate the right eef subtasks with different action indices.
+
+
+ To generate the dataset:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/generate_dataset.py \
+ --task Isaac-NutPour-GR1T2-Pink-IK-Abs-Mimic-v0 \
+ --visualizer kit \
+ --enable_cameras \
+ --device cpu \
+ --headless \
+ --generation_num_trials 1000 \
+ --num_envs 5 \
+ --input_file ./datasets/dataset_annotated_gr1_nut_pouring.hdf5 \
+ --output_file ./datasets/generated_dataset_gr1_nut_pouring.hdf5
+
+
+Train a policy
+^^^^^^^^^^^^^^
+
+Use `Robomimic `__ to train a visuomotor BC agent for the task.
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/robomimic/train.py \
+ --task Isaac-NutPour-GR1T2-Pink-IK-Abs-v0 \
+ --algo bc \
+ --normalize_training_actions \
+ --dataset ./datasets/generated_dataset_gr1_nut_pouring.hdf5
+
+The training script will normalize the actions in the dataset to the range [-1, 1].
+The normalization parameters are saved in the model directory under ``PATH_TO_MODEL_DIRECTORY/logs/normalization_params.txt``.
+Record the normalization parameters for later use in the visualization step.
+
+.. note::
+ By default the trained models and logs will be saved to ``IsaacLab/logs/robomimic``.
+
+You can also post-train a `GR00T `__ foundation model to deploy a Vision-Language-Action policy for the task.
+
+Please refer to the `IsaacLabEvalTasks `__ repository for more details.
+
+.. _visualize-results-demo-2:
+
+Visualize the results
+^^^^^^^^^^^^^^^^^^^^^
+
+Visualize the results of the trained policy by running the following command, using the normalization parameters recorded in the prior training step:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/robomimic/play.py \
+ --task Isaac-NutPour-GR1T2-Pink-IK-Abs-v0 \
+ --visualizer kit \
+ --device cpu \
+ --enable_cameras \
+ --num_rollouts 50 \
+ --horizon 350 \
+ --norm_factor_min \
+ --norm_factor_max \
+ --checkpoint /PATH/TO/desired_model_checkpoint.pth
+
+.. note::
+ Change the ``NORM_FACTOR`` in the above command with the values generated in the training step.
+
+.. tip::
+
+ **If you don't see expected performance results:** Test policies from various checkpoint epochs, not just the final one.
+ Policy performance can vary substantially across training, and intermediate checkpoints often yield better results.
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/gr-1_nut_pouring_policy.gif
+ :width: 100%
+ :align: center
+ :alt: GR-1 humanoid robot performing a pouring task
+ :figclass: align-center
+
+ The trained visuomotor policy performing the pouring task in Isaac Lab.
+
+.. note::
+
+ **Expected Success Rates and Timings for Visuomotor Nut Pour GR1T2 Task**
+
+ * Success rate for data generation depends on the quality of human demonstrations (how well the user performs them) and dataset annotation quality. Both data generation and downstream policy success are sensitive to these factors and can show high variance. See :ref:`Common Pitfalls when Generating Data ` for tips to improve your dataset.
+ * Data generation for 1000 demonstrations takes approximately 10 hours on a RTX ADA 6000.
+ * Behavior Cloning (BC) policy success is typically 50-60% (evaluated on 50 rollouts) when trained on 1000 generated demonstrations for 600 epochs (default). Training takes approximately 15 hours on a RTX ADA 6000.
+ * **Recommendation:** Train for 600 epochs with 1000 generated demonstrations, and **evaluate multiple checkpoints saved between the 300th and 600th epochs** to select the best-performing policy. Testing various epochs is critical for achieving optimal performance.
+
+
+Demo 3: Data Generation and Policy Training for Humanoid Robot Locomanipulation with Unitree G1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In this demo, we showcase the integration of locomotion and manipulation capabilities within a single humanoid robot system.
+This locomanipulation environment enables data collection for complex tasks that combine navigation and object manipulation.
+The demonstration follows a multi-step process: first, it generates pick and place tasks similar to Demo 1, then introduces
+a navigation component that uses specialized scripts to generate scenes where the humanoid robot must move from point A to point B.
+The robot picks up an object at the initial location (point A) and places it at the target destination (point B).
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/locomanipulation-g-1_steering_wheel_pick_place.gif
+ :width: 100%
+ :align: center
+ :alt: G1 humanoid robot with locomanipulation performing a pick and place task
+ :figclass: align-center
+
+.. note::
+ **Locomotion policy training**
+
+ The locomotion policy used in this integration example was trained using the `AGILE `__ framework.
+ AGILE is an officially supported humanoid control training pipeline that leverages the manager based environment in Isaac Lab. It will also be
+ seamlessly integrated with other evaluation and deployment tools across Isaac products. This allows teams to rely on a single, maintained stack
+ covering all necessary infrastructure and tooling for policy training, with easy export to real-world deployment. The AGILE repository contains
+ updated pre-trained policies with separate upper and lower body policies for flexibtility. They have been verified in the real world and can be
+ directly deployed. Users can also train their own locomotion or whole-body control policies using the AGILE framework.
+
+.. _generate-the-manipulation-dataset:
+
+Generate the manipulation dataset
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The same data generation and policy training steps from Demo 1 can be applied to the G1 humanoid robot with locomanipulation capabilities.
+This demonstration shows how to train a G1 robot to perform pick and place tasks with full-body locomotion and manipulation.
+
+The process follows the same workflow as Demo 1, but uses the ``Isaac-PickPlace-Locomanipulation-G1-Abs-v0`` task environment.
+
+Follow the same data collection, annotation, and generation process as demonstrated in Demo 1, but adapted for the G1 locomanipulation task.
+
+.. hint::
+
+ If desired, data collection and annotation can be done using the same commands as the prior examples for validation of the dataset.
+
+ The G1 robot with locomanipulation capabilities combines full-body locomotion with manipulation to perform pick and place tasks.
+
+ **Note that the following commands are only for your reference and dataset validation purposes - they are not required for this demo.**
+
+ To collect demonstrations:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/tools/record_demos.py \
+ --device cpu \
+ --xr \
+ --visualizer kit \
+ --task Isaac-PickPlace-Locomanipulation-G1-Abs-v0 \
+ --dataset_file ./datasets/dataset_g1_locomanip.hdf5 \
+ --num_demos 5
+
+ .. note::
+
+ Depending on how the Apple Vision Pro app was initialized, the hands of the operator might be very far up or far down compared to the hands of the G1 robot. If this is the case, you can click **Stop AR** in the AR tab in Isaac Lab, and move the AR Anchor prim. Adjust it down to bring the hands of the operator lower, and up to bring them higher. Click **Start AR** to resume teleoperation session. Make sure to match the hands of the robot before clicking **Play** in the Apple Vision Pro, otherwise there will be an undesired large force generated initially.
+
+ You can replay the collected demonstrations by running:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/tools/replay_demos.py \
+ --device cpu \
+ --visualizer kit \
+ --task Isaac-PickPlace-Locomanipulation-G1-Abs-v0 \
+ --dataset_file ./datasets/dataset_g1_locomanip.hdf5
+
+ To annotate the demonstrations:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/annotate_demos.py \
+ --device cpu \
+ --visualizer kit \
+ --task Isaac-Locomanipulation-G1-Abs-Mimic-v0 \
+ --input_file ./datasets/dataset_g1_locomanip.hdf5 \
+ --output_file ./datasets/dataset_annotated_g1_locomanip.hdf5
+
+
+If you skipped the prior collection and annotation step, download the pre-recorded annotated dataset ``dataset_annotated_g1_locomanip.hdf5`` from
+here: `[Annotated G1 Dataset] `_.
+Place the file under ``IsaacLab/datasets`` and run the following command to generate a new dataset with 1000 demonstrations.
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/isaaclab_mimic/generate_dataset.py \
+ --device cpu --headless --num_envs 20 --generation_num_trials 1000 \
+ --input_file ./datasets/dataset_annotated_g1_locomanip.hdf5 --output_file ./datasets/generated_dataset_g1_locomanip.hdf5
+
+
+Train a manipulation-only policy
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+At this point you can train a policy that only performs manipulation tasks using the generated dataset:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/robomimic/train.py \
+ --task Isaac-PickPlace-Locomanipulation-G1-Abs-v0 --algo bc \
+ --normalize_training_actions \
+ --dataset ./datasets/generated_dataset_g1_locomanip.hdf5
+
+Visualize the results
+^^^^^^^^^^^^^^^^^^^^^
+
+Visualize the trained policy performance:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/robomimic/play.py \
+ --device cpu \
+ --visualizer kit \
+ --task Isaac-PickPlace-Locomanipulation-G1-Abs-v0 \
+ --num_rollouts 50 \
+ --horizon 400 \
+ --norm_factor_min \
+ --norm_factor_max \
+ --checkpoint /PATH/TO/desired_model_checkpoint.pth
+
+.. note::
+ Change the ``NORM_FACTOR`` in the above command with the values generated in the training step.
+
+.. tip::
+
+ **If you don't see expected performance results:** Always test policies from various checkpoint epochs.
+ Different epochs can produce significantly different results, so evaluate multiple checkpoints to find the optimal model.
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/locomanipulation-g-1_steering_wheel_pick_place.gif
+ :width: 100%
+ :align: center
+ :alt: G1 humanoid robot performing a pick and place task
+ :figclass: align-center
+
+ The trained policy performing the pick and place task in Isaac Lab.
+
+.. note::
+
+ **Expected Success Rates and Timings for Locomanipulation Pick and Place Task**
+
+ * Success rate for data generation depends on the quality of human demonstrations (how well the user performs them) and dataset annotation quality. Both data generation and downstream policy success are sensitive to these factors and can show high variance. See :ref:`Common Pitfalls when Generating Data ` for tips to improve your dataset.
+ * Data generation success for this task is typically 65-82% over 1000 demonstrations, taking 18-40 minutes depending on GPU hardware and success rate (18 minutes on a RTX ADA 6000 @ 82% success rate).
+ * Behavior Cloning (BC) policy success is typically 75-85% (evaluated on 50 rollouts) when trained on 1000 generated demonstrations for 2000 epochs (default), depending on demonstration quality. Training takes approximately 40 minutes on a RTX ADA 6000.
+ * **Recommendation:** Train for 2000 epochs with 1000 generated demonstrations, and **evaluate multiple checkpoints saved between the 1000th and 2000th epochs** to select the best-performing policy. Testing various epochs is essential for finding optimal performance.
+
+Generate the dataset with manipulation and point-to-point navigation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To create a comprehensive locomanipulation dataset that combines both manipulation and navigation capabilities, you can generate a navigation dataset using the manipulation dataset from the previous step as input.
+
+.. list-table::
+ :widths: 50 50
+ :header-rows: 0
+
+ * - .. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/g1_locomanip_no_obstacles.gif
+ :height: 260px
+ :align: center
+ :alt: G1 locomanipulation data generation without obstacles
+
+ Default: no obstacles (open scene).
+ - .. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/g1_locomanip_with_obstacles.gif
+ :height: 260px
+ :align: center
+ :alt: G1 locomanipulation data generation with forklift obstacles
+
+ With 8 forklift obstacles and ``--randomize_placement`` enabled.
+
+The locomanipulation dataset generation process takes the previously generated manipulation dataset and creates scenarios where the robot must navigate from one location to another while performing manipulation tasks. This creates a more complex dataset that includes both locomotion and manipulation behaviors.
+
+To generate the locomanipulation dataset, use the following command:
+
+.. code:: bash
+
+ ./isaaclab.sh -p \
+ scripts/imitation_learning/locomanipulation_sdg/generate_data.py \
+ --device cpu \
+ --kit_args="--enable isaacsim.replicator.mobility_gen" \
+ --task="Isaac-G1-SteeringWheel-Locomanipulation" \
+ --dataset ./datasets/generated_dataset_g1_locomanip.hdf5 \
+ --num_runs 1 \
+ --lift_step 60 \
+ --navigate_step 130 \
+ --output_file ./datasets/generated_dataset_g1_locomanipulation_sdg.hdf5 \
+ --enable_cameras \
+ --randomize_placement \
+ --visualizer kit
+
+.. note::
+
+ The input dataset (``--dataset``) should be the manipulation dataset generated in the previous step. You can specify any output filename using the ``--output_file_name`` parameter.
+
+The key parameters for locomanipulation dataset generation are:
+
+* ``--lift_step 60``: Number of steps for the lifting phase of the manipulation task. This should mark the point immediately after the robot has grasped the object.
+* ``--navigate_step 130``: Number of steps for the navigation phase between locations. This should make the point where the robot has lifted the object and is ready to walk.
+* ``--output_file``: Name of the output dataset file
+
+.. note::
+
+ You can change the number of obstacles (forklifts and boxes) in the scene by editing the locomanipulation SDG environment configuration. In ``source/isaaclab_mimic/isaaclab_mimic/locomanipulation_sdg/envs/g1_locomanipulation_sdg_env.py``, set the module-level constants ``NUM_FORKLIFTS`` and ``NUM_BOXES`` to the desired counts. Use ``--randomize_placement`` when running :file:`generate_data.py` to randomize obstacle and fixture positions each run.
+
+This process creates a dataset where the robot performs the manipulation task at different locations, requiring it to navigate between points while maintaining the learned manipulation behaviors. The resulting dataset can be used to train policies that combine both locomotion and manipulation capabilities.
+
+.. note::
+
+ You can visualize the robot trajectory results with the following script command:
+
+ .. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/locomanipulation_sdg/plot_navigation_trajectory.py --input_file datasets/generated_dataset_g1_locomanipulation_sdg.hdf5 --output_dir /PATH/TO/DESIRED_OUTPUT_DIR
+
+The data generated from this locomanipulation pipeline can also be used to finetune an imitation learning policy using GR00T N1.5.
+The following steps describe how to install GR00T, convert the dataset to LeRobot format, finetune the policy, and run rollouts in Isaac Lab.
+
+Finetune GR00T N1.5 policy for locomanipulation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**Prerequisites:** Generate the locomanipulation dataset using the command in the previous section (e.g. ``generated_dataset_g1_locomanipulation_sdg.hdf5``).
+You may place one or more such HDF5 files in a single directory for the conversion step.
+
+Install GR00T with Isaac Lab (uv)
+"""""""""""""""""""""""""""""""""
+
+Clone the Isaac-GR00T repository and install GR00T N1.5 in the same uv environment used for Isaac Lab. From a parent directory that contains both repositories (or adjust paths accordingly), run:
+
+.. code:: bash
+
+ git clone -b n1.5-release https://github.com/NVIDIA/Isaac-GR00T
+
+Copy the G1 locomanipulation data config from Isaac Lab into the GR00T experiment data config:
+
+.. code:: bash
+
+ cp IsaacLab/scripts/imitation_learning/locomanipulation_sdg/gr00t/data_config.py Isaac-GR00T/gr00t/experiment/data_config.py
+
+Then, from the **Isaac-GR00T** directory, install GR00T N1.5 and its dependencies:
+
+.. code:: bash
+
+ cd Isaac-GR00T
+ uv pip install -e .
+ uv pip install wheel
+ MAX_JOBS=4 uv pip install --no-build-isolation flash-attn==2.7.1.post4
+ MAX_JOBS=4 uv pip install --no-build-isolation pytorch3d
+ uv pip install diffusers decord zmq
+
+Convert dataset to LeRobot format
+"""""""""""""""""""""""""""""""""
+
+GR00T N1.5 expects data in LeRobot format. From the **IsaacLab** repository root, run the conversion script. ```` is a directory containing one or more ``.hdf5`` files (e.g. the output directory where you saved files from ``generate_data.py``). ```` is the LeRobot-format output directory (e.g. ``./datasets/datasets_train_200_lerobot``). Episodes with very low object displacement are skipped.
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/locomanipulation_sdg/gr00t/convert_dataset.py
+
+Example:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/locomanipulation_sdg/gr00t/convert_dataset.py ./datasets ./datasets/datasets_train_200_lerobot
+
+Finetune the policy
+"""""""""""""""""""
+
+Run finetuning from the **Isaac-GR00T** repository root. Use the LeRobot-format output path from the previous step as ``--dataset-path`` and choose an ``--output-dir`` for checkpoints. The ``--data-config g1_locomanipulation_sdg`` and ``--embodiment-tag new_embodiment`` options are required for the G1 locomanipulation task.
+
+.. code:: bash
+
+ cd Isaac-GR00T
+ python scripts/gr00t_finetune.py \
+ --dataset-path \
+ --output-dir \
+ --data-config g1_locomanipulation_sdg \
+ --embodiment-tag new_embodiment \
+ --num-gpus 1 \
+ --max-steps 10000 \
+ --save-steps 1000 \
+ --video-backend decord \
+ --report-to tensorboard
+
+See the GR00T N1.5 repository documentation for additional training options.
+
+Rollout the policy in Isaac Lab
+"""""""""""""""""""""""""""""""
+
+From the **IsaacLab** repository root, run the rollout script with the path to your finetuned checkpoint, the static manipulation dataset (used for scene/demo setup), and the task name:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/locomanipulation_sdg/gr00t/rollout_policy.py \
+ --model_path \
+ --embodiment_tag new_embodiment \
+ --dataset ./datasets/generated_dataset_g1_locomanip.hdf5 \
+ --demo demo_0 \
+ --output_file ./datasets/rollout_output.hdf5 \
+ --task Isaac-G1-SteeringWheel-Locomanipulation \
+ --device cpu \
+ --enable_cameras \
+ --visualizer kit
+
+Optional arguments include ``--randomize_placement`` and ``--policy_quat_format wxyz`` (use if your checkpoint was trained with wxyz quaternion format).
+
+.. figure:: https://download.isaacsim.omniverse.nvidia.com/isaaclab/images/locomanipulation_sdg_disjoint_nav_groot_policy_4x.gif
+ :width: 100%
+ :align: center
+ :alt: Simulation rollout of GR00T N1.5 policy finetuned for locomanipulation
+ :figclass: align-center
+
+ Simulation rollout of GR00T N1.5 policy finetuned for locomanipulation.
+
+The policy shown above uses the camera image, hand poses, hand joint positions, object pose, and base goal pose as inputs.
+The output of the model is the target base velocity, hand poses, and hand joint positions for the next several timesteps.
+
+Use NuRec Background in Locomanipulation SDG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+**Prerequisites:** Generate a manipulation dataset or download a pre-recorded annotated dataset from :ref:`Generate the manipulation dataset `.
+
+The `NuRec assets `__
+are neural volumes reconstructed from real-world captures. When integrated into the locomanipulation SDG workflow, these
+assets allow you to generate synthetic data in photorealistic environments that mirror real-world.
+
+Custom NuRec Asset Requirements
+"""""""""""""""""""""""""""""""
+
+To load a custom USD asset, ensure it meets the following specifications:
+
+- Neural Rendering: Include neural reconstruction for rendering.
+- Navigation: Include a pre-computed occupancy map for path planning and navigation. You can use the `Occupancy Map Generator `_ to generate the occupancy map.
+- Orientation: Transform the asset so that the ground aligns with the z=0 plane.
+- Collision Mesh (optional): If a collision mesh is included, set it to invisible.
+
+Using Pre-constructed Assets
+""""""""""""""""""""""""""""
+
+Pre-constructed assets are available via the `PhysicalAI Robotics NuRec `__
+dataset. Some of them are captured from a humanoid-viewpoint to match the camera view of the humanoid robot.
+
+For example, when using the asset ``hand_hold-voyager-babyboom``, the relevant files are:
+
+- `stage.usdz `__: a USDZ archive that bundles 3D Gaussian splatting (``volume.nurec``), a collision mesh (``mesh.usd``), etc.
+- `occupancy_map.yaml `__ and `occupancy_map.png `__: occupancy map for path planning and navigation.
+
+Download the files and place them under ````, then run the following command to generate a new dataset with background:
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/imitation_learning/locomanipulation_sdg/generate_data.py \
+ --device cpu \
+ --kit_args="--enable isaacsim.replicator.mobility_gen" \
+ --task="Isaac-G1-SteeringWheel-Locomanipulation" \
+ --dataset /dataset_annotated_g1_locomanip.hdf5 \
+ --num_runs 1 \
+ --lift_step 60 \
+ --navigate_step 130 \
+ --output_file /generated_dataset_g1_locomanipulation_sdg_with_background.hdf5 \
+ --enable_cameras \
+ --visualizer kit \
+ --background_usd_path /stage.usdz \
+ --background_occupancy_yaml_file /occupancy_map.yaml \
+ --randomize_placement \
+ --high_res_video
+
+The key parameters are:
+
+- ``--background_usd_path``: Path to the NuRec USD asset.
+- ``--background_occupancy_yaml_file``: Path to the occupancy map file.
+- ``--high_res_video``: Generate a higher resolution video (540x960) for the ego-centric camera view.
+- ``--sensor_camera_view``: Optionally set the Sim GUI viewport to the ``robot_pov_cam`` sensor view.
+
+On successful task completion, an HDF5 dataset is generated containing camera observations. You can convert
+the ego-centric camera view to MP4.
+
+.. code:: bash
+
+ ./isaaclab.sh -p scripts/tools/hdf5_to_mp4.py \
+ --input_file /generated_dataset_g1_locomanipulation_sdg_with_background.hdf5 \
+ --output_dir / \
+ --input_keys robot_pov_cam \
+ --video_width 960 \
+ --video_height 540
+
+To play the generated MP4 video on Ubuntu, install the following multimedia packages:
+
+.. code:: bash
+
+ sudo apt update
+ sudo apt install libavcodec-extra gstreamer1.0-libav gstreamer1.0-plugins-ugly
diff --git a/docs/source/overview/imitation-learning/index.rst b/docs/source/overview/imitation-learning/index.rst
index f8f77d031fb..769b259185f 100644
--- a/docs/source/overview/imitation-learning/index.rst
+++ b/docs/source/overview/imitation-learning/index.rst
@@ -8,5 +8,6 @@ with Isaac Lab.
:maxdepth: 1
teleop_imitation
+ humanoids_imitation
augmented_imitation
skillgen
diff --git a/docs/source/overview/imitation-learning/skillgen.rst b/docs/source/overview/imitation-learning/skillgen.rst
index b577f82e13a..be8382b5c5e 100644
--- a/docs/source/overview/imitation-learning/skillgen.rst
+++ b/docs/source/overview/imitation-learning/skillgen.rst
@@ -135,7 +135,7 @@ The dataset contains:
Download and Setup
^^^^^^^^^^^^^^^^^^
-1. Download the pre-annotated dataset by clicking `here `__.
+1. Download the pre-annotated dataset by clicking `here `__.
2. Prepare the datasets directory and move the downloaded file:
@@ -173,7 +173,8 @@ Download and Setup
--task Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0 \
--teleop_device spacemouse \
--dataset_file ./datasets/dataset_skillgen.hdf5 \
- --num_demos 10
+ --num_demos 10 \
+ --visualizer kit
**Annotate demonstrations for SkillGen** (writes both term and start boundaries):
@@ -184,7 +185,8 @@ Download and Setup
--task Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0 \
--input_file ./datasets/dataset_skillgen.hdf5 \
--output_file ./datasets/annotated_dataset_skillgen.hdf5 \
- --annotate_subtask_start_signals
+ --annotate_subtask_start_signals \
+ --visualizer kit
Understanding Dataset Annotation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -283,7 +285,7 @@ Start with a small dataset to verify everything works:
--input_file ./datasets/annotated_dataset_skillgen.hdf5 \
--output_file ./datasets/generated_dataset_small_skillgen_cube_stack.hdf5 \
--task Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0 \
- --use_skillgen
+ --use_skillgen --visualizer kit
Full-Scale Generation
^^^^^^^^^^^^^^^^^^^^^
@@ -337,7 +339,7 @@ Test the adaptive stacking setup:
--input_file ./datasets/annotated_dataset_skillgen.hdf5 \
--output_file ./datasets/generated_dataset_small_skillgen_bin_cube_stack.hdf5 \
--task Isaac-Stack-Cube-Bin-Franka-IK-Rel-Mimic-v0 \
- --use_skillgen
+ --use_skillgen --visualizer kit
Full-Scale Generation
^^^^^^^^^^^^^^^^^^^^^
@@ -419,7 +421,8 @@ Test your trained policies:
--device cpu \
--task Isaac-Stack-Cube-Franka-IK-Rel-Skillgen-v0 \
--num_rollouts 50 \
- --checkpoint /path/to/model_checkpoint.pth
+ --checkpoint /path/to/model_checkpoint.pth \
+ --visualizer kit
.. code:: bash
@@ -428,7 +431,8 @@ Test your trained policies:
--device cpu \
--task Isaac-Stack-Cube-Bin-Franka-IK-Rel-Mimic-v0 \
--num_rollouts 50 \
- --checkpoint /path/to/model_checkpoint.pth
+ --checkpoint /path/to/model_checkpoint.pth \
+ --visualizer kit
.. note::
diff --git a/docs/source/overview/imitation-learning/teleop_imitation.rst b/docs/source/overview/imitation-learning/teleop_imitation.rst
index 14017e65b5d..2511b6a57b7 100644
--- a/docs/source/overview/imitation-learning/teleop_imitation.rst
+++ b/docs/source/overview/imitation-learning/teleop_imitation.rst
@@ -47,21 +47,20 @@ For smoother operation and off-axis operation, we recommend using a SpaceMouse a
where ``<#>`` is the device index of the connected SpaceMouse.
- If you are using the IsaacLab + CloudXR container deployment (:ref:`cloudxr-teleoperation`), you can add the ``devices`` attribute under the ``services -> isaac-lab-base`` section of the
- ``docker/docker-compose.cloudxr-runtime.patch.yaml`` file.
-
Isaac Lab is only compatible with the SpaceMouse Wireless and SpaceMouse Compact models from 3Dconnexion.
-For tasks that benefit from the use of an extended reality (XR) device with hand tracking, Isaac Lab supports using NVIDIA CloudXR to immersively stream the scene to compatible XR devices for teleoperation. Note that when using hand tracking we recommend using the absolute variant of the task (``Isaac-Stack-Cube-Franka-IK-Abs-v0``), which requires the ``handtracking`` device:
+For tasks that benefit from the use of an extended reality (XR) device with hand tracking, Isaac Lab supports using `Isaac Teleop `_ with NVIDIA CloudXR to immersively stream the scene to compatible XR devices for teleoperation. Note that when using hand tracking we recommend using the absolute variant of the task (``Isaac-Stack-Cube-Franka-IK-Abs-v0``):
.. code:: bash
- ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py --task Isaac-Stack-Cube-Franka-IK-Abs-v0 --teleop_device handtracking --device cpu
+ ./isaaclab.sh -p scripts/environments/teleoperation/teleop_se3_agent.py --task Isaac-Stack-Cube-Franka-IK-Abs-v0 --visualizer kit --xr
.. note::
- See :ref:`cloudxr-teleoperation` to learn how to use CloudXR and experience teleoperation with Isaac Lab.
+ See :ref:`cloudxr-teleoperation` to learn how to install Isaac Teleop and set up CloudXR for
+ teleoperation. For architecture details, retargeting pipelines, and control scheme
+ recommendations, see :ref:`isaac-teleop-feature`.
The script prints the teleoperation events configured. For keyboard,
@@ -96,8 +95,50 @@ The next section describes how teleoperation devices can be used for data collec
Imitation Learning with Isaac Lab Mimic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Using the teleoperation devices, it is also possible to collect data for
-learning from demonstrations (LfD). For this, we provide scripts to collect data into the open HDF5 format.
+.. figure:: ../../_static/mimic/franka_mimic_imitation_learning.jpg
+ :width: 100%
+ :align: center
+ :alt: Franka robot performing a stacking task
+ :figclass: align-center
+
+What is Isaac Lab Mimic?
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Isaac Lab Mimic (Mimic) is a trajectory data generation tool that can be used to
+augment human demonstrations by generating new synthetic data. Given a set of human demonstrations,
+Mimic can automatically generate new demonstrations involving the same task but with different spatial configurations.
+The generated data can be used to train imitation learning policies that are more robust to spatial variations
+even if just a handful of manual demonstrations are available.
+
+Mimic works by taking a set of human demonstrations and splitting each demonstration into a sequence of subtasks.
+Subtasks are defined based on reference objects that dictate the motion of the robot's end-effectors (eefs). Each subtask
+is a contiguous segment of the demonstration where the eef's motion is dictated by a single reference object. A new subtask begins
+when the reference object changes. Annotations mark points in the demonstration where a subtask is completed.
+
+During data generation, Mimic takes the human demonstration subtask segments and applies rigid body transformations to the robot's actions
+to transform them into new demonstrations involving the same task but with different spatial configurations.
+The new demonstrations are evaluated to determine if they are successful, and if so, are added to the output dataset.
+
+Mimic is compatible with a variety of embodiments including single-eef (e.g. manipulator robots) and multi-eef (e.g. humanoid robots).
+The use of rigid body transformations requires that the embodiment's action space is defined in **task space**. If
+the embodiment's action is in joint space, then the action must be converted to task space using forward kinematics.
+
+In the following section, we will show how to collect a small batch of human demonstrations for a stacking task
+with the Franka robot and then increase the size of the dataset by generating new synthetic data using Isaac Lab Mimic.
+
+
+Pre-recorded demonstrations
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We provide a pre-recorded ``dataset.hdf5`` containing 10 human demonstrations for ``Isaac-Stack-Cube-Franka-IK-Rel-v0``
+here: `[Franka Dataset] `__.
+This dataset may be downloaded and used in the remaining tutorial steps if you do not wish to collect your own demonstrations.
+
+If using the pre-recorded dataset, skip the next section and proceed directly to the :ref:`Generating additional demonstrations ` section.
+
+.. note::
+ Use of the pre-recorded dataset is optional.
+
Collecting demonstrations
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,24 +147,18 @@ To collect demonstrations with teleoperation for the environment ``Isaac-Stack-C
.. code:: bash
- # step a: create folder for datasets
+ #Create folder for datasets
mkdir -p datasets
- # step b: collect data with a selected teleoperation device. Replace