Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3c485d9
Fix depth-only cameras blacking out GUI viewport (#6304)
ooctipus Jul 2, 2026
30a394e
Consolidate OVRTX tile-extraction kernels (#6331)
rilei-nvidia Jul 3, 2026
0ede6da
[CI][Auto Version Bump] Compile changelog fragments (schedule)
isaaclab-bot[bot] Jul 3, 2026
861d343
[Kamino] Core (#5962)
aserifi Jul 3, 2026
21ba048
[IsaacLab 3.0.0 Multi-Backend] Visual Logging for Headless Runs (#6212)
mataylor-nvidia Jul 3, 2026
1a9971e
[IsaacLab CI] Smoke test marker (#6347)
mataylor-nvidia Jul 4, 2026
1425417
Adding Rigid Body Material USD data classes and writers (#6287)
vidurv-nvidia Jul 4, 2026
e211621
[CI][Auto Version Bump] Compile changelog fragments (schedule)
isaaclab-bot[bot] Jul 4, 2026
17136c6
Fix contact sensor activation for nested rigid bodies (#6259)
ooctipus Jul 4, 2026
186f152
[CI][Auto Version Bump] Compile changelog fragments (schedule)
isaaclab-bot[bot] Jul 5, 2026
5aafdb5
Added 'motion_vectors' data type support to OVRTX renderer integratio…
rilei-nvidia Jul 6, 2026
1ca4a60
Raise instead of swallowing OVRTXRenderer failures (#6321)
rilei-nvidia Jul 6, 2026
b2dd3cc
[CI][Auto Version Bump] Compile changelog fragments (schedule)
isaaclab-bot[bot] Jul 6, 2026
f3c0008
Run OV test jobs on fork PRs without the OVPhysX wheelhouse (#6348)
ooctipus Jul 6, 2026
b8ed8a9
Add backend-agnostic benchmark core (benchmark refactor, Part 1/5) (#…
AntoineRichard Jul 6, 2026
029fcb4
Fix OVPhysX runtime pin (#6333)
AntoineRichard Jul 6, 2026
447d8c5
[Kamino] Small Cleanup (#6359)
aserifi Jul 6, 2026
6216fe7
Fix pre-launch runtime imports (#6275)
AntoineRichard Jul 6, 2026
5f2db99
[Kamino] fourbar-pole swingup task (#6327)
rubengrandia Jul 6, 2026
c67c681
[CI][Auto Version Bump] Compile changelog fragments (schedule)
isaaclab-bot[bot] Jul 7, 2026
569fcaa
Articulation Reordering Part 1/8: Extract rigid object interface test…
AntoineRichard Jul 7, 2026
63c4bff
fix(deps): bump usd-core to >=26.5 for multithreaded collider crash fix
pv-nvidia Jun 30, 2026
e6040a2
fix(newton): rebuild collision pipeline on hard reset to fix CUDA 700
Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/actions/run-package-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ inputs:
skipped. Combines with filter-pattern (include + exclude).
default: ''
required: false
test-k-expr:
description: >-
Global pytest -k expression applied inside every per-file pytest run
spawned by tools/conftest.py (combined with device-split selectors).
default: ''
required: false
shard-index:
description: 'Zero-based shard index'
default: ''
Expand Down Expand Up @@ -286,6 +292,7 @@ runs:
pytest-options: ${{ inputs.pytest-options }}
filter-pattern: ${{ inputs.filter-pattern }}
exclude-pattern: ${{ inputs.exclude-pattern }}
test-k-expr: ${{ inputs.test-k-expr }}
shard-index: ${{ inputs.shard-index }}
shard-count: ${{ inputs.shard-count }}
curobo-only: ${{ inputs.curobo-only }}
Expand Down
23 changes: 22 additions & 1 deletion .github/actions/run-tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ inputs:
excluded. Combines with filter-pattern (include + exclude).
default: ''
required: false
test-k-expr:
description: >-
Global pytest -k expression applied inside every per-file pytest run
spawned by tools/conftest.py (combined with device-split selectors).
Unlike pytest-options, this reaches the individual test processes, so it
can deselect parametrized cases (e.g. "not ovphysx").
default: ''
required: false
curobo-only:
description: 'Run only cuRobo and SkillGen tests (requires the cuRobo Docker image)'
default: 'false'
Expand Down Expand Up @@ -94,6 +102,12 @@ runs:
steps:
- name: Run Tests in Docker Container
shell: bash
env:
# Passed via env instead of inline ${{ }} interpolation: pytest options may
# contain spaces and quotes (e.g. -k "not ovphysx"), which would word-split
# the run_tests positional arguments if substituted textually.
PYTEST_OPTIONS: ${{ inputs.pytest-options }}
TEST_K_EXPR_INPUT: ${{ inputs.test-k-expr }}
run: |
# Function to run tests in Docker container
run_tests() {
Expand All @@ -116,6 +130,7 @@ runs:
local test_node_ids_key="${17}"
local wheelhouse_host_dir="${18}"
local wheelhouse_packages="${19}"
local test_k_expr="${20}"
local logs_pid=""
local wait_pid=""
local docker_wait_file="/tmp/.docker_exit_${container_name}"
Expand Down Expand Up @@ -258,6 +273,12 @@ runs:
docker_env_vars="$docker_env_vars -e TEST_EXTRA_PIP_PACKAGES"
fi

if [ -n "$test_k_expr" ]; then
export TEST_K_EXPR="$test_k_expr"
docker_env_vars="$docker_env_vars -e TEST_K_EXPR"
echo "Setting per-file pytest -k expression: $test_k_expr"
fi

# 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=""
Expand Down Expand Up @@ -491,7 +512,7 @@ runs:
}

# 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 }}" "${{ inputs.exclude-pattern }}" "${{ inputs.curobo-only }}" "${{ inputs.include-files }}" "${{ inputs.quarantined-only }}" "${{ inputs.shard-index }}" "${{ inputs.shard-count }}" "${{ inputs.volume-mount-source }}" "${{ inputs.extra-pip-packages }}" "${{ inputs.test-node-ids-file }}" "${{ inputs.test-node-ids-key }}" "${{ inputs.wheelhouse-host-dir }}" "${{ inputs.wheelhouse-packages }}"
run_tests "${{ inputs.test-path }}" "${{ inputs.result-file }}" "${{ inputs.container-name }}" "${{ inputs.image-tag }}" "${{ inputs.reports-dir }}" "$PYTEST_OPTIONS" "${{ inputs.filter-pattern }}" "${{ inputs.exclude-pattern }}" "${{ inputs.curobo-only }}" "${{ inputs.include-files }}" "${{ inputs.quarantined-only }}" "${{ inputs.shard-index }}" "${{ inputs.shard-count }}" "${{ inputs.volume-mount-source }}" "${{ inputs.extra-pip-packages }}" "${{ inputs.test-node-ids-file }}" "${{ inputs.test-node-ids-key }}" "${{ inputs.wheelhouse-host-dir }}" "${{ inputs.wheelhouse-packages }}" "$TEST_K_EXPR_INPUT"

- name: Kill container on cancellation
if: cancelled()
Expand Down
19 changes: 10 additions & 9 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,7 @@ jobs:
needs: [build, config]
if: >-
github.event_name != 'push' &&
needs.build.result == 'success' &&
(needs.config.outputs.ovphysx_wheelhouse_resource == '' ||
(github.event_name == 'pull_request' && github.base_ref == 'develop' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name != 'pull_request' && github.ref_name == 'develop'))
needs.build.result == 'success'
env:
USE_OVPHYSX_WHEELHOUSE: ${{ needs.config.outputs.ovphysx_wheelhouse_resource != '' && ((github.event_name == 'pull_request' && github.base_ref == 'develop' && github.event.pull_request.head.repo.full_name == github.repository) || (github.event_name != 'pull_request' && github.ref_name == 'develop')) }}
steps:
Expand All @@ -613,6 +610,10 @@ jobs:
isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }}
isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }}
filter-pattern: "isaaclab_ov"
# isaaclab_ovphysx requires ovphysx >= 0.5.1, which is only available from the
# NGC wheelhouse; untrusted runs (fork PRs) fall back to the public pip index
# and keep only the ovrtx-based isaaclab_ov coverage.
exclude-pattern: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && '' || 'isaaclab_ovphysx' }}
extra-pip-packages: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && 'ovrtx' || 'ovrtx ovphysx' }}
wheelhouse-resource: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && needs.config.outputs.ovphysx_wheelhouse_resource || '' }}
wheelhouse-packages: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && 'ovphysx' || '' }}
Expand Down Expand Up @@ -777,11 +778,7 @@ jobs:
timeout-minutes: 120
continue-on-error: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }}
needs: [build, config]
if: >-
needs.build.result == 'success' &&
(needs.config.outputs.ovphysx_wheelhouse_resource == '' ||
(github.event_name == 'pull_request' && github.base_ref == 'develop' && github.event.pull_request.head.repo.full_name == github.repository) ||
(github.event_name != 'pull_request' && github.ref_name == 'develop'))
if: needs.build.result == 'success'
env:
USE_OVPHYSX_WHEELHOUSE: ${{ needs.config.outputs.ovphysx_wheelhouse_resource != '' && ((github.event_name == 'pull_request' && github.base_ref == 'develop' && github.event.pull_request.head.repo.full_name == github.repository) || (github.event_name != 'pull_request' && github.ref_name == 'develop')) }}
steps:
Expand All @@ -795,6 +792,10 @@ jobs:
isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }}
isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }}
filter-pattern: "isaaclab_tasks"
# ovphysx-backed test params require ovphysx >= 0.5.1, which is only available
# from the NGC wheelhouse; untrusted runs (fork PRs) fall back to the public pip
# index and keep the newton/ovrtx kitless rendering coverage.
test-k-expr: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && '' || 'not ovphysx' }}
extra-pip-packages: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && 'ovrtx' || 'ovrtx ovphysx' }}
wheelhouse-resource: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && needs.config.outputs.ovphysx_wheelhouse_resource || '' }}
wheelhouse-packages: ${{ env.USE_OVPHYSX_WHEELHOUSE == 'true' && 'ovphysx' || '' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/daily-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:
image-tag: ${{ env.DOCKER_IMAGE_TAG }}
pytest-options: ""
filter-pattern: "isaaclab_tasks"
extra-pip-packages: "ovrtx ovphysx==0.4.13"
extra-pip-packages: "ovrtx ovphysx==0.5.2+head.f62c22207c"

- name: Copy All Test Results from IsaacLab Tasks Container
run: |
Expand Down
138 changes: 138 additions & 0 deletions .github/workflows/license-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,145 @@ concurrency:

jobs:
license-check:
# Fork PRs cannot access NGC_API_KEY, so they cannot resolve the immutable
# OVPhysX wheel required by the development extras.
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-24.04
env:
NGC_API_KEY: ${{ secrets.NGC_API_KEY }}

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
filter: tree:0

- name: Load OVPhysX wheelhouse configuration
id: config
shell: bash
run: |
set -euo pipefail
resource=$(yq -r .ovphysx_wheelhouse_resource .github/workflows/config.yaml)
echo "wheelhouse_resource=${resource}" >> "$GITHUB_OUTPUT"

- name: Restore NGC CLI cache
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/ngc-cli-cache/ngccli_linux.zip
key: ngc-cli-${{ runner.os }}-${{ runner.arch }}-4.20.0-5cf084c88998c58ad8abf7849d2d1b41d578423886eb03018df10194e341d35b

- name: Extract OVPhysX wheelhouse
id: extract-wheelhouse
shell: bash
env:
WHEELHOUSE_RESOURCE: ${{ steps.config.outputs.wheelhouse_resource }}
run: |
set -euo pipefail

if [ -z "${NGC_API_KEY:-}" ]; then
echo "::error::NGC_API_KEY is unavailable; cannot download the configured OVPhysX wheelhouse"
exit 1
fi

NGC_CLI_VERSION="4.20.0"
NGC_CLI_SHA256="5cf084c88998c58ad8abf7849d2d1b41d578423886eb03018df10194e341d35b"
NGC_CLI_URL="https://api.ngc.nvidia.com/v2/resources/nvidia/ngc-apps/ngc_cli/versions/${NGC_CLI_VERSION}/files/ngccli_linux.zip"

wheelhouse_root="$(mktemp -d "${RUNNER_TEMP:-/tmp}/ovphysx-wheelhouse.XXXXXX")"
download_root="$(mktemp -d "${RUNNER_TEMP:-/tmp}/ovphysx-wheelhouse-download.XXXXXX")"
ngc_home="$(mktemp -d "${RUNNER_TEMP:-/tmp}/ovphysx-ngc-home.XXXXXX")"
ngc_unpack_dir=""
preserve_wheelhouse_root=false
cleanup() {
if [ "$preserve_wheelhouse_root" != "true" ]; then
rm -rf "$wheelhouse_root"
fi
rm -rf "$download_root" "$ngc_home"
if [ -n "$ngc_unpack_dir" ]; then
rm -rf "$ngc_unpack_dir"
fi
}
trap cleanup EXIT

cache_dir="${RUNNER_TEMP:-/tmp}/ngc-cli-cache"
ngc_zip="${cache_dir}/ngccli_linux.zip"
mkdir -p "$cache_dir"
if [ ! -f "$ngc_zip" ]; then
echo "Downloading NGC CLI ${NGC_CLI_VERSION}"
curl -fsSL -o "$ngc_zip" "$NGC_CLI_URL"
fi
echo "${NGC_CLI_SHA256} ${ngc_zip}" | sha256sum -c -
ngc_unpack_dir="$(mktemp -d "${RUNNER_TEMP:-/tmp}/ngc-cli.XXXXXX")"
unzip -q "$ngc_zip" -d "$ngc_unpack_dir"
export PATH="${ngc_unpack_dir}/ngc-cli:${PATH}"

export NGC_CLI_API_KEY="$NGC_API_KEY"
export NGC_CLI_ORG=nvidian
export NGC_CLI_TEAM=no-team
export NGC_CLI_HOME="$ngc_home"

ngc --version
echo "Downloading wheelhouse resource: $WHEELHOUSE_RESOURCE"
ngc registry resource download-version "$WHEELHOUSE_RESOURCE" --dest "$download_root"

mapfile -t manifests < <(find "$download_root" -type f -name manifest.json)
if [ "${#manifests[@]}" -ne 1 ]; then
echo "::error::expected exactly one manifest.json in downloaded wheelhouse resource, found ${#manifests[@]}"
printf '%s\n' "${manifests[@]}"
exit 1
fi

payload_dir="$(dirname "${manifests[0]}")"
if [ ! -d "${payload_dir}/wheelhouse" ]; then
echo "::error::downloaded wheelhouse resource is missing wheelhouse/ next to manifest.json"
exit 1
fi

mkdir -p "$wheelhouse_root/wheelhouse"
cp "${payload_dir}/manifest.json" "$wheelhouse_root/manifest.json"
cp "${payload_dir}/wheelhouse/"*.whl "$wheelhouse_root/wheelhouse/"

python3 - <<'PY' "$wheelhouse_root/manifest.json" "$wheelhouse_root/wheelhouse"
import hashlib
import json
import pathlib
import sys

manifest_path = pathlib.Path(sys.argv[1])
wheelhouse_dir = pathlib.Path(sys.argv[2])
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))

