Replaces IsaacSim `stage_utils` with IsaacLab `stage_utils`
Description
Remove dependency on IsaacSim stage_utils for integration of new simulation engines like newton.
Type of change
- Dependency removal
Checklist
- [ ] I have read and understood the contribution guidelines
- [ ] I have run the
pre-commitchecks with./isaaclab.sh --format - [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have updated the changelog and the corresponding version in the extension's
config/extension.tomlfile - [ ] I have added my name to the
CONTRIBUTORS.mdor my name already exists there
Seems like many things are failing :eyes:
I looked into the failing issue it seems like because we are combining from utils import * with cross package import. If you changes import isaaclab.sim.utils.stage as stage_utils to from isaaclab.sim.utils import stage as stage_utils
it will work again, Explaination:
from utils import * rebinds names on the parent package, and in your case it ends up binding isaaclab.sim.utils to the module isaaclab.sim.utils.utils instead of the utils package.
import isaaclab.sim.utils.stage as stage_utils requires isaaclab.sim.utils to be a package (with path) so it can descend to stage, which fails when it’s actually the module.
from isaaclab.sim.utils import stage as stage_utils works because it imports the package and then accesses its stage attribute directly, bypassing that package-versus-module mix-up.
Personally I think that the root cause is import * in init.py files. It blindly rebinds names and can shadow the package object (isaaclab.sim.utils) with a module (utils.py), breaking dotted imports like import isaaclab.sim.utils.stage as ….
In the new rework we may need to consider to drop * import all together (at least for core)
Greptile Overview
Greptile Summary
This PR successfully removes the IsaacLab dependency on IsaacSim's stage_utils module by implementing its own stage.py utility module. This enables integration with alternative simulation engines like Newton.
Key Changes:
- Created new
isaaclab/sim/utils/stage.pywith ~800 lines implementing stage management functions - Refactored
utils.pyto import and re-export key functions from the newstage.pymodule, maintaining backward compatibility - Updated 50+ files across the codebase to import from IsaacLab's stage utilities instead of IsaacSim's
- The new implementation includes proper Isaac Sim version checks and fallbacks for compatibility
Implementation Quality:
- Clean separation of concerns with stage utilities in dedicated module
- Proper thread-local storage pattern for concurrent stage access
- Comprehensive error handling and version compatibility checks
- Backward compatibility maintained through re-exports in
utils.py
The migration is comprehensive and well-executed. All test files have been updated appropriately, and the changelog documents the change.
Confidence Score: 5/5
- This PR is safe to merge - it's a clean dependency removal with comprehensive test coverage and backward compatibility
- The PR achieves its goal of removing IsaacSim dependency on stage_utils with a well-structured implementation. The new stage.py module properly implements all necessary functions with version checks and error handling. All imports across 50+ files have been systematically updated. Backward compatibility is maintained through re-exports. No logical errors or breaking changes detected.
- No files require special attention - the implementation is solid throughout
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| source/isaaclab/isaaclab/sim/utils/stage.py | 5/5 | New file implementing IsaacLab's own stage utilities, replacing IsaacSim dependency. Clean implementation with proper error handling and version checks. |
| source/isaaclab/isaaclab/sim/utils/utils.py | 5/5 | Refactored to remove stage utility functions and import them from new stage.py module. Maintains backward compatibility through re-exports. |
| source/isaaclab/isaaclab/sim/simulation_context.py | 5/5 | Updated imports to use IsaacLab stage utilities instead of IsaacSim's. Clean migration with no logic changes. |
| source/isaaclab/isaaclab/scene/interactive_scene.py | 5/5 | Updated imports from IsaacSim stage utils to IsaacLab stage module. No functional changes. |
| source/isaaclab/test/sim/test_stage_in_memory.py | 5/5 | Test file updated to use IsaacLab stage utilities. All function calls properly migrated. |
Sequence Diagram
sequenceDiagram
participant User
participant SimContext as SimulationContext
participant StageUtils as isaaclab.sim.utils.stage
participant IsaacSim as IsaacSim Core
participant USD as USD Stage
User->>SimContext: Initialize simulation
SimContext->>StageUtils: create_new_stage_in_memory()
StageUtils->>USD: Usd.Stage.CreateInMemory()
USD-->>StageUtils: stage instance
StageUtils-->>SimContext: stage instance
User->>SimContext: Setup scene
SimContext->>StageUtils: use_stage(stage_in_memory)
StageUtils->>StageUtils: Set thread-local stage context
User->>SimContext: Attach stage for rendering
SimContext->>StageUtils: attach_stage_to_usd_context()
StageUtils->>StageUtils: Check if stage is in memory
StageUtils->>IsaacSim: physx_sim_interface.attach_stage()
StageUtils->>IsaacSim: omni.usd.attach_stage_with_callback()
IsaacSim-->>StageUtils: Stage attached
User->>SimContext: Query stage state
SimContext->>StageUtils: is_current_stage_in_memory()
StageUtils->>USD: get_current_stage_id()
StageUtils->>IsaacSim: omni.usd.get_context().get_stage()
StageUtils-->>SimContext: boolean result
@ooctipus I think for this one we are also ready to go