Add sleeping documentation
https://youtu.be/vct493lGQ8Q PiperOrigin-RevId: 829390353 Change-Id: I92f85a03be0bb585d2d8e29de1ed1a2e848f247f
This commit is contained in:
committed by
Copybara-Service
parent
769f37b653
commit
8734cab366
+36
-3
@@ -463,7 +463,7 @@ adjust it properly through the XML.
|
|||||||
.. _option-sleep_tolerance:
|
.. _option-sleep_tolerance:
|
||||||
|
|
||||||
:at:`sleep_tolerance`: :at-val:`real, "1e-4"`
|
:at:`sleep_tolerance`: :at-val:`real, "1e-4"`
|
||||||
Velocity tolerance below which sleeping is possible. Feature under development, documentation pending.
|
Velocity tolerance below which :ref:`sleeping<Sleeping>` is allowed.
|
||||||
|
|
||||||
.. _option-sdf_iterations:
|
.. _option-sdf_iterations:
|
||||||
|
|
||||||
@@ -674,7 +674,16 @@ from its default.
|
|||||||
.. _option-flag-sleep:
|
.. _option-flag-sleep:
|
||||||
|
|
||||||
:at:`sleep`: :at-val:`[disable, enable], "disable"`
|
:at:`sleep`: :at-val:`[disable, enable], "disable"`
|
||||||
This flag enables sleeping. Feature under development, documentation pending.
|
This flag enables :ref:`sleeping<Sleeping>`. Disabling this flag when some trees are sleeping will wake them.
|
||||||
|
|
||||||
|
.. admonition:: flag value at initialization time
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
Unlike any other :ref:`flag<option-flag>`, the :at:`sleep` flag has an effect during :ref:`mjData`
|
||||||
|
**initialization** (:ref:`mj_makeData` or :ref:`mj_resetData`). First, it must be set at initialization time in
|
||||||
|
order for the :ref:`sleep-init<body-sleep>` policy to take effect. Second, it must be set in order for static
|
||||||
|
quantities to be computed. See :ref:`implementation notes<siSleep>` for more details.
|
||||||
|
|
||||||
|
|
||||||
.. _compiler:
|
.. _compiler:
|
||||||
|
|
||||||
@@ -2072,7 +2081,31 @@ defined. Its body name is automatically defined as "world".
|
|||||||
.. _body-sleep:
|
.. _body-sleep:
|
||||||
|
|
||||||
:at:`sleep`: :at-val:`[auto, never, allowed, init], "auto"`
|
:at:`sleep`: :at-val:`[auto, never, allowed, init], "auto"`
|
||||||
Sleep policy for the tree under this body. Feature under development, documentation pending.
|
:ref:`Sleep<Sleeping>` policy for the tree under this body. This attribute is only supported by moving bodies which
|
||||||
|
are the root of a kinematic :ref:`tree<ElemTree>`. For the default :at-val:`auto`, the compiler will set the sleep
|
||||||
|
policy as follows:
|
||||||
|
|
||||||
|
- A tree which is affected by actuators is not allowed to sleep (overridable).
|
||||||
|
- Trees which are connected by tendons which have non-zero stiffness and damping are not allowed to sleep
|
||||||
|
(overridable).
|
||||||
|
- Trees which are connected by tendons which connect more than two trees are not allowed to sleep (not overridable).
|
||||||
|
- :ref:`flexes<ElemFlex>` are not allowed to sleep (not overridable).
|
||||||
|
- All other trees are allowed to sleep (overridable).
|
||||||
|
|
||||||
|
The policies :at-val:`never` and :at-val:`allowed` constitute user overrides of the automatic compiler policy.
|
||||||
|
|
||||||
|
The :at-val:`init` sleep policy can only be specified by the user and means "initialize this tree as asleep". This
|
||||||
|
policy is implemented in :ref:`mj_resetData` and :ref:`mj_makeData` and only applies to the default configuration. If
|
||||||
|
a :ref:`keyframe<keyframe>` changes the configuration of (or assigns nonzero velocity to) a sleeping tree, it will be
|
||||||
|
woken up. This policy is useful for very large models where waiting for the automatic sleeping mechanism to kick in
|
||||||
|
can be expensive. Trees initialized as sleeping can be placed in unstable configurations like deep penetration or in
|
||||||
|
mid-air, but will only move when woken up. Also note that this policy can fail. For example if a tree marked as
|
||||||
|
sleep="init" is in contact with a tree not marked as such (i.e., they are in the same :ref:`island<soIsland>`) then
|
||||||
|
it is impossible to put the tree to sleep; such `models
|
||||||
|
<https://github.com/google-deepmind/mujoco/blob/main/test/engine/testdata/sleep/init_island_fail.xml>`__ will lead to
|
||||||
|
a compilation error.
|
||||||
|
|
||||||
|
See :ref:`implementation notes<siSleep>` for more details.
|
||||||
|
|
||||||
.. _body-user:
|
.. _body-user:
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -6,9 +6,14 @@ Upcoming version (not yet released)
|
|||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
General
|
General
|
||||||
^^^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
- Initial changes related to sleeping. Feature under development, documentation pending.
|
.. youtube:: vct493lGQ8Q
|
||||||
|
:align: right
|
||||||
|
:width: 35%
|
||||||
|
|
||||||
|
- Introduced a major new feature: :ref:`sleeping islands<Sleeping>`. Preliminary release for early testing, see
|
||||||
|
documentation for details.
|
||||||
- Added "quadratic" option to :ref:`flexcomp/dof<body-flexcomp-dof>`. This type of fast :ref:`deformable<CDeformable>`
|
- Added "quadratic" option to :ref:`flexcomp/dof<body-flexcomp-dof>`. This type of fast :ref:`deformable<CDeformable>`
|
||||||
flex object is similar to the "trilinear" option, but it includes curved deformations.
|
flex object is similar to the "trilinear" option, but it includes curved deformations.
|
||||||
- Raise an error if there are name collisions also during parsing.
|
- Raise an error if there are name collisions also during parsing.
|
||||||
|
|||||||
+65
-14
@@ -1380,25 +1380,28 @@ Constraint islands
|
|||||||
:width: 58%
|
:width: 58%
|
||||||
:align: right
|
:align: right
|
||||||
|
|
||||||
Consider the abstract graph defined by degrees of freedom (dofs) and constraints. A vertex is all the dofs in a single
|
Consider the abstract graph defined by degrees of freedom (:ref:`DOFs<ElemDof>`) and constraints. A vertex is all the
|
||||||
kinematic subtree; an edge is a constraint (a contact or equality) between two bodies belonging to different subtrees. A
|
DOFs in a single kinematic :ref:`tree<ElemTree>`; an edge is a constraint (a contact, equality or tendon limit) between
|
||||||
*constraint island* is a disjoint sub-graph which can be solved for independently, because constraint forces cannot
|
two bodies belonging to different trees. A *constraint island* is a disjoint sub-graph which can be solved for
|
||||||
propagate between islands. Constraint island discovery and construction ("islanding") invloves finding the disjoint
|
independently, because constraint forces cannot propagate between islands. Constraint island discovery and construction
|
||||||
subgraphs and reordering both the dofs and constraints to make them memory-contiguous. This amounts to a
|
("islanding") involves finding these disjoint subgraphs and reordering both the DOFs and constraints to make them
|
||||||
block-diagonalization of the constraint Jacobian :math:`J`, as illustrated in the figure. On the left is the monolithic
|
memory-contiguous. This amounts to a block-diagonalization of the constraint Jacobian :math:`J`, as illustrated in the
|
||||||
Jacobian of size :math:`\nc \times \nv`, where we use the :ref:`corresponding <Framework>` size names from MuJoCo's data
|
figure. On the left is the monolithic Jacobian of size :math:`\nc \times \nv`, where we use the :ref:`corresponding
|
||||||
structures ``mjData.nefc`` and ``mjModel.nv``. On the right is the block-diagonalized Jacobian with 3 islands that can
|
<Framework>` size names from MuJoCo's data structures ``mjData.nefc`` and ``mjModel.nv``. On the right is the
|
||||||
be solved indepenently. Note that islanding also identifies unconstrained dofs, so ``mjData.nidof``, the total number of
|
block-diagonalized Jacobian with 3 islands that can be solved independently. Note that islanding also identifies
|
||||||
dofs in all islands, might be smaller than ``mjModel.nv``. While islanding is not free (see implementation in
|
unconstrained DOFs, so ``mjData.nidof``, the total number of DOFs in all islands, might be smaller than ``mjModel.nv``.
|
||||||
`engine_island.c <https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_island.c>`__), it is worth the
|
While islanding is not free (see implementation in `engine_island.c
|
||||||
effort:
|
<https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_island.c>`__), it is worth the effort:
|
||||||
|
|
||||||
- Different islands require different numbers of iterations to converge, and a monolithic solve would run for the
|
- Different islands require different numbers of iterations to converge, and a monolithic solve would run for the
|
||||||
number required by the slowest island.
|
number required by the slowest island.
|
||||||
- Unconstrained dofs are completely untouched by the solver, which otherwise needs to discover that they are unaffected.
|
- Unconstrained DOFs are completely untouched by the solver, which otherwise needs to discover that they are unaffected.
|
||||||
- Solving separate islands can be multi-threaded.
|
- Solving separate islands can be multi-threaded.
|
||||||
|
|
||||||
Islanding is not yet supported by the PGS solver.
|
.. admonition:: Known issues
|
||||||
|
:class: note
|
||||||
|
|
||||||
|
Islanding is not yet supported by the PGS solver.
|
||||||
|
|
||||||
|
|
||||||
.. _soParameters:
|
.. _soParameters:
|
||||||
@@ -1668,6 +1671,54 @@ callbacks. This can be used to incorporate a general-purpose "triangle soup" col
|
|||||||
do not recommend such an approach. Pre-processing the geometry and representing it as a union of convex geoms takes some
|
do not recommend such an approach. Pre-processing the geometry and representing it as a union of convex geoms takes some
|
||||||
work, but it pays off at runtime and yields both faster and more stable simulation.
|
work, but it pays off at runtime and yields both faster and more stable simulation.
|
||||||
|
|
||||||
|
.. _Sleeping:
|
||||||
|
|
||||||
|
Sleeping islands
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Sleeping is a performance optimization whereby movable elements of the simulation that are detected to be stationary are
|
||||||
|
temporarily removed from the pipeline ("put to sleep"). This optimization is most useful when the model contains a large
|
||||||
|
number of passive objects. The smallest unit which can be asleep or awake is a :ref:`kinematic tree<ElemTree>`, however
|
||||||
|
trees are always put to sleep together with other trees to which they are connected by constraints, hence the term
|
||||||
|
"sleeping :ref:`islands<soIsland>`".
|
||||||
|
|
||||||
|
.. youtube:: vct493lGQ8Q
|
||||||
|
:align: right
|
||||||
|
:width: 50%
|
||||||
|
|
||||||
|
The video on the right demonstrates several aspects of sleeping. First we show the `dominos
|
||||||
|
<https://github.com/google-deepmind/mujoco/blob/main/model/sleep/dominos.xml>`__ model, which simulates a traditional
|
||||||
|
"chain reaction" of falling domino bricks. All bricks except one are in a stable equilibrium and quickly go to sleep,
|
||||||
|
but the first brick, which is unstable, remains awake and starts falling. Every time a contact is made between awake and
|
||||||
|
sleeping bricks, the latter are woken automatically. After stabilizing on the ground, piles of bricks are put to sleep
|
||||||
|
again and their associated contacts disappear. This sequence is repeated with island visualization enabled, which
|
||||||
|
recolors geoms according to the first DOF of their island, using darker colors if asleep. At the end of the subclip,
|
||||||
|
sleeping is toggled off and on, demonstrating the speed gain afforded by sleeping (lower right). The second subclip
|
||||||
|
shows a variant of the `100 humanoids
|
||||||
|
<https://github.com/google-deepmind/mujoco/blob/main/model/sleep/100_humanoids.xml>`__ model, where all humanoids are
|
||||||
|
*initialized asleep*. Trees initialized as sleeping can be in any configuration, including floating in mid-air, deep
|
||||||
|
penetration, etc. One humanoid is manually woken by direct user perturbation and then dragged around to wake any other
|
||||||
|
humanoid that it touches.
|
||||||
|
|
||||||
|
While the smooth dynamics benefit from sleeping, the largest speedup is due to the reduced number of contacts. Sleeping
|
||||||
|
islands behave like static bodies for the purpose of collision detection: all contacts within an island and between the
|
||||||
|
island and static bodies are skipped. In the case of static piles of objects, the number of skipped contacts can be
|
||||||
|
high, leading to substantial speed gains. Contacts between sleeping islands and awake trees are allowed, and indeed are
|
||||||
|
the main automatic trigger for waking, though manual waking is also supported. Because waking happens in the
|
||||||
|
:ref:`position stage <piStages>` of the pipeline it is effectively instantaneous, and the woken island will behave
|
||||||
|
exactly as if it was awake all along.
|
||||||
|
|
||||||
|
Sleeping is off by default and enabled using the :ref:`sleep<option-flag-sleep>` flag. A detailed description of the
|
||||||
|
sleeping mechanism is provided in the :ref:`Simulation chapter<siSleep>` but here we provide a brief overview.
|
||||||
|
|
||||||
|
Sleeping can occur in one of two ways:
|
||||||
|
|
||||||
|
- **Automatic:** A tree whose maximum velocity in absolute value is less than the
|
||||||
|
:ref:`tolerance <option-sleep_tolerance>` for :ref:`mjMINAWAKE <glNumeric>` time steps is marked as "ready to sleep".
|
||||||
|
If all trees in an island are ready to sleep, they are put to sleep during state advancement.
|
||||||
|
- **Initialized asleep:** By setting the :ref:`body/sleep<body-sleep>` attribute of a tree root to "init", it is
|
||||||
|
marked as "initialized-asleep" and put to sleep during :ref:`mjData` initialization.
|
||||||
|
|
||||||
.. _Pipeline:
|
.. _Pipeline:
|
||||||
|
|
||||||
Simulation pipeline
|
Simulation pipeline
|
||||||
|
|||||||
+60
-9
@@ -422,12 +422,19 @@ Kinematic tree
|
|||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
MuJoCo simulates the dynamics of a collection of rigid bodies whose motion is usually constrained. The system state is
|
MuJoCo simulates the dynamics of a collection of rigid bodies whose motion is usually constrained. The system state is
|
||||||
represented in joint coordinates and the bodies are explicitly organized into kinematic trees. Each body except for the
|
represented in joint coordinates and the bodies are explicitly organized into kinematic trees. The tree structure is
|
||||||
top-level "world" body has a unique parent. Kinematic loops are not allowed; if loop joints are needed they should be
|
given by ``mjModel.body_parentid``, an integer array of length ``nbody >= 1``. The top-level "world" body always exists
|
||||||
modeled with equality constraints. Thus the backbone of a MuJoCo model is one or several kinematic trees formed by
|
(with id ``0``) and is its own parent, thus ``body_parentid[0] == 0`` and ``body_parentid[i] < i`` for all other ``i``.
|
||||||
nested body definitions; an isolated floating body counts as a tree. Several other elements listed below are defined
|
Note that the world body and other static (joint-less) child bodies form a unique "static tree" with no associated
|
||||||
within a body and belong to that body. This is in contrast with the stand-alone elements listed later which cannot be
|
degrees of freedom. Below this top-level static tree, multiple kinematic trees can be attached, see :ref:`Tree
|
||||||
associated with a single body.
|
<ElemTree>` below.
|
||||||
|
|
||||||
|
Kinematic loops are not allowed; if loop joints are needed they should be modeled with equality constraints. Thus the
|
||||||
|
backbone of a MuJoCo model is one or several kinematic trees formed by nested body definitions; an isolated floating
|
||||||
|
body counts as a tree. Several other elements listed below are defined within a body and belong to that body. This is in
|
||||||
|
contrast with the stand-alone elements listed later which cannot be associated with a single body.
|
||||||
|
|
||||||
|
.. _ElemBody:
|
||||||
|
|
||||||
Body
|
Body
|
||||||
^^^^
|
^^^^
|
||||||
@@ -438,6 +445,9 @@ position other elements relative to it, and an inertial frame centered at the bo
|
|||||||
its principal axes of inertia. The body inertia matrix is therefore diagonal in this frame. At each time step MuJoCo
|
its principal axes of inertia. The body inertia matrix is therefore diagonal in this frame. At each time step MuJoCo
|
||||||
computes the forward kinematics recursively, yielding all body positions and orientations in global Cartesian
|
computes the forward kinematics recursively, yielding all body positions and orientations in global Cartesian
|
||||||
coordinates. This provides the basis for all subsequent computations.
|
coordinates. This provides the basis for all subsequent computations.
|
||||||
|
The number of bodies is given by ``mjModel.nbody``.
|
||||||
|
|
||||||
|
.. _ElemJoint:
|
||||||
|
|
||||||
Joint
|
Joint
|
||||||
^^^^^
|
^^^^^
|
||||||
@@ -448,7 +458,7 @@ over-complete Cartesian coordinates, where joints remove DOFs instead of adding
|
|||||||
ball, slide, hinge, and a "free joint" which creates floating bodies. A single body can have multiple joints. In this
|
ball, slide, hinge, and a "free joint" which creates floating bodies. A single body can have multiple joints. In this
|
||||||
way composite joints are created automatically, without having to define dummy bodies. The orientation components of
|
way composite joints are created automatically, without having to define dummy bodies. The orientation components of
|
||||||
ball and free joints are represented as unit quaternions, and all computations in MuJoCo respect the properties of
|
ball and free joints are represented as unit quaternions, and all computations in MuJoCo respect the properties of
|
||||||
quaternions.
|
quaternions. The number of joints is given by ``mjModel.njnt``.
|
||||||
|
|
||||||
Joint reference
|
Joint reference
|
||||||
'''''''''''''''
|
'''''''''''''''
|
||||||
@@ -475,6 +485,8 @@ spring reference pose is saved in ``mjModel.qpos_spring``. For slide and hinge j
|
|||||||
specified with the attribute springref. For ball and free joints, the spring reference corresponds to the initial
|
specified with the attribute springref. For ball and free joints, the spring reference corresponds to the initial
|
||||||
model configuration.
|
model configuration.
|
||||||
|
|
||||||
|
.. _ElemDof:
|
||||||
|
|
||||||
DOF
|
DOF
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
@@ -485,7 +497,27 @@ system, while the joint velocities are coordinates over the tangent space to thi
|
|||||||
DOFs have velocity-related properties such as friction loss, damping, armature inertia. All generalized forces acting
|
DOFs have velocity-related properties such as friction loss, damping, armature inertia. All generalized forces acting
|
||||||
on the system are expressed in the space of DOFs. In contrast, joints have position-related properties such as limits
|
on the system are expressed in the space of DOFs. In contrast, joints have position-related properties such as limits
|
||||||
and spring stiffness. DOFs are not specified directly by the user. Instead they are created by the compiler given the
|
and spring stiffness. DOFs are not specified directly by the user. Instead they are created by the compiler given the
|
||||||
joints.
|
joints. The number of DOFs is given by ``mjModel.nv``.
|
||||||
|
|
||||||
|
.. _ElemTree:
|
||||||
|
|
||||||
|
Tree
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
As explained :ref:`above <Kinematic>`, moving bodies are organized into kinematic trees. A kinematic tree or "tree" is
|
||||||
|
*a movable body and all of its descendants*. Thus the world and other static bodies are in the global tree structure but
|
||||||
|
not associated with any *tree*. Because the global tree structure uses a depth-first organization, all bodies, joints
|
||||||
|
and DOFs belonging to a single tree are always sequential. Note that unlike bodies which (if static) are not associated
|
||||||
|
with any tree, joints and DOFs are always associated with a tree. Both :ref:`island discovery <soIsland>` and
|
||||||
|
:ref:`island sleeping <Sleeping>` operate on the level of trees.
|
||||||
|
|
||||||
|
The number of trees is given by ``mjModel.ntree``. For example, a model containing three free bodies and the `standard
|
||||||
|
humanoid <https://github.com/google-deepmind/mujoco/blob/main/model/humanoid/humanoid.xml>`__ has ``ntree = 4``. Note
|
||||||
|
that while trees are indeed subtrees of the global tree (whose root is the world), this should not be confused with the
|
||||||
|
specific term ``subtree``, which is reserved for per-body partial trees, thus ``mjModel.body_subtreemass`` gives the
|
||||||
|
total mass of the partial tree under each body, for all bodies.
|
||||||
|
|
||||||
|
.. _ElemGeom:
|
||||||
|
|
||||||
Geom
|
Geom
|
||||||
^^^^
|
^^^^
|
||||||
@@ -497,6 +529,9 @@ subsequent computation of contact forces, geoms are used for rendering, as well
|
|||||||
and inertias when the latter are omitted. MuJoCo supports several primitive geometric shapes: plane, sphere, capsule,
|
and inertias when the latter are omitted. MuJoCo supports several primitive geometric shapes: plane, sphere, capsule,
|
||||||
ellipsoid, cylinder, box. A geom can also be a mesh or a height field; this is done by referencing the corresponding
|
ellipsoid, cylinder, box. A geom can also be a mesh or a height field; this is done by referencing the corresponding
|
||||||
asset. Geoms have a number of material properties that affect the simulation and visualization.
|
asset. Geoms have a number of material properties that affect the simulation and visualization.
|
||||||
|
The number of geoms is given by ``mjModel.ngeom``.
|
||||||
|
|
||||||
|
.. _ElemSite:
|
||||||
|
|
||||||
Site
|
Site
|
||||||
^^^^
|
^^^^
|
||||||
@@ -504,6 +539,9 @@ Site
|
|||||||
Sites are essentially light geoms. They represent locations of interest within the body frame. Sites do not
|
Sites are essentially light geoms. They represent locations of interest within the body frame. Sites do not
|
||||||
participate in collision detection or automated computation of inertial properties, however they can be used to
|
participate in collision detection or automated computation of inertial properties, however they can be used to
|
||||||
specify the spatial properties of other objects like sensors, tendon routing, and slider-crank endpoints.
|
specify the spatial properties of other objects like sensors, tendon routing, and slider-crank endpoints.
|
||||||
|
The number of sites is given by ``mjModel.nsite``.
|
||||||
|
|
||||||
|
.. _ElemCamera:
|
||||||
|
|
||||||
Camera
|
Camera
|
||||||
^^^^^^
|
^^^^^^
|
||||||
@@ -515,6 +553,9 @@ orientation, the user can adjust the vertical field of view and the inter-pupila
|
|||||||
as well as create oblique projections needed for stereoscopic virtual environments. When modeling real cameras with
|
as well as create oblique projections needed for stereoscopic virtual environments. When modeling real cameras with
|
||||||
imperfect optics, it is possible to specify separate focal lengths for the horizontal and vertical directions and a
|
imperfect optics, it is possible to specify separate focal lengths for the horizontal and vertical directions and a
|
||||||
non-centered principal point.
|
non-centered principal point.
|
||||||
|
The number of cameras is given by ``mjModel.ncam``.
|
||||||
|
|
||||||
|
.. _ElemLight:
|
||||||
|
|
||||||
Light
|
Light
|
||||||
^^^^^
|
^^^^^
|
||||||
@@ -527,6 +568,7 @@ used with caution. Documenting the lighting model in detail is beyond the scope
|
|||||||
documentation <http://www.glprogramming.com/red/chapter05.html>`__ instead. Note that in addition to lights defined
|
documentation <http://www.glprogramming.com/red/chapter05.html>`__ instead. Note that in addition to lights defined
|
||||||
by the user in the kinematic tree, there is a default headlight that moves with the camera. Its properties are
|
by the user in the kinematic tree, there is a default headlight that moves with the camera. Its properties are
|
||||||
adjusted through the mjVisual options.
|
adjusted through the mjVisual options.
|
||||||
|
The number of lights is given by ``mjModel.nlight``.
|
||||||
|
|
||||||
.. _Standalone:
|
.. _Standalone:
|
||||||
|
|
||||||
@@ -536,6 +578,8 @@ Stand-alone
|
|||||||
Here we describe the model elements which do not belong to an individual body, and therefore are described outside the
|
Here we describe the model elements which do not belong to an individual body, and therefore are described outside the
|
||||||
kinematic tree.
|
kinematic tree.
|
||||||
|
|
||||||
|
.. _ElemTendon:
|
||||||
|
|
||||||
Tendon
|
Tendon
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
@@ -549,6 +593,8 @@ other, the user can also specify the preferred side. If there are multiple wrapp
|
|||||||
must be separated by sites, so as to avoid the need for an iterative solver. Spatial tendons can also be split into
|
must be separated by sites, so as to avoid the need for an iterative solver. Spatial tendons can also be split into
|
||||||
multiple branches using pulleys.
|
multiple branches using pulleys.
|
||||||
|
|
||||||
|
.. _ElemActuator:
|
||||||
|
|
||||||
Actuator
|
Actuator
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
@@ -561,6 +607,8 @@ biological muscles; using such actuators makes the overall system dynamics 3rd-o
|
|||||||
determines how the scalar control signal provided as input to the actuator is mapped into a scalar force, which is in
|
determines how the scalar control signal provided as input to the actuator is mapped into a scalar force, which is in
|
||||||
turn mapped into a generalized force by the moment arms inferred from the transmission.
|
turn mapped into a generalized force by the moment arms inferred from the transmission.
|
||||||
|
|
||||||
|
.. _ElemSensor:
|
||||||
|
|
||||||
Sensor
|
Sensor
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
@@ -574,6 +622,8 @@ other quantity of interest in the sensor data array. MuJoCo also has off-screen
|
|||||||
straightforward to simulate both color and depth camera sensors. This is not included in the standard sensor model
|
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>`.
|
and instead has to be done programmatically, as illustrated in the code sample :ref:`simulate.cc <saSimulate>`.
|
||||||
|
|
||||||
|
.. _ElemEquality:
|
||||||
|
|
||||||
Equality
|
Equality
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
@@ -584,11 +634,12 @@ available equality constraint types are: connect two bodies at a point (creating
|
|||||||
tree); weld two bodies together; fix the position of a joint or tendon; couple the positions of two joints or two
|
tree); weld two bodies together; fix the position of a joint or tendon; couple the positions of two joints or two
|
||||||
tendons via a cubic polynomial; constrain the edges of a flex (i.e. deformable mesh) to their initial lengths.
|
tendons via a cubic polynomial; constrain the edges of a flex (i.e. deformable mesh) to their initial lengths.
|
||||||
|
|
||||||
|
.. _ElemFlex:
|
||||||
|
|
||||||
Flex
|
Flex
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
Flexes were added in MuJoCo 3.0. They represent deformable meshes that can be 1, 2 or 3 dimensional (thus their elements
|
Flexes represent deformable meshes that can be 1, 2 or 3 dimensional (thus their elements
|
||||||
are capsules, triangles or tetrahedra). Unlike geoms which are static shapes attached rigidly to a single body, the
|
are capsules, triangles or tetrahedra). Unlike geoms which are static shapes attached rigidly to a single body, the
|
||||||
elements of a flex are deformable: they are constructed by connecting multiple bodies, thus the body positions and
|
elements of a flex are deformable: they are constructed by connecting multiple bodies, thus the body positions and
|
||||||
orientations determine the shape of the flex elements at runtime. These deformable elements support collisions and
|
orientations determine the shape of the flex elements at runtime. These deformable elements support collisions and
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ The default (and recommended) way to control the system is to implement a contro
|
|||||||
|
|
||||||
.. code-block:: C
|
.. code-block:: C
|
||||||
|
|
||||||
// simple controller applying damping to each dof
|
// simple controller applying damping to each DOF
|
||||||
void mycontroller(const mjModel* m, mjData* d) {
|
void mycontroller(const mjModel* m, mjData* d) {
|
||||||
if (m->nu == m->nv)
|
if (m->nu == m->nv)
|
||||||
mju_scl(d->ctrl, d->qvel, -0.1, m->nv);
|
mju_scl(d->ctrl, d->qvel, -0.1, m->nv);
|
||||||
@@ -923,6 +923,176 @@ is in [3-5] and the Z axis is in [6-8]. The reason for this arrangement is becau
|
|||||||
where only the normal axis is used, so it makes sense to have its coordinates in the first 3 positions of
|
where only the normal axis is used, so it makes sense to have its coordinates in the first 3 positions of
|
||||||
``mjContact.frame``.
|
``mjContact.frame``.
|
||||||
|
|
||||||
|
.. _siSleep:
|
||||||
|
|
||||||
|
Sleeping islands
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sleeping islands are described in broad strokes in the :ref:`Computation chapter <Sleeping>`. Here we focus on
|
||||||
|
implementation details.
|
||||||
|
|
||||||
|
The high level sleep state of :ref:`trees<ElemTree>` is described by ``mjData.tree_asleep`` (though see caveat below). A
|
||||||
|
negative value means a tree is awake, non-negative means asleep. Maximally awake trees are given the value - |-| (1 |-|
|
||||||
|
+ |-| :ref:`mjMINAWAKE<glNumeric>`), and for every timestep where their velocity falls below the sleep :ref:`tolerance
|
||||||
|
<option-sleep_tolerance>`, this integer is incremented, up to -1, which means "ready to sleep". If all trees in an
|
||||||
|
island are ready to sleep, they are put to sleep during state advancement and their associated values in ``tree_asleep``
|
||||||
|
are set to a (non-negative) index cycle: the "sleeping island". If any tree in the island is woken, all are woken.
|
||||||
|
|
||||||
|
Sleep policy
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The ability of a kinematic tree to sleep is governed by a policy determined at model compile time. The compiler
|
||||||
|
automatically determines the :ref:`policy<mjtSleepPolicy>` to be either "allowed" or "never", though these can be
|
||||||
|
overridden using the :ref:`body/sleep <body-sleep>` attribute (see documentation therein). There is also a special
|
||||||
|
"init" sleep policy, see next section.
|
||||||
|
|
||||||
|
Sleeping
|
||||||
|
^^^^^^^^
|
||||||
|
|
||||||
|
Sleeping can happen in one of two ways:
|
||||||
|
|
||||||
|
**Automatic:**
|
||||||
|
The velocity threshold described above is w.r.t. the infinity norm (largest absolute value) of all velocities
|
||||||
|
associated with an island. Before taking this norm, velocities are scaled elementwise by ``mjModel.dof_length``
|
||||||
|
because rotational and translational velocities have different units. The length of a translational DOF is 1; the
|
||||||
|
length of a rotational DOF corresponds to the mean length of its associated geometry. Thus :ref:`sleep_tolerance
|
||||||
|
<option-sleep_tolerance>` has units of [length/time].
|
||||||
|
|
||||||
|
When an island is put to sleep, its associated velocities are set to 0. Therefore, on any timestep where
|
||||||
|
islands are put to sleep, all velocity-dependent quantities must be recomputed before the sleep state is propagated
|
||||||
|
using a call to :ref:`mj_forwardSkip`.
|
||||||
|
|
||||||
|
If any tree in the island has the "never" sleep policy, the entire island cannot sleep.
|
||||||
|
|
||||||
|
**Initialized asleep:**
|
||||||
|
By setting the :ref:`body/sleep<body-sleep>` attribute of a tree root to "init", it is marked as "initialized asleep"
|
||||||
|
and put to sleep during :ref:`mjData` initialization. This is useful for large models where waiting for many trees to
|
||||||
|
fall asleep can be expensive.
|
||||||
|
|
||||||
|
Since trees which share contacts or are otherwise in the same island must sleep together, if some trees in an island
|
||||||
|
are initialized as sleeping, all of them must be marked as such. `This model
|
||||||
|
<https://github.com/google-deepmind/mujoco/blob/main/test/engine/testdata/sleep/init_island_fail.xml>`__ contains an
|
||||||
|
example XML that will produce a compilation error because this condition is not met. Finally, note that the
|
||||||
|
initialized-asleep feature is only available for the default configuration (and not keyframes, see discussion below).
|
||||||
|
|
||||||
|
Waking
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
Waking happens at the beginning of the timestep, either during :ref:`mj_kinematics` or soon thereafter during the
|
||||||
|
:ref:`position stage <piStages>` of the simulation pipeline. A sleeping island is woken up according to the following
|
||||||
|
criteria:
|
||||||
|
|
||||||
|
- Its associated configuration ``qpos`` is changed by the user, for example when repositioning the
|
||||||
|
configuration interactively when the simulation is paused.
|
||||||
|
- Its associated velocity ``qvel`` or applied forces ``qfrc_applied`` or ``xfrc_applied`` are set by the user to
|
||||||
|
a non-zero value, for example when perturbing the model interactively during simulation.
|
||||||
|
Note that the check is performed by bytewise comparison to 0, so setting an associated element to
|
||||||
|
the floating point value ``-0.0`` will wake the island but have no other side-effects.
|
||||||
|
- It comes into contact with an awake tree. Waking due to contact leads to collision detection being run *twice*, but
|
||||||
|
only on the timestep when it occurs. This is required in order to detect contacts inside the island and between the
|
||||||
|
island and the world, which were skipped in the first run when it was deemed asleep.
|
||||||
|
- It is connected to an awake tree by an active equality constraint or limited tendon.
|
||||||
|
- It is connected by an equality constraint to a sleeping tree in a different island. For this to occur, the equality
|
||||||
|
must have been disabled when both trees were put to sleep.
|
||||||
|
|
||||||
|
The automatic wake criteria listed above are designed so that sleeping islands behave as if they were awake, but this
|
||||||
|
is not always the case. For example, if free bodies on the floor are put to sleep and then gravity is reversed, they
|
||||||
|
will remain sleeping in place until woken for another reason. The most extreme example of non-physicality are islands
|
||||||
|
which are initialized asleep. These can be placed in mid-air or in deep collisions, but will not move until woken.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
^^^^^
|
||||||
|
|
||||||
|
.. admonition:: New feature
|
||||||
|
:class: warning
|
||||||
|
|
||||||
|
Sleeping is a new feature (Nov 2025) that is subject to change and may have latent bugs.
|
||||||
|
|
||||||
|
**Sleeping actuators**
|
||||||
|
As explained in the :ref:`body/sleep <body-sleep>` documentation, trees with actuators are by default not allowed to
|
||||||
|
sleep, but this can be overridden by the user. The reason sleeping is not allowed by default is that once an actuator
|
||||||
|
is marked as asleep, the computation required to wake it is no longer performed. Even if it were performed (i.e. if
|
||||||
|
actuation forces were always computed for all actuators, regardless of their sleep state), this computation happens in
|
||||||
|
acceleration/force stage, by which time it is already too late to wake a tree, since waking must happen in the
|
||||||
|
position stage. Therefore, if a tree with actuators is allowed to sleep, waking must be done manually by touching the
|
||||||
|
associated velocities or forces, as described above.
|
||||||
|
|
||||||
|
**Sleeping sensors**
|
||||||
|
The computation of sensor values are skipped if the objects associated with it are asleep or static, so the last
|
||||||
|
valid computed values remain untouched. This is straightforward for most sensors, but :ref:`contact<sensor-contact>`
|
||||||
|
sensors are an exception. Because contact sensors report contacts that occurred in the current timestep, and
|
||||||
|
sleeping implies that some contacts are not computed, skipping the sensor computation is not always possible.
|
||||||
|
For example, consider a scene with free bodies on the floor, some of which may be asleep. A sensor which reports
|
||||||
|
information from contacts of body A (with anything else), will keep reporting the same thing when the body goes to
|
||||||
|
sleep. However a sensor that reports all world contacts will report something different when some bodies go to sleep.
|
||||||
|
|
||||||
|
**Provisional choices**
|
||||||
|
Some implementation choices are provisional and subject to change.
|
||||||
|
|
||||||
|
A concrete example is the decision to hard-code the value of :ref:`mjMINAWAKE<glNumeric>` instead of exposing it to
|
||||||
|
the user as a runtime option. This was done for two reasons. First, in our experiments, we've found that changing this
|
||||||
|
value is equivalent to changing the :ref:`sleep_tolerance<option-sleep_tolerance>`, which is the more useful knob.
|
||||||
|
Second, one could argue for a time-to-sleep semantic that is in units of time rather than an integer number of
|
||||||
|
timesteps. Until there is clear evidence that one or both of these reasons are invalid, we've opted for a simple
|
||||||
|
numeric constant.
|
||||||
|
|
||||||
|
**Static bodies**
|
||||||
|
Besides the main optimization of allowing kinematic trees to sleep, the sleep feature also includes another, related
|
||||||
|
optimization: the skipping of computation related to static bodies. This can be valuable if, for example,
|
||||||
|
the world body or its static children contain a large number of geoms, whose poses will be computed only once.
|
||||||
|
|
||||||
|
This leads to a subtle (if unlikely) "gotcha". Although it is allowed to enable sleeping during simulation, sleeping
|
||||||
|
must be enabled either at initialization time or after at least one :ref:`mj_step`. To wit:
|
||||||
|
|
||||||
|
.. code-block:: C
|
||||||
|
|
||||||
|
// this is OK:
|
||||||
|
mjData* d = mj_makeData(m); // sleeping is enabled at init time
|
||||||
|
mj_step(m, d);
|
||||||
|
...
|
||||||
|
|
||||||
|
// this is also OK:
|
||||||
|
mjData* d = mj_makeData(m); // sleeping is disabled at init time
|
||||||
|
mj_step(m, d);
|
||||||
|
...
|
||||||
|
m->opt.enableflags |= mjENABLE_SLEEP; // enable sleeping after at least one step
|
||||||
|
mj_step(m, d);
|
||||||
|
|
||||||
|
// this is an error:
|
||||||
|
mjData* d = mj_makeData(m); // sleeping is disabled at init time
|
||||||
|
m->opt.enableflags |= mjENABLE_SLEEP; // enable sleeping
|
||||||
|
mj_step(m, d); // undefined behavior, static elements not computed
|
||||||
|
|
||||||
|
|
||||||
|
**Violated assumptions**
|
||||||
|
Sleeping breaks several assumptions that are baked into the core of MuJoCo (and continue to hold if sleeping is
|
||||||
|
disabled).
|
||||||
|
|
||||||
|
*Pipeline stages*: It is usually guaranteed that no velocity-related quantities will be read before the end of the
|
||||||
|
position stage and that no force-related quantities will be read before the end of velocity stage. This assumption,
|
||||||
|
which lies at the heart of the :ref:`mj_step1`/:ref:`mj_step2` split, is violated by the reading of ``qvel``,
|
||||||
|
``qfrc_applied`` and ``xfrc_applied`` in :ref:`mj_kinematics`.
|
||||||
|
|
||||||
|
*Compact state*: While the sleep state is notionally given by ``mjData.tree_asleep``, this is a mirage. Once an island
|
||||||
|
is asleep, the entire subset of position and velocity-dependent quantities in mjData associated with it becomes
|
||||||
|
a pre-computed latent state that is "waiting for the island to wake up". For this reason, the only way to fully save
|
||||||
|
and restore the state of a simulation with sleeping elements is to :ref:`copy<mj_copyData>` the entire mjData
|
||||||
|
structure. This is also the reason why sleep initialization is only available for the default configuration and not
|
||||||
|
for keyframes. Note that saving and loading the state using the :ref:`standard tools<geState>` remains a valid
|
||||||
|
operation, merely that sleeping islands will be implicitly woken up.
|
||||||
|
|
||||||
|
|
||||||
|
**RK4 integrator**
|
||||||
|
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:
|
||||||
|
|
||||||
|
- 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.
|
||||||
|
- Actual bugs. Hopefully these will lead to informative runtime errors, please report any to the development team.
|
||||||
|
|
||||||
|
|
||||||
.. _siCoordinate:
|
.. _siCoordinate:
|
||||||
|
|
||||||
Coordinate frames and transformations
|
Coordinate frames and transformations
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<!-- Copyright 2025 DeepMind Technologies Limited
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<mujoco model="100 Humanoids">
|
||||||
|
<option timestep="0.005">
|
||||||
|
<!-- modification of model/humanoid/100_humanoids.xml: enable sleep -->
|
||||||
|
<flag sleep="enable"/>
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<size memory="100M"/>
|
||||||
|
|
||||||
|
<asset>
|
||||||
|
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="512" height="512"/>
|
||||||
|
<texture name="floor" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||||
|
<material name="floor" texture="floor" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||||
|
<model name="humanoid" file="humanoid.xml"/>
|
||||||
|
</asset>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<map force="0.1" zfar="30"/>
|
||||||
|
<rgba haze="0.15 0.25 0.35 1"/>
|
||||||
|
<quality numslices="16" numstacks="8"/>
|
||||||
|
<global offwidth="800" offheight="800"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<geom name="floor" size="10 10 .05" type="plane" material="floor" condim="3"/>
|
||||||
|
<light directional="true" diffuse=".9 .9 .9" specular="0.1 0.1 0.1" pos="0 0 5" dir="0 0 -1" castshadow="true"/>
|
||||||
|
<light name="spotlight" mode="targetbodycom" target="world" diffuse="1 1 1" specular="0.3 0.3 0.3" pos="-6 -6 4" cutoff="60"/>
|
||||||
|
<replicate count="10" euler="0 0 36" sep="-">
|
||||||
|
<frame pos="1.2 0 0">
|
||||||
|
<replicate count="10" euler="0 0 17" sep="-" offset="0.6 0 0">
|
||||||
|
<attach model="humanoid" body="torso" prefix="_"/>
|
||||||
|
</replicate>
|
||||||
|
</frame>
|
||||||
|
</replicate>
|
||||||
|
</worldbody>
|
||||||
|
</mujoco>
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
<!-- Copyright 2025 DeepMind Technologies Limited
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<mujoco model="sleeping dominos">
|
||||||
|
<option cone="elliptic" impratio="10" sleep_tolerance="3e-4">
|
||||||
|
<flag sleep="enable"/>
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<default>
|
||||||
|
<default class="domino">
|
||||||
|
<geom type="box" size=".008 .044 .089" rgba=".9 .9 .9 1" mass="0.09"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<light pos=".5 0 3" diffuse="1 1 1"/>
|
||||||
|
<geom type="plane" size="2 2 .01" pos=".5 0 1e-6"/>
|
||||||
|
|
||||||
|
<!-- one domino atilt kicks off the chain reaction -->
|
||||||
|
<body pos="-.1 0 .089" euler="0 7 0">
|
||||||
|
<freejoint/>
|
||||||
|
<geom type="box" class="domino"/>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<!-- 5 rows of 15 dominoes, arranged in toppling order for consistent ids and colors -->
|
||||||
|
|
||||||
|
<!-- 3 rows of 15 dominoes, left to right -->
|
||||||
|
<replicate count="3" offset="0 1 0">
|
||||||
|
<frame pos="0 -1 0">
|
||||||
|
<replicate count="15" offset=".1 0 0">
|
||||||
|
<body pos="0 0 .089">
|
||||||
|
<freejoint/>
|
||||||
|
<geom type="box" class="domino"/>
|
||||||
|
</body>
|
||||||
|
</replicate>
|
||||||
|
</frame>
|
||||||
|
</replicate>
|
||||||
|
|
||||||
|
<!-- 2 rows of 15 dominoes, right to left -->
|
||||||
|
<replicate count="2" offset="0 1 0">
|
||||||
|
<frame pos="0 -.5 0">
|
||||||
|
<replicate count="15" offset="-.1 0 0">
|
||||||
|
<body pos="1.4 0 .089">
|
||||||
|
<freejoint/>
|
||||||
|
<geom type="box" class="domino"/>
|
||||||
|
</body>
|
||||||
|
</replicate>
|
||||||
|
</frame>
|
||||||
|
</replicate>
|
||||||
|
|
||||||
|
<!-- two "U turns", place blocks not too close in order to break the island chain -->
|
||||||
|
<replicate offset="0 -.55 0" count="2">
|
||||||
|
<frame pos="1.5 .26 0">
|
||||||
|
<replicate count="5" euler="0 0 45">
|
||||||
|
<body pos="0 -.23 .089">
|
||||||
|
<freejoint/>
|
||||||
|
<geom type="box" class="domino"/>
|
||||||
|
</body>
|
||||||
|
</replicate>
|
||||||
|
</frame>
|
||||||
|
</replicate>
|
||||||
|
|
||||||
|
<!-- two more U turns for the outside rows -->
|
||||||
|
<replicate offset="0 1.5 0" count="2">
|
||||||
|
<frame pos="-.1 -.75 0" euler="0 0 180">
|
||||||
|
<replicate count="5" euler="0 0 45">
|
||||||
|
<body pos="0 -.23 .089">
|
||||||
|
<freejoint/>
|
||||||
|
<geom type="box" class="domino"/>
|
||||||
|
</body>
|
||||||
|
</replicate>
|
||||||
|
</frame>
|
||||||
|
</replicate>
|
||||||
|
</worldbody>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<global elevation="-25" azimuth="60"/>
|
||||||
|
</visual>
|
||||||
|
<statistic center="1.2 0 0"/>
|
||||||
|
</mujoco>
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
<!-- Copyright 2025 DeepMind Technologies Limited
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<mujoco model="Humanoid">
|
||||||
|
<option timestep="0.005">
|
||||||
|
<!-- modification of model/humanoid/humanoid.xml: enable sleep -->
|
||||||
|
<flag sleep="enable"/>
|
||||||
|
</option>
|
||||||
|
|
||||||
|
<visual>
|
||||||
|
<map force="0.1" zfar="30"/>
|
||||||
|
<rgba haze="0.15 0.25 0.35 1"/>
|
||||||
|
<global offwidth="2560" offheight="1440" elevation="-20" azimuth="120"/>
|
||||||
|
</visual>
|
||||||
|
|
||||||
|
<statistic center="0 0 0.7"/>
|
||||||
|
|
||||||
|
<asset>
|
||||||
|
<texture type="skybox" builtin="gradient" rgb1=".3 .5 .7" rgb2="0 0 0" width="32" height="512"/>
|
||||||
|
<texture name="body" type="cube" builtin="flat" mark="cross" width="128" height="128" rgb1="0.8 0.6 0.4" rgb2="0.8 0.6 0.4" markrgb="1 1 1"/>
|
||||||
|
<material name="body" texture="body" texuniform="true" rgba="0.8 0.6 .4 1"/>
|
||||||
|
<texture name="grid" type="2d" builtin="checker" width="512" height="512" rgb1=".1 .2 .3" rgb2=".2 .3 .4"/>
|
||||||
|
<material name="grid" texture="grid" texrepeat="1 1" texuniform="true" reflectance=".2"/>
|
||||||
|
</asset>
|
||||||
|
|
||||||
|
<default>
|
||||||
|
<motor ctrlrange="-1 1" ctrllimited="true"/>
|
||||||
|
<default class="body">
|
||||||
|
|
||||||
|
<!-- geoms -->
|
||||||
|
<geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".015 1" material="body" group="1"/>
|
||||||
|
<default class="thigh">
|
||||||
|
<geom size=".06"/>
|
||||||
|
</default>
|
||||||
|
<default class="shin">
|
||||||
|
<geom fromto="0 0 0 0 0 -.3" size=".049"/>
|
||||||
|
</default>
|
||||||
|
<default class="foot">
|
||||||
|
<geom size=".027"/>
|
||||||
|
<default class="foot1">
|
||||||
|
<geom fromto="-.07 -.01 0 .14 -.03 0"/>
|
||||||
|
</default>
|
||||||
|
<default class="foot2">
|
||||||
|
<geom fromto="-.07 .01 0 .14 .03 0"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
<default class="arm_upper">
|
||||||
|
<geom size=".04"/>
|
||||||
|
</default>
|
||||||
|
<default class="arm_lower">
|
||||||
|
<geom size=".031"/>
|
||||||
|
</default>
|
||||||
|
<default class="hand">
|
||||||
|
<geom type="sphere" size=".04"/>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<!-- joints -->
|
||||||
|
<joint type="hinge" damping=".2" stiffness="1" armature=".01" limited="true" solimplimit="0 .99 .01"/>
|
||||||
|
<default class="joint_big">
|
||||||
|
<joint damping="5" stiffness="10"/>
|
||||||
|
<default class="hip_x">
|
||||||
|
<joint range="-30 10"/>
|
||||||
|
</default>
|
||||||
|
<default class="hip_z">
|
||||||
|
<joint range="-60 35"/>
|
||||||
|
</default>
|
||||||
|
<default class="hip_y">
|
||||||
|
<joint axis="0 1 0" range="-150 20"/>
|
||||||
|
</default>
|
||||||
|
<default class="joint_big_stiff">
|
||||||
|
<joint stiffness="20"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
<default class="knee">
|
||||||
|
<joint pos="0 0 .02" axis="0 -1 0" range="-160 2"/>
|
||||||
|
</default>
|
||||||
|
<default class="ankle">
|
||||||
|
<joint range="-50 50"/>
|
||||||
|
<default class="ankle_y">
|
||||||
|
<joint pos="0 0 .08" axis="0 1 0" stiffness="6"/>
|
||||||
|
</default>
|
||||||
|
<default class="ankle_x">
|
||||||
|
<joint pos="0 0 .04" stiffness="3"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
<default class="shoulder">
|
||||||
|
<joint range="-85 60"/>
|
||||||
|
</default>
|
||||||
|
<default class="elbow">
|
||||||
|
<joint range="-100 50" stiffness="0"/>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
</default>
|
||||||
|
|
||||||
|
<worldbody>
|
||||||
|
<geom name="floor" size="0 0 .05" type="plane" material="grid" condim="3"/>
|
||||||
|
<light name="spotlight" mode="targetbodycom" target="torso" diffuse=".8 .8 .8" specular="0.3 0.3 0.3" pos="0 -6 4" cutoff="30"/>
|
||||||
|
<light name="top" pos="0 0 2" mode="trackcom"/>
|
||||||
|
|
||||||
|
<!-- modification of model/humanoid/humanoid.xml: initialized asleep -->
|
||||||
|
|
||||||
|
<body name="torso" pos="0 0 1.282" childclass="body" sleep="init">
|
||||||
|
<camera name="back" pos="-3 0 1" xyaxes="0 -1 0 1 0 2" mode="trackcom"/>
|
||||||
|
<camera name="side" pos="0 -3 1" xyaxes="1 0 0 0 1 2" mode="trackcom"/>
|
||||||
|
<freejoint name="root"/>
|
||||||
|
<geom name="torso" fromto="0 -.07 0 0 .07 0" size=".07"/>
|
||||||
|
<geom name="waist_upper" fromto="-.01 -.06 -.12 -.01 .06 -.12" size=".06"/>
|
||||||
|
<body name="head" pos="0 0 .19">
|
||||||
|
<geom name="head" type="sphere" size=".09"/>
|
||||||
|
<camera name="egocentric" pos=".09 0 0" xyaxes="0 -1 0 .1 0 1" fovy="80"/>
|
||||||
|
</body>
|
||||||
|
<body name="waist_lower" pos="-.01 0 -.26">
|
||||||
|
<geom name="waist_lower" fromto="0 -.06 0 0 .06 0" size=".06"/>
|
||||||
|
<joint name="abdomen_z" pos="0 0 .065" axis="0 0 1" range="-45 45" class="joint_big_stiff"/>
|
||||||
|
<joint name="abdomen_y" pos="0 0 .065" axis="0 1 0" range="-75 30" class="joint_big"/>
|
||||||
|
<body name="pelvis" pos="0 0 -.165">
|
||||||
|
<joint name="abdomen_x" pos="0 0 .1" axis="1 0 0" range="-35 35" class="joint_big"/>
|
||||||
|
<geom name="butt" fromto="-.02 -.07 0 -.02 .07 0" size=".09"/>
|
||||||
|
<body name="thigh_right" pos="0 -.1 -.04">
|
||||||
|
<joint name="hip_x_right" axis="1 0 0" class="hip_x"/>
|
||||||
|
<joint name="hip_z_right" axis="0 0 1" class="hip_z"/>
|
||||||
|
<joint name="hip_y_right" class="hip_y"/>
|
||||||
|
<geom name="thigh_right" fromto="0 0 0 0 .01 -.34" class="thigh"/>
|
||||||
|
<body name="shin_right" pos="0 .01 -.4">
|
||||||
|
<joint name="knee_right" class="knee"/>
|
||||||
|
<geom name="shin_right" class="shin"/>
|
||||||
|
<body name="foot_right" pos="0 0 -.39">
|
||||||
|
<joint name="ankle_y_right" class="ankle_y"/>
|
||||||
|
<joint name="ankle_x_right" class="ankle_x" axis="1 0 .5"/>
|
||||||
|
<geom name="foot1_right" class="foot1"/>
|
||||||
|
<geom name="foot2_right" class="foot2"/>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
<body name="thigh_left" pos="0 .1 -.04">
|
||||||
|
<joint name="hip_x_left" axis="-1 0 0" class="hip_x"/>
|
||||||
|
<joint name="hip_z_left" axis="0 0 -1" class="hip_z"/>
|
||||||
|
<joint name="hip_y_left" class="hip_y"/>
|
||||||
|
<geom name="thigh_left" fromto="0 0 0 0 -.01 -.34" class="thigh"/>
|
||||||
|
<body name="shin_left" pos="0 -.01 -.4">
|
||||||
|
<joint name="knee_left" class="knee"/>
|
||||||
|
<geom name="shin_left" fromto="0 0 0 0 0 -.3" class="shin"/>
|
||||||
|
<body name="foot_left" pos="0 0 -.39">
|
||||||
|
<joint name="ankle_y_left" class="ankle_y"/>
|
||||||
|
<joint name="ankle_x_left" class="ankle_x" axis="-1 0 -.5"/>
|
||||||
|
<geom name="foot1_left" class="foot1"/>
|
||||||
|
<geom name="foot2_left" class="foot2"/>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
<body name="upper_arm_right" pos="0 -.17 .06">
|
||||||
|
<joint name="shoulder1_right" axis="2 1 1" class="shoulder"/>
|
||||||
|
<joint name="shoulder2_right" axis="0 -1 1" class="shoulder"/>
|
||||||
|
<geom name="upper_arm_right" fromto="0 0 0 .16 -.16 -.16" class="arm_upper"/>
|
||||||
|
<body name="lower_arm_right" pos=".18 -.18 -.18">
|
||||||
|
<joint name="elbow_right" axis="0 -1 1" class="elbow"/>
|
||||||
|
<geom name="lower_arm_right" fromto=".01 .01 .01 .17 .17 .17" class="arm_lower"/>
|
||||||
|
<body name="hand_right" pos=".18 .18 .18">
|
||||||
|
<geom name="hand_right" zaxis="1 1 1" class="hand"/>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
<body name="upper_arm_left" pos="0 .17 .06">
|
||||||
|
<joint name="shoulder1_left" axis="-2 1 -1" class="shoulder"/>
|
||||||
|
<joint name="shoulder2_left" axis="0 -1 -1" class="shoulder"/>
|
||||||
|
<geom name="upper_arm_left" fromto="0 0 0 .16 .16 -.16" class="arm_upper"/>
|
||||||
|
<body name="lower_arm_left" pos=".18 .18 -.18">
|
||||||
|
<joint name="elbow_left" axis="0 -1 -1" class="elbow"/>
|
||||||
|
<geom name="lower_arm_left" fromto=".01 -.01 .01 .17 -.17 .17" class="arm_lower"/>
|
||||||
|
<body name="hand_left" pos=".18 -.18 .18">
|
||||||
|
<geom name="hand_left" zaxis="1 -1 1" class="hand"/>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</body>
|
||||||
|
</worldbody>
|
||||||
|
|
||||||
|
<contact>
|
||||||
|
<exclude body1="waist_lower" body2="thigh_right"/>
|
||||||
|
<exclude body1="waist_lower" body2="thigh_left"/>
|
||||||
|
</contact>
|
||||||
|
|
||||||
|
<tendon>
|
||||||
|
<fixed name="hamstring_right" limited="true" range="-0.3 2">
|
||||||
|
<joint joint="hip_y_right" coef=".5"/>
|
||||||
|
<joint joint="knee_right" coef="-.5"/>
|
||||||
|
</fixed>
|
||||||
|
<fixed name="hamstring_left" limited="true" range="-0.3 2">
|
||||||
|
<joint joint="hip_y_left" coef=".5"/>
|
||||||
|
<joint joint="knee_left" coef="-.5"/>
|
||||||
|
</fixed>
|
||||||
|
</tendon>
|
||||||
|
|
||||||
|
<actuator>
|
||||||
|
<motor name="abdomen_z" gear="40" joint="abdomen_z"/>
|
||||||
|
<motor name="abdomen_y" gear="40" joint="abdomen_y"/>
|
||||||
|
<motor name="abdomen_x" gear="40" joint="abdomen_x"/>
|
||||||
|
<motor name="hip_x_right" gear="40" joint="hip_x_right"/>
|
||||||
|
<motor name="hip_z_right" gear="40" joint="hip_z_right"/>
|
||||||
|
<motor name="hip_y_right" gear="120" joint="hip_y_right"/>
|
||||||
|
<motor name="knee_right" gear="80" joint="knee_right"/>
|
||||||
|
<motor name="ankle_y_right" gear="20" joint="ankle_y_right"/>
|
||||||
|
<motor name="ankle_x_right" gear="20" joint="ankle_x_right"/>
|
||||||
|
<motor name="hip_x_left" gear="40" joint="hip_x_left"/>
|
||||||
|
<motor name="hip_z_left" gear="40" joint="hip_z_left"/>
|
||||||
|
<motor name="hip_y_left" gear="120" joint="hip_y_left"/>
|
||||||
|
<motor name="knee_left" gear="80" joint="knee_left"/>
|
||||||
|
<motor name="ankle_y_left" gear="20" joint="ankle_y_left"/>
|
||||||
|
<motor name="ankle_x_left" gear="20" joint="ankle_x_left"/>
|
||||||
|
<motor name="shoulder1_right" gear="20" joint="shoulder1_right"/>
|
||||||
|
<motor name="shoulder2_right" gear="20" joint="shoulder2_right"/>
|
||||||
|
<motor name="elbow_right" gear="40" joint="elbow_right"/>
|
||||||
|
<motor name="shoulder1_left" gear="20" joint="shoulder1_left"/>
|
||||||
|
<motor name="shoulder2_left" gear="20" joint="shoulder2_left"/>
|
||||||
|
<motor name="elbow_left" gear="40" joint="elbow_left"/>
|
||||||
|
</actuator>
|
||||||
|
|
||||||
|
<keyframe>
|
||||||
|
<!--
|
||||||
|
The values below are split into rows for readibility:
|
||||||
|
torso position
|
||||||
|
torso orientation
|
||||||
|
spinal
|
||||||
|
right leg
|
||||||
|
left leg
|
||||||
|
arms
|
||||||
|
-->
|
||||||
|
<key name="squat"
|
||||||
|
qpos="0 0 0.596
|
||||||
|
0.988015 0 0.154359 0
|
||||||
|
0 0.4 0
|
||||||
|
-0.25 -0.5 -2.5 -2.65 -0.8 0.56
|
||||||
|
-0.25 -0.5 -2.5 -2.65 -0.8 0.56
|
||||||
|
0 0 0 0 0 0"/>
|
||||||
|
<key name="stand_on_left_leg"
|
||||||
|
qpos="0 0 1.21948
|
||||||
|
0.971588 -0.179973 0.135318 -0.0729076
|
||||||
|
-0.0516 -0.202 0.23
|
||||||
|
-0.24 -0.007 -0.34 -1.76 -0.466 -0.0415
|
||||||
|
-0.08 -0.01 -0.37 -0.685 -0.35 -0.09
|
||||||
|
0.109 -0.067 -0.7 -0.05 0.12 0.16"/>
|
||||||
|
<key name="prone"
|
||||||
|
qpos="0.4 0 0.0757706
|
||||||
|
0.7325 0 0.680767 0
|
||||||
|
0 0.0729 0
|
||||||
|
0.0077 0.0019 -0.026 -0.351 -0.27 0
|
||||||
|
0.0077 0.0019 -0.026 -0.351 -0.27 0
|
||||||
|
0.56 -0.62 -1.752
|
||||||
|
0.56 -0.62 -1.752"/>
|
||||||
|
<key name="supine"
|
||||||
|
qpos="-0.4 0 0.08122
|
||||||
|
0.722788 0 -0.69107 0
|
||||||
|
0 -0.25 0
|
||||||
|
0.0182 0.0142 0.3 0.042 -0.44 -0.02
|
||||||
|
0.0182 0.0142 0.3 0.042 -0.44 -0.02
|
||||||
|
0.186 -0.73 -1.73
|
||||||
|
0.186 -0.73 -1.73"/>
|
||||||
|
</keyframe>
|
||||||
|
</mujoco>
|
||||||
Reference in New Issue
Block a user