Introduce trilinear flex parametrization.

These flexes use only 24 DOFs (3 per vertex of the bounding box), while colliding with the full high resolution mesh.

On an 8x8x8 cube, the performance using DOFs at all vertices is

```
 Simulation time      : 18.74 s
 Steps per second     : 533
 Realtime factor      : 0.53 x
 Time per step        : 1874.4 µs

 Contacts per step    : 114.88
 Constraints per step : 3322.51
 Degrees of freedom   : 1536
```

With the new implementation, it is the following:

```
 Simulation time      : 1.82 s
 Steps per second     : 5507
 Realtime factor      : 5.51 x
 Time per step        : 181.6 µs

 Contacts per step    : 38.84
 Constraints per step : 155.36
 Degrees of freedom   : 24
```

PiperOrigin-RevId: 721008829
Change-Id: I833df027527db578d86667cc4b24295bcf6f7d22
This commit is contained in:
Alessio Quaglino
2025-01-29 09:37:37 -08:00
committed by Copybara-Service
parent 1a4b821b6b
commit 7cdf180641
47 changed files with 8967 additions and 96 deletions
+9
View File
@@ -29,6 +29,7 @@
#define mjMAXIMP 0.9999 // maximum constraint impedance
#define mjMAXCONPAIR 50 // maximum number of contacts per geom pair
#define mjMAXTREEDEPTH 50 // maximum bounding volume hierarchy depth
#define mjMAXFLEXNODES 27 // maximum number of flex nodes
//---------------------------------- sizes ---------------------------------------------------------
@@ -43,6 +44,7 @@
#define mjNSOLVER 200 // size of one mjData.solver array
#define mjNISLAND 20 // number of mjData.solver arrays
//---------------------------------- enum types (mjt) ----------------------------------------------
typedef enum mjtDisableBit_ { // disable default feature bitflags
@@ -607,6 +609,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
@@ -859,6 +862,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)
@@ -872,6 +878,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)
@@ -881,6 +888,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)
+2
View File
@@ -439,7 +439,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
+6
View File
@@ -516,6 +516,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;
@@ -529,6 +533,8 @@ struct mjvSceneState_ {
int* flex_texcoordadr;
int* flex_bvhadr;
int* flex_bvhnum;
mjtByte* flex_centered;
mjtNum* flex_node;
mjtNum* flex_radius;
float* flex_rgba;
+8 -1
View File
@@ -81,6 +81,7 @@
XMJV( ncam ) \
XMJV( nlight ) \
XMJV( nflex ) \
X ( nflexnode ) \
XMJV( nflexvert ) \
X ( nflexedge ) \
X ( nflexelem ) \
@@ -326,6 +327,9 @@
XMJV( int, flex_dim, nflex, 1 ) \
XMJV( int, flex_matid, nflex, 1 ) \
XMJV( int, flex_group, nflex, 1 ) \
XMJV( int, flex_interp, nflex, 1 ) \
XMJV( int, flex_nodeadr, nflex, 1 ) \
XMJV( int, flex_nodenum, nflex, 1 ) \
XMJV( int, flex_vertadr, nflex, 1 ) \
XMJV( int, flex_vertnum, nflex, 1 ) \
X ( int, flex_edgeadr, nflex, 1 ) \
@@ -339,6 +343,7 @@
X ( int, flex_evpairadr, nflex, 1 ) \
X ( int, flex_evpairnum, nflex, 1 ) \
XMJV( int, flex_texcoordadr, nflex, 1 ) \
XMJV( int, flex_nodebodyid, nflexnode, 1 ) \
X ( int, flex_vertbodyid, nflexvert, 1 ) \
X ( int, flex_edge, nflexedge, 2 ) \
XMJV( int, flex_elem, nflexelemdata, 1 ) \
@@ -348,6 +353,8 @@
X ( int, flex_evpair, nflexevpair, 2 ) \
X ( mjtNum, flex_vert, nflexvert, 3 ) \
X ( mjtNum, flex_vert0, nflexvert, 3 ) \
XMJV( mjtNum, flex_node, nflexnode, 3 ) \
X ( mjtNum, flex_node0, nflexnode, 3 ) \
X ( mjtNum, flexedge_length0, nflexedge, 1 ) \
X ( mjtNum, flexedge_invweight0, nflexedge, 1 ) \
XMJV( mjtNum, flex_radius, nflex, 1 ) \
@@ -358,7 +365,7 @@
X ( mjtByte, flex_edgeequality, nflex, 1 ) \
X ( mjtByte, flex_rigid, nflex, 1 ) \
X ( mjtByte, flexedge_rigid, nflexedge, 1 ) \
X ( mjtByte, flex_centered, nflex, 1 ) \
XMJV( mjtByte, flex_centered, nflex, 1 ) \
XMJV( mjtByte, flex_flatskin, nflex, 1 ) \
XMJV( int, flex_bvhadr, nflex, 1 ) \
XMJV( int, flex_bvhnum, nflex, 1 ) \
+2 -2
View File
@@ -1125,8 +1125,8 @@ MJAPI void mju_quatIntegrate(mjtNum quat[4], const mjtNum vel[3], mjtNum scale);
// Construct quaternion performing rotation from z-axis to given vector.
MJAPI void mju_quatZ2Vec(mjtNum quat[4], const mjtNum vec[3]);
// 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
MJAPI int mju_mat2Rot(mjtNum quat[4], const mjtNum mat[9]);
// Convert sequence of Euler angles (radians) to quaternion.