Change GJK and EPA return values.

PiperOrigin-RevId: 717549079
Change-Id: I42df5660bcc8336e2e9c8fce71385cbb06104848
This commit is contained in:
Kyle Bayes
2025-01-20 08:58:45 -08:00
committed by Copybara-Service
parent 5c4c79cd6a
commit 600f4acb52
+25 -23
View File
@@ -81,8 +81,9 @@ static mjtNum attachFace(Polytope* pt, int v1, int v2, int v3, int adj1, int adj
// status must have initial tetrahedrons // status must have initial tetrahedrons
static int gjkIntersect(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2); static int gjkIntersect(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2);
// return the penetration depth of two convex objects; witness points are in status->{x1, x2} // return a face of the expanded polytope that best approximates the pentration depth
static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* obj2); // witness points are in status->{x1, x2}
static Face* epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* obj2);
// -------------------------------- inlined 3D vector utils -------------------------------------- // -------------------------------- inlined 3D vector utils --------------------------------------
@@ -145,7 +146,7 @@ static int discreteGeoms(mjCCDObj* obj1, mjCCDObj* obj2) {
// GJK algorithm // GJK algorithm
static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) { static void gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
int get_dist = status->dist_cutoff > 0; // need to recover geom distances if not in contact int get_dist = status->dist_cutoff > 0; // need to recover geom distances if not in contact
int backup_gjk = !get_dist; // use gjkIntersect if no geom distances needed int backup_gjk = !get_dist; // use gjkIntersect if no geom distances needed
mjtNum *simplex1 = status->simplex1; // simplex for obj1 mjtNum *simplex1 = status->simplex1; // simplex for obj1
@@ -192,7 +193,7 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
status->nsimplex = 0; status->nsimplex = 0;
status->nx = 0; status->nx = 0;
status->dist = mjMAXVAL; status->dist = mjMAXVAL;
return status->dist; return;
} }
} else if (status->dist_cutoff < mjMAXVAL) { } else if (status->dist_cutoff < mjMAXVAL) {
mjtNum vs = mju_dot3(x_k, s_k), vv = mju_dot3(x_k, x_k); mjtNum vs = mju_dot3(x_k, s_k), vv = mju_dot3(x_k, x_k);
@@ -201,7 +202,7 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
status->nsimplex = 0; status->nsimplex = 0;
status->nx = 0; status->nx = 0;
status->dist = mjMAXVAL; status->dist = mjMAXVAL;
return status->dist; return;
} }
} }
@@ -213,7 +214,7 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
if (ret != -1) { if (ret != -1) {
status->nx = 0; status->nx = 0;
status->dist = ret > 0 ? 0 : mjMAXVAL; status->dist = ret > 0 ? 0 : mjMAXVAL;
return status->dist; return;
} }
k = status->gjk_iterations; k = status->gjk_iterations;
backup_gjk = 0; backup_gjk = 0;
@@ -259,7 +260,6 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
status->gjk_iterations = k; status->gjk_iterations = k;
status->nsimplex = n; status->nsimplex = n;
status->dist = mju_norm3(x_k); status->dist = mju_norm3(x_k);
return status->dist;
} }
@@ -1294,8 +1294,9 @@ static void epaWitness(const Polytope* pt, const Face* face, mjtNum x1[3], mjtNu
// return the penetration depth of two convex objects; witness points are in status->{x1, x2} // return a face of the expanded polytope that best approximates the pentration depth
static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* obj2) { // witness points are in status->{x1, x2}
static Face* epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* obj2) {
mjtNum tolerance = status->tolerance, lower, upper = FLT_MAX; mjtNum tolerance = status->tolerance, lower, upper = FLT_MAX;
int k, kmax = status->max_iterations; int k, kmax = status->max_iterations;
mjData* d = (mjData*) obj1->data; mjData* d = (mjData*) obj1->data;
@@ -1368,7 +1369,8 @@ static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* o
mj_freeStack(d); mj_freeStack(d);
status->epa_iterations = k; status->epa_iterations = k;
status->nx = 0; status->nx = 0;
return 0; status->dist = 0;
return NULL;
} }
// store face in map // store face in map
@@ -1395,7 +1397,8 @@ static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* o
mj_freeStack(d); mj_freeStack(d);
status->epa_iterations = k; status->epa_iterations = k;
status->nx = 0; status->nx = 0;
return 0; status->dist = 0;
return NULL;
} }
// store face in map // store face in map
@@ -1417,7 +1420,8 @@ static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* o
epaWitness(pt, face, status->x1, status->x2); epaWitness(pt, face, status->x1, status->x2);
status->epa_iterations = k; status->epa_iterations = k;
status->nx = 1; status->nx = 1;
return face->dist; status->dist = -face->dist;
return face;
} }
@@ -1444,8 +1448,7 @@ static inline void inflate(mjCCDStatus* status, mjtNum margin1, mjtNum margin2)
// general convex collision detection // general convex collision detection
mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) { mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
// set up // setup
mjtNum dist;
obj1->center(status->x1, obj1); obj1->center(status->x1, obj1);
obj2->center(status->x2, obj2); obj2->center(status->x2, obj2);
status->gjk_iterations = 0; status->gjk_iterations = 0;
@@ -1488,11 +1491,11 @@ mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, m
} }
status->dist_cutoff += margin1 + margin2; status->dist_cutoff += margin1 + margin2;
dist = gjk(status, obj1, obj2); gjk(status, obj1, obj2);
status->dist_cutoff = config->dist_cutoff; status->dist_cutoff = config->dist_cutoff;
// shallow penetration, inflate contact // shallow penetration, inflate contact
if (dist > 0) { if (status->dist > 0) {
inflate(status, margin1, margin2); inflate(status, margin1, margin2);
if (status->dist > status->dist_cutoff) { if (status->dist > status->dist_cutoff) {
status->dist = mjMAXVAL; status->dist = mjMAXVAL;
@@ -1515,14 +1518,15 @@ mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, m
obj2->center(status->x2, obj2); obj2->center(status->x2, obj2);
} }
dist = gjk(status, obj1, obj2); gjk(status, obj1, obj2);
// penetration recovery for contacts not needed // penetration recovery for contacts not needed
if (!config->max_contacts) { if (!config->max_contacts) {
return dist; return status->dist;
} }
if (dist <= config->tolerance && status->nsimplex > 1) { if (status->dist <= config->tolerance && status->nsimplex > 1) {
status->dist = 0; // assume touching
int N = status->max_iterations; int N = status->max_iterations;
mjData* d = (mjData*) obj1->data; mjData* d = (mjData*) obj1->data;
mj_markStack((mjData*) obj1->data); mj_markStack((mjData*) obj1->data);
@@ -1561,11 +1565,9 @@ mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, m
// simplex not on boundary (objects are penetrating) // simplex not on boundary (objects are penetrating)
if (!ret) { if (!ret) {
dist = -epa(status, &pt, obj1, obj2); epa(status, &pt, obj1, obj2);
} else {
dist = 0;
} }
mj_freeStack(d); mj_freeStack(d);
} }
return dist; return status->dist;
} }