Replace box SDF with a smooth approximation.

This approximation is equivalent to the exact SDF on the surface and externally, but it is smooth on the inside, rotating the gradient from radial at the box center to normal to the faces at the surface, and interpolated linearly (using two Euler angles) in between. This enables stable contact gradients for deeper penetrations.

PiperOrigin-RevId: 776574022
Change-Id: I562976e9f0535b0067aa12b2bc9d48eccb6472e9
This commit is contained in:
Alessio Quaglino
2025-06-27 07:20:43 -07:00
committed by Copybara-Service
parent 931ea6938c
commit e97e5d31d0
2 changed files with 30 additions and 7 deletions
+2 -2
View File
@@ -60,7 +60,7 @@ TEST_F(SdfTest, SdfPrimitive) {
{-1, 0, 0, mju_sqrt(2)-1, mju_sqrt(2)-1, mju_sqrt(3)-1}, // sphere
{-.1, .9, .9, mju_sqrt(2)-.1, .9, mju_sqrt(2)-.1}, // capsule
{-1, 0, 0, mju_sqrt(2)-1, 0, mju_sqrt(2)-1}, // cylinder
{-1, 0, 0, 0, 0, 0}, // box
{-mju_sqrt(3), 0, 0, 0, 0, 0}, // box
};
mjtNum points[kpoints][3] = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0},
{1, 1, 0}, {0, 1, 1}, {1, 1, 1}};
@@ -71,7 +71,7 @@ TEST_F(SdfTest, SdfPrimitive) {
sdf.type = mjSDFTYPE_SINGLE;
sdf.geomtype = (mjtGeom*)(model->geom_type+i);
for (int j = 0; j < kpoints; j++) {
ASSERT_THAT(mjc_distance(model, data, &sdf, points[j]), dist[i][j]);
EXPECT_NEAR(mjc_distance(model, data, &sdf, points[j]), dist[i][j], 1e-9);
mjc_gradient(model, data, &sdf, gradient, points[j]);
}
}