39#include <urdf_parser/urdf_parser.h>
40#include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
41#include <gtest/gtest.h>
48constexpr double EPSILON{ 1.e-9 };
52Eigen::VectorXd makeVector(
const std::vector<double>& values)
54 Eigen::VectorXd vector = Eigen::VectorXd::Zero(values.size());
55 for (std::size_t i = 0; i < values.size(); i++)
57 vector[i] = values[i];
64 const Eigen::VectorXd& joint_values,
const Eigen::VectorXd& joint_velocities,
82 Eigen::MatrixXd jacobian;
83 state.
getJacobian(&joint_model_group, reference_link, Eigen::Vector3d::Zero(), jacobian);
86 const std::vector<const moveit::core::JointModel*>& joint_models = joint_model_group.
getJointModels();
88 return jm->getParentLinkModel() == reference_link;
90 if (it != joint_models.end())
92 std::size_t index = 0;
93 for (
auto jt = joint_models.begin(); jt != it; ++jt)
95 index += (*jt)->getVariableCount();
98 EXPECT_TRUE(jacobian.block(0, index, jacobian.rows(), jacobian.cols() - index).isZero())
99 <<
"Jacobian contains non-zero values for joints that are not used based on the reference link "
100 << reference_link->getName() <<
". This is the faulty Jacobian: " <<
'\n'
102 <<
"The columns " << index <<
" to " << jacobian.cols() <<
" should be zero. Instead the values are: " <<
'\n'
103 << jacobian.block(0, index, jacobian.rows(), jacobian.cols() - index);
107 const Eigen::VectorXd cartesian_velocity = jacobian * joint_velocities;
111 constexpr double time_step = 1e-5;
112 const Eigen::VectorXd delta_joint_angles = time_step * joint_velocities;
115 const Eigen::Isometry3d tip_pose_after_delta = root_pose_world * state.
getGlobalLinkTransform(reference_link);
116 const Eigen::Vector3d displacement = tip_pose_after_delta.translation() - tip_pose_initial.translation();
120 double angle = std::acos(displacement.dot(cartesian_velocity.head<3>()) /
121 (displacement.norm() * cartesian_velocity.head<3>().norm()));
122 EXPECT_NEAR(angle, 0.0, 1e-05) <<
"Angle between Cartesian velocity and Cartesian displacement larger than expected. "
124 << angle <<
". displacement: " << displacement.transpose()
125 <<
". Cartesian velocity: " << cartesian_velocity.head<3>().transpose() <<
'\n';
129static void expect_near(
const Eigen::MatrixXd& x,
const Eigen::MatrixXd& y,
130 double eps = std::numeric_limits<double>::epsilon())
132 ASSERT_EQ(x.rows(), y.rows());
133 ASSERT_EQ(x.cols(), y.cols());
134 for (
int r = 0; r < x.rows(); ++r)
136 for (
int c = 0; c < x.cols(); ++c)
137 EXPECT_NEAR(x(r, c), y(r, c), eps) <<
"(r,c) = (" << r <<
',' << c <<
')';
142#define EXPECT_NEAR_TRACED(...) { \
143 SCOPED_TRACE("expect_near(" #__VA_ARGS__ ")"); \
144 expect_near(__VA_ARGS__); \
151 builder.
addVirtualJoint(
"odom_combined",
"base_link",
"floating",
"base_joint");
152 ASSERT_TRUE(builder.
isValid());
153 moveit::core::RobotModelPtr model = builder.
build();
163 EXPECT_EQ(std::string(
"myrobot"), model->getName());
166 const std::vector<moveit::core::LinkModel*>& links = model->getLinkModels();
167 EXPECT_EQ(1u, links.size());
169 const std::vector<moveit::core::JointModel*>& joints = model->getJointModels();
170 EXPECT_EQ(1u, joints.size());
172 const std::vector<std::string>& pgroups = model->getJointModelGroupNames();
173 EXPECT_EQ(0u, pgroups.size());
179 geometry_msgs::msg::Pose pose;
180 pose.position.x = -0.1;
186 pose.orientation = tf2::toMsg(q);
192 pose.orientation = tf2::toMsg(q);
195 pose.position.y = 0.099;
198 pose.orientation = tf2::toMsg(q);
199 builder.
addInertial(
"base_link", 2.81, pose, 0.1, -0.2, 0.5, -0.09, 1, 0.101);
200 builder.
addVirtualJoint(
"odom_combined",
"base_link",
"planar",
"base_joint");
201 builder.
addGroup({}, {
"base_joint" },
"base");
203 ASSERT_TRUE(builder.
isValid());
204 moveit::core::RobotModelPtr model = builder.
build();
211 EXPECT_EQ(1u,
static_cast<unsigned int>(model->getJointModelCount()));
212 EXPECT_EQ(3u,
static_cast<unsigned int>(model->getJointModels()[0]->getLocalVariableNames().size()));
214 std::map<std::string, double> joint_values;
215 joint_values[
"base_joint/x"] = 10.0;
216 joint_values[
"base_joint/y"] = 8.0;
219 std::vector<std::string> missing_states;
221 ASSERT_EQ(missing_states.size(), 1u);
222 EXPECT_EQ(missing_states[0], std::string(
"base_joint/theta"));
223 joint_values[
"base_joint/theta"] = 0.1;
226 ASSERT_EQ(missing_states.size(), 0u);
232 const auto new_state = std::make_unique<moveit::core::RobotState>(state);
236 jv[state.
getRobotModel()->getVariableIndex(
"base_joint/x")] = 5.0;
237 jv[state.
getRobotModel()->getVariableIndex(
"base_joint/y")] = 4.0;
238 jv[state.
getRobotModel()->getVariableIndex(
"base_joint/theta")] = 0.0;
249 static const std::string MODEL2 = R
"(
250 <?xml version="1.0" ?>
251 <robot name="one_robot">
252 <link name="base_link">
255 <origin rpy="0 0 0" xyz="0.0 0.0 .0"/>
256 <inertia ixx="0.1" ixy="-0.2" ixz="0.5" iyy="-.09" iyz="1" izz="0.101"/>
258 <collision name="my_collision">
259 <origin rpy="0 0 0" xyz="0 0 0"/>
265 <origin rpy="0 0 0" xyz="0.0 0 0"/>
271 <joint name="joint_a" type="continuous">
273 <parent link="base_link"/>
274 <child link="link_a"/>
275 <origin rpy=" 0.0 0 0 " xyz="0.0 0 0 "/>
280 <origin rpy="0 0 0" xyz="0.0 0.0 .0"/>
281 <inertia ixx="0.1" ixy="-0.2" ixz="0.5" iyy="-.09" iyz="1" izz="0.101"/>
284 <origin rpy="0 0 0" xyz="0 0 0"/>
290 <origin rpy="0 0 0" xyz="0.0 0 0"/>
296 <joint name="joint_b" type="fixed">
297 <parent link="link_a"/>
298 <child link="link_b"/>
299 <origin rpy=" 0.0 -0.42 0 " xyz="0.0 0.5 0 "/>
304 <origin rpy="0 0 0" xyz="0.0 0.0 .0"/>
305 <inertia ixx="0.1" ixy="-0.2" ixz="0.5" iyy="-.09" iyz="1" izz="0.101"/>
308 <origin rpy="0 0 0" xyz="0 0 0"/>
314 <origin rpy="0 0 0" xyz="0.0 0 0"/>
320 <joint name="joint_c" type="prismatic">
322 <limit effort="100.0" lower="0.0" upper="0.09" velocity="0.2"/>
323 <safety_controller k_position="20.0" k_velocity="500.0" soft_lower_limit="0.0"
324 soft_upper_limit="0.089"/>
325 <parent link="link_b"/>
326 <child link="link_c"/>
327 <origin rpy=" 0.0 0.42 0.0 " xyz="0.0 -0.1 0 "/>
332 <origin rpy="0 0 0" xyz="0.0 0 .0"/>
333 <inertia ixx="0.1" ixy="-0.2" ixz="0.5" iyy="-.09" iyz="1" izz="0.101"/>
336 <origin rpy="0 0 0" xyz="0 0 0"/>
342 <origin rpy="0 0 0" xyz="0.0 0 0"/>
348 <joint name="mim_f" type="prismatic">
350 <limit effort="100.0" lower="0.0" upper="0.19" velocity="0.2"/>
351 <parent link="link_c"/>
352 <child link="link_d"/>
353 <origin rpy=" 0.0 0.0 0.0 " xyz="0.1 0.1 0 "/>
354 <mimic joint="joint_f" multiplier="1.5" offset="0.1"/>
356 <joint name="joint_f" type="prismatic">
358 <limit effort="100.0" lower="0.0" upper="0.19" velocity="0.2"/>
359 <parent link="link_d"/>
360 <child link="link_e"/>
361 <origin rpy=" 0.0 0.0 0.0 " xyz="0.1 0.1 0 "/>
365 <origin rpy="0 0 0" xyz="0 0 0"/>
371 <origin rpy="0 1 0" xyz="0 0.1 0"/>
379 <origin rpy="0 0 0" xyz="0 0 0"/>
385 <origin rpy="0 1 0" xyz="0 0.1 0"/>
394 static const std::string SMODEL2 = R
"xml(
395 <?xml version="1.0" ?>
396 <robot name="one_robot">
397 <virtual_joint name="base_joint" child_link="base_link" parent_frame="odom_combined" type="planar"/>
398 <group name="base_from_joints">
399 <joint name="base_joint"/>
400 <joint name="joint_a"/>
401 <joint name="joint_c"/>
403 <group name="mim_joints">
404 <joint name="joint_f"/>
405 <joint name="mim_f"/>
407 <group name="base_with_subgroups">
408 <group name="base_from_base_to_tip"/>
409 <joint name="joint_c"/>
411 <group name="base_from_base_to_tip">
412 <chain base_link="base_link" tip_link="link_b"/>
413 <joint name="base_joint"/>
415 <group name="base_from_base_to_e">
416 <chain base_link="base_link" tip_link="link_e"/>
417 <joint name="base_joint"/>
419 <group name="base_with_bad_subgroups">
420 <group name="error"/>
425 urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(MODEL2);
426 auto srdf_model = std::make_shared<srdf::Model>();
427 srdf_model->initString(*urdf_model, SMODEL2);
428 robot_model_ = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
469 moveit::core::RobotModelConstPtr model = robot_model_;
478 ASSERT_TRUE(g_one !=
nullptr);
479 ASSERT_TRUE(g_two !=
nullptr);
480 ASSERT_TRUE(g_three !=
nullptr);
481 ASSERT_TRUE(g_four ==
nullptr);
496 std::sort(jmn.begin(), jmn.end());
497 EXPECT_EQ(jmn[0],
"base_joint");
498 EXPECT_EQ(jmn[1],
"joint_a");
499 EXPECT_EQ(jmn[2],
"joint_c");
501 std::sort(jmn.begin(), jmn.end());
502 EXPECT_EQ(jmn[0],
"base_joint");
503 EXPECT_EQ(jmn[1],
"joint_a");
504 EXPECT_EQ(jmn[2],
"joint_b");
506 std::sort(jmn.begin(), jmn.end());
507 EXPECT_EQ(jmn[0],
"base_joint");
508 EXPECT_EQ(jmn[1],
"joint_a");
509 EXPECT_EQ(jmn[2],
"joint_b");
510 EXPECT_EQ(jmn[3],
"joint_c");
540 std::map<std::string, double> joint_values;
541 joint_values[
"base_joint/x"] = 1.0;
542 joint_values[
"base_joint/y"] = 1.0;
543 joint_values[
"base_joint/theta"] = 0.5;
544 joint_values[
"joint_a"] = -0.5;
545 joint_values[
"joint_c"] = 0.08;
574 std::map<std::string, double> upd_a;
575 upd_a[
"joint_a"] = 0.2;
582 upd_a[
"joint_a"] = 3.2;
614 EXPECT_NEAR(mim_f, 1.5 * joint_f + 0.1, 1e-8);
619 Eigen::Vector3d(0.1 + mim_f + joint_f + 0.1, 0.6, 0));
635 ASSERT_TRUE(joint_model_group);
639 std::cout <<
"\nVisual inspection should show NO joints out of bounds:\n";
642 std::cout <<
"\nVisual inspection should show ONE joint out of bounds:\n";
643 std::vector<double> single_joint(1);
644 single_joint[0] = -1.0;
648 std::cout <<
"\nVisual inspection should show TWO joint out of bounds:\n";
649 single_joint[0] = 1.0;
653 std::cout <<
"\nVisual inspection should show ONE joint out of bounds:\n";
654 single_joint[0] = 0.19;
667 for (
size_t i = 0; i <= 10; ++i)
669 state_a.
interpolate(state_b,
static_cast<double>(i) / 10., interpolated_state,
671 EXPECT_NEAR(state_a.
distance(state_b), 0,
EPSILON) <<
"Interpolation between identical states yielded a different "
674 for (
const auto& link_name : robot_model_->getLinkModelNames())
684 std::map<std::string, double> joint_values;
685 joint_values[
"base_joint/x"] = 1.0;
686 joint_values[
"base_joint/y"] = 1.0;
688 joint_values[
"base_joint/x"] = 0.0;
689 joint_values[
"base_joint/y"] = 2.0;
691 EXPECT_NEAR(3 * std::sqrt(2), state_a.
distance(state_b),
EPSILON) <<
"Simple interpolation of base_joint failed.";
694 EXPECT_NEAR(0., state_a.
distance(interpolated_state) - state_b.
distance(interpolated_state),
EPSILON) <<
"Simple "
700 "base_joint failed.";
702 "base_joint failed.";
705 "base_joint failed.";
707 "base_joint failed.";
710 joint_values[
"base_joint/x"] = 0.0;
711 joint_values[
"base_joint/y"] = 20.0;
712 joint_values[
"base_joint/theta"] = 3 * M_PI / 4;
713 joint_values[
"joint_a"] = -4 * M_PI / 5;
714 joint_values[
"joint_c"] = 0.0;
715 joint_values[
"joint_f"] = 1.0;
718 joint_values[
"base_joint/x"] = 10.0;
719 joint_values[
"base_joint/y"] = 0.0;
720 joint_values[
"base_joint/theta"] = -3 * M_PI / 4;
721 joint_values[
"joint_a"] = 4 * M_PI / 5;
722 joint_values[
"joint_c"] = 0.07;
723 joint_values[
"joint_f"] = 0.0;
726 for (
size_t i = 0; i <= 5; ++i)
728 double t =
static_cast<double>(i) / 5.;
731 "interpolation failed.";
738 <<
"Base joint theta interpolation failed.";
740 <<
"Continuous joint interpolation failed.";
744 EXPECT_NEAR(-3 * M_PI / 4 - (M_PI / 2) * (1 - t), interpolated_state.
getVariablePosition(
"base_joint/theta"),
746 <<
"Base joint theta interpolation failed.";
748 <<
"Continuous joint interpolation failed.";
759 bool nan_exception =
false;
764 catch (std::exception& e)
766 std::cout <<
"Caught expected exception: " << e.what() <<
'\n';
767 nan_exception =
true;
769 EXPECT_TRUE(nan_exception) <<
"NaN interpolation parameter did not create expected exception.";
776 EXPECT_EQ(robot_model_->getRigidlyConnectedParentLinkModel(link_e), link_e);
781 EXPECT_EQ(robot_model_->getRigidlyConnectedParentLinkModel(link_b), link_a);
790 state.
attachBody(std::make_unique<moveit::core::AttachedBody>(
791 link_b,
"object", Eigen::Isometry3d::Identity(), std::vector<shapes::ShapeConstPtr>{},
792 EigenSTL::vector_Isometry3d{}, std::set<std::string>{}, trajectory_msgs::msg::JointTrajectory{},
807TEST(getJacobian, RevoluteJoints)
810 constexpr char robot_urdf[] = R
"(
811 <?xml version="1.0" ?>
812 <robot name="one_robot">
813 <link name="base_link"/>
814 <joint name="joint_a_revolute" type="revolute">
816 <parent link="base_link"/>
817 <child link="link_a"/>
818 <origin rpy="0 0 0" xyz="0 0 0"/>
819 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
821 <link name="link_a"/>
822 <joint name="joint_b_revolute" type="revolute">
824 <parent link="link_a"/>
825 <child link="link_b"/>
826 <origin rpy="0 0 0" xyz="0.0 0.5 0"/>
827 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
829 <link name="link_b"/>
830 <joint name="joint_c_revolute" type="revolute">
832 <parent link="link_b"/>
833 <child link="link_c"/>
834 <origin rpy="0 0 0" xyz="0.2 0.2 0"/>
835 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
837 <link name="link_c"/>
838 <joint name="joint_d_revolute" type="revolute">
840 <parent link="link_c"/>
841 <child link="link_d"/>
842 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
843 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
845 <link name="link_d"/>
849 constexpr char robot_srdf[] = R
"xml(
850 <?xml version="1.0" ?>
851 <robot name="one_robot">
852 <group name="base_to_tip">
853 <joint name="joint_a_revolute"/>
854 <joint name="joint_b_revolute"/>
855 <joint name="joint_c_revolute"/>
856 <joint name="joint_d_revolute"/>
861 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
862 ASSERT_TRUE(urdf_model);
863 const auto srdf_model = std::make_shared<srdf::Model>();
864 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
865 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
871 checkJacobian(state, *jmg, makeVector({ 0.0, 0.0, 0.0, 0.0 }), makeVector({ 0.1, 0.2, 0.3, 0.4 }));
872 checkJacobian(state, *jmg, makeVector({ 0.1, 0.2, 0.3, 0.4 }), makeVector({ 0.5, 0.3, 0.2, 0.1 }));
875TEST(getJacobian, RevoluteJointsButDifferentLink)
878 constexpr char robot_urdf[] = R
"(
879 <?xml version="1.0" ?>
880 <robot name="one_robot">
881 <link name="base_link"/>
882 <joint name="joint_a_revolute" type="revolute">
884 <parent link="base_link"/>
885 <child link="link_a"/>
886 <origin rpy="0 0 0" xyz="0 0 0"/>
887 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
889 <link name="link_a"/>
890 <joint name="joint_b_revolute" type="revolute">
892 <parent link="link_a"/>
893 <child link="link_b"/>
894 <origin rpy="0 0 0" xyz="0.0 0.5 0"/>
895 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
897 <link name="link_b"/>
898 <joint name="joint_c_revolute" type="revolute">
900 <parent link="link_b"/>
901 <child link="link_c"/>
902 <origin rpy="0 0 0" xyz="0.2 0.2 0"/>
903 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
905 <link name="link_c"/>
906 <joint name="joint_d_revolute" type="revolute">
908 <parent link="link_c"/>
909 <child link="link_d"/>
910 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
911 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
913 <link name="link_d"/>
917 constexpr char robot_srdf[] = R
"xml(
918 <?xml version="1.0" ?>
919 <robot name="one_robot">
920 <group name="base_to_tip">
921 <joint name="joint_a_revolute"/>
922 <joint name="joint_b_revolute"/>
923 <joint name="joint_c_revolute"/>
924 <joint name="joint_d_revolute"/>
929 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
930 ASSERT_TRUE(urdf_model);
931 const auto srdf_model = std::make_shared<srdf::Model>();
932 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
933 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
939 checkJacobian(state, *jmg, makeVector({ 0.0, 0.0, 0.0, 0.0 }), makeVector({ 0.1, 0.2, 0.3, 0.4 }),
941 checkJacobian(state, *jmg, makeVector({ 0.1, 0.2, 0.3, 0.4 }), makeVector({ 0.5, 0.3, 0.2, 0.1 }),
945TEST(getJacobian, RevoluteAndPrismaticJoints)
948 constexpr char robot_urdf[] = R
"(
949 <?xml version="1.0" ?>
950 <robot name="one_robot">
951 <link name="base_link"/>
952 <joint name="joint_a_revolute" type="revolute">
954 <parent link="base_link"/>
955 <child link="link_a"/>
956 <origin rpy="0 0 0" xyz="0 0 0"/>
957 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
959 <link name="link_a"/>
960 <joint name="joint_b_revolute" type="revolute">
962 <parent link="link_a"/>
963 <child link="link_b"/>
964 <origin rpy="0 0 0" xyz="0.0 0.5 0"/>
965 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
967 <link name="link_b"/>
968 <joint name="joint_c_prismatic" type="prismatic">
970 <parent link="link_b"/>
971 <child link="link_c"/>
972 <origin rpy="0 0 0" xyz="0.2 0.2 0"/>
973 <limit effort="100.0" lower="-1.0" upper="1.0" velocity="0.2"/>
975 <link name="link_c"/>
976 <joint name="joint_d_revolute" type="revolute">
978 <parent link="link_c"/>
979 <child link="link_d"/>
980 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
981 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
983 <link name="link_d"/>
987 constexpr char robot_srdf[] = R
"xml(
988 <?xml version="1.0" ?>
989 <robot name="one_robot">
990 <group name="base_to_tip">
991 <joint name="joint_a_revolute"/>
992 <joint name="joint_b_revolute"/>
993 <joint name="joint_c_prismatic"/>
994 <joint name="joint_d_revolute"/>
999 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
1000 ASSERT_TRUE(urdf_model);
1001 const auto srdf_model = std::make_shared<srdf::Model>();
1002 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
1003 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
1009 checkJacobian(state, *jmg, makeVector({ 0.0, 0.0, 0.0, 0.0 }), makeVector({ 0.1, 0.2, 0.3, 0.4 }));
1010 checkJacobian(state, *jmg, makeVector({ 0.1, 0.2, 0.3, 0.4 }), makeVector({ 0.5, 0.3, 0.2, 0.1 }));
1013TEST(getJacobian, RevoluteAndFixedJoints)
1016 constexpr char robot_urdf[] = R
"(
1017 <?xml version="1.0" ?>
1018 <robot name="one_robot">
1019 <link name="base_link"/>
1020 <joint name="joint_a_revolute" type="revolute">
1022 <parent link="base_link"/>
1023 <child link="link_a"/>
1024 <origin rpy="0 0 0" xyz="0 0 0"/>
1025 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1027 <link name="link_a"/>
1028 <joint name="joint_b_fixed" type="fixed">
1029 <parent link="link_a"/>
1030 <child link="link_b"/>
1032 <link name="link_b"/>
1033 <joint name="joint_c_fixed" type="fixed">
1034 <parent link="link_b"/>
1035 <child link="link_c"/>
1037 <link name="link_c"/>
1038 <joint name="joint_d_revolute" type="revolute">
1040 <parent link="link_c"/>
1041 <child link="link_d"/>
1042 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
1043 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1045 <link name="link_d"/>
1049 constexpr char robot_srdf[] = R
"xml(
1050 <?xml version="1.0" ?>
1051 <robot name="one_robot">
1052 <group name="base_to_tip">
1053 <joint name="joint_a_revolute"/>
1054 <joint name="joint_b_fixed"/>
1055 <joint name="joint_c_fixed"/>
1056 <joint name="joint_d_revolute"/>
1061 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
1062 ASSERT_TRUE(urdf_model);
1063 const auto srdf_model = std::make_shared<srdf::Model>();
1064 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
1065 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
1071 checkJacobian(state, *jmg, makeVector({ 0.0, 0.0 }), makeVector({ 0.1, 0.4 }));
1072 checkJacobian(state, *jmg, makeVector({ 0.1, 0.4 }), makeVector({ 0.5, 0.1 }));
1075TEST(getJacobian, RevolutePlanarAndPrismaticJoints)
1078 constexpr char robot_urdf[] = R
"(
1079 <?xml version="1.0" ?>
1080 <robot name="one_robot">
1081 <link name="base_link"/>
1082 <joint name="joint_a_planar" type="planar">
1084 <parent link="base_link"/>
1085 <child link="link_a"/>
1086 <origin rpy="0 0 0" xyz="0 0 0"/>
1087 <limit effort="100.0" lower="-1.0" upper="1.0" velocity="0.2"/>
1089 <link name="link_a"/>
1090 <joint name="joint_b_revolute" type="revolute">
1092 <parent link="link_a"/>
1093 <child link="link_b"/>
1094 <origin rpy="0 0 0" xyz="0.0 0.5 0"/>
1095 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1097 <link name="link_b"/>
1098 <joint name="joint_c_prismatic" type="prismatic">
1100 <parent link="link_b"/>
1101 <child link="link_c"/>
1102 <origin rpy="0 0 0" xyz="0.2 0.2 0"/>
1103 <limit effort="100.0" lower="-1.0" upper="1.0" velocity="0.2"/>
1105 <link name="link_c"/>
1106 <joint name="joint_d_revolute" type="revolute">
1108 <parent link="link_c"/>
1109 <child link="link_d"/>
1110 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
1111 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1113 <link name="link_d"/>
1117 constexpr char robot_srdf[] = R
"xml(
1118 <?xml version="1.0" ?>
1119 <robot name="one_robot">
1120 <group name="base_to_tip">
1121 <joint name="joint_a_planar"/>
1122 <joint name="joint_b_revolute"/>
1123 <joint name="joint_c_prismatic"/>
1124 <joint name="joint_d_revolute"/>
1129 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
1130 ASSERT_TRUE(urdf_model);
1131 const auto srdf_model = std::make_shared<srdf::Model>();
1132 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
1133 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
1138 checkJacobian(state, *jmg, makeVector({ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }),
1139 makeVector({ 0.2, 0.05, 0.1, 0.2, 0.3, 0.4 }));
1145 constexpr char robot_urdf[] = R
"(
1146 <?xml version="1.0" ?>
1147 <robot name="one_robot">
1148 <link name="origin"/>
1149 <joint name="fixed_offset" type="fixed">
1150 <parent link="origin"/>
1151 <child link="link_a"/>
1152 <origin rpy="0 0 1.5707" xyz="0.0 0.0 0.0"/>
1154 <link name="link_a"/>
1155 <joint name="joint_a_revolute" type="revolute">
1157 <parent link="link_a"/>
1158 <child link="link_b"/>
1159 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
1160 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1162 <link name="link_b"/>
1163 <joint name="joint_b_revolute" type="revolute">
1165 <parent link="link_b"/>
1166 <child link="link_c"/>
1167 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
1168 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1170 <link name="link_c"/>
1171 <joint name="joint_c_revolute" type="revolute">
1173 <parent link="link_c"/>
1174 <child link="link_d"/>
1175 <origin rpy="0 0 0" xyz="0.0 0.2 0.4"/>
1176 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1178 <link name="link_d"/>
1182 constexpr char robot_srdf[] = R
"xml(
1183 <?xml version="1.0" ?>
1184 <robot name="one_robot">
1185 <group name="base_to_tip">
1186 <joint name="joint_a_revolute"/>
1187 <joint name="joint_b_revolute"/>
1188 <joint name="joint_c_revolute"/>
1193 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
1194 ASSERT_TRUE(urdf_model);
1195 const auto srdf_model = std::make_shared<srdf::Model>();
1196 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
1197 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
1203 checkJacobian(state, *jmg, makeVector({ 0.0, 0.0, 0.0 }), makeVector({ 0.1, 0.4, 0.2 }));
1204 checkJacobian(state, *jmg, makeVector({ 0.1, 0.4, 0.3 }), makeVector({ 0.5, 0.1, 0.2 }));
1207TEST(getJointPositions, getFixedJointValue)
1211 constexpr char robot_urdf[] = R
"(
1212 <?xml version="1.0" ?>
1213 <robot name="one_robot">
1214 <link name="base_link"/>
1215 <joint name="joint_a_revolute" type="revolute">
1217 <parent link="base_link"/>
1218 <child link="link_a"/>
1219 <origin rpy="0 0 0" xyz="0 0 0"/>
1220 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1222 <link name="link_a"/>
1223 <joint name="joint_b_revolute" type="revolute">
1225 <parent link="link_a"/>
1226 <child link="link_b"/>
1227 <origin rpy="0 0 0" xyz="0 0 0"/>
1228 <limit effort="100.0" lower="-3.14" upper="3.14" velocity="0.2"/>
1230 <link name="link_b"/>
1231 <joint name="joint_c_fixed" type="fixed">
1232 <parent link="link_b"/>
1233 <child link="link_c"/>
1235 <link name="link_c"/>
1239 constexpr char robot_srdf[] = R
"xml(
1240 <?xml version="1.0" ?>
1241 <robot name="one_robot">
1242 <group name="base_to_tip">
1243 <joint name="joint_a_revolute"/>
1244 <joint name="joint_b_revolute"/>
1245 <joint name="joint_c_fixed"/>
1250 const urdf::ModelInterfaceSharedPtr urdf_model = urdf::parseURDF(robot_urdf);
1251 ASSERT_TRUE(urdf_model);
1252 const auto srdf_model = std::make_shared<srdf::Model>();
1253 ASSERT_TRUE(srdf_model->initString(*urdf_model, robot_srdf));
1254 const auto robot_model = std::make_shared<moveit::core::RobotModel>(urdf_model, srdf_model);
1260 ASSERT_EQ(joint_value,
nullptr);
1265 testing::InitGoogleTest(&argc, argv);
1266 return RUN_ALL_TESTS();
moveit::core::RobotModelConstPtr robot_model_
const std::vector< std::string > & getJointModelNames() const
Get the names of the joints in this group. These are the names of the joints returned by getJointMode...
const std::vector< const LinkModel * > & getLinkModels() const
Get the links that are part of this joint group.
unsigned int getVariableCount() const
Get the number of variables that describe this joint group. This includes variables necessary for mim...
const std::vector< std::string > & getLinkModelNames() const
Get the names of the links that are part of this joint group.
const std::vector< const LinkModel * > & getUpdatedLinkModels() const
Get the names of the links that are to be updated when the state of this group changes....
const std::vector< const JointModel * > & getJointModels() const
Get all the joints in this group (including fixed and mimic joints).
A joint from the robot. Models the transform that this joint applies in the kinematic chain....
const LinkModel * getParentLinkModel() const
Get the link that this joint connects to. The robot is assumed to start with a joint,...
A link from the robot. Contains the constant transform applied to the link and its geometry.
Easily build different robot models for testing. Essentially a programmer-friendly light wrapper arou...
void addInertial(const std::string &link_name, double mass, geometry_msgs::msg::Pose origin, double ixx, double ixy, double ixz, double iyy, double iyz, double izz)
void addCollisionBox(const std::string &link_name, const std::vector< double > &dims, geometry_msgs::msg::Pose origin)
Adds a collision box to a specific link.
bool isValid()
Returns true if the building process so far has been valid.
void addGroup(const std::vector< std::string > &links, const std::vector< std::string > &joints, const std::string &name)
Adds a new group using a list of links and a list of joints.
moveit::core::RobotModelPtr build()
Builds and returns the robot model added to the builder.
void addVirtualJoint(const std::string &parent_frame, const std::string &child_link, const std::string &type, const std::string &name="")
Adds a virtual joint to the SRDF.
void addVisualBox(const std::string &link_name, const std::vector< double > &size, geometry_msgs::msg::Pose origin)
Adds a visual box to a specific link.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void setVariablePositions(const double *position)
It is assumed positions is an array containing the new positions for all variables in this state....
void setVariableAcceleration(const std::string &variable, double value)
Set the acceleration of a variable. If an unknown variable name is specified, an exception is thrown.
double getVariableAcceleration(const std::string &variable) const
Get the acceleration of a particular variable. An exception is thrown if the variable is not known.
void attachBody(std::unique_ptr< AttachedBody > attached_body)
Add an attached body to this state.
bool getJacobian(const JointModelGroup *group, const LinkModel *link, const Eigen::Vector3d &reference_point_position, Eigen::MatrixXd &jacobian, bool use_quaternion_representation=false) const
Compute the Jacobian with reference to a particular point on a given link, for a specified group.
const double * getJointPositions(const std::string &joint_name) const
void setVariableVelocity(const std::string &variable, double value)
Set the velocity of a variable. If an unknown variable name is specified, an exception is thrown.
double getVariableVelocity(const std::string &variable) const
Get the velocity of a particular variable. An exception is thrown if the variable is not known.
void setVariablePosition(const std::string &variable, double value)
Set the position of a single variable. An exception is thrown if the variable name is not known.
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
void copyJointGroupPositions(const std::string &joint_group_name, std::vector< double > &gstate) const
For a given group, copy the position values of the variables that make up the group into another loca...
const JointModelGroup * getJointModelGroup(const std::string &group) const
Get the model of a particular joint group.
void printStatePositionsWithJointLimits(const moveit::core::JointModelGroup *jmg, std::ostream &out=std::cout) const
Output to console the current state of the robot's joint limits.
const LinkModel * getLinkModel(const std::string &link) const
Get the model of a particular link.
const RobotModelConstPtr & getRobotModel() const
Get the robot model this state is constructed for.
void updateLinkTransforms()
Update the reference frame transforms for links. This call is needed before using the transforms of l...
void interpolate(const RobotState &to, double t, RobotState &state) const
const Eigen::Isometry3d & getCollisionBodyTransform(const std::string &link_name, std::size_t index)
Get the link transform w.r.t. the root link (model frame) of the RobotModel. This is typically the ro...
double distance(const RobotState &other) const
Return the sum of joint distances to "other" state. An L1 norm. Only considers active joints.
void setToRandomPositions()
Set all joints to random values. Values will be within default bounds.
bool satisfiesBounds(double margin=0.0) const
bool dirtyLinkTransforms() const
double getVariablePosition(const std::string &variable) const
Get the position of a particular variable. An exception is thrown if the variable is not known.
void setToDefaultValues()
Set all joints to their default positions. The default position is 0, or if that is not within bounds...
std::size_t getVariableCount() const
Get the number of variables that make up this state.
const Eigen::Isometry3d & getGlobalLinkTransform(const std::string &link_name)
Get the link transform w.r.t. the root link (model frame) of the RobotModel. This is typically the ro...
const moveit::core::LinkModel * getRigidlyConnectedParentLinkModel(const std::string &frame) const
Get the latest link upwards the kinematic tree which is only connected via fixed joints.
void setJointPositions(const std::string &joint_name, const double *position)
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
int main(int argc, char **argv)
TEST(Loading, SimpleRobot)
#define EXPECT_NEAR_TRACED(...)
TEST_F(OneRobot, setToDefaultValues)