MuJoCo Web Viewer: update code to support the web viewer

PiperOrigin-RevId: 957147035
Change-Id: Ibe5d68b2654a7faac23c297d4f492929209c078d
This commit is contained in:
Matija Kecman
2026-07-31 08:06:33 -07:00
committed by Copybara-Service
parent a1e90c24b3
commit 6c78c98418
3 changed files with 12 additions and 4 deletions
@@ -93,9 +93,7 @@ def run_viewer_target(
Raises: Raises:
ValueError: If the viewer mode requested in config is unknown. ValueError: If the viewer mode requested in config is unknown.
NotImplementedError: If web mode is requested.
""" """
if config.viewer_mode == viewer_protocol.ViewerMode.NATIVE: if config.viewer_mode == viewer_protocol.ViewerMode.NATIVE:
from mujoco.experimental.studio import native_viewer # pylint: disable=g-import-not-at-top from mujoco.experimental.studio import native_viewer # pylint: disable=g-import-not-at-top
@@ -103,7 +101,9 @@ def run_viewer_target(
config, viewer_endpoint, handlers=handlers config, viewer_endpoint, handlers=handlers
) )
elif config.viewer_mode == viewer_protocol.ViewerMode.WEB: elif config.viewer_mode == viewer_protocol.ViewerMode.WEB:
raise NotImplementedError('Web viewer not implemented yet') from mujoco.experimental.studio import web_viewer # pylint: disable=g-import-not-at-top
viewer = web_viewer.WebViewer(config, viewer_endpoint, handlers=handlers)
else: else:
raise ValueError(f'Unknown viewer mode: {config.viewer_mode!r}') raise ValueError(f'Unknown viewer mode: {config.viewer_mode!r}')
@@ -31,6 +31,12 @@ _MJCF_PATH = flags.DEFINE_string('mjcf', None, 'Path to MJCF file.')
_VIEWER = flags.DEFINE_enum_class( _VIEWER = flags.DEFINE_enum_class(
'viewer', vp.ViewerMode.NATIVE, vp.ViewerMode, 'Viewer mode.' 'viewer', vp.ViewerMode.NATIVE, vp.ViewerMode, 'Viewer mode.'
) )
_PORT = flags.DEFINE_integer(
'port',
0,
'Web viewer port. 0 picks the first free port starting at 8080, so '
'several viewers can run side by side.',
)
def main(argv: list[str]) -> None: def main(argv: list[str]) -> None:
@@ -39,6 +45,7 @@ def main(argv: list[str]) -> None:
height=_HEIGHT.value, height=_HEIGHT.value,
gfx=_GFX.value or '', gfx=_GFX.value or '',
viewer_mode=_VIEWER.value, viewer_mode=_VIEWER.value,
http_port=_PORT.value,
) )
# Resolve model path, if provided. # Resolve model path, if provided.
@@ -15,6 +15,7 @@
import copy import copy
import dataclasses import dataclasses
import mujoco import mujoco
from mujoco.experimental.studio import messages from mujoco.experimental.studio import messages
from mujoco.experimental.studio import parser from mujoco.experimental.studio import parser
@@ -355,7 +356,7 @@ class ViewerApp:
paused = ( paused = (
self.step_control_state.get_pause_state() != sim.PauseState.UNPAUSED self.step_control_state.get_pause_state() != sim.PauseState.UNPAUSED
) )
ux.stats_gui(self.model, self.data, paused, 0.0) ux.info_gui(self.model, self.data, paused, 0.0)
imgui.End() imgui.End()
# -- Status bar ----------------------------------------------------------- # -- Status bar -----------------------------------------------------------