Add geom surfacevel: zero-dof conveyors, treadmills and turntables.

https://www.youtube.com/watch?v=PdSdrqhSiZA

The new geom attribute surfacevel (6 numbers: linear and angular velocity in the geom's local frame, angular about the geom frame origin) specifies the velocity of the geom's surface material relative to the geom frame. The relative surface velocity of the two geoms is added to the tangential contact rows of efc_vel in mj_referenceConstraint, so friction drives touching bodies toward the motion of the surface: objects on a conveyor are transported at belt speed, turntables impart omega x r with torsional spin-up for condim >= 4, and surface velocities compose with each other and with body motion. The component along the contact normal is projected out: probe experiments showed that velocity-space emission chatters mass-independently and ingestion merely deepens penetration; normal-direction effects belong to force-space features.

surfacevel is interpreted in the geom frame as authored: for mesh geoms, whose compiled frame absorbs the mesh centering and principal-axes transform, the compiler re-expresses the authored value in the compiled frame.

No special interaction with sleeping: objects being transported do not fall asleep because they are moving; objects at rest on an active surface may sleep like any other resting object.

Includes showcase models (model/surfacevel/): a luggage carousel whose ring is a spinning square-profile supertorus fed by a cascade of belts with matched spinning end rollers, bags dropping in and circulating indefinitely; and a treadmill with a passive humanoid.

PiperOrigin-RevId: 948647785
Change-Id: I0c6559a91cc7ece1237eb8ac2e51986e7342d962
This commit is contained in:
Yuval Tassa
2026-07-15 17:57:28 -07:00
committed by Copybara-Service
parent 97eb1e5d0c
commit 4787c8094c
32 changed files with 781 additions and 11 deletions
+2
View File
@@ -332,6 +332,7 @@ typedef struct mjModel_ {
mjtSize nnames_map; // number of slots in the names hash map
mjtSize nJmom; // number of non-zeros in sparse actuator_moment matrix
mjtSize ngravcomp; // number of bodies with nonzero gravcomp
mjtSize nsurfacevel; // number of geoms with nonzero surfacevel
mjtSize nemax; // number of potential equality-constraint rows
mjtSize njmax; // number of available rows in constraint Jacobian (legacy)
mjtSize nconmax; // number of potential contacts in contact list (legacy)
@@ -472,6 +473,7 @@ typedef struct mjModel_ {
mjtNum* geom_friction; // friction for (slide, spin, roll) (ngeom x 3)
mjtNum* geom_margin; // geometric inflation for contact (ngeom x 1)
mjtNum* geom_gap; // additional contact detection buffer (ngeom x 1)
mjtNum* geom_surfacevel; // surface velocity in local frame: lin,ang (ngeom x 6)
mjtNum* geom_fluid; // fluid interaction parameters (ngeom x mjNFLUID)
mjtNum* geom_user; // user data (ngeom x nuser_geom)
float* geom_rgba; // rgba when material is omitted (ngeom x 4)
+1
View File
@@ -358,6 +358,7 @@ typedef struct mjsGeom_ { // geom specification
mjtNum solimp[mjNIMP]; // solver impedance
double margin; // margin for contact detection
double gap; // additional contact detection buffer
double surfacevel[6]; // surface velocity in local frame: linear, angular
// inertia inference
double mass; // used to compute density
+1
View File
@@ -182,6 +182,7 @@
XVEC( mjtNum, solimp, mjNIMP ) \
X ( double, margin, 1 ) \
X ( double, gap, 1 ) \
XVEC( double, surfacevel, 6 ) \
X ( double, mass, 1 ) \
X ( double, density, 1 ) \
X ( mjtGeomInertia, typeinertia, 1 ) \
+2
View File
@@ -247,6 +247,7 @@
X( nnames_map ) \
X( nJmom ) \
X( ngravcomp ) \
X( nsurfacevel ) \
X( nemax ) \
X( njmax ) \
X( nconmax ) \
@@ -385,6 +386,7 @@
X ( mjtNum, geom_friction, ngeom, 3 ) \
X ( mjtNum, geom_margin, ngeom, 1 ) \
X ( mjtNum, geom_gap, ngeom, 1 ) \
X ( mjtNum, geom_surfacevel, ngeom, 6 ) \
XNV ( mjtNum, geom_fluid, ngeom, mjNFLUID ) \
X ( mjtNum, geom_user, ngeom, MJ_M(nuser_geom) ) \
X ( float, geom_rgba, ngeom, 4 )