python.rst 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. ======
  2. Python
  3. ======
  4. MuJoCo comes with native Python bindings that are developed in C++ using
  5. `pybind11 <https://pybind11.readthedocs.io/>`__. The Python API is consistent with the underlying C API. This leads to
  6. some non-Pythonic code structure (e.g. order of function arguments), but it has the benefit that the
  7. :doc:`API documentation<APIreference/index>` is applicable to both languages.
  8. The Python bindings are distributed as the ``mujoco`` package on `PyPI <https://pypi.org/project/mujoco>`__. These are
  9. low-level bindings that are meant to give as close to a direct access to the MuJoCo library as possible. However, in
  10. order to provide an API and semantics that developers would expect in a typical Python library, the bindings
  11. deliberately diverge from the raw MuJoCo API in a number of places, which are documented throughout this page.
  12. Google DeepMind’s `dm_control <https://github.com/google-deepmind/dm_control>`__ reinforcement learning library depends
  13. on the ``mujoco`` package and continues to be supported by Google DeepMind. For code that depends on dm_control versions
  14. prior to 1.0.0, consult the
  15. `migration guide <https://github.com/google-deepmind/dm_control/blob/main/migration_guide_1.0.md>`__.
  16. For mujoco-py users, we include :ref:`migration notes <PyMjpy_migration>` below.
  17. .. _PyNotebook:
  18. Tutorial notebook
  19. =================
  20. A MuJoCo tutorial using the Python bindings is available here: |mjcolab|
  21. .. |mjcolab| image:: https://colab.research.google.com/assets/colab-badge.svg
  22. :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/tutorial.ipynb
  23. .. _PyInstallation:
  24. Installation
  25. ============
  26. The recommended way to install this package is via `PyPI <https://pypi.org/project/mujoco/>`__:
  27. .. code-block:: shell
  28. pip install mujoco
  29. A copy of the MuJoCo library is provided as part of the package and does **not** need to be downloaded or installed
  30. separately.
  31. .. _PyViewer:
  32. Interactive viewer
  33. ==================
  34. An interactive GUI viewer is provided as part of the Python package in the ``mujoco.viewer`` module. It is based on the
  35. same codebase as the :ref:`simulate<saSimulate>` application that ships with the MuJoCo binary releases. Three distinct
  36. use cases are supported:
  37. .. _PyViewerApp:
  38. Standalone app
  39. --------------
  40. - ``python -m mujoco.viewer`` launches an empty visualization session, where a model can be loaded by drag-and-drop.
  41. - ``python -m mujoco.viewer --mjcf=/path/to/some/mjcf.xml`` launches a visualization session for the specified
  42. model file.
  43. .. _PyViewerManaged:
  44. Managed viewer
  45. --------------
  46. Called from a Python program/script, through the function ``viewer.launch``. This function *blocks user code* to
  47. support precise timing of the physics loop. This mode should be used if user code is implemented as
  48. :ref:`engine plugins<exPlugin>` or :ref:`physics callbacks<glPhysics>`, and is called by MuJoCo during :ref:`mj_step`.
  49. - ``viewer.launch()`` launches an empty visualization session, where a model can be loaded by drag-and-drop.
  50. - ``viewer.launch(model)`` launches a visualization session for the given ``mjModel`` where the visualizer
  51. internally creates its own instance of ``mjData``
  52. - ``viewer.launch(model, data)`` is the same as above, except that the visualizer operates directly on the given
  53. ``mjData`` instance -- upon exit the ``data`` object will have been modified.
  54. .. _PyViewerPassive:
  55. Passive viewer
  56. --------------
  57. By calling ``viewer.launch_passive(model, data)``. This function *does not block*, allowing user code to continue
  58. execution. In this mode, the user's script is responsible for timing and advancing the physics state, and mouse-drag
  59. perturbations will not work unless the user explicitly synchronizes incoming events.
  60. .. warning::
  61. On MacOS, ``launch_passive`` requires that the user script is executed via a special ``mjpython`` launcher.
  62. The ``mjpython`` command is installed as part of the ``mujoco`` package, and can be used as a drop-in replacement
  63. for the usual ``python`` command and supports an identical set of command line flags and arguments. For example,
  64. a script can be executed via ``mjpython my_script.py``, and an IPython shell can be launched via
  65. ``mjpython -m IPython``.
  66. The ``launch_passive`` function returns a handle which can be used to interact with the viewer. It has the following
  67. attributes:
  68. - ``cam``, ``opt``, and ``pert`` properties: correspond to :ref:`mjvCamera`, :ref:`mjvOption`, and :ref:`mjvPerturb`
  69. structs, respectively.
  70. - ``lock()``: provides a mutex lock for the viewer as a context manager. Since the viewer operates its own
  71. thread, user code must ensure that it is holding the viewer lock before modifying any physics or visualization
  72. state. These include the ``mjModel`` and ``mjData`` instance passed to ``launch_passive``, and also the ``cam``,
  73. ``opt``, and ``pert`` properties of the viewer handle.
  74. - ``sync()``: synchronizes state between ``mjModel``, ``mjData``, and GUI user inputs since the previous call to
  75. ``sync``. In order to allow user scripts to make arbitrary modifications to ``mjModel`` and ``mjData`` without
  76. needing to hold the viewer lock, the passive viewer does not access or modify these structs outside of ``sync``
  77. calls.
  78. User scripts must call ``sync`` in order for the viewer to reflect physics state changes. The ``sync`` function
  79. also transfers user inputs from the GUI back into ``mjOption`` (inside ``mjModel``) and ``mjData``, including
  80. enable/disable flags, control inputs, and mouse perturbations.
  81. - ``update_hfield(hfieldid)``: updates the height field data at the specified ``hfieldid`` for subsequent renderings.
  82. - ``update_mesh(meshid)``: updates the mesh data at the specified ``meshid`` for subsequent renderings.
  83. - ``update_texture(texid)``: updates the texture data at the specified ``texid`` for subsequent renderings.
  84. - ``close()``: programmatically closes the viewer window. This method can be safely called without locking.
  85. - ``is_running()``: returns ``True`` if the viewer window is running and ``False`` if it is closed.
  86. This method can be safely called without locking.
  87. - ``user_scn``: an :ref:`mjvScene` object that allows users to add change rendering flags and add custom
  88. visualization geoms to the rendered scene. This is separate from the ``mjvScene`` that the viewer uses internally to
  89. render the final scene, and is entirely under the user's control. User scripts can call e.g. :ref:`mjv_initGeom` or
  90. :ref:`mjv_makeConnector` to add visualization geoms to ``user_scn``, and upon the next call to ``sync()``, the viewer
  91. will incorporate these geoms to future rendered images. Similarly, user scripts can make changes to ``user_scn.flags``
  92. which would be picked up at the next call to ``sync()``. The ``sync()`` call also copies changes to rendering flags
  93. made via the GUI back into ``user_scn`` to preserve consistency. For example:
  94. .. code-block:: python
  95. with mujoco.viewer.launch_passive(m, d, key_callback=key_callback) as viewer:
  96. # Enable wireframe rendering of the entire scene.
  97. viewer.user_scn.flags[mujoco.mjtRndFlag.mjRND_WIREFRAME] = 1
  98. viewer.sync()
  99. while viewer.is_running():
  100. ...
  101. # Step the physics.
  102. mujoco.mj_step(m, d)
  103. # Add a 3x3x3 grid of variously colored spheres to the middle of the scene.
  104. viewer.user_scn.ngeom = 0
  105. i = 0
  106. for x, y, z in itertools.product(*((range(-1, 2),) * 3)):
  107. mujoco.mjv_initGeom(
  108. viewer.user_scn.geoms[i],
  109. type=mujoco.mjtGeom.mjGEOM_SPHERE,
  110. size=[0.02, 0, 0],
  111. pos=0.1*np.array([x, y, z]),
  112. mat=np.eye(3).flatten(),
  113. rgba=0.5*np.array([x + 1, y + 1, z + 1, 2])
  114. )
  115. i += 1
  116. viewer.user_scn.ngeom = i
  117. viewer.sync()
  118. ...
  119. The viewer handle can also be used as a context manager which calls ``close()`` automatically upon exit. A minimal
  120. example of a user script that uses ``launch_passive`` might look like the following. (Note that example is a simple
  121. illustrative example that does **not** necessarily keep the physics ticking at the correct wallclock rate.)
  122. .. code-block:: python
  123. import time
  124. import mujoco
  125. import mujoco.viewer
  126. m = mujoco.MjModel.from_xml_path('/path/to/mjcf.xml')
  127. d = mujoco.MjData(m)
  128. with mujoco.viewer.launch_passive(m, d) as viewer:
  129. # Close the viewer automatically after 30 wall-seconds.
  130. start = time.time()
  131. while viewer.is_running() and time.time() - start < 30:
  132. step_start = time.time()
  133. # mj_step can be replaced with code that also evaluates
  134. # a policy and applies a control signal before stepping the physics.
  135. mujoco.mj_step(m, d)
  136. # Example modification of a viewer option: toggle contact points every two seconds.
  137. with viewer.lock():
  138. viewer.opt.flags[mujoco.mjtVisFlag.mjVIS_CONTACTPOINT] = int(d.time % 2)
  139. # Pick up changes to the physics state, apply perturbations, update options from GUI.
  140. viewer.sync()
  141. # Rudimentary time keeping, will drift relative to wall clock.
  142. time_until_next_step = m.opt.timestep - (time.time() - step_start)
  143. if time_until_next_step > 0:
  144. time.sleep(time_until_next_step)
  145. Optionally, ``viewer.launch_passive`` accepts the following keyword arguments.
  146. - ``key_callback``: A callable which gets called each time a keyboard event occurs in the viewer window. This allows
  147. user scripts to react to various key presses, e.g., pause or resume the run loop when the spacebar is pressed.
  148. .. code-block:: python
  149. paused = False
  150. def key_callback(keycode):
  151. if chr(keycode) == ' ':
  152. nonlocal paused
  153. paused = not paused
  154. ...
  155. with mujoco.viewer.launch_passive(m, d, key_callback=key_callback) as viewer:
  156. while viewer.is_running():
  157. ...
  158. if not paused:
  159. mujoco.mj_step(m, d)
  160. viewer.sync()
  161. ...
  162. - ``show_left_ui`` and ``show_right_ui``: Boolean arguments indicating whether UI panels should be visible
  163. or hidden when the viewer is launched. Note that regardless of the values specified, the user can still toggle the
  164. visibility of these panels after launch by pressing Tab or Shift+Tab.
  165. .. _PyUsage:
  166. Basic usage
  167. ===========
  168. Once installed, the package can be imported via ``import mujoco``. Structs, functions, constants, and enums are
  169. available directly from the top-level ``mujoco`` module.
  170. .. _PyStructs:
  171. Structs
  172. -------
  173. The bindings include Python classes that expose MuJoCo data structures. For maximum performance, these classes provide
  174. access to the raw memory used by MuJoCo without copying or buffering. This means that some MuJoCo functions (e.g.,
  175. :ref:`mj_step`) change the content of fields *in place*. The user is therefore advised to create copies where required.
  176. For example, when logging the position of a body, one could write
  177. ``positions.append(data.body('my_body').xpos.copy())``. Without the ``.copy()``, the list would contain identical
  178. elements, all pointing to the most recent value.
  179. In order to conform to `PEP 8 <https://peps.python.org/pep-0008/>`__
  180. naming guidelines, struct names begin with a capital letter, for example ``mjData`` becomes ``mujoco.MjData`` in Python.
  181. All structs other than ``mjModel`` have constructors in Python. For structs that have an ``mj_defaultFoo``-style
  182. initialization function, the Python constructor calls the default initializer automatically, so for example
  183. ``mujoco.MjOption()`` creates a new ``mjOption`` instance that is pre-initialized with :ref:`mj_defaultOption`.
  184. Otherwise, the Python constructor zero-initializes the underlying C struct.
  185. Structs with a ``mj_makeFoo``-style initialization function have corresponding constructor overloads in Python,
  186. for example ``mujoco.MjvScene(model, maxgeom=10)`` in Python creates a new ``mjvScene`` instance that is
  187. initialized with ``mjv_makeScene(model, [the new mjvScene instance], 10)`` in C. When this form of initialization is
  188. used, the corresponding deallocation function ``mj_freeFoo/mj_deleteFoo`` is automatically called when the Python
  189. object is deleted. The user does not need to manually free resources.
  190. The ``mujoco.MjModel`` class does not a have Python constructor. Instead, we provide three static factory functions
  191. that create a new :ref:`mjModel` instance: ``mujoco.MjModel.from_xml_string``, ``mujoco.MjModel.from_xml_path``, and
  192. ``mujoco.MjModel.from_binary_path``. The first function accepts a model XML as a string, while the latter two
  193. functions accept the path to either an XML or MJB model file. All three functions optionally accept a Python
  194. dictionary which is converted into a MuJoCo :ref:`Virtualfilesystem` for use during model compilation.
  195. .. _PyFunctions:
  196. Functions
  197. ---------
  198. MuJoCo functions are exposed as Python functions of the same name. Unlike with structs, we do not attempt to make
  199. the function names `PEP 8 <https://peps.python.org/pep-0008/>`__-compliant, as MuJoCo uses both underscores and
  200. CamelCases. In most cases, function arguments appear exactly as they do in C, and keyword arguments are supported
  201. with the same names as declared in :ref:`mujoco.h<inHeader>`. Python bindings to C functions that accept array input
  202. arguments expect NumPy arrays or iterable objects that are convertible to NumPy arrays (e.g. lists). Output
  203. arguments (i.e. array arguments that MuJoCo expect to write values back to the caller) must always be writeable
  204. NumPy arrays.
  205. In the C API, functions that take dynamically-sized arrays as inputs expect a pointer argument to the array along with
  206. an integer argument that specifies the array's size. In Python, the size arguments are omitted since we can
  207. automatically (and indeed, more safely) deduce it from the NumPy array. When calling these functions, pass all
  208. arguments other than array sizes in the same order as they appear in :ref:`mujoco.h<inHeader>`, or use keyword
  209. arguments. For example, :ref:`mj_jac` should be called as ``mujoco.mj_jac(m, d, jacp, jacr, point, body)`` in Python.
  210. The bindings **releases the Python Global Interpreter Lock (GIL)** before calling the underlying MuJoCo function.
  211. This allows for some thread-based parallelism, however users should bear in mind that the GIL is only released for the
  212. duration of the MuJoCo C function itself, and not during the execution of any other Python code.
  213. .. note::
  214. One place where the bindings do offer added functionality is the top-level :ref:`mj_step` function. Since it is
  215. often called in a loop, we have added an additional ``nstep`` argument, indicating how many times the underlying
  216. :ref:`mj_step` should be called. If not specified, ``nstep`` takes the default value of 1. The following two code
  217. snippets perform the same computation, but the first one does so without acquiring the GIL in between subsequent
  218. physics steps:
  219. .. code-block:: python
  220. mj_step(model, data, nstep=20)
  221. .. code-block:: python
  222. for _ in range(20):
  223. mj_step(model, data)
  224. .. _PyEnums:
  225. Enums and constants
  226. -------------------
  227. MuJoCo enums are available as ``mujoco.mjtEnumType.ENUM_VALUE``, for example ``mujoco.mjtObj.mjOBJ_SITE``. MuJoCo
  228. constants are available with the same name directly under the ``mujoco`` module, for example ``mujoco.mjVISSTRING``.
  229. .. _PyExample:
  230. Minimal example
  231. ---------------
  232. .. code-block:: python
  233. import mujoco
  234. XML=r"""
  235. <mujoco>
  236. <asset>
  237. <mesh file="gizmo.stl"/>
  238. </asset>
  239. <worldbody>
  240. <body>
  241. <freejoint/>
  242. <geom type="mesh" name="gizmo" mesh="gizmo"/>
  243. </body>
  244. </worldbody>
  245. </mujoco>
  246. """
  247. ASSETS=dict()
  248. with open('/path/to/gizmo.stl', 'rb') as f:
  249. ASSETS['gizmo.stl'] = f.read()
  250. model = mujoco.MjModel.from_xml_string(XML, ASSETS)
  251. data = mujoco.MjData(model)
  252. while data.time < 1:
  253. mujoco.mj_step(model, data)
  254. print(data.geom_xpos)
  255. .. _PyNamed:
  256. Named access
  257. ------------
  258. Most well-designed MuJoCo models assign names to objects (joints, geoms, bodies, etc.) of interest. When the model is
  259. compiled down to an ``mjModel`` instance, these names become associated with numeric IDs that are used to index into the
  260. various array members. For convenience and code readability, the Python bindings provide "named access" API on
  261. ``MjModel`` and ``MjData``. Each ``name_fooadr`` field in the ``mjModel`` struct defines a name category ``foo``.
  262. For each name category ``foo``, ``mujoco.MjModel`` and ``mujoco.MjData`` objects provide a method ``foo`` that takes
  263. a single string argument, and returns an accessor object for all arrays corresponding to the entity ``foo`` of the
  264. given name. The accessor object contains attributes whose names correspond to the fields of either ``mujoco.MjModel`` or
  265. ``mujoco.MjData`` but with the part before the underscore removed. In addition, accessor objects also provide ``id`` and
  266. ``name`` properties, which can be used as replacements for ``mj_name2id`` and ``mj_id2name`` respectively. For example:
  267. - ``m.geom('gizmo')`` returns an accessor for arrays in the ``MjModel`` object ``m`` associated with the geom named
  268. "gizmo".
  269. - ``m.geom('gizmo').rgba`` is a NumPy array view of length 4 that specifies the RGBA color for the geom.
  270. Specifically, it corresponds to the portion of ``m.geom_rgba[4*i:4*i+4]`` where
  271. ``i = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_GEOM, 'gizmo')``.
  272. - ``m.geom('gizmo').id`` is the same number as returned by ``mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_GEOM, 'gizmo')``.
  273. - ``m.geom(i).name`` is ``'gizmo'``, where ``i = mujoco.mj_name2id(m, mujoco.mjtObj.mjOBJ_GEOM, 'gizmo')``.
  274. Additionally, the Python API define a number of aliases for some name categories corresponding to the XML element name
  275. in the MJCF schema that defines an entity of that category. For example, ``m.joint('foo')`` is the same as
  276. ``m.jnt('foo')``. A complete list of these aliases are provided below.
  277. The accessor for joints is somewhat different that of the other categories. Some ``mjModel`` and ``mjData`` fields
  278. (those of size size ``nq`` or ``nv``) are associated with degrees of freedom (DoFs) rather than joints. This is because
  279. different types of joints have different numbers of DoFs. We nevertheless associate these fields to their corresponding
  280. joints, for example through ``d.joint('foo').qpos`` and ``d.joint('foo').qvel``, however the size of these arrays would
  281. differ between accessors depending on the joint's type.
  282. Named access is guaranteed to be O(1) in the number of entities in the model. In other words, the time it takes to
  283. access an entity by name does not grow with the number of names or entities in the model.
  284. For completeness, we provide here a complete list of all name categories in MuJoCo, along with their corresponding
  285. aliases defined in the Python API.
  286. - ``body``
  287. - ``jnt`` or ``joint``
  288. - ``geom``
  289. - ``site``
  290. - ``cam`` or ``camera``
  291. - ``light``
  292. - ``mesh``
  293. - ``skin``
  294. - ``hfield``
  295. - ``tex`` or ``texture``
  296. - ``mat`` or ``material``
  297. - ``pair``
  298. - ``exclude``
  299. - ``eq`` or ``equality``
  300. - ``tendon`` or ``ten``
  301. - ``actuator``
  302. - ``sensor``
  303. - ``numeric``
  304. - ``text``
  305. - ``tuple``
  306. - ``key`` or ``keyframe``
  307. .. _PyRender:
  308. Rendering
  309. ---------
  310. MuJoCo itself expects users to set up a working OpenGL context before calling any of its ``mjr_`` rendering routine.
  311. The Python bindings provide a basic class ``mujoco.GLContext`` that helps users set up such a context for offscreen
  312. rendering. To create a context, call ``ctx = mujoco.GLContext(max_width, max_height)``. Once the context is created,
  313. it must be made current before MuJoCo rendering functions can be called, which you can do so via ``ctx.make_current()``.
  314. Note that a context can only be made current on one thread at any given time, and all subsequent rendering calls must be
  315. made on the same thread.
  316. The context is freed automatically when the ``ctx`` object is deleted, but in some multi-threaded scenario it may be
  317. necessary to explicitly free the underlying OpenGL context. To do so, call ``ctx.free()``, after which point it is the
  318. user's responsibility to ensure that no further rendering calls are made on the context.
  319. Once the context is created, users can follow MuJoCo's standard rendering, for example as documented in the
  320. :ref:`Visualization` section.
  321. .. _PyError:
  322. Error handling
  323. --------------
  324. MuJoCo reports irrecoverable errors via the :ref:`mju_error` mechanism, which immediately terminates the entire process.
  325. Users are permitted to install a custom error handler via the :ref:`mju_user_error` callback, but it too is expected
  326. to terminate the process, otherwise the behavior of MuJoCo after the callback returns is undefined. In actuality, it is
  327. sufficient to ensure that error callbacks do not return *to MuJoCo*, but it is permitted to use
  328. `longjmp <https://en.cppreference.com/w/c/program/longjmp>`__ to skip MuJoCo's call stack back to the external callsite.
  329. The Python bindings utilizes longjmp to allow it to convert irrecoverable MuJoCo errors into Python exceptions of type
  330. ``mujoco.FatalError`` that can be caught and processed in the usual Pythonic way. Furthermore, it installs its error
  331. callback in a thread-local manner using a currently private API, thus allowing for concurrent calls into MuJoCo from
  332. multiple threads.
  333. .. _PyCallbacks:
  334. Callbacks
  335. ---------
  336. MuJoCo allows users to install custom callback functions to modify certain parts of its computation pipeline.
  337. For example, :ref:`mjcb_sensor` can be used to implement custom sensors, and :ref:`mjcb_control` can be used to
  338. implement custom actuators. Callbacks are exposed through the function pointers prefixed ``mjcb_`` in
  339. :ref:`mujoco.h<inHeader>`.
  340. For each callback ``mjcb_foo``, users can set it to a Python callable via ``mujoco.set_mjcb_foo(some_callable)``. To
  341. reset it, call ``mujoco.set_mjcb_foo(None)``. To retrieve the currently installed callback, call
  342. ``mujoco.get_mjcb_foo()``. (The getter **should not** be used if the callback is not installed via the Python bindings.)
  343. The bindings automatically acquire the GIL each time the callback is entered, and release it before reentering MuJoCo.
  344. This is likely to incur a severe performance impact as callbacks are triggered several times throughout MuJoCo's
  345. computation pipeline and is unlikely to be suitable for "production" use case. However, it is expected that this feature
  346. will be useful for prototyping complex models.
  347. Alternatively, if a callback is implemented in a native dynamic library, users can use
  348. `ctypes <https://docs.python.org/3/library/ctypes.html>`__ to obtain a Python handle to the C function pointer and pass
  349. it to ``mujoco.set_mjcb_foo``. The bindings will then retrieve the underlying function pointer and assign it directly to
  350. the raw callback pointer, and the GIL will **not** be acquired each time the callback is entered.
  351. .. _PyModelEdit:
  352. Model editing
  353. =============
  354. The :doc:`Model Editing<programming/modeledit>` framework which allows for procedural model manipulation is exposed
  355. via Python. In many ways this API is conceptually similar to ``dm_control``'s
  356. `PyMJCF module <https://github.com/google-deepmind/dm_control/tree/main/dm_control/mjcf#readme>`__, where ``MjSpec``
  357. plays the role of ``mjcf_model``. The largest difference between these two APIs is speed. Native model manipulation via
  358. ``MjSpec`` is around ~100x faster than PyMJCF.
  359. Below is a simple example of how to use the model editing API. For more examples, please refer to
  360. `specs_test.py <https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/specs_test.py>`__.
  361. .. code-block:: python
  362. import mujoco
  363. spec = mujoco.MjSpec()
  364. body = spec.worldbody.add_body(
  365. pos=[1, 2, 3],
  366. quat=[0, 1, 0, 0],
  367. )
  368. geom = body.add_geom(
  369. name='my_geom',
  370. type=mujoco.mjtGeom.mjGEOM_SPHERE,
  371. size=[1, 0, 0],
  372. rgba=[1, 0, 0, 1],
  373. )
  374. ...
  375. model = spec.compile()
  376. .. admonition:: Missing features
  377. :class: attention
  378. We are aware of multiple missing features in the Python API, including:
  379. - Better tree traversal utilities like :python:`children = body.children()` etc.
  380. - PyMJCF's notion of "binding", allowing access to :ref:`mjModel` and :ref:`mjData` values via the associated ``mjs``
  381. elements.
  382. There are certainly other missing features that we are not aware of. Please contact us on GitHub with feature
  383. requests or bug reports and we will prioritize accordingly.
  384. .. _PyBuild:
  385. Building from source
  386. ====================
  387. .. note::
  388. Building from source is only necessary if you are modifying the
  389. Python bindings (or are trying to run on exceptionally old Linux systems).
  390. If that's not the case, then we recommend installing the prebuilt binaries
  391. from PyPI.
  392. 1. Make sure you have CMake and a C++17 compiler installed.
  393. 2. Download the `latest binary release <https://github.com/google-deepmind/mujoco/releases>`__
  394. from GitHub. On macOS, the download corresponds to a DMG file which you can mount by
  395. double-clicking or running ``hdiutil attach <dmg_file>``.
  396. 3. Clone the entire ``mujoco`` repository from GitHub and ``cd`` into the python
  397. directory:
  398. .. code-block:: shell
  399. git clone https://github.com/google-deepmind/mujoco.git
  400. cd mujoco/python
  401. 4. Create a virtual environment:
  402. .. code-block:: shell
  403. python3 -m venv /tmp/mujoco
  404. source /tmp/mujoco/bin/activate
  405. 5. Generate a `source distribution <https://packaging.python.org/en/latest/glossary/#term-Source-Distribution-or-sdist>`__
  406. tarball with the ``make_sdist.sh`` script.
  407. .. code-block:: shell
  408. bash make_sdist.sh
  409. The ``make_sdist.sh`` script generates additional C++ header files that are
  410. needed to build the bindings, and also pulls in required files from elsewhere
  411. in the repository outside the ``python`` directory into the sdist. Upon
  412. completion, the script will create a ``dist`` directory with a
  413. ``mujoco-x.y.z.tar.gz`` file (where ``x.y.z`` is the version number).
  414. 6. Use the generated source distribution to build and install the bindings.
  415. You'll need to specify the path to the MuJoCo library you downloaded earlier
  416. in the ``MUJOCO_PATH`` environment variable, and the path to the MuJoCo
  417. plugin directory in the ``MUJOCO_PLUGIN_PATH`` environment variable.
  418. .. note::
  419. For macOS, the files need to be extracted from the DMG.
  420. Once you mounted it as in step 2, the ``mujoco.framework`` directory can be found in ``/Volumes/MuJoCo``,
  421. and the plugins directory can be found in ``/Volumes/MuJoCo/MuJoCo.app/Contents/MacOS/mujoco_plugin``.
  422. Those two directories can be copied out somewhere convenient, or you can use
  423. ``MUJOCO_PATH=/Volumes/MuJoCo MUJOCO_PLUGIN_PATH=/Volumes/MuJoCo/MuJoCo.app/Contents/MacOS/mujoco_plugin``.
  424. .. code-block:: shell
  425. cd dist
  426. MUJOCO_PATH=/PATH/TO/MUJOCO \
  427. MUJOCO_PLUGIN_PATH=/PATH/TO/MUJOCO_PLUGIN \
  428. pip install mujoco-x.y.z.tar.gz
  429. The Python bindings should now be installed! To check that they've been
  430. successfully installed, ``cd`` outside of the ``mujoco`` directory and run
  431. ``python -c "import mujoco"``.
  432. .. tip::
  433. As a reference, a working build configuration can be found in MuJoCo's
  434. `continuous integration setup <https://github.com/google-deepmind/mujoco/blob/main/.github/workflows/build.yml>`_ on
  435. GitHub.
  436. .. _PyModule:
  437. Modules
  438. =======
  439. The ``mujoco`` package contains two sub-modules: ``mujoco.rollout`` and ``mujoco.minimize``
  440. .. _PyRollout:
  441. rollout
  442. -------
  443. ``mujoco.rollout`` shows how to add additional C/C++ functionality, exposed as a Python module via pybind11. It is
  444. implemented in `rollout.cc <https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/rollout.cc>`__
  445. and wrapped in `rollout.py <https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/rollout.py>`__. The module
  446. performs a common functionality where tight loops implemented outside of Python are beneficial: rolling out a trajectory
  447. (i.e., calling :ref:`mj_step` in a loop), given an intial state and sequence of controls, and returning subsequent
  448. states and sensor values. The basic usage form is
  449. .. code-block:: python
  450. state, sensordata = rollout.rollout(model, data, initial_state, control)
  451. ``initial_state`` is an ``nroll x nstate`` array, with ``nroll`` initial states of size ``nstate``, where
  452. ``nstate = mj_stateSize(model, mjtState.mjSTATE_FULLPHYSICS)`` is the size of the
  453. :ref:`full physics state<geFullPhysics>`. ``control`` is a ``nroll x nstep x ncontrol`` array of controls. Controls are
  454. by default the ``mjModel.nu`` standard actuators, but any combination of :ref:`user input<geInput>` arrays can be
  455. specified by passing an optional ``control_spec`` bitflag.
  456. If a rollout diverges, the current state and sensor values are used to fill the remainder of the trajectory.
  457. Therefore, non-increasing time values can be used to detect diverged rollouts.
  458. The ``rollout`` function is designed to be completely stateless, so all inputs of the stepping pipeline are set and any
  459. values already present in the given ``MjData`` instance will have no effect on the output.
  460. Since the Global Interpreter Lock can be released, this function can be efficiently threaded using Python threads. See
  461. the ``test_threading`` function in
  462. `rollout_test.py <https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/rollout_test.py>`__ for an example
  463. of threaded operation (and more generally for usage examples).
  464. .. _PyMinimize:
  465. minimize
  466. --------
  467. This module contains optimization-related utilities.
  468. The ``minimize.least_squares()`` function implements a nonlinear Least Squares optimizer solving sequential
  469. Quadratic Programs with :ref:`mju_boxQP`. It is documented in the associated notebook: |lscolab|
  470. .. |lscolab| image:: https://colab.research.google.com/assets/colab-badge.svg
  471. :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/least_squares.ipynb
  472. .. _PyUSDexport:
  473. USD exporter
  474. ------------
  475. The `USD exporter <https://github.com/google-deepmind/mujoco/tree/main/python/mujoco/usd>`__ module allows users to save
  476. scenes and trajectories in the `USD format <https://openusd.org/release/index.html>`__ for rendering in external
  477. renderers such as NVIDIA Omniverse or Blender. These renderers provide higher quality rendering capabilities not
  478. provided by the default renderer. Additionally, exporting to USD allows users to include different types of texture maps
  479. to make objects in the scene look more realistic.
  480. .. _PyUSDInstallation:
  481. Installation
  482. ^^^^^^^^^^^^
  483. The recommended way to install the necessary requirements for the USD exporter is via
  484. `PyPI <https://pypi.org/project/mujoco/>`__:
  485. .. code-block:: shell
  486. pip install mujoco[usd]
  487. This installs the optional dependencies ``usd-core`` and ``pillow`` required by the USD exporter.
  488. If you are building from source, please ensure to `build the Python bindings
  489. <https://mujoco.readthedocs.io/en/stable/python.html#building-from-source>`__. Then, using pip, install the required
  490. ``usd-core`` and ``pillow`` packages.
  491. .. _PyUSDExporter:
  492. USDExporter
  493. ^^^^^^^^^^^
  494. The ``USDExporter`` class in the ``mujoco.usd.exporter`` module allows saving full trajectories in addition to defining
  495. custom cameras and lights. The constructor arguments of a ``USDExporter`` instance are:
  496. - ``model``: An MjModel instance. The USD exporter reads relevant information from the model including details about
  497. cameras, lights, textures, and object geometries.
  498. - ``max_geom``: Maximum number of geoms in a scene, required when instatiating the internal .
  499. `mjvScene <https://mujoco.readthedocs.io/en/stable/APIreference/APItypes.html#mjvscene>`__.
  500. - ``output_directory``: Name of the directory under which the exported USD file and all relevant
  501. assets are stored. When saving a scene/trajectory as a USD file, the exporter creates the following directory
  502. structure.
  503. .. code-block:: text
  504. output_directory_root/
  505. └-output_directory/
  506. ├-assets/
  507. | ├-texture_0.png
  508. | ├-texture_1.png
  509. | └-...
  510. └─frames/
  511. └-frame_301.usd
  512. Using this file structure allows users to easily archive the ``output_directory``. All paths to assets in the USD file
  513. are relative, facilitating the use of the USD archive on another machine.
  514. - ``output_directory_root``: Root directory to add USD trajectory to.
  515. - ``light_intensity``: Intensity of all lights. Note that the units of intensity may be defined differently in
  516. different renderers, so this value may need to be adjusted on a render-specific basis.
  517. - ``camera_names``: List of cameras to be stored in the USD file. At each time step, for each camera defined, we
  518. calculate its position and orientation and add that value for that given frame in the USD. USD allows us to store
  519. multiple cameras.
  520. - ``verbose``: Whether or not to print log messages from the exporter.
  521. If you wish to export a model loaded directly from an MJCF, we provide a `demo
  522. <https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/usd/demo.py>`__ script that shows how to do so. This
  523. demo file also serves as an example of the USD export functionality.
  524. .. _PyUSDBasicUsage:
  525. Basic usage
  526. ^^^^^^^^^^^
  527. Once the optional dependencies are installed, the USD exporter can be imported via ``from mujoco.usd import exporter``.
  528. Below, we demonstrate a simple example of using the ``USDExporter``. During initialization, the ``USDExporter`` creates
  529. an empty USD stage, as well as the assets and frames directories if they do not already exist. Additionally, it
  530. generates .png files for each texture defined in the model. Every time ``update_scene`` is called, the exporter records
  531. the position and orientation of all geoms, lights, and cameras in the scene.
  532. The ``USDExporter`` keeps track of frames internally by maintaining a frame counter. Each time ``update_scene`` is
  533. called, the counter is incremented, and the poses of all geoms, cameras, and lights are saved for the corresponding
  534. frame. It's important to note that you can step through the simulation multiple times before calling ``update_scene``.
  535. The final USD file will only store the poses of the geoms, lights, and cameras as they were at the last update_scene
  536. call.
  537. .. code-block:: python
  538. import mujoco
  539. from mujoco.usd import exporter
  540. m = mujoco.MjModel.from_xml_path('/path/to/mjcf.xml')
  541. d = mujoco.MjData(m)
  542. # Create the USDExporter
  543. exp = exporter.USDExporter(model=m)
  544. duration = 5
  545. framerate = 60
  546. while d.time < duration:
  547. # Step the physics
  548. mujoco.mj_step(m, d)
  549. if exp.frame_count < d.time * framerate:
  550. # Update the USD with a new frame
  551. exp.update_scene(data=d)
  552. # Export the USD file
  553. exp.save_scene(filetype="usd")
  554. .. _PyUSDExportAPI:
  555. USD Export API
  556. ^^^^^^^^^^^^^^
  557. - ``update_scene(self, data, scene_option)``: updates the scene with the latest simulation data passed in by the
  558. user. This function updates the geom, cameras, and lights in the scene.
  559. - ``add_light(self, pos, intensity, radius, color, obj_name, light_type)``: adds a light to the USD scene with the
  560. given properties post hoc.
  561. - ``add_camera(self, pos, rotation_xyz, obj_name)``: adds a camera to the USD scene with the given properties post hoc.
  562. - ``save_scene(self, filetype)``: exports the USD scene using one of the usd filetype extensions ``.usd``, ``.usda``,
  563. or ``.usdc``.
  564. .. _PyUSDTodos:
  565. Missing features
  566. ^^^^^^^^^^^^^^^^
  567. Below, we list remaining action items for the USD exporter. Please feel free to suggest additional requests
  568. by creating a new `feature request <https://github.com/google-deepmind/mujoco/issues/new/choose>`__ in GitHub.
  569. - Add support for additional texture maps including metallic, occlusion, roughness, bump, etc.
  570. - Add support for online rendering with Isaac.
  571. - Add support for custom cameras.
  572. .. _PyUtility:
  573. Utilities
  574. =========
  575. The `python/mujoco <https://github.com/google-deepmind/mujoco/tree/main/python/mujoco>`__ directory also contains
  576. utility scripts.
  577. .. _PyMsh2obj:
  578. msh2obj.py
  579. ----------
  580. The `msh2obj.py <https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/msh2obj.py>`__ script converts the
  581. :ref:`legacy .msh format<legacy-msh-docs>` for surface meshes (different from the possibly-volumetric
  582. :ref:`gmsh format<gmsh-file-docs>` also using .msh), to OBJ files. The legacy format is deprecated and will be removed
  583. in a future release. Please convert all legacy files to OBJ.
  584. .. _PyMjpy_migration:
  585. mujoco-py migration
  586. ===================
  587. In mujoco-py, the main entry point is the `MjSim <https://github.com/openai/mujoco-py/blob/master/mujoco_py/mjsim.pyx>`_
  588. class. Users construct a stateful ``MjSim`` instance from an MJCF model (similar to ``dm_control.Physics``), and this
  589. instance holds references to an ``mjModel`` instance and its associated ``mjData``. In contrast, the MuJoCo Python
  590. bindings (``mujoco``) take a more low-level approach, as explained above: following the design principle of the C
  591. library, the ``mujoco`` module itself is stateless, and merely wraps the underlying native structs and functions.
  592. While a complete survey of mujoco-py is beyond the scope of this document, we offer below implementation notes for a
  593. non-exhaustive list of specific mujoco-py features:
  594. ``mujoco_py.load_model_from_xml(bstring)``
  595. This factory function constructs a stateful ``MjSim`` instance. When using ``mujoco``, the user should call the
  596. factory function ``mujoco.MjModel.from_xml_*`` as described :ref:`above <PyStructs>`. The user is then responsible
  597. for holding the resulting ``MjModel`` struct instance and explicitly generating the corresponding ``MjData`` by
  598. calling ``mujoco.MjData(model)``.
  599. ``sim.reset()``, ``sim.forward()``, ``sim.step()``
  600. Here as above, ``mujoco`` users needs to call the underlying library functions, passing instances of ``MjModel`` and
  601. ``MjData``: :ref:`mujoco.mj_resetData(model, data) <mj_resetData>`, :ref:`mujoco.mj_forward(model, data)
  602. <mj_forward>`, and :ref:`mujoco.mj_step(model, data) <mj_step>`.
  603. ``sim.get_state()``, ``sim.set_state(state)``, ``sim.get_flattened_state()``, ``sim.set_state_from_flattened(state)``
  604. The MuJoCo library’s computation is deterministic given a specific input, as explained in the :ref:`Programming
  605. section <Simulation>`. mujoco-py implements methods for getting and setting some of the relevant fields (and
  606. similarly ``dm_control.Physics`` offers methods that correspond to the flattened case). ``mujoco`` do not offer such
  607. abstraction, and the user is expected to get/set the values of the relevant fields explicitly.
  608. ``sim.model.get_joint_qvel_addr(joint_name)``
  609. This is a convenience method in mujoco-py that returns a list of contiguous indices corresponding to this joint. The
  610. list starts from ``model.jnt_qposadr[joint_index]``, and its length depends on the joint type. ``mujoco`` doesn't
  611. offer this functionality, but this list can be easily constructed using ``model.jnt_qposadr[joint_index]`` and
  612. ``xrange``.
  613. ``sim.model.*_name2id(name)``
  614. mujoco-py creates dicts in ``MjSim`` that allow for efficient lookup of indices for objects of different types:
  615. ``site_name2id``, ``body_name2id`` etc. These functions replace the function :ref:`mujoco.mj_name2id(model,
  616. type_enum, name) <mj_name2id>`. ``mujoco`` offers a different approach for using entity names – :ref:`named access
  617. <PyNamed>`, as well as access to the native :ref:`mj_name2id`.
  618. ``sim.save(fstream, format_name)``
  619. This is the one context in which the MuJoCo library (and therefore also ``mujoco``) is stateful: it holds a copy in
  620. memory of the last XML that was compiled, which is used in :ref:`mujoco.mj_saveLastXML(fname) <mj_saveLastXML>`. Note
  621. that mujoco-py’s implementation has a convenient extra feature, whereby the pose (as determined by ``sim.data``’s
  622. state) is transformed to a keyframe that’s added to the model before saving. This extra feature is not currently
  623. available in ``mujoco``.