42 #include <moveit_msgs/DisplayTrajectory.h> 
   43 #include <visualization_msgs/MarkerArray.h> 
   44 #include <boost/tokenizer.hpp> 
   45 #include <boost/algorithm/string/join.hpp> 
   54                                                       const std::string& planner_plugin_param_name,
 
   55                                                       const std::string& adapter_plugins_param_name)
 
   56   : active_{ 
false }, pipeline_nh_(pipeline_nh), private_nh_(
"~"), robot_model_(model)
 
   59   if (pipeline_nh_.getParam(planner_plugin_param_name, planner))
 
   60     planner_plugin_name_ = planner;
 
   63   if (pipeline_nh_.getParam(adapter_plugins_param_name, adapters))
 
   65     boost::char_separator<char> sep(
" ");
 
   66     boost::tokenizer<boost::char_separator<char>> tok(adapters, sep);
 
   67     for (boost::tokenizer<boost::char_separator<char>>::iterator beg = tok.begin(); beg != tok.end(); ++beg)
 
   68       adapter_plugin_names_.push_back(*beg);
 
   76                                                       const std::string& planner_plugin_name,
 
   77                                                       const std::vector<std::string>& adapter_plugin_names)
 
   79   , pipeline_nh_(pipeline_nh)
 
   81   , planner_plugin_name_(planner_plugin_name)
 
   82   , adapter_plugin_names_(adapter_plugin_names)
 
   90   check_solution_paths_ = 
false;  
 
   91   publish_received_requests_ = 
false;
 
   92   display_computed_motion_plans_ = 
false;  
 
   97     planner_plugin_loader_ = std::make_unique<pluginlib::ClassLoader<planning_interface::PlannerManager>>(
 
   98         "moveit_core", 
"planning_interface::PlannerManager");
 
  102     ROS_FATAL_STREAM(
"Exception while creating planning plugin loader " << ex.what());
 
  105   std::vector<std::string> classes;
 
  106   if (planner_plugin_loader_)
 
  107     classes = planner_plugin_loader_->getDeclaredClasses();
 
  108   if (planner_plugin_name_.empty() && classes.size() == 1)
 
  110     planner_plugin_name_ = classes[0];
 
  111     ROS_INFO(
"No '~planning_plugin' parameter specified, but only '%s' planning plugin is available. Using that one.",
 
  112              planner_plugin_name_.c_str());
 
  114   if (planner_plugin_name_.empty() && classes.size() > 1)
 
  116     planner_plugin_name_ = classes[0];
 
  117     ROS_INFO(
"Multiple planning plugins available. You should specify the '~planning_plugin' parameter. Using '%s' for " 
  119              planner_plugin_name_.c_str());
 
  123     planner_instance_ = planner_plugin_loader_->createUniqueInstance(planner_plugin_name_);
 
  124     if (!planner_instance_->initialize(robot_model_, pipeline_nh_.getNamespace()))
 
  125       throw std::runtime_error(
"Unable to initialize planning plugin");
 
  126     ROS_INFO_STREAM(
"Using planning interface '" << planner_instance_->getDescription() << 
"'");
 
  131                      << planner_plugin_name_ << 
"': " << ex.what() << std::endl
 
  132                      << 
"Available plugins: " << boost::algorithm::join(classes, 
", "));
 
  136   if (!adapter_plugin_names_.empty())
 
  138     std::vector<planning_request_adapter::PlanningRequestAdapterConstPtr> ads;
 
  141       adapter_plugin_loader_ =
 
  142           std::make_unique<pluginlib::ClassLoader<planning_request_adapter::PlanningRequestAdapter>>(
 
  143               "moveit_core", 
"planning_request_adapter::PlanningRequestAdapter");
 
  147       ROS_ERROR_STREAM(
"Exception while creating planning plugin loader " << ex.what());
 
  150     if (adapter_plugin_loader_)
 
  151       for (
const std::string& adapter_plugin_name : adapter_plugin_names_)
 
  153         planning_request_adapter::PlanningRequestAdapterPtr ad;
 
  156           ad = adapter_plugin_loader_->createUniqueInstance(adapter_plugin_name);
 
  160           ROS_ERROR_STREAM(
"Exception while loading planning adapter plugin '" << adapter_plugin_name
 
  161                                                                                << 
"': " << ex.what());
 
  165           ad->initialize(pipeline_nh_);
 
  166           ads.push_back(std::move(ad));
 
  171       adapter_chain_ = std::make_unique<planning_request_adapter::PlanningRequestAdapterChain>();
 
  172       for (planning_request_adapter::PlanningRequestAdapterConstPtr& ad : ads)
 
  174         ROS_INFO_STREAM(
"Using planning request adapter '" << ad->getDescription() << 
"'");
 
  175         adapter_chain_->addAdapter(ad);
 
  179   displayComputedMotionPlans(
true);
 
  180   checkSolutionPaths(
true);
 
  185   if (display_computed_motion_plans_ && !flag)
 
  186     display_path_publisher_.shutdown();
 
  187   else if (!display_computed_motion_plans_ && flag)
 
  188     display_path_publisher_ = private_nh_.advertise<moveit_msgs::DisplayTrajectory>(DISPLAY_PATH_TOPIC, 10, 
true);
 
  189   display_computed_motion_plans_ = flag;
 
  194   if (publish_received_requests_ && !flag)
 
  195     received_request_publisher_.shutdown();
 
  196   else if (!publish_received_requests_ && flag)
 
  197     received_request_publisher_ =
 
  198         private_nh_.advertise<moveit_msgs::MotionPlanRequest>(MOTION_PLAN_REQUEST_TOPIC, 10, 
true);
 
  199   publish_received_requests_ = flag;
 
  204   if (check_solution_paths_ && !flag)
 
  205     contacts_publisher_.shutdown();
 
  206   else if (!check_solution_paths_ && flag)
 
  207     contacts_publisher_ = private_nh_.advertise<visualization_msgs::MarkerArray>(MOTION_CONTACTS_TOPIC, 100, 
true);
 
  208   check_solution_paths_ = flag;
 
  215   std::vector<std::size_t> dummy;
 
  222                                                        std::vector<std::size_t>& adapter_added_state_index)
 const 
  228   if (publish_received_requests_)
 
  229     received_request_publisher_.publish(request);
 
  230   adapter_added_state_index.clear();
 
  232   if (!planner_instance_)
 
  234     ROS_ERROR(
"No planning plugin loaded. Cannot plan.");
 
  243   for (moveit_msgs::Constraints& constraint : req.goal_constraints)
 
  251       solved = adapter_chain_->adaptAndPlan(planner_instance_, 
planning_scene, req, res, adapter_added_state_index);
 
  252       if (!adapter_added_state_index.empty())
 
  254         std::stringstream ss;
 
  255         for (std::size_t added_index : adapter_added_state_index)
 
  256           ss << added_index << 
