1 #ifndef TESSERACT_STATE_SOLVER_STATE_SOLVER_TEST_SUITE_H
2 #define TESSERACT_STATE_SOLVER_STATE_SOLVER_TEST_SUITE_H
6 #include <gtest/gtest.h>
9 #include <tesseract_urdf/urdf_parser.h>
24 std::string path = locator.
locateResource(
"package://tesseract_support/urdf/lbr_iiwa_14_r820.urdf")->getFilePath();
25 return tesseract_urdf::parseURDFFile(path, locator);
30 auto subgraph = std::make_unique<SceneGraph>();
31 subgraph->setName(
"subgraph");
34 auto visual = std::make_shared<Visual>();
35 visual->geometry = std::make_shared<tesseract_geometry::Box>(1, 1, 1);
36 auto collision = std::make_shared<Collision>();
37 collision->geometry = std::make_shared<tesseract_geometry::Box>(1, 1, 1);
39 const std::string link_name1 =
"subgraph_base_link";
40 const std::string link_name2 =
"subgraph_link_1";
41 const std::string joint_name1 =
"subgraph_joint1";
42 Link link_1(link_name1);
43 link_1.
visual.push_back(visual);
45 Link link_2(link_name2);
47 Joint joint_1(joint_name1);
53 subgraph->addLink(link_1);
54 subgraph->addLink(link_2);
55 subgraph->addJoint(joint_1);
62 EXPECT_EQ(base_state.
joints.size(), compare_state.
joints.size());
66 for (
const auto& pair : base_state.
joints)
68 EXPECT_NEAR(pair.second, compare_state.
joints.at(pair.first), 1e-6);
73 EXPECT_TRUE(pair.second.isApprox(compare_state.
floating_joints.at(pair.first), 1e-6));
78 EXPECT_TRUE(pair.second.isApprox(compare_state.
joint_transforms.at(pair.first), 1e-6));
83 EXPECT_TRUE(link_pair.second.isApprox(compare_state.
link_transforms.at(link_pair.first), 1e-6));
104 for (
const auto& link_name : base_solver.
getLinkNames())
109 for (
int i = 0; i < 10; ++i)
117 comp_state_const = comp_solver.
getState(base_random_state.
joints);
124 comp_state_const = comp_solver.
getState(base_random_state.
joints);
126 std::vector<std::string> joint_names(base_random_state.
joints.size());
127 Eigen::VectorXd joint_values(base_random_state.
joints.size());
129 for (
const auto& joint : base_random_state.
joints)
131 joint_names.at(j) = joint.first;
132 joint_values(
static_cast<Eigen::Index
>(j)) = joint.second;
135 comp_solver.
setState(joint_names, joint_values);
140 comp_state_const = comp_solver.
getState(base_random_state.
joints);
143 Eigen::VectorXd joint_values = base_random_state.
getJointValues(joint_names);
155 EXPECT_TRUE(base_link_tf.second.isApprox(comp_solver.
getLinkTransform(base_link_tf.first), 1e-6));
158 std::vector<std::string> comp_link_names = comp_solver.
getLinkNames();
160 for (std::size_t j = 0; j < comp_link_names.size(); ++j)
162 EXPECT_TRUE(base_random_state.
link_transforms[comp_link_names.at(j)].isApprox(comp_link_tf.at(j), 1e-6));
165 for (
const auto& from_link_name : comp_link_names)
167 for (
const auto& to_link_name : comp_link_names)
170 Eigen::Isometry3d base_tf = base_random_state.
link_transforms[from_link_name].inverse() *
172 EXPECT_TRUE(base_tf.isApprox(comp_tf, 1e-6));
183 for (Eigen::Index i = 0; i < static_cast<Eigen::Index>(comp_joint_names.size()); ++i)
185 const auto& scene_joint = scene_graph.
getJoint(comp_joint_names[
static_cast<std::size_t
>(i)]);
186 EXPECT_NEAR(limits.
joint_limits(i, 0), scene_joint->limits->lower, 1e-5);
187 EXPECT_NEAR(limits.
joint_limits(i, 1), scene_joint->limits->upper, 1e-5);
188 EXPECT_NEAR(limits.
velocity_limits(i, 0), -scene_joint->limits->velocity, 1e-5);
189 EXPECT_NEAR(limits.
velocity_limits(i, 1), scene_joint->limits->velocity, 1e-5);
192 EXPECT_NEAR(limits.
jerk_limits(i, 0), -scene_joint->limits->jerk, 1e-5);
193 EXPECT_NEAR(limits.
jerk_limits(i, 1), scene_joint->limits->jerk, 1e-5);
206 const Eigen::Isometry3d& change_base,
208 const std::vector<std::string>& joint_names,
209 const Eigen::Ref<const Eigen::VectorXd>& joint_values,
210 const std::string& link_name,
211 const Eigen::Ref<const Eigen::Vector3d>& link_point)
213 Eigen::VectorXd njvals;
214 double delta = 0.001;
216 if (joint_names.empty())
221 Eigen::Isometry3d pose = poses[link_name];
222 pose = change_base * pose;
224 for (
int i = 0; i < static_cast<int>(joint_values.size()); ++i)
226 njvals = joint_values;
229 if (joint_names.empty())
234 Eigen::Isometry3d updated_pose = updated_poses[link_name];
235 updated_pose = change_base * updated_pose;
237 Eigen::Vector3d temp = pose * link_point;
238 Eigen::Vector3d temp2 = updated_pose * link_point;
239 jacobian(0, i) = (temp2.x() - temp.x()) / delta;
240 jacobian(1, i) = (temp2.y() - temp.y()) / delta;
241 jacobian(2, i) = (temp2.z() - temp.z()) / delta;
243 Eigen::AngleAxisd r12(pose.rotation().transpose() * updated_pose.rotation());
244 double theta = r12.angle();
245 theta = copysign(fmod(fabs(theta), 2.0 * M_PI), theta);
247 theta = theta + 2. * M_PI;
249 theta = theta - 2. * M_PI;
250 Eigen::VectorXd omega = (pose.rotation() * r12.axis() * theta) / delta;
251 jacobian(3, i) = omega(0);
252 jacobian(4, i) = omega(1);
253 jacobian(5, i) = omega(2);
268 const std::vector<std::string>& joint_names,
269 const Eigen::VectorXd& jvals,
270 const std::string& link_name,
271 const Eigen::Vector3d& link_point,
272 const Eigen::Isometry3d& change_base)
274 Eigen::MatrixXd jacobian, numerical_jacobian;
275 jacobian.resize(6, jvals.size());
282 std::vector<long> order;
283 order.reserve(solver_jn.size());
284 if (joint_names.empty())
286 for (
int i = 0; i < static_cast<int>(solver_jn.size()); ++i)
290 jacobian = state_solver.
getJacobian(jvals, link_name);
294 for (
const auto& joint_name : solver_jn)
296 std::distance(joint_names.begin(), std::find(joint_names.begin(), joint_names.end(), joint_name)));
299 jacobian = state_solver.
getJacobian(joint_names, jvals, link_name);
305 numerical_jacobian.resize(6, jvals.size());
306 numericalJacobian(numerical_jacobian, change_base, state_solver, joint_names, jvals, link_name, link_point);
308 for (
int i = 0; i < 6; ++i)
310 for (
int j = 0; j < static_cast<int>(jvals.size()); ++j)
312 EXPECT_NEAR(numerical_jacobian(i, order[
static_cast<std::size_t
>(j)]), jacobian(i, j), 1e-3);
318 const std::unordered_map<std::string, double>& joints_values,
319 const std::string& link_name,
320 const Eigen::Vector3d& link_point,
321 const Eigen::Isometry3d& change_base)
323 Eigen::MatrixXd jacobian, numerical_jacobian;
324 jacobian.resize(6,
static_cast<Eigen::Index
>(joints_values.size()));
326 std::vector<std::string> joint_names;
327 Eigen::VectorXd jvals(joints_values.size());
329 for (
const auto& jv : joints_values)
331 joint_names.push_back(jv.first);
332 jvals(j++) = jv.second;
340 std::vector<long> order;
341 order.reserve(solver_jn.size());
342 for (
const auto& joint_name : solver_jn)
343 order.push_back(std::distance(joint_names.begin(), std::find(joint_names.begin(), joint_names.end(), joint_name)));
346 jacobian = state_solver.
getJacobian(joints_values, link_name);
351 numerical_jacobian.resize(6,
static_cast<Eigen::Index
>(joints_values.size()));
352 numericalJacobian(numerical_jacobian, change_base, state_solver, joint_names, jvals, link_name, link_point);
354 for (
int i = 0; i < 6; ++i)
356 for (
int j = 0; j < static_cast<int>(jvals.size()); ++j)
358 EXPECT_NEAR(numerical_jacobian(i, order[
static_cast<std::size_t
>(j)]), jacobian(i, j), 1e-3);
363 template <
typename S>
369 auto state_solver = S(*scene_graph);
372 std::vector<std::string> joint_names_empty;
373 std::vector<std::string> link_names = {
"base_link",
"link_1",
"link_2",
"link_3",
"link_4",
374 "link_5",
"link_6",
"link_7",
"tool0" };
379 Eigen::VectorXd jvals;
397 std::unordered_map<std::string, double> jv_map;
398 for (Eigen::Index i = 0; i < jvals.rows(); ++i)
399 jv_map[
"joint_a" + std::to_string(i + 1)] = jvals(i);
405 Eigen::Vector3d link_point(0, 0, 0);
406 for (
const auto& link_name : link_names)
408 runCompareJacobian(state_solver, joint_names_empty, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
410 *state_solver_clone, joint_names_empty, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
415 state_solver, joint_names_empty, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
419 *state_solver_clone, joint_names_empty, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
425 for (
int k = 0; k < 3; ++k)
427 Eigen::Vector3d link_point(0, 0, 0);
430 for (
const auto& link_name : link_names)
432 runCompareJacobian(state_solver, joint_names_empty, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
434 *state_solver_clone, joint_names_empty, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
439 state_solver, joint_names_empty, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
443 *state_solver_clone, joint_names_empty, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
449 for (
int k = 0; k < 3; ++k)
451 Eigen::Vector3d link_point(0, 0, 0);
452 Eigen::Isometry3d change_base;
453 change_base.setIdentity();
454 change_base(0, 0) = 0;
455 change_base(1, 0) = 1;
456 change_base(0, 1) = -1;
457 change_base(1, 1) = 0;
458 change_base.translation() = Eigen::Vector3d(0, 0, 0);
459 change_base.translation()[k] = 1;
461 for (
const auto& link_name : link_names)
463 runCompareJacobian(state_solver, joint_names_empty, jvals, link_name, link_point, change_base);
464 runCompareJacobian(*state_solver_clone, joint_names_empty, jvals, link_name, link_point, change_base);
469 runCompareJacobian(state_solver, joint_names_empty, jvals,
"", link_point, change_base));
473 runCompareJacobian(*state_solver_clone, joint_names_empty, jvals,
"", link_point, change_base));
479 for (
int k = 0; k < 3; ++k)
481 Eigen::Vector3d link_point(0, 0, 0);
484 Eigen::Isometry3d change_base;
485 change_base.setIdentity();
486 change_base(0, 0) = 0;
487 change_base(1, 0) = 1;
488 change_base(0, 1) = -1;
489 change_base(1, 1) = 0;
490 change_base.translation() = link_point;
492 for (
const auto& link_name : link_names)
494 runCompareJacobian(state_solver, joint_names_empty, jvals, link_name, link_point, change_base);
495 runCompareJacobian(*state_solver_clone, joint_names_empty, jvals, link_name, link_point, change_base);
500 runCompareJacobian(state_solver, joint_names_empty, jvals,
"", link_point, change_base));
504 runCompareJacobian(*state_solver_clone, joint_names_empty, jvals,
"", link_point, change_base));
510 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
512 Eigen::Vector3d link_point(0, 0, 0);
513 for (
const auto& link_name : link_names)
515 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
516 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
518 runCompareJacobian(state_solver, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
519 runCompareJacobian(*state_solver_clone, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
524 runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
528 *state_solver_clone, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
534 for (
int k = 0; k < 3; ++k)
536 Eigen::Vector3d link_point(0, 0, 0);
539 for (
const auto& link_name : link_names)
541 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
542 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
544 runCompareJacobian(state_solver, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
545 runCompareJacobian(*state_solver_clone, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
550 runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
554 *state_solver_clone, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
560 for (
int k = 0; k < 3; ++k)
562 Eigen::Vector3d link_point(0, 0, 0);
563 Eigen::Isometry3d change_base;
564 change_base.setIdentity();
565 change_base(0, 0) = 0;
566 change_base(1, 0) = 1;
567 change_base(0, 1) = -1;
568 change_base(1, 1) = 0;
569 change_base.translation() = Eigen::Vector3d(0, 0, 0);
570 change_base.translation()[k] = 1;
572 for (
const auto& link_name : link_names)
574 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, change_base);
575 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, change_base);
582 EXPECT_ANY_THROW(
runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, change_base));
586 runCompareJacobian(*state_solver_clone, joint_names, jvals,
"", link_point, change_base));
592 for (
int k = 0; k < 3; ++k)
594 Eigen::Vector3d link_point(0, 0, 0);
597 Eigen::Isometry3d change_base;
598 change_base.setIdentity();
599 change_base(0, 0) = 0;
600 change_base(1, 0) = 1;
601 change_base(0, 1) = -1;
602 change_base(1, 1) = 0;
603 change_base.translation() = link_point;
605 for (
const auto& link_name : link_names)
607 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, change_base);
608 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, change_base);
615 EXPECT_ANY_THROW(
runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, change_base));
619 runCompareJacobian(*state_solver_clone, joint_names, jvals,
"", link_point, change_base));
625 std::reverse(joint_names.begin(), joint_names.end());
635 Eigen::Vector3d link_point(0, 0, 0);
636 for (
const auto& link_name : link_names)
638 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
639 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
641 runCompareJacobian(state_solver, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
642 runCompareJacobian(*state_solver_clone, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
647 runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
651 *state_solver_clone, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
657 for (
int k = 0; k < 3; ++k)
659 Eigen::Vector3d link_point(0, 0, 0);
662 for (
const auto& link_name : link_names)
664 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
665 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, Eigen::Isometry3d::Identity());
667 runCompareJacobian(state_solver, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
668 runCompareJacobian(*state_solver_clone, jv_map, link_name, link_point, Eigen::Isometry3d::Identity());
673 runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
677 *state_solver_clone, joint_names, jvals,
"", link_point, Eigen::Isometry3d::Identity()));
683 for (
int k = 0; k < 3; ++k)
685 Eigen::Vector3d link_point(0, 0, 0);
686 Eigen::Isometry3d change_base;
687 change_base.setIdentity();
688 change_base(0, 0) = 0;
689 change_base(1, 0) = 1;
690 change_base(0, 1) = -1;
691 change_base(1, 1) = 0;
692 change_base.translation() = Eigen::Vector3d(0, 0, 0);
693 change_base.translation()[k] = 1;
695 for (
const auto& link_name : link_names)
697 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, change_base);
698 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, change_base);
704 EXPECT_ANY_THROW(
runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, change_base));
708 runCompareJacobian(*state_solver_clone, joint_names, jvals,
"", link_point, change_base));
714 for (
int k = 0; k < 3; ++k)
716 Eigen::Vector3d link_point(0, 0, 0);
719 Eigen::Isometry3d change_base;
720 change_base.setIdentity();
721 change_base(0, 0) = 0;
722 change_base(1, 0) = 1;
723 change_base(0, 1) = -1;
724 change_base(1, 1) = 0;
725 change_base.translation() = link_point;
727 for (
const auto& link_name : link_names)
729 runCompareJacobian(state_solver, joint_names, jvals, link_name, link_point, change_base);
730 runCompareJacobian(*state_solver_clone, joint_names, jvals, link_name, link_point, change_base);
736 EXPECT_ANY_THROW(
runCompareJacobian(state_solver, joint_names, jvals,
"", link_point, change_base));
740 runCompareJacobian(*state_solver_clone, joint_names, jvals,
"", link_point, change_base));
744 template <
typename S>
750 auto state_solver = S(*scene_graph);
752 Eigen::Isometry3d origin{ Eigen::Isometry3d::Identity() };
753 origin.translation()(0) = 1.25;
756 Joint joint_1(
"joint_a1");
762 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
763 EXPECT_TRUE(scene_graph->addJoint(joint_1));
764 EXPECT_TRUE(state_solver.replaceJoint(joint_1));
775 origin.translation()(1) = 1.5;
777 floating_joint_values[
"joint_a1"] = origin;
778 state_solver.setState(floating_joint_values);
780 EXPECT_TRUE(scene_graph->changeJointOrigin(
"joint_a1", origin));
791 origin.translation()(2) = 1.5;
792 auto state = state_solver.getState();
793 state.floating_joints.at(
"joint_a1") = origin;
794 state_solver.setState(state.joints, state.floating_joints);
796 EXPECT_TRUE(scene_graph->changeJointOrigin(
"joint_a1", origin));
809 floating_joint_values[
"does_not_exist"] = origin;
810 EXPECT_ANY_THROW(state_solver.setState(floating_joint_values));
814 auto state = state_solver.getState();
815 state.floating_joints[
"does_not_exist"] = origin;
816 EXPECT_ANY_THROW(state_solver.setState(state.joints, state.floating_joints));
820 template <
typename S>
826 auto state_solver = S(*scene_graph);
828 auto visual = std::make_shared<Visual>();
829 visual->geometry = std::make_shared<tesseract_geometry::Box>(1, 1, 1);
830 auto collision = std::make_shared<Collision>();
831 collision->geometry = std::make_shared<tesseract_geometry::Box>(1, 1, 1);
833 const std::string link_name1 =
"link_n1";
834 const std::string link_name2 =
"link_n2";
835 const std::string joint_name1 =
"joint_n1";
836 const std::string joint_name2 =
"joint_n2";
838 Link link_1(link_name1);
839 link_1.
visual.push_back(visual);
842 Joint joint_1(joint_name1);
847 Link link_2(link_name2);
849 Joint joint_2(joint_name2);
857 EXPECT_TRUE(scene_graph->addLink(link_1, joint_1));
858 EXPECT_TRUE(state_solver.addLink(link_1, joint_1));
860 auto base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
869 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
872 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
876 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
879 EXPECT_TRUE(scene_graph->addLink(link_2, joint_2));
880 EXPECT_TRUE(state_solver.addLink(link_2, joint_2));
882 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
888 state_solver_clone = state_solver.clone();
891 joint_names = state_solver.getActiveJointNames();
892 state = state_solver.getState();
894 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name2) == joint_names.end());
899 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
904 EXPECT_TRUE(scene_graph->removeLink(link_name1,
true));
905 EXPECT_TRUE(state_solver.removeLink(link_name1));
907 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
913 state_solver_clone = state_solver.clone();
916 joint_names = state_solver.getActiveJointNames();
917 state = state_solver.getState();
918 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
921 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
924 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
932 EXPECT_FALSE(state_solver.removeLink(link_name1));
937 state_solver_clone = state_solver.clone();
940 EXPECT_FALSE(state_solver.removeLink(link_name2));
945 state_solver_clone = state_solver.clone();
948 EXPECT_FALSE(state_solver.removeJoint(joint_name1));
953 state_solver_clone = state_solver.clone();
956 EXPECT_FALSE(state_solver.removeJoint(joint_name2));
961 state_solver_clone = state_solver.clone();
968 EXPECT_TRUE(scene_graph->addLink(link_1, joint_1));
969 EXPECT_TRUE(state_solver.addLink(link_1, joint_1));
971 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
977 state_solver_clone = state_solver.clone();
980 joint_names = state_solver.getActiveJointNames();
981 state = state_solver.getState();
983 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
987 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
989 EXPECT_TRUE(scene_graph->addLink(link_2, joint_2));
990 EXPECT_TRUE(state_solver.addLink(link_2, joint_2));
992 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
998 state_solver_clone = state_solver.clone();
1001 joint_names = state_solver.getActiveJointNames();
1002 state = state_solver.getState();
1004 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name2) == joint_names.end());
1009 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1014 EXPECT_TRUE(scene_graph->removeJoint(joint_name1,
true));
1015 EXPECT_TRUE(state_solver.removeJoint(joint_name1));
1017 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1023 state_solver_clone = state_solver.clone();
1026 joint_names = state_solver.getActiveJointNames();
1027 state = state_solver.getState();
1028 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
1031 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1035 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1040 EXPECT_FALSE(state_solver.removeLink(link_name1));
1045 state_solver_clone = state_solver.clone();
1048 EXPECT_FALSE(state_solver.removeLink(link_name2));
1053 state_solver_clone = state_solver.clone();
1056 EXPECT_FALSE(state_solver.removeJoint(joint_name1));
1061 state_solver_clone = state_solver.clone();
1064 EXPECT_FALSE(state_solver.removeJoint(joint_name2));
1069 state_solver_clone = state_solver.clone();
1073 Link link_exists(
"link_1");
1074 EXPECT_FALSE(state_solver.addLink(link_exists, joint_1));
1079 state_solver_clone = state_solver.clone();
1083 Link link_10(
"link_10");
1084 Joint joint_exists(
"joint_a1");
1089 EXPECT_FALSE(state_solver.addLink(link_10, joint_exists));
1094 state_solver_clone = state_solver.clone();
1098 template <
typename S>
1104 auto state_solver = S(*scene_graph);
1106 auto subgraph = std::make_unique<SceneGraph>();
1107 subgraph->setName(
"subgraph");
1109 Joint joint_1_empty(
"provided_subgraph_joint");
1114 EXPECT_FALSE(scene_graph->insertSceneGraph(*subgraph, joint_1_empty));
1115 EXPECT_FALSE(state_solver.insertSceneGraph(*subgraph, joint_1_empty));
1117 auto base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1128 const std::string subgraph_joint_name =
"attach_subgraph_joint";
1130 Joint joint(subgraph_joint_name);
1135 EXPECT_TRUE(scene_graph->insertSceneGraph(*subgraph, joint));
1136 EXPECT_TRUE(state_solver.insertSceneGraph(*subgraph, joint));
1138 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1144 state_solver_clone = state_solver.clone();
1147 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
1149 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), subgraph_joint_name) == joint_names.end());
1152 EXPECT_TRUE(state.
joints.find(subgraph_joint_name) == state.
joints.end());
1155 EXPECT_FALSE(scene_graph->insertSceneGraph(*subgraph, joint));
1156 EXPECT_FALSE(state_solver.insertSceneGraph(*subgraph, joint));
1158 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1164 state_solver_clone = state_solver.clone();
1168 std::string prefix =
"prefix_";
1169 Joint prefix_joint(prefix + subgraph_joint_name);
1174 EXPECT_TRUE(scene_graph->insertSceneGraph(*subgraph, prefix_joint, prefix));
1175 EXPECT_TRUE(state_solver.insertSceneGraph(*subgraph, prefix_joint, prefix));
1177 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1183 state_solver_clone = state_solver.clone();
1186 joint_names = state_solver.getActiveJointNames();
1187 state = state_solver.getState();
1188 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), prefix + subgraph_joint_name) == joint_names.end());
1192 EXPECT_TRUE(state.
joints.find(prefix + subgraph_joint_name) == state.
joints.end());
1195 prefix =
"prefix2_";
1196 Joint prefix_joint2(prefix + subgraph_joint_name);
1201 EXPECT_TRUE(scene_graph->insertSceneGraph(*subgraph, prefix_joint2, prefix));
1202 EXPECT_TRUE(state_solver.insertSceneGraph(*subgraph, prefix_joint2, prefix));
1204 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1210 state_solver_clone = state_solver.clone();
1213 joint_names = state_solver.getActiveJointNames();
1215 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), prefix + subgraph_joint_name) == joint_names.end());
1216 state = state_solver.getState();
1219 EXPECT_TRUE(state.
joints.find(prefix + subgraph_joint_name) == state.
joints.end());
1223 prefix =
"prefix3_";
1224 Joint prefix_joint3(prefix + subgraph_joint_name);
1229 EXPECT_FALSE(state_solver.insertSceneGraph(empty_scene_graph, prefix_joint3, prefix));
1231 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1237 state_solver_clone = state_solver.clone();
1241 template <
typename S>
1247 auto state_solver = S(*scene_graph);
1249 const std::string link_name1 =
"link_n1";
1250 const std::string joint_name1 =
"joint_n1";
1251 Link link_1(link_name1);
1253 Joint joint_1(joint_name1);
1258 EXPECT_TRUE(scene_graph->addLink(link_1, joint_1));
1259 EXPECT_TRUE(state_solver.addLink(link_1, joint_1));
1261 const std::string link_name2 =
"link_n2";
1262 const std::string joint_name2 =
"joint_n2";
1263 Link link_2(link_name2);
1265 Joint joint_2(joint_name2);
1271 EXPECT_TRUE(scene_graph->addLink(link_2, joint_2));
1272 EXPECT_TRUE(state_solver.addLink(link_2, joint_2));
1274 auto base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1286 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1287 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1295 Eigen::Isometry3d new_origin1 = Eigen::Isometry3d::Identity();
1296 new_origin1.translation()(0) += 1.234;
1298 Eigen::Isometry3d new_origin2 = Eigen::Isometry3d::Identity();
1299 new_origin2.translation()(1) += 1.234;
1301 EXPECT_TRUE(scene_graph->changeJointOrigin(joint_name1, new_origin1));
1302 EXPECT_TRUE(state_solver.changeJointOrigin(joint_name1, new_origin1));
1303 EXPECT_TRUE(scene_graph->changeJointOrigin(joint_name2, new_origin2));
1304 EXPECT_TRUE(state_solver.changeJointOrigin(joint_name2, new_origin2));
1306 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1312 state_solver_clone = state_solver.clone();
1316 state = state_solver.getState();
1317 EXPECT_TRUE(state.
link_transforms.at(link_name1).isApprox(new_origin1));
1319 EXPECT_TRUE(state.
link_transforms.at(link_name2).isApprox(new_origin2));
1321 EXPECT_TRUE(state.
floating_joints.at(joint_name2).isApprox(new_origin2));
1326 EXPECT_FALSE(state_solver.changeJointOrigin(
"joint_does_not_exist", new_origin1));
1328 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1334 state_solver_clone = state_solver.clone();
1338 template <
typename S>
1344 auto state_solver = S(*scene_graph);
1346 const std::string link_name1 =
"link_n1";
1347 const std::string link_name2 =
"link_n2";
1348 const std::string joint_name1 =
"joint_n1";
1349 const std::string joint_name2 =
"joint_n2";
1350 Link link_1(link_name1);
1351 Link link_2(link_name2);
1353 Joint joint_1(joint_name1);
1358 Joint joint_2(joint_name2);
1364 EXPECT_TRUE(scene_graph->addLink(link_1, joint_1));
1365 EXPECT_TRUE(state_solver.addLink(link_1, joint_1));
1367 auto base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1379 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1381 EXPECT_TRUE(scene_graph->addLink(link_2, joint_2));
1382 EXPECT_TRUE(state_solver.addLink(link_2, joint_2));
1384 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1389 state_solver_clone = state_solver.clone();
1392 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
1393 state = state_solver.getState();
1394 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
1395 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name2) == joint_names.end());
1398 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1402 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1406 EXPECT_TRUE(scene_graph->moveJoint(joint_name1,
"tool0"));
1407 EXPECT_TRUE(state_solver.moveJoint(joint_name1,
"tool0"));
1409 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1415 state_solver_clone = state_solver.clone();
1418 joint_names = state_solver.getActiveJointNames();
1419 state = state_solver.getState();
1420 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
1421 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name2) == joint_names.end());
1424 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1428 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1433 EXPECT_FALSE(state_solver.moveJoint(
"joint_does_not_exist",
"tool0"));
1435 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1441 state_solver_clone = state_solver.clone();
1445 EXPECT_FALSE(state_solver.moveJoint(joint_name1,
"link_does_not_exist"));
1447 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1453 state_solver_clone = state_solver.clone();
1457 template <
typename S>
1463 auto state_solver = S(*scene_graph);
1465 const std::string link_name1 =
"link_n1";
1466 const std::string link_name2 =
"link_n2";
1467 const std::string joint_name1 =
"joint_n1";
1468 const std::string joint_name2 =
"joint_n2";
1469 Link link_1(link_name1);
1470 Link link_2(link_name2);
1472 Joint joint_1(joint_name1);
1477 Joint joint_2(joint_name2);
1483 EXPECT_TRUE(scene_graph->addLink(link_1, joint_1));
1484 EXPECT_TRUE(state_solver.addLink(link_1, joint_1));
1486 auto base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1499 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1501 EXPECT_TRUE(scene_graph->addLink(link_2, joint_2));
1502 EXPECT_TRUE(state_solver.addLink(link_2, joint_2));
1504 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1510 state_solver_clone = state_solver.clone();
1513 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
1514 state = state_solver.getState();
1515 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
1516 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name2) == joint_names.end());
1520 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1523 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1527 std::string moved_joint_name = joint_name1 +
"_moved";
1528 Joint move_link_joint = joint_1.
clone(moved_joint_name);
1532 EXPECT_TRUE(scene_graph->moveLink(move_link_joint));
1533 EXPECT_TRUE(state_solver.moveLink(move_link_joint));
1535 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1541 state_solver_clone = state_solver.clone();
1544 joint_names = state_solver.getActiveJointNames();
1545 state = state_solver.getState();
1546 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name1) == joint_names.end());
1547 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), moved_joint_name) == joint_names.end());
1548 EXPECT_TRUE(std::find(joint_names.begin(), joint_names.end(), joint_name2) == joint_names.end());
1555 EXPECT_TRUE(state.
joints.find(joint_name1) == state.
joints.end());
1558 EXPECT_TRUE(state.
joints.find(joint_name2) == state.
joints.end());
1563 std::string moved_joint_name_err = joint_name1 +
"_err";
1564 Joint move_link_joint_err1 = joint_1.
clone(moved_joint_name_err);
1568 EXPECT_FALSE(state_solver.moveLink(move_link_joint_err1));
1570 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1576 Joint move_link_joint_err2 = joint_1.
clone(moved_joint_name_err);
1579 EXPECT_FALSE(state_solver.moveLink(move_link_joint_err2));
1581 base_state_solver = std::make_shared<KDLStateSolver>(*scene_graph);
1587 template <
typename S>
1593 auto state_solver = S(*scene_graph);
1595 double new_lower = 1.0;
1596 double new_upper = 2.0;
1597 double new_velocity = 3.0;
1598 double new_acceleration = 4.0;
1599 double new_jerk = 5.0;
1601 scene_graph->changeJointPositionLimits(
"joint_a1", new_lower, new_upper);
1602 scene_graph->changeJointVelocityLimits(
"joint_a1", new_velocity);
1603 scene_graph->changeJointAccelerationLimits(
"joint_a1", new_acceleration);
1604 scene_graph->changeJointJerkLimits(
"joint_a1", new_jerk);
1606 EXPECT_TRUE(state_solver.changeJointPositionLimits(
"joint_a1", new_lower, new_upper));
1607 EXPECT_TRUE(state_solver.changeJointVelocityLimits(
"joint_a1", new_velocity));
1608 EXPECT_TRUE(state_solver.changeJointAccelerationLimits(
"joint_a1", new_acceleration));
1609 EXPECT_TRUE(state_solver.changeJointJerkLimits(
"joint_a1", new_jerk));
1612 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
1613 long idx = std::distance(joint_names.begin(), std::find(joint_names.begin(), joint_names.end(),
"joint_a1"));
1614 auto limits = state_solver.getLimits();
1615 EXPECT_NEAR(limits.joint_limits(idx, 0), new_lower, 1e-5);
1616 EXPECT_NEAR(limits.joint_limits(idx, 1), new_upper, 1e-5);
1617 EXPECT_NEAR(limits.velocity_limits(idx, 0), -new_velocity, 1e-5);
1618 EXPECT_NEAR(limits.velocity_limits(idx, 1), new_velocity, 1e-5);
1619 EXPECT_NEAR(limits.acceleration_limits(idx, 0), -new_acceleration, 1e-5);
1620 EXPECT_NEAR(limits.acceleration_limits(idx, 1), new_acceleration, 1e-5);
1621 EXPECT_NEAR(limits.jerk_limits(idx, 0), -new_jerk, 1e-5);
1622 EXPECT_NEAR(limits.jerk_limits(idx, 1), new_jerk, 1e-5);
1627 S& state_solver_clone =
static_cast<S&
>(*temp);
1629 std::vector<std::string> joint_names = state_solver_clone.getActiveJointNames();
1630 long idx = std::distance(joint_names.begin(), std::find(joint_names.begin(), joint_names.end(),
"joint_a1"));
1631 auto limits = state_solver_clone.getLimits();
1632 EXPECT_NEAR(limits.joint_limits(idx, 0), new_lower, 1e-5);
1633 EXPECT_NEAR(limits.joint_limits(idx, 1), new_upper, 1e-5);
1634 EXPECT_NEAR(limits.velocity_limits(idx, 0), -new_velocity, 1e-5);
1635 EXPECT_NEAR(limits.velocity_limits(idx, 1), new_velocity, 1e-5);
1636 EXPECT_NEAR(limits.acceleration_limits(idx, 0), -new_acceleration, 1e-5);
1637 EXPECT_NEAR(limits.acceleration_limits(idx, 1), new_acceleration, 1e-5);
1638 EXPECT_NEAR(limits.jerk_limits(idx, 0), -new_jerk, 1e-5);
1639 EXPECT_NEAR(limits.jerk_limits(idx, 1), new_jerk, 1e-5);
1643 double new_lower_err = 1.0 * 10;
1644 double new_upper_err = 2.0 * 10;
1645 double new_velocity_err = 3.0 * 10;
1646 double new_acceleration_err = 4.0 * 10;
1647 double new_jerk_err = 5.0 * 10;
1648 EXPECT_FALSE(state_solver.changeJointPositionLimits(
"joint_does_not_exist", new_lower_err, new_upper_err));
1649 EXPECT_FALSE(state_solver.changeJointVelocityLimits(
"joint_does_not_exist", new_velocity_err));
1650 EXPECT_FALSE(state_solver.changeJointAccelerationLimits(
"joint_does_not_exist", new_acceleration_err));
1651 EXPECT_FALSE(state_solver.changeJointJerkLimits(
"joint_does_not_exist", new_jerk_err));
1654 std::vector<std::string> joint_names = state_solver.getActiveJointNames();
1655 long idx = std::distance(joint_names.begin(), std::find(joint_names.begin(), joint_names.end(),
"joint_a1"));
1656 auto limits = state_solver.getLimits();
1657 EXPECT_NEAR(limits.joint_limits(idx, 0), new_lower, 1e-5);
1658 EXPECT_NEAR(limits.joint_limits(idx, 1), new_upper, 1e-5);
1659 EXPECT_NEAR(limits.velocity_limits(idx, 0), -new_velocity, 1e-5);
1660 EXPECT_NEAR(limits.velocity_limits(idx, 1), new_velocity, 1e-5);
1661 EXPECT_NEAR(limits.acceleration_limits(idx, 0), -new_acceleration, 1e-5);
1662 EXPECT_NEAR(limits.acceleration_limits(idx, 1), new_acceleration, 1e-5);
1663 EXPECT_NEAR(limits.jerk_limits(idx, 0), -new_jerk, 1e-5);
1664 EXPECT_NEAR(limits.jerk_limits(idx, 1), new_jerk, 1e-5);
1669 S& state_solver_clone =
static_cast<S&
>(*temp);
1671 std::vector<std::string> joint_names = state_solver_clone.getActiveJointNames();
1672 long idx = std::distance(joint_names.begin(), std::find(joint_names.begin(), joint_names.end(),
"joint_a1"));
1673 auto limits = state_solver_clone.getLimits();
1674 EXPECT_NEAR(limits.joint_limits(idx, 0), new_lower, 1e-5);
1675 EXPECT_NEAR(limits.joint_limits(idx, 1), new_upper, 1e-5);
1676 EXPECT_NEAR(limits.velocity_limits(idx, 0), -new_velocity, 1e-5);
1677 EXPECT_NEAR(limits.velocity_limits(idx, 1), new_velocity, 1e-5);
1678 EXPECT_NEAR(limits.acceleration_limits(idx, 0), -new_acceleration, 1e-5);
1679 EXPECT_NEAR(limits.acceleration_limits(idx, 1), new_acceleration, 1e-5);
1680 EXPECT_NEAR(limits.jerk_limits(idx, 0), -new_jerk, 1e-5);
1681 EXPECT_NEAR(limits.jerk_limits(idx, 1), new_jerk, 1e-5);
1685 template <
typename S>
1692 auto state_solver = S(*scene_graph);
1694 Joint joint_1(
"joint_a1");
1700 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1701 EXPECT_TRUE(scene_graph->addJoint(joint_1));
1702 EXPECT_TRUE(state_solver.replaceJoint(joint_1));
1717 auto state_solver = S(*scene_graph);
1719 Joint joint_1(
"joint_a1");
1725 EXPECT_FALSE(state_solver.replaceJoint(joint_1));
1740 auto state_solver = S(*scene_graph);
1742 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1745 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1746 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1747 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1762 auto state_solver = S(*scene_graph);
1764 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1768 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1769 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1770 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1785 auto state_solver = S(*scene_graph);
1788 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1792 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1793 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1794 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1798 auto state = state_solver.getState();
1799 EXPECT_TRUE(state.floating_joints.find(
"joint_a1") != state.floating_joints.end());
1800 EXPECT_FALSE(state.floating_joints.empty());
1811 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1815 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1816 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1817 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1821 auto state = state_solver.getState();
1822 EXPECT_TRUE(state.floating_joints.find(
"joint_a1") != state.floating_joints.end());
1823 EXPECT_FALSE(state.floating_joints.empty());
1834 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1838 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1839 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1840 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1844 auto state = state_solver.getState();
1845 EXPECT_TRUE(state.floating_joints.find(
"joint_a1") == state.floating_joints.end());
1846 EXPECT_TRUE(state.floating_joints.empty());
1860 auto state_solver = S(*scene_graph);
1862 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1866 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1867 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1868 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1883 auto state_solver = S(*scene_graph);
1885 Joint new_joint_a1 = scene_graph->getJoint(
"joint_a1")->
clone();
1889 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a1"));
1890 EXPECT_TRUE(scene_graph->addJoint(new_joint_a1));
1891 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a1));
1906 auto state_solver = S(*scene_graph);
1908 Joint new_joint_a3 = scene_graph->getJoint(
"joint_a3")->
clone();
1911 EXPECT_TRUE(state_solver.replaceJoint(new_joint_a3));
1913 EXPECT_TRUE(scene_graph->removeJoint(
"joint_a3"));
1914 EXPECT_TRUE(scene_graph->addJoint(new_joint_a3));
1928 auto state_solver = S(*scene_graph);
1930 Joint new_joint_a3 = scene_graph->getJoint(
"joint_a3")->
clone(
"joint_does_not_exist");
1932 EXPECT_FALSE(state_solver.replaceJoint(new_joint_a3));
1946 auto state_solver = S(*scene_graph);
1948 Joint new_joint_a3 = scene_graph->getJoint(
"joint_a3")->
clone();
1951 EXPECT_FALSE(state_solver.replaceJoint(new_joint_a3));
1965 #endif // TESSERACT_STATE_SOLVER_