Skip to content

Commit

Permalink
handle bad inertial values in collision
Browse files Browse the repository at this point in the history
Signed-off-by: Ian Chen <[email protected]>
  • Loading branch information
iche033 committed Feb 11, 2025
1 parent 75867c0 commit 2b0cbb2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 19 deletions.
5 changes: 4 additions & 1 deletion src/Collision.cc
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ void Collision::CalculateInertial(
{
_errors.push_back({ErrorCode::LINK_INERTIA_INVALID,
"Inertia Calculated for collision: " +
this->dataPtr->name + " is invalid."});
this->dataPtr->name + " is invalid, using default inertial values."});
_inertial = gz::math::Inertiald(
gz::math::MassMatrix3d(1, gz::math::Vector3d::One,
gz::math::Vector3d::Zero), gz::math::Pose3d::Zero);
}
else
{
Expand Down
43 changes: 43 additions & 0 deletions src/Collision_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,49 @@ TEST(DOMcollision, SetSurface)
EXPECT_EQ(collision.Surface()->Contact()->CollideBitmask(), 0x2);
}

/////////////////////////////////////////////////
TEST(DOMCollision, IncorrectMeshCollisionCalculateInertial)
{
sdf::Collision collision;

sdf::ElementPtr sdf(new sdf::Element());
collision.Load(sdf);

const sdf::ParserConfig sdfParserConfig;
sdf::Geometry geom;
sdf::Mesh mesh;
geom.SetType(sdf::GeometryType::MESH);
geom.SetMeshShape(mesh);
collision.SetGeom(geom);

sdf::ParserConfig config;
sdf::Errors errors;
sdf::CustomInertiaCalcProperties inertiaCalcProps;

// Custom inertia calculator that returns null inertia
auto customMeshInertiaCalculator = [](
sdf::Errors &,
const sdf::CustomInertiaCalcProperties &)
-> std::optional<gz::math::Inertiald>
{
return std::nullopt;
};
config.RegisterCustomInertiaCalc(customMeshInertiaCalculator);

gz::math::Inertiald collisionInertial;
collision.CalculateInertial(errors, collisionInertial, config);
ASSERT_FALSE(errors.empty());

// Expect mesh class to handle null inertia and return
// default inertial values
gz::math::Inertiald defaultInertial;
defaultInertial.SetMassMatrix(
gz::math::MassMatrix3d(1.0,
gz::math::Vector3d::One,
gz::math::Vector3d::Zero));
ASSERT_EQ(collisionInertial, defaultInertial);
}

/////////////////////////////////////////////////
TEST(DOMCollision, IncorrectBoxCollisionCalculateInertial)
{
Expand Down
24 changes: 6 additions & 18 deletions src/Mesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,6 @@ std::optional<gz::math::Inertiald> Mesh::CalculateInertial(sdf::Errors &_errors,
{
const auto &customCalculator = _config.CustomInertiaCalc();

auto defaultInertial = gz::math::Inertiald(
gz::math::MassMatrix3d(1, gz::math::Vector3d::One,
gz::math::Vector3d::Zero),
gz::math::Pose3d::Zero);
if (!customCalculator)
{
Error err(
Expand All @@ -389,25 +385,17 @@ std::optional<gz::math::Inertiald> Mesh::CalculateInertial(sdf::Errors &_errors,
"inertial values.");
enforceConfigurablePolicyCondition(
_config.WarningsPolicy(), err, _errors);
return defaultInertial;

using namespace gz::math;
return Inertiald(
MassMatrix3d(1, Vector3d::One, Vector3d::Zero),
Pose3d::Zero);
}

sdf::CustomInertiaCalcProperties calcInterface = CustomInertiaCalcProperties(
_density, *this, _autoInertiaParams);

std::optional<gz::math::Inertiald> inertial =
customCalculator(_errors, calcInterface);
if (!inertial)
{
Error err(
sdf::ErrorCode::WARNING,
"Custom moment of inertia calculator for meshes produced invalid inertia, "
"using default inertial values.");
enforceConfigurablePolicyCondition(
_config.WarningsPolicy(), err, _errors);
return defaultInertial;
}
return inertial;
return customCalculator(_errors, calcInterface);
}

/////////////////////////////////////////////////
Expand Down

0 comments on commit 2b0cbb2

Please sign in to comment.