Add show_{left,right}_ui kwarg to viewer.launch(_passive).

Fixes #857

PiperOrigin-RevId: 572333909
Change-Id: I12247fe856afddf808eb8f386a594acac47c34b5
This commit is contained in:
Saran Tunyasuvunakool
2023-10-10 12:29:24 -07:00
committed by Copybara-Service
parent 2e15574b58
commit a1d0cbd654
5 changed files with 81 additions and 31 deletions
+7 -4
View File
@@ -133,6 +133,8 @@ Python bindings
camera name used the default camera.
24. Added ``user_scn`` to the :ref:`passive viewer<PyViewerPassive>` handle, which allows users to add custom
visualization geoms (`#1023 <https://github.com/google-deepmind/mujoco/issues/870>`__).
25. Added optional boolean keyword arguments ``show_left_ui`` and ``show_right_ui`` to the functions ``viewer.launch``
and ``viewer.launch_passive``, which allow users to launch a viewer with UI panels hidden.
Simulate
^^^^^^^^
@@ -141,21 +143,22 @@ Simulate
:align: right
:width: 240px
25. Added **state history** mechanism to :ref:`simulate<saSimulate>` and the managed
26. Added **state history** mechanism to :ref:`simulate<saSimulate>` and the managed
:ref:`Python viewer<PyViewerManaged>`. State history can be viewed by scrubbing the History slider and (more
precisely) with the left and right arrow keys. See screen capture:
26. The ``LOADING...`` label is now shown correctly.
27. The ``LOADING...`` label is now shown correctly.
`Contribution <https://github.com/google-deepmind/mujoco/pull/1070>`__ by
`Levi Burner <https://github.com/aftersomemath>`__.
Bug fixes
^^^^^^^^^
27. Fixed a bug that was causing :ref:`geom margin<body-geom-margin>` to be ignored during the construction of
28. Fixed a bug that was causing :ref:`geom margin<body-geom-margin>` to be ignored during the construction of
midphase collision trees.
27. Fixed a bug that was generating incorrect values in ``efc_diagApprox`` for weld equality constraints.
29. Fixed a bug that was generating incorrect values in ``efc_diagApprox`` for weld equality constraints.
Version 2.3.7 (July 20, 2023)
-----------------------------
+22 -17
View File
@@ -191,28 +191,33 @@ illustrative example that does **not** necessarily keep the physics ticking at t
if time_until_next_step > 0:
time.sleep(time_until_next_step)
Optionally, ``viewer.launch_passive`` also accepts a callable as a keyword argument ``key_callback``, which gets called
each time a keyboard event occurs in the viewer window. This allows user scripts to react to various key presses, e.g.,
pause or resume the run loop when the spacebar is pressed.
Optionally, ``viewer.launch_passive`` accepts the following keyword arguments.
.. code-block:: python
- ``key_callback``: A callable which gets called each time a keyboard event occurs in the viewer window. This allows
user scripts to react to various key presses, e.g., pause or resume the run loop when the spacebar is pressed.
paused = False
.. code-block:: python
def key_callback(keycode):
if chr(keycode) == ' ':
nonlocal paused
paused = not paused
paused = False
...
def key_callback(keycode):
if chr(keycode) == ' ':
nonlocal paused
paused = not paused
with mujoco.viewer.launch_passive(m, d, key_callback=key_callback) as viewer:
while viewer.is_running():
...
if not paused:
mujoco.mj_step(m, d)
viewer.sync()
...
...
with mujoco.viewer.launch_passive(m, d, key_callback=key_callback) as viewer:
while viewer.is_running():
...
if not paused:
mujoco.mj_step(m, d)
viewer.sync()
...
- ``show_left_ui_panel`` and ``show_right_ui_panel``: Boolean arguments indicating whether UI panels should be visible
or hidden when the viewer is launched. Note that regardless of the values specified, the user can still toggle the
visibility of these panels after launch by pressing Tab or Shift+Tab.
.. _PyUsage:
+9 -3
View File
@@ -294,11 +294,17 @@ while True:
break
# Otherwise, launch the viewer.
model, data, handle_return, key_callback = task
model, data, handle_return, key_callback, show_left_ui, show_right_ui = task
ctypes.CDLL(None).mjpython_show_dock_icon()
mujoco.viewer._launch_internal(
model, data, run_physics_thread=False, handle_return=handle_return,
key_callback=key_callback)
model,
data,
run_physics_thread=False,
handle_return=handle_return,
key_callback=key_callback,
show_left_ui=show_left_ui,
show_right_ui=show_right_ui,
)
ctypes.CDLL(None).mjpython_hide_dock_icon()
finally:
+11 -1
View File
@@ -314,7 +314,17 @@ PYBIND11_MODULE(_simulate, pymodule) {
const auto max_length = sizeof_arr(sim.load_error);
std::strncpy(sim.load_error, error.c_str(), max_length - 1);
sim.load_error[max_length - 1] = '\0';
}));
}))
.def_property("ui0_enable", GetIfNotNull(&mujoco::Simulate::ui0_enable),
CallIfNotNull(+[](mujoco::Simulate& sim, int enabled) {
sim.ui0_enable = enabled;
}),
py::call_guard<py::gil_scoped_release>())
.def_property("ui1_enable", GetIfNotNull(&mujoco::Simulate::ui1_enable),
CallIfNotNull(+[](mujoco::Simulate& sim, int enabled) {
sim.ui1_enable = enabled;
}),
py::call_guard<py::gil_scoped_release>());
pymodule.def("set_glfw_dlhandle", [](std::uintptr_t dlhandle) {
mujoco::Glfw(reinterpret_cast<void*>(dlhandle));
+32 -6
View File
@@ -319,6 +319,8 @@ def _launch_internal(
loader: Optional[_InternalLoaderType] = None,
handle_return: Optional['queue.Queue[Handle]'] = None,
key_callback: Optional[KeyCallbackType] = None,
show_left_ui: bool = True,
show_right_ui: bool = True,
) -> None:
"""Internal API, so that the public API has more readable type annotations."""
if model is None and data is not None:
@@ -351,6 +353,9 @@ def _launch_internal(
cam, opt, pert, user_scn, run_physics_thread, key_callback
)
simulate.ui0_enable = show_left_ui
simulate.ui1_enable = show_right_ui
# Initialize GLFW if not using mjpython.
if _MJPYTHON is None:
if not glfw.init():
@@ -385,13 +390,23 @@ def _launch_internal(
simulate.destroy()
def launch(model: Optional[mujoco.MjModel] = None,
data: Optional[mujoco.MjData] = None,
*,
loader: Optional[LoaderType] = None) -> None:
def launch(
model: Optional[mujoco.MjModel] = None,
data: Optional[mujoco.MjData] = None,
*,
loader: Optional[LoaderType] = None,
show_left_ui: bool = True,
show_right_ui: bool = True,
) -> None:
"""Launches the Simulate GUI."""
_launch_internal(
model, data, run_physics_thread=True, loader=loader)
model,
data,
run_physics_thread=True,
loader=loader,
show_left_ui=show_left_ui,
show_right_ui=show_right_ui,
)
def launch_from_path(path: str) -> None:
@@ -404,6 +419,8 @@ def launch_passive(
data: mujoco.MjData,
*,
key_callback: Optional[KeyCallbackType] = None,
show_left_ui: bool = True,
show_right_ui: bool = True,
) -> Handle:
"""Launches a passive Simulate GUI without blocking the running thread."""
if not isinstance(model, mujoco.MjModel):
@@ -425,6 +442,8 @@ def launch_passive(
run_physics_thread=False,
handle_return=handle_return,
key_callback=key_callback,
show_left_ui=show_left_ui,
show_right_ui=show_right_ui,
),
)
thread.daemon = True
@@ -434,7 +453,14 @@ def launch_passive(
raise RuntimeError(
'`launch_passive` requires that the Python script be run under '
'`mjpython` on macOS')
_MJPYTHON.launch_on_ui_thread(model, data, handle_return, key_callback)
_MJPYTHON.launch_on_ui_thread(
model,
data,
handle_return,
key_callback,
show_left_ui,
show_right_ui,
)
return handle_return.get()