Skip to content
Open
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
25 changes: 25 additions & 0 deletions urdf_parser/src/link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ bool parseSphere(Sphere &s, tinyxml2::XMLElement *c)
return false;
}

if (!std::isfinite(s.radius) || s.radius <= 0)
{
CONSOLE_BRIDGE_logError("Sphere radius must be a positive finite value");
return false;
}

return true;
}

Expand All @@ -150,6 +156,13 @@ bool parseBox(Box &b, tinyxml2::XMLElement *c)
CONSOLE_BRIDGE_logError("%s", e.what());
return false;
}

if (b.dim.x <= 0 || b.dim.y <= 0 || b.dim.z <= 0)
{
CONSOLE_BRIDGE_logError("Box size must be positive finite values");
return false;
}

return true;
}

Expand Down Expand Up @@ -183,6 +196,12 @@ bool parseCylinder(Cylinder &y, tinyxml2::XMLElement *c)
return false;
}

if (!std::isfinite(y.length) || !std::isfinite(y.radius) || y.length <= 0 || y.radius <= 0)
{
CONSOLE_BRIDGE_logError("Cylinder length and radius must be positive finite values");
return false;
}

return true;
}

Expand Down Expand Up @@ -246,6 +265,12 @@ bool parseCapsule(Capsule &c, tinyxml2::XMLElement *elem)
return false;
}

if (!std::isfinite(c.length) || !std::isfinite(c.radius) || c.length <= 0 || c.radius <= 0)
{
CONSOLE_BRIDGE_logError("Capsule length and radius must be positive finite values");
return false;
}

return true;
}

Expand Down
49 changes: 44 additions & 5 deletions urdf_parser/test/urdf_schema_capsule_geometry_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,55 @@ TEST(URDF_UNIT_TEST, parse_capsule_geometry_zero_values)
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
// Invalid radius/length causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, parse_capsule_geometry_negative_radius_fails)
{
std::string urdf_str = R"urdf(
<robot name="capsule_negative_test" version="1.1">
<link name="link1">
<visual>
<geometry>
<capsule radius="-0.05" length="0.5"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
// Negative radius causes geometry parsing to fail, visual is empty
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

std::shared_ptr<urdf::Capsule> capsule =
std::dynamic_pointer_cast<urdf::Capsule>(link->visual_array[0]->geometry);
ASSERT_NE(nullptr, capsule);
EXPECT_DOUBLE_EQ(0.0, capsule->radius);
EXPECT_DOUBLE_EQ(0.0, capsule->length);
TEST(URDF_UNIT_TEST, parse_capsule_geometry_negative_length_fails)
{
std::string urdf_str = R"urdf(
<robot name="capsule_negative_length_test" version="1.1">
<link name="link1">
<visual>
<geometry>
<capsule radius="0.05" length="-0.5"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);
// Negative length causes geometry parsing to fail, visual is empty
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, parse_capsule_geometry_missing_radius_fails)
Expand Down
183 changes: 183 additions & 0 deletions urdf_parser/test/urdf_unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,189 @@ TEST(URDF_UNIT_TEST, parse_color_doubles)
EXPECT_EQ(0.908, urdf->links_["l1"]->inertial->izz);
}

TEST(URDF_UNIT_TEST, negative_sphere_radius_fails)
{
std::string urdf_str = R"urdf(
<robot name="negative_sphere_test">
<link name="link1">
<visual>
<geometry>
<sphere radius="-0.5"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Invalid radius causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, zero_as_sphere_radius_fails)
{
std::string urdf_str = R"urdf(
<robot name="zero_sphere_test">
<link name="link1">
<visual>
<geometry>
<sphere radius="0.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Invalid radius causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, negative_box_size_fails)
{
std::string urdf_str = R"urdf(
<robot name="negative_box_test">
<link name="link1">
<visual>
<geometry>
<box size="1.0 -2.0 3.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Negative size causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, zero_box_size_fails)
{
std::string urdf_str = R"urdf(
<robot name="zero_box_test">
<link name="link1">
<visual>
<geometry>
<box size="1.0 0.0 3.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Zero size causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, negative_cylinder_radius_fails)
{
std::string urdf_str = R"urdf(
<robot name="negative_cylinder_test">
<link name="link1">
<visual>
<geometry>
<cylinder radius="-0.5" length="1.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Negative radius causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, negative_cylinder_length_fails)
{
std::string urdf_str = R"urdf(
<robot name="negative_cylinder_length_test">
<link name="link1">
<visual>
<geometry>
<cylinder radius="0.5" length="-1.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Negative length causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, zero_cylinder_radius_fails)
{
std::string urdf_str = R"urdf(
<robot name="zero_cylinder_test">
<link name="link1">
<visual>
<geometry>
<cylinder radius="0.0" length="1.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Zero radius causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

TEST(URDF_UNIT_TEST, zero_cylinder_length_fails)
{
std::string urdf_str = R"urdf(
<robot name="zero_cylinder_length_test">
<link name="link1">
<visual>
<geometry>
<cylinder radius="0.5" length="0.0"/>
</geometry>
</visual>
</link>
</robot>
)urdf";

urdf::ModelInterfaceSharedPtr urdf = urdf::parseURDF(urdf_str);

// Zero length causes geometry parsing to fail
ASSERT_NE(nullptr, urdf);
urdf::LinkConstSharedPtr link = urdf->getLink("link1");
ASSERT_NE(nullptr, link);
EXPECT_TRUE(link->visual_array.empty());
}

int main(int argc, char **argv)
{
Expand Down