Add flex and elasticity documentation. Fixes #873.

PiperOrigin-RevId: 574179040
Change-Id: Iaf90bbf2b2c3fe075c940c2b66b7b841f256e653
This commit is contained in:
Alessio Quaglino
2023-10-17 09:44:58 -07:00
committed by Copybara-Service
parent db067a3b94
commit 139a8ae298
11 changed files with 825 additions and 375 deletions
+631 -306
View File
File diff suppressed because it is too large Load Diff
+34 -22
View File
@@ -8,27 +8,47 @@ Upcoming version (not yet released)
New features
^^^^^^^^^^^^
.. youtube:: Vc1tq0fFvQA
:align: right
:width: 240px
1. Added constraint island discovery with :ref:`mj_island`. Constraint islands are disjoint sets of constraints
and degrees-of-freedom that do not interact. The only solver which currently supports islands is
:ref:`CG<option-solver>`. Island discovery can be activated using a new :ref:`enable flag<option-flag-island>`.
If island discovery is enabled, geoms, contacts and tendons will be colored according to the corresponding island,
see video.
.. youtube:: QewlEqIZi1o
:align: right
:width: 240px
2. Added new signed distance field (SDF) collision primitive. SDFs can take any shape and are not constrained to be
1. Added new signed distance field (SDF) collision primitive. SDFs can take any shape and are not constrained to be
convex. Collision points are found by minimizing the maximum of the two colliding SDFs via gradient descent.
- Added new SDF plugin for defining implicit geometries. The plugin must define methods computing an SDF and its
gradient at query points. See the :ref:`documentation<exWriting>` for more details.
3. Added :ref:`mjThreadPool` and :ref:`mjTask` which allow for multi-threaded operations within the MuJoCo engine
.. youtube:: ra2bTiZHGlw
:align: right
:width: 240px
2. Added new low-level model element called ``flex``, used to define deformable objects. These
`simplicial complexes <https://en.wikipedia.org/wiki/Simplicial_complex>`__ can be of dimension 1, 2
or 3, corresponding to stretchable lines, triangles or tetrahedra. Two new MJCF elements are used
to define flexes. The top-level :ref:`deformable<deformable>` section contains the low-level flex definition.
The :ref:`flexcomp<body-flexcomp>` element, similar to :ref:`composite<body-composite>` is a convenience macro for
creating deformables, and supports the GMSH tetrahedral file format.
- Added `shell <https://github.com/deepmind/mujoco/blob/main/plugin/elasticity/shell.cc>`__ passive force plugin,
computing bending forces using a constant precomputed Hessian (cotangent operator).
**Note**: This feature is still under development and subject to change. In particular, deformable object
functionality is currently available both via :ref:`deformable<CDeformable>` and :ref:`composite<CComposite>`,
and both are modifiable by the first-party
`elasticity plugins <https://github.com/google-deepmind/mujoco/tree/main/plugin/elasticity>`__. We expect some of
this functionallity to be unified in the future.
.. youtube:: Vc1tq0fFvQA
:align: right
:width: 240px
3. Added constraint island discovery with :ref:`mj_island`. Constraint islands are disjoint sets of constraints
and degrees-of-freedom that do not interact. The only solver which currently supports islands is
:ref:`CG<option-solver>`. Island discovery can be activated using a new :ref:`enable flag<option-flag-island>`.
If island discovery is enabled, geoms, contacts and tendons will be colored according to the corresponding island,
see video.
4. Added :ref:`mjThreadPool` and :ref:`mjTask` which allow for multi-threaded operations within the MuJoCo engine
pipeline. If engine-internal threading is enabled, the following operations will be multi-threaded:
- Island constraint resolution, if island discovery is :ref:`enabled<option-flag-island>` and the
@@ -40,16 +60,8 @@ New features
Engine-internal threading is a work in progress and currently only available in first-party code via the
:ref:`testspeed<saTestspeed>` utility, exposed with the ``npoolthread`` flag.
.. youtube:: ra2bTiZHGlw
:align: right
:width: 240px
4. Added capability to initialize :ref:`composite<body-composite>` particles with arbitrary positions.
5. Added `shell <https://github.com/deepmind/mujoco/blob/main/plugin/elasticity/shell.cc>`__ passive force plugin:
- Collisions use spheres located at mesh vertices.
- Stretching as tendon constraints and bending using a constant precomputed Hessian (cotangent operator).
5. Added capability to initialize :ref:`composite<body-composite>` particles from OBJ files. Fixes :github:issue:`642`
and :github:issue:`674`.
General
^^^^^^^
Binary file not shown.

