Skip to content

Conversation

@kellyguo11
Copy link
Contributor

Description

Building on top of #3979 from @matthewtrepte

Initial design to support multiple visualizers with Isaac Lab 3.0

The visualizers

OV Visualizer
Newton OpenGL Visualizer
Newton Rerun Visualizer
Each visualizer comes with a config class.

CLI newton_visualizer argument is removed.

Discussion on how we can best enable visualizer with CLI arg is ongoing.
Currently, visualizers can be selected in the code by visualizer_cfgs in simulation_cfg
and the --headless arg disables any selected visualizer
Also there is a new abstraction called scene data provider which manages per step data flow to visualizers.
This is a pretty thin abstraction right now and subject to change with the renderers design and ov sdk.

Adds additional --visualizer flag for specifying which visualizer(s) to enable.
Updates numpy to >=2 to support new rerun package that resolves a flashing screen issue.
Introduces default visualizer configs in the simulation config so that users can launch any visualizer without explicitly adding new configs into the environments.

Type of change

  • New feature (non-breaking change which adds functionality)
  • Breaking change (existing functionality will not work without user modification)

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Nov 26, 2025

Greptile Overview

Greptile Summary

This PR introduces a comprehensive visualizer system for Isaac Lab 3.0, replacing the single --newton_visualizer CLI flag with a flexible multi-visualizer architecture. The changes implement three distinct visualizer types: Newton OpenGL Visualizer (lightweight rendering), Omniverse Visualizer (high-fidelity USD-based rendering), and Rerun Visualizer (web-based with time scrubbing and recording). The new system uses a unified --visualizer CLI flag and configuration classes (NewtonVisualizerCfg, OVVisualizerCfg, RerunVisualizerCfg) that inherit from a common VisualizerCfg base class. A SceneDataProvider abstraction manages data flow between physics backends and visualizers, while the SimulationContext handles visualizer lifecycle management. The changes also upgrade numpy to version 2.0+ to support the updated rerun-sdk and introduce intelligent headless mode detection based on visualizer selection.

Important Files Changed

Filename Score Overview
source/isaaclab/isaaclab/app/app_launcher.py 4/5 Adds --visualizer CLI flag with intelligent headless mode detection
source/isaaclab/isaaclab/sim/simulation_context.py 4/5 Implements complete visualizer lifecycle management and scene data integration
source/isaaclab/isaaclab/visualizers/newton_visualizer.py 4/5 New Newton OpenGL visualizer implementation with training/rendering pause controls
source/isaaclab/isaaclab/visualizers/ov_visualizer.py 4/5 New Omniverse viewport visualizer with UI docking and camera management
source/isaaclab/isaaclab/visualizers/rerun_visualizer.py 4/5 New web-based Rerun visualizer with recording and time scrubbing capabilities
source/isaaclab/isaaclab/sim/scene_data_provider.py 4/5 New abstraction layer for managing physics data flow to visualizers
source/isaaclab/isaaclab/sim/simulation_cfg.py 4/5 Replaces enable_newton_rendering with flexible visualizer_cfgs configuration
source/isaaclab/isaaclab/visualizers/init.py 4/5 Lazy-loading registry pattern for visualizer backends with error handling
source/isaaclab/isaaclab/visualizers/visualizer.py 5/5 Abstract base class defining common visualizer interface and lifecycle
source/isaaclab/isaaclab/visualizers/visualizer_cfg.py 4/5 Base configuration class with factory pattern for visualizer creation
source/isaaclab/isaaclab/visualizers/newton_visualizer_cfg.py 5/5 Configuration class for Newton OpenGL visualizer with comprehensive options
source/isaaclab/isaaclab/visualizers/ov_visualizer_cfg.py 4/5 Configuration class for Omniverse visualizer with viewport settings
source/isaaclab/isaaclab/visualizers/rerun_visualizer_cfg.py 4/5 Configuration class for Rerun visualizer with server and recording options
source/isaaclab/isaaclab/sim/_impl/newton_manager.py 4/5 Removes tightly-coupled visualizer code from physics manager
source/isaaclab/isaaclab/sim/_impl/newton_manager_cfg.py 4/5 Removes viewer-specific config parameters from physics configuration
source/isaaclab/isaaclab/envs/ui/base_env_window.py 4/5 Adds live plots integration for visualizers with auto-expanding frames
source/isaaclab/setup.py 3/5 Upgrades numpy to >=2 and rerun-sdk to 0.27 for visualizer support
source/isaaclab_tasks/isaaclab_tasks/utils/parse_cfg.py 4/5 Removes newton_visualizer parameter from configuration parsing
source/isaaclab/isaaclab/ui/widgets/manager_live_visualizer.py 4/5 Adds auto-expand frames feature for visualizer integration
source/isaaclab/isaaclab/sim/_impl/newton_viewer.py 4/5 Entire Newton viewer implementation removed as part of refactoring
scripts/reinforcement_learning/rl_games/train.py 5/5 Removes deprecated --newton_visualizer CLI argument and config override
scripts/reinforcement_learning/rl_games/play.py 4/5 Removes deprecated --newton_visualizer CLI argument
scripts/reinforcement_learning/skrl/train.py 5/5 Removes deprecated --newton_visualizer CLI argument
scripts/reinforcement_learning/skrl/play.py 5/5 Removes deprecated --newton_visualizer CLI argument
scripts/reinforcement_learning/rsl_rl/train.py 4/5 Removes deprecated --newton_visualizer CLI argument
scripts/reinforcement_learning/rsl_rl/play.py 4/5 Removes deprecated --newton_visualizer CLI argument and setup logic
scripts/reinforcement_learning/sb3/train.py 4/5 Removes deprecated --newton_visualizer CLI argument
scripts/reinforcement_learning/sb3/play.py 4/5 Removes deprecated --newton_visualizer CLI argument
scripts/sim2sim_transfer/rsl_rl_transfer.py 5/5 Removes deprecated --newton_visualizer CLI argument
scripts/environments/random_agent.py 5/5 Removes deprecated --newton_visualizer CLI argument
scripts/environments/zero_agent.py 4/5 Removes deprecated --newton_visualizer CLI argument

