Interactive renderer to use with the official Python bindings for MuJoCo.
Starting with version 2.1.2, MuJoCo comes with native Python bindings officially supported by the MuJoCo devs.
If you have been a user of mujoco-py
, you might be looking to migrate.
Some pointers on migration are available here.
git clone https://github.com/gaolongsen/mujoco-python-viewer.git
cd mujoco-python-viewer
pip install -e .
import mujoco
import mujoco_viewer
model = mujoco.MjModel.from_xml_path('humanoid.xml')
data = mujoco.MjData(model)
# create the viewer object
viewer = mujoco_viewer.MujocoViewer(model, data)
# simulate and render
for _ in range(10000):
if viewer.is_alive:
mujoco.mj_step(model, data)
viewer.render()
else:
break
# close
viewer.close()
The render should pop up and the simulation should be running.
Double-click on a geom and hold Ctrl
to apply forces (using right mouse button) and torques (using left mouse button). This version we add the plot show on bottom-right side of the render windows as shown below:
import mujoco
import mujoco_viewer
model = mujoco.MjModel.from_xml_path('humanoid.xml')
data = mujoco.MjData(model)
viewer = mujoco_viewer.MujocoViewer(model, data, 'offscreen')
mujoco.mj_forward(model, data)
img = viewer.read_pixels(camid=2)
## do something cool with img
title
: set the title of the window, for example:viewer = mujoco_viewer.MujocoViewer(model, data, title='My Demo')
(defaults tomujoco-python-viewer
).width
: set the window width, for example:viewer = mujoco_viewer.MujocoViewer(model, data, width=300)
(defaults to full screen's width).height
: set the window height, for example:viewer = mujoco_viewer.MujocoViewer(model, data, height=300)
(defaults to full screen's height).hide_menus
: set whether the overlay menus and graph should be hidden or not (defaults toFalse
).
Now I update the Lib and can make sure you can create more than one data panel to show your variables update on the right-hand side of your render window. This would help your project to show different types of the variables clearly through different panels, especially different variables with different value range during the process, for example, if you want to show the wrench applied by robot arm(6 by 1 vector) and the position tracking error(3 by 1) together through the panel.
For example, when you call Mujoco
in you main code, you can initiated the parameter panel_num
like interface = Mujoco(robot_config, dt=0.001, panel_num=2)
to create another panel on the right-center part on your render window.
Note that if you just want only one data panel on the right-bottom side of the window, you don't need to initiate panel_num
because its inital value is 1
; Here is the example code that how to create two data panels on the render window:
# Assume 'model' and 'data' are already defined MuJoCo objects
viewer = MujocoViewer(model, data, panel_num=2) # note that you need to initialize panel_num = 2
# Configure bottom-right graph (fig_idx=0)
viewer.set_graph_name("Joint Angles", fig_idx=0)
viewer.set_x_label("Time (s)", fig_idx=0)
viewer.show_graph_legend(True, fig_idx=0)
viewer.set_grid_divisions(x_div=10, y_div=5, x_axis_time=10.0, fig_idx=0)
# Add lines to bottom-right graph
viewer.add_graph_line("Joint1 Angle", line_data=0.0, fig_idx=0)
viewer.add_graph_line("Joint2 Angle", line_data=0.0, fig_idx=0)
# Configure center-right graph (fig_idx=1)
viewer.set_graph_name("Joint Velocities", fig_idx=1)
viewer.set_x_label("Time (s)", fig_idx=1)
viewer.show_graph_legend(True, fig_idx=1)
viewer.set_grid_divisions(x_div=10, y_div=5, x_axis_time=10.0, fig_idx=1)
# Add lines to center-right graph
viewer.add_graph_line("Joint1 Velocity", line_data=0.0, fig_idx=1)
viewer.add_graph_line("Joint2 Velocity", line_data=0.0, fig_idx=1)
# In your simulation loop, update the plots
while viewer.is_alive:
# ... your simulation step ...
# Example data retrieval (replace with actual data)
joint1_angle = data.qpos[0]
joint2_angle = data.qpos[1]
joint1_velocity = data.qvel[0]
joint2_velocity = data.qvel[1]
# Update bottom-right graph
viewer.update_graph_line("Joint1 Angle", joint1_angle, fig_idx=0)
viewer.update_graph_line("Joint2 Angle", joint2_angle, fig_idx=0)
# Update center-right graph
viewer.update_graph_line("Joint1 Velocity", joint1_velocity, fig_idx=1)
viewer.update_graph_line("Joint2 Velocity", joint2_velocity, fig_idx=1)
# Render the viewer
viewer.render()
Here is an example from one of our research work and you can see for the wrench applied from the end-effector of UR5e and the state variables from the hinge can be shown clearly on the right-center side and right-bottom side, respectively.
Note that in order to show the legends on your multiple data panel successfully. You must make sure show_graph_legend
function must be behind of all of your add_graph_line
functions.