From fabb68a86894a94f2d13d10c822789c9820b380e Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 24 Aug 2026 16:54:35 -0700 Subject: [PATCH 1/5] Restore leading positional slots in InteractiveSceneCfg Commit 0a0dc1be47 ("Support Multi-Backend for Demo Scripts", #5938) added class_type as the first field of InteractiveSceneCfg. Because configclass builds a dataclass, declaration order is the positional __init__ signature, so every scene configuration constructed as MySceneCfg(num_envs, env_spacing) began assigning num_envs into class_type and failing validation with "Missing values detected ... num_envs". Declare class_type last instead. Nothing reads it positionally, and InteractiveScene._collect_asset_cfgs excludes base fields by name via InteractiveSceneCfg.__dataclass_fields__, so ordering is inert there. --- .../add-new-robot-scene-cfg-positional.rst | 10 ++++++++++ .../isaaclab/scene/interactive_scene_cfg.py | 16 ++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst diff --git a/source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst b/source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst new file mode 100644 index 000000000000..61d9587fb691 --- /dev/null +++ b/source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst @@ -0,0 +1,10 @@ +Fixed +^^^^^ + +* Fixed :class:`isaaclab.scene.InteractiveSceneCfg` consuming the first positional constructor + argument as :attr:`class_type`. The field is now declared last, so scene configurations that + pass :attr:`num_envs` and :attr:`env_spacing` positionally construct correctly again instead + of failing validation with ``Missing values detected ... num_envs``. +* Fixed the ``add_new_robot.py`` tutorial failing at startup, and its wheel-velocity actions + being sized for a single environment so that ``--num_envs`` greater than one raised a shape + mismatch. diff --git a/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py b/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py index cd9581256b01..ae4aba605d0b 100644 --- a/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py +++ b/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py @@ -79,12 +79,6 @@ class MySceneCfg(InteractiveSceneCfg): """ - class_type: type[InteractiveScene] | str = "{DIR}.interactive_scene:InteractiveScene" - """The class to use for the interactive scene. - - Defaults to :class:`isaaclab.scene.InteractiveScene`. - """ - num_envs: int = MISSING """Number of environment instances handled by the scene.""" @@ -150,6 +144,16 @@ class MySceneCfg(InteractiveSceneCfg): clone_cfg: CloneCfg = CloneCfg() """Clone execution and legal scene-combination configuration.""" + class_type: type[InteractiveScene] | str = "{DIR}.interactive_scene:InteractiveScene" + """The class to use for the interactive scene. + + Defaults to :class:`isaaclab.scene.InteractiveScene`. + + .. note:: + Declared last so that :attr:`num_envs` and :attr:`env_spacing` keep their leading + positional slots for scene configurations that construct them positionally. + """ + def add( target: InteractiveSceneCfg, From e98831ad04be93706803458de577b048b3aff087 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 24 Aug 2026 16:54:47 -0700 Subject: [PATCH 2/5] Fix add_new_robot tutorial startup and multi-environment actions Pass num_envs by keyword so the tutorial does not depend on the positional slot order of InteractiveSceneCfg, which is what broke it when class_type was inserted ahead of num_envs. Size the wheel-velocity actions to the scene instead of hard-coding a batch of one. Any --num_envs greater than one previously aborted in the first step with "Shape mismatch: torch.Size([1, 2]) != (2, 2)". --- scripts/tutorials/01_assets/add_new_robot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/tutorials/01_assets/add_new_robot.py b/scripts/tutorials/01_assets/add_new_robot.py index 7afd19a77bc0..ca0c477ef587 100644 --- a/scripts/tutorials/01_assets/add_new_robot.py +++ b/scripts/tutorials/01_assets/add_new_robot.py @@ -105,8 +105,8 @@ def run_simulator(sim: sim_utils.SimulationContext, scene: InteractiveScene): # wheel-velocity templates allocated once on the simulation device; the joint # target setters dispatch to GPU Warp kernels and reject CPU tensors. - straight_action = torch.tensor([[10.0, 10.0]], device=sim.device) - turn_action = torch.tensor([[5.0, -5.0]], device=sim.device) + straight_action = torch.tensor([[10.0, 10.0]], device=sim.device).repeat(scene.num_envs, 1) + turn_action = torch.tensor([[5.0, -5.0]], device=sim.device).repeat(scene.num_envs, 1) while simulation_app.is_running(): # reset @@ -173,7 +173,7 @@ def main(): sim = sim_utils.SimulationContext(sim_cfg) sim.set_camera_view([3.5, 0.0, 3.2], [0.0, 0.0, 0.5]) # Design scene - scene_cfg = NewRobotsSceneCfg(args_cli.num_envs, env_spacing=2.0) + scene_cfg = NewRobotsSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0) scene = InteractiveScene(scene_cfg) # Play the simulator sim.reset() From efe908bf7ac58596be27b1a1d8f0041e51253959 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Mon, 24 Aug 2026 16:54:49 -0700 Subject: [PATCH 3/5] Launch standalone tutorial scripts in CI Both standalone script jobs pass standalone-script-scope "demos", and select_script_scope keeps only scripts/demos, so the 24 tutorial scripts were discovered and given readiness markers but never actually launched. That is why the add_new_robot regression survived from its merge to SQA. Add the matching tutorials-scope jobs for the Kit and non-Kit runtime groups. --- .github/workflows/build.yaml | 59 ++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8b5566d418f1..9bce5c63e9b0 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -425,6 +425,65 @@ jobs: container-name: isaac-lab-standalone-demos-non-kit-test omni-github-test-type: standalone-demo + # Tutorials are scoped separately from demos: both scopes come from the same + # discovery in standalone_script_cases.py, and running them in one job would + # exceed the per-job budget. + test-standalone-tutorials-kit: + name: standalone tutorials (headless, Kit) + runs-on: [self-hosted, gpu] + timeout-minutes: 180 + needs: [build, config] + if: >- + github.event_name != 'push' && + needs.build.result == 'success' + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 1 + lfs: true + - uses: ./.github/actions/run-package-tests + with: + image-tag: ${{ needs.config.outputs.ci_image_tag }} + isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} + isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} + include-files: "test_standalone_scripts.py" + standalone-script-scope: "tutorials" + standalone-script-visualizer: "none" + standalone-script-runtime-group: kit + result-file: "test-standalone-tutorials-kit-report.xml" + container-name: isaac-lab-standalone-tutorials-kit-test + omni-github-test-type: standalone-tutorial + + test-standalone-tutorials-non-kit: + name: standalone tutorials (headless, non-Kit) + runs-on: [self-hosted, gpu] + timeout-minutes: 180 + needs: [build, config] + if: >- + github.event_name != 'push' && + needs.build.result == 'success' + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 1 + lfs: true + - name: Resolve OVPhysX runtime pin from pyproject + uses: ./.github/actions/resolve-ov-pins + id: ov_pins + - uses: ./.github/actions/run-package-tests + with: + image-tag: ${{ needs.config.outputs.ci_image_tag }} + isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} + isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} + extra-pip-packages: ${{ steps.ov_pins.outputs.ovphysx }} + include-files: "test_standalone_scripts.py" + standalone-script-scope: "tutorials" + standalone-script-visualizer: "none" + standalone-script-runtime-group: non-kit + result-file: "test-standalone-tutorials-non-kit-report.xml" + container-name: isaac-lab-standalone-tutorials-non-kit-test + omni-github-test-type: standalone-tutorial + test-isaaclab-rl: name: isaaclab_rl runs-on: [self-hosted, gpu] From d18618bc3ed5b9707241ec6a822f53d5519bec66 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Sat, 29 Aug 2026 22:23:01 -0700 Subject: [PATCH 4/5] Restore class_type as the first InteractiveSceneCfg field Every peer base configuration declares class_type first: AssetBaseCfg, ActuatorBaseCfg, ActionTermCfg, CommandTermCfg and RecorderTermCfg. Moving it last made InteractiveSceneCfg the sole outlier. The reorder was also unnecessary. The repository contains exactly one positional scene-configuration construction, in add_new_robot.py, which this branch already fixes by passing num_envs as a keyword. Every other call site and all five documented examples already use keywords. Drop the changelog fragment with it: no source package changes any more, so tools/changelog/cli.py requires none. --- .../add-new-robot-scene-cfg-positional.rst | 10 ---------- .../isaaclab/scene/interactive_scene_cfg.py | 16 ++++++---------- 2 files changed, 6 insertions(+), 20 deletions(-) delete mode 100644 source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst diff --git a/source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst b/source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst deleted file mode 100644 index 61d9587fb691..000000000000 --- a/source/isaaclab/changelog.d/add-new-robot-scene-cfg-positional.rst +++ /dev/null @@ -1,10 +0,0 @@ -Fixed -^^^^^ - -* Fixed :class:`isaaclab.scene.InteractiveSceneCfg` consuming the first positional constructor - argument as :attr:`class_type`. The field is now declared last, so scene configurations that - pass :attr:`num_envs` and :attr:`env_spacing` positionally construct correctly again instead - of failing validation with ``Missing values detected ... num_envs``. -* Fixed the ``add_new_robot.py`` tutorial failing at startup, and its wheel-velocity actions - being sized for a single environment so that ``--num_envs`` greater than one raised a shape - mismatch. diff --git a/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py b/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py index ae4aba605d0b..cd9581256b01 100644 --- a/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py +++ b/source/isaaclab/isaaclab/scene/interactive_scene_cfg.py @@ -79,6 +79,12 @@ class MySceneCfg(InteractiveSceneCfg): """ + class_type: type[InteractiveScene] | str = "{DIR}.interactive_scene:InteractiveScene" + """The class to use for the interactive scene. + + Defaults to :class:`isaaclab.scene.InteractiveScene`. + """ + num_envs: int = MISSING """Number of environment instances handled by the scene.""" @@ -144,16 +150,6 @@ class MySceneCfg(InteractiveSceneCfg): clone_cfg: CloneCfg = CloneCfg() """Clone execution and legal scene-combination configuration.""" - class_type: type[InteractiveScene] | str = "{DIR}.interactive_scene:InteractiveScene" - """The class to use for the interactive scene. - - Defaults to :class:`isaaclab.scene.InteractiveScene`. - - .. note:: - Declared last so that :attr:`num_envs` and :attr:`env_spacing` keep their leading - positional slots for scene configurations that construct them positionally. - """ - def add( target: InteractiveSceneCfg, From 0461d7a178b885ab235c20ac2f5d2e2b360ee1b7 Mon Sep 17 00:00:00 2001 From: jichuanh Date: Sat, 29 Aug 2026 22:23:08 -0700 Subject: [PATCH 5/5] Drop the standalone tutorial CI jobs The tutorials are slated for removal, so wiring them into the launch matrix is not worth two additional required status checks. The coverage gap itself stands: both standalone-script jobs pass standalone-script-scope "demos", so select_script_scope filters every scripts/tutorials path out of CASES. Tutorials are still discovered and marker-checked, just never launched. --- .github/workflows/build.yaml | 59 ------------------------------------ 1 file changed, 59 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 0ac0f0728ce1..2ff42e847a07 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -435,65 +435,6 @@ jobs: container-name: isaac-lab-standalone-demos-non-kit-test omni-github-test-type: standalone-demo - # Tutorials are scoped separately from demos: both scopes come from the same - # discovery in standalone_script_cases.py, and running them in one job would - # exceed the per-job budget. - test-standalone-tutorials-kit: - name: standalone tutorials (headless, Kit) - runs-on: [self-hosted, gpu] - timeout-minutes: 180 - needs: [build, config] - if: >- - github.event_name != 'push' && - needs.build.result == 'success' - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 1 - lfs: true - - uses: ./.github/actions/run-package-tests - with: - image-tag: ${{ needs.config.outputs.ci_image_tag }} - isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} - isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} - include-files: "test_standalone_scripts.py" - standalone-script-scope: "tutorials" - standalone-script-visualizer: "none" - standalone-script-runtime-group: kit - result-file: "test-standalone-tutorials-kit-report.xml" - container-name: isaac-lab-standalone-tutorials-kit-test - omni-github-test-type: standalone-tutorial - - test-standalone-tutorials-non-kit: - name: standalone tutorials (headless, non-Kit) - runs-on: [self-hosted, gpu] - timeout-minutes: 180 - needs: [build, config] - if: >- - github.event_name != 'push' && - needs.build.result == 'success' - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 1 - lfs: true - - name: Resolve OVPhysX runtime pin from pyproject - uses: ./.github/actions/resolve-ov-pins - id: ov_pins - - uses: ./.github/actions/run-package-tests - with: - image-tag: ${{ needs.config.outputs.ci_image_tag }} - isaacsim-base-image: ${{ needs.config.outputs.isaacsim_image_name }} - isaacsim-version: ${{ needs.config.outputs.isaacsim_image_tag }} - extra-pip-packages: ${{ steps.ov_pins.outputs.ovphysx }} - include-files: "test_standalone_scripts.py" - standalone-script-scope: "tutorials" - standalone-script-visualizer: "none" - standalone-script-runtime-group: non-kit - result-file: "test-standalone-tutorials-non-kit-report.xml" - container-name: isaac-lab-standalone-tutorials-non-kit-test - omni-github-test-type: standalone-tutorial - test-isaaclab-rl: name: isaaclab_rl runs-on: [self-hosted, gpu]