Skip to content

Commit 03904ab

Browse files
Fix PhysX simulation lifecycle ownership (#6588)
# Description PR #6505 removed the Kit extension startup that previously re-imported `isaaclab_physx` after Kit loaded. When task configuration imports the PhysX package before Kit, the compatibility hook returns early and is never retried. The original Isaac Sim `SimulationManager` STOP callback then invalidates the tensor view shared with `PhysxManager`, causing Franka and other PhysX articulation environments to fail during their first reset. This PR retries the existing idempotent compatibility takeover from `PhysxManager.initialize()`, where Kit is available and PhysX is the selected backend. It also updates the import-order contract and adds an integration regression test that imports `PhysxCfg` before launching Kit. This fix is independent of #6337. ## Type of change - Bug fix (non-breaking change which fixes an issue) - Documentation update ## Screenshots N/A ## Validation - Regression RED on unmodified develop: module alias remained the original Isaac Sim `SimulationManager` after `SimulationContext` initialization. - Regression GREEN: `1 passed`. - `Isaac-Reach-Franka`, 16 environments, PhysX: environment creation, reset, and first step completed with exit code 0 and without invalidated-view errors. - `./isaaclab.sh -p tools/changelog/cli.py check develop` - `./isaaclab.sh -f` ## Checklist - [x] I have read and understood the contribution guidelines - [x] I have run the pre-commit checks with `./isaaclab.sh -f` - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove the fix is effective - [x] I have added a changelog fragment for every touched package - [x] My name already exists in `CONTRIBUTORS.md`
1 parent 97b23cf commit 03904ab

4 files changed

Lines changed: 59 additions & 7 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fixed
2+
^^^^^
3+
4+
* Fixed PhysX tensor views being invalidated when the PhysX backend configuration
5+
was imported before Kit startup.

source/isaaclab_physx/isaaclab_physx/__init__.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,11 @@ def _patch_isaacsim_simulation_manager():
4949
5050
This function is intentionally lazy: it only patches if
5151
``isaacsim.core.simulation_manager`` is already present in ``sys.modules``.
52-
In the normal production flow Kit loads that module during extension startup,
53-
before any user script imports :mod:`isaaclab_physx`, so the condition is
54-
true and the patch fires on time. If :mod:`isaaclab_physx` happens to be
55-
imported for pure config loading before Kit has launched (e.g. in
56-
``test_env_cfg_no_forbidden_imports``), the module is absent and this
57-
function is a no-op — which is correct, because no callbacks have been
58-
registered yet.
52+
Config loading may import :mod:`isaaclab_physx` before Kit has launched. In
53+
that case, the module is absent and this function is a no-op because no
54+
callbacks have been registered yet. :meth:`PhysxManager.initialize` invokes
55+
this function again after Kit startup, guaranteeing that the original
56+
callbacks are disabled before Isaac Lab creates PhysX tensor views.
5957
"""
6058
original_module = sys.modules.get("isaacsim.core.simulation_manager")
6159
if original_module is None:

source/isaaclab_physx/isaaclab_physx/physics/physx_manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ def __getattr__(self, name: str) -> Callable[..., Any]:
285285
@classmethod
286286
def initialize(cls, sim_context: SimulationContext) -> None:
287287
"""Initialize the physics manager."""
288+
from isaaclab_physx import _patch_isaacsim_simulation_manager
289+
290+
_patch_isaacsim_simulation_manager()
291+
288292
from isaaclab.sim.utils.stage import get_current_stage_id
289293

290294
super().initialize(sim_context)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
2+
# All rights reserved.
3+
#
4+
# SPDX-License-Identifier: BSD-3-Clause
5+
6+
"""Verify PhysX lifecycle ownership when its package is imported before Kit starts."""
7+
8+
from isaaclab_physx.physics import PhysxCfg
9+
10+
from isaaclab.app import AppLauncher
11+
from isaaclab.test.utils import resolve_test_sim_device
12+
13+
# Launch Kit only after importing the PhysX config to reproduce normal entry-point config resolution.
14+
simulation_app = AppLauncher(headless=True, device=resolve_test_sim_device()).app
15+
16+
import pytest
17+
from isaaclab_physx.physics import PhysxManager
18+
19+
import isaacsim.core.simulation_manager as simulation_manager_module
20+
21+
import isaaclab.sim as sim_utils
22+
from isaaclab.sim import SimulationCfg, SimulationContext
23+
24+
pytestmark = pytest.mark.integration
25+
26+
27+
@pytest.fixture(autouse=True)
28+
def setup_teardown():
29+
"""Create a fresh stage and simulation context for each test."""
30+
SimulationContext.clear_instance()
31+
sim_utils.create_new_stage()
32+
yield
33+
SimulationContext.clear_instance()
34+
35+
36+
@pytest.mark.isaacsim_ci
37+
def test_initialize_claims_simulation_manager_lifecycle():
38+
"""PhysxManager initialization disables Isaac Sim's original lifecycle callbacks."""
39+
original_manager = simulation_manager_module.SimulationManager
40+
assert original_manager is not PhysxManager
41+
42+
SimulationContext(cfg=SimulationCfg(physics=PhysxCfg()))
43+
44+
assert simulation_manager_module.SimulationManager is PhysxManager
45+
assert not any(original_manager.get_default_callback_status().values())

0 commit comments

Comments
 (0)