diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 647a731b..efbecc2f 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -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`. 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"` diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index 9036d1c0..5b32d4bb 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -452,7 +452,7 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`margin` | :ref:`gap` | :ref:`internal` | :ref:`selfcollide` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`activelayers` | | | | | +| | | | :ref:`activelayers` | :ref:`vertcollide` | | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_2| flexcomp |br| |_2| |L| | | .. table:: | @@ -502,7 +502,7 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`margin` | :ref:`gap` | :ref:`internal` | :ref:`selfcollide` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`activelayers` | | | | | +| | | | :ref:`activelayers` | :ref:`vertcollide` | | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_2| flex |br| |_2| |L| | | .. table:: | diff --git a/doc/includes/references.h b/doc/includes/references.h index 0689e150..d8071b2c 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -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 diff --git a/include/mujoco/mjspec.h b/include/mujoco/mjspec.h index 3202d9dc..fb95afad 100644 --- a/include/mujoco/mjspec.h +++ b/include/mujoco/mjspec.h @@ -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 diff --git a/model/plugin/elasticity/poncho_vertcollide.xml b/model/plugin/elasticity/poncho_vertcollide.xml new file mode 100644 index 00000000..895df038 --- /dev/null +++ b/model/plugin/elasticity/poncho_vertcollide.xml @@ -0,0 +1,1432 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/mujoco/introspect/structs.py b/python/mujoco/introspect/structs.py index c7c3f4d1..e3ec1bc8 100644 --- a/python/mujoco/introspect/structs.py +++ b/python/mujoco/introspect/structs.py @@ -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', diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 1d0dbece..cb7124c1 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -33,6 +33,7 @@ #include "engine/engine_util_errmem.h" #include "user/user_flexcomp.h" #include +#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; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index a5bf6824..8404364a 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -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); }