Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scripts/benchmarks/benchmark_non_rl.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def main(env_cfg: ManagerBasedRLEnvCfg | DirectRLEnvCfg | DirectMARLEnvCfg, agen
# override configurations with non-hydra CLI arguments
env_cfg.scene.num_envs = args_cli.num_envs if args_cli.num_envs is not None else env_cfg.scene.num_envs
env_cfg.sim.device = args_cli.device if args_cli.device is not None else env_cfg.sim.device
env_cfg.seed = args_cli.seed if args_cli.seed is not None else env_cfg.sim.seed

# process distributed
world_size = 1
Expand Down
2 changes: 1 addition & 1 deletion source/isaaclab/config/extension.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

# Note: Semantic Versioning is used: https://semver.org/
version = "0.46.3"
version = "0.46.4"

# Description
title = "Isaac Lab framework for Robot Learning"
Expand Down
11 changes: 11 additions & 0 deletions source/isaaclab/docs/CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Changelog
---------

0.46.4 (2025-10-06)
~~~~~~~~~~~~~~~~~~~

Changed
^^^^^^^

* Fixed :attr:`~isaaclab.sim.simulation_context.SimulationContext.device` to return the device from the configuration.
Previously, it was returning the device from the simulation manager, which was causing a performance overhead.


0.46.3 (2025-09-17)
~~~~~~~~~~~~~~~~~~~

Expand All @@ -10,6 +20,7 @@ Added
* Modified setter to support for viscous and dynamic joint friction coefficients in articulation based on IsaacSim 5.0.
* Added randomization of viscous and dynamic joint friction coefficients in event term.


0.46.2 (2025-09-13)
~~~~~~~~~~~~~~~~~~~

Expand Down
264 changes: 146 additions & 118 deletions source/isaaclab/isaaclab/sim/simulation_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import omni.physx
import omni.usd
from isaacsim.core.api.simulation_context import SimulationContext as _SimulationContext
from isaacsim.core.simulation_manager import SimulationManager
from isaacsim.core.utils.carb import get_carb_setting, set_carb_setting
from isaacsim.core.utils.viewports import set_camera_view
from isaacsim.core.version import get_version
Expand Down Expand Up @@ -259,6 +260,19 @@ def __init__(self, cfg: SimulationCfg | None = None):
" simulation step size if you run into physics issues."
)

# set simulation device
# note: Although Isaac Sim sets the physics device in the init function,
# it does a render call which gets the wrong device.
SimulationManager.set_physics_sim_device(self.cfg.device)

# obtain the parsed device
# This device should be the same as "self.cfg.device". However, for cases, where users specify the device
# as "cuda" and not "cuda:X", then it fetches the current device from SimulationManager.
# Note: Since we fix the device from the configuration and don't expect users to change it at runtime,
# we can obtain the device once from the SimulationManager.get_physics_sim_device() function.
# This reduces the overhead of calling the function.
self._physics_device = SimulationManager.get_physics_sim_device()

# create a simulation context to control the simulator
if float(".".join(self._isaacsim_version[2])) < 5:
# stage arg is not supported before isaac sim 5.0
Expand All @@ -283,126 +297,19 @@ def __init__(self, cfg: SimulationCfg | None = None):
stage=self._initial_stage,
)

