38 #include <gtest/gtest.h> 
   47 #include <moveit_msgs/DisplayTrajectory.h> 
   48 #include <moveit_msgs/MotionPlanResponse.h> 
   50 #include <tf2_eigen/tf2_eigen.hpp> 
   71 static std::string createManipulatorJointName(
const size_t& joint_number)
 
   73   return std::string(
"prbt_joint_") + std::to_string(joint_number + 1);
 
   76 static std::string createGripperJointName(
const size_t& joint_number)
 
   81       return "prbt_gripper_finger_left_joint";
 
   85   throw std::runtime_error(
"Could not create gripper joint name");
 
   91   void SetUp() 
override;
 
   95   ros::NodeHandle ph_{ 
"~" };
 
   97   std::shared_ptr<pilz_industrial_motion_planner::CommandListManager> 
manager_;
 
   98   planning_scene::PlanningScenePtr 
scene_;
 
  101   std::unique_ptr<pilz_industrial_motion_planner_testutils::TestdataLoader> 
data_loader_;
 
  109     FAIL() << 
"Robot model could not be loaded.";
 
  112   std::string test_data_file_name;
 
  117       std::make_unique<pilz_industrial_motion_planner_testutils::XmlTestdataLoader>(test_data_file_name, robot_model_);
 
  118   ASSERT_NE(
nullptr, data_loader_) << 
"Failed to load test data by provider.";
 
  121   manager_ = std::make_shared<pilz_industrial_motion_planner::CommandListManager>(ph_, robot_model_);
 
  122   scene_ = std::make_shared<planning_scene::PlanningScene>(robot_model_);
 
  123   pipeline_ = std::make_shared<planning_pipeline::PlanningPipeline>(robot_model_, ph_);
 
  133   std::shared_ptr<NegativeBlendRadiusException> nbr_ex{ 
new NegativeBlendRadiusException(
"") };
 
  134   EXPECT_EQ(nbr_ex->getErrorCode(), moveit_msgs::msg::MoveItErrorCodes::INVALID_MOTION_PLAN);
 
  136   std::shared_ptr<LastBlendRadiusNotZeroException> lbrnz_ex{ 
new LastBlendRadiusNotZeroException(
"") };
 
  137   EXPECT_EQ(lbrnz_ex->getErrorCode(), moveit_msgs::msg::MoveItErrorCodes::INVALID_MOTION_PLAN);
 
  139   std::shared_ptr<StartStateSetException> sss_ex{ 
new StartStateSetException(
"") };
 
  140   EXPECT_EQ(sss_ex->getErrorCode(), moveit_msgs::msg::MoveItErrorCodes::INVALID_ROBOT_STATE);
 
  142   std::shared_ptr<OverlappingBlendRadiiException> obr_ex{ 
new OverlappingBlendRadiiException(
"") };
 
  143   EXPECT_EQ(obr_ex->getErrorCode(), moveit_msgs::msg::MoveItErrorCodes::INVALID_MOTION_PLAN);
 
  145   std::shared_ptr<PlanningPipelineException> pp_ex{ 
new PlanningPipelineException(
"") };
 
  146   EXPECT_EQ(pp_ex->getErrorCode(), moveit_msgs::msg::MoveItErrorCodes::FAILURE);
 
  171   Sequence seq{ data_loader_->getSequence(
"ComplexSequence") };
 
  172   ASSERT_GE(seq.size(), 3u);
 
  173   seq.erase(3, seq.size());
 
  174   seq.setAllBlendRadiiToZero();
 
  176   RobotTrajCont res123_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  177   EXPECT_EQ(res123_vec.size(), 1u);
 
  178   EXPECT_GT(res123_vec.front()->getWayPointCount(), 0u);
 
  181   ROS_INFO(
"step 2: only first segment");
 
  182   moveit_msgs::msg::MotionSequenceRequest req_1;
 
  183   req_1.items.resize(1);
 
  184   req_1.items.at(0).req = seq.getCmd(0).toRequest();
 
  185   req_1.items.at(0).blend_radius = 0.;
 
  186   RobotTrajCont res1_vec{ manager_->solve(scene_, pipeline_, req_1) };
 
  187   EXPECT_EQ(res1_vec.size(), 1u);
 
  188   EXPECT_GT(res1_vec.front()->getWayPointCount(), 0u);
 
  189   EXPECT_EQ(res1_vec.front()->getFirstWayPoint().getVariableCount(),
 
  190             req_1.items.at(0).req.start_state.joint_state.name.size());
 
  192   ROS_INFO(
"step 3: only second segment");
 
  193   moveit_msgs::msg::MotionSequenceRequest req_2;
 
  194   req_2.items.resize(1);
 
  195   req_2.items.at(0).req = seq.getCmd(1).toRequest();
 
  196   req_2.items.at(0).blend_radius = 0.;
 
  197   RobotTrajCont res2_vec{ manager_->solve(scene_, pipeline_, req_2) };
 
  198   EXPECT_EQ(res2_vec.size(), 1u);
 
  199   EXPECT_GT(res2_vec.front()->getWayPointCount(), 0u);
 
  200   EXPECT_EQ(res2_vec.front()->getFirstWayPoint().getVariableCount(),
 
  201             req_2.items.at(0).req.start_state.joint_state.name.size());
 
  203   ROS_INFO(
"step 4: only third segment");
 
  204   moveit_msgs::msg::MotionSequenceRequest req_3;
 
  205   req_3.items.resize(1);
 
  206   req_3.items.at(0).req = seq.getCmd(2).toRequest();
 
  207   req_3.items.at(0).blend_radius = 0.;
 
  208   RobotTrajCont res3_vec{ manager_->solve(scene_, pipeline_, req_3) };
 
  209   EXPECT_EQ(res3_vec.size(), 1u);
 
  210   EXPECT_GT(res3_vec.front()->getWayPointCount(), 0u);
 
  211   EXPECT_EQ(res3_vec.front()->getFirstWayPoint().getVariableCount(),
 
  212             req_3.items.at(0).req.start_state.joint_state.name.size());
 
  215   auto t1_2_3 = res123_vec.front()->getWayPointDurationFromStart(res123_vec.front()->getWayPointCount() - 1);
 
  216   auto t1 = res1_vec.front()->getWayPointDurationFromStart(res123_vec.front()->getWayPointCount() - 1);
 
  217   auto t2 = res2_vec.front()->getWayPointDurationFromStart(res123_vec.front()->getWayPointCount() - 1);
 
  218   auto t3 = res3_vec.front()->getWayPointDurationFromStart(res123_vec.front()->getWayPointCount() - 1);
 
  219   ROS_DEBUG_STREAM(
"total time: " << t1_2_3 << 
" t1:" << t1 << 
" t2:" << t2 << 
" t3:" << t3);
 
  220   EXPECT_LT(fabs((t1_2_3 - t1 - t2 - t3)), 0.4);
 
  240   Sequence seq{ data_loader_->getSequence(
"ComplexSequence") };
 
  241   ASSERT_GE(seq.size(), 3u);
 
  242   seq.erase(3, seq.size());
 
  243   seq.setAllBlendRadiiToZero();
 
  244   seq.setBlendRadius(0, 0.1);
 
  245   RobotTrajCont res1{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  246   EXPECT_EQ(res1.size(), 1u);
 
  247   EXPECT_GT(res1.front()->getWayPointCount(), 0u);
 
  250   seq.setAllBlendRadiiToZero();
 
  251   seq.setBlendRadius(1, 0.1);
 
  252   RobotTrajCont res2{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  253   EXPECT_EQ(res2.size(), 1u);
 
  254   EXPECT_GT(res2.front()->getWayPointCount(), 0u);
 
  270   Sequence seq{ data_loader_->getSequence(
"PtpPtpSequence") };
 
  271   ASSERT_GE(seq.size(), 2u);
 
  272   seq.setAllBlendRadiiToZero();
 
  274   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  275   EXPECT_EQ(res_vec.size(), 1u);
 
  276   EXPECT_GT(res_vec.front()->getWayPointCount(), 0u);
 
  292   Sequence seq{ data_loader_->getSequence(
"PtpLinSequence") };
 
  293   ASSERT_GE(seq.size(), 2u);
 
  294   seq.setAllBlendRadiiToZero();
 
  296   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  297   EXPECT_EQ(res_vec.size(), 1u);
 
  298   EXPECT_GT(res_vec.front()->getWayPointCount(), 0u);
 
  314   Sequence seq{ data_loader_->getSequence(
"LinPtpSequence") };
 
  315   ASSERT_GE(seq.size(), 2u);
 
  316   seq.setAllBlendRadiiToZero();
 
  318   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  319   EXPECT_EQ(res_vec.size(), 1u);
 
  320   EXPECT_GT(res_vec.front()->getWayPointCount(), 0u);
 
  335   Sequence seq{ data_loader_->getSequence(
"SimpleSequence") };
 
  336   ASSERT_EQ(seq.size(), 2u);
 
  337   moveit_msgs::msg::MotionSequenceRequest req{ seq.toRequest() };
 
  338   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, req) };
 
  339   EXPECT_EQ(res_vec.size(), 1u);
 
  340   EXPECT_GT(res_vec.front()->getWayPointCount(), 0u);
 
  341   EXPECT_EQ(res_vec.front()->getFirstWayPoint().getVariableCount(),
 
  342             req.items.at(0).req.start_state.joint_state.name.size());
 
  345   ros::Publisher pub = nh.advertise<moveit_msgs::msg::DisplayTrajectory>(
"my_planned_path", 1);
 
  346   ros::Duration duration(1.0);  
 
  349   moveit_msgs::msg::DisplayTrajectory display_trajectory;
 
  350   moveit_msgs::msg::RobotTrajectory rob_traj_msg;
 
  351   res_vec.front()->getRobotTrajectoryMsg(rob_traj_msg);
 
  352   display_trajectory.trajectory.push_back(rob_traj_msg);
 
  353   pub.publish(display_trajectory);
 
  371   moveit_msgs::msg::MotionSequenceRequest empty_list;
 
  372   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, empty_list) };
 
  373   EXPECT_TRUE(res_vec.empty());
 
  387   Sequence seq{ data_loader_->getSequence(
"SimpleSequence") };
 
  388   ASSERT_GE(seq.size(), 2u);
 
  391   EXPECT_THROW(manager_->solve(scene_, pipeline_, seq.toRequest()), PlanningPipelineException);
 
  405   Sequence seq{ data_loader_->getSequence(
"SimpleSequence") };
 
  406   ASSERT_GE(seq.size(), 2u);
 
  408   moveit_msgs::msg::MotionSequenceRequest req{ seq.
toRequest() };
 
  409   req.items.at(1).req.start_state = lin.getGoalConfiguration().toMoveitMsgsRobotState();
 
  410   EXPECT_THROW(manager_->solve(scene_, pipeline_, req), StartStateSetException);
 
  425   Sequence seq{ data_loader_->getSequence(
"SimpleSequence") };
 
  426   ASSERT_GE(seq.size(), 2u);
 
  427   seq.setBlendRadius(0, -0.3);
 
  428   EXPECT_THROW(manager_->solve(scene_, pipeline_, seq.toRequest()), NegativeBlendRadiusException);
 
  443   Sequence seq{ data_loader_->getSequence(
"SimpleSequence") };
 
  444   ASSERT_EQ(seq.size(), 2u);
 
  445   seq.setBlendRadius(1, 0.03);
 
  446   EXPECT_THROW(manager_->solve(scene_, pipeline_, seq.toRequest()), LastBlendRadiusNotZeroException);
 
  462   Sequence seq{ data_loader_->getSequence(
"SimpleSequence") };
 
  463   ASSERT_GE(seq.size(), 2u);
 
  464   seq.setBlendRadius(0, 42.0);
 
  465   EXPECT_THROW(manager_->solve(scene_, pipeline_, seq.toRequest()), BlendingFailedException);
 
  482   Sequence seq{ data_loader_->getSequence(
"ComplexSequence") };
 
  483   ASSERT_GE(seq.size(), 3u);
 
  484   seq.erase(3, seq.size());
 
  486   RobotTrajCont res_valid_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  487   EXPECT_EQ(res_valid_vec.size(), 1u);
 
  488   EXPECT_GT(res_valid_vec.front()->getWayPointCount(), 0u);
 
  493   Eigen::Isometry3d p1, p2;
 
  494   tf2::fromMsg(ptp.getGoalConfiguration().getPose(), p1);
 
  495   tf2::fromMsg(circ.getGoalConfiguration().getPose(), p2);
 
  496   auto distance = (p2.translation() - p1.translation()).norm();
 
  498   seq.setBlendRadius(1, (
distance - seq.getBlendRadius(0) + 0.01));  
 
  499   EXPECT_THROW(manager_->solve(scene_, pipeline_, seq.toRequest()), OverlappingBlendRadiiException);
 
  518   Sequence seq{ data_loader_->getSequence(
"ComplexSequence") };
 
  519   ASSERT_GE(seq.size(), 2u);
 
  520   RobotTrajCont res_single_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  521   EXPECT_EQ(res_single_vec.size(), 1u);
 
  522   EXPECT_GT(res_single_vec.front()->getWayPointCount(), 0u);
 
  524   moveit_msgs::msg::MotionSequenceRequest req{ seq.toRequest() };
 
  527   const size_t n{ req.items.size() };
 
  528   for (
size_t i = 0; i < n; ++i)
 
  530     moveit_msgs::msg::MotionSequenceItem item{ req.items.at(i) };
 
  535       item.req.start_state = moveit_msgs::msg::RobotState();
 
  537     req.items.push_back(item);
 
  540   RobotTrajCont res_n_vec{ manager_->solve(scene_, pipeline_, req) };
 
  541   EXPECT_EQ(res_n_vec.size(), 1u);
 
  542   EXPECT_GT(res_n_vec.front()->getWayPointCount(), 0u);
 
  544   const double trajectory_time_1 =
 
  545       res_single_vec.front()->getWayPointDurationFromStart(res_single_vec.front()->getWayPointCount() - 1);
 
  546   const double trajectory_time_n =
 
  547       res_n_vec.front()->getWayPointDurationFromStart(res_n_vec.front()->getWayPointCount() - 1);
 
  548   double multiplicator = req.items.size() / n;
 
  549   EXPECT_LE(trajectory_time_n, trajectory_time_1 * multiplicator);
 
  550   EXPECT_GE(trajectory_time_n, trajectory_time_1 * multiplicator * 0.5);
 
  564   Sequence seq{ data_loader_->getSequence(
"ComplexSequenceWithGripper") };
 
  565   ASSERT_GE(seq.size(), 1u);
 
  567   unsigned int num_groups{ 1 };
 
  568   std::string last_group_name{ seq.getCmd(0).getPlanningGroup() };
 
  569   for (
size_t i = 1; i < seq.size(); ++i)
 
  571     if (seq.getCmd(i).getPlanningGroup() != last_group_name)
 
  574       last_group_name = seq.getCmd(i).getPlanningGroup();
 
  578   RobotTrajCont res_single_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  579   EXPECT_EQ(res_single_vec.size(), num_groups);
 
  581   for (
const auto& res : res_single_vec)
 
  583     EXPECT_GT(res->getWayPointCount(), 0u);
 
  594   Sequence seq{ data_loader_->getSequence(
"PureGripperSequence") };
 
  595   ASSERT_GE(seq.size(), 2u);
 
  596   ASSERT_TRUE(seq.cmdIsOfType<
Gripper>(0));
 
  597   ASSERT_TRUE(seq.cmdIsOfType<
Gripper>(1));
 
  600   seq.setBlendRadius(0, 1.0);
 
  601   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  602   EXPECT_EQ(res_vec.size(), 1u);
 
  620   using std::placeholders::_1;
 
  622   Sequence seq{ data_loader_->getSequence(
"ComplexSequenceWithGripper") };
 
  623   ASSERT_GE(seq.size(), 4u);
 
  624   seq.erase(4, seq.size());
 
  627   gripper.
getStartConfiguration().setCreateJointNameFunc([](
size_t n) { 
return createGripperJointName(n); });
 
  630   gripper.getStartConfiguration().clearModel();
 
  633   ptp.
getStartConfiguration().setCreateJointNameFunc([](
size_t n) { 
return createManipulatorJointName(n); });
 
  636   ptp.getStartConfiguration().clearModel();
 
  638   RobotTrajCont res_vec{ manager_->solve(scene_, pipeline_, seq.toRequest()) };
 
  639   EXPECT_GE(res_vec.size(), 1u);
 
  640   EXPECT_GT(res_vec.front()->getWayPointCount(), 0u);
 
  649   Gripper gripper_cmd{ data_loader_->getGripper(
"open_gripper") };
 
  650   EXPECT_THROW(getSolverTipFrame(robot_model_->getJointModelGroup(gripper_cmd.getPlanningGroup())), NoSolverException);
 
  653 int main(
int argc, 
char** argv)
 
  655   ros::init(argc, argv, 
"integrationtest_command_list_manager");
 
  656   testing::InitGoogleTest(&argc, argv);
 
  660   return RUN_ALL_TESTS();
 
planning_scene::PlanningScenePtr scene_
 
std::shared_ptr< pilz_industrial_motion_planner::CommandListManager > manager_
 