expected = {
"artifact": "ovphysx-wheelhouse",
"platform": "manylinux_2_35_x86_64",
}
for key, value in expected.items():
actual = manifest.get(key)
if actual != value:
raise SystemExit(f"manifest {key!r} mismatch: expected {value!r}, got {actual!r}")

wheels = manifest.get("wheels")
if not isinstance(wheels, list) or not wheels:
raise SystemExit("manifest has no wheels list")

for wheel in wheels:
filename = wheel.get("file")
expected_sha = wheel.get("sha256")
if not filename or not expected_sha:
raise SystemExit(f"invalid wheel manifest entry: {wheel!r}")
wheel_path = wheelhouse_dir / filename
if not wheel_path.is_file():
raise SystemExit(f"manifest wheel is missing from wheelhouse: {filename}")
actual_sha = hashlib.sha256(wheel_path.read_bytes()).hexdigest()
if actual_sha != expected_sha:
raise SystemExit(f"sha256 mismatch for {filename}: expected {expected_sha}, got {actual_sha}")

print(f"Validated {len(wheels)} wheelhouse wheels from {manifest_path}")
PY

echo "wheelhouse_root=$wheelhouse_root" >> "$GITHUB_OUTPUT"
echo "wheelhouse_dir=$wheelhouse_root/wheelhouse" >> "$GITHUB_OUTPUT"

