Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ParserConfig: save auto inertial values by default #1325

Merged
merged 5 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ void Geometry::SetPolylineShape(const std::vector<Polyline> &_polylines)
this->dataPtr->polylines = _polylines;
}

/////////////////////////////////////////////////
std::optional<gz::math::Inertiald> Geometry::CalculateInertial(
sdf::Errors &_errors, const ParserConfig &_config,
double _density, sdf::ElementPtr _autoInertiaParams)
Expand Down
9 changes: 5 additions & 4 deletions src/Link.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@
{
Error err(
ErrorCode::WARNING,
"Inertial was used with auto=true for link, " +
this->dataPtr->name + " but user defined inertial values "
"were found. They would be overwritten by computed ones."
"Inertial was used with auto=true for the link named " +

Check warning on line 194 in src/Link.cc

View check run for this annotation

Codecov / codecov/patch

src/Link.cc#L194

Added line #L194 was not covered by tests
this->dataPtr->name + ", but user-defined inertial values were "
"found, which will be overwritten by the computed inertial values."
);
enforceConfigurablePolicyCondition(
_config.WarningsPolicy(), err, errors);
Expand Down Expand Up @@ -610,7 +610,8 @@
{
_errors.push_back({ErrorCode::ELEMENT_MISSING,
"Inertial is set to auto but there are no "
"<collision> elements for the link."});
"<collision> elements for the link named " +
this->Name() + "."});
return;
}

Expand Down
17 changes: 6 additions & 11 deletions src/Link_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,18 +293,13 @@ TEST(DOMLink, ResolveAutoInertialsWithNoCollisionsInLink)
sdf::Root root;
const sdf::ParserConfig sdfParserConfig;
sdf::Errors errors = root.LoadSdfString(sdf, sdfParserConfig);
EXPECT_TRUE(errors.empty());
ASSERT_EQ(1u, errors.size()) << errors;
EXPECT_EQ(sdf::ErrorCode::ELEMENT_MISSING, errors[0].Code());
EXPECT_NE(std::string::npos,
errors[0].Message().find(
"Inertial is set to auto but there are no <collision> elements "
"for the link named link."));
EXPECT_NE(nullptr, root.Element());

const sdf::Model *model = root.Model();
const sdf::Link *link = model->LinkByIndex(0);
root.ResolveAutoInertials(errors, sdfParserConfig);
ASSERT_FALSE(errors.empty());

// Default Inertial values set during load
EXPECT_EQ(1.0, link->Inertial().MassMatrix().Mass());
EXPECT_EQ(gz::math::Vector3d::One,
link->Inertial().MassMatrix().DiagonalMoments());
}