def _apply_physics_settings(self):
"""Sets various carb physics settings."""
# enable hydra scene-graph instancing
# note: this allows rendering of instanceable assets on the GUI
set_carb_setting(self.carb_settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
# change dispatcher to use the default dispatcher in PhysX SDK instead of carb tasking
# note: dispatcher handles how threads are launched for multi-threaded physics
set_carb_setting(self.carb_settings, "/physics/physxDispatcher", True)
# disable contact processing in omni.physx
# note: we disable it by default to avoid the overhead of contact processing when it isn't needed.
# The physics flag gets enabled when a contact sensor is created.
if hasattr(self.cfg, "disable_contact_processing"):
omni.log.warn(
"The `disable_contact_processing` attribute is deprecated and always set to True"
" to avoid unnecessary overhead. Contact processing is automatically enabled when"
" a contact sensor is created, so manual configuration is no longer required."
)
# FIXME: From investigation, it seems this flag only affects CPU physics. For GPU physics, contacts
# are always processed. The issue is reported to the PhysX team by @mmittal.
set_carb_setting(self.carb_settings, "/physics/disableContactProcessing", True)
# disable custom geometry for cylinder and cone collision shapes to allow contact reporting for them
# reason: cylinders and cones aren't natively supported by PhysX so we need to use custom geometry flags
# reference: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Geometry.html?highlight=capsule#geometry
set_carb_setting(self.carb_settings, "/physics/collisionConeCustomGeometry", False)
set_carb_setting(self.carb_settings, "/physics/collisionCylinderCustomGeometry", False)
# hide the Simulation Settings window
set_carb_setting(self.carb_settings, "/physics/autoPopupSimulationOutputWindow", False)

def _apply_render_settings_from_cfg(self):
"""Sets rtx settings specified in the RenderCfg."""

# define mapping of user-friendly RenderCfg names to native carb names
rendering_setting_name_mapping = {
"enable_translucency": "/rtx/translucency/enabled",
"enable_reflections": "/rtx/reflections/enabled",
"enable_global_illumination": "/rtx/indirectDiffuse/enabled",
"enable_dlssg": "/rtx-transient/dlssg/enabled",
"enable_dl_denoiser": "/rtx-transient/dldenoiser/enabled",
"dlss_mode": "/rtx/post/dlss/execMode",
"enable_direct_lighting": "/rtx/directLighting/enabled",
"samples_per_pixel": "/rtx/directLighting/sampledLighting/samplesPerPixel",
"enable_shadows": "/rtx/shadows/enabled",
"enable_ambient_occlusion": "/rtx/ambientOcclusion/enabled",
}

not_carb_settings = ["rendering_mode", "carb_settings", "antialiasing_mode"]

# grab the rendering mode using the following priority:
# 1. command line argument --rendering_mode, if provided
# 2. rendering_mode from Render Config, if set
# 3. lastly, default to "balanced" mode, if neither is specified
rendering_mode = get_carb_setting(self.carb_settings, "/isaaclab/rendering/rendering_mode")
if not rendering_mode:
rendering_mode = self.cfg.render.rendering_mode
if not rendering_mode:
rendering_mode = "balanced"

# set preset settings (same behavior as the CLI arg --rendering_mode)
if rendering_mode is not None:
# check if preset is supported
supported_rendering_modes = ["performance", "balanced", "quality"]
if rendering_mode not in supported_rendering_modes:
raise ValueError(
f"RenderCfg rendering mode '{rendering_mode}' not in supported modes {supported_rendering_modes}."
)

# grab isaac lab apps path
isaaclab_app_exp_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), *[".."] * 4, "apps")
# for Isaac Sim 4.5 compatibility, we use the 4.5 rendering mode app files in a different folder
if float(".".join(self._isaacsim_version[2])) < 5:
isaaclab_app_exp_path = os.path.join(isaaclab_app_exp_path, "isaacsim_4_5")

# grab preset settings
preset_filename = os.path.join(isaaclab_app_exp_path, f"rendering_modes/{rendering_mode}.kit")
with open(preset_filename) as file:
preset_dict = toml.load(file)
preset_dict = dict(flatdict.FlatDict(preset_dict, delimiter="."))

# set presets
for key, value in preset_dict.items():
key = "/" + key.replace(".", "/") # convert to carb setting format
set_carb_setting(self.carb_settings, key, value)

# set user-friendly named settings
for key, value in vars(self.cfg.render).items():
if value is None or key in not_carb_settings:
# skip unset settings and non-carb settings
continue
if key not in rendering_setting_name_mapping:
raise ValueError(
f"'{key}' in RenderCfg not found. Note: internal 'rendering_setting_name_mapping' dictionary might"
" need to be updated."
)
key = rendering_setting_name_mapping[key]
set_carb_setting(self.carb_settings, key, value)

# set general carb settings
carb_settings = self.cfg.render.carb_settings
if carb_settings is not None:
for key, value in carb_settings.items():
if "_" in key:
key = "/" + key.replace("_", "/") # convert from python variable style string
elif "." in key:
key = "/" + key.replace(".", "/") # convert from .kit file style string
if get_carb_setting(self.carb_settings, key) is None:
raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.")
set_carb_setting(self.carb_settings, key, value)
"""
Properties - Override.
"""

# set denoiser mode
if self.cfg.render.antialiasing_mode is not None:
try:
import omni.replicator.core as rep
@property
def device(self) -> str:
"""Device used by the simulation.

rep.settings.set_render_rtx_realtime(antialiasing=self.cfg.render.antialiasing_mode)
except Exception:
pass

# WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased.
if get_carb_setting(self.carb_settings, "/rtx/rendermode").lower() == "raytracedlighting":
set_carb_setting(self.carb_settings, "/rtx/rendermode", "RaytracedLighting")
Note:
In Omniverse, it is possible to configure multiple GPUs for rendering, while physics engine
operates on a single GPU. This function returns the device that is used for physics simulation.
"""
return self._physics_device

"""
Operations - New.
Expand Down Expand Up @@ -742,6 +649,127 @@ def clear_instance(cls):
Helper Functions
"""

