stomp_planner.cpp
Go to the documentation of this file.
1 
26 #include <ros/ros.h>
30 #include <stomp_core/utils.h>
34 
35 static const std::string DEBUG_NS = "stomp_planner";
36 static const std::string DESCRIPTION = "STOMP";
37 static const double TIMEOUT_INTERVAL = 0.5;
38 static int const IK_ATTEMPTS = 4;
39 static int const IK_TIMEOUT = 0.005;
40 const static double MAX_START_DISTANCE_THRESH = 0.5;
41 
50 {
51  using namespace XmlRpc;
52  // Set default values for optional config parameters
53  stomp_config.control_cost_weight = 0.0;
54  stomp_config.initialization_method = 1; // LINEAR_INTERPOLATION
55  stomp_config.num_timesteps = 40;
56  stomp_config.delta_t = 1.0;
57  stomp_config.num_iterations = 50;
58  stomp_config.num_iterations_after_valid = 0;
59  stomp_config.max_rollouts = 100;
60  stomp_config.num_rollouts = 10;
61  stomp_config.exponentiated_cost_sensitivity = 10.0;
62 
63  // Load optional config parameters if they exist
64  if (config.hasMember("control_cost_weight"))
65  stomp_config.control_cost_weight = static_cast<double>(config["control_cost_weight"]);
66 
67  if (config.hasMember("initialization_method"))
68  stomp_config.initialization_method = static_cast<int>(config["initialization_method"]);
69 
70  if (config.hasMember("num_timesteps"))
71  stomp_config.num_timesteps = static_cast<int>(config["num_timesteps"]);
72 
73  if (config.hasMember("delta_t"))
74  stomp_config.delta_t = static_cast<double>(config["delta_t"]);
75 
76  if (config.hasMember("num_iterations"))
77  stomp_config.num_iterations = static_cast<int>(config["num_iterations"]);
78 
79  if (config.hasMember("num_iterations_after_valid"))
80  stomp_config.num_iterations_after_valid = static_cast<int>(config["num_iterations_after_valid"]);
81 
82  if (config.hasMember("max_rollouts"))
83  stomp_config.max_rollouts = static_cast<int>(config["max_rollouts"]);
84 
85  if (config.hasMember("num_rollouts"))
86  stomp_config.num_rollouts = static_cast<int>(config["num_rollouts"]);
87 
88  if (config.hasMember("exponentiated_cost_sensitivity"))
89  stomp_config.exponentiated_cost_sensitivity = static_cast<int>(config["exponentiated_cost_sensitivity"]);
90 
91  // getting number of joints
92  stomp_config.num_dimensions = group->getActiveJointModels().size();
93  if(stomp_config.num_dimensions == 0)
94  {
95  ROS_ERROR("Planning Group %s has no active joints",group->getName().c_str());
96  return false;
97  }
98 
99  return true;
100 }
101 
102 namespace stomp_moveit
103 {
104 
105 StompPlanner::StompPlanner(const std::string& group,const XmlRpc::XmlRpcValue& config,
106  const moveit::core::RobotModelConstPtr& model):
107  PlanningContext(DESCRIPTION,group),
108  config_(config),
109  robot_model_(model),
110  ik_solver_(new utils::kinematics::IKSolver(model,group)),
111  ph_(new ros::NodeHandle("~"))
112 {
113  setup();
114 }
115 
116 StompPlanner::~StompPlanner()
117 {
118 }
119 
121 {
122  if(!getPlanningScene())
123  {
124  setPlanningScene(planning_scene::PlanningSceneConstPtr(new planning_scene::PlanningScene(robot_model_)));
125  }
126 
127  // loading parameters
128  try
129  {
130  // creating tasks
131  XmlRpc::XmlRpcValue task_config;
132  task_config = config_["task"];
133  task_.reset(new StompOptimizationTask(robot_model_,group_,task_config));
134 
135  if(!robot_model_->hasJointModelGroup(group_))
136  {
137  std::string msg = "Stomp Planning Group '" + group_ + "' was not found";
138  ROS_ERROR("%s",msg.c_str());
139  throw std::logic_error(msg);
140  }
141 
142  // parsing stomp parameters
143  if(!config_.hasMember("optimization") || !parseConfig(config_["optimization" ],robot_model_->getJointModelGroup(group_),stomp_config_))
144  {
145  std::string msg = "Stomp 'optimization' parameter for group '" + group_ + "' failed to load";
146  ROS_ERROR("%s", msg.c_str());
147  throw std::logic_error(msg);
148  }
149 
150  stomp_.reset(new stomp_core::Stomp(stomp_config_,task_));
151  }
152  catch(XmlRpc::XmlRpcException& e)
153  {
154  throw std::logic_error("Stomp Planner failed to load configuration for group '" + group_+"'; " + e.getMessage());
155  }
156 
157 }
158 
160 {
161  ros::WallTime start_time = ros::WallTime::now();
163  bool success = solve(detailed_res);
164  if(success)
165  {
166  res.trajectory_ = detailed_res.trajectory_.back();
167  }
168  ros::WallDuration wd = ros::WallTime::now() - start_time;
169  res.planning_time_ = ros::Duration(wd.sec, wd.nsec).toSec();
170  res.error_code_ = detailed_res.error_code_;
171 
172  return success;
173 }
174 
176 {
177  using namespace stomp_core;
178 
179  // initializing response
180  res.description_.resize(1,"plan");
181  res.processing_time_.resize(1);
182  res.trajectory_.resize(1);
183  res.error_code_.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
184 
185  ros::WallTime start_time = ros::WallTime::now();
186  bool success = false;
187 
188  trajectory_msgs::JointTrajectory trajectory;
189  Eigen::MatrixXd parameters;
190  bool planning_success;
191 
192  // local stomp config copy
193  auto config_copy = stomp_config_;
194 
195  // look for seed trajectory
196  Eigen::MatrixXd initial_parameters;
197  bool use_seed = getSeedParameters(initial_parameters);
198 
199 
200  // create timeout timer
201  ros::WallDuration allowed_time(request_.allowed_planning_time);
202  ROS_WARN_COND(TIMEOUT_INTERVAL > request_.allowed_planning_time,
203  "%s allowed planning time %f is less than the minimum planning time value of %f",
204  getName().c_str(),request_.allowed_planning_time,TIMEOUT_INTERVAL);
205  std::atomic<bool> terminating(false);
206  ros::Timer timeout_timer = ph_->createTimer(ros::Duration(TIMEOUT_INTERVAL), [&](const ros::TimerEvent& evnt)
207  {
208  if(((ros::WallTime::now() - start_time) > allowed_time))
209  {
210  ROS_ERROR_COND(!terminating,"%s exceeded allowed time of %f , terminating",getName().c_str(),allowed_time.toSec());
211  this->terminate();
212  terminating = true;
213  }
214 
215  },false);
216 
217 
218  if (use_seed)
219  {
220  ROS_INFO("%s Seeding trajectory from MotionPlanRequest",getName().c_str());
221 
222  // updating time step in stomp configuraion
223  config_copy.num_timesteps = initial_parameters.cols();
224 
225  // setting up up optimization task
226  if(!task_->setMotionPlanRequest(planning_scene_, request_, config_copy, res.error_code_))
227  {
228  res.error_code_.val = moveit_msgs::MoveItErrorCodes::FAILURE;
229  return false;
230  }
231 
232  stomp_->setConfig(config_copy);
233  planning_success = stomp_->solve(initial_parameters, parameters);
234  }
235  else
236  {
237 
238  // extracting start and goal
239  Eigen::VectorXd start, goal;
240  if(!getStartAndGoal(start,goal))
241  {
242  res.error_code_.val = moveit_msgs::MoveItErrorCodes::INVALID_MOTION_PLAN;
243  return false;
244  }
245 
246  // setting up up optimization task
247  if(!task_->setMotionPlanRequest(planning_scene_,request_, config_copy,res.error_code_))
248  {
249  res.error_code_.val = moveit_msgs::MoveItErrorCodes::FAILURE;
250  return false;
251  }
252 
253  stomp_->setConfig(config_copy);
254  planning_success = stomp_->solve(start,goal,parameters);
255  }
256 
257  // stopping timer
258  timeout_timer.stop();
259 
260  // Handle results
261  if(planning_success)
262  {
263  if(!parametersToJointTrajectory(parameters,trajectory))
264  {
265  res.error_code_.val = moveit_msgs::MoveItErrorCodes::PLANNING_FAILED;
266  return false;
267  }
268 
269  // creating request response
270  moveit::core::RobotState robot_state(robot_model_);
271  moveit::core::robotStateMsgToRobotState(request_.start_state,robot_state);
272  res.trajectory_[0]= robot_trajectory::RobotTrajectoryPtr(new robot_trajectory::RobotTrajectory(
273  robot_model_,group_));
274  res.trajectory_.back()->setRobotTrajectoryMsg( robot_state,trajectory);
275  }
276  else
277  {
278  res.error_code_.val = moveit_msgs::MoveItErrorCodes::PLANNING_FAILED;
279  return false;
280  }
281 
282  // checking against planning scene
283  if(planning_scene_ && !planning_scene_->isPathValid(*res.trajectory_.back(),group_,true))
284  {
285  res.error_code_.val = moveit_msgs::MoveItErrorCodes::PLANNING_FAILED;
286  success = false;
287  ROS_ERROR_STREAM("STOMP Trajectory is in collision");
288  }
289 
290  ros::WallDuration wd = ros::WallTime::now() - start_time;
291  res.processing_time_[0] = ros::Duration(wd.sec, wd.nsec).toSec();
292  ROS_INFO_STREAM("STOMP found a valid path after "<<res.processing_time_[0]<<" seconds");
293 
294  return true;
295 }
296 
297 bool StompPlanner::getSeedParameters(Eigen::MatrixXd& parameters) const
298 {
299  using namespace utils::kinematics;
300  using namespace utils::polynomial;
301 
302  auto within_tolerance = [&](const Eigen::VectorXd& a, const Eigen::VectorXd& b, double tol) -> bool
303  {
304  double dist = (a - b).cwiseAbs().sum();
305  return dist <= tol;
306  };
307 
308  trajectory_msgs::JointTrajectory traj;
310  {
311  ROS_DEBUG("%s Found no seed trajectory",getName().c_str());
312  return false;
313  }
314 
315  if(!jointTrajectorytoParameters(traj,parameters))
316  {
317  ROS_ERROR("%s Failed to created seed parameters from joint trajectory",getName().c_str());
318  return false;
319  }
320 
321  if(parameters.cols()<= 2)
322  {
323  ROS_ERROR("%s Found less than 3 points in seed trajectory",getName().c_str());
324  return false;
325  }
326 
327  /* ********************************************************************************
328  * Validating seed trajectory by ensuring that it does obey the
329  * motion plan request constraints
330  */
331  moveit::core::RobotState state (robot_model_);
332  const auto* group = state.getJointModelGroup(group_);
333  const auto& joint_names = group->getActiveJointModelNames();
334  const auto& tool_link = group->getLinkModelNames().back();
335  Eigen::VectorXd start, goal;
336 
337  // We check to see if the start state in the request and the seed state are 'close'
338  if (moveit::core::robotStateMsgToRobotState(request_.start_state, state))
339  {
340 
341  if(!state.satisfiesBounds(group))
342  {
343  ROS_ERROR("Start state is out of bounds");
344  return false;
345  }
346 
347  // copying start joint values
348  start.resize(joint_names.size());
349  for(auto j = 0u; j < joint_names.size(); j++)
350  {
351  start(j) = state.getVariablePosition(joint_names[j]);
352  }
353 
354  if(within_tolerance(parameters.leftCols(1),start,MAX_START_DISTANCE_THRESH))
355  {
356  parameters.leftCols(1) = start;
357  }
358  else
359  {
360  ROS_ERROR("%s Start State is in discrepancy with the seed trajectory",getName().c_str());
361  return false;
362  }
363  }
364  else
365  {
366  ROS_ERROR("%s Failed to get start state joints",getName().c_str());
367  return false;
368  }
369 
370  // We now extract the goal and make sure that the seed's goal obeys the goal constraints
371  bool found_goal = false;
372  goal = parameters.rightCols(1); // initializing goal;
373  for(auto& gc : request_.goal_constraints)
374  {
375  if(!gc.joint_constraints.empty())
376  {
377  // copying goal values into state
378  for(auto j = 0u; j < gc.joint_constraints.size() ; j++)
379  {
380  auto jc = gc.joint_constraints[j];
381  state.setVariablePosition(jc.joint_name,jc.position);
382  }
383 
384  // copying values into goal array
385  if(!state.satisfiesBounds(group))
386  {
387  ROS_ERROR("%s Requested Goal joint pose is out of bounds",getName().c_str());
388  continue;
389  }
390 
391  for(auto j = 0u; j < joint_names.size(); j++)
392  {
393  goal(j) = state.getVariablePosition(joint_names[j]);
394  }
395 
396  found_goal = true;
397  break;
398  }
399 
400  // now check Cartesian constraint
401  state.updateLinkTransforms();
402  Eigen::Affine3d start_tool_pose = state.getGlobalLinkTransform(tool_link);
403  boost::optional<moveit_msgs::Constraints> tool_constraints = curateCartesianConstraints(gc,start_tool_pose);
404  if(!tool_constraints.is_initialized())
405  {
406  ROS_WARN("Cartesian Goal could not be created from provided constraints");
407  found_goal = true;
408  break;
409  }
410 
411  Eigen::VectorXd solution;
412  ik_solver_->setKinematicState(state);
413  if(ik_solver_->solve(goal,tool_constraints.get(),solution))
414  {
415  goal = solution;
416  found_goal = true;
417  break;
418  }
419  else
420  {
421  ROS_ERROR("A valid ik solution for the given Cartesian constraints was not found ");
422  ROS_DEBUG_STREAM_NAMED(DEBUG_NS,"IK failed with goal constraint \n"<<tool_constraints.get());
423  ROS_DEBUG_STREAM_NAMED(DEBUG_NS,"Reference Tool pose used was: \n"<<start_tool_pose.matrix());
424  }
425  }
426 
427  // forcing the goal into the seed trajectory
428  if(found_goal)
429  {
430  if(within_tolerance(parameters.rightCols(1),goal,MAX_START_DISTANCE_THRESH))
431  {
432  parameters.rightCols(1) = goal;
433  }
434  else
435  {
436  ROS_ERROR("%s Goal in seed is too far away from requested goal constraints",getName().c_str());
437  return false;
438  }
439  }
440  else
441  {
442  ROS_ERROR("%s requested goal constraint was invalid or unreachable, comparison with goal in seed isn't possible",getName().c_str());
443  return false;
444  }
445 
446  if(!applyPolynomialSmoothing(robot_model_,group_,parameters,5,1e-5))
447  {
448  return false;
449  }
450 
451  return true;
452 }
453 
454 bool StompPlanner::parametersToJointTrajectory(const Eigen::MatrixXd& parameters,
455  trajectory_msgs::JointTrajectory& trajectory)
456 {
457  // filling trajectory joint values
458  trajectory.joint_names = robot_model_->getJointModelGroup(group_)->getActiveJointModelNames();
459  trajectory.points.clear();
460  trajectory.points.resize(parameters.cols());
461  std::vector<double> vals(parameters.rows());
462  std::vector<double> zeros(parameters.rows(),0.0);
463  for(auto t = 0u; t < parameters.cols() ; t++)
464  {
465  Eigen::VectorXd::Map(&vals[0],vals.size()) = parameters.col(t);
466  trajectory.points[t].positions = vals;
467  trajectory.points[t].velocities = zeros;
468  trajectory.points[t].accelerations = zeros;
469  trajectory.points[t].time_from_start = ros::Duration(0.0);
470  }
471 
473  robot_trajectory::RobotTrajectory traj(robot_model_,group_);
474  moveit::core::RobotState robot_state(robot_model_);
475  if(!moveit::core::robotStateMsgToRobotState(request_.start_state,robot_state))
476  {
477  return false;
478  }
479 
480  traj.setRobotTrajectoryMsg(robot_state,trajectory);
481 
482  // converting to msg
483  moveit_msgs::RobotTrajectory robot_traj_msgs;
484  if(time_generator.computeTimeStamps(traj,request_.max_velocity_scaling_factor))
485  {
486  traj.getRobotTrajectoryMsg(robot_traj_msgs);
487  trajectory = robot_traj_msgs.joint_trajectory;
488  }
489  else
490  {
491  ROS_ERROR("%s Failed to generate timing data",getName().c_str());
492  return false;
493  }
494  return true;
495 }
496 
497 bool StompPlanner::jointTrajectorytoParameters(const trajectory_msgs::JointTrajectory& traj, Eigen::MatrixXd& parameters) const
498 {
499  const auto dof = traj.joint_names.size();
500  const auto timesteps = traj.points.size();
501 
502  Eigen::MatrixXd mat (dof, timesteps);
503 
504  for (size_t step = 0; step < timesteps; ++step)
505  {
506  for (size_t joint = 0; joint < dof; ++joint)
507  {
508  mat(joint, step) = traj.points[step].positions[joint];
509  }
510  }
511 
512  parameters = mat;
513  return true;
514 }
515 
516 bool StompPlanner::extractSeedTrajectory(const moveit_msgs::MotionPlanRequest& req, trajectory_msgs::JointTrajectory& seed) const
517 {
518  if (req.trajectory_constraints.constraints.empty())
519  return false;
520 
521  const auto* joint_group = robot_model_->getJointModelGroup(group_);
522  const auto& names = joint_group->getActiveJointModelNames();
523  const auto dof = names.size();
524 
525  const auto& constraints = req.trajectory_constraints.constraints; // alias to keep names short
526  // Test the first point to ensure that it has all of the joints required
527  for (size_t i = 0; i < constraints.size(); ++i)
528  {
529  auto n = constraints[i].joint_constraints.size();
530  if (n != dof) // first test to ensure that dimensionality is correct
531  {
532  ROS_WARN("Seed trajectory index %lu does not have %lu constraints (has %lu instead).", i, dof, n);
533  return false;
534  }
535 
536  trajectory_msgs::JointTrajectoryPoint joint_pt;
537 
538  for (size_t j = 0; j < constraints[i].joint_constraints.size(); ++j)
539  {
540  const auto& c = constraints[i].joint_constraints[j];
541  if (c.joint_name != names[j])
542  {
543  ROS_WARN("Seed trajectory (index %lu, joint %lu) joint name '%s' does not match expected name '%s'",
544  i, j, c.joint_name.c_str(), names[j].c_str());
545  return false;
546  }
547  joint_pt.positions.push_back(c.position);
548  }
549 
550  seed.points.push_back(joint_pt);
551  }
552 
553  seed.joint_names = names;
554  return true;
555 }
556 
557 moveit_msgs::TrajectoryConstraints StompPlanner::encodeSeedTrajectory(const trajectory_msgs::JointTrajectory &seed)
558 {
559  moveit_msgs::TrajectoryConstraints res;
560 
561  const auto dof = seed.joint_names.size();
562 
563  for (size_t i = 0; i < seed.points.size(); ++i) // for each time step
564  {
565  moveit_msgs::Constraints c;
566 
567  if (seed.points[i].positions.size() != dof)
568  throw std::runtime_error("All trajectory position fields must have same dimensions as joint_names");
569 
570  for (size_t j = 0; j < dof; ++j) // for each joint
571  {
572  moveit_msgs::JointConstraint jc;
573  jc.joint_name = seed.joint_names[j];
574  jc.position = seed.points[i].positions[j];
575 
576  c.joint_constraints.push_back(jc);
577  }
578 
579  res.constraints.push_back(std::move(c));
580  }
581 
582  return res;
583 }
584 
585 bool StompPlanner::getStartAndGoal(Eigen::VectorXd& start, Eigen::VectorXd& goal)
586 {
587  using namespace moveit::core;
588  using namespace utils::kinematics;
589 
590  RobotStatePtr state(new RobotState(robot_model_));
591  const JointModelGroup* joint_group = robot_model_->getJointModelGroup(group_);
592  std::string tool_link = joint_group->getLinkModelNames().back();
593  bool found_goal = false;
594 
595  try
596  {
597  // copying start state
598  state->setToDefaultValues();
599  if(!robotStateMsgToRobotState(request_.start_state,*state))
600  {
601  ROS_ERROR("%s Failed to extract start state from MotionPlanRequest",getName().c_str());
602  return false;
603  }
604 
605  // copying start joint values
606  const std::vector<std::string> joint_names= state->getJointModelGroup(group_)->getActiveJointModelNames();
607  start.resize(joint_names.size());
608  goal.resize(joint_names.size());
609 
610  if(!state->satisfiesBounds(state->getJointModelGroup(group_)))
611  {
612  ROS_ERROR("%s Start joint pose is out of bounds",getName().c_str());
613  return false;
614  }
615 
616  for(auto j = 0u; j < joint_names.size(); j++)
617  {
618  start(j) = state->getVariablePosition(joint_names[j]);
619  }
620 
621  // check goal constraint
622  if(request_.goal_constraints.empty())
623  {
624  ROS_ERROR("%s A goal constraint was not provided",getName().c_str());
625  return false;
626  }
627 
628  // extracting goal joint values
629  for(const auto& gc : request_.goal_constraints)
630  {
631 
632  // check joint constraints first
633  if(!gc.joint_constraints.empty())
634  {
635 
636  // copying goal values into state
637  for(auto j = 0u; j < gc.joint_constraints.size() ; j++)
638  {
639  auto jc = gc.joint_constraints[j];
640  state->setVariablePosition(jc.joint_name,jc.position);
641  }
642 
643 
644  if(!state->satisfiesBounds(state->getJointModelGroup(group_)))
645  {
646  ROS_ERROR("%s Requested Goal joint pose is out of bounds",getName().c_str());
647  continue;
648  }
649 
650  ROS_DEBUG("%s Found goal from joint constraints",getName().c_str());
651 
652  // copying values into goal array
653  for(auto j = 0u; j < joint_names.size(); j++)
654  {
655  goal(j) = state->getVariablePosition(joint_names[j]);
656  }
657 
658  found_goal = true;
659  break;
660 
661  }
662 
663  // now check cartesian constraint
664  state->updateLinkTransforms();
665  Eigen::Affine3d start_tool_pose = state->getGlobalLinkTransform(tool_link);
666  boost::optional<moveit_msgs::Constraints> tool_constraints = curateCartesianConstraints(gc,start_tool_pose);
667  if(!tool_constraints.is_initialized())
668  {
669  ROS_WARN("Cartesian Goal could not be created from provided constraints");
670  found_goal = true;
671  break;
672  }
673 
674  // now solve ik
675  Eigen::VectorXd solution;
676  Eigen::VectorXd seed = start;
677  ik_solver_->setKinematicState(*state);
678  if(ik_solver_->solve(seed,tool_constraints.get(),solution))
679  {
680  goal = solution;
681  found_goal = true;
682  break;
683  }
684  else
685  {
686  ROS_ERROR("A valid ik solution for the given Cartesian constraints was not found ");
687  ROS_DEBUG_STREAM_NAMED(DEBUG_NS,"IK failed with goal constraint \n"<<tool_constraints.get());
688  ROS_DEBUG_STREAM_NAMED(DEBUG_NS,"Reference Tool pose used was: \n"<<start_tool_pose.matrix());
689  }
690  }
691 
692  ROS_ERROR_COND(!found_goal,"%s was unable to retrieve the goal from the MotionPlanRequest",getName().c_str());
693 
694  }
695  catch(moveit::Exception &e)
696  {
697  ROS_ERROR("Failure retrieving start or goal state joint values from request %s", e.what());
698  return false;
699  }
700 
701  return found_goal;
702 }
703 
704 
705 bool StompPlanner::canServiceRequest(const moveit_msgs::MotionPlanRequest &req) const
706 {
707  // check group
708  if(req.group_name != getGroupName())
709  {
710  ROS_ERROR("STOMP: Unsupported planning group '%s' requested", req.group_name.c_str());
711  return false;
712  }
713 
714  // check for single goal region
715  if (req.goal_constraints.size() != 1)
716  {
717  ROS_ERROR("STOMP: Can only handle a single goal region.");
718  return false;
719  }
720 
721  // check that we have joint or cartesian constraints at the goal
722  const auto& gc = req.goal_constraints[0];
723  if ((gc.joint_constraints.size() == 0) &&
725  {
726  ROS_ERROR("STOMP couldn't find either a joint or cartesian goal.");
727  return false;
728  }
729 
730  return true;
731 }
732 
734 {
735  if(stomp_)
736  {
737  if(!stomp_->cancel())
738  {
739  ROS_ERROR_STREAM("Failed to interrupt Stomp");
740  return false;
741  }
742  }
743  return true;
744 }
745 
747 {
748  stomp_->clear();
749 }
750 
751 bool StompPlanner::getConfigData(ros::NodeHandle &nh, std::map<std::string, XmlRpc::XmlRpcValue> &config, std::string param)
752 {
753  // Create a stomp planner for each group
754  XmlRpc::XmlRpcValue stomp_config;
755  if(!nh.getParam(param, stomp_config))
756  {
757  ROS_ERROR("The 'stomp' configuration parameter was not found");
758  return false;
759  }
760 
761  // each element under 'stomp' should be a group name
762  std::string group_name;
763  try
764  {
765  for(XmlRpc::XmlRpcValue::iterator v = stomp_config.begin(); v != stomp_config.end(); v++)
766  {
767  group_name = static_cast<std::string>(v->second["group_name"]);
768  config.insert(std::make_pair(group_name, v->second));
769  }
770  return true;
771  }
772  catch(XmlRpc::XmlRpcException& e )
773  {
774  ROS_ERROR("Unable to parse ROS parameter:\n %s",stomp_config.toXml().c_str());
775  return false;
776  }
777 }
778 
779 
780 } /* namespace stomp_moveit_interface */
781 
const std::string & getMessage() const
robot_trajectory::RobotTrajectoryPtr trajectory_
#define ROS_DEBUG_STREAM_NAMED(name, args)
ValueStruct::iterator iterator
const Eigen::Affine3d & getGlobalLinkTransform(const std::string &link_name)
virtual bool solve(planning_interface::MotionPlanResponse &res) override
Solve the motion planning problem as defined in the motion request passed before hand.
This defines the stomp planner for MoveIt.
const JointModelGroup * getJointModelGroup(const std::string &group) const
const std::vector< std::string > & getLinkModelNames() const
const std::string & getName() const
void stop()
void setup()
planner setup
virtual void clear() override
Clears results from previous plan.
#define ROS_WARN(...)
#define ROS_ERROR_COND(cond,...)
const planning_scene::PlanningSceneConstPtr & getPlanningScene() const
moveit_msgs::MoveItErrorCodes error_code_
static moveit_msgs::TrajectoryConstraints encodeSeedTrajectory(const trajectory_msgs::JointTrajectory &seed)
From a trajectory_msgs::JointTrajectory create a set of trajectory constraints that stomp can use lat...
bool parseConfig(XmlRpc::XmlRpcValue config, const moveit::core::JointModelGroup *group, stomp_core::StompConfiguration &stomp_config)
Parses a XmlRpcValue and populates a StompComfiguration structure.
virtual bool terminate() override
Thread-safe method that request early termination, if a solve() function is currently computing plans...
void getRobotTrajectoryMsg(moveit_msgs::RobotTrajectory &trajectory) const
boost::optional< moveit_msgs::Constraints > curateCartesianConstraints(const moveit_msgs::Constraints &c, const Eigen::Affine3d &ref_pose, double default_pos_tol=0.0005, double default_rot_tol=M_PI)
Populates the missing parts of a Cartesian constraints in order to provide a constraint that can be u...
Definition: kinematics.cpp:240
double dist(const T &p1, const T &p2)
std::string toXml() const
planning_scene::PlanningSceneConstPtr planning_scene_
moveit_msgs::MoveItErrorCodes error_code_
bool getSeedParameters(Eigen::MatrixXd &parameters) const
This function 1) gets the seed trajectory from the active motion plan request, 2) checks to see if th...
#define ROS_INFO(...)
robot_trajectory::RobotTrajectory trajectory(rmodel,"right_arm")
bool canServiceRequest(const moveit_msgs::MotionPlanRequest &req) const
Checks some conditions to determine whether it is able to plan given for this planning request...
const std::vector< std::string > & getActiveJointModelNames() const
This defines kinematic related utilities.
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
bool jointTrajectorytoParameters(const trajectory_msgs::JointTrajectory &traj, Eigen::MatrixXd &parameters) const
Converts from a joint trajectory to an Eigen Matrix.
void setPlanningScene(const planning_scene::PlanningSceneConstPtr &planning_scene)
Loads and manages the STOMP plugins during the planning process.
bool extractSeedTrajectory(const moveit_msgs::MotionPlanRequest &req, trajectory_msgs::JointTrajectory &seed) const
Populates a seed joint trajectory from the &#39;trajectory_constraints&#39; moveit_msgs::Constraints[] array...
bool satisfiesBounds(double margin=0.0) const
const std::string & getGroupName() const
bool isCartesianConstraints(const moveit_msgs::Constraints &c)
Checks if the constraint structured contains valid data from which a proper cartesian constraint can ...
Definition: kinematics.cpp:208
unsigned int step
bool hasMember(const std::string &name) const
#define ROS_INFO_STREAM(args)
static WallTime now()
std::vector< robot_trajectory::RobotTrajectoryPtr > trajectory_
static bool getConfigData(ros::NodeHandle &nh, std::map< std::string, XmlRpc::XmlRpcValue > &config, std::string param=std::string("stomp"))
Convenience method to load extract the parameters for each supported planning group.
const std::string & getName() const
bool computeTimeStamps(robot_trajectory::RobotTrajectory &trajectory, const double max_velocity_scaling_factor=1.0, const double max_acceleration_scaling_factor=1.0) const
bool getParam(const std::string &key, std::string &s) const
bool parametersToJointTrajectory(const Eigen::MatrixXd &parameters, trajectory_msgs::JointTrajectory &traj)
Converts from an Eigen Matrix to to a joint trajectory.
#define ROS_WARN_COND(cond,...)
bool getStartAndGoal(Eigen::VectorXd &start, Eigen::VectorXd &goal)
Gets the start and goal joint values from the motion plan request passed.
const std::vector< const JointModel * > & getActiveJointModels() const
double getVariablePosition(const std::string &variable) const
#define ROS_ERROR_STREAM(args)
void setVariablePosition(const std::string &variable, double value)
#define ROS_ERROR(...)
void setRobotTrajectoryMsg(const robot_state::RobotState &reference_state, const trajectory_msgs::JointTrajectory &trajectory)
#define ROS_DEBUG(...)


stomp_moveit
Author(s): Jorge Nicho
autogenerated on Fri May 8 2020 03:35:47