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:
|
||||
|
||||
: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:
|
||||
|
||||
@@ -674,7 +674,16 @@ from its default.
|
||||
.. _option-flag-sleep:
|
||||
|
||||
: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:
|
||||
|
||||
@@ -2072,7 +2081,31 @@ defined. Its body name is automatically defined as "world".
|
||||
.. _body-sleep:
|
||||
|
||||
: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:
|
||||
|
||||
|
||||
+7
-2
@@ -6,9 +6,14 @@ Upcoming version (not yet released)
|
||||
-----------------------------------
|
||||
|
||||
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>`
|
||||
flex object is similar to the "trilinear" option, but it includes curved deformations.
|
||||
- Raise an error if there are name collisions also during parsing.
|
||||
|
||||
+65
-14
@@ -1380,25 +1380,28 @@ Constraint islands
|
||||
:width: 58%
|
||||
:align: right
|
||||
|
||||
Consider the abstract graph defined by degrees of freedom (dofs) and constraints. A vertex is all the dofs in a single
|
||||
kinematic subtree; an edge is a constraint (a contact or equality) between two bodies belonging to different subtrees. A
|
||||
*constraint island* is a disjoint sub-graph which can be solved for independently, because constraint forces cannot
|
||||
propagate between islands. Constraint island discovery and construction ("islanding") invloves finding the disjoint
|
||||
subgraphs and reordering both the dofs and constraints to make them memory-contiguous. This amounts to a
|
||||
block-diagonalization of the constraint Jacobian :math:`J`, as illustrated in the figure. On the left is the monolithic
|
||||
Jacobian of size :math:`\nc \times \nv`, where we use the :ref:`corresponding <Framework>` size names from MuJoCo's data
|
||||
structures ``mjData.nefc`` and ``mjModel.nv``. On the right is the block-diagonalized Jacobian with 3 islands that can
|
||||
be solved indepenently. Note that islanding also identifies unconstrained dofs, so ``mjData.nidof``, the total number of
|
||||
dofs in all islands, might be smaller than ``mjModel.nv``. While islanding is not free (see implementation in
|
||||
`engine_island.c <https://github.com/google-deepmind/mujoco/blob/main/src/engine/engine_island.c>`__), it is worth the
|
||||
effort:
|
||||
Consider the abstract graph defined by degrees of freedom (:ref:`DOFs<ElemDof>`) and constraints. A vertex is all the
|
||||
DOFs in a single kinematic :ref:`tree<ElemTree>`; an edge is a constraint (a contact, equality or tendon limit) between
|
||||
two bodies belonging to different trees. A *constraint island* is a disjoint sub-graph which can be solved for
|
||||
independently, because constraint forces cannot propagate between islands. Constraint island discovery and construction
|
||||
("islanding") involves finding these disjoint subgraphs and reordering both the DOFs and constraints to make them
|
||||
memory-contiguous. This amounts to a block-diagonalization of the constraint Jacobian :math:`J`, as illustrated in the
|
||||
figure. On the left is the monolithic Jacobian of size :math:`\nc \times \nv`, where we use the :ref:`corresponding
|
||||
<Framework>` size names from MuJoCo's data structures ``mjData.nefc`` and ``mjModel.nv``. On the right is the
|
||||
block-diagonalized Jacobian with 3 islands that can be solved independently. Note that islanding also identifies
|
||||
unconstrained DOFs, so ``mjData.nidof``, the total number of DOFs in all islands, might be smaller than ``mjModel.nv``.
|
||||
While islanding is not free (see implementation in `engine_island.c
|
||||
<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
|
||||
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.
|
||||
|
||||
Islanding is not yet supported by the PGS solver.
|
||||
.. admonition:: Known issues
|
||||
:class: note
|
||||
|
||||
Islanding is not yet supported by the PGS solver.
|
||||
|
||||
|
||||
.. _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
|
||||
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:
|
||||
|
||||
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
|
||||
represented in joint coordinates and the bodies are explicitly organized into kinematic trees. Each body except for the
|
||||
top-level "world" body has a unique parent. 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.
|
||||
represented in joint coordinates and the bodies are explicitly organized into kinematic trees. The tree structure is
|
||||
given by ``mjModel.body_parentid``, an integer array of length ``nbody >= 1``. The top-level "world" body always exists
|
||||
(with id ``0``) and is its own parent, thus ``body_parentid[0] == 0`` and ``body_parentid[i] < i`` for all other ``i``.
|
||||
Note that the world body and other static (joint-less) child bodies form a unique "static tree" with no associated
|
||||
degrees of freedom. Below this top-level static tree, multiple kinematic trees can be attached, see :ref:`Tree
|
||||
<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
|
||||
^^^^
|
||||
@@ -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
|
||||
computes the forward kinematics recursively, yielding all body positions and orientations in global Cartesian
|
||||
coordinates. This provides the basis for all subsequent computations.
|
||||
The number of bodies is given by ``mjModel.nbody``.
|
||||
|
||||
.. _ElemJoint:
|
||||
|
||||
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
|
||||
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
|
||||
quaternions.
|
||||
quaternions. The number of joints is given by ``mjModel.njnt``.
|
||||
|
||||
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
|
||||
model configuration.
|
||||
|
||||
.. _ElemDof:
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
^^^^
|
||||
@@ -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,
|
||||
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.
|
||||
The number of geoms is given by ``mjModel.ngeom``.
|
||||
|
||||
.. _ElemSite:
|
||||
|
||||
Site
|
||||
^^^^
|
||||
@@ -504,6 +539,9 @@ Site
|
||||
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
|
||||
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
|
||||
^^^^^^
|
||||
@@ -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
|
||||
imperfect optics, it is possible to specify separate focal lengths for the horizontal and vertical directions and a
|
||||
non-centered principal point.
|
||||
The number of cameras is given by ``mjModel.ncam``.
|
||||
|
||||
.. _ElemLight:
|
||||
|
||||
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
|
||||
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.
|
||||
The number of lights is given by ``mjModel.nlight``.
|
||||
|
||||
.. _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
|
||||
kinematic tree.
|
||||
|
||||
.. _ElemTendon:
|
||||
|
||||
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
|
||||
multiple branches using pulleys.
|
||||
|
||||
.. _ElemActuator:
|
||||
|
||||
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
|
||||
turn mapped into a generalized force by the moment arms inferred from the transmission.
|
||||
|
||||
.. _ElemSensor:
|
||||
|
||||
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
|
||||
and instead has to be done programmatically, as illustrated in the code sample :ref:`simulate.cc <saSimulate>`.
|
||||
|
||||
.. _ElemEquality:
|
||||
|
||||
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
|
||||
tendons via a cubic polynomial; constrain the edges of a flex (i.e. deformable mesh) to their initial lengths.
|
||||
|
||||
.. _ElemFlex:
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
@@ -106,7 +106,7 @@ The default (and recommended) way to control the system is to implement a contro
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// simple controller applying damping to each dof
|
||||
// simple controller applying damping to each DOF
|
||||
void mycontroller(const mjModel* m, mjData* d) {
|
||||
if (m->nu == 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
|
||||
``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:
|
||||
|
||||
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