After

Width:  |  Height:  |  Size: 488 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

+141 -45
View File
@@ -1069,6 +1069,14 @@ has 1000 bodies (each with a geom), 3000 degrees of freedom and around 1000 acti
takes around 1 ms on a single core of a modern processor. As with most other MuJoCo models, the soft constraints allow
simulation at much larger timesteps (this model is stable at 30 ms timestep and even higher).
Particles are also compatible with the passive forces 2D and 3D plugins, discussed in the :ref:`deformable
<CDeformable>` section. However, collisions are limited to the particle themselves and not to the whole boundary of the
skin that encloses them. This makes contacts very fast but does not guarantee that all penetrations can be avoided. For
a more complete treatment, see again the :ref:`deformable <CDeformable>` section, which outlines how to use
:ref:`flexcomp<body-flexcomp>` to create such an object. It is easy to port models create with composite particles to
flex, see the folder `elasticity/ <https://github.com/google-deepmind/mujoco/tree/main/model/plugin/elasticity>`__ for
several examples.
**1D grid**.
|image6| |image7|
@@ -1111,59 +1119,51 @@ coordinates. The plot on the right shows a cloth pinned to the world body at the
capsule probe. The skin on the right is subdivided using bi-cubic interpolation, which increases visual quality in the
absence of textures. When textures are present (left) the benefits of subdivision are less visible.
**Rope and loop**.
**Cable**.
|image10| |image11|
|coil|
.. code-block:: xml
<body name="B10" pos="0 0 1">
<freejoint/>
<composite type="rope" count="21 1 1" spacing="0.04" offset="0 0 2">
<joint kind="main" damping="0.005"/>
<geom type="capsule" size=".01 .015" rgba=".8 .2 .1 1"/>
</composite>
</body>
<extension>
<plugin plugin="mujoco.elasticity.cable"/>
</extension>
The remaining composite object types create kinematic trees of element bodies, and the parent body becomes the root of
the tree. This is why :el:`composite` appears inside a moving body, and not inside the world body as in particle and
grid objects. If it appeared inside the world body, the root of the composite object would not move. Unlike grids and
particles, the orientation of the element bodies here can change. The kinematic tree is constructed using (mostly)
hinge joints. In the case of rope and loop objects illustrated here, the tree is a chain. Note the naming of the
parent body. This name must correspond to one of the automatically-generated names of the element bodies. This
mechanism is used to specify where the composite object should attach to the parent. Compared to 1D grids, the rope
and loop are less jittery and can use capsule and ellipsoid geoms in addition to spheres (thus filling the gaps for
collision detection). However this comes at a price. Because we have long kinematic chains, the resulting differential
equations become stiff and can no longer be integrated at large timesteps. The examples we provide illustrate
comfortable timesteps where the models are stable. The rope can be easily tied into a knot using mouse perturbations,
as shown in the left plot. Using a larger number of smaller elements makes knots and other manipulations even easier.
The loop is similar to a rope but the first and last element bodies are connected with an equality constraint.
<worldbody>
<composite prefix="actuated" type="cable" curve="cos(s) sin(s) s" count="41 1 1"
size="0.25 .1 4" offset="0.25 0 .05" initial="none">
<plugin plugin="mujoco.elasticity.cable">
<!--Units are in Pa (SI)-->
<config key="twist" value="5e8"/>
<config key="bend" value="15e8"/>
<config key="vmax" value="0"/>
</plugin>
<joint kind="main" damping="0.15" armature="0.01"/>
<geom type="capsule" size=".005" rgba=".8 .2 .1 1"/>
</composite>
</worldbody>
The cable simulates an inextensible elastic 1D object having twist and bending stiffness. It is discretized using a
sequence of capsules or boxes. Its stiffness and inertia properties are computed directly from the given parameters and
the shape of the cross section, which allows for anisotropic behaviors, which can be found in e.g. belts or computer
cables. It is a single kinematic tree, so it is exactly inextensible without the use of additional constraints, enabling
the use of large time steps. The elastic model is geometrically exact and based on computing the Bishop or twist-free
frame of the centerline, i.e., the line passing through the center of the cross section. The orientations of the geoms
are expressed with respect to this frame and then decomposed into twist and bending components, hence different
stiffnesses can be set independently. Moreover, it is possible to specify if the stress-free configuration is flat or
curve, such as in the case of coil springs. The cable requires using a first-party :ref:`engine plugin<exPlugin>`, which
may be integrated directly into the engine in the future.
**Rope and loop**.
The rope and loop are deprecated. It is recommended to use the cable for simulating inextensible elastic rods that are
bent and twisted and 1D flex :ref:`deformable objects <CDeformable>` for extensible strings in a tensile loading
scenario (e.g. a stretched rubber band).
**Cloth**.
|image12| |image13|
.. code-block:: xml
<body name="B3_5" pos="0 0 1">
<freejoint/>
<composite type="cloth" count="9 9 1" spacing="0.05" flatinertia="0.01">
<joint kind="main" damping="0.001"/>
<skin material="matcarpet" texcoord="true" inflate="0.005" subgrid="2"/>
<geom type="capsule" size="0.015 0.01" rgba=".8 .2 .1 1"/>
</composite>
</body>
The cloth type is an alternative to a 2D grid, and has somewhat different properties. Similar to rope vs. 1D grid, the
cloth is less jittery than a 2D grid and can also fill collision holes better. This is done by using capsules or
ellipsoids, and arranging them in the pattern shown on the right. The geom capsules are shown in red, the kinematic
tree in thick blue, the equality-constrained tendons holding the cloth together in thin gray, and the joints in cyan.
The element body corresponding to the parent body has a floating joint rendered as a cube, while the rest of the tree
is constructed using pairs of hinge joints that form universal joints. Note the naming of the parent body: similar to
rope, it must coincide with one of the automatically-generated element body names in the composite object. Explicit
pinning is not possible. However if the parent is a static body, the cloth is essentially pinned but only at one
point. Similar to rope, the cloth object involves long kinematic chains that require relatively small timesteps and
some damping for stable integration. The parameters can be found in the XML model files in the software distribution.
The cloth is deprecated. It is recommended to use 2D flex :ref:`deformable objects <CDeformable>` for simulating thin
elastic structures.
**Box**.
@@ -1222,6 +1222,94 @@ of the system making it softer or harder, damped or springy, etc. Note that box,
involve long kinematic chains, and can be simulated at large timesteps - similar to particle and grid, and unlike rope
and cloth.
.. _CDeformable:
Deformable objects
~~~~~~~~~~~~~~~~~~
The :ref:`composite objects <CComposite>` described earlier were intended to emulate soft bodies in what is effectively
a rigid-body simulator. This was possible because MuJoCo constraints are soft, but nevertheless it was limited in
functionality and modeling power. In MuJoCo 3.0 we have introduced true deformable objects involving new model elements.
The :ref:`skin<deformable-skin>` described earlier was actually one such element, but it is merely used for
visualization. We now have a related element :ref:`flex<deformable-flex>` which generates contact forces, constraint
forces and passive forces as needed to model a wide range of deformable entities. Both skins and flexes are now defined
within a new grouping element in the XML called :ref:`deformable<deformable>`. A flex is a low-level element that
specifies everything needed at runtime, but is difficult to design at modeling time. To aid with modeling, we have
further introduced the element :ref:`flexcomp<body-flexcomp>` which automates the creation of the low-level flex,
similar to how :ref:`composite<body-composite>` automates the creation of (collections of) MuJoCo objects needed to
emulate a soft body. Flexes may eventually supersede composites, but for now both are useful for somewhat different
purposes.
A flex is a collection of MuJoCo bodies that are connected with massless stretchable elements. These elements can be
capsules (1D flex), triangles (2D flex), or tetrahedra (3D flex). In all cases we allow a radius, which makes the
elements smooth and also volumetric in 1D and 2D. The primitive elements are illustrated below:
|flexelem|
Thus far these look like geoms. But the key difference is that they deform: as the bodies (vertices) move independently
of each other, the shape of the elements changes in real time. Collisions and contact forces are now generalized to
handle these deformable geometric elements. Note that when two such elements collide, the contact no longer involves
just two bodies, but can involve up to 8 bodies (if both elements are tetrahedra). Contact forces are computed as
before, given the contact frame and relevant quantities expressed in that frame. But then the contact force is
distributed among all interacting bodies. The notion of contact Jacobian is complicated because the contact point cannot
be considered fixed in any body frame. Instead we use a weighting scheme to "assign" each contact point to multiple
bodies. It is also possible to create a rigid flex, by assigning all vertices to the same body. This is a way to
re-purpose the new flex collision machinery to implement rigid non-convex mesh collisions (unlike mesh geoms which are
convexified for collision purposes).
**Deformation model**.
In order to preserve the shape of the flex (in a soft sense), we need to generate passive or constraint forces. Prior to
MuJoCo 3.0 this would involve a large number of tendons plus constraints on tendons and joints. This is still possible
here, but inefficient both in terms of modeling and in terms of simulation when the flex is large. Instead, the design
philosophy is to use a single set of parameters and provide two modeling choices: a new (soft) equality constraint type
that applies to all edges of a given flex, which permits large time steps, or a discretized continuum representation,
where each element is in a constant stress state, which is equivalent to piecewise linear finite elements and achieves
improved realism and accuracy. The edge-based model could be seen as a "lumped" stiffness model, where the correct
coupling of deformation modes (e.g. shear and volumetric) is averaged in a single quantity. The continuum model enables
instead to specify shear and volumetic stiffnesses separately using the `Poisson's ratio
<https://en.wikipedia.org/wiki/Poisson%27s_ratio>`__ of the material. For more details, see the `Saint Venant-Kirchhoff
<https://en.wikipedia.org/wiki/Hyperelastic_material#Saint_Venant%E2%80%93Kirchhoff_model>`__ hyperelastic model. This
functionality is currently based on first-party :ref:`engine plugins<exPlugin>` as of MuJoCo 3.0 but may be integrated
into the engine in future releases.
**Creation and visualization**.
.. code-block:: xml
<extension>
<plugin plugin="mujoco.elasticity.solid"/>
</extension>
<worldbody>
<flexcomp type="grid" count="24 4 4" spacing=".1 .1 .1" pos=".1 0 1.5"
radius=".0" rgba="0 .7 .7 1" name="softbody" dim="3" mass="7">
<contact condim="3" solref="0.01 1" solimp=".95 .99 .0001" selfcollide="none"/>
<edge damping="1"/>
<plugin plugin="mujoco.elasticity.solid">
<config key="poisson" value="0.2"/>
<!--Units are in Pa (SI)-->
<config key="young" value="5e4"/>
</plugin>
</flexcomp>
</worldbody>
Using the :ref:`flexcomp<body-flexcomp>` element, we can create flexes from meshes, including tetrahedral meshes, and
automatically generate all the bodies/vertices and connect them with suitable elements. We can also create grids and
other topologies automatically. This machinery makes it easy to create very large flexes, involving thousands or even
tens of thousands of bodies, elements and edges. Obviously such simulations will not be fast. Even for medium-sized
flexes, pruning of collision pairs and essential. This is why we have developed elaborate methods for pruning
self-collisions; see XML reference.
In case of 3D flexes made of tetrahedra, it may be useful to examine how the flex is "triangulated" internally. We have
a special visualization mode that peels off the outer layers. Below is an example with the Stanford Bunny. Note how it
has smaller tetrahedra on the outside and larger ones on the inside. This mesh design makes sense, because we want the
collision surface to be accurate, but on the inside we just need soft material properties - which require less spatial
resolution.
|bunny1| |bunny2|
.. _CInclude:
Including files
@@ -1562,3 +1650,11 @@ in a visible way, and the energy fluctuates around the initial value instead of
:height: 250px
.. |particle| image:: images/models/particle.gif
:width: 270px
.. |flexelem| image:: images/modeling/flexelem.png
:width: 400px
.. |bunny1| image:: images/modeling/bunny1.png
:width: 300px
.. |bunny2| image:: images/modeling/bunny2.png
:width: 300px
.. |coil| image:: images/modeling/coil.png
:width: 300px
+8
View File
@@ -588,6 +588,14 @@ available equality constraint types are: connect two bodies at a point (creating
tree); weld two bodies together; make two surfaces slide on each other; fix the position of a joint or tendon; couple
the positions of two joints or two tendons via a cubic polynomial.
Deformable
^^^^^^^^^^
These are collections of massless stretchable geometric elements (capsules, triangles or tetrahedra) connecting vertices
that are defined within different moving body frames. These stretchable elements support collisions and contact forces,
which are then distributed to all the interconnected bodies. Flexes also generate passive and constraint forces as
needed to simulate deformable entities with the desired material properties.
Contact pair
^^^^^^^^^^^^
+1
View File
@@ -256,6 +256,7 @@ Currently, there are three directories of first-party plugins:
bending strains. The 3D solid is a
`Saint Venant-Kirchhoff <https://en.wikipedia.org/wiki/Hyperelastic_material#Saint_Venant%E2%80%93Kirchhoff_model>`__
model discretized with piecewise linear finite elements, which is suitable for large deformations with small strains.
See also :ref:`composite <CComposite>` and :ref:`deformable <CDeformable>` objects.
* **sensor:** The plugins in the `sensor/ <https://github.com/google-deepmind/mujoco/tree/main/plugin/sensor>`__
directory implement custom sensors. Currently the sole sensor plugin is the touch grid sensor, see the
`README <https://github.com/google-deepmind/mujoco/blob/main/plugin/sensor/README.md>`__ for details.
+4 -1
View File
@@ -38,7 +38,7 @@
<default class="body">
<!-- geoms -->
<geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".015 1" material="body"/>
<geom type="capsule" condim="1" friction=".7" solimp=".9 .99 .003" solref=".003 1" material="body"/>
<default class="thigh">
<geom size=".06"/>
</default>
@@ -116,6 +116,9 @@
<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="neck">
<geom type="cylinder" size=".03" fromto="0 0 .07 0 0 .1"/>
</body>
<body name="waist_lower" pos="-.01 0 -.26">
<geom name="waist_lower" fromto="0 -.06 0 0 .06 0" size=".06"/>
<body name="pelvis" pos="0 0 -.165">
+6 -1
View File
@@ -30,11 +30,15 @@
<global offwidth="800" offheight="800"/>
</visual>
<default>
<geom solref="0.003 1"/>
</default>
<worldbody>
<light directional="false" diffuse=".2 .2 .2" specular="0 0 0" pos="0 0 5" dir="0 0 -1"/>
<flexcomp name="f1" type="direct" rgba=".8 .2 .2 1" radius="0.01" dim="2" pos="0 0 2"
mass="3"
mass="1"
point="0 0 0
-1 1 0
-0.875 1 0
@@ -1414,6 +1418,7 @@
398 399 418
398 376 378">
<edge equality="true" damping="0.1"/>
<contact solref="0.003"/>
<plugin plugin="mujoco.elasticity.shell">
<config key="poisson" value="0"/>
<config key="thickness" value="8e-3"/>