Repository navigation
[Core] Start simulation runtimes through backend launchers named by the config (1/2) - #8068
Conversation
There was a problem hiding this comment.
Isaac Lab Review Bot
The lifecycle policy is cleanly relocated and documented, but dropping exception suppression around SimulationApp.close() changes failure behavior during shutdown and can prevent SIGTERM from producing the documented signal-derived status.
- Design and architecture: The closure-based installer retains the prior lifecycle structure without a demonstrated layering or dependency break. The new
isaaclab_physx.appentry point is integrated through the package’s lazy-export pattern. - API: The new public function is exported and documented consistently, and the removed lifecycle class was private. However, the documented SIGTERM exit-status guarantee is not maintained when
app.close()raises. - Implementation: The normal status values, handler disarming, and post-close signal re-raise follow the prior implementation. Unlike the replaced class, the new callbacks do not suppress exceptions from
app.close(); on SIGTERM this skipssignal.raise_signal(signum), allowing a traceback, exit 1, or caller interception instead of the intended signal termination. Restore exception suppression while ensuring the re-raise remains unconditional.
Minor fixes needed. Posted 1 actionable finding inline.
Automated review; human maintainers own approval decisions.
|
|
||
| def on_sigterm(signum: int, frame) -> None: | ||
| signal.signal(signum, signal.SIG_DFL) | ||
| app.close(exit_code=128 + signum) |
There was a problem hiding this comment.
🔵 Suggestion · Implementation — Close failure now skips the SIGTERM re-raise
The replaced handler wrapped close() in contextlib.suppress(Exception) precisely so a teardown failure still reached signal.raise_signal(signum). Here an exception from app.close(exit_code=128 + signum) escapes the handler into the interrupted frame, so the process can report a traceback/exit 1 (or be swallowed by user code) instead of the documented 128+signum. Restore the suppression around both close calls, keeping the re-raise unconditional.
|
| @@ -33,6 +30,8 @@ | |||
|
|
|||
| SimulationApp = getattr(isaacsim, "SimulationApp", None) | |||
|
|
|||
| from isaaclab_physx.app import install_exit_handlers | |||
There was a problem hiding this comment.
Optional backend becomes required If an installation contains
isaaclab but not the optional isaaclab_physx package, importing AppLauncher now raises ModuleNotFoundError. The import happens before callers can use the launcher or its argument helpers, even though isaaclab does not declare a dependency on isaaclab_physx.
Knowledge Base Used: Physics backend extensions
| app.close(exit_code=128 + signum) | ||
| # close() only returns when fast shutdown is disabled | ||
| signal.raise_signal(signum) |
There was a problem hiding this comment.
Close errors interrupt SIGTERM shutdown If
app.close() raises during SIGTERM teardown, the handler never reaches signal.raise_signal(signum). It has already restored the default signal action but does not send the signal again, so this path no longer guarantees termination with the intended signal status. The previous handler continued to re-raise SIGTERM after a close error.
fc1fb4f to
0e9a048
Compare
StafaH
left a comment
There was a problem hiding this comment.
Maybe we can keep the app launcher in isaaclab core, now that I see the import change across the whole codebase, everyone has to import isaaclab_physx which doesn't look good
|
run-ci |
launch_simulation constructs the launcher each resolved config names in launcher_type: KitLauncher (isaaclab_physx.app, the former AppLauncher body) for Isaac Sim / Kit and OvrtxLauncher (isaaclab_ov.app) for OVRTX. Core stays free of Kit: KitLauncher installs the carb settings backend, the application runtime hook, and the Replicator seed hook once Kit is up. The exit lifecycle class is replaced by two lines in KitLauncher. Env configs gain class_type so scripts can construct runtime objects after the runtime starts. AppLauncher is deprecated and starts Kit through launch_simulation, so existing scripts keep running until they migrate.
Kit's USD-context work for a simulation is now a backend in the simulation's registry: KitStageBackend attaches the stage on construction, runs app updates for update_stage(), and closes Kit's context stage on teardown. Isaac Sim's stage-helper context is shared once by KitLauncher, show_stage_in_viewport moves to isaaclab_physx.app, and Replicator is seeded by the event terms that use it, so the global runtime and seed hooks are gone.
launch_simulation collects launcher_type from the physics and renderer config instances it resolves, with one Kit fallback for needs no config names. The visualizer-settings sync moves into sim_launcher without a blanket suppress, and wait_for_stage_load leaves until a caller needs it. APIs this PR had removed or moved now warn and forward instead: is_current_stage_in_memory, show_stage_in_viewport, initialize_carb_settings, and is_omniverse_mode; the hidden --cpu flag raises the same error as on develop.
A SimulationContext always has a stage, so SceneDataProvider.usd_stage returns it directly and the Kit visualizer drops its missing-stage check. Stage utilities no longer reach into Kit: the Kit stage backend closes Kit's USD context with the simulation, and Kit's own consumers run app updates, so update_stage() is deprecated and clear_stage()/close_stage() stay Kit-free.
clear_instance() closes native backends newest first, so the lifecycle test expects that order. The Kit-free render-settings test stubs enable_extension with the rest of Kit, and test_pva no longer reads the adapter's private _headless (it always launched headless).
The interface is a few lines and only launch_simulation uses it, so it lives in sim_launcher.py instead of a separate, near-identically named module.
_get_replicator() only loads Replicator again; the two Replicator event terms seed it with the environment seed where they draw from its random streams.
The stage utilities, settings manager, and scene data provider lose helpers that only restated an invariant or forwarded elsewhere: update_stage, is_current_stage_in_memory, the show_stage_in_viewport forwarder, initialize_carb_settings, is_omniverse_mode, and SceneDataProvider.usd_stage / get_usd_stage. Callers read SimulationContext.instance().stage directly. The hidden --cpu flag is gone as well.
A script that keeps no reference to AppLauncher or its app let the launch context be garbage-collected, which closed Kit mid-run (Kit startup test crashed). The adapter now holds the runtime at module level. Add the missing isaaclab_newton changelog fragment.
9b99c3f to
599e4ba
Compare
|
run-ci |
|
Backported to |
…he config (1/2) (#8068) ## Description **Part 1 of 2: the design.** The migration of every script and test is in the stacked follow-up, #8090. This PR keeps existing scripts running unchanged, so the two halves can be reviewed separately. `launch_simulation` now starts each simulation runtime through the launcher that the runtime's own backend package provides. The resolved config says which launcher is needed, so core never imports one. ```python # isaaclab.app: the interface every backend runtime implements class SimulationLauncher: device: str | None = None # optional device the runtime picked def __init__(self, launcher_args): ... # constructing it starts the runtime def close(self, exit_code: int = 0): ... # stops it # backend configs name their launcher, resolved lazily like ``class_type`` class PhysxCfg(PhysicsCfg): launcher_type: ClassVar[str] = "isaaclab_physx.app:KitLauncher" class OVRTXRendererCfg(RendererCfg): launcher_type: ClassVar[str] = "isaaclab_ov.app:OvrtxLauncher" ``` `launch_simulation(cfg, args)` scans the resolved config as it already did and collects `launcher_type` from the physics and renderer config instances it resolved. It constructs each launcher once and closes them in reverse order when the block exits. Kit needs that no config names (`require_kit`, no physics config, a Kit visualizer requested only on the CLI) fall back to `KitLauncher`. - **`isaaclab_physx.app.KitLauncher`** is the old `AppLauncher` body, minus dead code: - removed: argument-collision bookkeeping, the Isaac Sim 5 branch, and the hidden `--cpu` flag; - moved in from `launch_simulation`: the Isaac Sim availability check and the "Kit already running" guard. - **`isaaclab_ov.app.OvrtxLauncher`** registers the OVRTX USD schemas, which `launch_simulation` used to do inline. - **Moved into `sim_launcher.py`** because kitless launches need them too: argv fusing, visualizer argument normalization, and the visualizer-settings sync (no longer wrapped in a blanket `suppress(Exception)`). ### Kit stays in `isaaclab_physx` Core code no longer imports `carb`, `omni`, or `omni.replicator`. Kit concerns go through one of two owners, and no new global hook is added. - **The `SimulationContext` backend registry** owns anything tied to a simulation's lifetime: - `isaaclab_physx.app.KitStageBackend` is registered through `get_or_create_backend` when Kit runs; - it attaches the stage to Kit's USD context and closes Kit's context stage when `clear_instance()` closes the other backends; - core stage utilities never touch Kit: `clear_stage()`/`close_stage()` are Kit-free, and Kit's own consumers (PhysX reset/step, RTX render, the Kit visualizer) run the app updates they need. - **No defensive `None` handling on invariants:** a `SimulationContext` always has a stage, so consumers read `SimulationContext.instance().stage` directly (`SceneDataProvider.usd_stage` / `get_usd_stage` are removed). - **`KitLauncher`** owns one-time process setup: - `SettingsManager.set_backend(carb.settings)`, replacing `initialize_carb_settings` and `is_omniverse_mode`; - sharing Isaac Sim's stage-helper context; - one app update in `close()`, so scripts no longer need their own. - **Replicator** is enabled by the Isaac RTX renderer and seeded by the Replicator event terms that use it. The env classes no longer import it. - **`show_stage_in_viewport`** moves to `isaaclab_physx.app`, since it only works under Kit. - **Gravity:** tasks set it through `PhysxManager.set_gravity` instead of `carb.Float3`. ### Exit handling The ~110-line `_SimulationAppLifecycle` class from #6636 is gone. I measured a real Kit process with no handlers installed, and only two exit paths needed help. Both are now handled by two lines in `KitLauncher`: - An unhandled exception exits with 1. Kit's exit path reported 0. - `SIGINT` raises `KeyboardInterrupt`. Kit's own handler exited 0. `SIGTERM`, `SIGABRT`, and `SIGSEGV` keep their default actions. Fixes #7774, supersedes #7775 and #6531. ### Constructing runtime objects after launch Importing `pxr.Usd` before Kit starts makes Kit fail to start. Scripts therefore import only config classes and construct runtime objects with `instantiate(cfg)` (#8085), which resolves the config's lazy `class_type` after the runtime is up. - `ManagerBasedEnvCfg` and `ManagerBasedRLEnvCfg` gain `class_type`. - The 21 task configs with a custom env class name it. A registry test checks that all 126 match their registered entry point. - **Fixed:** `{DIR}` in an inherited `class_type` resolved against the module of a subclass missing `@configclass`, so the call failed with `ModuleNotFoundError`. ### Compatibility in this PR `isaaclab.app.AppLauncher` is deprecated. It now starts Kit through `launch_simulation`, so develop's scripts and tests run unchanged here. It still offers `is_available`, `has_gui`, and `has_window`, which unmigrated scripts use. The migration PR moves every caller and reduces it to an init-only shim. `isaaclab.test.utils.launch_test_simulation(**launcher_args)` starts Kit for a test module through `launch_simulation`. It picks the test device by default. ### Behavior changes - **Removed** (breaking; each only restated an invariant or forwarded elsewhere): - `sim_utils.update_stage`: the simulation's reset, step, and render process stage changes; - `sim_utils.is_current_stage_in_memory`: compare against `SimulationContext.instance().stage`; - `sim_utils.show_stage_in_viewport`: use `isaaclab_physx.app.show_stage_in_viewport`; - `SettingsManager.initialize_carb_settings` (and the module-level function) and `is_omniverse_mode`: `KitLauncher` sets the settings backend, and `has_kit()` checks for Kit; - `SceneDataProvider.usd_stage` / `get_usd_stage`; - the hidden `--cpu` flag: use `--device cpu`. - **Replicator seeding:** the Replicator event terms seed it with `env.cfg.seed` when they are built; `_get_replicator()` only loads it. Calling `env.seed(x)` later no longer reseeds Replicator. - **Kit startup marker** is now `[ISAACLAB] KitLauncher initialization complete`, and `tools/conftest.py` is updated to match. - **SIGTERM** ends the process immediately, without a Kit teardown. - **Warp environments:** `render_mode="rgb_array"` now warns and returns `None`, matching the core environments. Net: +2,326 / −3,045 across 154 files. ## Type of change - Breaking change (`AppLauncher` deprecated; Kit-coupled helpers removed; Kit exit and seeding behavior changed) ## Validation All runs on the display GPU (GPU 0), with develop's scripts and tests unchanged unless listed here. - **Launcher, app, and config tests:** - `isaaclab/test/app` (26) and `isaaclab_physx/test/app` (88); - `test_runtime_compatibility` (27), visualizer intent (8), distributed device (13), `test_preset_kit_decision` (6), `test_preset_cli` (11); - `test_configclass` (37), `test_sb3_leapp_export`, and the CLI tests (234). - **Kit tests through the deprecated adapter:** - `test_simulation_context` (30), PhysX `test_rigid_object` (44), `test_camera` (21); - stage utils (15), stage in memory (3), `test_events` (4), texture randomization (2), `test_manager_based_env` (4). - **Training:** `train.py --task Isaac-Cartpole --max_iterations 2` exits 0 with `isaacsim_physx` and `newton_mjwarp`. - `physics=physx` (kitless ovphysx) fails with an observation batch mismatch. - Develop `93b6e7432` fails the same way, so it is unrelated to this PR. - **Every script under `scripts/` and `examples/`**, compared against develop with the same invocation: - **Scripts outside the standalone matrix (78):** same outcome on develop and here. 52 run, 19 are blocked by an external resource (datasets, XR, Ray, gr00t, robomimic, moviepy), and 7 fail identically on develop. - **Standalone matrix (361 cases):** no regressions. The only case that first looked new was an old-style script with `--visualizer newton_rtx`. Kit and OVRTX cannot share a process, so the adapter now skips that visualizer with a warning, as Kit did on develop. - **Newton-based visualizers next to Kit PhysX:** those cases fail on develop too, when Newton builds its model from USD. - **After rebasing onto the latest develop:** the state machines, `bin_packing`, and Cartpole training still run. - **Known pre-existing failure:** `test_visualizer_integration_newton` has a flat-frame check that fails identically on develop. - Pre-commit passes. The changelog check only flags fragments from other PRs, because it compares against the fork's stale `develop`. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] I have made corresponding changes to the documentation (API pages for `isaaclab.app`, `isaaclab_physx.app`, `isaaclab_ov.app`) - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package (cherry picked from commit c9f9e22)
…mulation (3/3) (#8102) ## Description **Part 3 of 3.** #8068 (merged) added the launcher design, and #8090 moves the scripts onto it. This PR does the same for the tests. It is independent of #8090, so they can merge in either order. ### What changes - **One-line launch:** test modules start the runtime with a single `launch_test_simulation(...)` call. It replaces the `"""Launch Isaac Sim Simulator first."""` preamble in about 125 modules. - **`launch_test_simulation(cfg=None, **launcher_args)` is config-driven.** It starts whatever runtime the test's simulation config needs (the default `SimulationCfg()` when none is given) instead of forcing Kit, and it returns `None`. It still picks the test device from the multi-GPU mask by default. Every existing test gets the same runtime as before, because the default config uses PhysX, which starts Kit; the config makes that choice now, not the helper. - **Core `isaaclab` tests no longer import `omni`, `carb`, or `isaacsim`:** - camera tests rely on the simulation's own cleanup instead of Replicator's `destroy_hydra_textures`; - tests that check Kit, PhysX, or Isaac Sim behavior move to `isaaclab_physx`: the Isaac Sim `XformPrim` comparison, the Kit timeline and app-update tests, stage-in-memory, the UI window, Kit startup performance, and three Isaac Sim extension-path tests. No coverage is deleted. - **Tests that need the Kit app object** get it from `omni.kit.app` in their own package: Newton fabric sync, teleop XR, and the visualizer tests. The remaining Kit mentions in core tests are the `isaacsim_ci` CI markers, the `install_ci` installer checks, `omni.client`, and tests that stub `omni` to exercise core code's own Kit branches without starting Kit. Net: +856 / −1,260 across 169 files. ## Type of change - Breaking change (`launch_test_simulation` signature and return value) ## Validation All runs on the display GPU (GPU 0). - **Every changed or moved module passes,** including the app tests (43), simulation context (26), the moved Kit context tests (4), camera (21), Newton fabric sync (9), views, controllers, the other camera tests, pink IK, and teleop XR. - **Visualizer tests:** the integration and golden-image tests fail on this machine exactly as they do without this PR (a known flat-frame issue); CI is the check for those. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package
…mulation (3/3) (#8102) ## Description **Part 3 of 3.** #8068 (merged) added the launcher design, and #8090 moves the scripts onto it. This PR does the same for the tests. It is independent of #8090, so they can merge in either order. ### What changes - **One-line launch:** test modules start the runtime with a single `launch_test_simulation(...)` call. It replaces the `"""Launch Isaac Sim Simulator first."""` preamble in about 125 modules. - **`launch_test_simulation(cfg=None, **launcher_args)` is config-driven.** It starts whatever runtime the test's simulation config needs (the default `SimulationCfg()` when none is given) instead of forcing Kit, and it returns `None`. It still picks the test device from the multi-GPU mask by default. Every existing test gets the same runtime as before, because the default config uses PhysX, which starts Kit; the config makes that choice now, not the helper. - **Core `isaaclab` tests no longer import `omni`, `carb`, or `isaacsim`:** - camera tests rely on the simulation's own cleanup instead of Replicator's `destroy_hydra_textures`; - tests that check Kit, PhysX, or Isaac Sim behavior move to `isaaclab_physx`: the Isaac Sim `XformPrim` comparison, the Kit timeline and app-update tests, stage-in-memory, the UI window, Kit startup performance, and three Isaac Sim extension-path tests. No coverage is deleted. - **Tests that need the Kit app object** get it from `omni.kit.app` in their own package: Newton fabric sync, teleop XR, and the visualizer tests. The remaining Kit mentions in core tests are the `isaacsim_ci` CI markers, the `install_ci` installer checks, `omni.client`, and tests that stub `omni` to exercise core code's own Kit branches without starting Kit. Net: +856 / −1,260 across 169 files. ## Type of change - Breaking change (`launch_test_simulation` signature and return value) ## Validation All runs on the display GPU (GPU 0). - **Every changed or moved module passes,** including the app tests (43), simulation context (26), the moved Kit context tests (4), camera (21), Newton fabric sync (9), views, controllers, the other camera tests, pink IK, and teleop XR. - **Visualizer tests:** the integration and golden-image tests fail on this machine exactly as they do without this PR (a known flat-frame issue); CI is the check for those. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package (cherry picked from commit c7775bc)
…8090) ## Description **Part 2 of 3.** #8068 (merged) added the launcher design; this PR moves every script, example, tutorial, benchmark, and doc page onto it. The tests are in #8102. The two PRs are independent and can merge in either order. ```python from isaaclab.app import add_launcher_args, launch_simulation from isaaclab.utils import instantiate add_launcher_args(parser) args_cli = parser.parse_args() ... with launch_simulation(env_cfg, args_cli): # the runtime follows the config env = instantiate(env_cfg) ``` ### What changes - **Every script, example, tutorial, and benchmark** starts the runtime with `launch_simulation` and builds runtime objects with `instantiate` (#8085). Nothing outside the shim below uses `AppLauncher` any more. - **Kit calls leave the scripts:** - the teleop, record, and replay scripts no longer load Replicator or update the app after closing the env; - `pick_and_place.py` uses `Se3Keyboard` instead of raw `carb.input` (W/S/A/D move, Q/E height, K gripper, N/M aim). On develop it died before stepping; - the camera tutorials save PNGs with `save_images_to_file` instead of Replicator writers. - **The converter tools** (`convert_mesh`, `convert_urdf`, `convert_mjcf`) preview the converted asset in the visualizer chosen with `--viz`, Kit included, instead of a Kit-only viewport. `isaaclab_physx.app.show_stage_in_viewport` has no callers left and is removed. - **The 14 `check_*` scripts** under the core and PhysX test folders, which duplicated pytest coverage, are deleted. - **`AppLauncher` shrinks to an init-only shim**, so scripts written against the old API keep running: - `AppLauncher.add_app_launcher_args(parser)` adds the launcher arguments; - `AppLauncher(args).app` starts Kit through `launch_simulation`, and `app.close()` stops it; - `is_available`, `has_gui`, `has_window`, and `device` are removed. The runtime is held for the process, so a script that drops the launcher keeps Kit running. `test_app_launcher_shim.py` covers both a kept and a dropped launcher; the dropped case fails without the fix. - **Moved with their scripts:** the two converter tests and the replay-loop test, which read script code, and `wait_for_stage_load`, used by the teleop replay script. Net: +2,367 / −4,334 across 121 files. ## Type of change - Breaking change (`AppLauncher` reduced to a shim) ## Validation All runs on the display GPU (GPU 0). - **Every script under `scripts/` and `examples/`** was run on develop and with these changes, using the same invocation. No script that runs on develop fails here. - Of the 78 scripts outside the standalone matrix, 52 run, 19 are blocked by the same missing resource on both (datasets, XR, a Ray cluster, gr00t, robomimic, moviepy), and 7 fail the same way on both. - The standalone matrix (361 cases) shows no new failures. - **Converter tools:** each writes its USD. `--viz kit` and `--viz newton_gl` keep rendering the asset until the window closes. - **Tests:** the shim test (2), URDF converter (17), replay loop (1), and RTX utils (10) pass. - **Training:** Cartpole on `isaacsim_physx` runs 2 iterations. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] I have made corresponding changes to the documentation (tutorials and how-to guides) - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package
…8090) ## Description **Part 2 of 3.** #8068 (merged) added the launcher design; this PR moves every script, example, tutorial, benchmark, and doc page onto it. The tests are in #8102. The two PRs are independent and can merge in either order. ```python from isaaclab.app import add_launcher_args, launch_simulation from isaaclab.utils import instantiate add_launcher_args(parser) args_cli = parser.parse_args() ... with launch_simulation(env_cfg, args_cli): # the runtime follows the config env = instantiate(env_cfg) ``` ### What changes - **Every script, example, tutorial, and benchmark** starts the runtime with `launch_simulation` and builds runtime objects with `instantiate` (#8085). Nothing outside the shim below uses `AppLauncher` any more. - **Kit calls leave the scripts:** - the teleop, record, and replay scripts no longer load Replicator or update the app after closing the env; - `pick_and_place.py` uses `Se3Keyboard` instead of raw `carb.input` (W/S/A/D move, Q/E height, K gripper, N/M aim). On develop it died before stepping; - the camera tutorials save PNGs with `save_images_to_file` instead of Replicator writers. - **The converter tools** (`convert_mesh`, `convert_urdf`, `convert_mjcf`) preview the converted asset in the visualizer chosen with `--viz`, Kit included, instead of a Kit-only viewport. `isaaclab_physx.app.show_stage_in_viewport` has no callers left and is removed. - **The 14 `check_*` scripts** under the core and PhysX test folders, which duplicated pytest coverage, are deleted. - **`AppLauncher` shrinks to an init-only shim**, so scripts written against the old API keep running: - `AppLauncher.add_app_launcher_args(parser)` adds the launcher arguments; - `AppLauncher(args).app` starts Kit through `launch_simulation`, and `app.close()` stops it; - `is_available`, `has_gui`, `has_window`, and `device` are removed. The runtime is held for the process, so a script that drops the launcher keeps Kit running. `test_app_launcher_shim.py` covers both a kept and a dropped launcher; the dropped case fails without the fix. - **Moved with their scripts:** the two converter tests and the replay-loop test, which read script code, and `wait_for_stage_load`, used by the teleop replay script. Net: +2,367 / −4,334 across 121 files. ## Type of change - Breaking change (`AppLauncher` reduced to a shim) ## Validation All runs on the display GPU (GPU 0). - **Every script under `scripts/` and `examples/`** was run on develop and with these changes, using the same invocation. No script that runs on develop fails here. - Of the 78 scripts outside the standalone matrix, 52 run, 19 are blocked by the same missing resource on both (datasets, XR, a Ray cluster, gr00t, robomimic, moviepy), and 7 fail the same way on both. - The standalone matrix (361 cases) shows no new failures. - **Converter tools:** each writes its USD. `--viz kit` and `--viz newton_gl` keep rendering the asset until the window closes. - **Tests:** the shim test (2), URDF converter (17), replay loop (1), and RTX utils (10) pass. - **Training:** Cartpole on `isaacsim_physx` runs 2 iterations. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] I have made corresponding changes to the documentation (tutorials and how-to guides) - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package (cherry picked from commit 443dc47)
## Description A follow-up to #8068, #8090, and #8102: it inlines or removes launch-stack helpers whose names cost the reader more than their bodies do. This PR is pure cleanup with no behavior change; every public removal is listed below with its replacement. ### Launcher (`isaaclab.app.sim_launcher`) - **Arguments become a dict once.** `launch_simulation` and `scan` convert launcher args with `vars(args_cli)`, the namespace's live `__dict__`, so values resolved at launch (for example `args_cli.headless`) still reach the caller. That removes `_get_arg` / `_set_arg` and their three-way Namespace/dict/None branching on every read. - **Resolved once instead of twice:** - the livestream mode is resolved during argument normalization and read back afterwards; - the "explicit `--viz` overrides the config" rule for the Kit visualizer is part of the scan's visualizer intent. - **Inlined:** the logging-level resolver (now private here), the one-line `_is_*` config predicates, and the Kit-source list formatter. - **`make_physics_cfg` is private** (`_make_physics_cfg`); only `scan` used it. ### Settings (`isaaclab.app.settings_manager`) - **One accessor:** `SettingsManager.instance()` is removed. It was identical to `get_settings_manager()`. - **One setter:** `set_bool` / `set_int` / `set_float` / `set_string` are removed. They only called `set()`, which already dispatches on the value's type. Only calls on Isaac Lab's settings manager changed; calls on carb's settings interface are untouched. ### Kit launcher (`isaaclab_physx.app.KitLauncher`) - **Inlined:** three single-use helpers (spectator-view check, experience dependency check, deferred CUDA device). - **Merged:** the stop-button and play-button toolbar helpers become one `_set_toolbar_button_visible`, with each button's current behavior kept. - **Renamed:** `add_app_launcher_args` → `add_launcher_args`, and `ExplicitAction` → `_ExplicitAction` (internal). Net: +239 / −405 (about −165 lines). ## Type of change - Breaking change (removed `SettingsManager.instance`, the typed `SettingsManager.set_*` forwarders, and `isaaclab.app.make_physics_cfg`; renamed `KitLauncher.add_app_launcher_args`) ## Validation All runs on GPU 0. - **Launcher and runtime tests:** - Kit launcher (84), visualizer intent (8), distributed device resolution (11), runtime compatibility (27), `require_kit` (10); - preset Kit decision (6), preset CLI (11), RL entrypoints (44), CLI tests (234); - app tests, including the `AppLauncher` shim, exit status, and Kit startup; - simulation context (26), Isaac RTX renderer contract (26), and the changed contact-sensor and OvPhysX scene-data tests. - **`test_simulation_context_visualizers`:** 44 passed, 1 failed. The failing test needs `carb`, which only CI's image has, and it fails identically on develop. - **Training:** Cartpole runs 2 iterations with `isaacsim_physx` (Kit starts) and with `newton_mjwarp` (no Kit). - **Tutorial:** `create_empty.py` reaches setup and runs. - **Not run:** the toolbar-button and livestream `isaacsim.exp.full` paths need a GUI or a livestream. - **Removed test:** `test_deferred_cuda_device_synchronizes_torch_and_warp`. Its helper is now inlined into Kit-only startup code. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package
## Description A follow-up to #8068, #8090, and #8102: it inlines or removes launch-stack helpers whose names cost the reader more than their bodies do. This PR is pure cleanup with no behavior change; every public removal is listed below with its replacement. ### Launcher (`isaaclab.app.sim_launcher`) - **Arguments become a dict once.** `launch_simulation` and `scan` convert launcher args with `vars(args_cli)`, the namespace's live `__dict__`, so values resolved at launch (for example `args_cli.headless`) still reach the caller. That removes `_get_arg` / `_set_arg` and their three-way Namespace/dict/None branching on every read. - **Resolved once instead of twice:** - the livestream mode is resolved during argument normalization and read back afterwards; - the "explicit `--viz` overrides the config" rule for the Kit visualizer is part of the scan's visualizer intent. - **Inlined:** the logging-level resolver (now private here), the one-line `_is_*` config predicates, and the Kit-source list formatter. - **`make_physics_cfg` is private** (`_make_physics_cfg`); only `scan` used it. ### Settings (`isaaclab.app.settings_manager`) - **One accessor:** `SettingsManager.instance()` is removed. It was identical to `get_settings_manager()`. - **One setter:** `set_bool` / `set_int` / `set_float` / `set_string` are removed. They only called `set()`, which already dispatches on the value's type. Only calls on Isaac Lab's settings manager changed; calls on carb's settings interface are untouched. ### Kit launcher (`isaaclab_physx.app.KitLauncher`) - **Inlined:** three single-use helpers (spectator-view check, experience dependency check, deferred CUDA device). - **Merged:** the stop-button and play-button toolbar helpers become one `_set_toolbar_button_visible`, with each button's current behavior kept. - **Renamed:** `add_app_launcher_args` → `add_launcher_args`, and `ExplicitAction` → `_ExplicitAction` (internal). Net: +239 / −405 (about −165 lines). ## Type of change - Breaking change (removed `SettingsManager.instance`, the typed `SettingsManager.set_*` forwarders, and `isaaclab.app.make_physics_cfg`; renamed `KitLauncher.add_app_launcher_args`) ## Validation All runs on GPU 0. - **Launcher and runtime tests:** - Kit launcher (84), visualizer intent (8), distributed device resolution (11), runtime compatibility (27), `require_kit` (10); - preset Kit decision (6), preset CLI (11), RL entrypoints (44), CLI tests (234); - app tests, including the `AppLauncher` shim, exit status, and Kit startup; - simulation context (26), Isaac RTX renderer contract (26), and the changed contact-sensor and OvPhysX scene-data tests. - **`test_simulation_context_visualizers`:** 44 passed, 1 failed. The failing test needs `carb`, which only CI's image has, and it fails identically on develop. - **Training:** Cartpole runs 2 iterations with `isaacsim_physx` (Kit starts) and with `newton_mjwarp` (no Kit). - **Tutorial:** `create_empty.py` reaches setup and runs. - **Not run:** the toolbar-button and livestream `isaacsim.exp.full` paths need a GUI or a livestream. - **Removed test:** `test_deferred_cuda_device_synchronizes_torch_and_warp`. Its helper is now inlined into Kit-only startup code. ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added changelog fragments for every touched package (cherry picked from commit 24e1b46)
Description
Part 1 of 2: the design. The migration of every script and test is in the stacked follow-up, #8090. This PR keeps existing scripts running unchanged, so the two halves can be reviewed separately.
launch_simulationnow starts each simulation runtime through the launcher that the runtime's own backend package provides. The resolved config says which launcher is needed, so core never imports one.launch_simulation(cfg, args)scans the resolved config as it already did and collectslauncher_typefrom the physics and renderer config instances it resolved. It constructs each launcher once and closes them in reverse order when the block exits. Kit needs that no config names (require_kit, no physics config, a Kit visualizer requested only on the CLI) fall back toKitLauncher.isaaclab_physx.app.KitLauncheris the oldAppLauncherbody, minus dead code:--cpuflag;launch_simulation: the Isaac Sim availability check and the "Kit already running" guard.isaaclab_ov.app.OvrtxLauncherregisters the OVRTX USD schemas, whichlaunch_simulationused to do inline.sim_launcher.pybecause kitless launches need them too: argv fusing, visualizer argument normalization, and the visualizer-settings sync (no longer wrapped in a blanketsuppress(Exception)).Kit stays in
isaaclab_physxCore code no longer imports
carb,omni, oromni.replicator. Kit concerns go through one of two owners, and no new global hook is added.SimulationContextbackend registry owns anything tied to a simulation's lifetime:isaaclab_physx.app.KitStageBackendis registered throughget_or_create_backendwhen Kit runs;clear_instance()closes the other backends;clear_stage()/close_stage()are Kit-free, and Kit's own consumers (PhysX reset/step, RTX render, the Kit visualizer) run the app updates they need.Nonehandling on invariants: aSimulationContextalways has a stage, so consumers readSimulationContext.instance().stagedirectly (SceneDataProvider.usd_stage/get_usd_stageare removed).KitLauncherowns one-time process setup:SettingsManager.set_backend(carb.settings), replacinginitialize_carb_settingsandis_omniverse_mode;close(), so scripts no longer need their own.show_stage_in_viewportmoves toisaaclab_physx.app, since it only works under Kit.PhysxManager.set_gravityinstead ofcarb.Float3.Exit handling
The ~110-line
_SimulationAppLifecycleclass from #6636 is gone. I measured a real Kit process with no handlers installed, and only two exit paths needed help. Both are now handled by two lines inKitLauncher:SIGINTraisesKeyboardInterrupt. Kit's own handler exited 0.SIGTERM,SIGABRT, andSIGSEGVkeep their default actions. Fixes #7774, supersedes #7775 and #6531.Constructing runtime objects after launch
Importing
pxr.Usdbefore Kit starts makes Kit fail to start. Scripts therefore import only config classes and construct runtime objects withinstantiate(cfg)(#8085), which resolves the config's lazyclass_typeafter the runtime is up.ManagerBasedEnvCfgandManagerBasedRLEnvCfggainclass_type.{DIR}in an inheritedclass_typeresolved against the module of a subclass missing@configclass, so the call failed withModuleNotFoundError.Compatibility in this PR
isaaclab.app.AppLauncheris deprecated. It now starts Kit throughlaunch_simulation, so develop's scripts and tests run unchanged here. It still offersis_available,has_gui, andhas_window, which unmigrated scripts use. The migration PR moves every caller and reduces it to an init-only shim.isaaclab.test.utils.launch_test_simulation(**launcher_args)starts Kit for a test module throughlaunch_simulation. It picks the test device by default.Behavior changes
sim_utils.update_stage: the simulation's reset, step, and render process stage changes;sim_utils.is_current_stage_in_memory: compare againstSimulationContext.instance().stage;sim_utils.show_stage_in_viewport: useisaaclab_physx.app.show_stage_in_viewport;SettingsManager.initialize_carb_settings(and the module-level function) andis_omniverse_mode:KitLaunchersets the settings backend, andhas_kit()checks for Kit;SceneDataProvider.usd_stage/get_usd_stage;--cpuflag: use--device cpu.env.cfg.seedwhen they are built;_get_replicator()only loads it. Callingenv.seed(x)later no longer reseeds Replicator.[ISAACLAB] KitLauncher initialization complete, andtools/conftest.pyis updated to match.render_mode="rgb_array"now warns and returnsNone, matching the core environments.Net: +2,326 / −3,045 across 154 files.
Type of change
AppLauncherdeprecated; Kit-coupled helpers removed; Kit exit and seeding behavior changed)Validation
All runs on the display GPU (GPU 0), with develop's scripts and tests unchanged unless listed here.
isaaclab/test/app(26) andisaaclab_physx/test/app(88);test_runtime_compatibility(27), visualizer intent (8), distributed device (13),test_preset_kit_decision(6),test_preset_cli(11);test_configclass(37),test_sb3_leapp_export, and the CLI tests (234).test_simulation_context(30), PhysXtest_rigid_object(44),test_camera(21);test_events(4), texture randomization (2),test_manager_based_env(4).train.py --task Isaac-Cartpole --max_iterations 2exits 0 withisaacsim_physxandnewton_mjwarp.physics=physx(kitless ovphysx) fails with an observation batch mismatch.93b6e7432fails the same way, so it is unrelated to this PR.scripts/andexamples/, compared against develop with the same invocation:--visualizer newton_rtx. Kit and OVRTX cannot share a process, so the adapter now skips that visualizer with a warning, as Kit did on develop.bin_packing, and Cartpole training still run.test_visualizer_integration_newtonhas a flat-frame check that fails identically on develop.develop.Release backport
developChecklist
isaaclab.app,isaaclab_physx.app,isaaclab_ov.app)