/////////////////////////////////////////////////
Expand Down
16 changes: 16 additions & 0 deletions src/Mesh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,22 @@ std::optional<gz::math::Inertiald> Mesh::CalculateInertial(sdf::Errors &_errors,

const auto &customCalculator = _config.CustomInertiaCalc();

if (!customCalculator)
{
Error err(
sdf::ErrorCode::WARNING,
"Custom moment of inertia calculator for meshes not set via "
"sdf::ParserConfig::RegisterCustomInertiaCalc, using default "
"inertial values.");
enforceConfigurablePolicyCondition(
_config.WarningsPolicy(), err, _errors);

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

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

Expand Down
6 changes: 3 additions & 3 deletions src/ParserConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ class sdf::ParserConfig::Implementation
public: std::optional<EnforcementPolicy> deprecatedElementsPolicy;

/// \brief Configuration that is set for the CalculateInertial() function
/// By default it is set to SKIP_CALCULATION_IN_LOAD which would cause
/// Root::Load() to not call CalculateInertial()
/// By default it is set to SAVE_CALCULATION to preserve the behavior of
/// Root::Load() generating complete inertial information.
public: ConfigureResolveAutoInertials resolveAutoInertialsConfig =
ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD;
ConfigureResolveAutoInertials::SAVE_CALCULATION;

/// \brief Collection of custom model parsers.
public: std::vector<CustomModelParser> customParsers;
Expand Down
6 changes: 3 additions & 3 deletions src/ParserConfig_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ TEST(ParserConfig, Construction)
EXPECT_EQ(sdf::EnforcementPolicy::WARN, config.UnrecognizedElementsPolicy());
EXPECT_EQ(sdf::EnforcementPolicy::WARN, config.DeprecatedElementsPolicy());

EXPECT_EQ(sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD,
EXPECT_EQ(sdf::ConfigureResolveAutoInertials::SAVE_CALCULATION,
config.CalculateInertialConfiguration());
config.SetCalculateInertialConfiguration(
sdf::ConfigureResolveAutoInertials::SAVE_CALCULATION);
EXPECT_EQ(sdf::ConfigureResolveAutoInertials::SAVE_CALCULATION,
sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD);
EXPECT_EQ(sdf::ConfigureResolveAutoInertials::SKIP_CALCULATION_IN_LOAD,
config.CalculateInertialConfiguration());
EXPECT_FALSE(config.URDFPreserveFixedJoint());
EXPECT_FALSE(config.StoreResolvedURIs());
Expand Down
2 changes: 1 addition & 1 deletion src/gz_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1889,7 +1889,7 @@ TEST(inertial_stats, GZ_UTILS_TEST_DISABLED_ON_WIN32(SDF))

// Check a good SDF file from the same folder by passing a relative path
{
std::string path = "inertial_stats.sdf";
std::string path = "inertial_stats_auto.sdf";

std::string output =
custom_exec_str("cd " + pathBase + " && " +
Expand Down
10 changes: 10 additions & 0 deletions test/integration/root_dom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,13 @@ TEST(DOMRoot, CreateMulipleWorlds)
testFunc(root);
testFunc(root2);
}

/////////////////////////////////////////////////
TEST(DOMRoot, LoadWithoutMeshAutoInertialCalculator)
{
const std::string testFile =
sdf::testing::TestFile("sdf", "mesh_auto_inertial.sdf");
sdf::Root root;
sdf::Errors errors = root.Load(testFile);
EXPECT_TRUE(errors.empty()) << errors;
}
40 changes: 20 additions & 20 deletions test/sdf/inertial_stats.sdf
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
<?xml version="1.0" ?>
<!---
Model consists of 4 cubes places symmetrically
in the XY plane. This model is used to verify the
"gz sdf --inertial-stats" tool .
+y
┌─┼─┐
L3 │ │ │(0,5,0)
└─┼─┘
L2┌───┐ │ ┌───┐L1
────┼┼┼┼┼───┼─────┼┼┼┼┼─── +x
└───┘ │ └───┘
(-5,0,0) │ (5,0,0)
┌─┼─┐
│ │ │(0,-5,0)
└─┼─┘
L4│
-->
<sdf version="1.6">

<!---
Model consists of 4 cubes places symmetrically in the XY plane.
+y
┌─┼─┐
L3 │ │ │(0,5,0)
└─┼─┘
L2┌───┐ │ ┌───┐L1
────┼┼┼┼┼───┼─────┼┼┼┼┼─── +x
└───┘ │ └───┘
(-5,0,0) │ (5,0,0)
┌─┼─┐
│ │ │(0,-5,0)
└─┼─┘
L4│
-->
<![CDATA[
This model is used to verify the "gz sdf --inertial-stats" tool.
]]>
<model name="test_model">
<pose>0 0 0 0 0 0</pose>

Expand Down
107 changes: 107 additions & 0 deletions test/sdf/inertial_stats_auto.sdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?xml version="1.0" ?>
<sdf version="1.11">
<!---
Model consists of 4 cubes places symmetrically in the XY plane.
+y
┌─┼─┐
L3 │ │ │(0,5,0)
└─┼─┘
L2┌───┐ │ ┌───┐L1
────┼┼┼┼┼───┼─────┼┼┼┼┼─── +x
└───┘ │ └───┘
(-5,0,0) │ (5,0,0)
┌─┼─┐
│ │ │(0,-5,0)
└─┼─┘
L4│
-->
<![CDATA[
This model is used to verify the "gz sdf --inertial-stats" tool.
]]>
<model name="test_model">
<pose>0 0 0 0 0 0</pose>

<link name="link_1">
<pose>5 0 0 0 0 0</pose>
<inertial auto='true' />
<collision name="collision_1">
<density>6</density>
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual_1">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>

<link name="link_2">
<pose>-5 0 0 0 0 0</pose>
<inertial auto='true' />
<collision name="collision_2">
<density>6</density>
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual_2">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>

<link name="link_3">
<pose>0 5 0 0 0 0</pose>
<inertial auto='true' />
<collision name="collision_3">
<density>6</density>
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual_3">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>

<link name="link_4">
<pose>0 -5 0 0 0 0</pose>
<inertial auto='true' />
<collision name="collision_4">
<density>6</density>
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual_4">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>
</model>

</sdf>
17 changes: 17 additions & 0 deletions test/sdf/mesh_auto_inertial.sdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" ?>
<!-- Since sdformat itself doesn't have an moment of inertia calculator for meshes, this file is not expected to load without errors -->
<sdf version='1.11'>
<model name='test_model'>
<link name='L1'>
<inertial auto='true'/>
<collision name="collision">
<geometry>
<mesh>
<uri>box.dae</uri>
</mesh>
</geometry>
</collision>
</link>
</model>
</sdf>