planning_pipeline::PlanningPipelinePtr pipeline_
 
std::unique_ptr< pilz_industrial_motion_planner_testutils::TestdataLoader > data_loader_
 
StartType & getStartConfiguration()
 
planning_interface::MotionPlanRequest toRequest() const override
 
GoalType & getGoalConfiguration()
 
Data class storing all information regarding a Circ command.
 
Data class storing all information regarding a linear command.
 
Data class storing all information regarding a Ptp command.
 
Data class storing all information regarding a Sequence command.
 
const moveit::core::RobotModelPtr & getModel() const
Get the constructed planning_models::RobotModel.
 
const std::string ROBOT_DESCRIPTION_STR
 
int main(int argc, char **argv)
 
const std::string TEST_DATA_FILE_NAME("testdata_file_name")
 
const std::string EMPTY_VALUE
 
std::vector< robot_trajectory::RobotTrajectoryPtr > RobotTrajCont
 
TEST_F(GetSolverTipFrameIntegrationTest, TestHasSolverManipulator)
Check if hasSolver() can be called successfully for the manipulator group.
 
double distance(const urdf::Pose &transform)
 
::testing::AssertionResult hasStrictlyIncreasingTime(const robot_trajectory::RobotTrajectoryPtr &trajectory)
Checks that every waypoint in the trajectory has a non-zero duration between itself and its predecess...