Documentation pass for model editing, model encoding, and mjz.
PiperOrigin-RevId: 951665744 Change-Id: I1dfe3b40f451cca686431c263815039a9c38efc8
This commit is contained in:
committed by
Copybara-Service
parent
259e6c4dc6
commit
1f1bfa9e4e
@@ -66,18 +66,11 @@ Parse spec from a file.
|
||||
|
||||
.. mujoco-include:: mj_encode
|
||||
|
||||
Encode :ref:`mjSpec` or :ref:`mjModel` to a file. The output format is determined by the file extension (case insensitive) or
|
||||
``content_type``. Returns the number of bytes written on success, -1 on failure.
|
||||
Encode :ref:`mjSpec` or :ref:`mjModel` to a file. The output format is determined by the file extension
|
||||
(case insensitive) or ``content_type``. Returns the number of bytes written on success, -1 on failure.
|
||||
|
||||
The following formats are supported natively, without a registered encoder:
|
||||
|
||||
- **MJCF XML** — extension: ``.xml``, content_type: ``text/xml``. If an :ref:`mjSpec` is provided, saves via
|
||||
:ref:`mj_saveXML`. Otherwise falls back to :ref:`mj_saveLastXML`, which requires a compiled :ref:`mjModel`.
|
||||
- **MJB** — extension: ``.mjb``. MuJoCo binary format. Requires a compiled :ref:`mjModel`.
|
||||
- **TXT** — extension: ``.txt``, content_type: ``text/plain``. Human-readable text dump via :ref:`mj_printModel`.
|
||||
Requires a compiled :ref:`mjModel`.
|
||||
|
||||
For all other formats, a registered encoder is looked up via :ref:`mjp_findEncoder`.
|
||||
For detailed documentation, supported output formats (``.xml``, ``.mjb``, ``.txt``, ``.mjz``), and custom encoder
|
||||
plugins, see :ref:`Model Encoding & Saving <meSaving>`.
|
||||
|
||||
*Nullable:* ``s``, ``m``, ``vfs``, ``error``
|
||||
|
||||
|
||||
@@ -74,18 +74,11 @@ Save spec to XML file, return 0 on success, -1 otherwise. XML saving requires th
|
||||
|
||||
.. _mj_encode:
|
||||
|
||||
Encode :ref:`mjSpec` or :ref:`mjModel` to a file. The output format is determined by the file extension (case insensitive) or
|
||||
``content_type``. Returns the number of bytes written on success, -1 on failure.
|
||||
Encode :ref:`mjSpec` or :ref:`mjModel` to a file. The output format is determined by the file extension
|
||||
(case insensitive) or ``content_type``. Returns the number of bytes written on success, -1 on failure.
|
||||
|
||||
The following formats are supported natively, without a registered encoder:
|
||||
|
||||
- **MJCF XML** — extension: ``.xml``, content_type: ``text/xml``. If an :ref:`mjSpec` is provided, saves via
|
||||
:ref:`mj_saveXML`. Otherwise falls back to :ref:`mj_saveLastXML`, which requires a compiled :ref:`mjModel`.
|
||||
- **MJB** — extension: ``.mjb``. MuJoCo binary format. Requires a compiled :ref:`mjModel`.
|
||||
- **TXT** — extension: ``.txt``, content_type: ``text/plain``. Human-readable text dump via :ref:`mj_printModel`.
|
||||
Requires a compiled :ref:`mjModel`.
|
||||
|
||||
For all other formats, a registered encoder is looked up via :ref:`mjp_findEncoder`.
|
||||
For detailed documentation, supported output formats (``.xml``, ``.mjb``, ``.txt``, ``.mjz``), and custom encoder
|
||||
plugins, see :ref:`Model Encoding & Saving <meSaving>`.
|
||||
|
||||
*Nullable:* ``s``, ``m``, ``vfs``, ``error``
|
||||
|
||||
|
||||
+13
-7
@@ -143,11 +143,11 @@ Compiler
|
||||
- The :ref:`attach<body-attach>` element now supports self-attachment (attaching elements of the current model to
|
||||
itself) by omitting the :ref:`model<body-attach-model>` attribute. It also supports attaching a frame via the new
|
||||
:ref:`frame<body-attach-frame>` attribute, which is mutually exclusive with :ref:`body<body-attach-body>`.
|
||||
- Fixed loading of ``.mjz`` archives in :ref:`simulate<saSimulate>`: the archive was unmounted before model compilation,
|
||||
so assets failed to load. Failures in the ``mjz`` decoder now emit a warning with the underlying error instead of the
|
||||
generic "could not decode content" message.
|
||||
- The ``mjz`` decoder now searches for ``model.xml`` at the root of the archive as a fallback if the archive-named XML
|
||||
is not found.
|
||||
- Fixed loading of :ref:`.mjz <MJZArchives>` archives in :ref:`simulate<saSimulate>`: the archive was unmounted
|
||||
before model compilation, so assets failed to load. Failures in the :ref:`mjz <MJZArchives>` decoder now emit a
|
||||
warning with the underlying error instead of the generic "could not decode content" message.
|
||||
- The :ref:`mjz <MJZArchives>` decoder now searches for ``model.xml`` at the root of the archive as a fallback if the
|
||||
archive-named XML is not found.
|
||||
- Added support for resource writing via :ref:`mju_writeResource` and the ``write`` callback in
|
||||
:ref:`mjpResourceProvider`.
|
||||
|
||||
@@ -166,6 +166,12 @@ Python bindings
|
||||
^^^^^^^^^^^^^^^
|
||||
- The bindings now support free threading (`PEP 703 <https://peps.python.org/pep-0703/>`__) for Python 3.14.
|
||||
|
||||
Documentation
|
||||
^^^^^^^^^^^^^
|
||||
- Expanded documentation for :ref:`spec.encode <meSaving>` workflows and added detailed documentation for the
|
||||
:ref:`MJZ Archive <MJZArchives>` format (``.mjz`` / ``.zip``).
|
||||
|
||||
|
||||
Version 3.10.0 (June 22, 2026)
|
||||
------------------------------
|
||||
|
||||
@@ -234,8 +240,8 @@ Bug fixes
|
||||
15. :commit:`a8eaccd2` Fixed a vulnerability in the System Identification toolbox where loading a trajectory or time
|
||||
series called ``np.load`` with ``allow_pickle=True``, allowing arbitrary code execution from a malicious ``.npz``
|
||||
file. Signal metadata is now serialized as JSON and loaded with ``allow_pickle=False``.
|
||||
16. :commit:`b9fb817a` Fixed a bug in the ``mjz`` :ref:`decoder <mjpDecoder>` where unnormalized paths would fail to be
|
||||
read.
|
||||
16. :commit:`b9fb817a` Fixed a bug in the :ref:`mjz <MJZArchives>` :ref:`decoder <mjpDecoder>` where unnormalized paths
|
||||
would fail to be read.
|
||||
17. :commit:`986d73c0` Fixed a bug where the mesh compiler would produce non-unit convex hull polygon normals.
|
||||
|
||||
Version 3.9.0 (May 27, 2026)
|
||||
|
||||
+13
-71
@@ -5,91 +5,33 @@ Modeling
|
||||
Introduction
|
||||
------------
|
||||
|
||||
MuJoCo can load XML model files in its native **MJCF** format, as well as in the popular but more limited **URDF**
|
||||
format. This chapter is the MJCF modeling guide. The reference manual is available in the :doc:`XMLreference`
|
||||
chapter. The URDF documentation can be found elsewhere; here we only describe
|
||||
MuJoCo-specific :ref:`URDF extensions <CURDF>`.
|
||||
MuJoCo's native model format is **MJCF**, an XML-based language designed to describe complex dynamical systems. This
|
||||
chapter is the primary MJCF modeling guide. The complete element and attribute reference manual is available in the
|
||||
:doc:`XMLreference` chapter. MuJoCo also supports loading models from other formats such as URDF (see :ref:`URDF
|
||||
extensions <CURDF>`), MJZ Zip archives (see :ref:`MJZ Archives <MJZArchives>`), and OpenUSD (see :doc:`OpenUSD/index`).
|
||||
|
||||
MJCF models can represent complex dynamical systems with a wide range of features and model elements. Accessing all
|
||||
these features requires a rich modeling format, which can become cumbersome if it is not designed with usability in
|
||||
mind. Therefore we have made an effort to design MJCF as a scalable format, allowing users to start small and build
|
||||
more detailed models later. Particularly helpful in this regard is the extensive :ref:`default setting <CDefault>`
|
||||
mechanism inspired by the idea of Cascading Style Sheets (CSS) inlined in HTML. It enables users to rapidly create
|
||||
new models and experiment with them. Experimentation is further aided by numerous :ref:`options <option>` which
|
||||
can be used to reconfigure the simulation pipeline, and by quick re-loading that makes model editing an interactive
|
||||
process.
|
||||
mechanism inspired by the idea of Cascading Style Sheets (CSS) inlined in HTML. It enables users to rapidly create new
|
||||
models and experiment with them. Experimentation is further aided by numerous :ref:`options <option>` which can be used
|
||||
to reconfigure the simulation pipeline, and by quick re-loading that makes model editing an interactive process.
|
||||
|
||||
One can think of MJCF as a hybrid between a modeling format and a programming language. There is a built-in compiler,
|
||||
which is a concept normally associated with programming languages. While MJCF does not have the power of a
|
||||
general-purpose programming language, a number of sophisticated compile-time computations are invoked automatically
|
||||
depending on how the model is designed.
|
||||
|
||||
.. _Load:
|
||||
.. _ProceduralModeling:
|
||||
|
||||
Loading models
|
||||
~~~~~~~~~~~~~~
|
||||
Procedural Modeling
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As explained in :ref:`Model instances <Instance>` in the Overview chapter, MuJoCo models can be loaded from plain-text
|
||||
XML files in the MJCF or URDF formats, and then compiled into a low-level mjModel. Alternatively a previously saved
|
||||
mjModel can be loaded directly from a binary MJB file -- whose format is not documented but is essentially a copy of the
|
||||
mjModel memory buffer. MJCF and URDF files are loaded with :ref:`mj_loadXML` while MJB files are loaded with
|
||||
:ref:`mj_loadModel`.
|
||||
This chapter covers high-level model design. For detailed documentation on programmatic modeling via the :ref:`mjSpec`
|
||||
API—including loading, editing, compiling, and saving models in C/C++ or Python—see the
|
||||
:doc:`Model Editing <programming/modeledit>` chapter.
|
||||
|
||||
When an XML file is loaded, it is first parsed into a document object model (DOM) using the TinyXML parser internally.
|
||||
This DOM is then processed and converted into a high-level :ref:`mjSpec` object. The conversion depends on the model
|
||||
format -- which is inferred from the top-level element in the XML file, and not from the file extension. Recall that a
|
||||
valid XML file has a unique top-level element. This element must be :el:`mujoco` for MJCF, and :el:`robot` for URDF.
|
||||
|
||||
.. _Compile:
|
||||
|
||||
Compiling models
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Once a high-level :ref:`mjSpec` is created---by loading an MJCF file or a URDF file, or
|
||||
:doc:`programmatically<programming/modeledit>`---it is compiled into :ref:`mjModel`.
|
||||
Compilation is independent of loading, meaning that the compiler works in the same way regardless of how :ref:`mjSpec`
|
||||
was created. Both the parser and the compiler perform extensive error checking, and abort
|
||||
when the first error is encountered. The resulting error messages contain the row and column number in the XML file,
|
||||
and are self-explanatory so we do not document them here. The parser uses a custom schema to make sure that the file
|
||||
structure, elements and attributes are valid. The compiler then applies many additional semantic checks. Finally, one
|
||||
simulation step of the compiled model is performed and any runtime errors are intercepted. The latter is done by
|
||||
(temporarily) setting :ref:`mju_user_error` to point to a function that throws C++
|
||||
exceptions; the user can implement similar error-interception functionality at runtime if desired.
|
||||
|
||||
The entire process of parsing and compilation is very fast -- less than a second if the model does not contain large
|
||||
meshes or actuator lengthranges that need to be computed via simulation. This makes it possible to design models
|
||||
interactively, by re-loading often and visualizing the changes. Note that the :ref:`simulate.cc <saSimulate>` code
|
||||
sample has a keyboard shortcut for re-loading the current model (Ctrl+L).
|
||||
|
||||
.. _Save:
|
||||
|
||||
Saving models
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
An MJCF model can consist of multiple (included) XML files as well as meshes, height fields and textures referenced
|
||||
from the XML. After compilation, the contents of all these files are assembled into mjModel, which can be saved into a
|
||||
binary MJB file with :ref:`mj_saveModel`. The MJB is a stand-alone file and does not
|
||||
refer to any other files. It also loads faster. So we recommend saving commonly used models as MJB and loading them
|
||||
when needed for simulation.
|
||||
|
||||
It is also possible to save a compiled :ref:`mjSpec` as MJCF with :ref:`mj_saveLastXML`. If any real-valued fields in
|
||||
the corresponding mjModel were modified after compilation (which is unusual but can happen in system identification
|
||||
applications for example), the modifications are automatically copied back into :ref:`mjSpec` before saving. Note that
|
||||
structural changes cannot be made in the compiled model. The XML writer attempts to generate the smallest MJCF file
|
||||
which is guaranteed to compile into the same model, modulo negligible numeric differences caused by the plain text
|
||||
representation of real values. The resulting file may not have the same structure as the original because MJCF has many
|
||||
user convenience features, allowing the same model to be specified in different ways. The XML writer uses a "canonical"
|
||||
subset of MJCF where all coordinates are local and all body positions, orientations and inertial properties are
|
||||
explicitly specified. In the Computation chapter we showed an `example <_static/example.xml>`__ MJCF file and the
|
||||
corresponding `saved example <_static/example_saved.xml>`__.
|
||||
|
||||
.. _EditModel:
|
||||
|
||||
Editing models
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
As of MuJoCo 3.2, it is possible to create and modify models using the :ref:`mjSpec` struct and related API.
|
||||
For further documentation, please see the :doc:`Model Editing<programming/modeledit>` chapter.
|
||||
|
||||
.. _Mechanisms:
|
||||
|
||||
|
||||
+12
-9
@@ -166,31 +166,34 @@ There are several entities called "model" in MuJoCo. The user defines the model
|
||||
The software can then create multiple instances of the same model in different media (file or memory) and on different
|
||||
levels of description (high or low). All combinations are possible as shown in the following table:
|
||||
|
||||
+------------+---------------------------+----------------------------+
|
||||
| | High level | Low level |
|
||||
+============+===========================+============================+
|
||||
| **File** | MJCF/URDF (XML) | MJB (binary) |
|
||||
+------------+---------------------------+----------------------------+
|
||||
| **Memory** | :ref:`mjSpec` (C struct) | :ref:`mjModel` (C struct) |
|
||||
+------------+---------------------------+----------------------------+
|
||||
+------------+-------------------------------------+----------------------------+
|
||||
| | High level | Low level |
|
||||
+============+=====================================+============================+
|
||||
| **File** | MJCF/URDF (XML), MJZ (Zip archive) | MJB (binary) |
|
||||
+------------+-------------------------------------+----------------------------+
|
||||
| **Memory** | :ref:`mjSpec` (C struct) | :ref:`mjModel` (C struct) |
|
||||
+------------+-------------------------------------+----------------------------+
|
||||
|
||||
All runtime computations are performed with :ref:`mjModel` which is too complex to create manually. This is why we have
|
||||
two levels of modeling. The high level exists for user convenience: its sole purpose is to be compiled into a low level
|
||||
model on which computations can be performed. The resulting :ref:`mjModel` can be loaded and saved into a binary file
|
||||
(MJB), however those are version-specific and cannot be decompiled, thus models should always be maintained as XML
|
||||
files.
|
||||
files or packaged into MJZ archives.
|
||||
|
||||
The :ref:`mjSpec` C struct is in one-to-one correspondence with the MJCF file format. The XML loader interprets the MJCF
|
||||
or URDF file, creates the corresponding :ref:`mjSpec` and compiles it to :ref:`mjModel`. The user can create
|
||||
:ref:`mjSpec` programmatically and then save it to MJCF or compile it. Procedural model creation and editing is
|
||||
:ref:`mjSpec` programmatically and then save it to MJCF/MJZ or compile it. Procedural model creation and editing is
|
||||
described in the :doc:`Model Editing <programming/modeledit>` chapter.
|
||||
|
||||
The following diagram shows the different paths to obtaining an :ref:`mjModel`:
|
||||
|
||||
- (text editor) → MJCF/URDF file → (MuJoCo parser → mjSpec → compiler) → mjModel
|
||||
- MJZ archive → (MJZ decoder → mjSpec → compiler) → mjModel
|
||||
- (user code) → mjSpec → (MuJoCo compiler) → mjModel
|
||||
- MJB file → (model loader) → mjModel
|
||||
|
||||
Models and specs can also be serialized or packaged back to disk using :ref:`mj_encode`.
|
||||
|
||||
.. _Examples:
|
||||
|
||||
Examples
|
||||
|
||||
@@ -470,6 +470,62 @@ or content type:
|
||||
</asset>
|
||||
|
||||
|
||||
.. _exEncoder:
|
||||
|
||||
Encoders
|
||||
~~~~~~~~
|
||||
|
||||
Encoder plugins extend asset serialization and model saving capabilities beyond native formats (XML, MJB, TXT).
|
||||
Encoders are :ref:`registered <mjPLUGIN_LIB_INIT>` similarly to other MuJoCo plugins.
|
||||
|
||||
MuJoCo ships with a built-in Zip encoder for ``.mjz`` archives (``src/xml/mjz/mjz_encoder.cc``).
|
||||
|
||||
.. _exEncoderInterface:
|
||||
|
||||
Encoder interface
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
An encoder is described by the :ref:`mjpEncoder` struct, which has the following fields:
|
||||
|
||||
``content_type``
|
||||
A MIME-like content type string identifying the output format (e.g. ``"application/zip"``). When :ref:`mj_encode` is
|
||||
called with an explicit ``content_type`` argument, this string is used to find the appropriate encoder.
|
||||
|
||||
``extension``
|
||||
A file extension string (including the dot) used for format matching when no content type is specified. Multiple
|
||||
extensions can be separated by pipes (`|`) such as ``.mjz|.zip``.
|
||||
|
||||
``encode``
|
||||
A callback of type :ref:`mjfEncode` that performs the actual serialization. It receives an :ref:`mjSpec`, an
|
||||
optional compiled :ref:`mjModel`, an optional :ref:`mjVFS`, and an output :ref:`mjResource`. Returns the number of
|
||||
bytes written on success, or -1 on failure.
|
||||
|
||||
``close_resource``
|
||||
An optional callback that frees any memory allocated inside ``mjResource.data`` by the ``encode`` callback.
|
||||
|
||||
.. _exEncoderRegistration:
|
||||
|
||||
Registration
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Encoders must be registered before they can be used via :ref:`mj_encode`. Registration is performed via
|
||||
:ref:`mjp_registerEncoder`. The :ref:`mjp_defaultEncoder` function initializes an :ref:`mjpEncoder` struct with default
|
||||
values. The :ref:`mjPLUGIN_LIB_INIT` macro defines the initialization function that registers the encoder when the
|
||||
plugin library is loaded.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
mjPLUGIN_LIB_INIT(my_format_encoder) {
|
||||
mjpEncoder encoder;
|
||||
mjp_defaultEncoder(&encoder);
|
||||
encoder.content_type = "application/x-myformat";
|
||||
encoder.extension = ".myf";
|
||||
encoder.encode = MyEncode;
|
||||
encoder.close_resource = MyCloseResource;
|
||||
mjp_registerEncoder(&encoder);
|
||||
}
|
||||
|
||||
|
||||
.. _exProvider:
|
||||
|
||||
Resource providers
|
||||
|
||||
+108
-16
@@ -26,6 +26,114 @@ The workflow using :ref:`mjSpec` is:
|
||||
After compilation, the :ref:`mjSpec` remains editable, so steps 2 and 3 are interchangeable.
|
||||
|
||||
|
||||
.. _Load:
|
||||
.. _meLoading:
|
||||
|
||||
Model Parsing & Loading
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
As summarized in :ref:`Model instances <Instance>`, model description files (MJCF, MJZ, URDF, USD) are parsed into an
|
||||
:ref:`mjSpec` using :ref:`mj_parse` (or ``mjSpec.from_file()`` / ``mjSpec.from_string()`` in Python). The model format is
|
||||
inferred from the content type or file extension, and parsing into an :ref:`mjSpec` is delegated to the appropriate
|
||||
:ref:`decoder <exDecoder>` plugin.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
char error[1000] = "";
|
||||
mjSpec* spec = mj_parse(vfs, "robot.xml", NULL, NULL, error, sizeof(error));
|
||||
|
||||
For convenience, :ref:`mj_loadXML` (or Python ``MjModel.from_xml_path()``) combines parsing and compilation into a
|
||||
single step, returning a compiled :ref:`mjModel` directly from an XML file or ``.mjz`` archive.
|
||||
|
||||
Alternatively, a pre-compiled :ref:`mjModel` can be loaded directly from a binary MJB file using :ref:`mj_loadModel`
|
||||
(or Python ``MjModel.from_binary_path()``).
|
||||
|
||||
.. _Compile:
|
||||
.. _meCompilation:
|
||||
|
||||
Model Compilation
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Once a high-level :ref:`mjSpec` is created---by parsing a file, loading an archive, or constructing it
|
||||
programmatically---it is compiled into an :ref:`mjModel` using :ref:`mj_compile`.
|
||||
|
||||
Compilation is independent of loading, working in the exact same way regardless of how :ref:`mjSpec` was constructed.
|
||||
Both the parser and the compiler perform extensive error checking and abort when the first error is encountered. The
|
||||
parser uses a custom schema to validate file structure, elements, and attributes, while the compiler applies semantic
|
||||
checks and executes a test simulation step to catch runtime errors.
|
||||
|
||||
Parsing and compilation are extremely fast—typically less than a second—making interactive model design, live editing,
|
||||
and rapid reloading seamless.
|
||||
|
||||
.. _Save:
|
||||
.. _meSaving:
|
||||
|
||||
Model Encoding & Saving
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Model specs and compiled models can be serialized to files using :ref:`mj_encode`, or directly saved to XML strings
|
||||
using :ref:`mj_saveXMLString` or :ref:`mj_saveXML`.
|
||||
|
||||
The :ref:`mj_encode` function provides a unified entry point for serializing models:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
char error[1024] = "";
|
||||
mjtSize bytes_written = mj_encode(spec, model, "robot.mjz", NULL, vfs, error, sizeof(error));
|
||||
|
||||
The output format is selected automatically based on the file extension (case-insensitive) or explicit ``content_type``:
|
||||
|
||||
- **MJCF XML** (``.xml``): Flattens the spec into a single MJCF XML file using :ref:`mj_saveXML`. If an explicit
|
||||
:ref:`mjModel` argument is passed, :ref:`mj_encode` will copy modified values back from ``mjModel`` into the spec
|
||||
prior to saving. In the Computation chapter we show an `example <_static/example.xml>`__ MJCF file and the
|
||||
corresponding `saved example <_static/example_saved.xml>`__.
|
||||
- **MJZ Archive** (``.mjz`` or ``.zip``): Bundles the spec and all associated external assets (meshes, textures,
|
||||
included XMLs) into a self-contained Zip archive via the built-in ``mjz_encoder``.
|
||||
- **MJB Binary** (``.mjb``): Serializes the compiled :ref:`mjModel` in MuJoCo binary format via :ref:`mj_saveModel`.
|
||||
MJB files are standalone, do not refer to external files, and load faster than XML, but are version-specific and
|
||||
cannot be decompiled back to XML. Requires a compiled ``model``; does **not** serialize anything from ``spec``.
|
||||
- **TXT** (``.txt``): Writes a human-readable text dump via :ref:`mj_printModel`. Useful for diffing and debugging.
|
||||
Requires a compiled ``model``; does **not** serialize anything from ``spec``.
|
||||
|
||||
Importantly, saved XML will take into account any defined defaults. This is useful when a model has many repeated
|
||||
values, for example if loaded from URDF, which does not support defaults. In such a case one can add default classes,
|
||||
set the class of the relevant elements, and save; the resulting XML will use the defaults and be more human-readable.
|
||||
|
||||
.. _MJZArchives:
|
||||
|
||||
MJZ Archives
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Complex MuJoCo models often consist of multiple files: a main MJCF XML file, included XML sub-trees, and external asset
|
||||
files (meshes, textures, height fields). The **MJZ** format (extension ``.mjz`` or ``.zip``) provides a convenient way
|
||||
to bundle an entire model and all of its referenced assets into a single **Zip archive**.
|
||||
|
||||
Root XML Discovery
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When decoding an ``.mjz`` archive, MuJoCo searches for the root model XML file in the following order:
|
||||
|
||||
1. `<archive_stem>.xml` at the root of the archive (e.g. ``my_model.xml`` inside ``my_model.mjz``). This is
|
||||
considered **best practice**.
|
||||
2. `<archive_stem>/<archive_stem>.xml` inside a top-level directory matching the archive name (e.g.
|
||||
``my_model/my_model.xml``).
|
||||
3. `model.xml` at the root of the archive (common zipped MJCF fallback).
|
||||
|
||||
VFS Requirement
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Parsing and compilation of an ``.mjz`` archive (and all of its contained asset files) require using the **exact same
|
||||
VFS instance**.
|
||||
|
||||
.. _meCustomFormats:
|
||||
|
||||
Custom formats
|
||||
~~~~~~~~~~~~~~
|
||||
Adding support for new file formats can be done with :ref:`mjp_registerDecoder` and :ref:`mjp_registerEncoder`.
|
||||
When :ref:`mj_parse` and :ref:`mj_encode` are called for a non-native extension or content type, the appropriate plugins
|
||||
are found via :ref:`mjp_findDecoder` and :ref:`mjp_findEncoder`. For further details on writing custom format plugins,
|
||||
see :ref:`Decoders <exDecoder>` and :ref:`Encoders <exEncoder>`.
|
||||
|
||||
|
||||
.. _meUsage:
|
||||
|
||||
Usage
|
||||
@@ -59,13 +167,6 @@ In C++, one can use vectors and strings directly:
|
||||
std::string modelname = "my_model";
|
||||
*spec->modelname = modelname;
|
||||
|
||||
Loading a spec from XML can be done as follows:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
std::array<char, 1000> error;
|
||||
mjSpec* s = mj_parseXML(filename, vfs, error.data(), error.size());
|
||||
|
||||
.. _meMjsElements:
|
||||
|
||||
Model elements
|
||||
@@ -258,15 +359,6 @@ already initialized elements.
|
||||
loading pipeline. A future API change could allow defaults to be changed and applied after initialization. If you
|
||||
think this feature is important to you, please let us know on GitHub.
|
||||
|
||||
.. _meSaving:
|
||||
|
||||
XML saving
|
||||
^^^^^^^^^^
|
||||
Specs can be saved to an XML file or string using :ref:`mj_saveXML` or :ref:`mj_saveXMLString`, respectively.
|
||||
Saving requires that the spec first be compiled.
|
||||
Importantly, the saved XML will take into account any defined defaults. This is useful when a model has many repeated
|
||||
values, for example if loaded from URDF, which does not support defaults. In such a case one can add default classes,
|
||||
set the class of the relevant elements, and save; the resulting XML will use the defaults and be more human-readable.
|
||||
|
||||
.. _meRecompilation:
|
||||
|
||||
|
||||
+16
-2
@@ -597,11 +597,25 @@ Compiled ``MjSpec`` objects can be saved to XML string with the ``to_xml()`` met
|
||||
</worldbody>
|
||||
</mujoco>
|
||||
|
||||
Alternatively, the spec can be saved directly to a file using ``encode()``:
|
||||
Alternatively, specs or compiled models can be serialized to a file using ``encode()``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
spec.encode('model.xml', model)
|
||||
# Save spec directly to an MJCF XML file
|
||||
spec.encode('model.xml')
|
||||
|
||||
# Save XML from a compiled model; copies modified model values back to spec prior to saving
|
||||
spec.encode('model.xml', model=model)
|
||||
|
||||
# Save compiled model to binary MJB format (serializes mjModel only, not spec)
|
||||
spec.encode('model.mjb', model=model)
|
||||
|
||||
# Package spec and all referenced external assets (meshes, textures) into an MJZ zip archive
|
||||
spec.encode('robot.mjz', model=model)
|
||||
|
||||
The ``encode()`` method accepts the target filename, an optional compiled ``model`` (:ref:`MjModel`), an optional
|
||||
``vfs`` (:ref:`MjVFS`), and an optional ``content_type``. The target format is automatically determined by the file
|
||||
extension (``.xml``, ``.mjb``, ``.txt``, ``.mjz``) or content type.
|
||||
|
||||
Attachment
|
||||
----------
|
||||
|
||||
Reference in New Issue
Block a user