Commit 33bcf660 authored by matthewtrepte's avatar matthewtrepte Committed by Kelly Guo

Adds support for Stage in Memory (#375)

<!--
Thank you for your interest in sending a pull request. Please make sure
to check the contribution guidelines.

Link:
https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html
-->

Support using a stage in memory, rather the default stage attached to a
usd context, for faster operations during stage initialization and
cloning.

The feature requires a change on Isaac Sim which is tracked separately.

<!-- As a practice, it is recommended to open an issue to have
discussions on the proposed pull request.
This makes it easier for the community to keep track of what is being
developed or added, and if a given feature
is demanded by more than one party. -->

<!-- As you go through the list, delete the ones that are not
applicable. -->

- New feature (non-breaking change which adds functionality)

<!--
Example:

| Before | After |
| ------ | ----- |
| _gif/png before_ | _gif/png after_ |

To upload images to a PR -- simply drag and drop an image while in edit
mode and it should upload the image directly. You can then paste that
source into the above before/after sections.
-->

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [x] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

<!--
As you go through the checklist above, you can mark something as done by
putting an x character in it

For example,
- [x] I have done this task
- [ ] I have not done this task
-->

---------
Signed-off-by: 's avatarKelly Guo <kellyguo123@hotmail.com>
Signed-off-by: 's avatarrwiltz <165190220+rwiltz@users.noreply.github.com>
Signed-off-by: 's avatarAshwin Varghese Kuruttukulam <123109010+ashwinvkNV@users.noreply.github.com>
Signed-off-by: 's avatarKelly Guo <kellyg@nvidia.com>
Signed-off-by: 's avatarMichael Gussert <michael@gussert.com>
Co-authored-by: 's avatarpeterd-NV <peterd@nvidia.com>
Co-authored-by: 's avatarKelly Guo <kellyg@nvidia.com>
Co-authored-by: 's avatarcosmith-nvidia <141183495+cosmith-nvidia@users.noreply.github.com>
Co-authored-by: 's avatarjaczhangnv <jaczhang@nvidia.com>
Co-authored-by: 's avatarrwiltz <165190220+rwiltz@users.noreply.github.com>
Co-authored-by: 's avatarYanzi Zhu <yanziz@nvidia.com>
Co-authored-by: 's avatarnv-mhaselton <mhaselton@nvidia.com>
Co-authored-by: 's avatarCY Chen <cyc@nvidia.com>
Co-authored-by: 's avataroahmednv <oahmed@Nvidia.com>
Co-authored-by: 's avatarAshwin Varghese Kuruttukulam <123109010+ashwinvkNV@users.noreply.github.com>
Co-authored-by: 's avatarRafael Wiltz <rwiltz@nvidia.com>
Co-authored-by: 's avatarMichael Gussert <michael@gussert.com>
Co-authored-by: 's avatarKelly Guo <kellyguo123@hotmail.com>
Co-authored-by: 's avatarchengronglai <chengrongl@nvidia.com>
Co-authored-by: 's avatarpulkitg01 <pulkitg@nvidia.com>
Co-authored-by: 's avatarConnor Smith <cosmith@nvidia.com>
Co-authored-by: 's avatarAshwin Varghese Kuruttukulam <ashwinvk@nvidia.com>
Co-authored-by: 's avatarlotusl-code <lotusl@nvidia.com>
parent fd805c27
......@@ -45,6 +45,7 @@ import torch
import carb
import omni
from isaacsim.core.utils.stage import get_current_stage
from omni.kit.viewport.utility import get_viewport_from_window_name
from omni.kit.viewport.utility.camera_state import ViewportCameraState
from pxr import Gf, Sdf
......@@ -110,7 +111,7 @@ class H1RoughDemo:
def create_camera(self):
"""Creates a camera to be used for third-person view."""
stage = omni.usd.get_context().get_stage()
stage = get_current_stage()
self.viewport = get_viewport_from_window_name("Viewport")
# Create camera
self.camera_path = "/World/Camera"
......
......@@ -19,6 +19,8 @@ from __future__ import annotations
import argparse
from isaacsim.core.utils.stage import get_current_stage
from isaaclab.app import AppLauncher
# add argparse arguments
......@@ -37,7 +39,6 @@ simulation_app = app_launcher.app
import random
import omni.usd
from pxr import Gf, Sdf
import isaaclab.sim as sim_utils
......@@ -69,8 +70,8 @@ from isaaclab_assets.robots.anymal import ANYDRIVE_3_LSTM_ACTUATOR_CFG # isort:
def randomize_shape_color(prim_path_expr: str):
"""Randomize the color of the geometry."""
# acquire stage
stage = omni.usd.get_context().get_stage()
# get stage handle
stage = get_current_stage()
# resolve prim paths for spawning and cloning
prim_paths = sim_utils.find_matching_prim_paths(prim_path_expr)
# manually clone prims if the source prim path is a regex expression
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
......@@ -68,6 +68,7 @@ import isaacsim.core.utils.prims as prim_utils
from isaacsim.core.api.simulation_context import SimulationContext
from isaacsim.core.cloner import GridCloner
from isaacsim.core.utils.carb import set_carb_setting
from isaacsim.core.utils.stage import get_current_stage
from isaaclab.utils import Timer
from isaaclab.utils.assets import check_file_path
......@@ -82,6 +83,10 @@ def main():
sim = SimulationContext(
stage_units_in_meters=1.0, physics_dt=0.01, rendering_dt=0.01, backend="torch", device="cuda:0"
)
# get stage handle
stage = get_current_stage()
# enable fabric which avoids passing data over to USD structure
# this speeds up the read-write operation of GPU buffers
if sim.get_physics_context().use_gpu_pipeline:
......@@ -94,7 +99,7 @@ def main():
set_carb_setting(sim._settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
# Create interface to clone the scene
cloner = GridCloner(spacing=args_cli.spacing)
cloner = GridCloner(spacing=args_cli.spacing, stage=stage)
cloner.define_base_env("/World/envs")
prim_utils.define_prim("/World/envs/env_0")
# Spawn things into stage
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
......@@ -24,11 +24,14 @@ simulation_app = app_launcher.app
import numpy as np
import torch
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.actuators import ImplicitActuatorCfg
from isaaclab.assets import AssetBaseCfg
from isaaclab.assets.articulation import ArticulationCfg
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
JETBOT_CONFIG = ArticulationCfg(
......@@ -160,13 +163,16 @@ def run_simulator(sim: sim_utils.SimulationContext, scene: InteractiveScene):
def main():
"""Main function."""
# Initialize the simulation context
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
sim.set_camera_view([3.5, 0.0, 3.2], [0.0, 0.0, 0.5])
# design scene
# Design scene
scene_cfg = NewRobotsSceneCfg(args_cli.num_envs, env_spacing=2.0)
scene = InteractiveScene(scene_cfg)
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene = InteractiveScene(scene_cfg)
attach_stage_to_usd_context()
# Play the simulator
sim.reset()
# Now we are ready!
......
......@@ -35,10 +35,12 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.assets import Articulation
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
##
# Pre-defined configs
......@@ -121,12 +123,14 @@ def run_simulator(sim: sim_utils.SimulationContext, entities: dict[str, Articula
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 0.0, 4.0], [0.0, 0.0, 2.0])
# Design scene
scene_entities, scene_origins = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities, scene_origins = design_scene()
attach_stage_to_usd_context()
scene_origins = torch.tensor(scene_origins, device=sim.device)
# Play the simulator
sim.reset()
......
......@@ -36,11 +36,13 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
import isaaclab.utils.math as math_utils
from isaaclab.assets import DeformableObject, DeformableObjectCfg
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
def design_scene():
......@@ -146,12 +148,14 @@ def run_simulator(sim: sim_utils.SimulationContext, entities: dict[str, Deformab
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view(eye=[3.0, 0.0, 1.0], target=[0.0, 0.0, 0.5])
# Design scene
scene_entities, scene_origins = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities, scene_origins = design_scene()
attach_stage_to_usd_context()
scene_origins = torch.tensor(scene_origins, device=sim.device)
# Play the simulator
sim.reset()
......
......@@ -36,11 +36,13 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
import isaaclab.utils.math as math_utils
from isaaclab.assets import RigidObject, RigidObjectCfg
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
def design_scene():
......@@ -126,12 +128,14 @@ def run_simulator(sim: sim_utils.SimulationContext, entities: dict[str, RigidObj
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view(eye=[1.5, 0.0, 1.0], target=[0.0, 0.0, 0.0])
# Design scene
scene_entities, scene_origins = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities, scene_origins = design_scene()
attach_stage_to_usd_context()
scene_origins = torch.tensor(scene_origins, device=sim.device)
# Play the simulator
sim.reset()
......
......@@ -35,10 +35,13 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.assets import ArticulationCfg, AssetBaseCfg
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils import configclass
##
......@@ -110,13 +113,16 @@ def run_simulator(sim: sim_utils.SimulationContext, scene: InteractiveScene):
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 0.0, 4.0], [0.0, 0.0, 2.0])
# Design scene
scene_cfg = CartpoleSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)
scene = InteractiveScene(scene_cfg)
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene = InteractiveScene(scene_cfg)
attach_stage_to_usd_context()
# Play the simulator
sim.reset()
# Now we are ready!
......
......@@ -141,6 +141,7 @@ def main():
env_cfg = CartpoleEnvCfg()
env_cfg.scene.num_envs = args_cli.num_envs
env_cfg.sim.device = args_cli.device
env_cfg.sim.create_stage_in_memory = True
# setup base environment
env = ManagerBasedEnv(cfg=env_cfg)
......
......@@ -314,7 +314,9 @@ def main():
"""Main function."""
# setup base environment
env = ManagerBasedEnv(cfg=CubeEnvCfg())
env_cfg = CubeEnvCfg()
env_cfg.sim.create_stage_in_memory = True
env = ManagerBasedEnv(cfg=env_cfg)
# setup target position commands
target_position = torch.rand(env.num_envs, 3, device=env.device) * 2
......
......@@ -205,6 +205,7 @@ def main():
"""Main function."""
# setup base environment
env_cfg = QuadrupedEnvCfg()
env_cfg.sim.create_stage_in_memory = True
env = ManagerBasedEnv(cfg=env_cfg)
# load level policy
......
......@@ -70,6 +70,7 @@ def main():
env_cfg.sim.device = args_cli.device
if args_cli.device == "cpu":
env_cfg.sim.use_fabric = False
env_cfg.sim.create_stage_in_memory = True
# create environment
env = ManagerBasedRLEnv(cfg=env_cfg)
......
......@@ -46,6 +46,7 @@ def main():
env_cfg = CartpoleEnvCfg()
env_cfg.scene.num_envs = args_cli.num_envs
env_cfg.sim.device = args_cli.device
env_cfg.sim.create_stage_in_memory = True
# setup RL environment
env = ManagerBasedRLEnv(cfg=env_cfg)
......
......@@ -41,10 +41,13 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.assets import ArticulationCfg, AssetBaseCfg
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg
from isaaclab.sensors import CameraCfg, ContactSensorCfg, RayCasterCfg, patterns
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils import configclass
##
......@@ -157,13 +160,16 @@ def main():
"""Main function."""
# Initialize the simulation context
sim_cfg = sim_utils.SimulationCfg(dt=0.005, device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(dt=0.005, device=args_cli.device, create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view(eye=[3.5, 3.5, 3.5], target=[0.0, 0.0, 0.0])
# design scene
# Design scene
scene_cfg = SensorsSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)
scene = InteractiveScene(scene_cfg)
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene = InteractiveScene(scene_cfg)
attach_stage_to_usd_context()
# Play the simulator
sim.reset()
# Now we are ready!
......
......@@ -35,6 +35,7 @@ simulation_app = app_launcher.app
import math
import torch
import isaacsim.core.utils.stage as stage_utils
import isaacsim.util.debug_draw._debug_draw as omni_debug_draw
import isaaclab.sim as sim_utils
......@@ -44,6 +45,7 @@ from isaaclab.markers import VisualizationMarkers
from isaaclab.markers.config import FRAME_MARKER_CFG
from isaaclab.sensors import FrameTransformer, FrameTransformerCfg, OffsetCfg
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
##
# Pre-defined configs
......@@ -164,12 +166,14 @@ def run_simulator(sim: sim_utils.SimulationContext, scene_entities: dict):
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(dt=0.005, device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(dt=0.005, device=args_cli.device, create_stage_in_memory=True)
sim = SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view(eye=[2.5, 2.5, 2.5], target=[0.0, 0.0, 0.0])
# Design the scene
scene_entities = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities = design_scene()
attach_stage_to_usd_context()
# Play the simulator
sim.reset()
# Now we are ready!
......
......@@ -34,10 +34,12 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.assets import RigidObject, RigidObjectCfg
from isaaclab.sensors.ray_caster import RayCaster, RayCasterCfg, patterns
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
from isaaclab.utils.timer import Timer
......@@ -130,12 +132,14 @@ def run_simulator(sim: sim_utils.SimulationContext, scene_entities: dict):
def main():
"""Main function."""
# Load simulation context
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([0.0, 15.0, 15.0], [0.0, 0.0, -2.5])
# Design the scene
scene_entities = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities = design_scene()
attach_stage_to_usd_context()
# Play simulator
sim.reset()
# Now we are ready!
......
......@@ -39,10 +39,12 @@ import os
import torch
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import omni.replicator.core as rep
import isaaclab.sim as sim_utils
from isaaclab.sensors.ray_caster import RayCasterCamera, RayCasterCameraCfg, patterns
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils import convert_dict_to_backend
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
from isaaclab.utils.math import project_points, unproject_depth
......@@ -163,11 +165,14 @@ def run_simulator(sim: sim_utils.SimulationContext, scene_entities: dict):
def main():
"""Main function."""
# Load kit helper
sim = sim_utils.SimulationContext()
sim_cfg = sim_utils.SimulationCfg(create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 2.5, 3.5], [0.0, 0.0, 0.0])
# design the scene
scene_entities = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities = design_scene()
attach_stage_to_usd_context()
# Play simulator
sim.reset()
# Now we are ready!
......
......@@ -66,6 +66,7 @@ import random
import torch
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import omni.replicator.core as rep
import isaaclab.sim as sim_utils
......@@ -74,6 +75,7 @@ from isaaclab.markers import VisualizationMarkers
from isaaclab.markers.config import RAY_CASTER_MARKER_CFG
from isaaclab.sensors.camera import Camera, CameraCfg
from isaaclab.sensors.camera.utils import create_pointcloud_from_depth
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils import convert_dict_to_backend
......@@ -268,12 +270,14 @@ def run_simulator(sim: sim_utils.SimulationContext, scene_entities: dict):
def main():
"""Main function."""
# Load simulation context
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(device=args_cli.device, create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
# design the scene
scene_entities = design_scene()
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene_entities = design_scene()
attach_stage_to_usd_context()
# Play simulator
sim.reset()
# Now we are ready!
......
......@@ -39,6 +39,8 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.assets import AssetBaseCfg
from isaaclab.controllers import DifferentialIKController, DifferentialIKControllerCfg
......@@ -46,6 +48,7 @@ from isaaclab.managers import SceneEntityCfg
from isaaclab.markers import VisualizationMarkers
from isaaclab.markers.config import FRAME_MARKER_CFG
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils import configclass
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
from isaaclab.utils.math import subtract_frame_transforms
......@@ -190,13 +193,16 @@ def run_simulator(sim: sim_utils.SimulationContext, scene: InteractiveScene):
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device, create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
# Design scene
scene_cfg = TableTopSceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)
scene = InteractiveScene(scene_cfg)
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene = InteractiveScene(scene_cfg)
attach_stage_to_usd_context()
# Play the simulator
sim.reset()
# Now we are ready!
......
......@@ -38,6 +38,8 @@ simulation_app = app_launcher.app
import torch
import isaacsim.core.utils.stage as stage_utils
import isaaclab.sim as sim_utils
from isaaclab.assets import Articulation, AssetBaseCfg
from isaaclab.controllers import OperationalSpaceController, OperationalSpaceControllerCfg
......@@ -45,6 +47,7 @@ from isaaclab.markers import VisualizationMarkers
from isaaclab.markers.config import FRAME_MARKER_CFG
from isaaclab.scene import InteractiveScene, InteractiveSceneCfg
from isaaclab.sensors import ContactSensorCfg
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils import configclass
from isaaclab.utils.math import (
combine_frame_transforms,
......@@ -462,13 +465,16 @@ def convert_to_task_frame(osc: OperationalSpaceController, command: torch.tensor
def main():
"""Main function."""
# Load kit helper
sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device)
sim_cfg = sim_utils.SimulationCfg(dt=0.01, device=args_cli.device, create_stage_in_memory=True)
sim = sim_utils.SimulationContext(sim_cfg)
# Set main camera
sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
# Design scene
scene_cfg = SceneCfg(num_envs=args_cli.num_envs, env_spacing=2.0)
scene = InteractiveScene(scene_cfg)
# Create scene with stage in memory and then attach to USD context
with stage_utils.use_stage(sim.get_initial_stage()):
scene = InteractiveScene(scene_cfg)
attach_stage_to_usd_context()
# Play the simulator
sim.reset()
# Now we are ready!
......
[package]
# Note: Semantic Versioning is used: https://semver.org/
version = "0.41.21"
version = "0.42.21"
# Description
title = "Isaac Lab framework for Robot Learning"
......
Changelog
---------
0.41.21 (2025-06-25)
0.42.21 (2025-06-25)
~~~~~~~~~~~~~~~~~~~~
Added
......@@ -12,7 +12,7 @@ Added
env instance
0.41.20 (2025-07-11)
0.42.20 (2025-07-11)
~~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -22,7 +22,7 @@ Fixed
restricting the resetting joint indices be that user defined joint indices.
0.41.19 (2025-07-11)
0.42.19 (2025-07-11)
~~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -32,7 +32,7 @@ Fixed
env_ids are passed.
0.41.18 (2025-07-09)
0.42.18 (2025-07-09)
~~~~~~~~~~~~~~~~~~~~
Added
......@@ -49,7 +49,7 @@ Fixed
buffer on recording.
0.41.17 (2025-07-10)
0.42.17 (2025-07-10)
~~~~~~~~~~~~~~~~~~~~
Added
......@@ -80,7 +80,7 @@ Changed
* Changed the implementation of :func:`~isaaclab.utils.math.copysign` to better reflect the documented functionality.
0.41.16 (2025-07-08)
0.42.16 (2025-07-08)
~~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -90,7 +90,7 @@ Fixed
:class:`~isaaclab.assets.articulation.RigidObjectCollectionData`
0.41.15 (2025-07-08)
0.42.15 (2025-07-08)
~~~~~~~~~~~~~~~~~~~~
Added
......@@ -99,7 +99,7 @@ Added
* Added ability to set platform height independent of object height for trimesh terrains.
0.41.14 (2025-07-01)
0.42.14 (2025-07-01)
~~~~~~~~~~~~~~~~~~~~
Added
......@@ -110,7 +110,7 @@ Added
* Added deprecation warnings to the existing :attr:`max_height_noise` but still functions.
0.41.13 (2025-07-03)
0.42.13 (2025-07-03)
~~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -119,7 +119,7 @@ Fixed
* Fixed unittest tests that are floating inside pytests for articulation and rendering
0.41.12 (2025-07-03)
0.42.12 (2025-07-03)
~~~~~~~~~~~~~~~~~~~~
Changed
......@@ -129,7 +129,7 @@ Changed
videos with the ``--video`` flag.
0.41.11 (2025-06-27)
0.42.11 (2025-06-27)
~~~~~~~~~~~~~~~~~~~~
Added
......@@ -144,7 +144,7 @@ Fixed
* Fixed the implementation mistake in :func:`~isaaclab.utils.math.quat_inv`.
0.41.10 (2025-06-25)
0.42.10 (2025-06-25)
~~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -153,7 +153,7 @@ Fixed
* Fixed :func:`~isaaclab.utils.dict.update_class_from_dict` preventing setting flat Iterables with different lengths.
0.41.9 (2025-06-25)
0.42.9 (2025-06-25)
~~~~~~~~~~~~~~~~~~~
Added
......@@ -163,7 +163,7 @@ Added
sampling, which is now the default behavior. If set to False, the previous behavior of sharing the same bias value across all components is retained.
0.41.8 (2025-06-18)
0.42.8 (2025-06-18)
~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -175,7 +175,7 @@ Fixed
* added pytest that check against these data consistencies
0.41.7 (2025-06-24)
0.42.7 (2025-06-24)
~~~~~~~~~~~~~~~~~~~
Added
......@@ -189,12 +189,16 @@ Changed
* Renamed :func:`~isaaclab.utils.noise.NoiseModel.apply` method to :func:`~isaaclab.utils.noise.NoiseModel.__call__`.
<<<<<<< HEAD
<<<<<<< HEAD
0.40.6 (2025-06-12)
=======
0.41.6 (2025-06-12)
>>>>>>> cf094c211f (Updates to Isaac Sim 5.0 (#379))
=======
0.42.6 (2025-06-12)
>>>>>>> b048c33739 (Adds support for Stage in Memory (#375))
~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -203,7 +207,7 @@ Fixed
* Fixed potential issues in :func:`~isaaclab.envs.mdp.events.randomize_visual_texture_material` related to handling visual prims during texture randomization.
0.41.5 (2025-05-22)
0.42.5 (2025-05-22)
~~~~~~~~~~~~~~~~~~~
Fixed
......@@ -213,7 +217,7 @@ Fixed
currently has limitations for CPU simulation. Collision filtering needs to be manually enabled when using CPU simulation.
0.41.4 (2025-06-03)
0.42.4 (2025-06-03)
~~~~~~~~~~~~~~~~~~~
Changed
......@@ -224,7 +228,7 @@ Changed
passed in the ``TerrainGeneratorCfg``.
0.41.3 (2025-03-20)
0.42.3 (2025-03-20)
~~~~~~~~~~~~~~~~~~~
Changed
......@@ -239,7 +243,7 @@ Changed
more readable.
0.41.2 (2025-05-10)
0.42.2 (2025-05-31)
~~~~~~~~~~~~~~~~~~~
Added
......@@ -249,7 +253,7 @@ Added
* Added support for specifying module:task_name as task name to avoid module import for ``gym.make``
0.41.1 (2025-06-02)
0.42.1 (2025-06-02)
~~~~~~~~~~~~~~~~~~~
Added
......@@ -265,6 +269,16 @@ Changed
to make it available for mdp functions.
0.42.0 (2025-06-02)
~~~~~~~~~~~~~~~~~~~
Added
^^^^^
* Added support for stage in memory and cloning in fabric. This will help improve performance for scene setup and lower
overall startup time.
0.41.0 (2025-05-19)
~~~~~~~~~~~~~~~~~~~
......
......@@ -13,7 +13,6 @@ from collections.abc import Sequence
from prettytable import PrettyTable
from typing import TYPE_CHECKING
import isaacsim.core.utils.stage as stage_utils
import omni.log
import omni.physics.tensors.impl.api as physx
from isaacsim.core.simulation_manager import SimulationManager
......@@ -1578,14 +1577,13 @@ class Articulation(AssetBase):
self._spatial_tendon_names = list()
# parse fixed tendons properties if they exist
if self.num_fixed_tendons > 0 or self.num_spatial_tendons > 0:
stage = stage_utils.get_current_stage()
joint_paths = self.root_physx_view.dof_paths[0]
# iterate over all joints to find tendons attached to them
for j in range(self.num_joints):
usd_joint_path = joint_paths[j]
# check whether joint has tendons - tendon name follows the joint name it is attached to
joint = UsdPhysics.Joint.Get(stage, usd_joint_path)
joint = UsdPhysics.Joint.Get(self.stage, usd_joint_path)
if joint.GetPrim().HasAPI(PhysxSchema.PhysxTendonAxisRootAPI):
joint_name = usd_joint_path.split("/")[-1]
self._fixed_tendon_names.append(joint_name)
......
......@@ -18,6 +18,7 @@ import isaacsim.core.utils.prims as prim_utils
import omni.kit.app
import omni.timeline
from isaacsim.core.simulation_manager import IsaacEvents, SimulationManager
from isaacsim.core.utils.stage import get_current_stage
import isaaclab.sim as sim_utils
......@@ -69,6 +70,8 @@ class AssetBase(ABC):
self.cfg = cfg.copy()
# flag for whether the asset is initialized
self._is_initialized = False
# get stage handle
self.stage = get_current_stage()
# check if base asset path is valid
# note: currently the spawner does not work if there is a regex pattern in the leaf
......
......@@ -7,6 +7,7 @@ import torch
import weakref
import omni.physics.tensors.impl.api as physx
from isaacsim.core.utils.stage import get_current_stage_id
import isaaclab.utils.math as math_utils
from isaaclab.utils.buffers import TimestampedBuffer
......@@ -51,7 +52,8 @@ class RigidObjectData:
self._sim_timestamp = 0.0
# Obtain global physics sim view
physics_sim_view = physx.create_simulation_view("torch")
stage_id = get_current_stage_id()
physics_sim_view = physx.create_simulation_view("torch", stage_id)
physics_sim_view.set_subspace_roots("/")
gravity = physics_sim_view.get_gravity()
# Convert to direction vector
......
......@@ -7,6 +7,7 @@ import torch
import weakref
import omni.physics.tensors.impl.api as physx
from isaacsim.core.utils.stage import get_current_stage_id
import isaaclab.utils.math as math_utils
from isaaclab.utils.buffers import TimestampedBuffer
......@@ -54,7 +55,8 @@ class RigidObjectCollectionData:
self._sim_timestamp = 0.0
# Obtain global physics sim view
physics_sim_view = physx.create_simulation_view("torch")
stage_id = get_current_stage_id()
physics_sim_view = physx.create_simulation_view("torch", stage_id)
physics_sim_view.set_subspace_roots("/")
gravity = physics_sim_view.get_gravity()
# Convert to direction vector
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
......@@ -17,6 +17,7 @@ from collections.abc import Sequence
from dataclasses import MISSING
from typing import Any, ClassVar
import isaacsim.core.utils.stage as stage_utils
import isaacsim.core.utils.torch as torch_utils
import omni.kit.app
import omni.log
......@@ -25,6 +26,7 @@ from isaacsim.core.version import get_version
from isaaclab.managers import EventManager
from isaaclab.scene import InteractiveScene
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils.noise import NoiseModel
from isaaclab.utils.timer import Timer
......@@ -117,8 +119,10 @@ class DirectMARLEnv(gym.Env):
# generate scene
with Timer("[INFO]: Time taken for scene creation", "scene_creation"):
self.scene = InteractiveScene(self.cfg.scene)
self._setup_scene()
with stage_utils.use_stage(self.sim.get_initial_stage()):
self.scene = InteractiveScene(self.cfg.scene)
self._setup_scene()
attach_stage_to_usd_context()
print("[INFO]: Scene manager: ", self.scene)
# set up camera viewport controller
......
......@@ -17,6 +17,7 @@ from collections.abc import Sequence
from dataclasses import MISSING
from typing import Any, ClassVar
import isaacsim.core.utils.stage as stage_utils
import isaacsim.core.utils.torch as torch_utils
import omni.kit.app
import omni.log
......@@ -26,6 +27,7 @@ from isaacsim.core.version import get_version
from isaaclab.managers import EventManager
from isaaclab.scene import InteractiveScene
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.utils.noise import NoiseModel
from isaaclab.utils.timer import Timer
......@@ -123,8 +125,10 @@ class DirectRLEnv(gym.Env):
# generate scene
with Timer("[INFO]: Time taken for scene creation", "scene_creation"):
self.scene = InteractiveScene(self.cfg.scene)
self._setup_scene()
with stage_utils.use_stage(self.sim.get_initial_stage()):
self.scene = InteractiveScene(self.cfg.scene)
self._setup_scene()
attach_stage_to_usd_context()
print("[INFO]: Scene manager: ", self.scene)
# set up camera viewport controller
......
......@@ -8,6 +8,7 @@ import torch
from collections.abc import Sequence
from typing import Any
import isaacsim.core.utils.stage as stage_utils
import isaacsim.core.utils.torch as torch_utils
import omni.log
from isaacsim.core.simulation_manager import SimulationManager
......@@ -15,6 +16,7 @@ from isaacsim.core.simulation_manager import SimulationManager
from isaaclab.managers import ActionManager, EventManager, ObservationManager, RecorderManager
from isaaclab.scene import InteractiveScene
from isaaclab.sim import SimulationContext
from isaaclab.sim.utils import attach_stage_to_usd_context
from isaaclab.ui.widgets import ManagerLiveVisualizer
from isaaclab.utils.timer import Timer
......@@ -127,7 +129,10 @@ class ManagerBasedEnv:
# generate scene
with Timer("[INFO]: Time taken for scene creation", "scene_creation"):
self.scene = InteractiveScene(self.cfg.scene)
# get stage handle and set stage context
with stage_utils.use_stage(self.sim.get_initial_stage()):
self.scene = InteractiveScene(self.cfg.scene)
attach_stage_to_usd_context()
print("[INFO]: Scene manager: ", self.scene)
# set up camera viewport controller
......
......@@ -20,8 +20,8 @@ from typing import TYPE_CHECKING, Literal
import carb
import omni.physics.tensors.impl.api as physx
import omni.usd
from isaacsim.core.utils.extensions import enable_extension
from isaacsim.core.utils.stage import get_current_stage
from pxr import Gf, Sdf, UsdGeom, Vt
import isaaclab.sim as sim_utils
......@@ -92,7 +92,7 @@ def randomize_rigid_body_scale(
env_ids = env_ids.cpu()
# acquire stage
stage = omni.usd.get_context().get_stage()
stage = get_current_stage()
# resolve prim paths for spawning and cloning
prim_paths = sim_utils.find_matching_prim_paths(asset.cfg.prim_path)
......
......@@ -15,6 +15,7 @@ import isaacsim
import omni.kit.app
import omni.kit.commands
import omni.usd
from isaacsim.core.utils.stage import get_current_stage
from pxr import PhysxSchema, Sdf, Usd, UsdGeom, UsdPhysics
from isaaclab.ui.widgets import ManagerLiveVisualizer
......@@ -60,6 +61,9 @@ class BaseEnvWindow:
*self.env.scene.articulations.keys(),
]
# get stage handle
self.stage = get_current_stage()
# Listeners for environment selection changes
self._ui_listeners: list[ManagerLiveVisualizer] = []
......@@ -300,8 +304,7 @@ class BaseEnvWindow:
# stop the recording
_ = omni.kit.commands.execute("StopRecording")
# save the current stage
stage = omni.usd.get_context().get_stage()
source_layer = stage.GetRootLayer()
source_layer = self.stage.GetRootLayer()
# output the stage to a file
stage_usd_path = os.path.join(self.animation_log_dir, "Stage.usd")
source_prim_path = "/"
......@@ -311,8 +314,8 @@ class BaseEnvWindow:
temp_layer = Sdf.Layer.CreateNew(stage_usd_path)
temp_stage = Usd.Stage.Open(temp_layer)
# update stage data
UsdGeom.SetStageUpAxis(temp_stage, UsdGeom.GetStageUpAxis(stage))
UsdGeom.SetStageMetersPerUnit(temp_stage, UsdGeom.GetStageMetersPerUnit(stage))
UsdGeom.SetStageUpAxis(temp_stage, UsdGeom.GetStageUpAxis(self.stage))
UsdGeom.SetStageMetersPerUnit(temp_stage, UsdGeom.GetStageMetersPerUnit(self.stage))
# copy the prim
Sdf.CreatePrimInLayer(temp_layer, source_prim_path)
Sdf.CopySpec(source_layer, source_prim_path, temp_layer, source_prim_path)
......
......@@ -25,11 +25,14 @@ from dataclasses import MISSING
import isaacsim.core.utils.stage as stage_utils
import omni.kit.commands
import omni.log
import omni.physx.scripts.utils as physx_utils
from isaacsim.core.utils.stage import get_current_stage
from pxr import Gf, PhysxSchema, Sdf, Usd, UsdGeom, UsdPhysics, Vt
import isaaclab.sim as sim_utils
from isaaclab.sim.spawners import SpawnerCfg
from isaaclab.sim.utils import attach_stage_to_usd_context, is_current_stage_in_memory
from isaaclab.utils.configclass import configclass
from isaaclab.utils.math import convert_quat
......@@ -145,8 +148,8 @@ class VisualizationMarkers:
# get next free path for the prim
prim_path = stage_utils.get_next_free_path(cfg.prim_path)
# create a new prim
stage = stage_utils.get_current_stage()
self._instancer_manager = UsdGeom.PointInstancer.Define(stage, prim_path)
self.stage = get_current_stage()
self._instancer_manager = UsdGeom.PointInstancer.Define(self.stage, prim_path)
# store inputs
self.prim_path = prim_path
self.cfg = cfg
......@@ -395,6 +398,15 @@ class VisualizationMarkers:
child_prim.SetInstanceable(False)
# check if prim is a mesh -> if so, make it invisible to secondary rays
if child_prim.IsA(UsdGeom.Gprim):
# early attach stage to usd context if stage is in memory
# since stage in memory is not supported by the "ChangePropertyCommand" kit command
if is_current_stage_in_memory():
omni.log.warn(
"Attaching stage in memory to USD context early to support omni kit command during stage"
" creation."
)
attach_stage_to_usd_context()
# invisible to secondary rays such as depth images
omni.kit.commands.execute(
"ChangePropertyCommand",
......
......@@ -12,6 +12,7 @@ import omni.log
import omni.usd
from isaacsim.core.cloner import GridCloner
from isaacsim.core.prims import XFormPrim
from isaacsim.core.utils.stage import get_current_stage, get_current_stage_id
from pxr import PhysxSchema
import isaaclab.sim as sim_utils
......@@ -27,6 +28,7 @@ from isaaclab.assets import (
RigidObjectCollectionCfg,
)
from isaaclab.sensors import ContactSensorCfg, FrameTransformerCfg, SensorBase, SensorBaseCfg
from isaaclab.sim import SimulationContext
from isaaclab.terrains import TerrainImporter, TerrainImporterCfg
from .interactive_scene_cfg import InteractiveSceneCfg
......@@ -119,12 +121,14 @@ class InteractiveScene:
self._rigid_object_collections = dict()
self._sensors = dict()
self._extras = dict()
# obtain the current stage
self.stage = omni.usd.get_context().get_stage()
# get stage handle
self.sim = SimulationContext.instance()
self.stage = get_current_stage()
self.stage_id = get_current_stage_id()
# physics scene path
self._physics_scene_path = None
# prepare cloner for environment replication
self.cloner = GridCloner(spacing=self.cfg.env_spacing)
self.cloner = GridCloner(spacing=self.cfg.env_spacing, stage=self.stage)
self.cloner.define_base_env(self.env_ns)
self.env_prim_paths = self.cloner.generate_paths(f"{self.env_ns}/env", self.cfg.num_envs)
# create source prim
......
......@@ -154,9 +154,8 @@ class Camera(SensorBase):
" will be disabled in the current workflow and may lead to longer load times and increased memory"
" usage."
)
stage = omni.usd.get_context().get_stage()
with Sdf.ChangeBlock():
for prim in stage.Traverse():
for prim in self.stage.Traverse():
prim.SetInstanceable(False)
def __del__(self):
......@@ -421,12 +420,10 @@ class Camera(SensorBase):
self._render_product_paths: list[str] = list()
self._rep_registry: dict[str, list[rep.annotators.Annotator]] = {name: list() for name in self.cfg.data_types}
# Obtain current stage
stage = omni.usd.get_context().get_stage()
# Convert all encapsulated prims to Camera
for cam_prim_path in self._view.prim_paths:
# Get camera prim
cam_prim = stage.GetPrimAtPath(cam_prim_path)
cam_prim = self.stage.GetPrimAtPath(cam_prim_path)
# Check if prim is a camera
if not cam_prim.IsA(UsdGeom.Camera):
raise RuntimeError(f"Prim at path '{cam_prim_path}' is not a Camera.")
......
......@@ -13,7 +13,6 @@ from collections.abc import Sequence
from typing import TYPE_CHECKING, Any
import carb
import omni.usd
import warp as wp
from isaacsim.core.prims import XFormPrim
from isaacsim.core.version import get_version
......@@ -173,12 +172,10 @@ class TiledCamera(Camera):
# Create frame count buffer
self._frame = torch.zeros(self._view.count, device=self._device, dtype=torch.long)
# Obtain current stage
stage = omni.usd.get_context().get_stage()
# Convert all encapsulated prims to Camera
for cam_prim_path in self._view.prim_paths:
# Get camera prim
cam_prim = stage.GetPrimAtPath(cam_prim_path)
cam_prim = self.stage.GetPrimAtPath(cam_prim_path)
# Check if prim is a camera
if not cam_prim.IsA(UsdGeom.Camera):
raise RuntimeError(f"Prim at path '{cam_prim_path}' is not a Camera.")
......
......@@ -23,6 +23,7 @@ from typing import TYPE_CHECKING, Any
import omni.kit.app
import omni.timeline
from isaacsim.core.simulation_manager import IsaacEvents, SimulationManager
from isaacsim.core.utils.stage import get_current_stage
import isaaclab.sim as sim_utils
......@@ -59,6 +60,8 @@ class SensorBase(ABC):
self._is_initialized = False
# flag for whether the sensor is in visualization mode
self._is_visualizing = False
# get stage handle
self.stage = get_current_stage()
# note: Use weakref on callbacks to ensure that this object can be deleted when its destructor is called.
# add callbacks for stage play/stop
......
......@@ -8,9 +8,9 @@ from __future__ import annotations
import math
import isaacsim.core.utils.stage as stage_utils
import omni.log
import omni.physx.scripts.utils as physx_utils
from isaacsim.core.utils.stage import get_current_stage
from omni.physx.scripts import deformableUtils as deformable_utils
from pxr import PhysxSchema, Usd, UsdPhysics
......@@ -44,9 +44,10 @@ def define_articulation_root_properties(
ValueError: When the prim path is not valid.
TypeError: When the prim already has conflicting API schemas.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get articulation USD prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim path is valid
......@@ -102,9 +103,10 @@ def modify_articulation_root_properties(
Raises:
NotImplementedError: When the root prim is not a rigid body and a fixed joint is to be created.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get articulation USD prim
articulation_prim = stage.GetPrimAtPath(prim_path)
# check if prim has articulation applied on it
......@@ -204,9 +206,10 @@ def define_rigid_body_properties(
ValueError: When the prim path is not valid.
TypeError: When the prim already has conflicting API schemas.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim path is valid
......@@ -250,9 +253,10 @@ def modify_rigid_body_properties(
Returns:
True if the properties were successfully set, False otherwise.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get rigid-body USD prim
rigid_body_prim = stage.GetPrimAtPath(prim_path)
# check if prim has rigid-body applied on it
......@@ -299,9 +303,10 @@ def define_collision_properties(
Raises:
ValueError: When the prim path is not valid.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim path is valid
......@@ -343,9 +348,10 @@ def modify_collision_properties(
Returns:
True if the properties were successfully set, False otherwise.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
collider_prim = stage.GetPrimAtPath(prim_path)
# check if prim has collision applied on it
......@@ -390,9 +396,10 @@ def define_mass_properties(prim_path: str, cfg: schemas_cfg.MassPropertiesCfg, s
Raises:
ValueError: When the prim path is not valid.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim path is valid
......@@ -435,9 +442,10 @@ def modify_mass_properties(prim_path: str, cfg: schemas_cfg.MassPropertiesCfg, s
Returns:
True if the properties were successfully set, False otherwise.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
rigid_prim = stage.GetPrimAtPath(prim_path)
# check if prim has mass API applied on it
......@@ -478,9 +486,10 @@ def activate_contact_sensors(prim_path: str, threshold: float = 0.0, stage: Usd.
ValueError: If the input prim path is not valid.
ValueError: If there are no rigid bodies under the prim path.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get prim
prim: Usd.Prim = stage.GetPrimAtPath(prim_path)
# check if prim is valid
......@@ -564,9 +573,10 @@ def modify_joint_drive_properties(
Raises:
ValueError: If the input prim path is not valid.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim path is valid
......@@ -666,9 +676,10 @@ def modify_fixed_tendon_properties(
Raises:
ValueError: If the input prim path is not valid.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
tendon_prim = stage.GetPrimAtPath(prim_path)
# check if prim has fixed tendon applied on it
......@@ -734,7 +745,7 @@ def modify_spatial_tendon_properties(
"""
# obtain stage
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
tendon_prim = stage.GetPrimAtPath(prim_path)
# check if prim has spatial tendon applied on it
......@@ -792,9 +803,10 @@ def define_deformable_body_properties(
ValueError: When the prim path is not valid.
ValueError: When the prim has no mesh or multiple meshes.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get USD prim
prim = stage.GetPrimAtPath(prim_path)
# check if prim path is valid
......@@ -867,9 +879,9 @@ def modify_deformable_body_properties(
Returns:
True if the properties were successfully set, False otherwise.
"""
# obtain stage
# get stage handle
if stage is None:
stage = stage_utils.get_current_stage()
stage = get_current_stage()
# get deformable-body USD prim
deformable_body_prim = stage.GetPrimAtPath(prim_path)
......
......@@ -339,3 +339,9 @@ class SimulationCfg:
render: RenderCfg = RenderCfg()
"""Render settings. Default is RenderCfg()."""
create_stage_in_memory: bool = False
"""If stage is first created in memory and then attached to usd context for simulation and rendering.
Creating the stage in memory can reduce start-up time.
"""
......@@ -24,6 +24,7 @@ import flatdict
import isaacsim.core.utils.stage as stage_utils
import omni.log
import omni.physx
import omni.usd
from isaacsim.core.api.simulation_context import SimulationContext as _SimulationContext
from isaacsim.core.utils.carb import get_carb_setting, set_carb_setting
from isaacsim.core.utils.viewports import set_camera_view
......@@ -128,6 +129,12 @@ class SimulationContext(_SimulationContext):
if stage_utils.get_current_stage() is None:
raise RuntimeError("The stage has not been created. Did you run the simulator?")
# create stage in memory if requested
if self.cfg.create_stage_in_memory:
self._initial_stage = stage_utils.create_new_stage_in_memory()
else:
self._initial_stage = omni.usd.get_context().get_stage()
# acquire settings interface
self.carb_settings = carb.settings.get_settings()
......@@ -257,6 +264,7 @@ class SimulationContext(_SimulationContext):
sim_params=sim_params,
physics_prim_path=self.cfg.physics_prim_path,
device=self.cfg.device,
stage=self._initial_stage,
)
def _apply_physics_settings(self):
......@@ -526,6 +534,14 @@ class SimulationContext(_SimulationContext):
self.physics_sim_view.update_articulations_kinematic()
self._update_fabric(0.0, 0.0)
def get_initial_stage(self) -> Usd.Stage:
"""Returns stage handle used during scene creation.
Returns:
The stage used during scene creation.
"""
return self._initial_stage
"""
Operations - Override (standalone)
"""
......@@ -660,17 +676,18 @@ class SimulationContext(_SimulationContext):
def _init_stage(self, *args, **kwargs) -> Usd.Stage:
_ = super()._init_stage(*args, **kwargs)
# a stage update here is needed for the case when physics_dt != rendering_dt, otherwise the app crashes
# when in headless mode
self.set_setting("/app/player/playSimulations", False)
self._app.update()
self.set_setting("/app/player/playSimulations", True)
# set additional physx parameters and bind material
self._set_additional_physx_params()
# load flatcache/fabric interface
self._load_fabric_interface()
# return the stage
return self.stage
with stage_utils.use_stage(self.get_initial_stage()):
# a stage update here is needed for the case when physics_dt != rendering_dt, otherwise the app crashes
# when in headless mode
self.set_setting("/app/player/playSimulations", False)
self._app.update()
self.set_setting("/app/player/playSimulations", True)
# set additional physx parameters and bind material
self._set_additional_physx_params()
# load flatcache/fabric interface
self._load_fabric_interface()
# return the stage
return self.stage
async def _initialize_stage_async(self, *args, **kwargs) -> Usd.Stage:
await super()._initialize_stage_async(*args, **kwargs)
......
......@@ -8,7 +8,6 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import omni.kit.commands
import omni.log
from pxr import Gf, Sdf, Usd
......@@ -19,8 +18,16 @@ try:
except ModuleNotFoundError:
from pxr import Semantics
from isaacsim.core.utils.stage import get_current_stage
from isaaclab.sim import converters, schemas
from isaaclab.sim.utils import bind_physics_material, bind_visual_material, clone, select_usd_variants
from isaaclab.sim.utils import (
bind_physics_material,
bind_visual_material,
clone,
is_current_stage_in_memory,
select_usd_variants,
)
if TYPE_CHECKING:
from . import from_files_cfg
......@@ -166,18 +173,28 @@ def spawn_ground_plane(
# Change the color of the plane
# Warning: This is specific to the default grid plane asset.
if cfg.color is not None:
prop_path = f"{prim_path}/Looks/theGrid/Shader.inputs:diffuse_tint"
# change the color
omni.kit.commands.execute(
"ChangePropertyCommand",
prop_path=Sdf.Path(prop_path),
value=Gf.Vec3f(*cfg.color),
prev=None,
type_to_create_if_not_exist=Sdf.ValueTypeNames.Color3f,
)
# avoiding this step if stage is in memory since the "ChangePropertyCommand" kit command
# is not supported in stage in memory
if is_current_stage_in_memory():
omni.log.warn(
"Ground plane color modification is not supported while the stage is in memory. Skipping operation."
)
else:
prop_path = f"{prim_path}/Looks/theGrid/Shader.inputs:diffuse_tint"
# change the color
omni.kit.commands.execute(
"ChangePropertyCommand",
prop_path=Sdf.Path(prop_path),
value=Gf.Vec3f(*cfg.color),
prev=None,
type_to_create_if_not_exist=Sdf.ValueTypeNames.Color3f,
)
# Remove the light from the ground plane
# It isn't bright enough and messes up with the user's lighting settings
omni.kit.commands.execute("ToggleVisibilitySelectedPrims", selected_paths=[f"{prim_path}/SphereLight"])
stage = get_current_stage()
omni.kit.commands.execute("ToggleVisibilitySelectedPrims", selected_paths=[f"{prim_path}/SphereLight"], stage=stage)
prim = prim_utils.get_prim_at_path(prim_path)
# Apply semantic tags
......@@ -231,8 +248,10 @@ def _spawn_from_usd_file(
Raises:
FileNotFoundError: If the USD file does not exist at the given path.
"""
# get stage handle
stage = get_current_stage()
# check file path exists
stage: Usd.Stage = stage_utils.get_current_stage()
if not stage.ResolveIdentifierToEditTarget(usd_path):
raise FileNotFoundError(f"USD file not found at path: '{usd_path}'.")
# spawn asset if it doesn't exist.
......
......@@ -8,7 +8,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
from isaacsim.core.utils.stage import get_current_stage
from pxr import PhysxSchema, Usd, UsdPhysics, UsdShade
from isaaclab.sim.utils import clone, safe_set_attribute_on_usd_schema
......@@ -41,9 +41,12 @@ def spawn_rigid_body_material(prim_path: str, cfg: physics_materials_cfg.RigidBo
Raises:
ValueError: When a prim already exists at the specified prim path and is not a material.
"""
# get stage handle
stage = get_current_stage()
# create material prim if no prim exists
if not prim_utils.is_prim_path_valid(prim_path):
_ = UsdShade.Material.Define(stage_utils.get_current_stage(), prim_path)
_ = UsdShade.Material.Define(stage, prim_path)
# obtain prim
prim = prim_utils.get_prim_at_path(prim_path)
......@@ -99,9 +102,12 @@ def spawn_deformable_body_material(prim_path: str, cfg: physics_materials_cfg.De
.. _PxFEMSoftBodyMaterial: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/_api_build/structPxFEMSoftBodyMaterialModel.html
"""
# get stage handle
stage = get_current_stage()
# create material prim if no prim exists
if not prim_utils.is_prim_path_valid(prim_path):
_ = UsdShade.Material.Define(stage_utils.get_current_stage(), prim_path)
_ = UsdShade.Material.Define(stage, prim_path)
# obtain prim
prim = prim_utils.get_prim_at_path(prim_path)
......
......@@ -9,9 +9,15 @@ from typing import TYPE_CHECKING
import isaacsim.core.utils.prims as prim_utils
import omni.kit.commands
import omni.log
from pxr import Usd
from isaaclab.sim.utils import clone, safe_set_attribute_on_usd_prim
from isaaclab.sim.utils import (
attach_stage_to_usd_context,
clone,
is_current_stage_in_memory,
safe_set_attribute_on_usd_prim,
)
from isaaclab.utils.assets import NVIDIA_NUCLEUS_DIR
if TYPE_CHECKING:
......@@ -48,9 +54,19 @@ def spawn_preview_surface(prim_path: str, cfg: visual_materials_cfg.PreviewSurfa
"""
# spawn material if it doesn't exist.
if not prim_utils.is_prim_path_valid(prim_path):
# early attach stage to usd context if stage is in memory
# since stage in memory is not supported by the "CreatePreviewSurfaceMaterialPrim" kit command
if is_current_stage_in_memory():
omni.log.warn(
"Attaching stage in memory to USD context early to support an operation which doesn't support stage in"
" memory."
)
attach_stage_to_usd_context()
omni.kit.commands.execute("CreatePreviewSurfaceMaterialPrim", mtl_path=prim_path, select_new_prim=False)
else:
raise ValueError(f"A prim already exists at path: '{prim_path}'.")
# obtain prim
prim = prim_utils.get_prim_at_path(f"{prim_path}/Shader")
# apply properties
......@@ -58,7 +74,7 @@ def spawn_preview_surface(prim_path: str, cfg: visual_materials_cfg.PreviewSurfa
del cfg["func"]
for attr_name, attr_value in cfg.items():
safe_set_attribute_on_usd_prim(prim, f"inputs:{attr_name}", attr_value, camel_case=True)
# return prim
return prim
......@@ -93,6 +109,15 @@ def spawn_from_mdl_file(prim_path: str, cfg: visual_materials_cfg.MdlMaterialCfg
"""
# spawn material if it doesn't exist.
if not prim_utils.is_prim_path_valid(prim_path):
# early attach stage to usd context if stage is in memory
# since stage in memory is not supported by the "CreateMdlMaterialPrim" kit command
if is_current_stage_in_memory():
omni.log.warn(
"Attaching stage in memory to USD context early to support an operation which doesn't support stage in"
" memory."
)
attach_stage_to_usd_context()
# extract material name from path
material_name = cfg.mdl_path.split("/")[-1].split(".")[0]
omni.kit.commands.execute(
......
......@@ -12,7 +12,7 @@ import omni.kit.commands
import omni.log
from pxr import Sdf, Usd
from isaaclab.sim.utils import clone
from isaaclab.sim.utils import attach_stage_to_usd_context, clone, is_current_stage_in_memory
from isaaclab.utils import to_camel_case
if TYPE_CHECKING:
......@@ -88,6 +88,15 @@ def spawn_camera(
# lock camera from viewport (this disables viewport movement for camera)
if cfg.lock_camera:
# early attach stage to usd context if stage is in memory
# since stage in memory is not supported by the "ChangePropertyCommand" kit command
if is_current_stage_in_memory():
omni.log.warn(
"Attaching stage in memory to USD context early to support an operation which doesn't support stage in"
" memory."
)
attach_stage_to_usd_context()
omni.kit.commands.execute(
"ChangePropertyCommand",
prop_path=Sdf.Path(f"{prim_path}.omni:kit:cameraLock"),
......
......@@ -12,6 +12,7 @@ from typing import TYPE_CHECKING
import carb
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
from isaacsim.core.utils.stage import get_current_stage
from pxr import Sdf, Usd
import isaaclab.sim as sim_utils
......@@ -42,6 +43,9 @@ def spawn_multi_asset(
Returns:
The created prim at the first prim path.
"""
# get stage handle
stage = get_current_stage()
# resolve: {SPAWN_NS}/AssetName
# note: this assumes that the spawn namespace already exists in the stage
root_path, asset_path = prim_path.rsplit("/", 1)
......@@ -88,9 +92,6 @@ def spawn_multi_asset(
# resolve prim paths for spawning and cloning
prim_paths = [f"{source_prim_path}/{asset_path}" for source_prim_path in source_prim_paths]
# acquire stage
stage = stage_utils.get_current_stage()
# manually clone prims if the source prim path is a regex expression
# note: unlike in the cloner API from Isaac Sim, we do not "reset" xforms on the copied prims.
# This is because the "spawn" calls during the creation of the proto prims already handles this operation.
......
This diff is collapsed.
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
"""Launch Isaac Sim Simulator first."""
from isaaclab.app import AppLauncher
# launch omniverse app
simulation_app = AppLauncher(headless=True, enable_cameras=True).app
"""Rest everything follows."""
import isaacsim.core.utils.prims as prim_utils
import isaacsim.core.utils.stage as stage_utils
import omni
import omni.physx
import omni.usd
import pytest
import usdrt
from isaacsim.core.cloner import GridCloner
import isaaclab.sim as sim_utils
from isaaclab.sim.simulation_context import SimulationCfg, SimulationContext
from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR
@pytest.fixture
def sim():
"""Create a simulation context."""
cfg = SimulationCfg(create_stage_in_memory=True)
sim = SimulationContext(cfg=cfg)
stage_utils.update_stage()
yield sim
omni.physx.get_physx_simulation_interface().detach_stage()
sim.stop()
sim.clear()
sim.clear_all_callbacks()
sim.clear_instance()
"""
Tests
"""
def test_stage_in_memory_with_shapes(sim):
"""Test spawning of shapes with stage in memory."""
# define parameters
num_clones = 10
# grab stage in memory and set as current stage via the with statement
stage_in_memory = sim.get_initial_stage()
with stage_utils.use_stage(stage_in_memory):
# create cloned cone stage
for i in range(num_clones):
prim_utils.create_prim(f"/World/env_{i}", "Xform", translation=(i, i, 0))
cfg = sim_utils.MultiAssetSpawnerCfg(
assets_cfg=[
sim_utils.ConeCfg(
radius=0.3,
height=0.6,
),
sim_utils.CuboidCfg(
size=(0.3, 0.3, 0.3),
),
sim_utils.SphereCfg(
radius=0.3,
),
],
random_choice=True,
rigid_props=sim_utils.RigidBodyPropertiesCfg(
solver_position_iteration_count=4, solver_velocity_iteration_count=0
),
mass_props=sim_utils.MassPropertiesCfg(mass=1.0),
collision_props=sim_utils.CollisionPropertiesCfg(),
)
prim_path_regex = "/World/env_.*/Cone"
cfg.func(prim_path_regex, cfg)
# verify stage is in memory
assert sim_utils.is_current_stage_in_memory()
# verify prims exist in stage in memory
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) == num_clones
# verify prims do not exist in context stage
context_stage = omni.usd.get_context().get_stage()
with stage_utils.use_stage(context_stage):
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) != num_clones
# attach stage to context
sim_utils.attach_stage_to_usd_context()
# verify stage is no longer in memory
assert not sim_utils.is_current_stage_in_memory()
# verify prims now exist in context stage
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) == num_clones
def test_stage_in_memory_with_usds(sim):
"""Test spawning of USDs with stage in memory."""
# define parameters
num_clones = 10
usd_paths = [
f"{ISAACLAB_NUCLEUS_DIR}/Robots/ANYbotics/ANYmal-C/anymal_c.usd",
f"{ISAACLAB_NUCLEUS_DIR}/Robots/ANYbotics/ANYmal-D/anymal_d.usd",
]
# grab stage in memory and set as current stage via the with statement
stage_in_memory = sim.get_initial_stage()
with stage_utils.use_stage(stage_in_memory):
# create cloned robot stage
for i in range(num_clones):
prim_utils.create_prim(f"/World/env_{i}", "Xform", translation=(i, i, 0))
cfg = sim_utils.MultiUsdFileCfg(
usd_path=usd_paths,
random_choice=True,
rigid_props=sim_utils.RigidBodyPropertiesCfg(
disable_gravity=False,
retain_accelerations=False,
linear_damping=0.0,
angular_damping=0.0,
max_linear_velocity=1000.0,
max_angular_velocity=1000.0,
max_depenetration_velocity=1.0,
),
articulation_props=sim_utils.ArticulationRootPropertiesCfg(
enabled_self_collisions=True, solver_position_iteration_count=4, solver_velocity_iteration_count=0
),
activate_contact_sensors=True,
)
prim_path_regex = "/World/env_.*/Robot"
cfg.func(prim_path_regex, cfg)
# verify stage is in memory
assert sim_utils.is_current_stage_in_memory()
# verify prims exist in stage in memory
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) == num_clones
# verify prims do not exist in context stage
context_stage = omni.usd.get_context().get_stage()
with stage_utils.use_stage(context_stage):
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) != num_clones
# attach stage to context
sim_utils.attach_stage_to_usd_context()
# verify stage is no longer in memory
assert not sim_utils.is_current_stage_in_memory()
# verify prims now exist in context stage
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) == num_clones
def test_stage_in_memory_with_clone_in_fabric(sim):
"""Test cloning in fabric with stage in memory."""
# define parameters
usd_path = f"{ISAACLAB_NUCLEUS_DIR}/Robots/ANYbotics/ANYmal-C/anymal_c.usd"
num_clones = 100
# grab stage in memory and set as current stage via the with statement
stage_in_memory = sim.get_initial_stage()
with stage_utils.use_stage(stage_in_memory):
# set up paths
base_env_path = "/World/envs"
source_prim_path = f"{base_env_path}/env_0"
# create cloner
cloner = GridCloner(spacing=3, stage=stage_in_memory)
cloner.define_base_env(base_env_path)
# create source prim
prim_utils.create_prim(f"{source_prim_path}/Robot", "Xform", usd_path=usd_path)
# generate target paths
target_paths = cloner.generate_paths("/World/envs/env", num_clones)
# clone robots at target paths
cloner.clone(
source_prim_path=source_prim_path,
base_env_path=base_env_path,
prim_paths=target_paths,
replicate_physics=True,
clone_in_fabric=True,
)
prim_path_regex = "/World/envs/env_.*"
# verify prims do not exist in context stage
context_stage = omni.usd.get_context().get_stage()
with stage_utils.use_stage(context_stage):
prims = prim_utils.find_matching_prim_paths(prim_path_regex)
assert len(prims) != num_clones
# attach stage to context
sim_utils.attach_stage_to_usd_context()
# verify stage is no longer in memory
assert not sim_utils.is_current_stage_in_memory()
# verify prims now exist in fabric stage using usdrt apis
stage_id = stage_utils.get_current_stage_id()
usdrt_stage = usdrt.Usd.Stage.Attach(stage_id)
for i in range(num_clones):
prim = usdrt_stage.GetPrimAtPath(f"/World/envs/env_{i}/Robot")
assert prim.IsValid()
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2022-2025, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2024-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2024-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2024-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
......@@ -8,14 +8,14 @@ from __future__ import annotations
import torch
import omni.usd
# from Isaac Sim 4.2 onwards, pxr.Semantics is deprecated
try:
import Semantics
except ModuleNotFoundError:
from pxr import Semantics
from isaacsim.core.utils.stage import get_current_stage
import isaaclab.sim as sim_utils
from isaaclab.assets import Articulation, RigidObject
from isaaclab.scene import InteractiveSceneCfg
......@@ -78,7 +78,7 @@ class ShadowHandVisionEnv(InHandManipulationEnv):
self.object = RigidObject(self.cfg.object_cfg)
self._tiled_camera = TiledCamera(self.cfg.tiled_camera)
# get stage
stage = omni.usd.get_context().get_stage()
stage = get_current_stage()
# add semantics for in-hand cube
prim = stage.GetPrimAtPath("/World/envs/env_0/object")
sem = Semantics.SemanticsAPI.Apply(prim, "Semantics")
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
# Copyright (c) 2022-2025, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025, The Isaac Lab Project Developers.
# All rights reserved.
#
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment