Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d4dc70e
init
matthewtrepte Nov 8, 2025
d70b0d8
initial impl
matthewtrepte Nov 11, 2025
d5fcc05
add scene data provider abstraction layer
matthewtrepte Nov 12, 2025
a1e8ec2
bug fix
matthewtrepte Nov 12, 2025
c927485
clean
matthewtrepte Nov 12, 2025
1b24ba5
wip
matthewtrepte Nov 13, 2025
b67e00e
add rerun viz
matthewtrepte Nov 15, 2025
30116c0
clean
matthewtrepte Nov 15, 2025
95d9429
clean
matthewtrepte Nov 15, 2025
f1ca9db
try new newton
matthewtrepte Nov 19, 2025
a8c9d07
wip
matthewtrepte Nov 19, 2025
7ee435f
adding feats
matthewtrepte Nov 19, 2025
011c373
wip
matthewtrepte Nov 19, 2025
c0a3b1e
cleaning up
matthewtrepte Nov 19, 2025
6f4ff19
clean
matthewtrepte Nov 19, 2025
3d154aa
add OV ui auto enabling to live plots
matthewtrepte Nov 19, 2025
0f8dda3
fb draft
matthewtrepte Nov 21, 2025
e4aceab
wip
matthewtrepte Nov 21, 2025
0f99eaa
clean
matthewtrepte Nov 21, 2025
a5f8256
prepare for merge;
matthewtrepte Nov 21, 2025
ecb66af
clean before review
matthewtrepte Nov 21, 2025
7562067
default to no viz
matthewtrepte Nov 21, 2025
52ae2f3
Update simulation_cfg.py
matthewtrepte Nov 21, 2025
17aa1e5
Update simulation_cfg.py
matthewtrepte Nov 21, 2025
9b55035
Adds --visualizer flag and updates behavior with --headless; also add…
kellyguo11 Nov 26, 2025
2c511b0
updates numpy to >=2
kellyguo11 Nov 26, 2025
9080acb
Merge branch 'dev/newton' of github.com:isaac-sim/IsaacLab into newto…
kellyguo11 Nov 27, 2025
6ad47b0
Update source/isaaclab/isaaclab/visualizers/rerun_visualizer_cfg.py
kellyguo11 Nov 27, 2025
89f621d
Update source/isaaclab/isaaclab/sim/simulation_cfg.py
kellyguo11 Nov 27, 2025
8ec7a12
Update source/isaaclab/isaaclab/visualizers/rerun_visualizer.py
kellyguo11 Nov 27, 2025
ec34aa6
Update source/isaaclab/isaaclab/visualizers/ov_visualizer.py
kellyguo11 Nov 27, 2025
5daebaf
format
kellyguo11 Nov 30, 2025
ad5c37f
Merge branch 'dev/newton' into newton/visualizers
AntoineRichard Dec 1, 2025
004379c
linters
AntoineRichard Dec 1, 2025
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
102 changes: 102 additions & 0 deletions source/isaaclab/isaaclab/app/app_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ def __init__(self, launcher_args: argparse.Namespace | dict | None = None, **kwa
self._livestream: Literal[0, 1, 2] # 0: Disabled, 1: WebRTC public, 2: WebRTC private
self._offscreen_render: bool # 0: Disabled, 1: Enabled
self._sim_experience_file: str # Experience file to load
self._visualizer: (
list[str] | None
) # Visualizer backends to use: None or list of ["rerun", "newton", "omniverse"]

# Exposed to train scripts
self.device_id: int # device ID for GPU simulation (defaults to 0)
Expand Down Expand Up @@ -174,6 +177,16 @@ def app(self) -> SimulationApp:
else:
raise RuntimeError("The `AppLauncher.app` member cannot be retrieved until the class is initialized.")

@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

"""
Operations.
"""
Expand Down Expand Up @@ -226,6 +239,21 @@ def add_app_launcher_args(parser: argparse.ArgumentParser) -> None:
Arguments should be combined into a single string separated by space.
Example usage: --kit_args "--ext-folder=/path/to/ext1 --ext-folder=/path/to/ext2"

* ``visualizer`` (list[str]): The visualizer backend(s) to use for the simulation.
Valid options are:

- ``rerun``: Use Rerun visualizer.
- ``newton``: Use Newton visualizer.
- ``omniverse``: Use Omniverse visualizer.
- Multiple visualizers can be specified: ``--visualizer rerun newton``
- If not specified (default), NO visualizers will be initialized and headless mode is auto-enabled.

Note: If visualizer configs are not defined in the simulation config, default configs will be
automatically created with all default parameters.
If --headless is specified, it takes precedence and NO visualizers will be initialized.
When omniverse visualizer is specified, the app will launch in non-headless mode automatically.
When only non-GUI visualizers (rerun, newton) are specified, headless mode is auto-enabled.

Args:
parser: An argument parser instance to be extended with the AppLauncher specific options.
"""
Expand Down Expand Up @@ -362,6 +390,19 @@ def add_app_launcher_args(parser: argparse.ArgumentParser) -> None:
" exceeded, then the animation is not recorded."
),
)
arg_group.add_argument(
"--visualizer",
type=str,
nargs="*",
default=None,
help=(
"The visualizer backend(s) to use for the simulation."
' Can be one or more of: "rerun", "newton", "omniverse".'
" Multiple visualizers can be specified: --visualizer rerun newton."
" If not specified (default), NO visualizers will be created and headless mode is auto-enabled."
" If no visualizer configs are defined in sim config, default configs will be created automatically."
),
)
# special flag for backwards compatibility

# Corresponding to the beginning of the function,
Expand All @@ -382,6 +423,7 @@ def add_app_launcher_args(parser: argparse.ArgumentParser) -> None:
"device": ([str], "cuda:0"),
"experience": ([str], ""),
"rendering_mode": ([str], "balanced"),
"visualizer": ([list, type(None)], None),
}
"""A dictionary of arguments added manually by the :meth:`AppLauncher.add_app_launcher_args` method.

Expand Down Expand Up @@ -479,6 +521,7 @@ def _config_resolution(self, launcher_args: dict):
# Handle core settings
livestream_arg, livestream_env = self._resolve_livestream_settings(launcher_args)
self._resolve_headless_settings(launcher_args, livestream_arg, livestream_env)
self._resolve_visualizer_settings(launcher_args)
self._resolve_camera_settings(launcher_args)
self._resolve_xr_settings(launcher_args)
self._resolve_viewport_settings(launcher_args)
Expand Down Expand Up @@ -570,9 +613,16 @@ def _resolve_headless_settings(self, launcher_args: dict, livestream_arg: int, l
raise ValueError(
f"Invalid value for environment variable `HEADLESS`: {headless_env} . Expected: {headless_valid_vals}."
)

# Check if visualizers are requested and if omniverse visualizer is among them
visualizers = launcher_args.get("visualizer", AppLauncher._APPLAUNCHER_CFG_INFO["visualizer"][1])
visualizers_requested = visualizers is not None and len(visualizers) > 0
omniverse_visualizer_requested = visualizers_requested and "omniverse" in visualizers

# We allow headless kwarg to supersede HEADLESS envvar if headless_arg does not have the default value
# Note: Headless is always true when livestreaming
if headless_arg is True:
# User explicitly requested headless mode
self._headless = headless_arg
elif self._livestream in {1, 2}:
# we are always headless on the host machine
Expand All @@ -588,12 +638,56 @@ def _resolve_headless_settings(self, launcher_args: dict, livestream_arg: int, l
f"[INFO][AppLauncher]: Environment variable `LIVESTREAM={self._livestream}` has implicitly"
f" overridden the environment variable `HEADLESS={headless_env}` to True."
)
elif omniverse_visualizer_requested and headless_env == 0:
# Omniverse visualizer requires non-headless mode (needs Isaac Sim viewport)
self._headless = False
print(
"[INFO][AppLauncher]: Omniverse visualizer requested via --visualizer flag. "
"Launching in non-headless mode to enable viewport visualization."
)
elif visualizers_requested and not omniverse_visualizer_requested and headless_env == 0:
# Newton and Rerun don't need Isaac Sim viewport (they create their own windows or are web-based)
self._headless = True
print(
f"[INFO][AppLauncher]: Visualizer(s) {visualizers} requested. "
"Enabling headless mode (Isaac Sim viewport disabled)."
)
elif not visualizers_requested and headless_env == 0:
# No visualizers requested and headless not explicitly set -> enable headless mode
self._headless = True
print(
"[INFO][AppLauncher]: No visualizers specified via --visualizer flag. "
"Automatically enabling headless mode. Use --visualizer <type> to enable GUI."
)
else:
# Headless needs to be a bool to be ingested by SimulationApp
self._headless = bool(headless_env)
# Headless needs to be passed to the SimulationApp so we keep it here
launcher_args["headless"] = self._headless

def _resolve_visualizer_settings(self, launcher_args: dict):
"""Resolve visualizer related settings."""
# Get visualizer setting from launcher_args
visualizers = launcher_args.get("visualizer", AppLauncher._APPLAUNCHER_CFG_INFO["visualizer"][1])

# Validate visualizer names
valid_visualizers = ["rerun", "newton", "omniverse"]
if visualizers is not None and len(visualizers) > 0:
invalid = [v for v in visualizers if v not in valid_visualizers]
if invalid:
raise ValueError(f"Invalid visualizer(s) specified: {invalid}. Valid options are: {valid_visualizers}")

# Store visualizer setting for later use
# Convert empty list to None for consistency
self._visualizer = visualizers if visualizers and len(visualizers) > 0 else None

# Check if both headless and visualizer are specified
if self._headless and self._visualizer is not None:
print(
f"[WARN][AppLauncher]: Both headless mode and visualizer(s) {self._visualizer} were specified."
" Headless mode is enabled, so no visualizers will be initialized."
)

def _resolve_camera_settings(self, launcher_args: dict):
"""Resolve camera related settings."""
enable_cameras_env = int(os.environ.get("ENABLE_CAMERAS", 0))
Expand Down Expand Up @@ -831,6 +925,14 @@ def _load_extensions(self):
# for example: the `Camera` sensor class
carb_settings_iface.set_bool("/isaaclab/render/rtx_sensors", False)

# set carb 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
if self._visualizer is not None:
carb_settings_iface.set_string("/isaaclab/visualizer", ",".join(self._visualizer))
else:
carb_settings_iface.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())

Expand Down
4 changes: 2 additions & 2 deletions source/isaaclab/isaaclab/sim/simulation_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from typing import Literal

from isaaclab.utils import configclass
from isaaclab.visualizers import NewtonVisualizerCfg, OVVisualizerCfg, RerunVisualizerCfg, VisualizerCfg # noqa: F401
from isaaclab.visualizers import VisualizerCfg

from ._impl.newton_manager_cfg import NewtonCfg
from .spawners.materials import RigidBodyMaterialCfg
Expand Down Expand Up @@ -216,7 +216,7 @@ class SimulationCfg:
# Disable all visualizers
cfg.sim.visualizer_cfgs = []

# Use default visualizer (NewtonVisualizerCfg)
# No visualizers (default behavior)
cfg = SimulationCfg()

# Single custom visualizer
Expand Down
Loading
Loading