Confidence score: 3/5

  • This PR introduces significant architectural changes but carries moderate risk due to dependency upgrades and breaking changes
  • Score reflects potential issues with numpy 2.0 compatibility, missing documentation, duplicated copyright headers, and breaking CLI changes without clear migration path
  • Pay close attention to setup.py dependency changes, visualizer configuration files with duplicate headers, and comprehensive testing of the new multi-visualizer system

Sequence Diagram

sequenceDiagram
    participant User
    participant AppLauncher
    participant SimulationContext
    participant SceneDataProvider
    participant NewtonManager
    participant NewtonVisualizer
    participant NewtonViewerGL
    participant TrainingLoop

    User->>AppLauncher: "python train.py --visualizer newton"
    AppLauncher->>AppLauncher: "parse --visualizer flag"
    AppLauncher->>AppLauncher: "store visualizer type in carb settings"
    AppLauncher->>SimulationContext: "create simulation context"
    
    SimulationContext->>SimulationContext: "read visualizer setting from carb"
    alt visualizer requested
        SimulationContext->>SimulationContext: "_create_default_visualizer_configs()"
        SimulationContext->>SceneDataProvider: "create provider with visualizer configs"
        SceneDataProvider->>SceneDataProvider: "determine active backends"
    end
    
    SimulationContext->>NewtonManager: "start_simulation()"
    NewtonManager->>NewtonManager: "initialize physics model and state"
    
    SimulationContext->>SimulationContext: "reset()"
    SimulationContext->>SimulationContext: "initialize_visualizers()"
    
    alt newton visualizer enabled
        SimulationContext->>NewtonVisualizer: "create_visualizer() from config"
        SimulationContext->>NewtonVisualizer: "initialize(scene_data)"
        NewtonVisualizer->>SceneDataProvider: "get_model() and get_state()"
        SceneDataProvider->>NewtonManager: "access physics data"
        NewtonManager-->>SceneDataProvider: "return model and state"
        SceneDataProvider-->>NewtonVisualizer: "return physics data"
        NewtonVisualizer->>NewtonViewerGL: "create viewer with metadata"
        NewtonViewerGL->>NewtonViewerGL: "set_model() and configure camera"
        NewtonViewerGL-->>NewtonVisualizer: "viewer initialized"
        NewtonVisualizer-->>SimulationContext: "visualizer ready"
    end
    
    loop training/simulation
        TrainingLoop->>SimulationContext: "step(render=True)"
        SimulationContext->>NewtonManager: "step()"
        NewtonManager->>NewtonManager: "simulate physics"
        SimulationContext->>SceneDataProvider: "update()"
        SceneDataProvider->>NewtonManager: "sync fabric transforms for OV"
        SimulationContext->>SimulationContext: "step_visualizers(dt)"
        SimulationContext->>NewtonVisualizer: "step(dt, state=None)"
        NewtonVisualizer->>SceneDataProvider: "get updated state"
        SceneDataProvider->>NewtonManager: "access latest physics state"
        NewtonManager-->>SceneDataProvider: "return current state"
        SceneDataProvider-->>NewtonVisualizer: "return updated state"
        alt not paused and update frequency met
            NewtonVisualizer->>NewtonViewerGL: "begin_frame(sim_time)"
            NewtonVisualizer->>NewtonViewerGL: "log_state(state)"
            NewtonVisualizer->>NewtonViewerGL: "end_frame()"
            NewtonViewerGL->>NewtonViewerGL: "render 3D scene"
        end
    end
    
    User->>TrainingLoop: "stop training"
    TrainingLoop->>SimulationContext: "close_visualizers()"
    SimulationContext->>NewtonVisualizer: "close()"
    NewtonVisualizer->>NewtonViewerGL: "cleanup resources"
    SimulationContext->>SimulationContext: "clear_instance()"
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

