Skip to content

Commit 5cf6b91

Browse files
Levi ArmstrongLevi-Armstrong
authored andcommitted
Add ToolCenterPoint unit tests
1 parent 4844c7a commit 5cf6b91

File tree

3 files changed

+246
-5
lines changed

3 files changed

+246
-5
lines changed

tesseract_common/include/tesseract_common/manipulator_info.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class ToolCenterPoint
103103
* @param external_frame If an external tcp was defined as an Isometry then an external can be provided. If empty
104104
* assumed relative to world.
105105
*/
106-
void setExternal(bool value, std::string external_frame);
106+
void setExternal(bool value, std::string external_frame = "");
107107

108108
/**
109109
* @brief If an external tcp was defined as an Isometry then an external frame can be provided.
@@ -133,6 +133,7 @@ class ToolCenterPoint
133133
ret_val &= (external_frame_ == other.external_frame_);
134134
return ret_val;
135135
}
136+
bool operator!=(const ToolCenterPoint& rhs) const { return !operator==(rhs); }
136137

137138
protected:
138139
int type_{ 0 };
@@ -214,6 +215,7 @@ struct ManipulatorInfo
214215
ret_val &= (working_frame == other.working_frame);
215216
return ret_val;
216217
}
218+
bool operator!=(const ManipulatorInfo& rhs) const { return !operator==(rhs); }
217219

218220
private:
219221
friend class boost::serialization::access;

tesseract_common/src/manipulator_info.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,36 @@ bool ToolCenterPoint::isString() const { return (type_ == 1); }
4848
bool ToolCenterPoint::isTransform() const { return (type_ == 2); }
4949
bool ToolCenterPoint::isExternal() const { return external_; }
5050

51-
const std::string& ToolCenterPoint::getExternalFrame() const { return external_frame_; }
51+
const std::string& ToolCenterPoint::getExternalFrame() const
52+
{
53+
if (isTransform() && external_)
54+
return external_frame_;
55+
56+
throw std::runtime_error("ToolCenterPoint: Called getExternalFrame for invalid type.");
57+
}
5258
void ToolCenterPoint::setExternal(bool value, std::string external_frame)
5359
{
5460
external_ = value;
55-
external_frame_ = std::move(external_frame);
61+
62+
// External frame is only valid when a Isometry3d tcp is provided.
63+
if (isTransform() && value)
64+
external_frame_ = std::move(external_frame);
65+
else
66+
external_frame_.clear();
5667
}
5768

5869
const std::string& ToolCenterPoint::getString() const
5970
{
60-
assert(type_ == 1);
71+
if (type_ != 1)
72+
throw std::runtime_error("ToolCenterPoint: Called getString for invalid type.");
73+
6174
return name_;
6275
}
6376
const Eigen::Isometry3d& ToolCenterPoint::getTransform() const
6477
{
65-
assert(type_ == 2);
78+
if (type_ != 2)
79+
throw std::runtime_error("ToolCenterPoint: Called getTransform for invalid type.");
80+
6681
return transform_;
6782
}
6883

tesseract_common/test/tesseract_common_unit.cpp

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,90 @@ TEST(TesseractCommonUnit, bytesResource)
242242
EXPECT_EQ(bytes_resource->getResourceContents().size(), data.size());
243243
}
244244

245+
TEST(TesseractCommonUnit, ToolCenterPoint)
246+
{
247+
{ // Empty tcp
248+
tesseract_common::ToolCenterPoint tcp;
249+
EXPECT_TRUE(tcp.empty());
250+
EXPECT_FALSE(tcp.isString());
251+
EXPECT_FALSE(tcp.isTransform());
252+
EXPECT_FALSE(tcp.isExternal());
253+
EXPECT_ANY_THROW(tcp.getString());
254+
EXPECT_ANY_THROW(tcp.getTransform());
255+
EXPECT_ANY_THROW(tcp.getExternalFrame());
256+
}
257+
258+
{ // The tcp is a link attached to the tip of the kinematic chain
259+
tesseract_common::ToolCenterPoint tcp("tcp_link");
260+
EXPECT_FALSE(tcp.empty());
261+
EXPECT_TRUE(tcp.isString());
262+
EXPECT_FALSE(tcp.isTransform());
263+
EXPECT_FALSE(tcp.isExternal());
264+
EXPECT_EQ(tcp.getString(), "tcp_link");
265+
EXPECT_ANY_THROW(tcp.getTransform());
266+
EXPECT_ANY_THROW(tcp.getExternalFrame());
267+
}
268+
269+
{ // The tcp is external
270+
tesseract_common::ToolCenterPoint tcp("external_tcp_link", true);
271+
EXPECT_FALSE(tcp.empty());
272+
EXPECT_TRUE(tcp.isString());
273+
EXPECT_FALSE(tcp.isTransform());
274+
EXPECT_TRUE(tcp.isExternal());
275+
EXPECT_EQ(tcp.getString(), "external_tcp_link");
276+
EXPECT_ANY_THROW(tcp.getTransform());
277+
EXPECT_ANY_THROW(tcp.getExternalFrame());
278+
279+
tcp.setExternal(false);
280+
EXPECT_FALSE(tcp.isExternal());
281+
EXPECT_ANY_THROW(tcp.getExternalFrame());
282+
283+
tcp.setExternal(true, "should_not_add");
284+
EXPECT_TRUE(tcp.isExternal());
285+
EXPECT_ANY_THROW(tcp.getExternalFrame());
286+
}
287+
288+
{ // TCP as transform
289+
Eigen::Isometry3d pose = Eigen::Isometry3d::Identity();
290+
pose.translation() = Eigen::Vector3d(0, 0, 0.25);
291+
292+
tesseract_common::ToolCenterPoint tcp(pose);
293+
EXPECT_FALSE(tcp.empty());
294+
EXPECT_FALSE(tcp.isString());
295+
EXPECT_TRUE(tcp.isTransform());
296+
EXPECT_FALSE(tcp.isExternal());
297+
EXPECT_TRUE(tcp.getTransform().isApprox(pose, 1e-6));
298+
EXPECT_ANY_THROW(tcp.getString());
299+
EXPECT_ANY_THROW(tcp.getExternalFrame());
300+
}
301+
}
302+
303+
TEST(TesseractCommonUnit, ManipulatorInfo)
304+
{
305+
// Empty tcp
306+
tesseract_common::ManipulatorInfo manip_info;
307+
EXPECT_TRUE(manip_info.empty());
308+
EXPECT_TRUE(manip_info.tcp.empty());
309+
EXPECT_TRUE(manip_info.manipulator.empty());
310+
EXPECT_TRUE(manip_info.manipulator_ik_solver.empty());
311+
EXPECT_TRUE(manip_info.working_frame.empty());
312+
313+
Eigen::Isometry3d pose = Eigen::Isometry3d::Identity();
314+
pose.translation() = Eigen::Vector3d(0, 0, 0.25);
315+
316+
tesseract_common::ManipulatorInfo manip_info_override("manipulator");
317+
manip_info_override.tcp = tesseract_common::ToolCenterPoint(pose);
318+
manip_info_override.manipulator_ik_solver = "OPWInvKin";
319+
manip_info_override.working_frame = "tool0";
320+
321+
manip_info = manip_info.getCombined(manip_info_override);
322+
EXPECT_FALSE(manip_info.empty());
323+
EXPECT_TRUE(manip_info.tcp == manip_info_override.tcp);
324+
EXPECT_EQ(manip_info.manipulator, manip_info_override.manipulator);
325+
EXPECT_EQ(manip_info.manipulator_ik_solver, manip_info_override.manipulator_ik_solver);
326+
EXPECT_EQ(manip_info.working_frame, manip_info_override.working_frame);
327+
}
328+
245329
TEST(TesseractCommonUnit, serializationToolCenterPoint)
246330
{
247331
Eigen::Isometry3d pose = Eigen::Isometry3d::Identity();
@@ -351,6 +435,75 @@ TEST(TesseractCommonUnit, serializationKinematicLimits)
351435

352436
TEST(TesseractCommonUnit, serializationVectorXd)
353437
{
438+
{ // Serialize empty object
439+
Eigen::VectorXd ev;
440+
441+
{
442+
std::ofstream os("/tmp/eigen_vector_xd_boost.xml");
443+
boost::archive::xml_oarchive oa(os);
444+
oa << BOOST_SERIALIZATION_NVP(ev);
445+
}
446+
447+
Eigen::VectorXd nev;
448+
{
449+
std::ifstream ifs("/tmp/eigen_vector_xd_boost.xml");
450+
assert(ifs.good());
451+
boost::archive::xml_iarchive ia(ifs);
452+
453+
// restore the schedule from the archive
454+
ia >> BOOST_SERIALIZATION_NVP(nev);
455+
}
456+
}
457+
458+
// Serialize to object which already has data
459+
for (int i = 0; i < 5; ++i)
460+
{
461+
Eigen::VectorXd ev = Eigen::VectorXd::Random(6);
462+
463+
{
464+
std::ofstream os("/tmp/eigen_vector_xd_boost.xml");
465+
boost::archive::xml_oarchive oa(os);
466+
oa << BOOST_SERIALIZATION_NVP(ev);
467+
}
468+
469+
Eigen::VectorXd nev = Eigen::VectorXd::Random(6);
470+
{
471+
std::ifstream ifs("/tmp/eigen_vector_xd_boost.xml");
472+
assert(ifs.good());
473+
boost::archive::xml_iarchive ia(ifs);
474+
475+
// restore the schedule from the archive
476+
ia >> BOOST_SERIALIZATION_NVP(nev);
477+
}
478+
479+
EXPECT_TRUE(ev.isApprox(nev, 1e-5));
480+
}
481+
482+
// Serialize to object which already has data and different size
483+
for (int i = 0; i < 5; ++i)
484+
{
485+
Eigen::VectorXd ev = Eigen::VectorXd::Random(6);
486+
487+
{
488+
std::ofstream os("/tmp/eigen_vector_xd_boost.xml");
489+
boost::archive::xml_oarchive oa(os);
490+
oa << BOOST_SERIALIZATION_NVP(ev);
491+
}
492+
493+
Eigen::VectorXd nev = Eigen::VectorXd::Random(3);
494+
{
495+
std::ifstream ifs("/tmp/eigen_vector_xd_boost.xml");
496+
assert(ifs.good());
497+
boost::archive::xml_iarchive ia(ifs);
498+
499+
// restore the schedule from the archive
500+
ia >> BOOST_SERIALIZATION_NVP(nev);
501+
}
502+
503+
EXPECT_TRUE(ev.isApprox(nev, 1e-5));
504+
}
505+
506+
// Default use case
354507
for (int i = 0; i < 5; ++i)
355508
{
356509
Eigen::VectorXd ev = Eigen::VectorXd::Random(6);
@@ -377,6 +530,77 @@ TEST(TesseractCommonUnit, serializationVectorXd)
377530

378531
TEST(TesseractCommonUnit, serializationMatrixX2d)
379532
{
533+
{ // Serialize empty
534+
Eigen::MatrixX2d em;
535+
536+
{
537+
std::ofstream os("/tmp/eigen_matrix_x2d_boost.xml");
538+
boost::archive::xml_oarchive oa(os);
539+
oa << BOOST_SERIALIZATION_NVP(em);
540+
}
541+
542+
Eigen::MatrixX2d nem;
543+
{
544+
std::ifstream ifs("/tmp/eigen_matrix_x2d_boost.xml");
545+
assert(ifs.good());
546+
boost::archive::xml_iarchive ia(ifs);
547+
548+
// restore the schedule from the archive
549+
ia >> BOOST_SERIALIZATION_NVP(nem);
550+
}
551+
552+
EXPECT_TRUE(em.isApprox(nem, 1e-5));
553+
}
554+
555+
// Serialize to object which already has data
556+
for (int i = 0; i < 5; ++i)
557+
{
558+
Eigen::MatrixX2d em = Eigen::MatrixX2d::Random(4, 2);
559+
560+
{
561+
std::ofstream os("/tmp/eigen_matrix_x2d_boost.xml");
562+
boost::archive::xml_oarchive oa(os);
563+
oa << BOOST_SERIALIZATION_NVP(em);
564+
}
565+
566+
Eigen::MatrixX2d nem = Eigen::MatrixX2d::Random(4, 2);
567+
{
568+
std::ifstream ifs("/tmp/eigen_matrix_x2d_boost.xml");
569+
assert(ifs.good());
570+
boost::archive::xml_iarchive ia(ifs);
571+
572+
// restore the schedule from the archive
573+
ia >> BOOST_SERIALIZATION_NVP(nem);
574+
}
575+
576+
EXPECT_TRUE(em.isApprox(nem, 1e-5));
577+
}
578+
579+
// Serialize to object which already has data and different size
580+
for (int i = 0; i < 5; ++i)
581+
{
582+
Eigen::MatrixX2d em = Eigen::MatrixX2d::Random(4, 2);
583+
584+
{
585+
std::ofstream os("/tmp/eigen_matrix_x2d_boost.xml");
586+
boost::archive::xml_oarchive oa(os);
587+
oa << BOOST_SERIALIZATION_NVP(em);
588+
}
589+
590+
Eigen::MatrixX2d nem = Eigen::MatrixX2d::Random(2, 2);
591+
{
592+
std::ifstream ifs("/tmp/eigen_matrix_x2d_boost.xml");
593+
assert(ifs.good());
594+
boost::archive::xml_iarchive ia(ifs);
595+
596+
// restore the schedule from the archive
597+
ia >> BOOST_SERIALIZATION_NVP(nem);
598+
}
599+
600+
EXPECT_TRUE(em.isApprox(nem, 1e-5));
601+
}
602+
603+
// Default
380604
for (int i = 0; i < 5; ++i)
381605
{
382606
Eigen::MatrixX2d em = Eigen::MatrixX2d::Random(4, 2);

0 commit comments

Comments
 (0)