# - name: Install jq
# run: sudo apt-get update && sudo apt-get install -y jq

Expand Down Expand Up @@ -60,6 +191,7 @@ jobs:
OMNI_KIT_ACCEPT_EULA: yes
ACCEPT_EULA: Y
ISAACSIM_ACCEPT_EULA: YES
UV_FIND_LINKS: ${{ steps.extract-wheelhouse.outputs.wheelhouse_dir }}
run: |
uv sync --extra all
# Isaac Sim isn't in the dev pyproject; sync first so it isn't pruned.
Expand Down Expand Up @@ -153,3 +285,9 @@ jobs:
else
echo "All packages were checked."
fi

- name: Clean up OVPhysX wheelhouse
if: always()
shell: bash
run: |
rm -rf "${{ steps.extract-wheelhouse.outputs.wheelhouse_root }}"
2 changes: 2 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Guidelines for modifications:

## Contributors

* Agon Serifi
* Alessandro Assirelli
* Alex Omar
* Alexander Millane
Expand Down Expand Up @@ -127,6 +128,7 @@ Guidelines for modifications:
* Marco Alesiani
* Masoud Moghani
* Mateo Guaman Castro
* Matthew Taylor
* Maurice Rahme
* Michael Gussert
* Michael Lin
Expand Down
22 changes: 22 additions & 0 deletions docs/source/api/lab/isaaclab.sim.spawners.rst
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ Materials
MdlFileCfg
GlassMdlCfg
PhysicsMaterialCfg
RigidBodyMaterialBaseCfg
RigidBodyMaterialFragment
UsdPhysicsRigidBodyMaterialCfg
RigidBodyMaterialCfg
DeformableBodyMaterialBaseCfg
SurfaceDeformableBodyMaterialBaseCfg
Expand Down Expand Up @@ -303,8 +306,27 @@ Physical Materials
:members:
:exclude-members: __init__, func

.. autofunction:: spawn_physics_material

.. autofunction:: spawn_rigid_body_material

.. autoclass:: RigidBodyMaterialBaseCfg
:members:
:show-inheritance:
:exclude-members: __init__, func

.. autofunction:: spawn_rigid_body_material_from_fragments

.. autoclass:: RigidBodyMaterialFragment
:members:
:show-inheritance:
:exclude-members: __init__, func

.. autoclass:: UsdPhysicsRigidBodyMaterialCfg
:members:
:show-inheritance:
:exclude-members: __init__, func

.. autoclass:: RigidBodyMaterialCfg
:members:
:exclude-members: __init__, func
Expand Down
9 changes: 9 additions & 0 deletions docs/source/api/lab_newton/isaaclab_newton.sim.spawners.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ isaaclab_newton.sim.spawners

.. autosummary::

NewtonMaterialCfg
NewtonDeformableBodyMaterialCfg
NewtonDeformableMaterialCfg
NewtonSurfaceDeformableBodyMaterialCfg

Rigid Materials
---------------

.. autoclass:: NewtonMaterialCfg
:members:
:show-inheritance:
:exclude-members: __init__, func

Deformable Materials
--------------------

Expand Down
Loading
Loading