diff --git a/source/isaaclab/isaaclab/app/__init__.py b/source/isaaclab/isaaclab/app/__init__.py index 9e9b53b2f37..2c513d437f8 100644 --- a/source/isaaclab/isaaclab/app/__init__.py +++ b/source/isaaclab/isaaclab/app/__init__.py @@ -9,7 +9,9 @@ * Ability to launch the simulation app with different configurations * Run tests with the simulation app +* Settings manager for storing configuration in both Omniverse and standalone modes """ from .app_launcher import AppLauncher # noqa: F401, F403 +from .settings_manager import SettingsManager, get_settings_manager, initialize_carb_settings # noqa: F401, F403 diff --git a/source/isaaclab/isaaclab/app/app_launcher.py b/source/isaaclab/isaaclab/app/app_launcher.py index 01c915b0af0..d780334e25d 100644 --- a/source/isaaclab/isaaclab/app/app_launcher.py +++ b/source/isaaclab/isaaclab/app/app_launcher.py @@ -21,10 +21,20 @@ import sys from typing import Any, Literal +import flatdict + +# Import the settings manager for non-Omniverse mode +from .settings_manager import get_settings_manager, initialize_carb_settings + +# Conditionally import SimulationApp only when needed (for omniverse visualizer) +# This allows running Isaac Lab with Rerun/Newton visualizers without the full Omniverse stack +_SIMULATION_APP_AVAILABLE = False +_SimulationApp = None + with contextlib.suppress(ModuleNotFoundError): import isaacsim # noqa: F401 - -from isaacsim import SimulationApp + from isaacsim import SimulationApp as _SimulationApp + _SIMULATION_APP_AVAILABLE = True # import logger logger = logging.getLogger(__name__) @@ -127,37 +137,66 @@ def __init__(self, launcher_args: argparse.Namespace | dict | None = None, **kwa # Integrate env-vars and input keyword args into simulation app config self._config_resolution(launcher_args) - # Internal: Override SimulationApp._start_app method to apply patches after app has started. - self.__patch_simulation_start_app(launcher_args) - - # Create SimulationApp, passing the resolved self._config to it for initialization - self._create_app() - # Load IsaacSim extensions - self._load_extensions() - # Hide the stop button in the toolbar - self._hide_stop_button() - # Set settings from the given rendering mode - self._set_rendering_mode_settings(launcher_args) - # Set animation recording settings - self._set_animation_recording_settings(launcher_args) - - # Hide play button callback if the timeline is stopped - import omni.timeline - - self._hide_play_button_callback = ( - omni.timeline.get_timeline_interface() - .get_timeline_event_stream() - .create_subscription_to_pop_by_type( - int(omni.timeline.TimelineEventType.STOP), lambda e: self._hide_play_button(True) + # Determine if SimulationApp (Omniverse) is needed + # Only launch SimulationApp if: + # 1. Omniverse visualizer is explicitly requested OR + # 2. No specific visualizers are requested but livestreaming is enabled OR + # 3. No specific visualizers are requested and GUI is needed (not headless) + self._omniverse_required = self._check_if_omniverse_required() + + # Get the global settings manager + self._settings_manager = get_settings_manager() + + if self._omniverse_required: + if not _SIMULATION_APP_AVAILABLE: + raise RuntimeError( + "SimulationApp is required for the requested configuration but isaacsim module is not available. " + "Please ensure Isaac Sim is properly installed." + ) + + print("[INFO][AppLauncher]: Omniverse mode - Launching SimulationApp...") + + # Internal: Override SimulationApp._start_app method to apply patches after app has started. + self.__patch_simulation_start_app(launcher_args) + + # Create SimulationApp, passing the resolved self._config to it for initialization + self._create_app() + + # Initialize carb.settings integration in the settings manager + initialize_carb_settings() + + # Load IsaacSim extensions + self._load_extensions() + # Hide the stop button in the toolbar + self._hide_stop_button() + # Set settings from the given rendering mode + self._set_rendering_mode_settings(launcher_args) + # Set animation recording settings + self._set_animation_recording_settings(launcher_args) + + # Hide play button callback if the timeline is stopped + import omni.timeline + + self._hide_play_button_callback = ( + omni.timeline.get_timeline_interface() + .get_timeline_event_stream() + .create_subscription_to_pop_by_type( + int(omni.timeline.TimelineEventType.STOP), lambda e: self._hide_play_button(True) + ) ) - ) - self._unhide_play_button_callback = ( - omni.timeline.get_timeline_interface() - .get_timeline_event_stream() - .create_subscription_to_pop_by_type( - int(omni.timeline.TimelineEventType.PLAY), lambda e: self._hide_play_button(False) + self._unhide_play_button_callback = ( + omni.timeline.get_timeline_interface() + .get_timeline_event_stream() + .create_subscription_to_pop_by_type( + int(omni.timeline.TimelineEventType.PLAY), lambda e: self._hide_play_button(False) + ) ) - ) + else: + print("[INFO][AppLauncher]: Standalone mode - Running without SimulationApp (Rerun/Newton visualizers only)...") + self._app = None + # Store settings in the standalone settings manager + self._store_settings_standalone() + # Set up signal handlers for graceful shutdown # -- during explicit `kill` commands signal.signal(signal.SIGTERM, self._abort_signal_handle_callback) @@ -170,12 +209,30 @@ def __init__(self, launcher_args: argparse.Namespace | dict | None = None, **kwa """ @property - def app(self) -> SimulationApp: - """The launched SimulationApp.""" - if self._app is not None: - return self._app + def app(self) -> Any: + """The launched SimulationApp (or None if running in standalone mode). + + Returns: + SimulationApp instance if Omniverse mode is active, None if running in standalone mode. + """ + if self._omniverse_required: + if self._app is not None: + return self._app + else: + raise RuntimeError("The `AppLauncher.app` member cannot be retrieved until the class is initialized.") else: - raise RuntimeError("The `AppLauncher.app` member cannot be retrieved until the class is initialized.") + # Standalone mode - no SimulationApp + return None + + @property + def visualizer(self) -> list[str] | None: + """The visualizer backend(s) to use. + + Returns: + List of visualizer backend names (e.g., ["rerun", "newton"]) or None if no visualizers specified. + Empty list means no visualizers should be initialized. + """ + return self._visualizer @property def visualizer(self) -> list[str] | None: @@ -512,6 +569,56 @@ def _check_argparser_config_params(config: dict) -> None: # Print out values which will be used print(f"[INFO][AppLauncher]: The argument '{key}' will be used to configure the SimulationApp.") + def _check_if_omniverse_required(self) -> bool: + """Check if SimulationApp (Omniverse) needs to be launched. + + TODO: this will also need to check RTX renderer and kit app renderer in the future. + + Returns: + True if SimulationApp is required, False if can run in standalone mode. + """ + # Omniverse is required if: + # 1. Omniverse visualizer is explicitly requested + # 2. Livestreaming is enabled (requires Omniverse) + # 3. Cameras are enabled (requires Omniverse for rendering) + + # Omniverse visualizer explicitly requested + if self._visualizer is not None and "omniverse" in self._visualizer: + return True + + # Livestreaming requires Omniverse + if self._livestream >= 1: + return True + + # Cameras enabled requires Omniverse for RTX rendering + if self._enable_cameras: + return True + + # Otherwise, we can run in standalone mode (headless with rerun/newton, or just headless) + # If no visualizer is specified and not headless, we still assume headless mode (standalone) + return False + + def _store_settings_standalone(self): + """Store settings in the standalone settings manager (non-Omniverse mode). + + This replicates the settings that would normally be stored via carb.settings. + """ + # Store render settings + self._settings_manager.set_bool("/isaaclab/render/offscreen", self._offscreen_render) + self._settings_manager.set_bool("/isaaclab/render/active_viewport", getattr(self, "_render_viewport", False)) + self._settings_manager.set_bool("/isaaclab/render/rtx_sensors", False) + + # Store visualizer settings + if self._visualizer is not None: + self._settings_manager.set_string("/isaaclab/visualizer", ",".join(self._visualizer)) + else: + self._settings_manager.set_string("/isaaclab/visualizer", "") + + print(f"[INFO][AppLauncher]: Standalone settings stored:") + print(f" - visualizer: {self._visualizer}") + print(f" - offscreen_render: {self._offscreen_render}") + print(f" - headless: {self._headless}") + def _config_resolution(self, launcher_args: dict): """Resolve the input arguments and environment variables. @@ -880,7 +987,7 @@ def _create_app(self): if "--verbose" not in sys.argv and "--info" not in sys.argv: sys.stdout = open(os.devnull, "w") # noqa: SIM115 # launch simulation app - self._app = SimulationApp(self._sim_app_config, experience=self._sim_experience_file) + self._app = _SimulationApp(self._sim_app_config, experience=self._sim_experience_file) # enable sys stdout and stderr sys.stdout = sys.__stdout__ @@ -904,41 +1011,41 @@ def _rendering_enabled(self) -> bool: def _load_extensions(self): """Load correct extensions based on AppLauncher's resolved config member variables.""" - # These have to be loaded after SimulationApp is initialized - import carb - - # Retrieve carb settings for modification - carb_settings_iface = carb.settings.get_settings() - - # set carb setting to indicate Isaac Lab's offscreen_render pipeline should be enabled + # These have to be loaded after SimulationApp is initialized (if in Omniverse mode) + # In standalone mode, we just store settings + + # Store settings using the settings manager (works in both Omniverse and standalone mode) + # set setting to indicate Isaac Lab's offscreen_render pipeline should be enabled # this flag is used by the SimulationContext class to enable the offscreen_render pipeline # when the render() method is called. - carb_settings_iface.set_bool("/isaaclab/render/offscreen", self._offscreen_render) + self._settings_manager.set_bool("/isaaclab/render/offscreen", self._offscreen_render) - # set carb setting to indicate Isaac Lab's render_viewport pipeline should be enabled + # set setting to indicate Isaac Lab's render_viewport pipeline should be enabled # this flag is used by the SimulationContext class to enable the render_viewport pipeline # when the render() method is called. - carb_settings_iface.set_bool("/isaaclab/render/active_viewport", self._render_viewport) + self._settings_manager.set_bool("/isaaclab/render/active_viewport", self._render_viewport) - # set carb setting to indicate no RTX sensors are used + # set setting to indicate no RTX sensors are used # this flag is set to True when an RTX-rendering related sensor is created # for example: the `Camera` sensor class - carb_settings_iface.set_bool("/isaaclab/render/rtx_sensors", False) + self._settings_manager.set_bool("/isaaclab/render/rtx_sensors", False) - # set carb setting to store the visualizer backend(s) specified via command-line + # set setting to store the visualizer backend(s) specified via command-line # this allows SimulationContext to filter visualizers based on the --visualizer flag - # Store as comma-separated string for carb settings compatibility + # Store as comma-separated string for settings compatibility if self._visualizer is not None: - carb_settings_iface.set_string("/isaaclab/visualizer", ",".join(self._visualizer)) + self._settings_manager.set_string("/isaaclab/visualizer", ",".join(self._visualizer)) else: - carb_settings_iface.set_string("/isaaclab/visualizer", "") + self._settings_manager.set_string("/isaaclab/visualizer", "") - # set fabric update flag to disable updating transforms when rendering is disabled - carb_settings_iface.set_bool("/physics/fabricUpdateTransformations", self._rendering_enabled()) + # Only set Omniverse-specific settings if running in Omniverse mode + if self._settings_manager.is_omniverse_mode: + # set fabric update flag to disable updating transforms when rendering is disabled + self._settings_manager.set_bool("/physics/fabricUpdateTransformations", self._rendering_enabled()) - # in theory, this should ensure that dt is consistent across time stepping, but this is not the case - # for now, we use the custom loop runner from Isaac Sim to achieve this - carb_settings_iface.set_bool("/app/player/useFixedTimeStepping", False) + # in theory, this should ensure that dt is consistent across time stepping, but this is not the case + # for now, we use the custom loop runner from Isaac Sim to achieve this + self._settings_manager.set_bool("/app/player/useFixedTimeStepping", False) def _hide_stop_button(self): """Hide the stop button in the toolbar. @@ -1003,8 +1110,9 @@ def _set_animation_recording_settings(self, launcher_args: dict) -> None: def _interrupt_signal_handle_callback(self, signal, frame): """Handle the interrupt signal from the keyboard.""" - # close the app - self._app.close() + # close the app (if running in Omniverse mode) + if self._app is not None: + self._app.close() # raise the error for keyboard interrupt raise KeyboardInterrupt @@ -1027,8 +1135,9 @@ def _hide_play_button(self, flag): def _abort_signal_handle_callback(self, signal, frame): """Handle the abort/segmentation/kill signals.""" - # close the app - self._app.close() + # close the app (if running in Omniverse mode) + if self._app is not None: + self._app.close() def __patch_simulation_start_app(self, launcher_args: dict): if not launcher_args.get("enable_pinocchio", False): diff --git a/source/isaaclab/isaaclab/app/settings_manager.py b/source/isaaclab/isaaclab/app/settings_manager.py new file mode 100644 index 00000000000..764374f972b --- /dev/null +++ b/source/isaaclab/isaaclab/app/settings_manager.py @@ -0,0 +1,161 @@ +# 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 + +"""Settings manager for Isaac Lab that works with or without Omniverse carb.settings. + +This module provides a unified settings interface that can work in two modes: +1. Omniverse mode: Uses carb.settings when SimulationApp is launched +2. Standalone mode: Uses pure Python dictionary when running without Omniverse + +This allows Isaac Lab to run visualizers like Rerun and Newton without requiring +the full Omniverse/SimulationApp stack. +""" + +from typing import Any + + +class SettingsManager: + """A settings manager that provides a carb.settings-like interface without requiring Omniverse. + + This class can work in two modes: + - Standalone mode: Uses a Python dictionary to store settings + - Omniverse mode: Delegates to carb.settings when available + + The interface is designed to be compatible with the carb.settings API. + """ + + def __init__(self): + """Initialize the settings manager.""" + self._standalone_settings: dict[str, Any] = {} + self._carb_settings = None + self._use_carb = False + + def initialize_carb_settings(self): + """Initialize carb.settings if SimulationApp has been launched. + + This should be called after SimulationApp is created to enable + Omniverse mode. If not called, the manager operates in standalone mode. + """ + try: + import carb + self._carb_settings = carb.settings.get_settings() + self._use_carb = True + except (ImportError, AttributeError): + # carb not available or SimulationApp not launched - use standalone mode + self._use_carb = False + + def set(self, path: str, value: Any) -> None: + """Set a setting value at the given path. + + Args: + path: The settings path (e.g., "/isaaclab/render/offscreen") + value: The value to set + """ + if self._use_carb and self._carb_settings is not None: + # Delegate to carb.settings + if isinstance(value, bool): + self._carb_settings.set_bool(path, value) + elif isinstance(value, int): + self._carb_settings.set_int(path, value) + elif isinstance(value, float): + self._carb_settings.set_float(path, value) + elif isinstance(value, str): + self._carb_settings.set_string(path, value) + else: + # For other types, try generic set + self._carb_settings.set(path, value) + else: + # Standalone mode - use dictionary + self._standalone_settings[path] = value + + def get(self, path: str, default: Any = None) -> Any: + """Get a setting value at the given path. + + Args: + path: The settings path (e.g., "/isaaclab/render/offscreen") + default: Default value to return if path doesn't exist + + Returns: + The value at the path, or default if not found + """ + if self._use_carb and self._carb_settings is not None: + # Delegate to carb.settings + value = self._carb_settings.get(path) + return value if value is not None else default + else: + # Standalone mode - use dictionary + return self._standalone_settings.get(path, default) + + def set_bool(self, path: str, value: bool) -> None: + """Set a boolean setting value. + + Args: + path: The settings path + value: The boolean value to set + """ + self.set(path, value) + + def set_int(self, path: str, value: int) -> None: + """Set an integer setting value. + + Args: + path: The settings path + value: The integer value to set + """ + self.set(path, value) + + def set_float(self, path: str, value: float) -> None: + """Set a float setting value. + + Args: + path: The settings path + value: The float value to set + """ + self.set(path, value) + + def set_string(self, path: str, value: str) -> None: + """Set a string setting value. + + Args: + path: The settings path + value: The string value to set + """ + self.set(path, value) + + @property + def is_omniverse_mode(self) -> bool: + """Check if the settings manager is using carb.settings (Omniverse mode). + + Returns: + True if using carb.settings, False if using standalone mode + """ + return self._use_carb + + +# Global settings manager instance +_global_settings_manager: SettingsManager | None = None + + +def get_settings_manager() -> SettingsManager: + """Get the global settings manager instance. + + Returns: + The global SettingsManager instance + """ + global _global_settings_manager + if _global_settings_manager is None: + _global_settings_manager = SettingsManager() + return _global_settings_manager + + +def initialize_carb_settings(): + """Initialize carb.settings integration for the global settings manager. + + This should be called after SimulationApp is created to enable + Omniverse mode for the global settings manager. + """ + manager = get_settings_manager() + manager.initialize_carb_settings() + diff --git a/source/isaaclab/isaaclab/assets/articulation/articulation.py b/source/isaaclab/isaaclab/assets/articulation/articulation.py index b9a45105a17..22cdda49256 100644 --- a/source/isaaclab/isaaclab/assets/articulation/articulation.py +++ b/source/isaaclab/isaaclab/assets/articulation/articulation.py @@ -15,7 +15,6 @@ from typing import TYPE_CHECKING, Literal import warp as wp -from isaacsim.core.simulation_manager import SimulationManager from newton import JointMode, JointType, Model from newton.selection import ArticulationView as NewtonArticulationView from newton.solvers import SolverMuJoCo @@ -1326,8 +1325,6 @@ def write_spatial_tendon_properties_to_sim( """ def _initialize_impl(self): - # obtain global simulation view - self._physics_sim_view = SimulationManager.get_physics_sim_view() if self.cfg.articulation_root_prim_path is not None: # The articulation root prim path is specified explicitly, so we can just use this. diff --git a/source/isaaclab/isaaclab/sim/simulation_context.py b/source/isaaclab/isaaclab/sim/simulation_context.py index f2c0ad16864..eba59d939d7 100644 --- a/source/isaaclab/isaaclab/sim/simulation_context.py +++ b/source/isaaclab/isaaclab/sim/simulation_context.py @@ -16,7 +16,8 @@ from contextlib import contextmanager from typing import Any -import carb +# Import settings manager for both Omniverse and standalone modes +from isaaclab.app.settings_manager import get_settings_manager import flatdict import omni.physx import omni.usd @@ -141,7 +142,8 @@ def __init__(self, cfg: SimulationCfg | None = None): self._initial_stage = omni.usd.get_context().get_stage() # acquire settings interface - self.carb_settings = carb.settings.get_settings() + # Use settings manager (works in both Omniverse and standalone modes) + self.settings = get_settings_manager() # apply carb physics settings SimulationManager._clear() @@ -150,29 +152,29 @@ def __init__(self, cfg: SimulationCfg | None = None): # note: we read this once since it is not expected to change during runtime # read flag for whether a local GUI is enabled self._local_gui = ( - self.carb_settings.get("/app/window/enabled") - if self.carb_settings.get("/app/window/enabled") is not None + self.settings.get("/app/window/enabled") + if self.settings.get("/app/window/enabled") is not None else False ) # read flag for whether livestreaming GUI is enabled self._livestream_gui = ( - self.carb_settings.get("/app/livestream/enabled") - if self.carb_settings.get("/app/livestream/enabled") is not None + self.settings.get("/app/livestream/enabled") + if self.settings.get("/app/livestream/enabled") is not None else False ) # read flag for whether XR GUI is enabled self._xr_gui = ( - self.carb_settings.get("/app/xr/enabled") - if self.carb_settings.get("/app/xr/enabled") is not None + self.settings.get("/app/xr/enabled") + if self.settings.get("/app/xr/enabled") is not None else False ) # read flag for whether the Isaac Lab viewport capture pipeline will be used, # casting None to False if the flag doesn't exist # this flag is set from the AppLauncher class - self._offscreen_render = bool(self.carb_settings.get("/isaaclab/render/offscreen")) + self._offscreen_render = bool(self.settings.get("/isaaclab/render/offscreen")) # read flag for whether the default viewport should be enabled - self._render_viewport = bool(self.carb_settings.get("/isaaclab/render/active_viewport")) + self._render_viewport = bool(self.settings.get("/isaaclab/render/active_viewport")) # flag for whether any GUI will be rendered (local, livestreamed or viewport) self._has_gui = self._local_gui or self._livestream_gui or self._xr_gui @@ -293,7 +295,7 @@ def __init__(self, cfg: SimulationCfg | None = None): device=self.cfg.device, stage=self._initial_stage, ) - self.carb_settings.set_bool("/app/player/playSimulations", False) + self.settings.set_bool("/app/player/playSimulations", False) NewtonManager.set_simulation_dt(self.cfg.dt) NewtonManager.set_solver_settings(newton_params) physx_sim_interface = omni.physx.get_physx_simulation_interface() @@ -308,7 +310,7 @@ 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 - self.carb_settings.set_bool("/persistent/omnihydra/useSceneGraphInstancing", True) + self.settings.set("/persistent/omnihydra/useSceneGraphInstancing", True) def _apply_render_settings_from_cfg(self): """Sets rtx settings specified in the RenderCfg.""" @@ -349,7 +351,7 @@ def _apply_render_settings_from_cfg(self): # set presets for key, value in preset_dict.items(): key = "/" + key.replace(".", "/") # convert to carb setting format - self.set_setting(key, value) + self.settings.set(key, value) # set user-friendly named settings for key, value in vars(self.cfg.render_cfg).items(): @@ -362,7 +364,7 @@ def _apply_render_settings_from_cfg(self): " need to be updated." ) key = rendering_setting_name_mapping[key] - self.set_setting(key, value) + self.settings.set(key, value) # set general carb settings carb_settings = self.cfg.render_cfg.carb_settings @@ -372,9 +374,9 @@ def _apply_render_settings_from_cfg(self): key = "/" + key.replace("_", "/") # convert from python variable style string elif "." in key: key = "/" + key.replace(".", "/") # convert from .kit file style string - if self.get_setting(key) is None: + if self.settings.get(key) is None: raise ValueError(f"'{key}' in RenderCfg.general_parameters does not map to a carb setting.") - self.set_setting(key, value) + self.settings.set(key, value) # set denoiser mode if self.cfg.render_cfg.antialiasing_mode is not None: @@ -386,8 +388,8 @@ def _apply_render_settings_from_cfg(self): pass # WAR: Ensure /rtx/renderMode RaytracedLighting is correctly cased. - if self.get_setting("/rtx/rendermode").lower() == "raytracedlighting": - self.set_setting("/rtx/rendermode", "RaytracedLighting") + if self.settings.get("/rtx/rendermode").lower() == "raytracedlighting": + self.settings.set("/rtx/rendermode", "RaytracedLighting") """ Operations - New. @@ -527,15 +529,15 @@ def set_setting(self, name: str, value: Any): """ # Route through typed setters for correctness and consistency for common scalar types. if isinstance(value, bool): - self.carb_settings.set_bool(name, value) + self.settings.set_bool(name, value) elif isinstance(value, int): - self.carb_settings.set_int(name, value) + self.settings.set_int(name, value) elif isinstance(value, float): - self.carb_settings.set_float(name, value) + self.settings.set_float(name, value) elif isinstance(value, str): - self.carb_settings.set_string(name, value) + self.settings.set_string(name, value) elif isinstance(value, (list, tuple)): - self.carb_settings.set(name, value) + self.settings.set(name, value) else: raise ValueError(f"Unsupported value type for setting '{name}': {type(value)}") @@ -548,7 +550,7 @@ def get_setting(self, name: str) -> Any: Returns: The value of the setting. """ - return self.carb_settings.get(name) + return self.settings.get(name) def forward(self) -> None: """Updates articulation kinematics and scene data for rendering.""" @@ -611,9 +613,10 @@ def initialize_visualizers(self) -> None: - Only visualizers specified via --visualizer will be initialized, even if multiple visualizer configs are present in the simulation config. """ + # Check if specific visualizers were requested via command-line flag - carb_settings_iface = carb.settings.get_settings() - requested_visualizers_str = carb_settings_iface.get("/isaaclab/visualizer") + settings_manager = get_settings_manager() + requested_visualizers_str = settings_manager.get("/isaaclab/visualizer") if requested_visualizers_str is None: requested_visualizers_str = "" @@ -796,7 +799,7 @@ def get_initial_stage(self) -> Usd.Stage: """ def reset(self, soft: bool = False): - self.carb_settings.set_bool("/app/player/playSimulations", False) + self.settings.set_bool("/app/player/playSimulations", False) self._disable_app_control_on_stop_handle = True # check if we need to raise an exception that was raised in a callback if builtins.ISAACLAB_CALLBACK_EXCEPTION is not None: @@ -916,7 +919,7 @@ def render(self, mode: RenderMode | None = None): self._render_throttle_counter = 0 # here we don't render viewport so don't need to flush fabric data # note: we don't call super().render() anymore because they do flush the fabric data - self.carb_settings.set_bool("/app/player/playSimulations", False) + self.settings.set_bool("/app/player/playSimulations", False) self._app.update() else: # manually flush the fabric data to update Hydra textures @@ -924,7 +927,7 @@ def render(self, mode: RenderMode | None = None): # render the simulation # note: we don't call super().render() anymore because they do above operation inside # and we don't want to do it twice. We may remove it once we drop support for Isaac Sim 2022.2. - self.carb_settings.set_bool("/app/player/playSimulations", False) + self.settings.set_bool("/app/player/playSimulations", False) self._app.update() # app.update() may be changing the cuda device, so we force it back to our desired device here @@ -951,9 +954,9 @@ def _init_stage(self, *args, **kwargs) -> Usd.Stage: with 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.carb_settings.set_bool("/app/player/playSimulations", False) + self.settings.set_bool("/app/player/playSimulations", False) self._app.update() - self.carb_settings.set_bool("/app/player/playSimulations", True) + self.settings.set_bool("/app/player/playSimulations", True) # set additional physx parameters and bind material self._set_additional_physics_params() # load flatcache/fabric interface diff --git a/source/isaaclab/isaaclab/visualizers/ov_visualizer.py b/source/isaaclab/isaaclab/visualizers/ov_visualizer.py index adb19ee578a..560aa00d664 100644 --- a/source/isaaclab/isaaclab/visualizers/ov_visualizer.py +++ b/source/isaaclab/isaaclab/visualizers/ov_visualizer.py @@ -1,8 +1,3 @@ -# 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. #