Skip to content

Commit beb1e4e

Browse files
committed
fix error handling in material parsing
We should consider the return value of parseMaterial(). Redefining the same material again, should be accepted. This often occurs when composing URDFs via xacro.
1 parent 3ffc4ee commit beb1e4e

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

urdf_parser/src/model.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ bool assignMaterial(const VisualSharedPtr& visual, ModelInterfaceSharedPtr& mode
8686
return true;
8787
}
8888

89+
bool operator==(const Material& lhs, const Material& rhs)
90+
{
91+
return lhs.texture_filename == rhs.texture_filename &&
92+
lhs.color.r == rhs.color.r &&
93+
lhs.color.g == rhs.color.g &&
94+
lhs.color.b == rhs.color.b &&
95+
lhs.color.a == rhs.color.a;
96+
}
97+
inline bool operator!=(const Material& lhs, const Material& rhs)
98+
{
99+
return !(lhs == rhs);
100+
}
101+
89102
ModelInterfaceSharedPtr parseURDF(const std::string &xml_string)
90103
{
91104
ModelInterfaceSharedPtr model(new ModelInterface);
@@ -126,13 +139,15 @@ ModelInterfaceSharedPtr parseURDF(const std::string &xml_string)
126139
material.reset(new Material);
127140

128141
try {
129-
parseMaterial(*material, material_xml, false); // material needs to be fully defined here
130-
if (model->getMaterial(material->name))
142+
if (!parseMaterial(*material, material_xml, false))
143+
throw ParseError("");
144+
if (const MaterialSharedPtr& other = model->getMaterial(material->name))
131145
{
132-
CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
133-
material.reset();
134-
model.reset();
135-
return model;
146+
if (*material != *other) // accept redefinition of same material
147+
{
148+
CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
149+
throw ParseError("");
150+
}
136151
}
137152
else
138153
{

urdf_parser/test/urdf_unit_test.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,57 @@ TEST(URDF_UNIT_TEST, parse_color_doubles)
332332
EXPECT_EQ(0.908, urdf->links_["l1"]->inertial->izz);
333333
}
334334

335+
TEST(URDF_UNIT_TEST, parse_duplicate_materials)
336+
{
337+
std::string urdf_str =
338+
"<robot name=\"test\">"
339+
" <material name=\"red\">"
340+
" <color rgba=\"1 0 0 1\"/>"
341+
" </material>"
342+
" <material name=\"red\">"
343+
" <color rgba=\"1 0 0 1\"/>"
344+
" </material>"
345+
" <link name=\"dummy\"/>"
346+
"</robot>";
347+
348+
urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
349+
EXPECT_TRUE(static_cast<bool>(urdf)); // identical materials are fine
350+
351+
urdf_str =
352+
"<robot name=\"test\">"
353+
" <material name=\"red\">"
354+
" <color rgba=\"1 0 0 1\"/>"
355+
" </material>"
356+
" <material name=\"red\">"
357+
" <color rgba=\"0 1 0 1\"/>"
358+
" </material>"
359+
" <link name=\"dummy\"/>"
360+
"</robot>";
361+
urdf = urdf::parseURDF(urdf_str);
362+
EXPECT_FALSE(static_cast<bool>(urdf)); // different materials cause failure
363+
}
364+
365+
TEST(URDF_UNIT_TEST, parse_invalid_materials)
366+
{
367+
std::string urdf_str =
368+
"<robot name=\"test\">"
369+
" <material missing_name=\"red\">"
370+
" <color rgba=\"1 0 0 1\"/>"
371+
" </material>"
372+
" <link name=\"dummy\"/>"
373+
"</robot>";
374+
375+
urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
376+
EXPECT_FALSE(static_cast<bool>(urdf));
377+
378+
urdf_str =
379+
"<robot name=\"test\">"
380+
" <material name=\"red\"/>"
381+
" <link name=\"dummy\"/>"
382+
"</robot>";
383+
urdf = urdf::parseURDF(urdf_str);
384+
EXPECT_FALSE(static_cast<bool>(urdf)); // different materials cause failure
385+
}
335386

336387
int main(int argc, char **argv)
337388
{

0 commit comments

Comments
 (0)