Minor updates to documentation across multiple sections.

PiperOrigin-RevId: 898652783
Change-Id: Idb671910c18ed3406722b8a1307f97ae9a194139
This commit is contained in:
Yuval Tassa
2026-04-12 13:59:58 -07:00
committed by Copybara-Service
parent c08d181d52
commit 239aa1f856
11 changed files with 322 additions and 333 deletions
+60 -70
View File
@@ -266,7 +266,7 @@ This element does not strictly belong to MJCF. Instead it is a meta-element, use
files in a single document object model (DOM) before parsing. The included file must be a valid XML file with a unique
top-level element. This top-level element is removed by the parser, and the elements below it are inserted at the
location of the :el:`include` element. At least one element must be inserted as a result of this procedure. The
:el:`include` element can be used where ever an XML element is expected in the MJCF file. Nested includes are allowed,
:el:`include` element can be used wherever an XML element is expected in the MJCF file. Nested includes are allowed,
however a given XML file can be included at most once in the entire model. After all the included XML files have been
assembled into a single DOM, it must correspond to a valid MJCF model. Other than that, it is up to the user to decide
how to use includes and how to modularize large files if desired.
@@ -746,10 +746,8 @@ has any effect. The settings here are global and apply to the entire model.
.. _compiler-coordinate:
:at:`coordinate`: :at-val:`[local, global], "local"`
In previous versions, this attribute could be used to specify whether frame positions and orientations are expressed
in local or global coordinates, but the "global" option has since been removed, and will cause an error to be
generated. In order to convert older models which used the "global" option, load and save them in MuJoCo 2.3.3 or
older.
This attribute specifies whether frame positions and orientations are expressed in local coordinates. The "global"
option is no longer supported and will cause an error.
.. _compiler-angle:
@@ -826,8 +824,8 @@ has any effect. The settings here are global and apply to the entire model.
.. _compiler-usethread:
:at:`usethread`: :at-val:`[false, true], "true"`
If this attribute is "true", the model compiler will run in multi-threaded mode. Currently multi-threading is used
for computing the length ranges of actuators and for parallel loading and processing of meshes.
If this attribute is "true", the model compiler will run in multi-threaded mode. Multi-threading is used for
computing the length ranges of actuators and for parallel loading and processing of meshes.
.. _compiler-fusestatic:
@@ -995,25 +993,24 @@ compilation.
.. _size-njmax:
:at:`njmax`: :at-val:`int, "-1"` |nbsp| |nbsp| |nbsp| (legacy)
This is a deprecated legacy attribute. In versions prior to 2.3.0, it determined the maximum allowed number
of constraints. Currently it means "allocate as much memory as would have previously been required for this number of
This is a deprecated legacy attribute. It previously determined the maximum allowed number of constraints.
Currently it means "allocate as much memory as would have previously been required for this number of
constraints". Specifying both :at:`njmax` and :at:`memory` leads to an error.
.. _size-nconmax:
:at:`nconmax`: :at-val:`int, "-1"` |nbsp| |nbsp| |nbsp| (legacy)
This attribute specifies the maximum number of contacts that will be generated at runtime. If the number of active
contacts is about to exceed this value, the extra contacts are discarded and a warning is generated. This is a
deprecated legacy attribute which prior to version 2.3.0 affected memory allocation. It is kept for backwards
compatibility and debugging purposes.
contacts is about to exceed this value, the extra contacts are discarded and a warning is generated. This is a
deprecated legacy attribute which previously affected memory allocation. It is kept for backwards compatibility
and debugging purposes.
.. _size-nstack:
:at:`nstack`: :at-val:`int, "-1"` |nbsp| |nbsp| |nbsp| (legacy)
This is a deprecated legacy attribute. In versions prior to 2.3.0, it determined the maximum size of the
:ref:`stack <siStack>`. After version 2.3.0, if :at:`nstack` is specified, then the size of ``mjData.narena`` is
``nstack * sizeof(mjtNum)`` bytes, plus an additional space for the constraint solver. Specifying both :at:`nstack`
and :at:`memory` leads to an error.
This is a deprecated legacy attribute. It previously determined the maximum size of the :ref:`stack <siStack>`.
If :at:`nstack` is specified, then the size of ``mjData.narena`` is ``nstack * sizeof(mjtNum)`` bytes, plus an
additional space for the constraint solver. Specifying both :at:`nstack` and :at:`memory` leads to an error.
.. _size-nuserdata:
@@ -1290,8 +1287,8 @@ The full list of processing steps applied by the compiler to each mesh is as fol
:at:`inertia`: :at-val:`[convex, exact, legacy, shell], "legacy"`
This attribute controls how the mesh is used when mass and inertia are
:ref:`inferred from geometry<compiler-inertiafromgeom>`. The current default value :at-val:`legacy` will be changed
to :at-val:`convex` in a future release.
:ref:`inferred from geometry<compiler-inertiafromgeom>`. The default value is :at-val:`legacy` for backward
compatibility, but :at-val:`convex` is recommended.
:at-val:`convex`: Use the mesh's convex hull to compute volume and inertia, assuming uniform density.
@@ -1602,8 +1599,8 @@ also known as terrain map, is a 2D matrix of elevation data. The data can be spe
.. _asset-skin-rgba:
.. _asset-skin-group:
:ref:`Skins<deformable-skin>` have been moved under the new grouping element :ref:`deformable<deformable>`. They can
still be specified here but this functionality is now deprecated and will be removed in the future.
:ref:`Skins<deformable-skin>` are grouped under the :ref:`deformable<deformable>` element. Specifying them here is
deprecated.
@@ -1618,7 +1615,7 @@ The texture data can be loaded from files or can be generated by the compiler as
different texture types require different parameters, only a subset of the attributes below are used for any given
texture. Provisions are provided for loading cube and skybox textures from individual image files.
Currently, three file formats are supported for loading textures: PNG, KTX, and a custom MuJoCo texture format. The
Three file formats are supported for loading textures: PNG, KTX, and a custom MuJoCo texture format. The
loader will use the extension of the file name to determine which format to use, defaulting to the custom format if
the extension is not recognized. Alternatively, the content_type attribute can be used to specify the format
explicitly. Only ``image/png``, ``image/ktx``, or ``image/vnd.mujoco.texture`` are supported.
@@ -1917,8 +1914,8 @@ properties are grouped together.
This attribute should be in the range [0 1]. If the value is greater than 0, and the material is applied to a plane
or a box geom, the renderer will simulate reflectance. The larger the value, the stronger the reflectance. For boxes,
only the face in the direction of the local +Z axis is reflective. Simulating reflectance properly requires
ray-tracing which cannot (yet) be done in real-time. We are using the stencil buffer and suitable projections
instead. Only the first reflective geom in the model is rendered as such. This adds one extra rendering pass through
ray-tracing. This renderer uses the stencil buffer and suitable projections instead to approximate it. Only the
first reflective geom in the model is rendered as such. This adds one extra rendering pass through
all geoms, in addition to the extra rendering pass added by each shadow-casting light.
.. _asset-material-metallic:
@@ -2183,7 +2180,7 @@ between the body where it is defined and the body's parent. If multiple joints a
corresponding spatial transformations (of the body frame relative to the parent frame) are applied in order. If no
joints are defined, the body is welded to its parent. Joints cannot be defined in the world body. At runtime the
positions and orientations of all joints defined in the model are stored in the vector ``mjData.qpos``, in the order in
which the appear in the kinematic tree. The linear and angular velocities are stored in the vector ``mjData.qvel``.
which they appear in the kinematic tree. The linear and angular velocities are stored in the vector ``mjData.qvel``.
These two vectors have different dimensionality when free or ball joints are used, because such joints represent
rotations as unit quaternions.
@@ -2479,7 +2476,7 @@ helps clarify the role of bodies and geoms in MuJoCo.
.. _body-geom-type:
:at:`type`: :at-val:`[plane, hfield, sphere, capsule, ellipsoid, cylinder, box, mesh, sdf], "sphere"`
Type of geometric shape. The keywords have the following meaning: The **plane** type defines a plane which is
Type of geometric shape. The keywords have the following meaning: The **plane** type defines a surface which is
infinite for collision detection purposes. It can only be attached to the world body or static children of the world.
The plane passes through a point specified via the pos attribute. It is normal to the Z axis of the geom's local
frame. The +Z direction corresponds to empty space. Thus the position and orientation defaults of (0,0,0) and
@@ -3218,9 +3215,9 @@ object. These elements are bodies (with their own joints and geoms) that become
the macro. The macro expansion is done by the model compiler. If the resulting model is then saved, the macro will be
replaced with the actual model elements. The defaults mechanism used in the rest of MJCF does not apply here, even if
the parent body has a childclass attribute defined. Instead there are internal defaults adjusted automatically for each
composite object type. See :ref:`CComposite` in the modeling guide for more detailed explanation. Note that there used
to be several composite types, but they have incrementally replaced by :ref:`replicate<replicate>` (for repeated
objects) and :ref:`flexcomp<body-flexcomp>` (for soft objects). Therefore, the only supported composite type is now
composite object type. See :ref:`CComposite` in the modeling guide for more detailed explanation. Note that several
legacy composite types have been replaced by :ref:`replicate<replicate>` (for repeated objects) and
:ref:`flexcomp<body-flexcomp>` (for soft objects). Therefore, the only supported composite type is now
cable, which produces an inextensible chain of bodies connected with ball joints.
.. _body-composite-prefix:
@@ -3237,8 +3234,8 @@ cable, which produces an inextensible chain of bodies connected with ball joints
The **cable** type creates a 1D chain of bodies connected with ball joints, each having a geom with user-defined type
(cylinder, capsule or box). The geometry can either be defined with an array of 3D vertex coordinates :at:`vertex`
or with prescribed functions with the option :at:`curve`. Currently, only linear and trigonometric functions are
supported. For example, an helix can be obtained with curve="cos(s) sin(s) s". The size is set with the option
or with prescribed functions with the option :at:`curve`. Only linear and trigonometric functions are supported. For
example, an helix can be obtained with curve="cos(s) sin(s) s". The size is set with the option
:at:`size`, resulting in :math:`f(s)=\{\text{size}[1]\cdot\cos(2\pi\cdot\text{size}[2]),\;
\text{size}[1]\cdot\sin(2\pi\cdot\text{size}[2]),\; \text{size}[0]\cdot s\}`.
@@ -3360,7 +3357,7 @@ joints should be created, as well as to adjust the attributes of both automatic
''''''''''''''''''''''''''''''''''''''''
This sub-element adjusts the attributes of the geoms in the composite object. The default attributes are the same as in
the rest of MJCF (except that user-defined defaults have no effect here). Note that the geom sub-element can appears
the rest of MJCF (except that user-defined defaults have no effect here). Note that the geom sub-element can appear
only once, unlike joint and tendon sub-elements which can appear multiple times. This is because different kinds of
joints and tendons have different sets of attributes, while all geoms in the composite object are identical.
@@ -3500,8 +3497,8 @@ Associate this composite with an :ref:`engine plugin<exPlugin>`. Either :at:`plu
:el-prefix:`body/` |-| **flexcomp** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Similar to :el:`composite`, this element (new in MuJoCo 3.0) is not a model element, but rather a macro which expands
into multiple model elements representing a deformable entity. In particular this macro creates one
Similar to :el:`composite`, this element is not a model element, but rather a macro which expands into multiple
model elements representing a deformable entity. In particular this macro creates one
:ref:`flex<deformable-flex>` element, a number of bodies that are children of the body in which the :el:`flexcomp` is
defined, and optionally one :ref:`flex equality<equality-flex>` which constrains all flex edges to their initial length.
A number of attributes are specified here and then passed through to the automatically-constructed flex. The primary
@@ -3518,9 +3515,9 @@ flexcomp point is not pinned, a new child body is created at the coordinates of
parent body), and then the coordinates of the flex vertex within that new body are (0,0,0). The mechanism for
:ref:`pinning<flexcomp-pin>` flexcomp points is explained below.
Composite objects (available prior to MuJoCo 3.0) needed bodies with geoms for collisions, and sites for connecting
tendons which generated shape-preserving forces. In contrast, flexes generate their own collisions and shape-preserving
forces (as well as rendering), thus the bodies created here are much simpler: no geoms, sites or tendons are needed.
While :el:`composite` objects need bodies with geoms for collisions and sites for connecting tendons, flexes
generate their own collisions and shape-preserving forces. Thus the bodies created here are much simpler: no geoms,
sites or tendons are needed.
Most of the bodies created here have 3 orthogonal slider joints, corresponding to freely moving point masses. In some
cases we generate radial slider joints, allowing only expansion and contraction. Since no geoms are generated, the
bodies need to have explicit inertial parameters.
@@ -4142,8 +4139,8 @@ This is a grouping element and does not have any attributes. It groups elements
:el-prefix:`deformable/` |-| **flex** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Flexible objects (or flexes) were added in MuJoCo 3.0. These are collections of massless stretchable geometric elements
(capsules, triangles or tetrahedra) connecting vertices that are defined within different moving body frames. These
Flexible objects (or flexes) are collections of massless stretchable geometric elements (capsules, triangles or
tetrahedra) connecting vertices that are defined within different moving body frames. These
stretchable elements support collisions and contact forces, which are then distributed to all the interconnected bodies.
Flexes also generate passive and constraint forces as needed to simulate deformable entities with the desired material
properties. The modeling of flexes is automated and simplified by the :ref:`flexcomp<body-flexcomp>` element. In most
@@ -4321,9 +4318,8 @@ extensions specific to flexes.
flex. The pre-defined vertex-element pairs are generated by the model compiler automatically. In 3D, internal
collision checks are performed within each tetraheron: each vertex is collided with the plane corresponding to the
opposing triangle face (again using the flex radius). The resulting contacts are always created with condim 1, gap 0,
margin 0. Note that internal contacts modify the behavior implied by the :ref:`elasticity
parameters<flex-elasticity>` and is recommended only for flexes where element inversion cannot be prevented. The
default value of this attribute was changed from "true" to "false" in version 3.3.1.
margin 0. Note that internal contacts modify the behavior implied by the :ref:`elasticity parameters<flex-elasticity>`
and is recommended only for flexes where element inversion cannot be prevented.
.. _flex-contact-selfcollide:
@@ -4369,7 +4365,7 @@ extensions specific to flexes.
:at:`passive`: :at-val:`[true, false], "false"`
When enabled, the contact is not added to the contact solver but it is instead used to compute passive
(spring-damper) contact forces. All contacts, regardless of the specified condim, are frictionless (condim 1). This
is an experimental feature and might change in future releases.
is an experimental feature.
.. _deformable-skin:
@@ -4867,13 +4863,7 @@ constraint type is only supported for dimension 3 flexes with trilinear or quadr
Name of the flex whose strain is being constrained.
.. _equality-distance:
:el-prefix:`equality/` |-| **distance** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Distance equality constraints were removed in MuJoCo version 2.2.2. If you are using an earlier version, please switch
to the corresponding version of the documentation.
.. _tendon:
@@ -5157,7 +5147,7 @@ illustrated the use of pulleys.
This element creates an abstract tendon whose length is defined as a linear combination of joint positions. Recall that
the tendon length and its gradient are the only quantities needed for simulation. Thus we could define any scalar
function of joint positions, call it "tendon", and plug it in MuJoCo. Presently the only such function is a fixed linear
function of joint positions, call it "tendon", and use it in MuJoCo. The only such function supported is a fixed linear
combination. The attributes of fixed tendons are a subset of the attributes of spatial tendons and have the same meaning
as above.
@@ -5574,8 +5564,8 @@ specify them independently.
:el-prefix:`actuator/` |-| **motor** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This and the next three elements are the :ref:`Actuator shortcuts <CActShortcuts>` discussed earlier. When a
such shortcut is encountered, the parser creates a :el:`general` actuator and sets its dynprm, gainprm and biasprm
This and the next three elements are the :ref:`Actuator shortcuts <CActShortcuts>` discussed earlier. When
such a shortcut is encountered, the parser creates a :el:`general` actuator and sets its dynprm, gainprm and biasprm
attributes to the internal defaults shown above, regardless of any default settings. It then adjusts dyntype, gaintype
and biastype depending on the shortcut, parses any custom attributes (beyond the common ones), and translates them
into regular attributes (i.e., attributes of the :el:`general` actuator type) as explained here.
@@ -5775,7 +5765,7 @@ This element has one custom attribute in addition to the common attributes:
:el-prefix:`actuator/` |-| **velocity** |*|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This element creates a velocity servo. Note that in order create a PD controller, one has to define two actuators: a
This element creates a velocity servo. Note that in order to create a PD controller, one has to define two actuators: a
position servo and a velocity servo. This is because MuJoCo actuators are SISO while a PD controller takes two control
inputs (reference position and reference velocity).
When using this actuator, it is recommended to use the implicitfast or implicit :ref:`integrators<geIntegration>`.
@@ -6204,7 +6194,7 @@ This element has nine custom attributes in addition to the common attributes:
:at:`tausmooth`: :at-val:`real, "0"`
Width of smooth transition between activation and deactivation time constants. Units of ctrl, must be
nonegative.
nonnegative.
.. _actuator-muscle-range:
@@ -6598,7 +6588,7 @@ computations.
In addition to the sensors created with the elements below, the top-level function
:ref:`mj_step` computes the quantities mjData.cacc, mjData.cfrc_int and mjData.crfc_ext
corresponding to body accelerations and interaction forces. Some of these quantities are used to compute the output of
certain sensors (force, acceleration etc.) but even if no such sensors are defined in the model, these quantities
certain sensors (force, acceleration, etc.) but even if no such sensors are defined in the model, these quantities
themselves are "features" that could be of interest to the user.
@@ -6611,7 +6601,7 @@ This element creates a touch sensor. The active sensor zone is defined by a site
site's volume, and involves a geom attached to the same body as the site, the corresponding contact force is included in
the sensor reading. If a contact point falls outside the sensor zone, but the normal ray intersects the sensor zone, it
is also included. This re-projection feature is needed because, without it, the contact point may leave the sensor zone
from the back (due to soft contacts) and cause an erroneous force reading. The output of this sensor is non-negative
from the back (due to soft contacts) and cause an erroneous force reading. The output of this sensor is a non-negative
scalar. It is computed by adding up the (scalar) normal forces from all included contacts.
.. _sensor-touch-name:
@@ -6878,10 +6868,10 @@ defined as geoms whose rgba (or whose material rgba) has alpha=0, are also exclu
invisible in the visualizer by disabling their geom group are not excluded; this is because sensor calculations are
independent of the visualizer.
The image on the right (click to see the model being visualized) shows two rangefinder sensors attached to a perspective and
an orthographic camera, with frustums visualized. Both cameras have 4x4 resolution, for 16 rays each. The rangefinder
sensors report :at:`data` = :at-val:`"dist point normal"` (see below), so we can see the rays (lines), the intersection
points (spheres) and the surface normals (arrows).
The image on the right (click to see the model being visualized) shows two rangefinder sensors attached to a
perspective and an orthographic camera, with frustums visualized. Both cameras have 4x4 resolution, for 16 rays
each. The rangefinder sensors report :at:`data` = :at-val:`"dist point normal"` (see below), so we can see the rays
(lines), the intersection points (spheres) and the surface normals (arrows).
.. _sensor-rangefinder-data:
@@ -8328,7 +8318,7 @@ sensor reports information that was discovered during the collision and constrai
from ``mjData.{contact, efc_force}``, ignoring contacts that were filtered out by the :ref:`standard<coSelection>`
mechanism and produce no force.
Contact sensor output involves three stages: **matching**, **reduction** and **extraction**.
Contact sensor output involves three stages: **matching**, **reduction**, and **extraction**.
Matching
Selects a set of contacts from ``mjData.contact`` using criteria defined by :ref:`geom1<sensor-contact-geom1>`,
@@ -8346,7 +8336,7 @@ Matching
Reduction
Reduces the number of matched contacts to exactly :ref:`num<sensor-contact-num>` sub-arrays, or "slots".
If less than :at:`num` contacts match, the remaining slots are set to be identically zero. Note that the default,
"unsorted" reduction criterion is potentitally non-deterministic. See :ref:`reduce<sensor-contact-reduce>` below.
"unsorted" reduction criterion is potentially non-deterministic. See :ref:`reduce<sensor-contact-reduce>` below.
Extraction
Copies the set of fields specified by the user into each slot, see :ref:`data<sensor-contact-data>`.
@@ -8400,7 +8390,7 @@ Extraction
Importantly, the :at:`data` attribute can contain **multiple sequential data types**, as long as the relative
order---as listed above---is maintained. For example, :at:`data` = :at-val:`"found force dist"` will return 5 numbers
per contact (the concateneated values of [found, force, dist]), while :at:`data` = :at-val:`"force found dist"` is an
per contact (the concatenated values of [found, force, dist]), while :at:`data` = :at-val:`"force found dist"` is an
error because :at-val:`found` must come before :at-val:`force`.
Missing contacts
@@ -8599,8 +8589,8 @@ This element creates a user sensor. MuJoCo does not know how to compute the outp
should install the callback :ref:`mjcb_sensor` which is expected to fill in the sensor data in ``mjData.sensordata``.
The specification in the XML is used to allocate space for this sensor, and also determine which MuJoCo object it is
attached to and what stage of computation it needs before the data can be computed. Note that the MuJoCo object
referenced here can be a tuple, which in turn can reference a custom collection of MuJoCo objects -- for example several
bodies whose center of mass is of interest.
referenced here can be a tuple, which in turn can reference a custom collection of MuJoCo objects -- for example
several bodies whose center of mass is of interest.
If a user sensor is of :ref:`stage<sensor-user-needstage>` "vel" or "acc", then :ref:`mj_subtreeVel` or
:ref:`mj_rnePostConstraint` will be triggered, respectively.
@@ -8877,7 +8867,7 @@ visualization should somehow be simplified.
.. _visual-quality-shadowsize:
:at:`shadowsize`: :at-val:`int, "4096"`
This attribute specifies the size of the square texture used for shadow mapping. Higher values result is smoother
This attribute specifies the size of the square texture used for shadow mapping. Higher values result in smoother
shadows. The size of the area over which a :ref:`light <body-light>` can cast shadows also affects smoothness, so
these settings should be adjusted jointly. The default here is somewhat conservative. Most modern GPUs are able to
handle significantly larger textures without slowing down.
@@ -9246,7 +9236,7 @@ disables the rendering of the corresponding object.
.. _visual-rgba-contactgap:
:at:`contactgap`: :at-val:`real(4), "0.5, 0.8, 0.9, 1"`
:at:`contactgap`: :at-val:`real(4), "0.5 0.8 0.9 1"`
Color of contacts that fall in the contact gap (and are thereby excluded from contact force computations).
.. _visual-rgba-rangefinder:
@@ -9315,7 +9305,7 @@ if omitted.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| This element sets the attributes of the dummy :ref:`mesh <asset-mesh>` element of the defaults class.
| The available attributes are: :ref:`scale <asset-mesh-scale>` and :ref:`scale <asset-mesh-maxhullvert>`.
| The available attributes are: :ref:`scale <asset-mesh-scale>` and :ref:`maxhullvert <asset-mesh-maxhullvert>`.
.. _default-material:
@@ -9766,8 +9756,8 @@ if omitted.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This and the next three elements set the attributes of the :ref:`general <actuator-general>` element using
:ref:`Actuator shortcuts <CActShortcuts>`. It does not make sense to use more than one such shortcut in the same defaults
class, because they set the same underlying attributes, replacing any previous settings. All
:ref:`Actuator shortcuts <CActShortcuts>`. It does not make sense to use more than one such shortcut in the same
defaults class, because they set the same underlying attributes, replacing any previous settings. All
:ref:`motor <actuator-motor>` attributes are available here except: name, class, joint, jointinparent, site, refsite,
tendon, slidersite, cranksite.
@@ -10228,7 +10218,7 @@ See :ref:`exPlugin` for more details.
:el-prefix:`plugin/` |-| **instance** |*|
'''''''''''''''''''''''''''''''''''''''''
Declares a plugin instance. Explicit instances declaration is required when multiple elements are backed by the same
Declares a plugin instance. Explicit instance declaration is required when multiple elements are backed by the same
plugin, or when global plugin configuration is desired. See plugin :ref:`declaration<exDeclaration>` and
:ref:`configuration<exConfiguration>` for more details.
+65 -37
View File
@@ -202,7 +202,7 @@ earlier arm model :ref:`example <Examples>` the model has :math:`\nv = 13` degre
for each of the 4 hinge joints, and 6 for the free-floating object. They appear in the same order in all system-level
vectors and matrices whose dimensionality is :math:`\nv`. The data corresponding to a given model element can be
recovered via indexing operations as illustrated in the :ref:`Clarifications` section in the Overview chapter. Vectors
and matrices with dimensionality :math:`\nq` are somewhat different because the active :ref:`constraints <Constraint>`
and matrices with dimensionality :math:`\nc` are somewhat different because the active :ref:`constraints <Constraint>`
change at runtime. In that case there is still a fixed enumeration order (corresponding to the order in which the model
elements appear in ``mjModel``) but any inactive constraints are omitted.
@@ -524,13 +524,13 @@ the *new* velocity. *Implicit* Euler means:
\end{aligned}
Comparing :eq:`eq_semimplicit` and :eq:`eq_implicit`, we see that the acceleration :math:`a_{t+h}=\dot{v}_{t+h}` on the
right hand side of the velocity update is evaluated at the *next time step*. While evaluating the next acceleration
right-hand side of the velocity update is evaluated at the *next time step*. While evaluating the next acceleration
is not possible without stepping, we can use a first-order Taylor expansion to approximate this quantity, and
take a single step of Newton's method. When the expansion is only with respect to velocity (and not position), the
integrator is known as *implicit-in-velocity* Euler. This approach is particularly effective in systems where
instabilities are caused by velocity-dependent forces: multi-joint pendulums, bodies tumbling through space, systems
with lift and drag forces, and systems with substantial damping in tendons and actuators. Writing the
acceleration as a function of velocity: :math:`a_t = a(v_t)`, the velocity update we aim to approximate is
acceleration as a function of velocity, :math:`a_t = a(v_t)`, the velocity update we aim to approximate is
.. math:: v_{t+h} = v_t + h a(v_{t+h})
@@ -550,7 +550,7 @@ Thus we define the derivative
D &\equiv {\partial \over \partial v} \Big(\tau(v) - c (v) + J^T f(v)\Big)
\end{aligned}
The velocity update corresponding to Newton's method is as follows. First, we expand the right hand side to first order
The velocity update corresponding to Newton's method is as follows. First, we expand the right-hand side to first order
.. math::
\begin{aligned}
@@ -585,7 +585,7 @@ Semi-implicit with implicit joint damping (``Euler``)
For this method, :math:`D` only includes derivatives of joint damping. Note that in this case :math:`D` is diagonal
and :math:`\widehat{M}` is symmetric, so :math:`L^TL` decomposition (a variant of Cholesky) can be used. This
factorization is stored in ``mjData.qH``. If the model has no joint damping or the
:ref:`eulerdamp<option-flag-eulerdamp>` disable-flag is set, implicit damping is disabled and the semi-implicit
:ref:`eulerdamp<option-flag-eulerdamp>` disable flag is set, implicit damping is disabled and the semi-implicit
update :eq:`eq_semimplicit` is used, rather than :eq:`eq_implicit_update`, avoiding the additional factorization of
:math:`\widehat{M}` (*additional* because :math:`M` is already factorized for the acceleration update
:eq:`eq_forward`).
@@ -612,12 +612,12 @@ Fast implicit-in-velocity (``implicitfast``)
4th-order Runge-Kutta (``RK4``)
One advantage of our continuous-time formulation is that we can use higher order integrators such as Runge-Kutta or
multistep methods. The only such integrator currently implemented is the fixed-step `4th-order Runge-Kutta method
multistep methods. MuJoCo implements the fixed-step `4th-order Runge-Kutta method
<https://en.wikipedia.org/wiki/RungeKutta_methods#Derivation_of_the_RungeKutta_fourth-order_method>`__, though
users can easily implement other integrators by calling :ref:`mj_forward` and integrating accelerations themselves.
We have observed that for energy-conserving systems (`example <../_static/pendulum.xml>`__), RK4 is qualitatively
better than the single-step methods, both in terms of stability and accuracy, even when the timestep is decreased by
a factor of 4 (so the computational effort is identical). In the presence of large velocity- dependent forces, if the
a factor of 4 (so the computational effort is identical). In the presence of large velocity-dependent forces, if the
chosen single-step method integrates those forces implicitly, single-step methods can be significantly more stable
than RK4.
@@ -683,8 +683,8 @@ Constraint model
MuJoCo has a very flexible constraint model, which is nevertheless handled in a uniform way by the
:ref:`solver <Solver>` described later. Here we explain what the individual constraints are conceptually, and how they
are laid out in the system-level vector and matrices with dimensionality :math:`\nq`. Each conceptual constraint can
contribute one or more scalar constraints towards the total count :math:`\nq`, and each scalar constraint has a
are laid out in the system-level vector and matrices with dimensionality :math:`\nc`. Each conceptual constraint can
contribute one or more scalar constraints towards the total count :math:`\nc`, and each scalar constraint has a
corresponding row in the constraint Jacobian :math:`J`. Active constraints are ordered by type in the order in which the
types are described below, and then by model element within each type. The types are: equality, friction loss, limit,
contact. Limits are handled as frictionless contacts by the solver and are not treated as a separate type internally. We
@@ -698,7 +698,7 @@ Equality
MuJoCo can model equality constraints in the general form :math:`r(q) = 0` where :math:`r` can be any differentiable
scalar or vector function of the position vector :math:`q`. It has the semantics of a residual. The solver can actually
work with non-holonomic constraints as well, but we do not yet have such constraint types defined. Each equality
constraint contributes :math:`\dim(r)` elements to the total constraint count :math:`\nq`. The corresponding block in
constraint contributes :math:`\dim(r)` elements to the total constraint count :math:`\nc`. The corresponding block in
:math:`J` is simply the Jacobian of the residual, namely :math:`\partial r / \partial q`. Note that due to the
properties of quaternions, differentiation with respect to :math:`q` produces vectors of size :math:`\nv` rather than
:math:`\nq`.
@@ -1002,34 +1002,34 @@ We will use the following notation beyond the notation introduced earlier:
- Size
- Description
* - :math:`z`
- :math:`\nq`
- :math:`\nc`
- constraint deformations
* - :math:`\omega`
- :math:`\nq`
- :math:`\nc`
- velocity of constraint deformations
* - :math:`k`
- :math:`\nq`
- :math:`\nc`
- virtual constraint stiffness
* - :math:`b`
- :math:`\nq`
- :math:`\nc`
- virtual constraint damping
* - :math:`d`
- :math:`\nq`
- :math:`\nc`
- constraint impedance
* - :math:`A(q)`
- :math:`\nq \times \nq`
- :math:`\nc \times \nc`
- inverse inertia in constraint space
* - :math:`R(q)`
- :math:`\nq \times \nq`
- :math:`\nc \times \nc`
- diagonal regularizer in constraint space
* - :math:`\ar`
- :math:`\nq`
- :math:`\nc`
- reference acceleration in constraint space
* - :math:`\au(q, v, \tau)`
- :math:`\nq`
- :math:`\nc`
- unconstrained acceleration in constraint space
* - :math:`\ac(q, v, \dot{v})`
- :math:`\nq`
- :math:`\nc`
- constrained acceleration in constraint space
* - :math:`\mathcal{K}(q)`
-
@@ -1066,7 +1066,8 @@ explain what it means and why it makes sense. That problem is
:label: eq:primal
The new players here are the diagonal regularizer :math:`R > 0` which makes the constraints soft, and the reference
acceleration :math:`\ar` which stabilizes the constraints. The latter is similar in spirit to Baumgarte stabilization,
acceleration :math:`\ar` which stabilizes the constraints; the latter is a spring-damper defined in the
:ref:`Parameters <soParameters>` section below. It is similar in spirit to Baumgarte stabilization,
but instead of adding a constraint force directly, it modifies the optimization problem whose solution is the constraint
force. Since this problem is itself constrained, the relation between :math:`\ar` and :math:`f` is generally non-linear.
The quantities :math:`R` and :math:`\ar` are computed from the solver :ref:`parameters <soParameters>` as described
@@ -1254,13 +1255,15 @@ implementation, we do not actually compute the acceleration term :math:`\dot{J}
problems depend on differences of constraint-space accelerations, and so this term would cancel out even if we were to
compute it.
Note that the quadratic term in the inverse problem is weighted by :math:`R` instead of :math:`A+R`. This tells us two
things. First, in the limit :math:`R \to 0` corresponding to hard constraints the inverse is no longer defined, as one
would expect. Second and more useful, the inverse problem is diagonal, i.e., it decouples into independent optimization
problems over the individual constraint forces. The only remaining coupling is due to the constraint set :math:`\Omega`,
but that set is also decoupled over the conceptual constraints discussed earlier. It turns out that all these
independent optimization problems can be solved analytically. The only non-trivial case is the elliptic friction cone
model; we have shown how it can be handled in the above-referenced
Note that the quadratic term in the inverse problem is weighted by :math:`R` instead of :math:`A+R`. This is the key
structural insight: the :math:`A` matrix cancels entirely, leaving only :math:`R` in the quadratic term. Two
consequences follow. First, in the limit :math:`R \to 0` corresponding to hard constraints the inverse is no longer
defined, as one would expect. Second, the inverse problem is diagonal, i.e., it decouples into independent optimization
problems over the individual constraint forces. Since :math:`R` is diagonal, no matrix inversion or factorization is
needed -- the inverse dynamics require no optimization at all, only analytical formulas. The only remaining coupling is
due to the constraint set :math:`\Omega`, but that set is also decoupled over the conceptual constraints discussed
earlier. It turns out that all these independent optimization problems can be solved analytically. The only non-trivial
case is the elliptic friction cone model; we have shown how it can be handled in the above-referenced
`paper <https://scholar.google.com/scholar?cluster=9217655838195954277>`__. It requires a certain coupling of the
diagonal values of :math:`R`, which is automatically enforced by MuJoCo so as to enable an exact analytical inverse for
every model.
@@ -1287,12 +1290,15 @@ Each solver algorithm can be used with both pyramidal and elliptic friction cone
representations of the constraint Jacobian and related matrices.
**CG** : conjugate gradient method
This algorithm uses the non-linear conjugate gradient method with the Polak-Ribiere-Plus formula. Line-search is
exact, using Newton's method in one dimension, with analytical second derivatives.
This algorithm uses the non-linear conjugate gradient method with the Polak-Ribiere-Plus formula (non-negative
:math:`\beta`). Line-search is exact, using Newton's method in one dimension with analytical second derivatives on
the piecewise-quadratic cost. CG has no setup cost.
**Newton** : Newton's method
This algorithm implements the exact Newton method, with analytical second-order derivatives and Cholesky
factorization of the Hessian. The line-search is the same as in the CG method. It is the default solver.
factorization of the Hessian. The line-search is the same as in the CG method. When constraint states change between
iterations (e.g., a constraint transitions from quadratic to linear), the Hessian factorization is updated
incrementally via rank-1 Cholesky updates, avoiding full refactorization. It is the default solver.
**PGS** : Projected Gauss-Seidel method
This is the most common algorithm used in physics simulators, and used to be the default in MuJoCo, until we
@@ -1327,6 +1333,21 @@ representations of the constraint Jacobian and related matrices.
handle elliptic cones without approximating them. It does more work per contact, however the contact dimensionality
is smaller, and these two factors roughly balance each other.
**NoSlip** : post-processing pass
This is not a standalone solver but a post-processing step, enabled by setting ``noslip_iterations`` to a positive
value in :ref:`option <option>`. After the main solver (Newton, CG, or PGS) has converged, the NoSlip solver
re-solves the friction dimensions only, using a PGS sweep with :math:`R = 0` (i.e., hard constraints) in those
dimensions. This suppresses the contact slip that is inherent to soft-constraint models. However, this cascade of
optimization steps no longer solves a single well-defined optimization problem; it is an ad-hoc correction that can
occasionally cause instabilities in models with complex multi-contact interactions.
**Warmstart**
Before solving, the solver warmstarts the constraint forces from the previous time step. It evaluates the cost of
the warmstarted forces and compares it against the cost of zero forces (i.e., the unconstrained solution
``qacc_smooth``). The lower-cost initialization is used. This dual warmstart strategy is robust: it quickly
bootstraps the solver when constraints persist across time steps, but avoids carrying over stale forces from
constraints that have disappeared.
.. _soIsland:
Constraint islands
@@ -1384,7 +1405,7 @@ Thus the constrained acceleration interpolates between the unconstrained and the
in the limit :math:`R \to 0` we have a hard constraint and :math:`\ac = \ar`, while in the limit :math:`R \to \infty` we
have have an infinitely soft constraint (i.e., no constraint) and :math:`\ac = \au`. It is then natural to introduce a
model parameter which directly controls the interpolation. We call this parameter *impedance* and denote it :math:`d`.
It is a vector with dimensionality :math:`\nq` satisfying :math:`0<d<1` element-wise. Once it is specified, we compute
It is a vector with dimensionality :math:`\nc` satisfying :math:`0<d<1` element-wise. Once it is specified, we compute
the diagonal elements of the regularizer as
.. math::
@@ -1420,22 +1441,29 @@ pure damping: :math:`\ari = -b_i (J v)_i`. More detail is given in the :ref:`Fri
Modeling chapter.
To summarize, the constraint behavior is determined by three per-constraint quantities: impedance :math:`0<d<1`, damping
:math:`b > 0` and stiffness :math:`k \geq 0`. These are computed from the :at:`solimp` and :at:`solref` attributes as
:math:`b > 0`, and stiffness :math:`k \geq 0`. These are computed from the :at:`solimp` and :at:`solref` attributes as
described in the :ref:`solver parameters <soRefScaling>` section of the Modeling chapter, which also offers additional
automation (e.g., achieving critical damping, or varying :math:`d` with distance to model a soft contact layer). The
quantities :math:`R, \ar` are then computed from :eq:`eq:impedance_R` and :eq:`eq:aref`, and the selected optimization
algorithm is applied to solve problem :eq:`eq:dual`.
The closed-loop constraint dynamics resulting from the combination of :math:`R` and :math:`\ar` are analyzed in
detail in the :ref:`Solver parameters <CSolver>` section of the Modeling chapter. In brief, each scalar constraint
behaves approximately as a damped second-order system whose time constant and damping ratio are set by the :at:`solref`
attribute, and whose strength is controlled by the impedance :math:`d` set via :at:`solimp`. When critically damped
(:math:`\text{dampratio} = 1`), the steady-state penetration under a constant external load is independent of the
effective mass in constraint space -- a consequence of the impedance-scaled parameterization.
.. _soCones:
Friction cones
~~~~~~~~~~~~~~
As explained above, MuJoCo allows both elliptic friction cones and pyramidal approximations to them; the selected solver
determines which type of friction cone is used. The pyramidal approximation has :math:`2 (n-1)` edges where :math:`n` is
the dimensionality of the contact space as specified by condim. We could add more edges yielding better approximations
to the underlying elliptic cone, but this is pointless because the resulting solver would become slower than its
elliptic counterpart.
determines which type of friction cone is used. The pyramidal approximation has :math:`2 (n-1)` edges where :math:`n`
is the dimensionality of the contact space as specified by :at:`condim`. We could add more edges yielding better
approximations to the underlying elliptic cone, but this is pointless because the resulting solver would become
slower than its elliptic counterpart.
One might have expected that if we were to increase the number of edges in the pyramidal approximation, the solution to
our optimization problem :eq:`eq:primal` would converge to the solution for the elliptic cone. This is true in the limit
+6 -6
View File
@@ -14,10 +14,10 @@ under the `mjx <https://github.com/google-deepmind/mujoco/tree/main/mjx>`__ dire
MJX allows users to run MuJoCo
on all compute hardware supported by the `XLA <https://www.tensorflow.org/xla>`__ compiler. A JAX re-implementation of
MuJoCo (:ref:`MJX-JAX <MjxJAX>`) was added in version 3.0.0. MJX-JAX
MuJoCo (:ref:`MJX-JAX <MjxJAX>`) is available. MJX-JAX
`runs on <https://jax.readthedocs.io/en/latest/installation.html#supported-platforms>`__: Nvidia and AMD GPUs,
Apple Silicon, and `Google Cloud TPUs <https://cloud.google.com/tpu>`__. A Warp implementation of MuJoCo
(:ref:`MJX-Warp <MjxWarp>`) was added in version 3.3.5 to optimize performance specifically for NVIDIA GPUs, resolving
(:ref:`MJX-Warp <MjxWarp>`) optimizes performance specifically for NVIDIA GPUs, resolving
several performance bottlenecks exhibited in MJX-JAX.
MJX is distributed as a separate package called ``mujoco-mjx`` on `PyPI <https://pypi.org/project/mujoco-mjx>`__.
@@ -125,8 +125,8 @@ Notice that we pass two extra arguments to ``mjx.make_data``:
Contacts
~~~~~~~~
Since JAX and Warp diverge in their implementations of contact buffers, contacts were moved from
``mjx.Data.contact`` to private ``mjx.Data._impl`` in MuJoCo 3.3.5. We encourage users to read out contacts solely through
Since JAX and Warp diverge in their implementations of contact buffers, contacts are located in the private
``mjx.Data._impl`` instead of ``mjx.Data.contact``. We encourage users to read out contacts solely through
:ref:`contact sensors <sensor-contact>`.
For more details and examples of using MJX-Warp in the wild, see the announcement in MuJoCo Playground
@@ -426,8 +426,8 @@ solver parameters.
Feature Parity
==============
MJX supports most of the main simulation features of MuJoCo to be run on hardware accelerated devices. MJX will raise an exception if
asked to copy to device an :ref:`mjModel` with field values referencing unsupported features.
MJX supports most of the main simulation features of MuJoCo for execution on hardware-accelerated devices. MJX will
raise an exception if asked to copy an :ref:`mjModel` to the device that references unsupported features.
The following table compares feature support between MJX-Warp and MJX-JAX compared to MuJoCo:
+48 -72
View File
@@ -263,13 +263,15 @@ specified by the user, the frame is not rotated.
Solver parameters
~~~~~~~~~~~~~~~~~
The solver :ref:`Parameters <soParameters>` section of the Computation chapter explained the mathematical and
algorithmic meaning of the quantities :math:`d, b, k` which determine the behavior of the constraints in MuJoCo. Here we
explain how to set them. Setting is done indirectly, through the attributes :at:`solref` and :at:`solimp` which are
available in all MJCF elements involving constraints. These parameters can be adjusted per constraint, or per defaults
class, or left undefined -- in which case MuJoCo uses the internal defaults shown below. Note also the override mechanism
available in :ref:`option <option>`; it can be used to change all contact-related solver parameters at runtime, so as to
experiment interactively with parameter settings or implement continuation methods for numerical optimization.
The constraint solver finds forces that satisfy soft constraints, parameterized by three quantities: the *impedance*
:math:`d` (how strongly to enforce the constraint), *stiffness* :math:`k`, and *damping* :math:`b` (how to respond to
violations). These are described mathematically in the :ref:`Parameters <soParameters>` section of the Computation
chapter. Here we explain how to set them. Setting is done indirectly, through the attributes :at:`solref` and
:at:`solimp` which are available in all MJCF elements involving constraints. These parameters can be adjusted per
constraint, or per defaults class, or left undefined -- in which case MuJoCo uses the internal defaults shown below.
Note also the override mechanism available in :ref:`option <option>`; it can be used to change all contact-related
solver parameters at runtime, so as to experiment interactively with parameter settings or implement continuation
methods for numerical optimization.
Here we focus on a single scalar constraint. Using slightly different notation from the Computation chapter, let
:math:`\ac` denote the acceleration, :math:`v` the velocity, :math:`r` the position or residual (defined as 0 in
@@ -583,11 +585,11 @@ Solver settings
~~~~~~~~~~~~~~~
The computation of constraint forces and constrained accelerations involves solving an optimization problem
numerically. MuJoCo has three algorithms for solving this optimization problem: CG, Newton, PGS. Each of them can be
numerically. MuJoCo has three algorithms for solving this optimization problem: Newton, CG, PGS. Each of them can be
applied to a pyramidal or elliptic model of the friction cones, and with dense or sparse constraint Jacobians. In
addition, the user can specify the maximum number of iterations, and tolerance level which controls early termination.
There is also a second Noslip solver, which is a post-processing step enabled by specifying a positive number of
noslip iterations. All these algorithm settings can be specified in the :ref:`option <option>` element.
There is also a NoSlip solver, which is a post-processing step enabled by specifying a positive number of NoSlip
iterations. All these algorithm settings can be specified in the :ref:`option <option>` element.
The default settings work well for most models, but in some cases it is necessary to tune the algorithm. The best way to
do this is to experiment with the relevant settings and use the visual profiler in :ref:`simulate.cc <saSimulate>`,
@@ -621,8 +623,8 @@ general guidelines and observations:
with large mass ratios or other model properties causing poor conditioning, PGS convergence tends to be rather slow.
Keep in mind that PGS performs sequential updates, and therefore breaks symmetry in systems where the physics should
be symmetric. In contrast, CG and Newton perform parallel updates and preserve symmetry.
- The Noslip solver is a modified PGS solver. It is executed as a post-processing step after the main solver (which can
be Newton, CG or PGS). The main solver updates all unknowns. In contrast, the Noslip solver updates only the
- The NoSlip solver is a modified PGS solver. It is executed as a post-processing step after the main solver (which can
be Newton, CG or PGS). The main solver updates all unknowns. In contrast, the NoSlip solver updates only the
constraint forces in friction dimensions, and ignores constraint regularization. This has the effect of suppressing
the drift or slip caused by the soft-constraint model. However, this cascade of optimization steps is no longer
solving a well-defined optimization problem (or any other problem); instead it is just an adhoc mechanism. While it
@@ -630,9 +632,9 @@ general guidelines and observations:
contacts.
- PGS has a setup cost (in terms of CPU time) for computing the inverse inertia in constraint space. Similarly, Newton
has a setup cost for the initial factorization of the Hessian, and incurs additional factorization costs depending on
how many factorization updates are needed later. CG does not have any setup cost. Since the Noslip solver is also a
PGS solver, the PGS setup cost will be paid whenever Noslip is enabled, even if the main solver is CG or Newton. The
setup operation for the main PGS and Noslip PGS is the same, thus the setup cost is paid only once when both are
how many factorization updates are needed later. CG does not have any setup cost. Since the NoSlip solver is also a
PGS solver, the PGS setup cost will be paid whenever NoSlip is enabled, even if the main solver is CG or Newton. The
setup operation for the main PGS and NoSlip PGS is the same, thus the setup cost is paid only once when both are
enabled.
.. _CActuators:
@@ -681,7 +683,8 @@ independently. The full functionality can be accessed via the XML element :ref:`
the user to create a variety of custom actuators. In addition, MJCF provides shortcuts for configuring common actuators.
This is done via the XML elements :ref:`motor <actuator-motor>`, :ref:`position <actuator-position>`, :ref:`velocity
<actuator-velocity>`, :ref:`intvelocity <actuator-intvelocity>`, :ref:`damper<actuator-damper>`,
:ref:`cylinder<actuator-cylinder>`, :ref:`muscle <actuator-muscle>`, and :ref:`adhesion <actuator-adhesion>`. These are
:ref:`cylinder<actuator-cylinder>`, :ref:`muscle <actuator-muscle>`, :ref:`adhesion <actuator-adhesion>`, and
:ref:`dcmotor<actuator-dcmotor>`. These are
*not* separate model elements. Internally MuJoCo supports only one actuator type -which is why when an MJCF model is
saved all actuators are written as :el:`general`. Shortcuts create general actuators implicitly, set their attributes to
suitable values, and expose a subset of attributes with possibly different names. For example, :el:`position` creates a
@@ -764,9 +767,9 @@ Unlike all other fields of mjModel which are exact physical or geometric quantit
approximation. Intuitively it corresponds to the minimum and maximum length that the actuator's transmission can reach
over all "feasible" configurations of the model. However MuJoCo constraints are soft, so in principle any
configuration is feasible. Yet we need a well-defined range for muscle modeling. There are three ways to set this
range: (1) provide it explicitly using the new attribute lengthrange available in all actuators; (2) copy it from the
range: (1) provide it explicitly using the attribute lengthrange available in all actuators; (2) copy it from the
limits of the joint or tendon to which the actuator is attached; (3) compute it automatically, as explained in the
rest of this section. There are many options here, controlled with the new XML element
rest of this section. There are many options here, controlled with the XML element
:ref:`lengthrange <compiler-lengthrange>`.
Automatic computation of actuator length ranges is done at compile time, and the results are stored in
@@ -1111,10 +1114,8 @@ Here we describe the XML attributes common to all sensor types, so as to avoid r
.. _sensor-noise:
:at:`noise`: :at-val:`real, "0"`
The standard deviation of the noise model of this sensor. In versions prior to 3.1.4, this would lead to noise being
added to the sensors. In release 3.1.4 this feature was removed, see :doc:`3.1.4 changelog <changelog>` for a
detailed justification. As of subsequent versions, this attribute serves as a convenient location for saving standard
deviation information for later use.
The standard deviation of the noise model of this sensor. This attribute does not affect the simulation; it serves as
a convenient location for storing standard deviation information for later use.
.. _sensor-cutoff:
@@ -1292,10 +1293,15 @@ Besides the default, user-controllable, free camera, "fixed" cameras can be atta
Extrinsics
By default, camera frames are attached to the containing body. The optional :ref:`mode<body-camera-mode>` and
:ref:`target<body-camera-target>` attributes can be used to specify camera that track (move with) or target (look at)
a body or subtree. Cameras look towards the negative Z axis of the camera frame, while positive X and Y correspond to
:ref:`target<body-camera-target>` attributes can be used to specify cameras that track (move with) or target (look
at) a body or subtree. Cameras look towards the negative Z axis of the camera frame, while positive X and Y correspond to
*right* and *up* in the image plane, respectively.
Projection
Cameras use :ref:`perspective<body-camera-projection>` projection by default. Setting
:ref:`projection<body-camera-projection>` to ``orthographic`` switches to an orthographic projection, where the
:ref:`fovy<body-camera-fovy>` attribute is interpreted as the vertical extent in length units rather than degrees.
Intrinsics
Camera intrinsics are specified using :ref:`ipd<body-camera-ipd>` (inter-pupilary distance, required for
stereoscopic rendering and VR) and :ref:`fovy<body-camera-fovy>` (vertical field of view, in degrees).
@@ -1313,15 +1319,14 @@ Intrinsics
Composite objects
~~~~~~~~~~~~~~~~~
Composite objects are not new model elements. Instead, they are collections of existing element originally designed to
simulate particle systems, ropes, cloth, and soft bodies. Over time, most of these types have been replaced by
:ref:`replicate<replicate>` (for repeated objects) and :ref:`flexcomp<body-flexcomp>` (for soft objects). Therefore, the
only supported composite type is now ``cable``, which produces an inextensible chain of bodies connected with ball
joints.
Composite objects are collections of existing elements originally designed to simulate particle systems, ropes, cloth,
and soft bodies. Over time, most of these types have been replaced by :ref:`replicate<replicate>` (for repeated objects)
and :ref:`flexcomp<body-flexcomp>` (for soft objects). Therefore, the only supported composite type is now ``cable``,
which produces an inextensible chain of bodies connected with ball joints.
Composite objects are made up of regular MuJoCo bodies, which we call "element bodies" in this context. The collection
of element bodies is generated by the model compiler automatically. The user configures the automatic generator on a
high level, using the new XML element :ref:`composite <body-composite>` and its attributes and sub-elements, as
high level, using the XML element :ref:`composite <body-composite>` and its attributes and sub-elements, as
described in the XML reference chapter. If the compiled model is then saved, :el:`composite` is no longer present and is
replaced with the collection of regular model elements that were automatically generated. So think of it as a macro that
gets expanded by the model compiler. The element bodies are created as children of the body within which :el:`composite`
@@ -1380,32 +1385,11 @@ stiffnesses can be set independently. Moreover, it is possible to specify if the
curve, such as in the case of coil springs. The cable requires using a first-party :ref:`engine plugin<exPlugin>`, which
may be integrated directly into the engine in the future.
**Particle**.
**Deprecated types**.
The particle type is deprecated. It is recommended to use the more generic :ref:`replicate<replicate>` instead, for
example `this model <https://github.com/google-deepmind/mujoco/blob/main/model/replicate/particle.xml>`__.
**Grid**.
The grid composite type has been removed. It is recommended to use 2D flex :ref:`deformable objects <CDeformable>` for
simulating thin elastic structures.
**Rope and loop**.
The rope and loop are deprecated. It is recommended to use the cable for simulating inextensible elastic rods that are
bent and twisted and 1D flex :ref:`deformable objects <CDeformable>` for extensible strings in a tensile loading
scenario (e.g. a stretched rubber band).
**Cloth**.
The cloth is deprecated. It is recommended to use 2D flex :ref:`deformable objects <CDeformable>` for simulating thin
elastic structures.
**Box, cylinder and ellipsoid**.
The box type, as well as the cylinder and ellipsoid types, are now deprecated in favor of 3D flex :ref:`deformable
objects <CDeformable>`. element.
All composite types other than ``cable`` have been deprecated or removed. Use :ref:`replicate<replicate>` for repeated
objects (e.g., particle systems) and :ref:`flex<CDeformable>` deformable objects for soft bodies (ropes, cloth,
volumetric solids).
.. _CDeformable:
@@ -1512,7 +1496,7 @@ are allowed even when that does not make sense semantically in the context of a
the kinematic tree to have multiple roots (i.e., multiple :el:`worldbody` elements) which are merged automatically by
the parser. Otherwise including robots into scenes would be impossible.
The flexibility of repeated MCJF sections comes at a price: global settings that apply to the entire model, such as
The flexibility of repeated MJCF sections comes at a price: global settings that apply to the entire model, such as
the :at:`angle` attribute of :ref:`compiler <compiler>` for example, can be defined multiple times.
MuJoCo allows this, and uses the last definition encountered in the composite model, after all include elements have
been processed. So if model A is defined in degrees and model B is defined in radians, and A is included in B after
@@ -1608,9 +1592,9 @@ violate the simulated physics. But at the same time we want the resulting simula
this?
The first step is to define a mocap body in the MJCF model, and implement code that reads the data stream at runtime and
sets mjModel.mocap_pos and mjModel.mocap_quat to the position and orientation received from the motion capture system.
The :ref:`simulate.cc <saSimulate>` code sample uses the mouse as a motion capture device, allowing the user to move
mocap bodies around:
sets :ref:`mjData.mocap_pos <siMocap>` and :ref:`mjData.mocap_quat <siMocap>` to the position and orientation received
from the motion capture system. The :ref:`simulate.cc <saSimulate>` code sample uses the mouse as a motion capture
device, allowing the user to move mocap bodies around:
|particle|
@@ -1680,14 +1664,6 @@ memory efficient, followed by the Newton solver, while the PGS solver is the mos
models, we usually aim for 50% utilization in the worst-case scenario encountered while exploring the model. If you only
intend to use the CG solver, you can get away with significantly smaller arena allocation.
.. attention::
Memory allocation behaviour changed in MuJoCo 2.3.0. Before this version, the :at:`njmax`, :at:`nconmax` and
:at:`nstack` attributes of the :ref:`size <size>` MJCF element had the semantics of maximum memory allocated for
contacts, constraints and stack, respectively. If you are using an earlier version of MuJoCo, please switch to an
`earlier <https://mujoco.readthedocs.io/en/2.2.2/modeling.html#model-sizes>`_ documentation version to read about the
previous behaviour.
.. _Tips:
Tips and tricks
@@ -1746,9 +1722,9 @@ dedicated section :ref:`therein<MjxPerformance>`.
6. :ref:`Friction cones<option-cone>`: Elliptic cones are more accurate and better at preventing slip with high
:ref:`impratio<option-impratio>`, but are more expensive. If accurate friction is not important, try switching
to pyramidal cones.
7. Compile MuJoCo with 32-bit floating point precision (rather than the default 64). For large models running in
multi-threaded mode, where memory access is more expensive than computation, this can lead to (up to) 2x performance
improvement. See :ref:`mjtNum` for more information.
7. For custom builds, MuJoCo can be compiled with 32-bit floating point precision (rather than the default 64-bit). For
large models where memory bandwidth is the bottleneck, this can improve performance. See :ref:`mjtNum` for more
information. Note that float32 rarely yields measurable speedups in typical models.
.. _CSlippage:
@@ -1803,8 +1779,8 @@ better visualize and understand the contact configuration and resulting forces.
a. Increase the :ref:`impratio<option-impratio>` parameter. This will reduce (but not entirely prevent) slow
slippage. Note that high impratio values work well only with :ref:`elliptic cones<option-cone>`.
b. Enable the noslip solver by increasing :ref:`noslip_iterations<option-noslip_iterations>` to a positive integer.
A small number (1, 2 or 3) is usually sufficient. The noslip post-processing solver will entirely prevent slip,
b. Enable the NoSlip solver by increasing :ref:`noslip_iterations<option-noslip_iterations>` to a positive integer.
A small number (1, 2 or 3) is usually sufficient. The NoSlip post-processing solver will entirely prevent slip,
at the cost of making inverse dynamics ill-defined and additional computational cost.
.. _CBacklash:
+65 -43
View File
@@ -8,9 +8,9 @@ Introduction
aims to facilitate research and development in robotics, biomechanics, graphics and animation, machine learning, and
other areas that demand fast and accurate simulation of articulated structures interacting with their environment.
Initially developed by Roboti LLC, it was acquired and made `freely available
<https://github.com/google-deepmind/mujoco/blob/main/LICENSE>`__ by DeepMind in October 2021, and open sourced in May
2022. The MuJoCo codebase is available at the `google-deepmind/mujoco <https://github.com/google-deepmind/mujoco>`__ repository
on GitHub.
<https://github.com/google-deepmind/mujoco/blob/main/LICENSE>`__ by Google DeepMind in October 2021, and open sourced in
May 2022. The MuJoCo codebase is available at the `google-deepmind/mujoco
<https://github.com/google-deepmind/mujoco>`__ repository on GitHub.
MuJoCo is a C/C++ library with a C API, intended for researchers and developers. The runtime simulation module is tuned
to maximize performance and operates on low-level data structures which are preallocated by the built-in XML parser and
@@ -38,22 +38,21 @@ Generalized coordinates combined with modern contact dynamics
rely on the earlier spring-damper approach which requires very small time-steps. Gaming engines use a more modern
approach where contact forces are found by solving an optimization problem. However, they often resort to the
over-specified Cartesian representation where joint constraints are imposed numerically, causing inaccuracies and
instabilities when elaborate kinematic structures are involved. MuJoCo was the first general-purpose engine to
combine the best of both worlds: simulation in generalized coordinates and optimization-based contact dynamics. Other
simulators have more recently been adapted to use MuJoCo's approach, but that is not usually compatible with all of
their functionality because they were not designed to do this from the start. Users accustomed to gaming engines may
find the generalized coordinates counterintuitive at first; see :ref:`Clarifications` section below.
instabilities when elaborate kinematic structures are involved. MuJoCo pioneered the combination of simulation in
generalized coordinates with optimization-based contact dynamics. This approach has since been adopted by other
simulators. Users accustomed to gaming engines may find the generalized coordinates counterintuitive at first; see
:ref:`Clarifications` section below.
Soft, convex and analytically-invertible contact dynamics
In the modern approach to contact dynamics, the forces or impulses caused by frictional contacts are usually defined
as the solution to a linear or non-linear complementarity problem (LCP or NCP), both of which are NP-hard. MuJoCo is
based on a different formulation of the physics of contact which reduces to a convex optimization problem, as
explained in detail in the :doc:`computation/index` chapter. Our model allows soft contacts and other constraints,
and has a uniquely-defined inverse facilitating data analysis and control applications. There is a choice of
optimization algorithms, including a generalization to the projected Gauss-Seidel method that can handle elliptic
friction cones. The solver provides unified treatment of frictional contacts including torsional and rolling
friction, frictionless contacts, joint and tendon limits, dry friction in joints and tendons, as well as a variety of
equality constraints.
and has a uniquely-defined inverse facilitating data analysis and control applications. The default Newton solver
provides quadratic convergence; alternative algorithms include a conjugate gradient method and a generalized
Projected Gauss-Seidel method that can handle elliptic friction cones. The solver provides unified treatment of
frictional contacts including torsional and rolling friction, frictionless contacts, joint and tendon limits, dry
friction in joints and tendons, as well as a variety of equality constraints.
Tendon geometry
MuJoCo can model the 3D geometry of tendons -- which are minimum-path-length strings obeying wrapping and via-point
@@ -105,6 +104,13 @@ Separation of model and data
void mj_step(const mjModel* m, mjData* d);
Performance
MuJoCo's runtime performs zero memory allocations after initialization -- all working memory is preallocated in
``mjData``. A single simulation step is single-threaded by default, but :ref:`constraint islands <soIsland>` enable
per-island parallelism within a step. Large-scale data-parallel sampling is achieved by creating multiple ``mjData``
instances that share the same ``mjModel`` and running them on separate threads; see :ref:`multi-threading
<siMultithread>`.
Interactive simulation and visualization
The native :ref:`3D visualizer <Visualization>` provides rendering of meshes and geometric primitives, textures,
reflections, shadows, fog, transparency, wireframes, skyboxes, stereoscopic visualization (on video cards supporting
@@ -132,6 +138,25 @@ Automated generation of composite flexible objects
macros which are automatically expanded by the model compiler into the necessary collections of standard model
elements. Importantly, these resulting flexible objects are able to fully interact with the rest of the simulation.
Constraint islands and sleeping
The constraint solver automatically discovers independent :ref:`constraint islands <soIsland>` -- groups of bodies
coupled by constraints that can be solved independently. This enables per-island parallelism and avoids over-solving:
each island converges with the number of iterations it needs, and unconstrained degrees of freedom are skipped
entirely. Additionally, :ref:`island sleeping <Sleeping>` can freeze stationary islands, substantially reducing
computation when parts of the scene are at rest.
Plugin system
MuJoCo supports :doc:`engine plugins <programming/extension>` that extend the physics engine with custom
elements: sensors, actuators, and passive forces. Plugins are dynamically loaded shared libraries that register
themselves with the engine and are instantiated per model element. This allows extending MuJoCo without modifying
the core engine.
GPU-accelerated backends
In addition to the C engine, MuJoCo has GPU-accelerated backends for large-scale parallel simulation:
:doc:`MJX <mjx>` (JAX) and :doc:`MuJoCo Warp <mjwarp/index>` (NVIDIA Warp). Both backends consume the same
``mjModel`` and ``mjData`` structures, allowing seamless transfer between CPU and GPU. First-class
:doc:`Python bindings <python>` provide access to the full C API.
.. _Instance:
Model instances
@@ -601,7 +626,7 @@ Actuator
MuJoCo provides a flexible actuator model, with three components that can be specified independently. Together they
determine how the actuator works. Common actuator types are obtained by specifying these components in a coordinated
way. The three components are transmission, activation dynamics, and force generation. The transmission specifies how
the actuator is attached to the rest of the system; available types are joint, tendon and slider-crank. The
the actuator is attached to the rest of the system; available types are joint, tendon, slider-crank, site and body. The
activation dynamics can be used to model internal activation states of pneumatic or hydraulic cylinders as well as
biological muscles; using such actuators makes the overall system dynamics 3rd-order. The force generation mechanism
determines how the scalar control signal provided as input to the actuator is mapped into a scalar force, which is in
@@ -615,12 +640,12 @@ Sensor
MuJoCo can generate simulated sensor data which is saved in the global array ``mjData.sensordata``. The result is not
used in any internal computations; instead it is provided because the user presumably needs it for custom computation
or data analysis. Available sensor types include touch sensors, inertial measurement units (IMUs), force-torque
sensors, joint and tendon position and velocity sensors, actuator position, velocity and force sensors, motion
capture marker positions and quaternions, and magnetometers. Some of these require extra computation, while others
are copied from the corresponding fields of ``mjData``. There is also a user sensor, allowing user code to insert any
other quantity of interest in the sensor data array. MuJoCo also has off-screen rendering capabilities, making it
straightforward to simulate both color and depth camera sensors. This is not included in the standard sensor model
and instead has to be done programmatically, as illustrated in the code sample :ref:`simulate.cc <saSimulate>`.
sensors, joint and tendon position and velocity sensors, actuator sensors, body frame sensors, rangefinders, and
many others; see the :ref:`Sensor <sensor>` section of the XML reference for the complete list. There is also a user
sensor type, allowing user code to insert any other quantity of interest in the sensor data array. MuJoCo also has
off-screen rendering capabilities, making it straightforward to simulate both color and depth camera sensors. This is
not included in the standard sensor model and instead has to be done programmatically, as illustrated in the code
sample :ref:`simulate.cc <saSimulate>`.
.. _ElemEquality:
@@ -697,8 +722,8 @@ use tuples to define pairs of bodies for custom contact processing.
Keyframe
^^^^^^^^
A keyframe is a snapshot of the simulation state variables. It contains the vectors of joint positions, joint
velocities, actuator activations when present, and the simulation time. The model can contain a library of keyframes.
A keyframe is a snapshot of the simulation state variables. It contains joint positions, joint velocities, actuator
activations, controls, mocap body poses, and the simulation time. The model can contain a library of keyframes.
They are useful for resetting the state of the system to a point of interest. Note that keyframes are not intended
for storing trajectory data in the model; external files should be used for this purpose.
@@ -789,22 +814,18 @@ easy ways to avoid this problem:
.. _NotObject:
Not object-oriented
~~~~~~~~~~~~~~~~~~~
Data-oriented design
~~~~~~~~~~~~~~~~~~~~
Object-oriented programming is a very useful abstraction, built on top of the more fundamental (and closer-to-hardware)
notion of data structures vs. functions that operate on them. An object is a collection of data structures and functions
that correspond to one semantic entity, and thereby have stronger dependencies among them than with the rest of the
application. The reason we are not using this here is because the dependency structure is such that the natural entity
is the entire physics simulator. Instead of objects, we have a small number of data structures and a large number of
functions that operate on them.
MuJoCo uses a data-oriented architecture rather than an object-oriented one. The natural semantic entity here is the
entire physics simulator, rather than individual objects with private state and methods. Instead of objects, we have a
small number of data structures and a large number of functions that operate on them.
We still use a type of grouping, but it is different from the object-oriented approach. We separate the model
(``mjModel``) from the data (``mjData``). These are both data structures. The model contains everything needed to
describe the constant properties of the physical system being modeled, while the data contains the time-varying state
and the reusable intermediate results of internal computations. All top-level functions expect pointers to ``mjModel``
and ``mjData`` as arguments. In this way we avoid global variables which pollute the workspace and interfere with
multi-threading, but we do so in a way that is different from how object-oriented programming achieves the same effect.
We separate the model (``mjModel``) from the data (``mjData``). These are both data structures. The model contains
everything needed to describe the constant properties of the physical system being modeled, while the data contains the
time-varying state and the reusable intermediate results of internal computations. All top-level functions expect
pointers to ``mjModel`` and ``mjData`` as arguments. This design avoids global variables and naturally supports
multi-threading: each thread simply operates on its own ``mjData`` instance.
.. _Soft:
@@ -831,12 +852,12 @@ two elements of ``solimp``) as well as the global ``mjModel.opt.impratio`` setti
adjustment often requires smaller time steps to keep the simulation stable, because they make the nonlinear dynamics
more difficult to integrate numerically. Slip is also reduced by the Newton solver which is more accurate in general.
For situations where it is desirable to suppress slip completely, there is a second ``noslip`` solver which runs after
the main solver. It updates the contact forces in friction dimensions by disregarding constraint softness. When this
option is used however, MuJoCo is no longer solving the convex optimization problem it was designed to solve, and the
simulation may become less robust. Thus using the Newton solver with elliptic friction cones and large value of
``impratio`` is the recommended way of reducing slip. For more detailed recommendations, see
:ref:`preventing slip<CSlippage>` in the Modeling chapter.
For situations where it is desirable to suppress slip completely, there is a :ref:`NoSlip <soAlgorithms>`
post-processing solver which runs after the main solver. It updates the contact forces in friction dimensions by
disregarding constraint softness. When this option is used however, MuJoCo is no longer solving the convex optimization
problem it was designed to solve, and the simulation may become less robust. Thus using the Newton solver with elliptic
friction cones and large value of ``impratio`` is the recommended way of reducing slip. For more detailed
recommendations, see :ref:`preventing slip<CSlippage>` in the Modeling chapter.
.. _TypeNameId:
@@ -986,7 +1007,8 @@ necessarily unique) set of joint coordinates for which the forward kinematics pl
The situation is different for floating bodies, i.e., bodies that are connected to the world with a free joint. The
positions and orientations as well as the linear and angular velocities of such bodies are explicitly represented in
``mjData.qpos`` and ``mjData.qvel``, and can therefore be manipulated directly.
``mjData.qpos`` and ``mjData.qvel``, and can therefore be manipulated directly. For structured state manipulation and
serialization, see :ref:`State and control <siStateControl>` in the Simulation chapter.
The semantics of free joints are as follows. The position data is 7 numbers (3D position followed
by unit quaternion) while the velocity data is 6 numbers (3D linear velocity followed by 3D angular velocity).
+3 -3
View File
@@ -3,7 +3,7 @@
Extensions
----------
This section describes MuJoCo's mechanisms for user-authored extensions. At present, extensibility is provided by
This section describes MuJoCo's mechanisms for user-authored extensions. At present, extensibility is provided
via :ref:`engine plugins<exPlugin>` and :ref:`resource providers<exProvider>`.
.. _exPlugin:
@@ -11,7 +11,7 @@ via :ref:`engine plugins<exPlugin>` and :ref:`resource providers<exProvider>`.
Engine plugins
~~~~~~~~~~~~~~
Engine plugins, introduced in MuJoCo 2.3.0, allow user-defined logic to be inserted into various parts of MuJoCo's
Engine plugins allow user-defined logic to be inserted into various parts of MuJoCo's
computational pipeline. For example, custom sensor and actuator types can be implemented as plugins. Plugin features are
referenced in the XML content of an MJCF model, allowing MJCF to remain an abstract physical description of
a system even if the simulation requirements extend beyond MuJoCo's built-in capabilities.
@@ -462,6 +462,6 @@ Now we can write assets as strings in our MJCF files:
<asset>
<texture name="grid" file="grid.png" type="2d"/>
<mesh content-type="model/obj" file="data:model/obj;base65,I215IG9iamVjdA0KdiAxIDAgMA0KdiAwIDEgMA0KdiAwIDAgMQ=="/>
<mesh content-type="model/obj" file="data:model/obj;base64,I215IG9iamVjdA0KdiAxIDAgMA0KdiAwIDEgMA0KdiAwIDAgMQ=="/>
...
</asset>
+8 -13
View File
@@ -31,9 +31,9 @@ OpenGL renderer
state-of-the-art rendering engines (and can be replaced with such an engine if desired) but nevertheless it provides
efficient and informative 3D rendering.
Thread
The Threading framework (new in MuJoCo 3.0) is written in C++ and exposed in C. It provides a ThreadPool interface
to process Tasks asynchronously. To enable use in MuJoCo, create a ThreadPool and assign it to the thread_pool field
in mjData.
The threading framework is written in C++ and exposed in C. It provides a :ref:`mjThreadPool<mjThreadPool>` interface
to process tasks asynchronously. To enable use in MuJoCo, create a thread pool and assign it to the
``mjData.threadpool`` field.
UI framework
The UI framework is written in C. UI elements are rendered in OpenGL. It has its own event
mechanism and abstract hooks for keyboard and mouse input. The code samples use it with GLFW, but it can also be used
@@ -80,7 +80,7 @@ working development environment. We provide a cross-platform `CMake
applications independently of the MuJoCo library itself.
On macOS, the DMG disk image contains ``MuJoCo.app``, which you can double-click to launch the ``simulate`` GUI. You can
also drag ``MuJoCo.app`` into the ``/Application`` on your system, as you would to install any other app. As well as the
also drag ``MuJoCo.app`` into the ``/Applications`` on your system, as you would to install any other app. As well as the
``MuJoCo.app`` `Application Bundle <https://developer.apple.com/go/?id=bundle-
structure>`__, the DMG includes the ``mujoco.framework`` subdirectory containing the MuJoCo dynamic library and all of
its public headers. If you are using Xcode, you can import it as a framework dependency on your project. (This also
@@ -94,7 +94,7 @@ Building from source
To build MuJoCo from source, you will need CMake and a working C++17 compiler installed. The steps are:
#. Clone the ``mujoco`` repository: ``git clone https://github.com/deepmind/mujoco.git``
#. Clone the ``mujoco`` repository: ``git clone https://github.com/google-deepmind/mujoco.git``
#. Create a new build directory and ``cd`` into it.
#. Run :shell:`cmake $PATH_TO_CLONED_REPO` to configure the build.
#. Run ``cmake --build .`` to build.
@@ -109,7 +109,7 @@ section of the documentation.
Additionally, the CMake setup also implements an installation phase which will copy and organize the output files to a
target directory.
5. Select the directory: :shell:`cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=<my_install_dir>`
#. Select the directory: :shell:`cmake $PATH_TO_CLONED_REPO -DCMAKE_INSTALL_PREFIX=<my_install_dir>`
#. After building, install with ``cmake --install .``
#. If desired, proceed to building the Python bindings - see
:ref:`PyBuild`.
@@ -132,7 +132,7 @@ Building the docs
If you wish to build the documentation locally, for example to test pull-requests that improve it, do:
1. Clone the ``mujoco`` repository: ``git clone https://github.com/deepmind/mujoco.git``
1. Clone the ``mujoco`` repository: ``git clone https://github.com/google-deepmind/mujoco.git``
2. Go to the ``doc/`` directory: ``cd mujoco/doc``
3. Install the dependencies: ``pip install -r requirements.txt``
|br| Note that the MuJoCo Warp API documentation is autogenerated and requires additional dependencies.
@@ -238,7 +238,7 @@ to which the symbol belongs. First we list the prefixes corresponding to type de
``mjui``
Data structure related to UI framework, for example :ref:`mjuiSection`.
``mjs``
Data structure related :doc:`procedural model editing <modeledit>`, for example :ref:`mjsJoint`.
Data structure related to :doc:`procedural model editing <modeledit>`, for example :ref:`mjsJoint`.
Next we list the prefixes corresponding to function definitions. Note that function prefixes always end with underscore.
@@ -280,11 +280,6 @@ thread. On Windows and macOS, there is a canonical OpenGL library provided by th
currently supports GLX for rendering to an X11 window, OSMesa for headless software rendering, and EGL for hardware
accelerated headless rendering.
Before version 2.1.4, MuJoCo used GLEW rather than GLAD to manage OpenGL symbols, which required linking against
different GLEW libraries at build time depending on the GL implementation used. In order to avoid having manage OpenGL
dependency when no rendering was required, "nogl" builds of the library was made available. Since OpenGL symbols are
now lazily resolved at runtime after the switch to GLAD, the "nogl" libraries are no longer provided.
.. toctree::
:hidden:
+12 -18
View File
@@ -1,14 +1,8 @@
Model Editing
-------------
.. admonition:: New API
:class: note
The API described below is new but feature complete. It is recommended for general use, but latent bugs are still
possible. Please report any issues on GitHub.
As of MuJoCo 3.2.0, it is possible to create and modify models using the :ref:`mjSpec` struct and related API.
This datastructure is in one-to-one correspondence with MJCF and indeed, MuJoCo's own XML parsers (both MJCF and URDF)
It is possible to create and modify models using the :ref:`mjSpec` struct and related API.
This data structure is in one-to-one correspondence with MJCF and indeed, MuJoCo's own XML parsers (both MJCF and URDF)
use this API when loading a model.
@@ -17,16 +11,16 @@ use this API when loading a model.
Overview
~~~~~~~~
The new API augments the traditional workflow of creating and editing models using XML files, breaking up the *parse* and
The API augments the traditional workflow of creating and editing models using XML files, breaking up the *parse* and
*compile* steps. As summarized in the :ref:`Overview chapter<Instance>`, the traditional workflow is:
1. Create an XML model description file (MJCF or URDF) and associated assets. |br|
2. Call :ref:`mj_loadXML`, obtain an :ref:`mjModel` instance.
The new workflow using :ref:`mjSpec` is:
The workflow using :ref:`mjSpec` is:
1. Create an empty :ref:`mjSpec` using :ref:`mj_makeSpec` or parse an existing XML file using :ref:`mj_parseXML`.
2. Programmatically edit the :ref:`mjSpec` datastructure by adding, modifying and removing elements.
2. Programmatically edit the :ref:`mjSpec` data structure by adding, modifying, and removing elements.
3. Compile the :ref:`mjSpec` to an :ref:`mjModel` instance using :ref:`mj_compile`.
After compilation, the :ref:`mjSpec` remains editable, so steps 2 and 3 are interchangeable.
@@ -40,9 +34,9 @@ Usage
Here we describe the C API for procedural model editing, but it is also exposed in the :ref:`Python
bindings<PyModelEdit>`. Advanced users can refer to `user_api_test.cc
<https://github.com/google-deepmind/mujoco/blob/main/test/user/user_api_test.cc>`__ and the MJCF parser in
`xml_native_reader.cc <https://github.com/google-deepmind/mujoco/blob/main/src/xml/xml_native_reader.cc>`__ for more
usage examples. After creating a new :ref:`mjSpec` or parsing an existing XML file to an :ref:`mjSpec`, procedural
editing corresponds to setting attributes. For example, in order to change the timestep, one can do:
`xml_native_reader.cc <https://github.com/google-deepmind/mujoco/blob/main/src/xml/xml_native_reader.cc>`__ for
more usage examples. After creating a new :ref:`mjSpec` or parsing an existing XML file to an :ref:`mjSpec`,
procedural editing corresponds to setting attributes. For example, in order to change the timestep, one can do:
.. code-block:: C
@@ -56,7 +50,7 @@ In C one uses the provided :ref:`getters<AttributeGetters>` and :ref:`setters<At
.. code-block:: C
mjs_setString(model->modelname, "my_model");
mjs_setString(spec->modelname, "my_model");
In C++, one can use vectors and strings directly:
@@ -76,7 +70,7 @@ Loading a spec from XML can be done as follows:
Model elements
^^^^^^^^^^^^^^
Model elements corresponding to MJCF are exposed to the user as C structs with the ``mjs`` prefix, the definitions are
Model elements corresponding to MJCF are exposed to the user as C structs with the ``mjs`` prefix. The definitions are
listed under the :ref:`Model Editing<tySpecStructure>` section of the struct reference. For example, an MJCF
:ref:`geom<body-geom>` corresponds to an :ref:`mjsGeom`.
@@ -120,7 +114,7 @@ Attachment
^^^^^^^^^^
This framework introduces a powerful new feature: attaching and deleting model subtrees. This feature is already used to
power the :ref:`attach<body-attach>` an :ref:`replicate<replicate>` meta-elements in MJCF. Attachment allows the user to
power the :ref:`attach<body-attach>` and :ref:`replicate<replicate>` meta-elements in MJCF. Attachment allows the user to
move or copy a subtree from one model into another, while also copying or moving related referenced assets and
referencing elements from outside the kinematic tree (e.g., actuators and sensors). Similarly, deleting a subtree will
remove all associated elements from the model. The default behavior ("shallow copy") is to move the child into the
@@ -199,7 +193,7 @@ already initialized elements.
.. admonition:: Possible future change
:class: note
The behaviour described above, where defaults are only applied at initialization, is a remnant of the old, XML-only
The behavior described above, where defaults are only applied at initialization, is a remnant of the old, XML-only
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.
+13 -13
View File
@@ -13,7 +13,7 @@ initialized by the corresponding API functions. These are very elaborate data st
structures, preallocated data arrays for all intermediate results, as well as an :ref:`internal stack <siStack>`. Our
strategy is to allocate all necessary heap memory at the beginning of the simulation, and free it after the simulation
is done, so that we never have to call the C memory allocation and deallocation functions during the simulation. This is
done for speed, avoidance of memory fragmentation, future GPU portability, and ease of managing the state of the entire
done for speed, avoidance of memory fragmentation, GPU portability, and ease of managing the state of the entire
simulator during a reset. It also means however that the maximal variable-memory allocation given by the :at:`memory`
attribute in the :ref:`size <size>` MJCF element, which affects the allocation of :ref:`mjData`, must be set to a
sufficiently large value. If this maximal size is exceeded during simulation, it is not increased dynamically, but
@@ -331,6 +331,8 @@ Auxiliary Controls: ``qfrc_applied`` and ``xfrc_applied``
| Note that the effects of ``qfrc_applied`` and ``xfrc_applied`` can be recreated by appropriate actuator
definitions.
.. _siMocap:
MoCap poses: ``mocap_pos`` and ``mocap_quat``
``mjData.mocap_pos`` and ``mjData.mocap_quat`` are special optional kinematic states :ref:`described here<CMocap>`,
which allow the user to set the positions and orientations of static bodies in real-time, for example when streaming
@@ -560,14 +562,12 @@ external force computed by inverse dynamics.
Multi-threading
~~~~~~~~~~~~~~~
When MuJoCo is used for simulation as explained in the :ref:`simulation loop <siSimulation>` section, it runs in a
single thread. We have experimented with multi-threading parts of the simulation pipeline that are computationally
expensive and amenable to parallel processing, and have concluded that the speedup is not worth using up the extra
processor cores. This is because MuJoCo is already fast compared to the overhead of launching and synchronizing
multiple threads within the same time step. If users start working with large simulations involving many floating
bodies, we may eventually implement within-step multi-threading, but for now this use case is not common.
MuJoCo has experimental support for within-step multi-threading. When a :ref:`mjThreadPool` is assigned to
``mjData.threadpool``, parts of the simulation pipeline — such as collision detection and constraint solving across
:ref:`islands<siSleep>` — can be distributed across worker threads. Note that within-step threading currently has
significant memory overhead and is still a work in progress.
Rather than speed up a single simulation, we prefer to use multi-threading to speed up sampling operations that are
The more common and well-supported use of multi-threading is to speed up sampling operations that are
common in more advanced applications. Simulation is inherently serial over time (the output of one mj_step is the
input to the next), while in sampling many calls to either forward or inverse dynamics can be executed in parallel
since there are no dependencies among them, except perhaps for a common initial state.
@@ -784,7 +784,7 @@ difference between row-major and column-major formats.
When possible, MuJoCo exploits sparsity. This can make all the difference between O(N) and O(N^3) scaling. The inertia
matrix ``mjData.qM`` and its LTDL factorization ``mjData.qLD`` are always represented as sparse. ``qM`` uses a custom
indexing format designed for matrices that correspond to tree topology, while ``qLD`` uses the standard CSR format.
``qM`` will be migrated to CSR in and upcoming change. The functions :ref:`mj_factorM`, :ref:`mj_solveM`,
``qM`` will be migrated to CSR in an upcoming change. The functions :ref:`mj_factorM`, :ref:`mj_solveM`,
:ref:`mj_solveM2` and :ref:`mj_mulM` are used for sparse factorization, substitution and matrix-vector multiplication.
The user can also convert these matrices to dense format with the function :ref:`mj_fullM` although MuJoCo never does
that internally.
@@ -994,7 +994,7 @@ in MJCF which are sufficient for most models, and allow the user to adjust them
the simulator runs out of dynamic memory at runtime it will trigger an error. When such errors are triggered, the user
should increase :at:`memory`. The field ``mjData.maxuse_arena`` is designed to help with this adjustment. It keeps track
of the maximum arena use since the last reset. So one strategy is to make very large allocation, then monitor
``mjData.maxuse_memory`` statistics during typical simulations, and use it to reduce the allocation.
``mjData.maxuse_arena`` statistics during typical simulations, and use it to reduce the allocation.
The kinetic and potential energy are computed and stored in ``mjData.energy`` when the corresponding flag in
``mjModel.opt.enableflags`` is set. This can be used as another diagnostic. In general, simulation instability is
@@ -1061,7 +1061,7 @@ non-convex mesh collisions, or to replace some of the convex collision functions
beyond the ones provided by MuJoCo. The global 2D array :ref:`mjCOLLISIONFUNC` contains the collision function pointer
for each pair of geom types (in the upper-left triangle). To replace them, simply set these pointers to your
functions. The collision function type is :ref:`mjfCollision`. When user collision functions detect contacts, they
should construct an mjvContact structure for each contact and then call the function :ref:`mj_addContact` to add that
should construct an :ref:`mjContact` structure for each contact and then call the function :ref:`mj_addContact` to add that
contact to ``mjData.contact``. The reference documentation of mj_addContact explains which fields of mjContact must be
filled in by custom collision functions. Note that the functions we are talking about here correspond to near-phase
collisions, and are called only after the list of candidate geom pairs has been constructed by the internal
@@ -1176,7 +1176,7 @@ which are initialized asleep. These can be placed in mid-air or in deep collisio
Notes
^^^^^
.. admonition:: New feature
.. admonition:: Subject to change
:class: warning
Sleeping is a new feature (Nov 2025) that is subject to change and may have latent bugs.
@@ -1270,7 +1270,7 @@ Notes
The RK4 integrator is not currently supported, due to the subtleties of waking inside the sub-steps.
**Latent bugs**
Sleeping is a new feature (Nov 2025) and may have latent bugs. These bugs may generally come in two varieties:
Sleeping may have latent bugs. These bugs may generally come in two varieties:
- Quantities which could be skipped are instead recomputed. The only observable effect of such a bug would be that
the simulation is slower than it could be. This type of bug can only be diagnosed with detailed profiling.
+39 -54
View File
@@ -7,23 +7,23 @@ MuJoCo has a native 3D visualizer. Its use is illustrated in the :ref:`simulate.
the simpler :ref:`basic.cc <saBasic>` code sample. While it is not a full-featured rendering engine, it is a
convenient, efficient and reasonably good-looking visualizer that facilitates research and development. It renders not
only the simulation state but also decorative elements such as contact points and forces, equivalent inertia boxes,
convex hulls, kinematic trees, constraint violations, spatial frames and text labels; these can provide insight into
convex hulls, kinematic trees, constraint violations, spatial frames, and text labels; these can provide insight into
the physics simulation and help fine-tune the model.
The visualizer is tightly integrated with the simulator and supports both onscreen and offscreen rendering, as
illustrated in the :ref:`record.cc <saRecord>` code sample. This makes it suitable for synthetic computer vision and
machine learning applications, especially in cloud environments. VR integration is also available as of MuJoCo version
1.40, facilitating applications that utilize new head-mounted displays such as Oculus Rift and HTC Vive.
machine learning applications, especially in cloud environments. VR integration is also available, facilitating
applications that utilize head-mounted displays.
Visualization in MuJoCo is a two-stage process:
Abstract visualization and interaction
This stage populates the :ref:`mjvScene` data structure with a list of geometric objects, lights, cameras and
This stage populates the :ref:`mjvScene` data structure with a list of geometric objects, lights, cameras, and
everything else needed to produce a 3D rendering. It also provides abstract keyboard and mouse hooks for user
interaction. The relevant data structure and function names have the prefix ``mjv``.
OpenGL rendering
This stage takes the mjvScene data structure populated in the abstract visualization stage, and renders it. It also
provides basic 2d drawing and framebuffer access, so that most applications would not need to call OpenGL directly.
provides basic 2D drawing and framebuffer access, so that most applications would not need to call OpenGL directly.
The relevant data structure and function names have the prefix ``mjr``.
There are several reasons for this separation. First, the two stages are conceptually different and separating them is
@@ -105,8 +105,8 @@ Abstract visualization and interaction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This stage populates the :ref:`mjvScene` data structure with a list of geometric objects,
lights, cameras and everything else needed to produce a 3D rendering. It also provides abstract keyboard and mouse hooks
for user interaction.
lights, cameras, and everything else needed to produce a 3D rendering. It also provides abstract keyboard and mouse
hooks for user interaction.
.. _viCamera:
@@ -125,14 +125,14 @@ are defined by the enum mjtCamera:
mjCAMERA_FREE
This is the most commonly used abstract camera. It can be freely moved with the mouse. It has a lookat point,
distance to the lookat point, azimuth and elevation; twist around the line of sight is not allowed. The function
:ref:`mjv_moveCamera` is a mouse hook for controlling all these camera properties interactively with the mouse. When
:ref:`simulate.cc <saSimulate>` first starts, it uses the free camera.
distance to the lookat point, azimuth, and elevation; twist around the line of sight is not allowed. The function
:ref:`mjv_moveCamera` is a mouse hook for controlling all these camera properties interactively with the mouse.
When :ref:`simulate.cc <saSimulate>` first starts, it uses the free camera.
mjCAMERA_TRACKING
This is similar to the free camera, except the lookat point is no longer a free parameter but instead is coupled to
the MuJoCo body whose id is given by mjvCamera.trackbodyid. At each update, the lookat point is set to the center of
mass of the kinematic subtree rooted at the specified body. There is also some filtering which produces smooth camera
motion. The distance, azimuth and elevation are controlled by the user and are not modified automatically. This is
motion. The distance, azimuth, and elevation are controlled by the user and are not modified automatically. This is
useful for tracking a body as it moves around, without turning the camera. To switch from the free to the tracking
camera in :ref:`simulate.cc <saSimulate>`, hold Ctrl and right-double-click on the body of interest. Press Esc to go
back to the free camera.
@@ -171,7 +171,7 @@ because it needs information about the camera and viewport.
The function mjv_select returns the index of the geom at the specified window coordinates, or -1 if there is no geom
at those coordinates. The 3D position is also returned. See the code sample :ref:`simulate.cc <saSimulate>` for an
example of how to use this function. Internally, mjv_select calls the engine-level function :ref:`mj_ray` which in turn
calls the per-geom functions :ref:`mj_rayMesh`, :ref:`mj_rayHfield` and :ref:`mju_rayGeom`. The user can implement
calls the per-geom functions :ref:`mj_rayMesh`, :ref:`mj_rayHfield`, and :ref:`mju_rayGeom`. The user can implement
custom selection mechanisms by calling these functions directly. In a VR application for example, it would make sense to
use the hand-held controller as a "laser pointer" that can select objects.
@@ -184,9 +184,8 @@ Interactive perturbations have proven very useful in exploring the model dynamic
systems. The user is free to implement any perturbation mechanism of their choice by setting ``mjData.qfrc_applied`` or
``mjData.xfrc_applied`` to suitable forces (in generalized and Cartesian coordinates respectively).
Prior to MuJoCo version 1.40, user code had to maintain a collection of objects in order to implement perturbations.
All these objects are now grouped into the data structure :ref:`mjvPerturb`. Its use is illustrated in
:ref:`simulate.cc <saSimulate>`.
All objects needed to implement interactive perturbations are grouped into the data structure :ref:`mjvPerturb`.
Its use is illustrated in :ref:`simulate.cc <saSimulate>`.
The idea is to select a MuJoCo body of interest, and provide a reference pose (i.e., a 3D position and quaternion
orientation) for that body. These are stored in mjPerturb.refpos/quat. The function :ref:`mjv_movePerturb` is a mouse
hook for controlling the reference pose with the mouse. The function :ref:`mjv_initPerturb` is used to set the
@@ -275,40 +274,26 @@ Since we have introduced two spaces, namely model space and room space, we need
which spatial quantities are defined with respect to which spatial frame. Everything accessible by the simulator lives
in the model space. The room space is only accessible by the visualizer. The only quantities defined in room space are
the mjvGLCamera parameters. The functions :ref:`mjv_room2model`, :ref:`mjv_model2room`, :ref:`mjv_cameraInModel`,
:ref:`mjv_cameraInRoom` perform the necessary transformations, and are needed for VR applications.
and :ref:`mjv_cameraInRoom` perform the necessary transformations, and are needed for VR applications.
We now outline the procedure for hooking up head tracking to MuJoCo's visualizer in a VR application. A code sample
illustrating this will soon be posted. We assume that a tracking device provides in real-time the positions of the two
eyes (usually generated by tracking the position and orientation of the head and assuming a user-specific ipd), as
well as the forward and up camera directions. We copy these data directly into the two mjvGLCameras, which are in
mjvScene.camera[n] where n=0 is the left eye and n=1 is the right eye. Note that the forward direction is normal to
the projection surface, and not necessarily aligned with the gaze direction; indeed the gaze direction is unknown
(unless we also have an eye-tracking device) and does not affect the rendering.
While MuJoCo does not provide a built-in VR application, it provides data structures and functions to support VR
integration in user code.
We must also set the mjvGLCamera frustum. How this is done depends on the nature of the VR system. For head-mounted
displays such as the Oculus Rift and HTC Vive, the projection surface moves with the head, and so the frustum is fixed
and provided by the SDK. In this case we simply copy it into mjvGLCamera, averaging the left and right edges to
compute the frustum_center parameter. Alternatively, the projection surface can be a monitor which is stationary in
the room (which is the case in the zSpace system). For such systems we must compute the frustum at each frame, by
taking into account the spatial relations between the monitor and the eyes/cameras. This assumes that the monitor is
also tracked. The natural approach here is to define the monitor as the center of the room coordinate frame, and track
the head relative to it. In the zSpace system this is done by embedding the motion capture cameras in the monitor
itself.
**Head tracking and cameras**
In a typical VR application, a tracking device provides the positions and orientations of the user's eyes in
real-time. These data can be copied directly into the two ``mjvGLCamera`` structures in ``mjvScene.camera[n]``
(where ``n=0`` is the left eye and ``n=1`` is the right eye). The ``mjvGLCamera`` frustum parameters must also be
set according to the physical characteristics of the tracked display.
Apart from tracking the head and using the correct perspective projection, VR applications typically involve hand-held
spatial controllers that must be mapped to the motion of simulated objects or otherwise interact with the simulation.
The pose of these controllers is recorded by the motion capture system in room space. The transformation functions we
provide (mjv_room2model in particular) can be used to map to model space. Once we have the pose of the controller in
model space, we can use a MuJoCo mocap body (defined in the model) to insert the controller in the simulation. This is
precisely why mocap bodies were introduced in MuJoCo. Such bodies are treated as fixed from the viewpoint of physics,
yet the user is expected to move them programmatically at each simulation step. They can interact with the simulation
through contacts, or better yet, through soft equality constraints to regular bodies which in turn make contacts. The
latter approach is illustrated in the MPL models available on the Forum. It provides effective dynamic filtering and
avoids contacts involving bodies that behave as if they are infinitely heavy (which is what a fixed body is). Note
that the time-varying positions and orientations of the mocap bodies are stored in ``mjData.mocap_pos/quat``, as opposed
to storing them in mjModel. This is because mjModel is supposed to remain constant. The fixed mocap body pose stored
in mjModel is only used at initialization and reset, when user code has not yet had a chance to update
mjData.mocap_pos/quat.
**Controllers and mocap bodies**
Hand-held spatial controllers are also tracked in room space. The function :ref:`mjv_room2model` can map these
poses to model space. Once in model space, the controller poses can be used to update the position of MuJoCo
*mocap bodies*. Mocap bodies are treated as fixed from the viewpoint of physics, yet the user is expected to move
them programmatically at each simulation step. They can interact with the simulation through contacts, or better
yet, through soft equality constraints to regular bodies which in turn make contacts. This provides effective
dynamic filtering and avoids contacts involving bodies that behave as if they are infinitely heavy. The
time-varying positions and orientations of the mocap bodies are stored in ``mjData.mocap_pos`` and
``mjData.mocap_quat``.
.. _Rendering:
@@ -316,14 +301,14 @@ OpenGL Rendering
~~~~~~~~~~~~~~~~
This stage takes the mjvScene data structure populated in the abstract visualization stage, and renders it. It also
provides basic 2d drawing and framebuffer access, so that most applications would not need to call OpenGL directly.
provides basic 2D drawing and framebuffer access, so that most applications would not need to call OpenGL directly.
.. _reContext:
Context and GPU resources
'''''''''''''''''''''''''
The first step in the rendering process is create the model-specific GPU context :ref:`mjrContext`. This is done by
The first step in the rendering process is to create the model-specific GPU context :ref:`mjrContext`. This is done by
first clearing the data structure with the function :ref:`mjr_defaultContext`, and then calling the function
:ref:`mjr_makeContext`. This was already illustrated earlier; the relevant code is:
@@ -371,7 +356,7 @@ mjrContext.currentBuffer which changes whenever the active buffer changes. Some
because the user can upload modified resources with the functions :ref:`mjr_uploadTexture`, :ref:`mjr_uploadMesh`,
:ref:`mjr_uploadHField`. This can be used to achieve dynamic effects such as inserting a video feed into the
rendering, or modulating a terrain map. Such modifications affect the resources residing on the GPU, but their OpenGL
names are reused, thus the change is not actually visible in mjrContext.
names are reused; thus, the change is not actually visible in mjrContext.
The user should **never** make changes to mjrContext directly. MuJoCo's renderer assumes that only it can manage
mjrContext. In fact this kind of object would normally be opaque and its internal structure would not be exposed to
@@ -434,7 +419,7 @@ be obtained with the function :ref:`mjr_maxViewport`. Note that while the offscr
window buffer size changes whenever the user resizes or maximizes the window. Therefore user code should not assume
fixed viewport size. In the code sample :ref:`simulate.cc <saSimulate>` we use a callback which is triggered whenever
the window size changes, while in :ref:`basic.cc <saBasic>` we simply check the window size every time we render. On
certain scaled displays (only on OSX it seems) the window size and framebuffer size can be different. So if you are
certain scaled displays (notably on MacOS) the window size and framebuffer size can be different. So if you are
getting the size with GLFW functions, use glfwGetFramebufferSize rather than glfwGetWindowSize. On the other hand,
mouse coordinates are returned by the operating system in window rather than framebuffer units; thus the mouse
interaction functions discussed earlier should use glfwGetWindowSize to obtain the window height needed to normalize
@@ -468,10 +453,10 @@ mjSTEREO_SIDEBYSIDE
side. In principle users can cross their eyes and see stereo on a regular monitor, but the goal here is to show it in
a stereoscopic device. Most head-mounted displays support this stereo mode.
In addition to the main mjr_render function, we provide several functions for "decorating" the image. These are 2d
rendering functions and include :ref:`mjr_overlay`, :ref:`mjr_text`, :ref:`mjr_rectangle`, :ref:`mjr_figure`. The user
can draw additional decorations with their own OpenGL code. This should be done after mjr_render, because mjr_render
clears the viewport.
In addition to the main mjr_render function, we provide several functions for "decorating" the image. These are 2D
rendering functions and include :ref:`mjr_overlay`, :ref:`mjr_text`, :ref:`mjr_rectangle`, and :ref:`mjr_figure`. The
user can draw additional decorations with their own OpenGL code. This should be done after mjr_render, because
mjr_render clears the viewport.
We also provide the functions :ref:`mjr_finish` and :ref:`mjr_getError` for explicit synchronization with the GPU and
for OpenGL error checking. They simply call glFinish and glGetError internally. This together with the basic 2d
+3 -4
View File
@@ -269,7 +269,7 @@ initialized with ``mjv_makeScene(model, [the new mjvScene instance], 10)`` in C.
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.
The ``mujoco.MjModel`` class does not a have Python constructor. Instead, we provide three static factory functions
The ``mujoco.MjModel`` class does not have a Python constructor. Instead, we provide three static factory functions
that create a new :ref:`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
functions accept the path to either an XML or MJB model file. All three functions optionally accept a Python
@@ -797,7 +797,7 @@ The ``mujoco`` package contains two sub-modules: ``mujoco.rollout`` and ``mujoco
rollout
-------
``mujoco.rollout`` and ``mujoco.rollout.Rollout`` shows how to add additional C/C++ functionality, exposed as a Python
``mujoco.rollout`` and ``mujoco.rollout.Rollout`` show how to add additional C/C++ functionality, exposed as a Python
module via pybind11. It is implemented in `rollout.cc
<https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/rollout.cc>`__ and wrapped in `rollout.py
<https://github.com/google-deepmind/mujoco/blob/main/python/mujoco/rollout.py>`__. The module addresses a common
@@ -922,8 +922,7 @@ custom cameras and lights. The constructor arguments of a ``USDExporter`` instan
- ``model``: An MjModel instance. The USD exporter reads relevant information from the model including details about
cameras, lights, textures, and object geometries.
- ``max_geom``: Maximum number of geoms in a scene, required when instantiating the internal .
`mjvScene <https://mujoco.readthedocs.io/en/stable/APIreference/APItypes.html#mjvscene>`__.
- ``max_geom``: Maximum number of geoms in a scene, required when instantiating the internal :ref:`mjvScene`.
- ``output_directory``: Name of the directory under which the exported USD file and all relevant
assets are stored. When saving a scene/trajectory as a USD file, the exporter creates the following directory