Add Signed Distance Field to collision geometries.

PiperOrigin-RevId: 557507088
Change-Id: I358a642407aee1ba8dfc9d405eb9a4f609435fe9
This commit is contained in:
Alessio Quaglino
2023-08-16 09:14:29 -07:00
committed by Copybara-Service
parent 6245edae28
commit fdb041580c
57 changed files with 3229 additions and 81 deletions
+51 -1
View File
@@ -1558,6 +1558,24 @@ The full list of processing steps applied by the compiler to each mesh is as fol
Reference orientation relative to which the 3D vertex coordinates and normals are defined. The conjugate of this
quaternion is used to rotate the positions and normals. The model compiler normalizes the quaternion automatically.
.. _mesh-plugin:
:el-prefix:`mesh/` |-| **plugin** (?)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Associate this mesh with an :ref:`engine plugin<exPlugin>`. Either :at:`plugin` or :at:`instance` are required.
.. _mesh-plugin-plugin:
:at:`plugin`: :at-val:`string, optional`
Plugin identifier, used for implicit plugin instantiation.
.. _mesh-plugin-instance:
:at:`instance`: :at-val:`string, optional`
Instance name, used for explicit plugin instantiation.
.. _asset-skin:
@@ -1977,6 +1995,16 @@ adjust it properly through the XML.
:at:`mpr_tolerance`: :at-val:`real, "1e-6"`
Tolerance threshold used for early termination of the MPR algorithm.
.. _option-sdf_iterations:
:at:`sdf_iterations`: :at-val:`int, "10"`
Number of iterations used for Signed Distance Field collisions (per initial point).
.. _option-sdf_initpoints:
:at:`sdf_initpoints`: :at-val:`int, "40"`
Number of starting points used for fining contacts with Signed Distance Field collisions.
.. _option-flag:
@@ -2513,7 +2541,7 @@ helps clarify the role of bodies and geoms in MuJoCo.
.. _body-geom-type:
:at:`type`: :at-val:`[plane, hfield, sphere, capsule, ellipsoid, cylinder, box, mesh], "sphere"`
:at:`type`: :at-val:`[plane, hfield, sphere, capsule, ellipsoid, cylinder, box, mesh, sdf], "sphere"`
Type of geometric shape. The keywords have the following meaning: The **plane** type defines a plane which is
infinite for collision detection purposes. It can only be attached to the world body or static children of the world.
The plane passes through a point specified via the pos attribute. It is normal to the Z axis of the geom's local
@@ -2576,6 +2604,11 @@ helps clarify the role of bodies and geoms in MuJoCo.
they are offset by the translation and rotation that were needed to center and align the mesh asset in its own
coordinate frame. Recall the discussion of centering and alignment in the :ref:`mesh <asset-mesh>` element.
The **sdf** type defines a signed distance field (SDF, also referred to as signed distance function). In order to
visualize the SDF, a custom mesh must be specified using the :ref:`mesh/plugin <mesh-plugin>` attribute. See the
`model/plugin/sdf/ <https://github.com/deepmind/mujoco/tree/main/model/plugin/sdf>`__ directory for example models
with SDF geometries. For more details regarding SDF plugins, see the :ref:`Extensions chapter<exWriting>`.
.. _body-geom-contype:
:at:`contype`: :at-val:`int, "1"`
@@ -2832,6 +2865,23 @@ helps clarify the role of bodies and geoms in MuJoCo.
:at:`user`: :at-val:`real(nuser_geom), "0 0 ..."`
See :ref:`CUser`.
.. _geom-plugin:
:el-prefix:`geom/` |-| **plugin** (?)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Associate this geom with an :ref:`engine plugin<exPlugin>`. Either :at:`plugin` or :at:`instance` are required.
.. _geom-plugin-plugin:
:at:`plugin`: :at-val:`string, optional`
Plugin identifier, used for implicit plugin instantiation.
.. _geom-plugin-instance:
:at:`instance`: :at-val:`string, optional`
Instance name, used for explicit plugin instantiation.
.. _body-site:
+29 -1
View File
@@ -167,6 +167,20 @@
| | | | :ref:`refpos<asset-mesh-refpos>` | :ref:`refquat<asset-mesh-refquat>` | :ref:`scale<asset-mesh-scale>` | :ref:`smoothnormal<asset-mesh-smoothnormal>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_2| mesh |br| |_2| |L| | | .. table:: |
| :ref:`plugin | \* | :class: mjcf-attributes |
| <mesh-plugin>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`plugin<mesh-plugin-plugin>` | :ref:`instance<mesh-plugin-instance>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_3| plugin |br| |_3| |L| | | .. table:: |
| :ref:`config | \* | :class: mjcf-attributes |
| <plugin-config>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`key<plugin-config-key>` | :ref:`value<plugin-config-value>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| asset |br| |_| |L| | | .. table:: |
| :ref:`skin | \* | :class: mjcf-attributes |
| <asset-skin>` | | |
@@ -212,7 +226,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`cone<option-cone>` | :ref:`jacobian<option-jacobian>` | :ref:`solver<option-solver>` | :ref:`iterations<option-iterations>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`noslip_iterations<option-noslip_iterations>` | :ref:`mpr_iterations<option-mpr_iterations>` | | | |
| | | | :ref:`noslip_iterations<option-noslip_iterations>` | :ref:`mpr_iterations<option-mpr_iterations>` | :ref:`sdf_iterations<option-sdf_iterations>` | :ref:`sdf_initpoints<option-sdf_initpoints>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| option |br| |_| |L| | | .. table:: |
@@ -313,6 +327,20 @@
| | | | :ref:`user<body-geom-user>` | | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_2| geom |br| |_2| |L| | | .. table:: |
| :ref:`plugin | \* | :class: mjcf-attributes |
| <geom-plugin>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`plugin<geom-plugin-plugin>` | :ref:`instance<geom-plugin-instance>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_3| plugin |br| |_3| |L| | | .. table:: |
| :ref:`config | \* | :class: mjcf-attributes |
| <plugin-config>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`key<plugin-config-key>` | :ref:`value<plugin-config-value>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| body |br| |_| |L| | | .. table:: |
| :ref:`site | \* | :class: mjcf-attributes |
| <body-site>` | | |
+14 -3
View File
@@ -8,15 +8,26 @@ Upcoming version (not yet released)
General
^^^^^^^
.. youtube:: Vc1tq0fFvQA
.. youtube:: QewlEqIZi1o
:align: right
:width: 240px
1. Added constraint island discovery in :ref:`mj_island`. Constraint islands are disjoint sets of constraints
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.
- Increased ``mjMAXCONPAIR`` to 100.
.. youtube:: Vc1tq0fFvQA
:align: right
:width: 240px
#. Added constraint island discovery in :ref:`mj_island`. Constraint islands are disjoint sets of constraints
and degrees-of-freedom that do not interact. In a future release the constraint solver will be refactored to
exploit the disjoint structure. Island discovery can be activated using a new :ref:`enable flag<option-flag-island>`
which will be removed after the refactor. If island discovery is enabled, geoms, contacts and
tendons will be colored according to the corresponding island, see video:
tendons will be colored according to the corresponding island, see video.
#. Added a new :ref:`dyntype<actuator-general-dyntype>`, ``filterexact``, which updates first-order filter states with
the exact formula rather than with Euler integration.
#. Added an actuator attribute, :ref:`actearly<actuator-general-actearly>`, which uses semi-implicit integration for
+22
View File
@@ -416,6 +416,7 @@ typedef enum mjtGeom_ { // type of geometric shape
mjGEOM_CYLINDER, // cylinder
mjGEOM_BOX, // box
mjGEOM_MESH, // mesh
mjGEOM_SDF, // signed distance field
mjNGEOMTYPES, // number of regular geom types
@@ -703,6 +704,10 @@ struct mjOption_ { // physics options
int mpr_iterations; // maximum number of MPR solver iterations
int disableflags; // bit flags for disabling standard features
int enableflags; // bit flags for enabling optional features
// sdf collision settings
int sdf_initpoints; // number of starting points for gradient descent
int sdf_iterations; // max number of iterations for gradient descent
};
typedef struct mjOption_ mjOption;
struct mjVisual_ { // visualization options
@@ -969,6 +974,7 @@ struct mjModel_ {
int* geom_matid; // material id for rendering; -1: none (ngeom x 1)
int* geom_group; // group for visibility (ngeom x 1)
int* geom_priority; // geom contact priority (ngeom x 1)
int* geom_plugin; // plugin instance id; -1: not in use (ngeom x 1)
mjtByte* geom_sameframe; // same as body frame (1) or iframe (2) (ngeom x 1)
mjtNum* geom_solmix; // mixing coef for solref/imp in geom pair (ngeom x 1)
mjtNum* geom_solref; // constraint solver reference: contact (ngeom x mjNREF)
@@ -1262,6 +1268,7 @@ typedef enum mjtPluginCapabilityBit_ {
mjPLUGIN_ACTUATOR = 1<<0, // actuator forces
mjPLUGIN_SENSOR = 1<<1, // sensor measurements
mjPLUGIN_PASSIVE = 1<<2, // passive forces
mjPLUGIN_SDF = 1<<3, // signed distance fields
} mjtPluginCapabilityBit;
struct mjpPlugin_ {
const char* name; // globally unique name identifying the plugin
@@ -1298,6 +1305,20 @@ struct mjpPlugin_ {
// called by mjv_updateScene (optional)
void (*visualize)(const mjModel*m, mjData* d, const mjvOption* opt, mjvScene* scn, int instance);
// methods specific to signed distance fields (optional)
// signed distance from the surface
mjtNum (*sdf_distance)(const mjtNum point[3], const mjData* d, int instance);
// gradient of distance with respect to local coordinates
void (*sdf_gradient)(mjtNum gradient[3], const mjtNum point[3], const mjData* d, int instance);
// called during compilation for marching cubes
mjtNum (*sdf_staticdistance)(const mjtNum point[3], const mjtNum* attributes);
// bounding box of implicit surface
void (*sdf_aabb)(mjtNum aabb[6], const mjtNum* attributes);
};
typedef struct mjpPlugin_ mjpPlugin;
typedef enum mjtGridPos_ { // grid position for overlay
@@ -1719,6 +1740,7 @@ typedef enum mjtVisFlag_ { // flags enabling model element visualization
mjVIS_SKIN, // skin
mjVIS_MIDPHASE, // mid-phase bounding volume hierarchy
mjVIS_MESHBVH, // mesh bounding volume hierarchy
mjVIS_SDFITER, // iterations of SDF gradient descent
mjNVISFLAG // number of visualization flags
} mjtVisFlag;
+51 -1
View File
@@ -84,6 +84,7 @@ supported plugin capabilities are:
* Actuator plugin
* Sensor plugin
* Passive force plugin
* Signed distance field plugin
Additional capabilities will be added in the future as required.
@@ -234,7 +235,7 @@ provided for this scan-and-load use case.
Writing plugins
^^^^^^^^^^^^^^^
This section, targeted at developers, is not yet written. We encourage people who wish to write their own plugins
This section, targeted at developers, is incomplete. We encourage people who wish to write their own plugins
to contact the MuJoCo development team for help. A good starting point for experienced developers is the
`associated tests <https://github.com/deepmind/mujoco/blob/main/test/engine/engine_plugin_test.cc>`_ and the first-party
plugins in the `first-party plugin directory <https://github.com/deepmind/mujoco/tree/main/plugin>`_.
@@ -247,6 +248,55 @@ A future version of this section will include:
* Things that developers need to keep in mind in order to ensure that plugins function correctly when :ref:`mjData` is
copied, stepped, or reset.
Currently, there are three directories of first-party plugins:
* **elasticity:** The plugins in the `elasticity/ <https://github.com/deepmind/mujoco/tree/main/plugin/elasticity>`__
directory are passive forces based on continuum mechanics for 1-dimensional and 3-dimensional bodies. The
1D model is invariant under rotations and captures the large deformation of elastic cables, decoupling twisting and
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.
* **sensor:** The plugins in the `sensor/ <https://github.com/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/deepmind/mujoco/blob/main/plugin/sensor/README.md>`__ for details.
* **sdf:** The plugins in the `sdf/ <https://github.com/deepmind/mujoco/tree/main/plugin/sdf>`__
directory specify custom shapes in a mesh-free manner, by defining methods computing a signed distance field and its
gradient at query points. This shape then acts as a new geom type in the collision table at the top of
`engine_collision_driver.c <https://github.com/deepmind/mujoco/blob/main/src/engine/engine_collision_driver.c>`__.
Collision points are found by minimizing the maximum of the two colliding SDFs via gradient descent.
Because SDFs are non-convex, multiple starting points are required in order to converge to multiple local minima.
The number of starting points is set using :ref:`sdf_initpoints<option-sdf_initpoints>`, and are
initialized using the Halton sequence inside the intersection of the axis-aligned bounding boxes.
The number of gradient descent iterations is set using :ref:`sdf_iterations<option-sdf_iterations>`.
While *exact* SDFs---encoding the precise signed distance to the surface---are preferred, collisions are possible with
any function whose value vanishes at the surface and grows monotonically away from it, with a negative sign in the
interior. For such functions, it is still possible to find collisons, albeit with a possibly
increased number of starting points.
The ``sdf_distance`` method is called by the compiler to produce a visual mesh for rendering using the marching cubes
algorithm implemented by `MarchingCubeCpp <https://github.com/aparis69/MarchingCubeCpp>`__.
Future improvement to the gradient descent algorithm, such as a line search which takes advantage of the properties of
SDFs, might reduce the number of iterations and/or starting points.
For the sdf plugin, the following methods need to be specified
``sdf_distance``:
Returns the signed distance of the query point given in local coordinates.
``sdf_staticdistance``:
This is the static version of the previous function, taking config attributes as additional inputs. This function is
required because mesh creation occurs during model compilation before the plugin object has been instantiated.
``sdf_gradient``:
Computes the gradient in local coodinates of the SDF at the query point.
``sdf_aabb``:
Computes the axis-aligned bounding box in local coordinates. This volume is voxelized uniformly before the call to
the marching cubes algorithm.
.. _exProvider:
Resource providers