def _apply_physics_settings(self):
"""Sets various carb physics settings."""
# enable hydra scene-graph instancing
# note: this allows rendering of instanceable assets on the GUI
set_carb_setting(self.carb_settings, "/persistent/omnihydra/useSceneGraphInstancing", True)
# change dispatcher to use the default dispatcher in PhysX SDK instead of carb tasking
# note: dispatcher handles how threads are launched for multi-threaded physics
set_carb_setting(self.carb_settings, "/physics/physxDispatcher", True)
# disable contact processing in omni.physx
# note: we disable it by default to avoid the overhead of contact processing when it isn't needed.
# The physics flag gets enabled when a contact sensor is created.
if hasattr(self.cfg, "disable_contact_processing"):
omni.log.warn(
"The `disable_contact_processing` attribute is deprecated and always set to True"
" to avoid unnecessary overhead. Contact processing is automatically enabled when"
" a contact sensor is created, so manual configuration is no longer required."
)
# FIXME: From investigation, it seems this flag only affects CPU physics. For GPU physics, contacts
# are always processed. The issue is reported to the PhysX team by @mmittal.
set_carb_setting(self.carb_settings, "/physics/disableContactProcessing", True)
# disable custom geometry for cylinder and cone collision shapes to allow contact reporting for them
# reason: cylinders and cones aren't natively supported by PhysX so we need to use custom geometry flags
# reference: https://nvidia-omniverse.github.io/PhysX/physx/5.4.1/docs/Geometry.html?highlight=capsule#geometry
set_carb_setting(self.carb_settings, "/physics/collisionConeCustomGeometry", False)
set_carb_setting(self.carb_settings, "/physics/collisionCylinderCustomGeometry", False)
# hide the Simulation Settings window
set_carb_setting(self.carb_settings, "/physics/autoPopupSimulationOutputWindow", False)

def _apply_render_settings_from_cfg(self):
"""Sets rtx settings specified in the RenderCfg."""

# define mapping of user-friendly RenderCfg names to native carb names
rendering_setting_name_mapping = {
"enable_translucency": "/rtx/translucency/enabled",
"enable_reflections": "/rtx/reflections/enabled",
"enable_global_illumination": "/rtx/indirectDiffuse/enabled",
"enable_dlssg": "/rtx-transient/dlssg/enabled",
"enable_dl_denoiser": "/rtx-transient/dldenoiser/enabled",
"dlss_mode": "/rtx/post/dlss/execMode",
"enable_direct_lighting": "/rtx/directLighting/enabled",
"samples_per_pixel": "/rtx/directLighting/sampledLighting/samplesPerPixel",
"enable_shadows": "/rtx/shadows/enabled",
"enable_ambient_occlusion": "/rtx/ambientOcclusion/enabled",
}

not_carb_settings = ["rendering_mode", "carb_settings", "antialiasing_mode"]

# grab the rendering mode using the following priority:
# 1. command line argument --rendering_mode, if provided
# 2. rendering_mode from Render Config, if set
# 3. lastly, default to "balanced" mode, if neither is specified
rendering_mode = get_carb_setting(self.carb_settings, "/isaaclab/rendering/rendering_mode")
if not rendering_mode:
rendering_mode = self.cfg.render.rendering_mode
if not rendering_mode:
rendering_mode = "balanced"

# set preset settings (same behavior as the CLI arg --rendering_mode)
if rendering_mode is not None:
# check if preset is supported
supported_rendering_modes = ["performance", "balanced", "quality"]
if rendering_mode not in supported_rendering_modes:
raise ValueError(
f"RenderCfg rendering mode '{rendering_mode}' not in supported modes {supported_rendering_modes}."
)

# grab isaac lab apps path
isaaclab_app_exp_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), *[".."] * 4, "apps")
# for Isaac Sim 4.5 compatibility, we use the 4.5 rendering mode app files in a different folder
if float(".".join(self._isaacsim_version[2])) < 5:
isaaclab_app_exp_path = os.path.join(isaaclab_app_exp_path, "isaacsim_4_5")

# grab preset settings
preset_filename = os.path.join(isaaclab_app_exp_path, f"rendering_modes/{rendering_mode}.kit")
with open(preset_filename) as file:
preset_dict = toml.load(file)
preset_dict = dict(flatdict.FlatDict(preset_dict, delimiter="."))

# set presets
for key, value in preset_dict.items():
key = "/" + key.replace(".", "/") # convert to carb setting format
set_carb_setting(self.carb_settings, key, value)

# set user-friendly named settings
for key, value in vars(self.cfg.render).items():
if value is None or key in not_carb_settings:
# skip unset settings and non-carb settings
continue
if key not in rendering_setting_name_mapping:
raise ValueError(
f"'{key}' in RenderCfg not found. Note: internal 'rendering_setting_name_mapping' dictionary might"
" need to be updated."
)
key = rendering_setting_name_mapping[key]
set_carb_setting(self.carb_settings, key, value)

# set general carb settings
carb_settings = self.cfg.render.carb_settings
if carb_settings is not None:
for key, value in carb_settings.items():
if "_" in key:
key = "/" + key.replace("_", "/") # convert from python variable style string
elif "." in key:
key = "/" + key.replace(".", "/") # convert from .kit file style string
if get_carb_setting(self.carb_settings, key) is None:
raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.")
set_carb_setting(self.carb_settings, key, value)

# set denoiser mode
if self.cfg.render.antialiasing_mode is not None:
try:
import omni.replicator.core as rep

rep.settings.set_render_rtx_realtime(antialiasing=self.cfg.render.antialiasing_mode)
except Exception:
pass

# WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased.
if get_carb_setting(self.carb_settings, "/rtx/rendermode").lower() == "raytracedlighting":
set_carb_setting(self.carb_settings, "/rtx/rendermode", "RaytracedLighting")

def _set_additional_physx_params(self):
"""Sets additional PhysX parameters that are not directly supported by the parent class."""
# obtain the physics scene api
Expand Down
Loading