generate_motion_plan.cpp
Go to the documentation of this file.
1 //
2 // Created by yijiangh on 7/8/17.
3 //
4 
5 #include "generate_motion_plan.h"
6 #include "trajectory_utils.h"
7 #include "path_transitions.h"
8 #include "common_utils.h"
9 
12 
13 // pose conversion
15 
16 // msg
17 #include <geometry_msgs/Pose.h>
18 #include <trajectory_msgs/JointTrajectoryPoint.h>
19 #include <choreo_msgs/SubProcess.h>
20 #include <choreo_msgs/ElementCandidatePoses.h>
21 #include <choreo_msgs/WireFrameCollisionObject.h>
22 #include <choreo_msgs/AssemblySequencePickNPlace.h>
23 #include <choreo_msgs/SequencedElement.h>
24 
25 #include <shape_msgs/Mesh.h>
26 #include <moveit_msgs/PlanningScene.h>
27 
28 // srv
29 #include <moveit_msgs/ApplyPlanningScene.h>
31 
32 #include <ros/console.h>
33 #include <Eigen/Geometry>
34 
35 #include <boost/filesystem.hpp>
36 
37 const static int TRANSITION_PLANNING_LOOP_COUNT = 5;
38 
40 {
41 void retractionPlanning(descartes_core::RobotModelPtr model,
42  const std::vector <planning_scene::PlanningScenePtr> &planning_scenes_approach,
43  const std::vector <planning_scene::PlanningScenePtr> &planning_scenes_depart,
44  const std::vector <descartes_planner::ConstrainedSegment> &segs,
45  std::vector <choreo_msgs::UnitProcessPlan> &plans)
46 {
47  if (plans.size() == 0)
48  {
49  ROS_ERROR("[retraction Planning] plans size = 0!");
50  assert(false);
51  }
52 
53  const auto ret_planning_start = ros::Time::now();
54 
55  for (size_t i = 0; i < plans.size(); i++)
56  {
57  ROS_INFO_STREAM("[retraction Planning] process #" << i);
58 
59  const std::vector<double>
60  start_process_joint = plans[i].sub_process_array.back().joint_array.points.front().positions;
61  const std::vector<double> end_process_joint = plans[i].sub_process_array.back().joint_array.points.back().positions;
62 
63  if (0 != i)
64  {
65  const auto last_process_end_joint = plans[i - 1].sub_process_array.back().joint_array.points.back().positions;
66 
67  // TODO: user option if start process pt = end process pt, skip retraction planning
68 // if(last_process_end_joint == start_process_joint)
69 // {
70 // // skip retraction planning
71 // ROS_INFO_STREAM("[retraction Planning] process #" << i << "retraction planning skipped.");
72 // continue;
73 // }
74  }
75 
76  model->setPlanningScene(planning_scenes_approach[i]);
77 
78  std::vector <std::vector<double>> approach_retract_traj;
79  if (!choreo_process_planning::retractPath(start_process_joint, segs[i].retract_dist, segs[i].linear_vel,
80  segs[i].orientations,
81  model, approach_retract_traj))
82  {
83  ROS_ERROR_STREAM("[retraction planning] process #" << i << " failed to find feasible approach retract motion!");
84  }
85  else
86  {
87 
88  std::reverse(approach_retract_traj.begin(), approach_retract_traj.end());
89 
90  trajectory_msgs::JointTrajectory approach_ros_traj =
91  choreo_process_planning::toROSTrajectory(approach_retract_traj, *model);
92 
93  choreo_msgs::SubProcess sub_process_approach;
94 
95  sub_process_approach.process_type = choreo_msgs::SubProcess::RETRACTION;
96  sub_process_approach.main_data_type = choreo_msgs::SubProcess::CART;
97  sub_process_approach.element_process_type = choreo_msgs::SubProcess::APPROACH;
98  sub_process_approach.joint_array = approach_ros_traj;
99 
100  plans[i].sub_process_array.insert(plans[i].sub_process_array.begin(), sub_process_approach);
101  }
102 
103  model->setPlanningScene(planning_scenes_depart[i]);
104 
105  std::vector <std::vector<double>> depart_retract_traj;
106  if (!choreo_process_planning::retractPath(end_process_joint, segs[i].retract_dist, segs[i].linear_vel,
107  segs[i].orientations,
108  model, depart_retract_traj))
109  {
110  ROS_ERROR_STREAM("[retraction planning] process #" << i << " failed to find feasible depart retract motion!");
111  }
112  else
113  {
114  trajectory_msgs::JointTrajectory depart_ros_traj =
115  choreo_process_planning::toROSTrajectory(depart_retract_traj, *model);
116 
117  choreo_msgs::SubProcess sub_process_depart;
118 
119  sub_process_depart.process_type = choreo_msgs::SubProcess::RETRACTION;
120  sub_process_depart.main_data_type = choreo_msgs::SubProcess::CART;
121  sub_process_depart.element_process_type = choreo_msgs::SubProcess::DEPART;
122  sub_process_depart.joint_array = depart_ros_traj;
123 
124  plans[i].sub_process_array.insert(plans[i].sub_process_array.end(), sub_process_depart);
125  }
126  } // loop for all unit plans
127 
128  const auto ret_planning_end = ros::Time::now();
129  ROS_INFO_STREAM("[retraction planning] Retraction Planning took " << (ret_planning_end - ret_planning_start).toSec()
130  << " seconds.");
131 }
132 
133 void transitionPlanning(std::vector <choreo_msgs::UnitProcessPlan> &plans,
134  moveit::core::RobotModelConstPtr moveit_model,
135  ros::ServiceClient &planning_scene_diff_client,
136  const std::string &move_group_name,
137  const std::vector<double> &start_state,
138  std::vector <planning_scene::PlanningScenePtr> &planning_scenes)
139 {
140  if (plans.size() == 0)
141  {
142  ROS_ERROR("[transionPlanning] plans size = 0!");
143  assert(false);
144  }
145 
146  const auto tr_planning_start = ros::Time::now();
147 
148  // generate full eef collision object
149  bool add_eef_full = true;
150  auto full_eef_collision_obj = choreo_process_planning::addFullEndEffectorCollisionObject(add_eef_full);
151 
152  std::vector<int> planning_failure_ids;
153 
154  std::vector<double> last_joint_pose = start_state;
155  std::vector<double> current_first_joint_pose;
156 
157  for (size_t i = 0; i < plans.size(); i++)
158  {
159  ROS_INFO_STREAM("[Transition Planning] process #" << i);
160 
161  if (0 != i)
162  {
163  last_joint_pose = plans[i - 1].sub_process_array.back().joint_array.points.back().positions;
164  }
165 
166  current_first_joint_pose = plans[i].sub_process_array.front().joint_array.points.front().positions;
167 
168  if (last_joint_pose == current_first_joint_pose)
169  {
170  // skip transition planning
171  continue;
172  }
173 
174  // update the planning scene
175  if (!planning_scene_diff_client.waitForExistence())
176  {
177  ROS_ERROR_STREAM("[Tr Planning] cannot connect with planning scene diff server...");
178  }
179 
180  moveit_msgs::ApplyPlanningScene srv;
181  auto scene_with_attached_eef = planning_scenes[i]->diff();
182  if (!scene_with_attached_eef->processAttachedCollisionObjectMsg(full_eef_collision_obj))
183  {
184  ROS_ERROR_STREAM("[Tr Planning] planning scene # " << i << "fails to add attached full eef collision geometry");
185  }
186 
187  scene_with_attached_eef->getPlanningSceneMsg(srv.request.scene);
188 
189  if (!planning_scene_diff_client.call(srv))
190  {
191  ROS_ERROR_STREAM("[Tr Planning] Failed to publish planning scene diff srv!");
192  }
193 
194  int repeat_planning_call = 0;
195  trajectory_msgs::JointTrajectory ros_trans_traj;
196 
197  bool joint_target_meet = true;
198  while (repeat_planning_call < TRANSITION_PLANNING_LOOP_COUNT)
199  {
200  // reset joint target meet flag
201  joint_target_meet = true;
202 
203  ros_trans_traj = choreo_process_planning::getMoveitTransitionPlan(move_group_name,
204  last_joint_pose,
205  current_first_joint_pose,
206  start_state,
207  moveit_model);
208 
209  // TODO: recover from transition planning failure
210  if (repeat_planning_call > 0)
211  {
212  ROS_WARN_STREAM("[Process Planning] transition planning retry - round "
213  << repeat_planning_call << "/" << TRANSITION_PLANNING_LOOP_COUNT);
214  }
215 
216  if (0 == ros_trans_traj.points.size())
217  {
218 // ROS_ERROR_STREAM("[Process Planning] Transition planning fails.");
219  joint_target_meet = false;
220  repeat_planning_call++;
221  continue;
222  }
223 
224  for (int s = 0; s < current_first_joint_pose.size(); s++)
225  {
226  if (current_first_joint_pose[s] - ros_trans_traj.points.back().positions[s] > 0.0001)
227  {
228  joint_target_meet = false;
229  break;
230  }
231  }
232 
233  if (joint_target_meet)
234  {
235  std::string retry_msg = repeat_planning_call>0 ? "retry":"";
236  ROS_WARN_STREAM("[Process Planning] transition planning "
237  << retry_msg << " succeed!");
238  break;
239  }
240 
241  repeat_planning_call++;
242  }
243 
244  if (!joint_target_meet)
245  {
246  planning_failure_ids.push_back(i);
247  ROS_ERROR_STREAM("[Tr planning] transition planning fails at index #" << i);
248  continue;
249  }
250 
251  choreo_msgs::SubProcess sub_process;
252 
253  sub_process.process_type = choreo_msgs::SubProcess::TRANSITION;
254  sub_process.main_data_type = choreo_msgs::SubProcess::JOINT;
255  sub_process.joint_array = ros_trans_traj;
256 
257  plans[i].sub_process_array.insert(plans[i].sub_process_array.begin(), sub_process);
258  }
259 
260  for (auto id : planning_failure_ids)
261  {
262  ROS_ERROR_STREAM("[Tr planning] transition planning fails at process #" << id);
263  }
264 
265  const auto tr_planning_end = ros::Time::now();
266  ROS_INFO_STREAM("[Process Planning] Transition Planning took " << (tr_planning_end - tr_planning_start).toSec()
267  << " seconds.");
268 }
269 
270 void transitionPlanningPickNPlace(std::vector <choreo_msgs::UnitProcessPlan> &plans,
271  moveit::core::RobotModelConstPtr moveit_model,
272  ros::ServiceClient &planning_scene_diff_client,
273  const std::string &move_group_name,
274  const std::vector<double> &start_state,
275  const std::vector<std::vector<planning_scene::PlanningScenePtr>>& planning_scenes)
276 {
277  if (plans.size() == 0)
278  {
279  ROS_ERROR("[transionPlanning] plans size = 0!");
280  assert(false);
281  }
282 
283  const auto tr_planning_start = ros::Time::now();
284 
285 // // generate full eef collision object
286 // bool add_eef_full = true;
287 // auto full_eef_collision_obj = choreo_process_planning::addFullEndEffectorCollisionObject(add_eef_full);
288 
289  std::vector<int> planning_failure_ids;
290 
291  std::vector<double> last_joint_pose = start_state;
292  std::vector<double> current_first_joint_pose;
293 
294  for (size_t i = 0; i < plans.size(); i++)
295  {
296  ROS_INFO_STREAM("[Transition Planning] process #" << i);
297 
298  // transition planning scenes' number
299  // <transition> - <sub-process> - <transition> - <sub-process> -... - <sub-process>
300  assert(planning_scenes[i].size() == plans[i].sub_process_array.size());
301  std::vector<choreo_msgs::SubProcess> weaved_sub_process;
302 
303  for (size_t j = 0; j < plans[i].sub_process_array.size(); j++)
304  {
305  if(0 == j)
306  {
307  // last joint pose from last unit process's last subprocess
308  if (0 != i)
309  {
310  last_joint_pose = plans[i - 1].sub_process_array.back().joint_array.points.back().positions;
311  }
312  }
313  else
314  {
315  last_joint_pose = plans[i].sub_process_array[j-1].joint_array.points.back().positions;
316  }
317 
318  current_first_joint_pose = plans[i].sub_process_array[j].joint_array.points.front().positions;
319 
320  if (last_joint_pose != current_first_joint_pose)
321  {
322  // update the planning scene
323  if (!planning_scene_diff_client.waitForExistence())
324  {
325  ROS_ERROR_STREAM("[Tr Planning] cannot connect with planning scene diff server...");
326  }
327 
328  moveit_msgs::ApplyPlanningScene srv;
329  auto scene = planning_scenes[i][j]->diff();
330 
331 // if (!scene_with_attached_eef->processAttachedCollisionObjectMsg(full_eef_collision_obj))
332 // {
333 // ROS_ERROR_STREAM("[Tr Planning] planning scene # " << i << "fails to add attached full eef collision geometry");
334 // }
335 
336  scene->getPlanningSceneMsg(srv.request.scene);
337 
338  if (!planning_scene_diff_client.call(srv))
339  {
340  ROS_ERROR_STREAM("[Tr Planning] Failed to publish planning scene diff srv!");
341  }
342 
343  int repeat_planning_call = 0;
344  trajectory_msgs::JointTrajectory ros_trans_traj;
345 
346  bool joint_target_meet = true;
347  while (repeat_planning_call < TRANSITION_PLANNING_LOOP_COUNT)
348  {
349  // reset joint target meet flag
350  joint_target_meet = true;
351 
352  ros_trans_traj = choreo_process_planning::getMoveitTransitionPlan(move_group_name,
353  last_joint_pose,
354  current_first_joint_pose,
355  start_state,
356  moveit_model);
357 
358  // TODO: recover from transition planning failure
359  if (repeat_planning_call > 0)
360  {
361  ROS_WARN_STREAM("[Process Planning] transition planning retry - round "
362  << repeat_planning_call << "/" << TRANSITION_PLANNING_LOOP_COUNT);
363  }
364 
365  if (0 == ros_trans_traj.points.size())
366  {
367 // ROS_ERROR_STREAM("[Process Planning] Transition planning fails.");
368  joint_target_meet = false;
369  repeat_planning_call++;
370  continue;
371  }
372 
373  for (int s = 0; s < current_first_joint_pose.size(); s++)
374  {
375  if (current_first_joint_pose[s] - ros_trans_traj.points.back().positions[s] > 0.0001)
376  {
377  joint_target_meet = false;
378  break;
379  }
380  }
381 
382  if (joint_target_meet)
383  {
384  std::string retry_msg = repeat_planning_call > 0 ? "retry" : "";
385  ROS_WARN_STREAM("[Process Planning] transition planning "
386  << retry_msg << " succeed!");
387  break;
388  }
389 
390  repeat_planning_call++;
391  } // end while
392 
393  if (!joint_target_meet)
394  {
395  planning_failure_ids.push_back(i);
396  ROS_ERROR_STREAM("[Tr planning] transition planning fails at index #" << i << ", subprocess #" << j);
397  continue;
398  }
399 
400  choreo_msgs::SubProcess sub_process;
401 
402  sub_process.process_type = choreo_msgs::SubProcess::TRANSITION;
403  sub_process.main_data_type = choreo_msgs::SubProcess::JOINT;
404  sub_process.joint_array = ros_trans_traj;
405 
406  weaved_sub_process.push_back(sub_process);
407  }
408 
409  weaved_sub_process.push_back(plans[i].sub_process_array[j]);
410 
411  } // end subprocess
412 
413  plans[i].sub_process_array = weaved_sub_process;
414  }// end process
415 
416  for (auto id : planning_failure_ids)
417  {
418  ROS_ERROR_STREAM("[Tr planning] transition planning fails at process #" << id);
419  }
420 
421  const auto tr_planning_end = ros::Time::now();
422  ROS_INFO_STREAM("[Process Planning] Transition Planning took " << (tr_planning_end - tr_planning_start).toSec()
423  << " seconds.");
424 }
425 
426 void adjustTrajectoryTiming(std::vector <choreo_msgs::UnitProcessPlan> &plans,
427  const std::vector <std::string> &joint_names,
428  const std::string world_frame)
429 {
430  if (plans.size() == 0)
431  {
432  ROS_ERROR("[ProcessPlanning : adjustTrajectoryTiming] plans size = 0!");
433  assert(false);
434  }
435 
436  if (0 == plans[0].sub_process_array.size())
437  {
438  ROS_ERROR("[ProcessPlanning : adjustTrajectoryTiming] plans[0] doesn't have sub process!");
439  assert(false);
440  }
441 
442  choreo_process_planning::fillTrajectoryHeaders(joint_names, plans[0].sub_process_array[0].joint_array, world_frame);
443  auto last_filled_jts = plans[0].sub_process_array[0].joint_array;
444 
445  // inline function for append trajectory headers (adjust time frame)
446  auto adjustTrajectoryHeaders =
447  [](trajectory_msgs::JointTrajectory &last_filled_jts, choreo_msgs::SubProcess &sp, double sim_speed)
448  {
449  choreo_process_planning::appendTrajectoryHeaders(last_filled_jts, sp.joint_array, sim_speed);
450  last_filled_jts = sp.joint_array;
451  };
452 
453  for (size_t i = 0; i < plans.size(); i++)
454  {
455  for (size_t j = 0; j < plans[i].sub_process_array.size(); j++)
456  {
457  plans[i].sub_process_array[j].unit_process_id = i;
458  plans[i].sub_process_array[j].sub_process_id = j;
459 
460  double sim_speed = 1.0;
461  if (2 != plans[i].sub_process_array[j].process_type)
462  {
463  sim_speed = 0.1;
464  }
465 
466  adjustTrajectoryHeaders(last_filled_jts, plans[i].sub_process_array[j], sim_speed);
467  }
468 
469 // ROS_INFO_STREAM("[Process Planning] process #" << i << " time stamp adjusted.");
470  }
471 }
472 
473 void appendTCPPoseToPlans(const descartes_core::RobotModelPtr model,
474  const std::vector <planning_scene::PlanningScenePtr> &planning_scenes_shrinked,
475  const std::vector <planning_scene::PlanningScenePtr> &planning_scenes_full,
476  std::vector <choreo_msgs::UnitProcessPlan> &plans)
477 {
478  int process_id_count = 0;
479  for (auto &unit_plan : plans)
480  {
481  for (auto &sub_process : unit_plan.sub_process_array)
482  {
483  if (sub_process.process_type == choreo_msgs::SubProcess::TRANSITION)
484  {
485  model->setPlanningScene(planning_scenes_full[process_id_count]);
486  }
487  else
488  {
489  model->setPlanningScene(planning_scenes_shrinked[process_id_count]);
490  }
491 
492  for (const auto &jt_pt : sub_process.joint_array.points)
493  {
494  Eigen::Affine3d TCP_pose = Eigen::Affine3d::Identity();
495  geometry_msgs::Pose geo_pose_msg;
496 
497  // convert it to TCP pose
498  if (!model->getFK(jt_pt.positions, TCP_pose))
499  {
500  ROS_ERROR_STREAM("FK solution failed at unit process #" << sub_process.unit_process_id
501  << ", subprocess #" << sub_process.sub_process_id
502  << ", process type: " << sub_process.process_type
503  << " (0: process, 1: near_model, 2: transition)");
504  }
505 
506  // affine3d to geometry_msg/pose
507  tf::poseEigenToMsg(TCP_pose, geo_pose_msg);
508 
509  sub_process.TCP_pose_array.push_back(geo_pose_msg);
510  }
511  }
512 // ROS_INFO_STREAM("[Process Planning] process #" << process_id_count << "TCP added.");
513  process_id_count++;
514  }
515 }
516 
517 void appendTCPPoseToPlansPickNPlace(const descartes_core::RobotModelPtr model,
518  const std::vector<std::vector<planning_scene::PlanningScenePtr>>& planning_scenes_transition,
519  const std::vector<std::vector<planning_scene::PlanningScenePtr>>& planning_scenes_subprocess,
520  std::vector<choreo_msgs::UnitProcessPlan>& plans)
521 {
522  int process_id_count = 0;
523  for (auto &unit_plan : plans)
524  {
525  int sp_count = 0;
526  int tr_count = 0;
527 
528  for (auto &sub_process : unit_plan.sub_process_array)
529  {
530  if (sub_process.process_type == choreo_msgs::SubProcess::TRANSITION)
531  {
532  model->setPlanningScene(planning_scenes_transition[process_id_count][tr_count]);
533  tr_count++;
534  }
535  else
536  {
537  model->setPlanningScene(planning_scenes_subprocess[process_id_count][sp_count]);
538  sp_count++;
539  }
540 
541  for (const auto &jt_pt : sub_process.joint_array.points)
542  {
543  Eigen::Affine3d TCP_pose = Eigen::Affine3d::Identity();
544  geometry_msgs::Pose geo_pose_msg;
545 
546  // convert it to TCP pose
547  if (!model->getFK(jt_pt.positions, TCP_pose))
548  {
549  ROS_ERROR_STREAM("FK solution failed at unit process #" << sub_process.unit_process_id
550  << ", subprocess #" << sub_process.sub_process_id
551  << ", process type: " << sub_process.process_type
552  << " (0: process, 1: near_model, 2: transition)");
553  }
554 
555  // affine3d to geometry_msg/pose
556  tf::poseEigenToMsg(TCP_pose, geo_pose_msg);
557 
558  sub_process.TCP_pose_array.push_back(geo_pose_msg);
559  }
560  }
561 // ROS_INFO_STREAM("[Process Planning] process #" << process_id_count << "TCP added.");
562  process_id_count++;
563  }
564 }
565 
566 // TODO: spatial extrusion overload
568  const std::string world_frame,
569  const bool use_saved_graph,
570  const std::string &saved_graph_file_name,
571  const double clt_rrt_unit_process_timeout,
572  const double clt_rrt_timeout,
573  const std::string &move_group_name,
574  const std::vector<double> &start_state,
575  const std::vector <choreo_msgs::ElementCandidatePoses> &task_seq,
576  const std::vector <choreo_msgs::WireFrameCollisionObject> &wf_collision_objs,
577  std::vector <descartes_planner::ConstrainedSegment> &segs,
578  descartes_core::RobotModelPtr model,
579  moveit::core::RobotModelConstPtr moveit_model,
580  ros::ServiceClient &planning_scene_diff_client,
581  std::vector <choreo_msgs::UnitProcessPlan> &plans)
582 {
583  // Step 0: Sanity checks
584  if (segs.size() == 0 || task_seq.size() != segs.size())
585  {
586  ROS_ERROR_STREAM("[Process Planning] input descartes Constrained Segment size" << segs.size());
587  return false;
588  }
589  assert(task_seq.size() == wf_collision_objs.size());
590 
591  plans.resize(segs.size());
592  const std::vector <std::string> &joint_names =
593  moveit_model->getJointModelGroup(move_group_name)->getActiveJointModelNames();
594 
595  // Step 1: Let's create all of our planning scenes to collision check against
596  std::vector <planning_scene::PlanningScenePtr> planning_scenes_shrinked_approach;
597  std::vector <planning_scene::PlanningScenePtr> planning_scenes_shrinked_depart;
598  std::vector <planning_scene::PlanningScenePtr> planning_scenes_full;
599  constructPlanningScenes(moveit_model, wf_collision_objs,
600  planning_scenes_shrinked_approach,
601  planning_scenes_shrinked_depart,
602  planning_scenes_full);
603 
604  // Step 2: CLT RRT* to solve process trajectory
605  CLTRRTforProcessROSTraj(model, segs, clt_rrt_unit_process_timeout, clt_rrt_timeout,
606  planning_scenes_shrinked_approach, planning_scenes_shrinked_depart,
607  task_seq, plans, saved_graph_file_name, use_saved_graph);
608 
609  // retract planning
610  retractionPlanning(model, planning_scenes_shrinked_approach, planning_scenes_shrinked_depart, segs, plans);
611 
612  // Step 5 : Plan for transition between each pair of sequential path
613  transitionPlanning(plans, moveit_model, planning_scene_diff_client, move_group_name,
614  start_state, planning_scenes_full);
615 
616  // Step 7 : fill in trajectory's time headers and pack into sub_process_plans
617  // for each unit_process (process id is added here too)
618  adjustTrajectoryTiming(plans, joint_names, world_frame);
619 
620  // Step 8: fill in TCP pose according to trajectories
621  appendTCPPoseToPlans(model, planning_scenes_shrinked_approach, planning_scenes_full, plans);
622 
623  ROS_INFO("[Process Planning] trajectories solved and packing finished");
624  return true;
625 }
626 
627 namespace {
628 
629 void testApplyPlanningScene(ros::ServiceClient& planning_scene_diff_client,
630  planning_scene::PlanningScenePtr& planning_scene)
631 {
632  // update the planning scene
633  if (!planning_scene_diff_client.waitForExistence())
634  {
635  ROS_ERROR_STREAM("[Tr Planning] cannot connect with planning scene diff server...");
636  }
637 
638  moveit_msgs::ApplyPlanningScene srv;
639 
640  planning_scene->getPlanningSceneMsg(srv.request.scene);
641 
642  if (!planning_scene_diff_client.call(srv))
643  {
644  ROS_ERROR_STREAM("[Tr Planning] Failed to publish TEST planning scene diff srv!");
645  }
646 }
647 
648 }
649 
650 // TODO: picknplace overload
652  const std::string world_frame,
653  const bool use_saved_graph,
654  const std::string &saved_graph_file_name,
655  const double clt_rrt_unit_process_timeout,
656  const double clt_rrt_timeout,
657  const double& linear_vel,
658  const double& linear_disc,
659  const std::string &move_group_name,
660  const std::vector<double> &start_state,
661  const choreo_msgs::AssemblySequencePickNPlace& as_pnp,
662  descartes_core::RobotModelPtr model,
663  moveit::core::RobotModelConstPtr moveit_model,
664  ros::ServiceClient &planning_scene_diff_client,
665  std::vector <choreo_msgs::UnitProcessPlan> &plans)
666 {
667  plans.resize(as_pnp.sequenced_elements.size());
668  const std::vector <std::string> &joint_names =
669  moveit_model->getJointModelGroup(move_group_name)->getActiveJointModelNames();
670 
671  // Step 1: Let's create all of our planning scenes to collision check against
672  std::vector<std::vector<planning_scene::PlanningScenePtr>> planning_scenes_transition;
673  std::vector<std::vector<planning_scene::PlanningScenePtr>> planning_scenes_subprocess;
674 
675  constructPlanningScenes(moveit_model,
676  world_frame,
677  as_pnp,
678  planning_scenes_transition,
679  planning_scenes_subprocess);
680 
681  // Step 2: CLT RRT* to solve process trajectory
683  as_pnp,
684  clt_rrt_unit_process_timeout,
685  clt_rrt_timeout,
686  linear_vel,
687  linear_disc,
688  planning_scenes_subprocess,
689  plans,
690  saved_graph_file_name,
691  use_saved_graph);
692 
693  // skip retract planning for picknplace
694 
695 // // Step 5 : Plan for transition between each pair of sequential path
696  transitionPlanningPickNPlace(plans, moveit_model, planning_scene_diff_client, move_group_name,
697  start_state, planning_scenes_subprocess);
698 
699 // // Step 7 : fill in trajectory's time headers and pack into sub_process_plans
700 // // for each unit_process (process id is added here too)
701  adjustTrajectoryTiming(plans, joint_names, world_frame);
702 
703 // // Step 8: fill in TCP pose according to trajectories
704  appendTCPPoseToPlansPickNPlace(model, planning_scenes_transition, planning_scenes_subprocess, plans);
705 
706  ROS_INFO("[Process Planning] trajectories solved and packing finished");
707  return true;
708 }
709 
710 } // end choreo process planning namespace
void adjustTrajectoryTiming(std::vector< choreo_msgs::UnitProcessPlan > &plans, const std::vector< std::string > &joint_names, const std::string world_frame)
static const int TRANSITION_PLANNING_LOOP_COUNT
void poseEigenToMsg(const Eigen::Affine3d &e, geometry_msgs::Pose &m)
XmlRpcServer s
void transitionPlanningPickNPlace(std::vector< choreo_msgs::UnitProcessPlan > &plans, moveit::core::RobotModelConstPtr moveit_model, ros::ServiceClient &planning_scene_diff_client, const std::string &move_group_name, const std::vector< double > &start_state, const std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes)
void transitionPlanning(std::vector< choreo_msgs::UnitProcessPlan > &plans, moveit::core::RobotModelConstPtr moveit_model, ros::ServiceClient &planning_scene_diff_client, const std::string &move_group_name, const std::vector< double > &start_state, std::vector< planning_scene::PlanningScenePtr > &planning_scenes)
void CLTRRTforProcessROSTraj(descartes_core::RobotModelPtr model, std::vector< descartes_planner::ConstrainedSegment > &segs, const double clt_rrt_unit_process_timeout, const double clt_rrt_timeout, const std::vector< planning_scene::PlanningScenePtr > &planning_scenes_approach, const std::vector< planning_scene::PlanningScenePtr > &planning_scenes_depart, const std::vector< choreo_msgs::ElementCandidatePoses > &task_seq, std::vector< choreo_msgs::UnitProcessPlan > &plans, const std::string &saved_graph_file_name, bool use_saved_graph)
void retractionPlanning(descartes_core::RobotModelPtr model, const std::vector< planning_scene::PlanningScenePtr > &planning_scenes_approach, const std::vector< planning_scene::PlanningScenePtr > &planning_scenes_depart, const std::vector< descartes_planner::ConstrainedSegment > &segs, std::vector< choreo_msgs::UnitProcessPlan > &plans)
std::size_t size(custom_string const &s)
bool call(MReq &req, MRes &res)
void appendTrajectoryHeaders(const trajectory_msgs::JointTrajectory &orig_traj, trajectory_msgs::JointTrajectory &traj, const double sim_time_scale=0.0)
trajectory_msgs::JointTrajectory toROSTrajectory(const DescartesTraj &solution, const descartes_core::RobotModel &model)
bool retractPath(const std::vector< double > &start_joint, double retract_dist, double TCP_speed, const std::vector< Eigen::Matrix3d > &eef_directions, descartes_core::RobotModelPtr &model, std::vector< std::vector< double >> &retract_jt_traj)
void constructPlanningScenes(moveit::core::RobotModelConstPtr moveit_model, const std::string &world_frame, const choreo_msgs::AssemblySequencePickNPlace &as_pnp, std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes_transition, std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes_subprocess)
void appendTCPPoseToPlans(const descartes_core::RobotModelPtr model, const std::vector< planning_scene::PlanningScenePtr > &planning_scenes_shrinked, const std::vector< planning_scene::PlanningScenePtr > &planning_scenes_full, std::vector< choreo_msgs::UnitProcessPlan > &plans)
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))
#define ROS_INFO(...)
bool generateMotionPlan(const std::string world_frame, const bool use_saved_graph, const std::string &saved_graph_file_name, const double clt_rrt_unit_process_timeout, const double clt_rrt_timeout, const std::string &move_group_name, const std::vector< double > &start_state, const std::vector< choreo_msgs::ElementCandidatePoses > &task_seq, const std::vector< choreo_msgs::WireFrameCollisionObject > &wf_collision_objs, std::vector< descartes_planner::ConstrainedSegment > &segs, descartes_core::RobotModelPtr model, moveit::core::RobotModelConstPtr moveit_model, ros::ServiceClient &planning_scene_diff_client, std::vector< choreo_msgs::UnitProcessPlan > &plans)
#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)
#define ROS_INFO_STREAM(args)
static Time now()
#define ROS_ERROR_STREAM(args)
void appendTCPPoseToPlansPickNPlace(const descartes_core::RobotModelPtr model, const std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes_transition, const std::vector< std::vector< planning_scene::PlanningScenePtr >> &planning_scenes_subprocess, std::vector< choreo_msgs::UnitProcessPlan > &plans)
#define ROS_ERROR(...)


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