Skip to content

Commit 9ebb53a

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 bb16265 commit 9ebb53a

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
@@ -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);
@@ -129,19 +142,20 @@ ModelInterfaceSharedPtr parseURDF(const std::string &xml_string)
129142
try {
130143
success = parseMaterial(*material, material_xml, false); // material needs to be fully defined here
131144
} catch(ParseError &) {
145+
CONSOLE_BRIDGE_logError("material xml is not initialized correctly");
132146
success = false;
133147
}
134148

135-
if (!success) {
136-
CONSOLE_BRIDGE_logError("material xml is not initialized correctly");
137-
material.reset();
138-
model.reset();
139-
return model;
149+
if (const MaterialSharedPtr& other = model->getMaterial(material->name))
150+
{
151+
if (*material != *other)
152+
{
153+
CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
154+
success = false;
155+
}
140156
}
141157

142-
if (model->getMaterial(material->name))
143-
{
144-
CONSOLE_BRIDGE_logError("material '%s' is not unique.", material->name.c_str());
158+
if (!success) {
145159
material.reset();
146160
model.reset();
147161
return model;

urdf_parser/test/urdf_unit_test.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,47 @@ TEST(URDF_UNIT_TEST, material_no_name)
317317
ASSERT_EQ(nullptr, urdf);
318318
}
319319

320+
TEST(URDF_UNIT_TEST, materials_no_rgb)
321+
{
322+
std::string urdf_str =
323+
"<robot name=\"test\">"
324+
" <material name=\"red\"/>"
325+
" <link name=\"dummy\"/>"
326+
"</robot>";
327+
urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
328+
EXPECT_FALSE(static_cast<bool>(urdf)); // different materials cause failure
329+
}
330+
331+
TEST(URDF_UNIT_TEST, duplicate_materials)
332+
{
333+
std::string urdf_str =
334+
"<robot name=\"test\">"
335+
" <material name=\"red\">"
336+
" <color rgba=\"1 0 0 1\"/>"
337+
" </material>"
338+
" <material name=\"red\">"
339+
" <color rgba=\"1 0 0 1\"/>"
340+
" </material>"
341+
" <link name=\"dummy\"/>"
342+
"</robot>";
343+
344+
urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
345+
EXPECT_TRUE(static_cast<bool>(urdf)); // identical materials are fine
346+
347+
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=\"0 1 0 1\"/>"
354+
" </material>"
355+
" <link name=\"dummy\"/>"
356+
"</robot>";
357+
urdf = urdf::parseURDF(urdf_str);
358+
EXPECT_FALSE(static_cast<bool>(urdf)); // different materials cause failure
359+
}
360+
320361
TEST(URDF_UNIT_TEST, link_no_name)
321362
{
322363
std::string joint_str =

0 commit comments

Comments
 (0)