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.