Add show_{left,right}_ui kwarg to viewer.launch(_passive).
Fixes #857 PiperOrigin-RevId: 572333909 Change-Id: I12247fe856afddf808eb8f386a594acac47c34b5
This commit is contained in:
committed by
Copybara-Service
parent
2e15574b58
commit
a1d0cbd654
+7
-4
@@ -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
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user