31 files reviewed, 11 comments

Edit Code Review Agent Settings | Greptile

visualizer_train_mode: bool = True
"""Whether the visualizer is in training mode (True) or play mode (False)."""

solver_cfg: NewtonSolverCfg = MJWarpSolverCfg()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Missing docstring for the solver_cfg attribute

Suggested change
solver_cfg: NewtonSolverCfg = MJWarpSolverCfg()
solver_cfg: NewtonSolverCfg = MJWarpSolverCfg()
"""Configuration for the Newton solver."""

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +19 to +21
This module uses a registry pattern to decouple visualizer instantiation from specific types.
Visualizer implementations can register themselves using the `register_visualizer` decorator,
and configs can create visualizers via the `create_visualizer()` factory method.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

syntax: Documentation mentions register_visualizer decorator and create_visualizer() factory method that don't exist in the implementation

Suggested change
This module uses a registry pattern to decouple visualizer instantiation from specific types.
Visualizer implementations can register themselves using the `register_visualizer` decorator,
and configs can create visualizers via the `create_visualizer()` factory method.
This module uses a registry pattern to decouple visualizer instantiation from specific types.
Visualizer implementations are lazy-loaded through the `get_visualizer_class()` factory function.

Comment on lines +174 to +176
# Calculate camera direction vector (from position to target)
cam_pos = self.cfg.camera_position
cam_target = self.cfg.camera_target
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: camera position and target are retrieved but not used in the blueprint configuration. Should these camera parameters be applied to the blueprint's Spatial3DView configuration?

for visualizer in self.env.sim._visualizers:
# Check if visualizer supports live plots and has it enabled
if hasattr(visualizer, "cfg") and hasattr(visualizer.cfg, "enable_live_plots"):
if visualizer.supports_live_plots() and visualizer.cfg.enable_live_plots:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: This method call could raise an AttributeError if the visualizer object doesn't implement supports_live_plots(). Consider adding a hasattr check.

Comment on lines +748 to +751
# Handle training pause - block until resumed
while visualizer.is_training_paused() and visualizer.is_running():
# Visualizers fetch backend-specific state themselves
visualizer.step(0.0, state=None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: This blocking while loop could cause the main thread to hang if a visualizer never resumes from pause. Consider adding a timeout or making this non-blocking with a sleep.

kellyguo11 and others added 5 commits November 26, 2025 16:16
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Kelly Guo <kellyg@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants