Skip to content

Commit e787fc8

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 47eb7d4 commit e787fc8

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

urdf_parser/src/model.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,19 @@ bool assignMaterial(const VisualSharedPtr& visual, ModelInterfaceSharedPtr& mode
8888
return true;
8989
}
9090

91+
bool operator==(const Material& lhs, const Material& rhs)
92+
{
93+
return lhs.texture_filename == rhs.texture_filename &&
94+
lhs.color.r == rhs.color.r &&
95+
lhs.color.g == rhs.color.g &&
96+
lhs.color.b == rhs.color.b &&
97+
lhs.color.a == rhs.color.a;
98+
}
99+
inline bool operator!=(const Material& lhs, const Material& rhs)
100+
{
101+
return !(lhs == rhs);
102+
}
103+
91104
ModelInterfaceSharedPtr parseURDF(const std::string &xml_string)
92105
{
93106
ModelInterfaceSharedPtr model(new ModelInterface);
@@ -146,19 +159,20 @@ ModelInterfaceSharedPtr parseURDF(const std::string &xml_string)
146159
try {
147160
success = parseMaterial(*material, material_xml, false); // material needs to be fully defined here
148161
} catch(ParseError &) {
162+
CONSOLE_BRIDGE_logError("material xml is not initialized correctly");
149163
success = false;
150164
}
151165

152-
if (!success) {
153-
CONSOLE_BRIDGE_logError("material xml is not initialized correctly");
154-
material.reset();
155-
model.reset();
156-
return model;
166+
if (const MaterialSharedPtr& other = model->getMaterial(material->name))
167+
{
168+
if (*material != *other)
169+
{
170+
CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
171+
success = false;
172+
}
157173
}
158174

159-
if (model->getMaterial(material->name))
160-
{
161-
CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
175+
if (!success) {
162176
material.reset();
163177
model.reset();
164178
return model;

urdf_parser/test/urdf_unit_test.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,47 @@ TEST(URDF_UNIT_TEST, material_no_name)
331331
ASSERT_EQ(nullptr, urdf);
332332
}
333333

334+
TEST(URDF_UNIT_TEST, materials_no_rgb)
335+
{
336+
std::string urdf_str =
337+
"<robot name=\"test\">"
338+
" <material name=\"red\"/>"
339+
" <link name=\"dummy\"/>"
340+
"</robot>";
341+
urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
342+
EXPECT_FALSE(static_cast<bool>(urdf)); // different materials cause failure
343+
}
344+
345+
TEST(URDF_UNIT_TEST, duplicate_materials)
346+
{
347+
std::string urdf_str =
348+
"<robot name=\"test\">"
349+
" <material name=\"red\">"
350+
" <color rgba=\"1 0 0 1\"/>"
351+
" </material>"
352+
" <material name=\"red\">"
353+
" <color rgba=\"1 0 0 1\"/>"
354+
" </material>"
355+
" <link name=\"dummy\"/>"
356+
"</robot>";
357+
358+
urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
359+
EXPECT_TRUE(static_cast<bool>(urdf)); // identical materials are fine
360+
361+
urdf_str =
362+
"<robot name=\"test\">"
363+
" <material name=\"red\">"
364+
" <color rgba=\"1 0 0 1\"/>"
365+
" </material>"
366+
" <material name=\"red\">"
367+
" <color rgba=\"0 1 0 1\"/>"
368+
" </material>"
369+
" <link name=\"dummy\"/>"
370+
"</robot>";
371+
urdf = urdf::parseURDF(urdf_str);
372+
EXPECT_FALSE(static_cast<bool>(urdf)); // different materials cause failure
373+
}
374+
334375
TEST(URDF_UNIT_TEST, link_no_name)
335376
{
336377
std::string joint_str =

0 commit comments

Comments
 (0)