Rename Python mujoco.simulate to mujoco.viewer.
PiperOrigin-RevId: 492701386 Change-Id: I059c572e2a63bd5529e863a9404720973df8ea46
This commit is contained in:
committed by
Copybara-Service
parent
dee1d6020a
commit
0846f38c82
+2
-2
@@ -9,8 +9,8 @@ Upcoming version (not yet released)
|
|||||||
Python bindings
|
Python bindings
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
- The ``simulate`` GUI is now available through the ``mujoco`` Python package. See :ref:`documentation<PyGUI>` for
|
- The ``simulate`` GUI is now available through the ``mujoco`` Python package as ``mujoco.viewer``.
|
||||||
details. (Contribution by `Levi Burner <https://github.com/aftersomemath>`_.)
|
See :ref:`documentation<PyViewer>` for details. (Contribution by `Levi Burner <https://github.com/aftersomemath>`_.)
|
||||||
|
|
||||||
General
|
General
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|||||||
+167
-167
@@ -102,8 +102,41 @@ The Python bindings should now be installed! To check that they've been
|
|||||||
successfully installed, ``cd`` outside of the ``mujoco`` directory and run
|
successfully installed, ``cd`` outside of the ``mujoco`` directory and run
|
||||||
``python -c "import mujoco"``.
|
``python -c "import mujoco"``.
|
||||||
|
|
||||||
|
.. _PyViewer:
|
||||||
|
|
||||||
|
Interactive viewer
|
||||||
|
==================
|
||||||
|
|
||||||
|
An interactive GUI viewer is available as part of the Python package. (This is the same viewer as the ``simulate``
|
||||||
|
application that ships with the MuJoCo binary releases.)
|
||||||
|
|
||||||
|
Three distinct use cases are supported:
|
||||||
|
|
||||||
|
#. Launching as a standalone application:
|
||||||
|
|
||||||
|
- ``python -m mujoco.viewer`` launches an empty visualization session, where a model can be loaded by drag-and-drop.
|
||||||
|
- ``python -m mujoco.viewer --mjcf=/path/to/some/mjcf.xml`` launches a visualization session for the specified
|
||||||
|
model file.
|
||||||
|
|
||||||
|
#. Launching from a Python program/script -- import the module via ``from mujoco import viewer`` and launch the GUI
|
||||||
|
using one of the following invocations:
|
||||||
|
|
||||||
|
- ``viewer.launch()`` launches an empty visualization session, where a model can be loaded by drag-and-drop.
|
||||||
|
- ``viewer.launch(model)`` launches a visualzation session for the given ``mjModel`` where the visualizer
|
||||||
|
internally creates its own instance of ``mjData``
|
||||||
|
- ``viewer.launch(model, data)`` is the same as above, except that the visualizer operates directly on the given
|
||||||
|
``mjData`` instance -- upon exit the ``data`` object will have been modified.
|
||||||
|
|
||||||
|
#. Launching from an interactive Python session (aka REPL): when working interactively either in a ``python`` or
|
||||||
|
``ipython`` shell, the visualizer can be launched in a "passive" mode via ``viewer.launch_repl(model, data)``, where
|
||||||
|
the user remains in full control of modifying or stepping the physics. In this mode, the user can interact with the
|
||||||
|
visualizer using the mouse and keyboard as usual, however the physics will be frozen unless the user explicitly calls
|
||||||
|
``mj_step`` (or perform any other modification of the ``mjData`` or ``mjModel``) in the REPL terminal. Note that since
|
||||||
|
the visualizer does not modify ``mjData`` in this mode, mouse-drag perturbations will not work unless the user
|
||||||
|
explicitly handles incoming GUI perturbation events in the REPL session.
|
||||||
|
|
||||||
Basic usage
|
Basic usage
|
||||||
-----------
|
===========
|
||||||
|
|
||||||
Once installed, the package can be imported via ``import mujoco``. Structs, functions, constants, and enums are
|
Once installed, the package can be imported via ``import mujoco``. Structs, functions, constants, and enums are
|
||||||
available directly from the top-level ``mujoco`` module.
|
available directly from the top-level ``mujoco`` module.
|
||||||
@@ -111,135 +144,102 @@ available directly from the top-level ``mujoco`` module.
|
|||||||
.. _PyStructs:
|
.. _PyStructs:
|
||||||
|
|
||||||
Structs
|
Structs
|
||||||
=======
|
-------
|
||||||
|
|
||||||
MuJoCo data structures are exposed as Python classes. In order to conform to
|
MuJoCo data structures are exposed as Python classes. In order to conform to
|
||||||
`PEP 8 <https://peps.python.org/pep-0008/>`__ naming guidelines, struct names begin with a capital letter, for example
|
`PEP 8 <https://peps.python.org/pep-0008/>`__ naming guidelines, struct names begin with a capital letter, for example
|
||||||
``mjData`` becomes ``mujoco.MjData`` in Python.
|
``mjData`` becomes ``mujoco.MjData`` in Python.
|
||||||
|
|
||||||
All structs other than ``mjModel`` have constructors in Python. For structs that have an ``mj_defaultFoo``-style
|
All structs other than ``mjModel`` have constructors in Python. For structs that have an ``mj_defaultFoo``-style
|
||||||
initialization function, the Python constructor calls the default initializer automatically, so for example
|
initialization function, the Python constructor calls the default initializer automatically, so for example
|
||||||
``mujoco.MjOption()`` creates a new ``mjOption`` instance that is pre-initialized with :ref:`mj_defaultOption`.
|
``mujoco.MjOption()`` creates a new ``mjOption`` instance that is pre-initialized with :ref:`mj_defaultOption`.
|
||||||
Otherwise, the Python constructor zero-initializes the underlying C struct.
|
Otherwise, the Python constructor zero-initializes the underlying C struct.
|
||||||
|
|
||||||
Structs with a ``mj_makeFoo``-style initialization function have corresponding constructor overloads in Python,
|
Structs with a ``mj_makeFoo``-style initialization function have corresponding constructor overloads in Python,
|
||||||
for example ``mujoco.MjvScene(model, maxgeom=10)`` in Python creates a new ``mjvScene`` instance that is
|
for example ``mujoco.MjvScene(model, maxgeom=10)`` in Python creates a new ``mjvScene`` instance that is
|
||||||
initialized with ``mjv_makeScene(model, [the new mjvScene instance], 10)`` in C. When this form of initialization is
|
initialized with ``mjv_makeScene(model, [the new mjvScene instance], 10)`` in C. When this form of initialization is
|
||||||
used, the corresponding deallocation function ``mj_freeFoo/mj_deleteFoo`` is automatically called when the Python
|
used, the corresponding deallocation function ``mj_freeFoo/mj_deleteFoo`` is automatically called when the Python
|
||||||
object is deleted. The user does not need to manually free resources.
|
object is deleted. The user does not need to manually free resources.
|
||||||
|
|
||||||
The ``mujoco.MjModel`` class does not a have Python constructor. Instead, we provide three static factory functions
|
The ``mujoco.MjModel`` class does not a have Python constructor. Instead, we provide three static factory functions
|
||||||
that create a new ``mjModel`` instance: ``mujoco.MjModel.from_xml_string``, ``mujoco.MjModel.from_xml_path``, and
|
that create a new ``mjModel`` instance: ``mujoco.MjModel.from_xml_string``, ``mujoco.MjModel.from_xml_path``, and
|
||||||
``mujoco.MjModel.from_binary_path``. The first function accepts a model XML as a string, while the latter two
|
``mujoco.MjModel.from_binary_path``. The first function accepts a model XML as a string, while the latter two
|
||||||
functions accept the path to either an XML or MJB model file. All three functions optionally accept a Python
|
functions accept the path to either an XML or MJB model file. All three functions optionally accept a Python
|
||||||
dictionary which is converted into a MuJoCo :ref:`Virtualfilesystem` for use during model compilation.
|
dictionary which is converted into a MuJoCo :ref:`Virtualfilesystem` for use during model compilation.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
=========
|
---------
|
||||||
|
|
||||||
MuJoCo functions are exposed as Python functions of the same name. Unlike with structs, we do not attempt to make
|
MuJoCo functions are exposed as Python functions of the same name. Unlike with structs, we do not attempt to make
|
||||||
the function names `PEP 8 <https://peps.python.org/pep-0008/>`__-compliant, as MuJoCo uses both underscores and
|
the function names `PEP 8 <https://peps.python.org/pep-0008/>`__-compliant, as MuJoCo uses both underscores and
|
||||||
CamelCases. In most cases, function arguments appear exactly as they do in C, and keyword arguments are supported
|
CamelCases. In most cases, function arguments appear exactly as they do in C, and keyword arguments are supported
|
||||||
with the same names as declared in :ref:`mujoco.h<inHeader>`. Python bindings to C functions that accept array input
|
with the same names as declared in :ref:`mujoco.h<inHeader>`. Python bindings to C functions that accept array input
|
||||||
arguments expect NumPy arrays or iterable objects that are convertible to NumPy arrays (e.g. lists). Output
|
arguments expect NumPy arrays or iterable objects that are convertible to NumPy arrays (e.g. lists). Output
|
||||||
arguments (i.e. array arguments that MuJoCo expect to write values back to the caller) must always be writeable
|
arguments (i.e. array arguments that MuJoCo expect to write values back to the caller) must always be writeable
|
||||||
NumPy arrays.
|
NumPy arrays.
|
||||||
|
|
||||||
In the C API, functions that take dynamically-sized arrays as inputs expect a pointer argument to the array along with
|
In the C API, functions that take dynamically-sized arrays as inputs expect a pointer argument to the array along with
|
||||||
an integer argument that specifies the array's size. In Python, the size arguments are omitted since we can
|
an integer argument that specifies the array's size. In Python, the size arguments are omitted since we can
|
||||||
automatically (and indeed, more safely) deduce it from the NumPy array. When calling these functions, pass all
|
automatically (and indeed, more safely) deduce it from the NumPy array. When calling these functions, pass all
|
||||||
arguments other than array sizes in the same order as they appear in :ref:`mujoco.h<inHeader>`, or use keyword
|
arguments other than array sizes in the same order as they appear in :ref:`mujoco.h<inHeader>`, or use keyword
|
||||||
arguments. For example, :ref:`mj_jac` should be called as ``mujoco.mj_jac(m, d, jacp, jacr, point, body)`` in Python.
|
arguments. For example, :ref:`mj_jac` should be called as ``mujoco.mj_jac(m, d, jacp, jacr, point, body)`` in Python.
|
||||||
|
|
||||||
The bindings **releases the Python Global Interpreter Lock (GIL)** before calling the underlying MuJoCo function.
|
The bindings **releases the Python Global Interpreter Lock (GIL)** before calling the underlying MuJoCo function.
|
||||||
This allows for some thread-based parallelism, however users should bear in mind that the GIL is only released for the
|
This allows for some thread-based parallelism, however users should bear in mind that the GIL is only released for the
|
||||||
duration of the MuJoCo C function itself, and not during the execution of any other Python code.
|
duration of the MuJoCo C function itself, and not during the execution of any other Python code.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
One place where the bindings do offer added functionality is the top-level :ref:`mj_step` function. Since it is
|
One place where the bindings do offer added functionality is the top-level :ref:`mj_step` function. Since it is
|
||||||
often called in a loop, we have added an additional ``nstep`` argument, indicating how many times the underlying
|
often called in a loop, we have added an additional ``nstep`` argument, indicating how many times the underlying
|
||||||
:ref:`mj_step` should be called. If not specified, ``nstep`` takes the default value of 1. The following two code
|
:ref:`mj_step` should be called. If not specified, ``nstep`` takes the default value of 1. The following two code
|
||||||
snippets perform the same computation, but the first one does so without acquiring the GIL in between subsequent
|
snippets perform the same computation, but the first one does so without acquiring the GIL in between subsequent
|
||||||
physics steps:
|
physics steps:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
mj_step(model, data, nstep=20)
|
mj_step(model, data, nstep=20)
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
for _ in range(20):
|
|
||||||
mj_step(model, data)
|
|
||||||
|
|
||||||
|
for _ in range(20):
|
||||||
|
mj_step(model, data)
|
||||||
|
|
||||||
Enums and constants
|
Enums and constants
|
||||||
===================
|
-------------------
|
||||||
|
|
||||||
MuJoCo enums are available as ``mujoco.mjtEnumType.ENUM_VALUE``, for example ``mujoco.mjtObj.mjOBJ_SITE``. MuJoCo
|
MuJoCo enums are available as ``mujoco.mjtEnumType.ENUM_VALUE``, for example ``mujoco.mjtObj.mjOBJ_SITE``. MuJoCo
|
||||||
constants are available with the same name directly under the ``mujoco`` module, for example ``mujoco.mjVISSTRING``.
|
constants are available with the same name directly under the ``mujoco`` module, for example ``mujoco.mjVISSTRING``.
|
||||||
|
|
||||||
Minimal example
|
Minimal example
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import mujoco
|
import mujoco
|
||||||
|
|
||||||
XML=r"""
|
XML=r"""
|
||||||
<mujoco>
|
<mujoco>
|
||||||
<asset>
|
<asset>
|
||||||
<mesh file="gizmo.stl"/>
|
<mesh file="gizmo.stl"/>
|
||||||
</asset>
|
</asset>
|
||||||
<worldbody>
|
<worldbody>
|
||||||
<body>
|
<body>
|
||||||
<freejoint/>
|
<freejoint/>
|
||||||
<geom type="mesh" name="gizmo" mesh="gizmo"/>
|
<geom type="mesh" name="gizmo" mesh="gizmo"/>
|
||||||
</body>
|
</body>
|
||||||
</worldbody>
|
</worldbody>
|
||||||
</mujoco>
|
</mujoco>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ASSETS=dict()
|
ASSETS=dict()
|
||||||
with open('/path/to/gizmo.stl', 'rb') as f:
|
with open('/path/to/gizmo.stl', 'rb') as f:
|
||||||
ASSETS['gizmo.stl'] = f.read()
|
ASSETS['gizmo.stl'] = f.read()
|
||||||
|
|
||||||
model = mujoco.MjModel.from_xml_string(XML, ASSETS)
|
|
||||||
data = mujoco.MjData(model)
|
|
||||||
while data.time < 1:
|
|
||||||
mujoco.mj_step(model, data)
|
|
||||||
print(data.geom_xpos)
|
|
||||||
|
|
||||||
.. _PyGUI:
|
|
||||||
|
|
||||||
Interactive visualizer
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
MuJoCo's interactive GUI (also known as the ``simulate`` application) is available as part of the Python package.
|
|
||||||
Three distinct use cases are supported:
|
|
||||||
|
|
||||||
- Launching as a standalone application:
|
|
||||||
|
|
||||||
* ``python -m mujoco.simulate`` launches an empty visualization session, where a model can be loaded by drag-and-drop.
|
|
||||||
* ``python -m mujoco.simulate --mjcf=/path/to/some/mjcf.xml`` launches a visualization session for the specified
|
|
||||||
model file.
|
|
||||||
|
|
||||||
- Launching from a Python program/script -- import the module via ``from mujoco import simulate`` and launch the GUI
|
|
||||||
using one of the following invocations:
|
|
||||||
|
|
||||||
* ``simulate.launch()`` launches an empty visualization session, where a model can be loaded by drag-and-drop.
|
|
||||||
* ``simulate.launch(model)`` launches a visualzation session for the given ``mjModel`` where the visualizer
|
|
||||||
internally creates its own instance of ``mjData``
|
|
||||||
* ``simulate.launch(model, data)`` is the same as above, except that the visualizer operates directly on the given
|
|
||||||
``mjData`` instance -- upon exit the ``data`` object will have been modified.
|
|
||||||
|
|
||||||
- Launching from an interactive Python session (aka REPL): when working interactively either in a ``python`` or
|
|
||||||
``ipython`` shell, the visualizer can be launched in a "passive" mode via ``simulate.launch_repl(model, data)``, where
|
|
||||||
the user remains in full control of modifying or stepping the physics. In this mode, the user can interact with the
|
|
||||||
visualizer using the mouse and keyboard as usual, however the physics will be frozen unless the user explicitly calls
|
|
||||||
``mj_step`` (or perform any other modification of the ``mjData`` or ``mjModel``) in the REPL terminal. Note that since
|
|
||||||
the visualizer does not modify ``mjData`` in this mode, mouse-drag perturbations will not work unless the user
|
|
||||||
explicitly handles incoming GUI perturbation events in the REPL session.
|
|
||||||
|
|
||||||
|
model = mujoco.MjModel.from_xml_string(XML, ASSETS)
|
||||||
|
data = mujoco.MjData(model)
|
||||||
|
while data.time < 1:
|
||||||
|
mujoco.mj_step(model, data)
|
||||||
|
print(data.geom_xpos)
|
||||||
|
|
||||||
.. _PyNamed:
|
.. _PyNamed:
|
||||||
|
|
||||||
@@ -356,69 +356,8 @@ Alternatively, if a callback is implemented in a native dynamic library, users c
|
|||||||
it to ``mujoco.set_mjcb_foo``. The bindings will then retrieve the underlying function pointer and assign it directly to
|
it to ``mujoco.set_mjcb_foo``. The bindings will then retrieve the underlying function pointer and assign it directly to
|
||||||
the raw callback pointer, and the GIL will **not** be acquired each time the callback is entered.
|
the raw callback pointer, and the GIL will **not** be acquired each time the callback is entered.
|
||||||
|
|
||||||
.. _PyMjpy_migration:
|
|
||||||
|
|
||||||
Migration Notes for mujoco-py
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
In mujoco-py, the main entry point is the `MjSim <https://github.com/openai/mujoco-py/blob/master/mujoco_py/mjsim.pyx>`_
|
|
||||||
class. Users construct a stateful ``MjSim`` instance from an MJCF model (similar to ``dm_control.Physics``), and this
|
|
||||||
instance holds references to an ``mjModel`` instance and its associated ``mjData``. In contrast, the MuJoCo Python
|
|
||||||
bindings (``mujoco``) take a more low-level approach, as explained above: following the design principle of the C
|
|
||||||
library, the ``mujoco`` module itself is stateless, and merely wraps the underlying native structs and functions.
|
|
||||||
|
|
||||||
While a complete survey of mujoco-py is beyond the scope of this document, we offer below implementation notes for a
|
|
||||||
non-exhaustive list of specific mujoco-py features:
|
|
||||||
|
|
||||||
``mujoco_py.load_model_from_xml(bstring)``
|
|
||||||
===========================================
|
|
||||||
|
|
||||||
This factory function constructs a stateful ``MjSim`` instance. When using ``mujoco``, the user should call the factory
|
|
||||||
function ``mujoco.MjModel.from_xml_*`` as described :ref:`above <PyStructs>`. The user is then responsible for holding
|
|
||||||
the resulting ``MjModel`` struct instance and explicitly generating the corresponding ``MjData`` by calling
|
|
||||||
``mujoco.MjData(model)``.
|
|
||||||
|
|
||||||
``sim.reset()``, ``sim.forward()``, ``sim.step()``
|
|
||||||
==================================================
|
|
||||||
|
|
||||||
Here as above, ``mujoco`` users needs to call the underlying library functions, passing instances of ``MjModel`` and
|
|
||||||
``MjData``: :ref:`mujoco.mj_resetData(model, data) <mj_resetData>`, :ref:`mujoco.mj_forward(model, data) <mj_forward>`,
|
|
||||||
and :ref:`mujoco.mj_step(model, data) <mj_step>`.
|
|
||||||
|
|
||||||
``sim.get_state()``, ``sim.set_state(state)``, ``sim.get_flattened_state()``, ``sim.set_state_from_flattened(state)``
|
|
||||||
=====================================================================================================================
|
|
||||||
|
|
||||||
The MuJoCo library’s computation is deterministic given a specific input, as explained in the :ref:`Programming section
|
|
||||||
<Simulation>`. mujoco-py implements methods for getting and setting some of the relevant fields (and similarly
|
|
||||||
``dm_control.Physics`` offers methods that correspond to the flattened case). ``mujoco`` do not offer such abstraction,
|
|
||||||
and the user is expected to get/set the values of the relevant fields explicitly.
|
|
||||||
|
|
||||||
``sim.model.get_joint_qvel_addr(joint_name)``
|
|
||||||
=============================================
|
|
||||||
|
|
||||||
This is a convenience method in mujoco-py that returns a list of contiguous indices corresponding to this joint. The
|
|
||||||
list starts from ``model.jnt_qposadr[joint_index]``, and its length depends on the joint type. ``mujoco`` doesn't offer
|
|
||||||
this functionality, but this list can be easily constructed using ``model.jnt_qposadr[joint_index]`` and ``xrange``.
|
|
||||||
|
|
||||||
``sim.model.*_name2id(name)``
|
|
||||||
=============================
|
|
||||||
|
|
||||||
mujoco-py creates dicts in ``MjSim`` that allow for efficient lookup of indices for objects of different types:
|
|
||||||
``site_name2id``, ``body_name2id`` etc. These functions replace the function :ref:`mujoco.mj_name2id(model, type_enum,
|
|
||||||
name) <mj_name2id>` whose current implementation is inefficient. ``mujoco`` offers a different
|
|
||||||
approach for using entity names – :ref:`named access <PyNamed>`, as well as access to the native :ref:`mj_name2id`.
|
|
||||||
|
|
||||||
``sim.save(fstream, format_name)``
|
|
||||||
==================================
|
|
||||||
|
|
||||||
This is the one context in which the MuJoCo library (and therefore also ``mujoco``) is stateful: it holds a copy in
|
|
||||||
memory of the last XML that was compiled, which is used in :ref:`mujoco.mj_saveLastXML(fname) <mj_saveLastXML>`. Note
|
|
||||||
that mujoco-py’s implementation has a convenient extra feature, whereby the pose (as determined by ``sim.data``’s
|
|
||||||
state) is transformed to a keyframe that’s added to the model before saving. This extra feature is not currently
|
|
||||||
available in ``mujoco``.
|
|
||||||
|
|
||||||
Code Sample: open-loop rollout
|
Code Sample: open-loop rollout
|
||||||
------------------------------
|
==============================
|
||||||
|
|
||||||
We include a code sample showing how to add additional C/C++ functionality, exposed as a Python module via pybind11. The
|
We include a code sample showing how to add additional C/C++ functionality, exposed as a Python module via pybind11. The
|
||||||
sample, implemented in ``rollout.cc`` and wrapped in ``rollout.py``, implements a common use case where tight loops
|
sample, implemented in ``rollout.cc`` and wrapped in ``rollout.py``, implements a common use case where tight loops
|
||||||
@@ -441,3 +380,64 @@ all inputs including ``time`` and ``qacc_warmstart`` are set to default values,
|
|||||||
|
|
||||||
Since the Global Interpreter Lock can be released, this function can be efficiently threaded using Python threads. See
|
Since the Global Interpreter Lock can be released, this function can be efficiently threaded using Python threads. See
|
||||||
the ``test_threading`` function in ``rollout_test.py`` for an example of threaded operation.
|
the ``test_threading`` function in ``rollout_test.py`` for an example of threaded operation.
|
||||||
|
|
||||||
|
.. _PyMjpy_migration:
|
||||||
|
|
||||||
|
Migration Notes for mujoco-py
|
||||||
|
=============================
|
||||||
|
|
||||||
|
In mujoco-py, the main entry point is the `MjSim <https://github.com/openai/mujoco-py/blob/master/mujoco_py/mjsim.pyx>`_
|
||||||
|
class. Users construct a stateful ``MjSim`` instance from an MJCF model (similar to ``dm_control.Physics``), and this
|
||||||
|
instance holds references to an ``mjModel`` instance and its associated ``mjData``. In contrast, the MuJoCo Python
|
||||||
|
bindings (``mujoco``) take a more low-level approach, as explained above: following the design principle of the C
|
||||||
|
library, the ``mujoco`` module itself is stateless, and merely wraps the underlying native structs and functions.
|
||||||
|
|
||||||
|
While a complete survey of mujoco-py is beyond the scope of this document, we offer below implementation notes for a
|
||||||
|
non-exhaustive list of specific mujoco-py features:
|
||||||
|
|
||||||
|
``mujoco_py.load_model_from_xml(bstring)``
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
This factory function constructs a stateful ``MjSim`` instance. When using ``mujoco``, the user should call the factory
|
||||||
|
function ``mujoco.MjModel.from_xml_*`` as described :ref:`above <PyStructs>`. The user is then responsible for holding
|
||||||
|
the resulting ``MjModel`` struct instance and explicitly generating the corresponding ``MjData`` by calling
|
||||||
|
``mujoco.MjData(model)``.
|
||||||
|
|
||||||
|
``sim.reset()``, ``sim.forward()``, ``sim.step()``
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
Here as above, ``mujoco`` users needs to call the underlying library functions, passing instances of ``MjModel`` and
|
||||||
|
``MjData``: :ref:`mujoco.mj_resetData(model, data) <mj_resetData>`, :ref:`mujoco.mj_forward(model, data) <mj_forward>`,
|
||||||
|
and :ref:`mujoco.mj_step(model, data) <mj_step>`.
|
||||||
|
|
||||||
|
``sim.get_state()``, ``sim.set_state(state)``, ``sim.get_flattened_state()``, ``sim.set_state_from_flattened(state)``
|
||||||
|
---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
The MuJoCo library’s computation is deterministic given a specific input, as explained in the :ref:`Programming section
|
||||||
|
<Simulation>`. mujoco-py implements methods for getting and setting some of the relevant fields (and similarly
|
||||||
|
``dm_control.Physics`` offers methods that correspond to the flattened case). ``mujoco`` do not offer such abstraction,
|
||||||
|
and the user is expected to get/set the values of the relevant fields explicitly.
|
||||||
|
|
||||||
|
``sim.model.get_joint_qvel_addr(joint_name)``
|
||||||
|
---------------------------------------------
|
||||||
|
|
||||||
|
This is a convenience method in mujoco-py that returns a list of contiguous indices corresponding to this joint. The
|
||||||
|
list starts from ``model.jnt_qposadr[joint_index]``, and its length depends on the joint type. ``mujoco`` doesn't offer
|
||||||
|
this functionality, but this list can be easily constructed using ``model.jnt_qposadr[joint_index]`` and ``xrange``.
|
||||||
|
|
||||||
|
``sim.model.*_name2id(name)``
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
mujoco-py creates dicts in ``MjSim`` that allow for efficient lookup of indices for objects of different types:
|
||||||
|
``site_name2id``, ``body_name2id`` etc. These functions replace the function :ref:`mujoco.mj_name2id(model, type_enum,
|
||||||
|
name) <mj_name2id>` whose current implementation is inefficient. ``mujoco`` offers a different
|
||||||
|
approach for using entity names – :ref:`named access <PyNamed>`, as well as access to the native :ref:`mj_name2id`.
|
||||||
|
|
||||||
|
``sim.save(fstream, format_name)``
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
This is the one context in which the MuJoCo library (and therefore also ``mujoco``) is stateful: it holds a copy in
|
||||||
|
memory of the last XML that was compiled, which is used in :ref:`mujoco.mj_saveLastXML(fname) <mj_saveLastXML>`. Note
|
||||||
|
that mujoco-py’s implementation has a convenient extra feature, whereby the pose (as determined by ``sim.data``’s
|
||||||
|
state) is transformed to a keyframe that’s added to the model before saving. This extra feature is not currently
|
||||||
|
available in ``mujoco``.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
"""Python bindings for the Simulate GUI."""
|
"""Interactive GUI viewer for MuJoCo."""
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import code
|
import code
|
||||||
@@ -69,7 +69,7 @@ def _file_loader(path: str) -> _LoaderWithPathType:
|
|||||||
|
|
||||||
|
|
||||||
def _physics_loop(simulate: Simulate, loader: Optional[_InternalLoaderType]):
|
def _physics_loop(simulate: Simulate, loader: Optional[_InternalLoaderType]):
|
||||||
"""Physics loop for the Simulate GUI, to be run in a separate thread."""
|
"""Physics loop for the GUI, to be run in a separate thread."""
|
||||||
m: mujoco.MjModel = None
|
m: mujoco.MjModel = None
|
||||||
d: mujoco.MjData = None
|
d: mujoco.MjData = None
|
||||||
ctrlnoise = np.array([])
|
ctrlnoise = np.array([])
|
||||||
Reference in New Issue
Block a user