Add vertcollide option for adding spheres at flex vertices.

PiperOrigin-RevId: 757789990
Change-Id: I8ccba52b13e8c02a7be78f992297d6f414d98f8e
This commit is contained in:
Alessio Quaglino
2025-05-12 09:12:44 -07:00
committed by Copybara-Service
parent 09bf5409ab
commit d77126dc58
8 changed files with 1480 additions and 11 deletions
+10 -2
View File
@@ -3554,6 +3554,7 @@ saving the XML:
.. _flexcomp-contact-internal:
.. _flexcomp-contact-selfcollide:
.. _flexcomp-contact-vertcollide:
.. _flexcomp-contact-activelayers:
.. _flexcomp-contact-contype:
.. _flexcomp-contact-conaffinity:
@@ -3567,8 +3568,8 @@ saving the XML:
.. _flexcomp-contact-gap:
.. |body/flexcomp/contact attrib list| replace::
:at:`internal`, :at:`selfcollide`, :at:`activelayers`, :at:`contype`, :at:`conaffinity`, :at:`condim`,
:at:`priority`, :at:`friction`, :at:`solmix`, :at:`solimp`, :at:`margin`, :at:`gap`
:at:`internal`, :at:`selfcollide`, :at:`vertcollide`, :at:`activelayers`, :at:`contype`, :at:`conaffinity`,
:at:`condim`, :at:`priority`, :at:`friction`, :at:`solmix`, :at:`solimp`, :at:`margin`, :at:`gap`
|body/flexcomp/contact attrib list|
Same as in :ref:`flex/contact<flex-contact>`. All attributes are passed through to the automatically-generated flex.
@@ -4086,6 +4087,13 @@ extensions specific to flexes.
**sap** in 1D and 2D, and **bvh** in 3D. Which strategy performs better depends on the specifics of the model. The
automatic setting is just a simple rule which we have found to perform well in general.
.. _flex-contact-vertcollide:
:at:`vertcollide`: :at-val:`[true, false], "false"`
Enables or disables vertex collisions. if **true**, spherical geoms are added at the vertices of flex, with radius
equal to the radius of the flex. These geoms can collide with other geoms and are not visible by default. If
**false**, no additional geoms are added.
.. _flex-contact-activelayers:
:at:`activelayers`: :at-val:`int(1), "1"`
+2 -2
View File
@@ -452,7 +452,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`margin<flexcomp-contact-margin>` | :ref:`gap<flexcomp-contact-gap>` | :ref:`internal<flexcomp-contact-internal>` | :ref:`selfcollide<flexcomp-contact-selfcollide>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`activelayers<flexcomp-contact-activelayers>` | | | | |
| | | | :ref:`activelayers<flexcomp-contact-activelayers>` | :ref:`vertcollide<flexcomp-contact-vertcollide>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_2| flexcomp |br| |_2| |L| | | .. table:: |
@@ -502,7 +502,7 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`margin<flex-contact-margin>` | :ref:`gap<flex-contact-gap>` | :ref:`internal<flex-contact-internal>` | :ref:`selfcollide<flex-contact-selfcollide>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`activelayers<flex-contact-activelayers>` | | | | |
| | | | :ref:`activelayers<flex-contact-activelayers>` | :ref:`vertcollide<flex-contact-vertcollide>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_2| flex |br| |_2| |L| | | .. table:: |
+2 -1
View File
@@ -2049,7 +2049,8 @@ typedef struct mjsFlex_ { // flex specification
double radius; // radius around primitive element
mjtByte internal; // enable internal collisions
mjtByte flatskin; // render flex skin with flat shading
int selfcollide; // mode for flex self colllision
int selfcollide; // mode for flex self collision
int vertcollide; // mode for vertex collision
int activelayers; // number of active element layers in 3D
int group; // group for visualizatioh
double edgestiffness; // edge stiffness
+2 -1
View File
@@ -430,7 +430,8 @@ typedef struct mjsFlex_ { // flex specification
double radius; // radius around primitive element
mjtByte internal; // enable internal collisions
mjtByte flatskin; // render flex skin with flat shading
int selfcollide; // mode for flex self colllision
int selfcollide; // mode for flex self collision
int vertcollide; // mode for vertex collision
int activelayers; // number of active element layers in 3D
int group; // group for visualizatioh
double edgestiffness; // edge stiffness
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -10722,7 +10722,12 @@ STRUCTS: Mapping[str, StructDecl] = dict([
StructFieldDecl(
name='selfcollide',
type=ValueType(name='int'),
doc='mode for flex self colllision',
doc='mode for flex self collision',
),
StructFieldDecl(
name='vertcollide',
type=ValueType(name='int'),
doc='mode for vertex collision',
),
StructFieldDecl(
name='activelayers',
+16
View File
@@ -33,6 +33,7 @@
#include "engine/engine_util_errmem.h"
#include "user/user_flexcomp.h"
#include <mujoco/mjspec.h>
#include "user/user_api.h"
#include "user/user_model.h"
#include "user/user_objects.h"
#include "user/user_resource.h"
@@ -459,6 +460,14 @@ bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
// add new body at vertex coordinates
mjsBody* pb = mjs_addBody(body, 0);
// add geom if vertcollide
if (dflex->vertcollide) {
mjsGeom* geom = mjs_addGeom(pb, 0);
geom->type = mjGEOM_SPHERE;
geom->size[0] = dflex->radius;
geom->group = 4;
}
// set frame and inertial
pb->pos[0] = point[3*i];
pb->pos[1] = point[3*i+1];
@@ -544,6 +553,13 @@ bool mjCFlexcomp::Make(mjsBody* body, char* error, int error_sz) {
pb->inertia[2] = pb->mass*(2.0*inertiabox*inertiabox)/3.0;
pb->explicitinertial = true;
// add geom if vertcollide
if (dflex->vertcollide) {
mjsGeom* geom = mjs_addGeom(pb, 0);
geom->type = mjGEOM_SPHERE;
geom->size[0] = dflex->radius;
}
for (int d=0; d < 3; d++) {
mjsJoint* jnt = mjs_addJoint(pb, 0);
jnt->type = mjJNT_SLIDE;
+10 -4
View File
@@ -311,9 +311,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"<"},
{"edge", "?", "5", "equality", "solref", "solimp", "stiffness", "damping"},
{"elasticity", "?", "4", "young", "poisson", "damping", "thickness"},
{"contact", "?", "13", "contype", "conaffinity", "condim", "priority",
{"contact", "?", "14", "contype", "conaffinity", "condim", "priority",
"friction", "solmix", "solref", "solimp", "margin", "gap",
"internal", "selfcollide", "activelayers"},
"internal", "selfcollide", "activelayers", "vertcollide"},
{"pin", "*", "4", "id", "range", "grid", "gridrange"},
{"plugin", "*", "2", "plugin", "instance"},
{"<"},
@@ -327,9 +327,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"flex", "*", "13", "name", "group", "dim", "radius", "material",
"rgba", "flatskin", "body", "vertex", "element", "texcoord", "elemtexcoord", "node"},
{"<"},
{"contact", "?", "13", "contype", "conaffinity", "condim", "priority",
{"contact", "?", "14", "contype", "conaffinity", "condim", "priority",
"friction", "solmix", "solref", "solimp", "margin", "gap",
"internal", "selfcollide", "activelayers"},
"internal", "selfcollide", "activelayers", "vertcollide"},
{"edge", "?", "2", "stiffness", "damping"},
{"elasticity", "?", "4", "young", "poisson", "damping", "thickness"},
{">"},
@@ -1380,6 +1380,9 @@ void mjXReader::OneFlex(XMLElement* elem, mjsFlex* flex) {
flex->internal = (n == 1);
}
MapValue(cont, "selfcollide", &flex->selfcollide, flexself_map, 5);
if (MapValue(cont, "vertcollide", &flex->vertcollide, bool_map, 2)) {
flex->vertcollide = (n == 1);
}
ReadAttrInt(cont, "activelayers", &flex->activelayers);
}
@@ -2682,6 +2685,9 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjsBody* body, const mjVFS* vfs) {
dflex.internal = (n == 1);
}
MapValue(cont, "selfcollide", &dflex.selfcollide, flexself_map, 5);
if (MapValue(cont, "vertcollide", &n, bool_map, 2)) {
dflex.vertcollide = (n == 1);
}
ReadAttrInt(cont, "activelayers", &dflex.activelayers);
}