Add insidesite sensor for detecting when an object is inside the volume of a site.
PiperOrigin-RevId: 780993257 Change-Id: I2dcfc840d222680adc3b934344a0819f4d78b6eb
This commit is contained in:
committed by
Copybara-Service
parent
a86461fc57
commit
e6c5715903
@@ -2122,6 +2122,7 @@ static int sensorSize(mjtSensor sensor_type, int sensor_dim) {
|
||||
case mjSENS_TENDONLIMITVEL:
|
||||
case mjSENS_TENDONLIMITFRC:
|
||||
case mjSENS_GEOMDIST:
|
||||
case mjSENS_INSIDESITE:
|
||||
case mjSENS_E_POTENTIAL:
|
||||
case mjSENS_E_KINETIC:
|
||||
case mjSENS_CLOCK:
|
||||
|
||||
@@ -365,6 +365,15 @@ void mj_sensorPos(const mjModel* m, mjData* d) {
|
||||
mju_copy3(d->sensordata+adr, d->subtree_com+3*objid);
|
||||
break;
|
||||
|
||||
case mjSENS_INSIDESITE: // insidesite
|
||||
get_xpos_xmat(d, objtype, objid, i, &xpos, &xmat);
|
||||
d->sensordata[adr] = mju_insideGeom(d->site_xpos + 3*refid,
|
||||
d->site_xmat + 9*refid,
|
||||
m->site_size + 3*refid,
|
||||
m->site_type[refid],
|
||||
xpos);
|
||||
break;
|
||||
|
||||
case mjSENS_GEOMDIST: // signed distance between two geoms
|
||||
case mjSENS_GEOMNORMAL: // normal direction between two geoms
|
||||
case mjSENS_GEOMFROMTO: // segment between two geoms
|
||||
|
||||
@@ -450,6 +450,53 @@ void mju_geomSemiAxes(mjtNum semiaxes[3], const mjtNum size[3], mjtGeom type) {
|
||||
}
|
||||
|
||||
|
||||
// return 1 if point is inside a primitive geom, 0 otherwise
|
||||
int mju_insideGeom(const mjtNum pos[3], const mjtNum mat[9], const mjtNum size[3], mjtGeom type,
|
||||
const mjtNum point[3]) {
|
||||
// vector from geom to point
|
||||
mjtNum vec[3];
|
||||
mju_sub3(vec, point, pos);
|
||||
|
||||
// quick return for spheres, frame rotation not required
|
||||
if (type == mjGEOM_SPHERE) {
|
||||
return mju_dot3(vec, vec) < size[0]*size[0];
|
||||
}
|
||||
|
||||
// rotate into local frame
|
||||
mjtNum plocal[3];
|
||||
mju_mulMatTVec3(plocal, mat, vec);
|
||||
|
||||
// handle other geom types
|
||||
switch (type) {
|
||||
case mjGEOM_CAPSULE: {
|
||||
mjtNum z = plocal[2];
|
||||
mjtNum z_clamped = mju_clip(z, -size[1], size[1]);
|
||||
mjtNum z_dist_sq = (z - z_clamped) * (z - z_clamped);
|
||||
return (plocal[0]*plocal[0] + plocal[1]*plocal[1] + z_dist_sq < size[0]*size[0]);
|
||||
}
|
||||
|
||||
case mjGEOM_ELLIPSOID:
|
||||
return (plocal[0]*plocal[0]/(size[0]*size[0]) +
|
||||
plocal[1]*plocal[1]/(size[1]*size[1]) +
|
||||
plocal[2]*plocal[2]/(size[2]*size[2]) < 1);
|
||||
|
||||
case mjGEOM_CYLINDER:
|
||||
return (mju_abs(plocal[2]) < size[1] &&
|
||||
plocal[0]*plocal[0] + plocal[1]*plocal[1] < size[0]*size[0]);
|
||||
|
||||
case mjGEOM_BOX:
|
||||
return (mju_abs(plocal[0]) < size[0] &&
|
||||
mju_abs(plocal[1]) < size[1] &&
|
||||
mju_abs(plocal[2]) < size[2]);
|
||||
|
||||
case mjGEOM_PLANE:
|
||||
return plocal[2] < 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------- Flex interpolation ------------------------------------------------
|
||||
|
||||
|
||||
@@ -53,6 +53,10 @@ MJAPI mjtNum mju_muscleDynamics(mjtNum ctrl, mjtNum act, const mjtNum prm[3]);
|
||||
// all 3 semi-axes of a geom
|
||||
MJAPI void mju_geomSemiAxes(mjtNum semiaxes[3], const mjtNum size[3], mjtGeom type);
|
||||
|
||||
// return 1 if point is inside a primitive geom, 0 otherwise
|
||||
int mju_insideGeom(const mjtNum pos[3], const mjtNum mat[9], const mjtNum size[3], mjtGeom type,
|
||||
const mjtNum point[3]);
|
||||
|
||||
// ----------------------------- Flex interpolation ------------------------------------------------
|
||||
|
||||
// evaluate the deformation gradient at p using the nodal dof values
|
||||
|
||||
Reference in New Issue
Block a user