35 #include <gtest/gtest.h>
46 #include <moveit_msgs/Constraints.h>
47 #include <moveit_msgs/GetMotionPlan.h>
48 #include <moveit_msgs/JointConstraint.h>
52 #include <tf2_eigen/tf2_eigen.hpp>
53 #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
78 void SetUp()
override;
81 ros::NodeHandle ph_{
"~" };
88 std::unique_ptr<pilz_industrial_motion_planner_testutils::TestdataLoader>
test_data_;
90 unsigned int num_joints_{ 0 };
97 robot_model_ = model_loader.
getModel();
106 ASSERT_TRUE(ros::service::waitForService(
PLAN_SERVICE_NAME, ros::Duration(testutils::DEFAULT_SERVICE_TIMEOUT)));
110 std::make_unique<pilz_industrial_motion_planner_testutils::XmlTestdataLoader>(test_data_file_name_, robot_model_);
111 ASSERT_NE(
nullptr, test_data_) <<
"Failed to load test data by provider.";
113 num_joints_ = robot_model_->getJointModelGroup(planning_group_)->getActiveJointModelNames().size();
128 ros::NodeHandle node_handle(
"~");
129 auto ptp{ test_data_->getPtpJoint(
"Ptp1") };
131 moveit_msgs::GetMotionPlan srv;
133 srv.request.motion_plan_request = req;
135 ros::ServiceClient client = node_handle.serviceClient<moveit_msgs::GetMotionPlan>(
PLAN_SERVICE_NAME);
137 ASSERT_TRUE(client.call(srv));
138 const moveit_msgs::msg::MotionPlanResponse& response{ srv.response.motion_plan_response };
141 ASSERT_EQ(moveit_msgs::msg::MoveItErrorCodes::SUCCESS, response.error_code.val) <<
"Planning failed!";
142 trajectory_msgs::JointTrajectory trajectory = response.trajectory.joint_trajectory;
144 EXPECT_EQ(trajectory.joint_names.size(), num_joints_) <<
"Wrong number of jointnames";
145 EXPECT_GT(trajectory.points.size(), 0u) <<
"There are no points in the trajectory";
148 for (
const auto& point : trajectory.points)
150 EXPECT_EQ(point.positions.size(), num_joints_);
151 EXPECT_EQ(point.velocities.size(), num_joints_);
152 EXPECT_EQ(point.accelerations.size(), num_joints_);
155 for (
size_t i = 0; i < num_joints_; ++i)
157 EXPECT_NEAR(trajectory.points.back().positions.at(i), req.goal_constraints.back().joint_constraints.at(i).position,
159 EXPECT_NEAR(trajectory.points.back().velocities.at(i), 0, 10e-10);
177 ros::NodeHandle node_handle(
"~");
179 PtpJointCart ptp{ test_data_->getPtpJointCart(
"Ptp1") };
181 ptp.getGoalConfiguration().setAngleTolerance(0.01);
183 moveit_msgs::GetMotionPlan srv;
184 srv.request.motion_plan_request = ptp.toRequest();
186 ros::ServiceClient client = node_handle.serviceClient<moveit_msgs::GetMotionPlan>(
PLAN_SERVICE_NAME);
188 ASSERT_TRUE(client.call(srv));
189 const moveit_msgs::msg::MotionPlanResponse& response{ srv.response.motion_plan_response };
192 ASSERT_EQ(moveit_msgs::msg::MoveItErrorCodes::SUCCESS, response.error_code.val) <<
"Planning failed!";
195 trajectory_msgs::JointTrajectory trajectory = response.trajectory.joint_trajectory;
197 EXPECT_EQ(trajectory.joint_names.size(), num_joints_) <<
"Wrong number of jointnames";
198 EXPECT_GT(trajectory.points.size(), 0u) <<
"There are no points in the trajectory";
201 for (
const auto& point : trajectory.points)
203 EXPECT_EQ(point.positions.size(), num_joints_);
204 EXPECT_EQ(point.velocities.size(), num_joints_);
205 EXPECT_EQ(point.accelerations.size(), num_joints_);
208 robot_state::RobotState rstate(robot_model_);
209 rstate.setToDefaultValues();
210 rstate.setJointGroupPositions(planning_group_, response.trajectory.joint_trajectory.points.back().positions);
211 Eigen::Isometry3d tf = rstate.getFrameTransform(target_link_);
213 const geometry_msgs::Pose& expected_pose{ ptp.getGoalConfiguration().getPose() };
215 EXPECT_NEAR(tf(0, 3), expected_pose.position.x,
EPSILON);
216 EXPECT_NEAR(tf(1, 3), expected_pose.position.y,
EPSILON);
217 EXPECT_NEAR(tf(2, 3), expected_pose.position.z,
EPSILON);
219 Eigen::Isometry3d exp_iso3d_pose;
220 tf2::fromMsg(expected_pose, exp_iso3d_pose);
222 EXPECT_TRUE(Eigen::Quaterniond(tf.rotation()).isApprox(Eigen::Quaterniond(exp_iso3d_pose.rotation()),
EPSILON));
243 std::cout <<
"++++++++++" <<
'\n';
244 std::cout <<
"+ Step 1 +" <<
'\n';
245 std::cout <<
"++++++++++" <<
'\n';
247 moveit_msgs::GetMotionPlan srv;
248 srv.request.motion_plan_request = req;
250 ros::NodeHandle node_handle(
"~");
251 ros::ServiceClient client = node_handle.serviceClient<moveit_msgs::GetMotionPlan>(
PLAN_SERVICE_NAME);
253 ASSERT_TRUE(client.call(srv));
254 const moveit_msgs::msg::MotionPlanResponse& response{ srv.response.motion_plan_response };
256 ASSERT_EQ(moveit_msgs::msg::MoveItErrorCodes::SUCCESS, response.error_code.val) <<
"Planning failed!";
258 std::cout <<
"++++++++++" <<
'\n';
259 std::cout <<
"+ Step 2 +" <<
'\n';
260 std::cout <<
"++++++++++" <<
'\n';
263 orientation_norm_tolerance_))
264 <<
"Goal not reached.";
266 std::cout <<
"++++++++++" <<
'\n';
267 std::cout <<
"+ Step 3 +" <<
'\n';
268 std::cout <<
"++++++++++" <<
'\n';
271 pose_norm_tolerance_, orientation_norm_tolerance_))
272 <<
"Trajectory violates cartesian linearity.";
292 ros::NodeHandle node_handle(
"~");
295 std::cout <<
"++++++++++" <<
'\n';
296 std::cout <<
"+ Step 1 +" <<
'\n';
297 std::cout <<
"++++++++++" <<
'\n';
299 moveit_msgs::GetMotionPlan srv;
300 srv.request.motion_plan_request = req;
302 ros::ServiceClient client = node_handle.serviceClient<moveit_msgs::GetMotionPlan>(
PLAN_SERVICE_NAME);
304 ASSERT_TRUE(client.call(srv));
305 const moveit_msgs::msg::MotionPlanResponse& response{ srv.response.motion_plan_response };
307 ASSERT_EQ(moveit_msgs::msg::MoveItErrorCodes::SUCCESS, response.error_code.val) <<
"Planning failed!";
309 std::cout <<
"++++++++++" <<
'\n';
310 std::cout <<
"+ Step 2 +" <<
'\n';
311 std::cout <<
"++++++++++" <<
'\n';
314 orientation_norm_tolerance_))
315 <<
"Goal not reached.";
317 std::cout <<
"++++++++++" <<
'\n';
318 std::cout <<
"+ Step 3 +" <<
'\n';
319 std::cout <<
"++++++++++" <<
'\n';
322 pose_norm_tolerance_, orientation_norm_tolerance_))
323 <<
"Trajectory violates cartesian linearity.";
340 ros::NodeHandle node_handle(
"~");
346 moveit_msgs::GetMotionPlan srv;
347 srv.request.motion_plan_request = req;
349 ros::ServiceClient client = node_handle.serviceClient<moveit_msgs::GetMotionPlan>(
PLAN_SERVICE_NAME);
351 ASSERT_TRUE(client.call(srv));
352 const moveit_msgs::msg::MotionPlanResponse& response{ srv.response.motion_plan_response };
355 ASSERT_EQ(moveit_msgs::msg::MoveItErrorCodes::SUCCESS, response.error_code.val) <<
"Planning failed!";
356 trajectory_msgs::JointTrajectory trajectory = response.trajectory.joint_trajectory;
358 EXPECT_EQ(trajectory.joint_names.size(), num_joints_) <<
"Wrong number of jointnames";
359 EXPECT_GT(trajectory.points.size(), 0u) <<
"There are no points in the trajectory";
362 for (
const auto& point : trajectory.points)
364 EXPECT_EQ(point.positions.size(), num_joints_);
365 EXPECT_EQ(point.velocities.size(), num_joints_);
366 EXPECT_EQ(point.accelerations.size(), num_joints_);
371 orientation_norm_tolerance_))
372 <<
"Goal not reached.";
375 robot_state::RobotState waypoint_state(robot_model_);
376 Eigen::Isometry3d waypoint_pose;
377 double x_dist, y_dist, z_dist;
379 const geometry_msgs::Pose& aux_pose{ circ.getAuxiliaryConfiguration().getConfiguration().getPose() };
381 CircCenterCart circ_cart{ test_data_->getCircCartCenterCart(
"circ1_center_2") };
383 const geometry_msgs::Pose& goal_pose{ circ_cart.getGoalConfiguration().getPose() };
385 x_dist = aux_pose.position.x - start_pose.position.x;
386 y_dist = aux_pose.position.y - start_pose.position.y;
387 z_dist = aux_pose.position.z - start_pose.position.z;
388 double expected_radius = sqrt(x_dist * x_dist + y_dist * y_dist + z_dist * z_dist);
389 for (
const auto& waypoint : trajectory.points)
391 waypoint_state.setToDefaultValues();
392 waypoint_state.setJointGroupPositions(planning_group_, waypoint.positions);
393 waypoint_pose = waypoint_state.getFrameTransform(target_link_);
397 x_dist = aux_pose.position.x - waypoint_pose(0, 3);
398 y_dist = aux_pose.position.y - waypoint_pose(1, 3);
399 z_dist = aux_pose.position.z - waypoint_pose(2, 3);
400 double actual_radius = sqrt(x_dist * x_dist + y_dist * y_dist + z_dist * z_dist);
401 EXPECT_NEAR(actual_radius, expected_radius, pose_norm_tolerance_) <<
"Trajectory way point is not on the circle.";
404 Eigen::Isometry3d start_pose_iso3d, goal_pose_iso3d;
405 tf2::fromMsg(start_pose, start_pose_iso3d);
406 tf2::fromMsg(goal_pose, goal_pose_iso3d);
407 EXPECT_TRUE(
testutils::checkSLERP(start_pose_iso3d, goal_pose_iso3d, waypoint_pose, orientation_norm_tolerance_));
425 ros::NodeHandle node_handle(
"~");
427 CircCenterCart circ{ test_data_->getCircCartCenterCart(
"circ1_center_2") };
429 moveit_msgs::GetMotionPlan srv;
430 srv.request.motion_plan_request = req;
432 ros::ServiceClient client = node_handle.serviceClient<moveit_msgs::GetMotionPlan>(
PLAN_SERVICE_NAME);
434 ASSERT_TRUE(client.call(srv));
435 const moveit_msgs::msg::MotionPlanResponse& response = srv.response.motion_plan_response;
438 ASSERT_EQ(moveit_msgs::msg::MoveItErrorCodes::SUCCESS, response.error_code.val) <<
"Planning failed!";
439 trajectory_msgs::JointTrajectory trajectory = response.trajectory.joint_trajectory;
441 EXPECT_EQ(trajectory.joint_names.size(), num_joints_) <<
"Wrong number of jointnames";
442 EXPECT_GT(trajectory.points.size(), 0u) <<
"There are no points in the trajectory";
445 for (
const auto& point : trajectory.points)
447 EXPECT_EQ(point.positions.size(), num_joints_);
448 EXPECT_EQ(point.velocities.size(), num_joints_);
449 EXPECT_EQ(point.accelerations.size(), num_joints_);
454 orientation_norm_tolerance_))
455 <<
"Goal not reached.";
458 robot_state::RobotState waypoint_state(robot_model_);
459 Eigen::Isometry3d waypoint_pose;
460 double x_dist, y_dist, z_dist;
462 const geometry_msgs::Pose& start_pose{ circ.getStartConfiguration().getPose() };
463 const geometry_msgs::Pose& aux_pose{ circ.getAuxiliaryConfiguration().getConfiguration().getPose() };
464 const geometry_msgs::Pose& goal_pose{ circ.getGoalConfiguration().getPose() };
466 x_dist = aux_pose.position.x - start_pose.position.x;
467 y_dist = aux_pose.position.y - start_pose.position.y;
468 z_dist = aux_pose.position.z - start_pose.position.z;
469 double expected_radius = sqrt(x_dist * x_dist + y_dist * y_dist + z_dist * z_dist);
470 for (
const auto& waypoint : trajectory.points)
472 waypoint_state.setToDefaultValues();
473 waypoint_state.setJointGroupPositions(planning_group_, waypoint.positions);
474 waypoint_pose = waypoint_state.getFrameTransform(target_link_);
478 x_dist = aux_pose.position.x - waypoint_pose(0, 3);
479 y_dist = aux_pose.position.y - waypoint_pose(1, 3);
480 z_dist = aux_pose.position.z - waypoint_pose(2, 3);
481 double actual_radius = sqrt(x_dist * x_dist + y_dist * y_dist + z_dist * z_dist);
482 EXPECT_NEAR(actual_radius, expected_radius, pose_norm_tolerance_) <<
"Trajectory way point is not on the circle.";
485 Eigen::Isometry3d start_pose_iso3d, goal_pose_iso3d;
486 tf2::fromMsg(start_pose, start_pose_iso3d);
487 tf2::fromMsg(goal_pose, goal_pose_iso3d);
488 EXPECT_TRUE(
testutils::checkSLERP(start_pose_iso3d, goal_pose_iso3d, waypoint_pose, orientation_norm_tolerance_));
492 int main(
int argc,
char** argv)
494 ros::init(argc, argv,
"integrationtest_command_planning");
497 testing::InitGoogleTest(&argc, argv);
498 return RUN_ALL_TESTS();
robot_model::RobotModelPtr robot_model_
std::unique_ptr< pilz_industrial_motion_planner_testutils::TestdataLoader > test_data_
double orientation_norm_tolerance_
std::string planning_group_
StartType & getStartConfiguration()
GoalType & getGoalConfiguration()
Data class storing all information regarding a Circ command.
Data class storing all information regarding a linear command.
const moveit::core::RobotModelPtr & getModel() const
Get the constructed planning_models::RobotModel.
const std::string PARAM_PLANNING_GROUP_NAME("planning_group")
int main(int argc, char **argv)
const std::string PARAM_TARGET_LINK_NAME("target_link")
TEST_F(IntegrationTestCommandPlanning, PtpJoint)
Tests if ptp motions with start & goal state given as joint configuration are executed correctly.
const std::string POSE_TRANSFORM_MATRIX_NORM_TOLERANCE("pose_norm_tolerance")
const std::string ORIENTATION_NORM_TOLERANCE("orientation_norm_tolerance")
const std::string PLAN_SERVICE_NAME
const std::string TEST_DATA_FILE_NAME("testdata_file_name")
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
bool isGoalReached(const trajectory_msgs::msg::JointTrajectory &trajectory, const std::vector< moveit_msgs::msg::JointConstraint > &goal, const double joint_position_tolerance, const double joint_velocity_tolerance=1.0e-6)
check if the goal given in joint space is reached Only the last point in the trajectory is veryfied.
bool checkSLERP(const Eigen::Isometry3d &start_pose, const Eigen::Isometry3d &goal_pose, const Eigen::Isometry3d &wp_pose, const double rot_axis_norm_tolerance, const double rot_angle_tolerance=10e-5)
check SLERP. The orientation should rotate around the same axis linearly.
bool checkCartesianLinearity(const moveit::core::RobotModelConstPtr &robot_model, const trajectory_msgs::msg::JointTrajectory &trajectory, const planning_interface::MotionPlanRequest &req, const double translation_norm_tolerance, const double rot_axis_norm_tolerance, const double rot_angle_tolerance=10e-5)
Check that given trajectory is straight line.