" ";
 
  257         ROS_INFO(
"Planning adapters have added states at index positions: [ %s]", ss.str().c_str());
 
  262       planning_interface::PlanningContextPtr context =
 
  264       solved = context ? context->solve(res) : 
false;
 
  267   catch (std::exception& ex)
 
  269     ROS_ERROR(
"Exception caught: '%s'", ex.what());
 
  278     std::size_t state_count = res.
trajectory_->getWayPointCount();
 
  279     ROS_DEBUG_STREAM(
"Motion planner reported a solution path with " << state_count << 
" states");
 
  280     if (check_solution_paths_)
 
  282       visualization_msgs::MarkerArray arr;
 
  283       visualization_msgs::Marker m;
 
  284       m.action = visualization_msgs::Marker::DELETEALL;
 
  285       arr.markers.push_back(m);
 
  287       std::vector<std::size_t> 
index;
 
  292         bool problem = 
false;
 
  293         for (std::size_t i = 0; i < 
index.size() && !problem; ++i)
 
  296           for (std::size_t added_index : adapter_added_state_index)
 
  297             if (
index[i] == added_index)
 
  308             ROS_DEBUG(
"It appears the robot is starting at an invalid state, but that is ok.");
 
  312             res.
error_code_.val = moveit_msgs::MoveItErrorCodes::INVALID_MOTION_PLAN;
 
  315             std::stringstream ss;
 
  316             for (std::size_t it : 
index)
 
  318             ROS_ERROR_STREAM(
"Computed path is not valid. Invalid states at index locations: [ " 
  319                              << ss.str() << 
"] out of " << state_count
 
  320                              << 
". Explanations follow in command line. Contacts are published on " 
  321                              << private_nh_.resolveName(MOTION_CONTACTS_TOPIC));
 
  324             for (std::size_t it : 
index)
 
  328               planning_scene->isStateValid(robot_state, req.path_constraints, req.group_name, 
true);
 
  340                 visualization_msgs::MarkerArray arr_i;
 
  343                 arr.markers.insert(arr.markers.end(), arr_i.markers.begin(), arr_i.markers.end());
 
  350           ROS_DEBUG(
"Planned path was found to be valid, except for states that were added by planning request " 
  351                     "adapters, but that is ok.");
 
  354         ROS_DEBUG(
"Planned path was found to be valid when rechecked");
 
  355       contacts_publisher_.publish(arr);
 
  360   if (display_computed_motion_plans_ && solved)
 
  362     moveit_msgs::DisplayTrajectory disp;
 
  363     disp.model_id = robot_model_->getName();
 
  364     disp.trajectory.resize(1);
 
  365     res.
trajectory_->getRobotTrajectoryMsg(disp.trajectory[0]);
 
  367     display_path_publisher_.publish(disp);
 
  374     bool stacked_constraints = 
false;
 
  375     if (req.path_constraints.position_constraints.size() > 1 || req.path_constraints.orientation_constraints.size() > 1)
 
  376       stacked_constraints = 
true;
 
  377     for (
const auto& constraint : req.goal_constraints)
 
  379       if (constraint.position_constraints.size() > 1 || constraint.orientation_constraints.size() > 1)
 
  380         stacked_constraints = 
true;
 
  382     if (stacked_constraints)
 
  383       ROS_WARN(
"More than one constraint is set. If your move_group does not have multiple end effectors/arms, this is " 
  384                "unusual. Are you using a move_group_interface and forgetting to call clearPoseTargets() or " 
  389   return solved && valid;
 
  394   if (planner_instance_)
 
  395     planner_instance_->terminate();