26 #ifndef TESSERACT_KINEMATICS_KIN_TEST_SUITE_H
27 #define TESSERACT_KINEMATICS_KIN_TEST_SUITE_H
31 #include <gtest/gtest.h>
33 #include <yaml-cpp/yaml.h>
49 #include <tesseract_urdf/urdf_parser.h>
57 std::string path = locator.
locateResource(
"package://tesseract_support/urdf/lbr_iiwa_14_r820.urdf")->getFilePath();
58 return tesseract_urdf::parseURDFFile(path, locator);
65 locator.
locateResource(
"package://tesseract_support/urdf/abb_irb2400_external_positioner.urdf")->getFilePath();
66 return tesseract_urdf::parseURDFFile(path, locator);
73 locator.
locateResource(
"package://tesseract_support/urdf/abb_irb2400_on_positioner.urdf")->getFilePath();
74 return tesseract_urdf::parseURDFFile(path, locator);
79 std::string path = locator.
locateResource(
"package://tesseract_support/urdf/abb_irb2400.urdf")->getFilePath();
80 return tesseract_urdf::parseURDFFile(path, locator);
85 std::string path = locator.
locateResource(
"package://tesseract_support/urdf/iiwa7.urdf")->getFilePath();
86 return tesseract_urdf::parseURDFFile(path, locator);
90 double shoulder_offset,
95 auto sg = std::make_unique<SceneGraph>(
"universal_robot");
96 sg->addLink(
Link(
"base_link"));
97 sg->addLink(
Link(
"shoulder_link"));
98 sg->addLink(
Link(
"upper_arm_link"));
99 sg->addLink(
Link(
"forearm_link"));
100 sg->addLink(
Link(
"wrist_1_link"));
101 sg->addLink(
Link(
"wrist_2_link"));
102 sg->addLink(
Link(
"wrist_3_link"));
103 sg->addLink(
Link(
"ee_link"));
104 sg->addLink(
Link(
"tool0"));
107 Joint j(
"shoulder_pan_joint");
108 j.
type = JointType::REVOLUTE;
111 j.
axis = Eigen::Vector3d::UnitZ();
113 j.
limits = std::make_shared<JointLimits>();
114 j.
limits->lower = -2.0 * M_PI;
115 j.
limits->upper = 2.0 * M_PI;
116 j.
limits->velocity = 2.16;
122 Joint j(
"shoulder_lift_joint");
123 j.
type = JointType::REVOLUTE;
126 j.
axis = Eigen::Vector3d::UnitY();
130 j.
limits = std::make_shared<JointLimits>();
131 j.
limits->lower = -2.0 * M_PI;
132 j.
limits->upper = 2.0 * M_PI;
133 j.
limits->velocity = 2.16;
139 Joint j(
"elbow_joint");
140 j.
type = JointType::REVOLUTE;
143 j.
axis = Eigen::Vector3d::UnitY();
145 j.
limits = std::make_shared<JointLimits>();
146 j.
limits->lower = -2.0 * M_PI;
147 j.
limits->upper = 2.0 * M_PI;
148 j.
limits->velocity = 2.16;
154 Joint j(
"wrist_1_joint");
155 j.
type = JointType::REVOLUTE;
158 j.
axis = Eigen::Vector3d::UnitY();
162 j.
limits = std::make_shared<JointLimits>();
163 j.
limits->lower = -2.0 * M_PI;
164 j.
limits->upper = 2.0 * M_PI;
165 j.
limits->velocity = 2.16;
171 Joint j(
"wrist_2_joint");
172 j.
type = JointType::REVOLUTE;
175 j.
axis = Eigen::Vector3d::UnitZ();
177 Eigen::Vector3d(0, params.
d4 - elbow_offset - shoulder_offset, 0);
178 j.
limits = std::make_shared<JointLimits>();
179 j.
limits->lower = -2.0 * M_PI;
180 j.
limits->upper = 2.0 * M_PI;
181 j.
limits->velocity = 2.16;
187 Joint j(
"wrist_3_joint");
188 j.
type = JointType::REVOLUTE;
191 j.
axis = Eigen::Vector3d::UnitY();
193 j.
limits = std::make_shared<JointLimits>();
194 j.
limits->lower = -2.0 * M_PI;
195 j.
limits->upper = 2.0 * M_PI;
196 j.
limits->velocity = 2.16;
202 Joint j(
"ee_fixed_joint");
203 j.
type = JointType::FIXED;
213 Joint j(
"wrist_3_link-tool0_fixed_joint");
214 j.
type = JointType::FIXED;
227 const std::vector<std::string>& joint_names)
229 auto s =
static_cast<Eigen::Index
>(joint_names.size());
234 for (Eigen::Index i = 0; i < s; ++i)
236 auto joint = scene_graph.
getJoint(joint_names[
static_cast<std::size_t
>(i)]);
261 const Eigen::VectorXd& jvals,
262 const std::string& link_name,
263 const Eigen::Vector3d& link_point,
264 const Eigen::Isometry3d& change_base)
266 Eigen::MatrixXd jacobian, numerical_jacobian;
276 numerical_jacobian.resize(6, kin.
numJoints());
279 for (
int i = 0; i < 6; ++i)
280 for (
int j = 0; j < static_cast<int>(kin.
numJoints()); ++j)
281 EXPECT_NEAR(numerical_jacobian(i, j), jacobian(i, j), 1e-3);
294 const Eigen::VectorXd& jvals,
295 const std::string& link_name,
296 const Eigen::Vector3d& link_point)
298 Eigen::MatrixXd jacobian, numerical_jacobian;
299 jacobian.resize(6, kin_group.
numJoints());
302 jacobian = kin_group.
calcJacobian(jvals, link_name, link_point);
304 numerical_jacobian.resize(6, kin_group.
numJoints());
306 numerical_jacobian, Eigen::Isometry3d::Identity(), kin_group, jvals, link_name, link_point);
308 for (
int i = 0; i < 6; ++i)
309 for (
int j = 0; j < static_cast<int>(kin_group.
numJoints()); ++j)
310 EXPECT_NEAR(numerical_jacobian(i, j), jacobian(i, j), 1e-3);
316 numerical_jacobian.resize(6, kin_group.
numJoints());
318 numerical_jacobian, Eigen::Isometry3d::Identity(), kin_group, jvals, link_name, Eigen::Vector3d::Zero());
320 for (
int i = 0; i < 6; ++i)
321 for (
int j = 0; j < static_cast<int>(kin_group.
numJoints()); ++j)
322 EXPECT_NEAR(numerical_jacobian(i, j), jacobian(i, j), 1e-3);
327 for (
const auto& static_link_name : static_link_names)
330 jacobian = kin_group.
calcJacobian(jvals, static_link_name, link_name, link_point);
332 numerical_jacobian.resize(6, kin_group.
numJoints());
334 numerical_jacobian, poses.at(static_link_name).inverse(), kin_group, jvals, link_name, link_point);
336 for (
int i = 0; i < 6; ++i)
337 for (
int j = 0; j < static_cast<int>(kin_group.
numJoints()); ++j)
338 EXPECT_NEAR(numerical_jacobian(i, j), jacobian(i, j), 1e-3);
342 jacobian = kin_group.
calcJacobian(jvals, static_link_name, link_name);
344 numerical_jacobian.resize(6, kin_group.
numJoints());
346 poses.at(static_link_name).inverse(),
350 Eigen::Vector3d::Zero());
352 for (
int i = 0; i < 6; ++i)
353 for (
int j = 0; j < static_cast<int>(kin_group.
numJoints()); ++j)
354 EXPECT_NEAR(numerical_jacobian(i, j), jacobian(i, j), 1e-3);
376 for (Eigen::Index i = 0; i < limits.
joint_limits.rows(); ++i)
408 for (Eigen::Index i = 0; i < limits.
joint_limits.rows(); ++i)
428 EXPECT_ANY_THROW(kin_group.
setLimits(limits_empty));
437 const std::vector<std::string>& target_names)
439 EXPECT_EQ(names.size(), target_names.size());
440 EXPECT_FALSE(names.empty());
441 EXPECT_FALSE(target_names.empty());
443 std::vector<std::string> v1 = names;
444 std::vector<std::string> v2 = target_names;
445 std::sort(v1.begin(), v1.end());
446 std::sort(v2.begin(), v2.end());
447 EXPECT_TRUE(std::equal(v1.begin(), v1.end(), v2.begin()));
460 const Eigen::Isometry3d& target_pose,
461 const std::string& tip_link_name,
462 const Eigen::VectorXd& seed)
470 EXPECT_TRUE(!solutions.empty());
472 for (
const auto& sol : solutions)
475 Eigen::Isometry3d result = result_poses[tip_link_name];
476 EXPECT_TRUE(target_pose.translation().isApprox(result.translation(), 1e-4));
478 Eigen::Quaterniond rot_pose(target_pose.rotation());
479 Eigen::Quaterniond rot_result(result.rotation());
480 EXPECT_TRUE(rot_pose.isApprox(rot_result, 1e-3));
491 const Eigen::Isometry3d& target_pose,
492 const std::string& working_frame,
493 const std::string& tip_link_name,
494 const Eigen::VectorXd& seed)
501 EXPECT_TRUE(!solutions.empty());
503 for (
const auto& sol : solutions)
506 Eigen::Isometry3d result = result_poses.at(working_frame).inverse() * result_poses[tip_link_name];
507 EXPECT_TRUE(target_pose.translation().isApprox(result.translation(), 1e-4));
509 Eigen::Quaterniond rot_pose(target_pose.rotation());
510 Eigen::Quaterniond rot_result(result.rotation());
511 EXPECT_TRUE(rot_pose.isApprox(rot_result, 1e-3));
523 Eigen::VectorXd jvals;
529 EXPECT_EQ(poses.size(), 1);
530 Eigen::Isometry3d pose = poses.at(
"tool0");
531 Eigen::Isometry3d result;
532 result.setIdentity();
533 result.translation()[0] = 0;
534 result.translation()[1] = 0;
535 result.translation()[2] = 1.306;
536 EXPECT_TRUE(pose.isApprox(result));
542 std::string tip_link =
"tool0";
543 std::string base_link =
"base_link";
548 Eigen::VectorXd jvals;
551 jvals(0) = -0.785398;
553 jvals(2) = -0.785398;
555 jvals(4) = -0.785398;
557 jvals(6) = -0.785398;
562 Eigen::Vector3d link_point(0, 0, 0);
563 runJacobianTest(kin, jvals, tip_link, link_point, Eigen::Isometry3d::Identity());
565 EXPECT_ANY_THROW(
runJacobianTest(kin, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
570 for (
int k = 0; k < 3; ++k)
572 Eigen::Vector3d link_point(0, 0, 0);
575 runJacobianTest(kin, jvals, tip_link, link_point, Eigen::Isometry3d::Identity());
577 EXPECT_ANY_THROW(
runJacobianTest(kin, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
583 for (
int k = 0; k < 3; ++k)
585 link_point = Eigen::Vector3d(0, 0, 0);
586 Eigen::Isometry3d change_base;
587 change_base.setIdentity();
588 change_base(0, 0) = 0;
589 change_base(1, 0) = 1;
590 change_base(0, 1) = -1;
591 change_base(1, 1) = 0;
592 change_base.translation() = Eigen::Vector3d(0, 0, 0);
593 change_base.translation()[k] = 1;
597 EXPECT_ANY_THROW(
runJacobianTest(kin, jvals,
"", link_point, change_base));
603 for (
int k = 0; k < 3; ++k)
605 Eigen::Vector3d link_point(0, 0, 0);
608 Eigen::Isometry3d change_base;
609 change_base.setIdentity();
610 change_base(0, 0) = 0;
611 change_base(1, 0) = 1;
612 change_base(0, 1) = -1;
613 change_base(1, 1) = 0;
614 change_base.translation() = link_point;
618 EXPECT_ANY_THROW(
runJacobianTest(kin, jvals,
"", link_point, change_base));
624 std::string base_link_name =
"base_link";
625 std::vector<std::string> link_names = {
"base_link",
"link_1",
"link_2",
"link_3",
"link_4",
626 "link_5",
"link_6",
"link_7",
"tool0" };
631 Eigen::VectorXd jvals;
634 jvals(0) = -0.785398;
636 jvals(2) = -0.785398;
638 jvals(4) = -0.785398;
640 jvals(6) = -0.785398;
646 for (
int k = 0; k < 3; ++k)
648 Eigen::Vector3d link_point(0, 0, 0);
651 for (
const auto& link_name : link_names)
661 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Zero(8)));
662 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(7, std::numeric_limits<double>::max())));
663 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(7, -std::numeric_limits<double>::max())));
664 EXPECT_TRUE(kin_group.
checkJoints(Eigen::VectorXd::Zero(7)));
666 std::vector<std::string> target_active_link_names = {
"link_1",
"link_2",
"link_3",
"link_4",
667 "link_5",
"link_6",
"link_7",
"tool0" };
669 std::vector<std::string> target_static_link_names = {
"base_link",
"base" };
671 std::vector<std::string> target_link_names = target_active_link_names;
672 target_link_names.insert(target_link_names.end(), target_static_link_names.begin(), target_static_link_names.end());
674 for (
const auto& l : target_active_link_names)
679 for (
const auto& l : target_link_names)
695 std::vector<std::string> link_names = kin_group.
getLinkNames();
702 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Zero(7)));
703 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(6, std::numeric_limits<double>::max())));
704 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(6, -std::numeric_limits<double>::max())));
705 EXPECT_TRUE(kin_group.
checkJoints(Eigen::VectorXd::Zero(6)));
707 std::vector<std::string> target_active_link_names = {
"link_1",
"link_2",
"link_3",
"link_4",
708 "link_5",
"link_6",
"tool0" };
710 std::vector<std::string> target_static_link_names = {
"base_link" };
712 std::vector<std::string> target_link_names = target_active_link_names;
713 target_link_names.insert(target_link_names.end(), target_static_link_names.begin(), target_static_link_names.end());
715 for (
const auto& l : target_active_link_names)
720 for (
const auto& l : target_link_names)
736 std::vector<std::string> link_names = kin_group.
getLinkNames();
743 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Zero(7)));
744 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(6, std::numeric_limits<double>::max())));
745 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(6, -std::numeric_limits<double>::max())));
746 EXPECT_TRUE(kin_group.
checkJoints(Eigen::VectorXd::Zero(6)));
748 std::vector<std::string> target_active_link_names = {
"shoulder_link",
"upper_arm_link",
"forearm_link",
749 "wrist_1_link",
"wrist_2_link",
"wrist_3_link",
752 std::vector<std::string> target_static_link_names = {
"base_link" };
754 std::vector<std::string> target_link_names = target_active_link_names;
755 target_link_names.insert(target_link_names.end(), target_static_link_names.begin(), target_static_link_names.end());
757 for (
const auto& l : target_active_link_names)
762 for (
const auto& l : target_link_names)
778 std::vector<std::string> link_names = kin_group.
getLinkNames();
785 std::string base_link_name =
"positioner_base_link";
786 std::vector<std::string> link_names{
"positioner_base_link",
801 Eigen::MatrixXd jacobian, numerical_jacobian;
802 Eigen::VectorXd jvals;
805 jvals(0) = -0.785398;
807 jvals(2) = -0.785398;
809 jvals(4) = -0.785398;
811 jvals(6) = -0.785398;
817 for (
int k = 0; k < 3; ++k)
819 Eigen::Vector3d link_point(0, 0, 0);
822 for (
const auto& link_name : link_names)
832 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Zero(8)));
833 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(7, std::numeric_limits<double>::max())));
834 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(7, -std::numeric_limits<double>::max())));
835 EXPECT_TRUE(kin_group.
checkJoints(Eigen::VectorXd::Zero(7)));
837 std::vector<std::string> target_active_link_names = {
"positioner_tool0",
"base_link",
"base",
"link_1",
"link_2",
838 "link_3",
"link_4",
"link_5",
"link_6",
"tool0" };
840 std::vector<std::string> target_static_link_names = {
"positioner_base_link" };
842 std::vector<std::string> target_link_names = target_active_link_names;
843 target_link_names.insert(target_link_names.end(), target_static_link_names.begin(), target_static_link_names.end());
845 for (
const auto& l : target_active_link_names)
850 for (
const auto& l : target_link_names)
866 std::vector<std::string> link_names = kin_group.
getLinkNames();
873 std::string base_link_name =
"positioner_base_link";
874 std::vector<std::string> link_names{
"positioner_base_link",
889 Eigen::MatrixXd jacobian, numerical_jacobian;
890 Eigen::VectorXd jvals;
893 jvals(0) = -0.785398;
895 jvals(2) = -0.785398;
897 jvals(4) = -0.785398;
899 jvals(6) = -0.785398;
906 for (
int k = 0; k < 3; ++k)
908 Eigen::Vector3d link_point(0, 0, 0);
911 for (
const auto& link_name : link_names)
921 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Zero(9)));
922 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(8, std::numeric_limits<double>::max())));
923 EXPECT_FALSE(kin_group.
checkJoints(Eigen::VectorXd::Constant(8, -std::numeric_limits<double>::max())));
924 EXPECT_TRUE(kin_group.
checkJoints(Eigen::VectorXd::Zero(8)));
926 std::vector<std::string> target_active_link_names = {
927 "positioner_tool0",
"positioner_link_1",
"link_1",
"link_2",
"link_3",
"link_4",
"link_5",
"link_6",
"tool0"
930 std::vector<std::string> target_static_link_names = {
"world",
"base_link",
"base",
"positioner_base_link" };
932 std::vector<std::string> target_link_names = target_active_link_names;
933 target_link_names.insert(target_link_names.end(), target_static_link_names.begin(), target_static_link_names.end());
935 for (
const auto& l : target_active_link_names)
940 for (
const auto& l : target_link_names)
956 std::vector<std::string> link_names = kin_group.
getLinkNames();
962 const std::string& inv_factory_name,
963 const std::string& fwd_factory_name)
967 std::string manip_name =
"manip";
968 std::string base_link_name =
"base_link";
969 std::string tip_link_name =
"tool0";
970 std::vector<std::string> joint_names{
"joint_a1",
"joint_a2",
"joint_a3",
"joint_a4",
971 "joint_a5",
"joint_a6",
"joint_a7" };
972 std::vector<std::string> joint_link_names{
"link_1",
"link_2",
"link_3",
"link_4",
"link_5",
"link_6",
"link_7" };
979 fwd_plugin_info.
class_name = fwd_factory_name;
980 fwd_plugin_info.
config[
"base_link"] = base_link_name;
981 fwd_plugin_info.
config[
"tip_link"] = tip_link_name;
984 inv_plugin_info.
class_name = inv_factory_name;
988 Eigen::Isometry3d pose;
990 pose.translation()[0] = 0;
991 pose.translation()[1] = 0;
992 pose.translation()[2] = 1.306;
994 Eigen::VectorXd seed;
1000 seed(4) = -0.785398;
1002 seed(6) = -0.785398;
1006 auto kin_empty = factory.
createInvKin(inv_factory_name, inv_plugin_info, scene_graph_empty, scene_state);
1007 EXPECT_TRUE(kin_empty ==
nullptr);
1010 auto fwd_kin = factory.
createFwdKin(fwd_factory_name, fwd_plugin_info, *scene_graph, scene_state);
1011 EXPECT_TRUE(fwd_kin !=
nullptr);
1013 EXPECT_EQ(fwd_kin->numJoints(), 7);
1014 EXPECT_EQ(fwd_kin->getBaseLinkName(), base_link_name);
1015 EXPECT_EQ(fwd_kin->getTipLinkNames().size(), 1);
1016 EXPECT_EQ(fwd_kin->getTipLinkNames()[0], tip_link_name);
1017 EXPECT_EQ(fwd_kin->getJointNames(), joint_names);
1022 auto inv_kin = factory.
createInvKin(inv_factory_name, inv_plugin_info, *scene_graph, scene_state);
1023 EXPECT_TRUE(inv_kin !=
nullptr);
1025 EXPECT_EQ(inv_kin->numJoints(), 7);
1026 EXPECT_EQ(inv_kin->getBaseLinkName(), base_link_name);
1027 EXPECT_EQ(inv_kin->getWorkingFrame(), base_link_name);
1028 EXPECT_EQ(inv_kin->getTipLinkNames().size(), 1);
1029 EXPECT_EQ(inv_kin->getTipLinkNames()[0], tip_link_name);
1030 EXPECT_EQ(inv_kin->getJointNames(), joint_names);
1032 runInvKinTest(*inv_kin, *fwd_kin, pose, tip_link_name, seed);
1034 KinematicGroup kin_group(manip_name, joint_names, std::move(inv_kin), *scene_graph, scene_state);
1036 runInvKinTest(kin_group, pose, base_link_name, tip_link_name, seed);
1045 auto fwd_kin = factory.
createFwdKin(fwd_factory_name, fwd_plugin_info, *scene_graph, scene_state);
1046 EXPECT_TRUE(fwd_kin !=
nullptr);
1047 auto fwd_kin3 = fwd_kin->clone();
1049 EXPECT_EQ(fwd_kin3->numJoints(), 7);
1050 EXPECT_EQ(fwd_kin3->getBaseLinkName(), base_link_name);
1051 EXPECT_EQ(fwd_kin3->getTipLinkNames().size(), 1);
1052 EXPECT_EQ(fwd_kin3->getTipLinkNames()[0], tip_link_name);
1053 EXPECT_EQ(fwd_kin3->getJointNames(), joint_names);
1058 auto inv_kin = factory.
createInvKin(inv_factory_name, inv_plugin_info, *scene_graph, scene_state);
1059 auto inv_kin3 = inv_kin->clone();
1060 EXPECT_TRUE(inv_kin3 !=
nullptr);
1062 EXPECT_EQ(inv_kin3->numJoints(), 7);
1063 EXPECT_EQ(inv_kin3->getBaseLinkName(), base_link_name);
1064 EXPECT_EQ(inv_kin3->getWorkingFrame(), base_link_name);
1065 EXPECT_EQ(inv_kin3->getTipLinkNames().size(), 1);
1066 EXPECT_EQ(inv_kin3->getTipLinkNames()[0], tip_link_name);
1067 EXPECT_EQ(inv_kin3->getJointNames(), joint_names);
1069 runInvKinTest(*inv_kin3, *fwd_kin3, pose, tip_link_name, seed);
1071 KinematicGroup kin_group(manip_name, joint_names, std::move(inv_kin3), *scene_graph, scene_state);
1073 runInvKinTest(kin_group, pose, base_link_name, tip_link_name, seed);
1081 fwd_plugin_info.
config[
"base_link"] =
"missing_link";
1082 fwd_plugin_info.
config[
"tip_link"] = tip_link_name;
1087 auto fwd_kin = factory.
createFwdKin(fwd_factory_name, fwd_plugin_info, *scene_graph, scene_state);
1088 EXPECT_TRUE(fwd_kin ==
nullptr);
1092 auto inv_kin = factory.
createInvKin(inv_factory_name, inv_plugin_info, *scene_graph, scene_state);
1093 EXPECT_TRUE(inv_kin ==
nullptr);
1098 #endif // TESSERACT_KINEMATICS_KIN_TEST_SUITE_H