diff --git a/doc/APIreference/functions.rst b/doc/APIreference/functions.rst index e2f922c7..d7b8db51 100644 --- a/doc/APIreference/functions.rst +++ b/doc/APIreference/functions.rst @@ -3572,8 +3572,8 @@ Construct quaternion performing rotation from z-axis to given vector. .. mujoco-include:: mju_mat2Rot -extract 3D rotation from an arbitrary 3x3 matrix by refining the input quaternion -returns the number of iterations required to converge +Extract 3D rotation from an arbitrary 3x3 matrix by refining the input quaternion. +Returns the number of iterations required to converge .. _mju_euler2Quat: diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 3daec8d9..3d878eff 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -3487,6 +3487,45 @@ saving the XML: radius in 2D, and tetrahedra with radius in 3D. Certain flexcomp types imply a dimensionality, in which case the value specified here is ignored. +.. youtube:: uNt3i8hrJu4 + :align: right + :width: 240px + +.. _body-flexcomp-dof: + +:at:`dof`: :at-val:`[full, radial, trilinear], "full"` + The parametrization of the flex's degrees of freedom (dofs). See the video on the right illustrating the + different parametrizations with deformable spheres. The three models in the video are respectively + `sphere_full `__, + `sphere_radial `__ + and `sphere_trilinear `__. + + **full** + Three translational dofs per vertex. This is the most expressive but also the most expensive option. + + **radial** + A single radial translational dof per vertex. Note that unlike in the "full" case, the radial parametrization + requires a free joint at the flex's parent in order for free body motion to be possible. This type of + parametrization is appropriate for shapes that are relatively spherical. + + **trilinear** + Three translational dofs at each corner of the bounding box of the flex, for a total of 24 dofs for the entire + flex, independent of the number of vertices. The positions of the vertices are updated using trilinear + interpolation over the bounding box. + + .. youtube:: qJFbx-FR7Bc + :align: right + :width: 240px + + Trilinear flexes are much faster than the previous two options, and are the preferred choice if the expected + deformations can be captured by the reduced parametriation. For example, see the video on the right comparing `full + `__ and `trilinear + `__ flexes for modeling + deformable gripper pads. + + Note that the choice of dof parametrization affects the deformation modes of the flex but has no effect on the + accuracy of the collision geometry, which always takes into account the high-resolution mesh of the flex. + .. _body-flexcomp-type: :at:`type`: :at-val:`[grid, box, cylinder, ellipsoid, disc, circle, mesh, gmsh, direct], "grid"` @@ -4081,6 +4120,12 @@ cases, the user will specify a :el:`flexcomp` which will then automatically cons Integer group to which the flex belongs. This attribute can be used for custom tags. It is also used by the visualizer to enable and disable the rendering of entire groups of flexes. +.. _deformable-flex-node: + +:at:`node`: :at-val:`string(nnode), optional` + The degrees-of-freedom of the flex. + An array of MuJoCo body names (separated by white space) to which each node belongs. The number of body names + should equal the number of nodes (nnode). See the flexcomp :ref:`dof` attribute for more details. .. _flex-edge: diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index b3bbc567..f18ef816 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -435,17 +435,17 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`name` | :ref:`type` | :ref:`group` | :ref:`dim` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`count` | :ref:`spacing` | :ref:`radius` | :ref:`rigid` | | +| | | | :ref:`dof` | :ref:`count` | :ref:`spacing` | :ref:`radius` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`mass` | :ref:`inertiabox` | :ref:`scale` | :ref:`file` | | +| | | | :ref:`rigid` | :ref:`mass` | :ref:`inertiabox` | :ref:`scale` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`point` | :ref:`element` | :ref:`texcoord` | :ref:`material` | | +| | | | :ref:`file` | :ref:`point` | :ref:`element` | :ref:`texcoord` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`rgba` | :ref:`flatskin` | :ref:`pos` | :ref:`quat` | | +| | | | :ref:`material` | :ref:`rgba` | :ref:`flatskin` | :ref:`pos` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`axisangle` | :ref:`xyaxes` | :ref:`zaxis` | :ref:`euler` | | +| | | | :ref:`quat` | :ref:`axisangle` | :ref:`xyaxes` | :ref:`zaxis` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`origin` | | | | | +| | | | :ref:`euler` | :ref:`origin` | | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_2| flexcomp |br| |_2| |L| | | .. table:: | @@ -509,7 +509,7 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`material` | :ref:`rgba` | :ref:`flatskin` | :ref:`body` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`vertex` | :ref:`element` | :ref:`texcoord` | | | +| | | | :ref:`vertex` | :ref:`element` | :ref:`texcoord` | :ref:`node` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_2| flex |br| |_2| |L| | | .. table:: | diff --git a/doc/changelog.rst b/doc/changelog.rst index 7c9efba4..4d16a788 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -5,8 +5,27 @@ Changelog Upcoming version (not yet released) ----------------------------------- + +Feature promotion +^^^^^^^^^^^^^^^^^ +.. youtube:: qJFbx-FR7Bc + :align: right + :width: 240px + +- Introduced a new kind of **fast deformable body**, activated by setting :ref:`flexcomp/dof` to + "trilinear". This type of :ref:`deformable` flex object has the same collision geometry as a regular + flex, but has far fewer degrees of freedom. Instead of 3 dofs per vertex, only the corners of the bounding box are + free to move, with the positions of the interior vertices computed with trilinear interpolation of the 8 corners, for + a total of 24 dofs for the entire flex object (or less, if some of the corners are pinned). This limits the types of + deformation achievable by the flex, but allows for much faster simulation. For example, see the video on the right + comparing `full `__ and `trilinear + `__ flexes for modeling + deformable gripper pads. + General ^^^^^^^ +- Separate collision and deformation meshes for :ref:`flex`. This enables a fixed cost for the soft + body computations, while preserving the fidelity of high-resolution collisions. - Added :ref:`mjs_setDeepCopy` API function. When the deep copy flag is 0, attaching a model will not copy it to the parent, so the original references to the child can be used to modify the parent after attachment. The default behavior is to perform such a shallow copy. The old behavior of creating a deep copy of the child model while diff --git a/doc/includes/references.h b/doc/includes/references.h index 74d6778c..dcb3f22d 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -901,6 +901,7 @@ struct mjModel_ { int ncam; // number of cameras int nlight; // number of lights int nflex; // number of flexes + int nflexnode; // number of dofs in all flexes int nflexvert; // number of vertices in all flexes int nflexedge; // number of edges in all flexes int nflexelem; // number of elements in all flexes @@ -1153,6 +1154,9 @@ struct mjModel_ { int* flex_dim; // 1: lines, 2: triangles, 3: tetrahedra (nflex x 1) int* flex_matid; // material id for rendering (nflex x 1) int* flex_group; // group for visibility (nflex x 1) + int* flex_interp; // interpolation (0: vertex, 1: nodes) (nflex x 1) + int* flex_nodeadr; // first node address (nflex x 1) + int* flex_nodenum; // number of nodes (nflex x 1) int* flex_vertadr; // first vertex address (nflex x 1) int* flex_vertnum; // number of vertices (nflex x 1) int* flex_edgeadr; // first edge address (nflex x 1) @@ -1166,6 +1170,7 @@ struct mjModel_ { int* flex_evpairadr; // first evpair address (nflex x 1) int* flex_evpairnum; // number of evpairs (nflex x 1) int* flex_texcoordadr; // address in flex_texcoord; -1: none (nflex x 1) + int* flex_nodebodyid; // node body ids (nflexnode x 1) int* flex_vertbodyid; // vertex body ids (nflexvert x 1) int* flex_edge; // edge vertex ids (2 per edge) (nflexedge x 2) int* flex_elem; // element vertex ids (dim+1 per elem) (nflexelemdata x 1) @@ -1175,6 +1180,8 @@ struct mjModel_ { int* flex_evpair; // (element, vertex) collision pairs (nflexevpair x 2) mjtNum* flex_vert; // vertex positions in local body frames (nflexvert x 3) mjtNum* flex_vert0; // vertex positions in qpos0 on [0, 1]^d (nflexvert x 3) + mjtNum* flex_node; // node positions in local body frames (nflexnode x 3) + mjtNum* flex_node0; // Cartesian node positions in qpos0 (nflexnode x 3) mjtNum* flexedge_length0; // edge lengths in qpos0 (nflexedge x 1) mjtNum* flexedge_invweight0; // edge inv. weight in qpos0 (nflexedge x 1) mjtNum* flex_radius; // radius around primitive element (nflex x 1) @@ -1983,7 +1990,9 @@ typedef struct mjsFlex_ { // flex specification double thickness; // thickness (2D only) // mesh properties + mjStringVec* nodebody; // node body names mjStringVec* vertbody; // vertex body names + mjDoubleVec* node; // node positions mjDoubleVec* vert; // vertex positions mjIntVec* elem; // element vertex ids mjFloatVec* texcoord; // vertex texture coordinates @@ -2968,6 +2977,10 @@ struct mjvSceneState_ { int* flex_dim; int* flex_matid; int* flex_group; + int* flex_interp; + int* flex_nodeadr; + int* flex_nodenum; + int* flex_nodebodyid; int* flex_vertadr; int* flex_vertnum; int* flex_elem; @@ -2981,6 +2994,8 @@ struct mjvSceneState_ { int* flex_texcoordadr; int* flex_bvhadr; int* flex_bvhnum; + mjtByte* flex_centered; + mjtNum* flex_node; mjtNum* flex_radius; float* flex_rgba; diff --git a/doc/modeling.rst b/doc/modeling.rst index ac48c614..b34eae4e 100644 --- a/doc/modeling.rst +++ b/doc/modeling.rst @@ -1335,9 +1335,7 @@ improved realism and accuracy. The edge-based model could be seen as a "lumped" 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 `__ of the material. For more details, see the `Saint Venant-Kirchhoff -`__ hyperelastic model. This -functionality is currently based on first-party :ref:`engine plugins` as of MuJoCo 3.0 but may be integrated -into the engine in future releases. +`__ hyperelastic model. **Creation and visualization**. @@ -1345,20 +1343,12 @@ into the engine in future releases.