common_utils.cpp
Go to the documentation of this file.
1 //
2 // Created by yijiangh on 7/5/17.
3 //
4 
5 #include "common_utils.h"
6 #include "trajectory_utils.h"
7 
8 #include <ros/topic.h>
10 
11 #include <descartes_planner/dense_planner.h>
12 #include <descartes_planner/sparse_planner.h>
13 #include <descartes_trajectory/axial_symmetric_pt.h>
14 
16 #include <moveit_msgs/GetMotionPlan.h>
17 
18 // services
19 #include <moveit_msgs/ApplyPlanningScene.h>
20 #include <moveit_msgs/GetPlanningScene.h>
21 
22 #include <moveit_msgs/GetMotionPlan.h>
23 
24 // mesh collision geometry import
26 
27 // Constants
28 const static double DEFAULT_TIME_UNDEFINED_VELOCITY =
29  0.0; // When a Descartes trajectory point has no timing info associated
30 // with it, this value (in seconds) is used instead
31 const static std::string DEFAULT_FRAME_ID =
32  "world_frame"; // The default frame_id used for trajectories generated
33 // by these helper functions
34 const static double DEFAULT_ANGLE_DISCRETIZATION =
35  M_PI / 12.0; // Default discretization used for axially-symmetric points
36 // in these helper functions
37 const static double DEFAULT_JOINT_WAIT_TIME = 5.0; // Maximum time allowed to capture a new joint
38 // state message
39 const static double DEFAULT_JOINT_VELOCITY = 0.3; // rad/s
40 
41 // MoveIt Configuration Constants
43 const static double DEFAULT_MOVEIT_PLANNING_TIME = 20.0; // seconds
44 const static double DEFAULT_MOVEIT_VELOCITY_SCALING = 0.5; // Slow down the robot
45 const static std::string DEFAULT_MOVEIT_PLANNER_ID = "RRTstar";
46 const static std::string DEFAULT_MOVEIT_FRAME_ID = "world_frame";
47 const static std::string DEFAULT_MOVEIT_PLANNING_SERVICE_NAME = "plan_kinematic_path";
48 
49 const static std::string GET_PLANNING_SCENE_SERVICE = "get_planning_scene";
50 const static std::string GET_PLANNER_PARAM_SERVICE = "get_planner_params";
51 
52 // customized threshold to get rid of weird solution generated by RRT (40)
53 const static int RRT_WEIRD_SOL_NUM_THRESHOLD = 40;
54 
55 Eigen::Affine3d choreo_process_planning::createNominalTransform(const geometry_msgs::Pose& ref_pose,
56  const geometry_msgs::Point& pt)
57 {
58  Eigen::Affine3d eigen_pose;
59  Eigen::Vector3d eigen_pt;
60 
61  tf::poseMsgToEigen(ref_pose, eigen_pose);
62  tf::pointMsgToEigen(pt, eigen_pt);
63 
64  // Translation transform
65  Eigen::Affine3d to_point;
66  to_point = Eigen::Translation3d(eigen_pt);
67 
68  // Reverse the Z axis
69  Eigen::Affine3d flip_z;
70  flip_z = Eigen::AngleAxisd(M_PI, Eigen::Vector3d::UnitY());
71 
72  // "snap" to the pt and flip z axis
73  return eigen_pose * to_point * flip_z;
74 }
75 
76 Eigen::Affine3d choreo_process_planning::createNominalTransform(const geometry_msgs::Pose& ref_pose,
77  const double z_adjust)
78 {
79  Eigen::Affine3d eigen_pose;
80 
81  tf::poseMsgToEigen(ref_pose, eigen_pose);
82 
83  return createNominalTransform(eigen_pose, z_adjust);
84 }
85 
86 Eigen::Affine3d choreo_process_planning::createNominalTransform(const Eigen::Affine3d &ref_pose,
87  const double z_adjust)
88 {
89  // Reverse the Z axis
90  Eigen::Affine3d flip_z;
91  flip_z = Eigen::AngleAxisd(M_PI, Eigen::Vector3d::UnitY());
92 
93  return ref_pose * Eigen::Translation3d(0, 0, z_adjust) * flip_z;
94 }
95 
96 static double calcDefaultTime(const std::vector<double>& a, const std::vector<double>& b,
97  double max_joint_vel)
98 {
99  ROS_ASSERT(a.size() == b.size());
100  ROS_ASSERT(a.size() > 0);
101  std::vector<double> result (a.size());
102  std::transform(a.begin(), a.end(), b.begin(), result.begin(), [] (double a, double b)
103  {
104  return std::abs(a - b);
105  });
106 
107  return *std::max_element(result.begin(), result.end()) / max_joint_vel;
108 }
109 
110 trajectory_msgs::JointTrajectory choreo_process_planning::toROSTrajectory(
111  const std::vector<std::vector<double>>& solution,
112  const descartes_core::RobotModel& model)
113 {
114  ros::Duration from_start(0.0);
115  std::vector<double> joint_point;
116  std::vector<double> dummy;
117  trajectory_msgs::JointTrajectory ros_trajectory; // result
118 
119  const int dof = model.getDOF();
120 
121  for (std::size_t i = 0; i < solution.size(); ++i)
122  {
123  assert(solution[i].size()==dof);
124 
125  trajectory_msgs::JointTrajectoryPoint pt;
126  pt.positions = solution[i];
127  pt.velocities.resize(joint_point.size(), 0.0);
128  pt.accelerations.resize(joint_point.size(), 0.0);
129  pt.effort.resize(joint_point.size(), 0.0);
130 
131  if (i == 0)
132  {
133  from_start += ros::Duration(DEFAULT_TIME_UNDEFINED_VELOCITY); // default time
134  }
135  else
136  {
137  // If we have a previous point then it makes more sense to set the time of the
138  // motion based on the largest joint motion required between two points and a
139  // default velocity.
140  const auto& prev = ros_trajectory.points.back().positions;
141  const auto& next = pt.positions;
142  const auto td = calcDefaultTime(prev, next, DEFAULT_JOINT_VELOCITY);
143  from_start += ros::Duration(td);
144  }
145 
146  pt.time_from_start = from_start;
147 
148  ros_trajectory.points.push_back(pt);
149  }
150 
151  return ros_trajectory;
152 }
153 
154 trajectory_msgs::JointTrajectory choreo_process_planning::toROSTrajectory(
156  const descartes_core::RobotModel& model)
157 {
158  ros::Duration from_start(0.0);
159  std::vector<double> joint_point;
160  std::vector<double> dummy;
161  trajectory_msgs::JointTrajectory ros_trajectory; // result
162 
163  for (std::size_t i = 0; i < solution.size(); ++i)
164  {
165  solution[i]->getNominalJointPose(dummy, model, joint_point);
166 
167  trajectory_msgs::JointTrajectoryPoint pt;
168  pt.positions = joint_point;
169  pt.velocities.resize(joint_point.size(), 0.0);
170  pt.accelerations.resize(joint_point.size(), 0.0);
171  pt.effort.resize(joint_point.size(), 0.0);
172 
173  double time_step = solution[i]->getTiming().upper; // request descartes timing
174  if (time_step == 0.0)
175  {
176  if (i == 0)
177  {
178  from_start += ros::Duration(DEFAULT_TIME_UNDEFINED_VELOCITY); // default time
179  }
180  else
181  {
182  // If we have a previous point then it makes more sense to set the time of the
183  // motion based on the largest joint motion required between two points and a
184  // default velocity.
185  const auto& prev = ros_trajectory.points.back().positions;
186  const auto& next = pt.positions;
187  const auto td = calcDefaultTime(prev, next, DEFAULT_JOINT_VELOCITY);
188  from_start += ros::Duration(td);
189  }
190  }
191  else
192  {
193  from_start += ros::Duration(time_step);
194  }
195 
196  pt.time_from_start = from_start;
197 
198  ros_trajectory.points.push_back(pt);
199  }
200 
201  return ros_trajectory;
202 }
203 
204 void choreo_process_planning::fillTrajectoryHeaders(const std::vector<std::string>& joints,
205  trajectory_msgs::JointTrajectory& traj,
206  const std::string world_frame)
207 {
208  traj.joint_names = joints;
209  traj.header.frame_id = world_frame;
210  traj.header.stamp = ros::Time::now();
211 }
212 
213 void choreo_process_planning::appendTrajectoryHeaders(const trajectory_msgs::JointTrajectory& orig_traj,
214  trajectory_msgs::JointTrajectory& traj,
215  const double sim_time_scale)
216 {
217  traj.joint_names = orig_traj.joint_names;
218  traj.header.frame_id = orig_traj.header.frame_id;
219  traj.header.stamp = orig_traj.header.stamp + orig_traj.points.back().time_from_start;
220 
221  // set time_from_start relative to first point
222  ros::Duration base_time = traj.points[0].time_from_start;
223 
224  for (int i = 0; i < traj.points.size(); i++)
225  {
226  traj.points[i].time_from_start -= base_time;
227 
228  //sim speed tuning
229  traj.points[i].time_from_start *= sim_time_scale;
230  }
231 }
232 
233 std::vector<double> choreo_process_planning::getCurrentJointState(const std::string& topic)
234 {
235  sensor_msgs::JointStateConstPtr state = ros::topic::waitForMessage<sensor_msgs::JointState>(
237  if (!state)
238  throw std::runtime_error("Joint state message capture failed");
239  return state->position;
240 }
241 
243  ros::ServiceClient& planning_scene_diff_client, const moveit_msgs::CollisionObject& c_obj)
244 {
245  if(planning_scene_diff_client.waitForExistence())
246  {
247 // ROS_INFO_STREAM("planning scene diff srv connected!");
248  }
249  else
250  {
251  ROS_ERROR_STREAM("cannot connect with planning scene diff server...");
252  }
253 
254  moveit_msgs::ApplyPlanningScene srv;
255 
256  moveit_msgs::PlanningScene planning_scene_msg;
257  planning_scene_msg.world.collision_objects.push_back(c_obj);
258  planning_scene_msg.is_diff = true;
259  srv.request.scene = planning_scene_msg;
260 
261  if(planning_scene_diff_client.call(srv))
262  {
263 // ROS_INFO_STREAM("adding new collision object to planning scene published!");
264  return true;
265  }
266  else
267  {
268  ROS_ERROR_STREAM("Failed to publish planning scene diff srv!");
269  return false;
270  }
271 }
272 
273 // TODO: temp input param
274 moveit_msgs::AttachedCollisionObject choreo_process_planning::addFullEndEffectorCollisionObject(bool is_add)
275 {
276  // millimeter to meter
277  double scale = 0.001;
278  Eigen::Vector3d scale_vector(scale, scale, scale);
279  moveit_msgs::AttachedCollisionObject attached_full_eef;
280  attached_full_eef.link_name = "eef_base_link";
281 
282  /* A default pose */
283  geometry_msgs::Pose pose;
284  pose.position.x = 0.0;
285  pose.position.y = 0.0;
286  pose.position.z = 0.0;
287  pose.orientation.w= 0.0;
288  pose.orientation.x= 0.0;
289  pose.orientation.y= 0.0;
290  pose.orientation.z= 0.0;
291 
292  /* Define the full eef mesh */
294  "package://asw_end_effector/meshes/collision/asw_hotend_end_effector_hull_bulky.stl", scale_vector);
295  shape_msgs::Mesh mesh;
296  shapes::ShapeMsg mesh_msg;
297  shapes::constructMsgFromShape(m, mesh_msg);
298  mesh = boost::get<shape_msgs::Mesh>(mesh_msg);
299 
300  attached_full_eef.object.header.frame_id = "eef_tcp_frame";
301  attached_full_eef.object.id = "full_eef";
302 
303  attached_full_eef.object.meshes.resize(1);
304  attached_full_eef.object.mesh_poses.resize(1);
305 
306  attached_full_eef.object.meshes[0] = mesh;
307  attached_full_eef.object.mesh_poses[0] = pose;
308 
309  if(is_add)
310  {
311  attached_full_eef.object.operation = moveit_msgs::CollisionObject::ADD;
312  }
313  else
314  {
315  attached_full_eef.object.operation = moveit_msgs::CollisionObject::REMOVE;
316  }
317 
318  return attached_full_eef;
319 }
320 
322 {
323  // fetch scene
324  ros::NodeHandle nh;
325  auto planning_scene_fetch_client = nh.serviceClient<moveit_msgs::GetPlanningScene>(GET_PLANNING_SCENE_SERVICE);
326 
327  if(!planning_scene_fetch_client.waitForExistence())
328  {
329  ROS_ERROR_STREAM("[Process Planning] cannot connect with get fetch planning scene server...");
330  }
331 
332  moveit_msgs::GetPlanningScene fetch_srv;
333  fetch_srv.request.components.components = moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
334 
335  if(!planning_scene_fetch_client.call(fetch_srv))
336  {
337  ROS_ERROR_STREAM("[Process Planning] Failed to fetch planning scene srv!");
338  }
339 
340  // publish diff scene
341  if(!planning_scene_diff_client.waitForExistence())
342  {
343  ROS_ERROR_STREAM("cannot connect with planning scene diff server...");
344  }
345 
346  moveit_msgs::ApplyPlanningScene srv;
347 
348  moveit_msgs::PlanningScene planning_scene_msg;
349  for(auto& existing_obj : fetch_srv.response.scene.world.collision_objects)
350  {
351  existing_obj.operation = moveit_msgs::CollisionObject::REMOVE;
352  planning_scene_msg.world.collision_objects.push_back(existing_obj);
353 
354 // ROS_INFO_STREAM("collision object # " << existing_obj.id << " removed.");
355  }
356 
357  planning_scene_msg.is_diff = true;
358  srv.request.scene = planning_scene_msg;
359 
360  if(planning_scene_diff_client.call(srv))
361  {
362 // ROS_INFO_STREAM("adding new collision object to planning scene published!");
363  return true;
364  }
365  else
366  {
367  ROS_ERROR_STREAM("Failed to publish <Clear> planning scene diff srv!");
368  return false;
369  }
370 }
371 
373 choreo_process_planning::createJointPath(const std::vector<double>& start,
374  const std::vector<double>& stop, double dtheta)
375 {
376  JointVector path = interpolateJoint(start, stop, dtheta);
377  DescartesTraj result;
378  for (std::size_t i = 0; i < path.size(); ++i)
379  {
380  result.push_back(boost::make_shared<descartes_trajectory::JointTrajectoryPt>(path[i]));
381  }
382  return result;
383 }
384 
385 trajectory_msgs::JointTrajectory choreo_process_planning::getMoveitPlan(
386  const std::string& group_name, const std::vector<double>& joints_start,
387  const std::vector<double>& joints_stop, moveit::core::RobotModelConstPtr model)
388 {
389  const moveit::core::JointModelGroup* group = model->getJointModelGroup(group_name);
390  robot_state::RobotState goal_state(model);
391  goal_state.setJointGroupPositions(group, joints_stop);
392 
393  moveit_msgs::GetMotionPlan::Request req;
394  req.motion_plan_request.group_name = group_name;
395  req.motion_plan_request.num_planning_attempts = DEFAULT_MOVEIT_NUM_PLANNING_ATTEMPTS;
396  req.motion_plan_request.max_velocity_scaling_factor = DEFAULT_MOVEIT_VELOCITY_SCALING;
397  req.motion_plan_request.allowed_planning_time = DEFAULT_MOVEIT_PLANNING_TIME;
398  req.motion_plan_request.planner_id = DEFAULT_MOVEIT_PLANNER_ID;
399 
400  req.motion_plan_request.workspace_parameters.header.frame_id = model->getRootLinkName();
401  req.motion_plan_request.workspace_parameters.header.stamp = ros::Time::now();
402 
403  // Set the start state
404  // Will want to add options here to start from a state that's not the start state
405  moveit_msgs::RobotState start_state;
406  start_state.is_diff = false;
407  sensor_msgs::JointState joint_state;
408  joint_state.name = group->getActiveJointModelNames();
409  joint_state.position = joints_start;
410  start_state.joint_state = joint_state;
411  req.motion_plan_request.start_state = start_state;
412 
413  // Set the goal state
414  moveit_msgs::Constraints c = kinematic_constraints::constructGoalConstraints(goal_state, group);
415  req.motion_plan_request.goal_constraints.push_back(c);
416 
417  // Make connection the planning-service offered by the MoveIt MoveGroup node
418  ros::NodeHandle nh;
419 
420  std::string planner_name;
421  if(!ros::param::get("~planner", planner_name))
422  {
423  ROS_WARN_STREAM("[Tr planning] planner param fetch fails.");
424  }
425 
426  if("ompl" != planner_name)
427  {
428  ROS_INFO_STREAM("[Moveit Transition Planning] planner: " << planner_name);
429  }
430  else
431  {
432  ROS_INFO_STREAM("[Moveit Transition Planning] planner: " << planner_name << " - " << DEFAULT_MOVEIT_PLANNER_ID);
433  }
434 
435  ros::ServiceClient client =
436  nh.serviceClient<moveit_msgs::GetMotionPlan>(DEFAULT_MOVEIT_PLANNING_SERVICE_NAME);
437 
438  trajectory_msgs::JointTrajectory jt;
439  moveit_msgs::GetMotionPlan::Response res;
440  if (client.call(req, res))
441  {
442  jt = res.motion_plan_response.trajectory.joint_trajectory;
443  }
444  else
445  {
446  ROS_ERROR("%s: Unable to call MoveIt path planning service: '%s' or planning failed",
447  __FUNCTION__, DEFAULT_MOVEIT_PLANNING_SERVICE_NAME.c_str());
448 // throw std::runtime_error("Unable to generate MoveIt path plan");
449  }
450  return jt;
451 }
452 
453 trajectory_msgs::JointTrajectory choreo_process_planning::getMoveitTransitionPlan(
454  const std::string& group_name,
455  const std::vector<double>& joints_start,
456  const std::vector<double>& joints_stop,
457  const std::vector<double>& initial_pose,
458  moveit::core::RobotModelConstPtr model,
459  const bool force_insert_reset)
460 {
461  ros::NodeHandle nh;
462 
463  std::string planner_name;
464  if(!ros::param::get("~planner", planner_name))
465  {
466  ROS_WARN_STREAM("[Tr planning] planner param fetch fails.");
467  }
468 
469  const moveit::core::JointModelGroup* group = model->getJointModelGroup(group_name);
470  robot_state::RobotState goal_state(model);
471  goal_state.setJointGroupPositions(group, joints_stop);
472 
473  moveit_msgs::GetMotionPlan::Request req;
474  req.motion_plan_request.group_name = group_name;
475  req.motion_plan_request.num_planning_attempts = DEFAULT_MOVEIT_NUM_PLANNING_ATTEMPTS;
476  req.motion_plan_request.max_velocity_scaling_factor = DEFAULT_MOVEIT_VELOCITY_SCALING;
477  req.motion_plan_request.allowed_planning_time = DEFAULT_MOVEIT_PLANNING_TIME;
478 
479  if("ompl" == planner_name)
480  {
481  req.motion_plan_request.planner_id = DEFAULT_MOVEIT_PLANNER_ID;
482  }
483 
484  req.motion_plan_request.workspace_parameters.header.frame_id = model->getRootLinkName();
485  req.motion_plan_request.workspace_parameters.header.stamp = ros::Time::now();
486 
487  // Set the start state
488  // Will want to add options here to start from a state that's not the start state
489  moveit_msgs::RobotState start_state;
490  start_state.is_diff = false;
491  sensor_msgs::JointState joint_state;
492  joint_state.name = group->getActiveJointModelNames();
493  joint_state.position = joints_start;
494  start_state.joint_state = joint_state;
495  req.motion_plan_request.start_state = start_state;
496 
497  // Set the goal state
498  moveit_msgs::Constraints c_goal = kinematic_constraints::constructGoalConstraints(goal_state, group);
499  req.motion_plan_request.goal_constraints.push_back(c_goal);
500 
501  // Make connection the planning-service offered by the MoveIt MoveGroup node
502  ros::ServiceClient client =
503  nh.serviceClient<moveit_msgs::GetMotionPlan>(DEFAULT_MOVEIT_PLANNING_SERVICE_NAME);
504 
505  trajectory_msgs::JointTrajectory jt;
506  moveit_msgs::GetMotionPlan::Response res;
507 
508  if("ompl" != planner_name)
509  {
510  ROS_INFO_STREAM("[Moveit Transition Planning] planner: " << planner_name);
511  }
512  else
513  {
514  ROS_INFO_STREAM("[Moveit Transition Planning] planner: " << planner_name << " - " << DEFAULT_MOVEIT_PLANNER_ID);
515  }
516 
517  bool insert_reset = false;
518 
519  if(!force_insert_reset)
520  {
521  bool plan_call_success = client.call(req, res);
522  if (plan_call_success && res.motion_plan_response.error_code.SUCCESS == res.motion_plan_response.error_code.val)
523  {
524  ROS_INFO_STREAM("[Tr Planning] direct transition planning succeed!");
525  jt = res.motion_plan_response.trajectory.joint_trajectory;
526 
527  if ("ompl" == planner_name)
528  {
529  if (jt.points.size() > RRT_WEIRD_SOL_NUM_THRESHOLD)
530  {
531  ROS_WARN_STREAM("[Tr Planning] transition planning jt num overflow:" << jt.points.size()
532  << ", current threshold: "
534  << ". reset transition is forced.");
535  insert_reset = true;
536  }
537  }
538  }
539  else
540  {
541  ROS_WARN_STREAM("[Tr Planning] direct transition planning failed.");
542  insert_reset = true;
543  }
544  }
545 
546  if(force_insert_reset || insert_reset)
547  {
548  ROS_WARN("[Tr Planning] try resetting robot to intial pose and replan");
549 
550  moveit_msgs::GetMotionPlan::Request req_to_reset = req;
551  moveit_msgs::GetMotionPlan::Request req_to_goal = req;
552 
553  // configure request to reset
554  robot_state::RobotState reset_goal_state(model);
555  reset_goal_state.setJointGroupPositions(group, initial_pose);
556  moveit_msgs::Constraints c_reset = kinematic_constraints::constructGoalConstraints(reset_goal_state, group);
557  req_to_reset.motion_plan_request.goal_constraints.clear();
558  req_to_reset.motion_plan_request.goal_constraints.push_back(c_reset);
559 
560  // configure request to goal
561  moveit_msgs::RobotState start_state_to_goal;
562  joint_state.position = initial_pose;
563  start_state_to_goal.is_diff = false;
564  start_state_to_goal.joint_state = joint_state;
565  req_to_goal.motion_plan_request.start_state = start_state_to_goal;
566 
567  req_to_goal.motion_plan_request.goal_constraints.clear();
568  req_to_goal.motion_plan_request.goal_constraints.push_back(c_goal);
569 
570  // obtain trajectory
571  trajectory_msgs::JointTrajectory jt_to_reset;
572  trajectory_msgs::JointTrajectory jt_to_goal;
573 
574  // reset planning
575  bool plan_call_success = client.call(req_to_reset, res);
576  if (plan_call_success && res.motion_plan_response.error_code.SUCCESS == res.motion_plan_response.error_code.val)
577  {
578  jt_to_reset = res.motion_plan_response.trajectory.joint_trajectory;
579  ROS_WARN("[Tr Planning] reset planning success.");
580  }
581  else
582  {
583  ROS_ERROR("%s: Unable to call MoveIt path planning service: '%s' or planning failed, AFTER RESETTING POSE",
584  __FUNCTION__, DEFAULT_MOVEIT_PLANNING_SERVICE_NAME.c_str());
585 // throw std::runtime_error("Unable to generate reset MoveIt path plan");
586  jt.points.clear();
587 
588  return jt;
589  }
590 
591  // goal planning
592  plan_call_success = client.call(req_to_goal, res);
593  if (plan_call_success && res.motion_plan_response.error_code.SUCCESS == res.motion_plan_response.error_code.val)
594  {
595  jt_to_goal = res.motion_plan_response.trajectory.joint_trajectory;
596  ROS_WARN("[Tr Planning] reset to goal planning success.");
597  }
598  else
599  {
600  ROS_ERROR("%s: Unable to call MoveIt path planning service: '%s' or planning failed, AFTER RESETTING POSE",
601  __FUNCTION__, DEFAULT_MOVEIT_PLANNING_SERVICE_NAME.c_str());
602 // throw std::runtime_error("Unable to generate reset to goal MoveIt path plan");
603  jt.points.clear();
604 
605  return jt;
606  }
607 
608  // concatenate trajectories
609  jt = jt_to_reset;
610  ros::Duration last_time = jt.points.back().time_from_start;
611 
612  for(auto pt : jt_to_goal.points)
613  {
614  pt.time_from_start += last_time;
615  jt.points.push_back(pt);
616  }
617  }
618  return jt;
619 }
620 
621 trajectory_msgs::JointTrajectory choreo_process_planning::planFreeMove(
622  descartes_core::RobotModel& model, const std::string& group_name,
623  moveit::core::RobotModelConstPtr moveit_model, const std::vector<double>& start,
624  const std::vector<double>& stop)
625 {
626  // Attempt joint interpolated motion
627  DescartesTraj joint_approach = createJointPath(start, stop);
628 
629  // Check approach for collisions
630  bool collision_free = true;
631  for (std::size_t i = 0; i < joint_approach.size(); ++i)
632  {
633  if (!joint_approach[i]->isValid(model))
634  {
635  collision_free = false;
636  break;
637  }
638  }
639 
640  // If the method is collision free, then we use the interpolation
641  // otherwise let moveit try
642  if (collision_free)
643  {
644  ROS_INFO_STREAM("[PlanFreeMove] Intepolated Plan used.");
645  return toROSTrajectory(joint_approach, model);
646  }
647  else
648  {
649  ROS_INFO_STREAM("[PlanFreeMove] Moveit Plan used");
650  return choreo_process_planning::getMoveitPlan(group_name, start, stop, moveit_model);
651  }
652 }
653 
654 double choreo_process_planning::freeSpaceCostFunction(const std::vector<double> &source,
655  const std::vector<double> &target)
656 {
657  const double FREE_SPACE_MAX_ANGLE_DELTA =
658  M_PI; // The maximum angle a joint during a freespace motion
659  // from the start to end position without that motion
660  // being penalized. Avoids flips.
661  const double FREE_SPACE_ANGLE_PENALTY =
662  2.0; // The factor by which a joint motion is multiplied if said
663  // motion is greater than the max.
664 
665  // The cost function here penalizes large single joint motions in an effort to
666  // keep the robot from flipping a joint, even if some other joints have to move
667  // a bit more.
668  double cost = 0.0;
669  for (std::size_t i = 0; i < source.size(); ++i)
670  {
671  double diff = std::abs(source[i] - target[i]);
672  if (diff > FREE_SPACE_MAX_ANGLE_DELTA)
673  cost += FREE_SPACE_ANGLE_PENALTY * diff;
674  else
675  cost += diff;
676  }
677  return cost;
678 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
bool addCollisionObject(ros::ServiceClient &planning_scene, const moveit_msgs::CollisionObject &c_obj)
bool clearAllCollisionObjects(ros::ServiceClient &planning_scene)
void poseMsgToEigen(const geometry_msgs::Pose &m, Eigen::Affine3d &e)
static const std::string GET_PLANNING_SCENE_SERVICE
static const std::string DEFAULT_MOVEIT_PLANNER_ID
Eigen::Affine3d createNominalTransform(const geometry_msgs::Pose &ref_pose, const geometry_msgs::Point &pt)
JointVector interpolateJoint(const std::vector< double > &start, const std::vector< double > &stop, double dtheta)
std::vector< std::vector< double > > JointVector
static const std::string DEFAULT_MOVEIT_FRAME_ID
std::size_t size(custom_string const &s)
bool call(MReq &req, MRes &res)
static const double DEFAULT_MOVEIT_VELOCITY_SCALING
void appendTrajectoryHeaders(const trajectory_msgs::JointTrajectory &orig_traj, trajectory_msgs::JointTrajectory &traj, const double sim_time_scale=0.0)
#define M_PI
static const double DEFAULT_TIME_UNDEFINED_VELOCITY
static const double DEFAULT_ANGLE_DISCRETIZATION
trajectory_msgs::JointTrajectory toROSTrajectory(const DescartesTraj &solution, const descartes_core::RobotModel &model)
#define ROS_WARN(...)
std::vector< double > getCurrentJointState(const std::string &topic)
static const double DEFAULT_JOINT_VELOCITY
static const double DEFAULT_JOINT_WAIT_TIME
DescartesTraj createJointPath(const std::vector< double > &start, const std::vector< double > &stop, double dtheta=M_PI/180.0)
static const int DEFAULT_MOVEIT_NUM_PLANNING_ATTEMPTS
group
static double calcDefaultTime(const std::vector< double > &a, const std::vector< double > &b, double max_joint_vel)
moveit_msgs::AttachedCollisionObject addFullEndEffectorCollisionObject(bool is_add)
void fillTrajectoryHeaders(const std::vector< std::string > &joints, trajectory_msgs::JointTrajectory &traj, const std::string world_frame)
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
ROSCPP_DECL bool get(const std::string &key, std::string &s)
moveit_msgs::Constraints constructGoalConstraints(const robot_state::RobotState &state, const robot_model::JointModelGroup *jmg, double tolerance_below, double tolerance_above)
static const int RRT_WEIRD_SOL_NUM_THRESHOLD
const std::vector< std::string > & getActiveJointModelNames() const
void pointMsgToEigen(const geometry_msgs::Point &m, Eigen::Vector3d &e)
trajectory_msgs::JointTrajectory getMoveitPlan(const std::string &group_name, const std::vector< double > &joints_start, const std::vector< double > &joints_stop, moveit::core::RobotModelConstPtr model)
static const double DEFAULT_MOVEIT_PLANNING_TIME
#define ROS_WARN_STREAM(args)
trajectory_msgs::JointTrajectory getMoveitTransitionPlan(const std::string &group_name, const std::vector< double > &joints_start, const std::vector< double > &joints_stop, const std::vector< double > &initial_pose, moveit::core::RobotModelConstPtr model, const bool force_insert_reset=false)
trajectory_msgs::JointTrajectory planFreeMove(descartes_core::RobotModel &model, const std::string &group_name, moveit::core::RobotModelConstPtr moveit_model, const std::vector< double > &start, const std::vector< double > &stop)
std::vector< descartes_core::TrajectoryPtPtr > DescartesTraj
Definition: common_utils.h:25
res
bool constructMsgFromShape(const Shape *shape, ShapeMsg &shape_msg)
Mesh * createMeshFromResource(const std::string &resource)
#define ROS_INFO_STREAM(args)
static const std::string DEFAULT_MOVEIT_PLANNING_SERVICE_NAME
double freeSpaceCostFunction(const std::vector< double > &source, const std::vector< double > &target)
static const std::string DEFAULT_FRAME_ID
static const std::string GET_PLANNER_PARAM_SERVICE
static Time now()
#define ROS_ERROR_STREAM(args)
#define ROS_ASSERT(cond)
#define ROS_ERROR(...)
boost::variant< shape_msgs::SolidPrimitive, shape_msgs::Mesh, shape_msgs::Plane > ShapeMsg


choreo_process_planning
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:02