choreo_core_service.cpp
Go to the documentation of this file.
2 
5 
6 //subscribed services
7 #include <choreo_msgs/TaskSequenceProcessing.h>
8 #include <choreo_msgs/TaskSequencePlanning.h>
9 #include <choreo_msgs/ProcessPlanning.h>
10 #include <choreo_msgs/MoveToTargetPose.h>
11 #include <choreo_msgs/OutputProcessing.h>
12 
13 // msgs
14 #include <descartes_msgs/LadderGraphList.h>
15 
16 // topics and services
17 const static std::string SAVE_DATA_BOOL_PARAM = "save_data";
18 const static std::string SAVE_LOCATION_PARAM = "save_location";
19 
20 // TODO: externalize tehse service name as ros params
21 // provided services
22 const static std::string FRAMEFAB_PARAMETERS_SERVICE = "choreo_parameters";
23 const static std::string ELEMENT_NUMBER_REQUEST_SERVICE = "element_member_request";
24 const static std::string VISUALIZE_SELECTED_PATH_SERVICE= "visualize_select_path";
25 const static std::string GET_AVAILABLE_PROCESS_PLANS_SERVICE= "get_available_process_plans";
26 const static std::string OUTPUT_PROCESS_PLANS_SERVICE= "output_process_plans";
27 const static std::string QUERY_COMPUTATION_RESULT="query_computation_result";
28 
29 // subscribed services
30 const static std::string TASK_SEQUENCE_PROCESSING_SERVICE = "task_sequence_processing";
31 const static std::string TASK_SEQUENCE_PLANNING_SERVICE = "task_sequence_planning";
32 const static std::string PROCESS_PLANNING_SERVICE = "process_planning";
33 const static std::string MOVE_TO_TARGET_POSE_SERVICE = "move_to_target_pose";
34 const static std::string OUTPUT_PROCESSING_SERVICE = "output_processing";
35 
36 const static std::string PICKNPLACE_PLANNING_SERVICE = "picknplace_planning";
37 
38 // Default filepaths and namespaces for caching stored parameters
39 const static std::string MODEL_INPUT_PARAMS_FILE = "model_input_parameters.msg";
40 const static std::string TASK_SEQUENCE_INPUT_PARAMS_FILE = "task_sequence_input_parameters.msg";
41 const static std::string ROBOT_INPUT_PARAMS_FILE = "robot_input_parameters.msg";
42 const static std::string OUTPUT_SAVE_DIR_INPUT_PARAMS_FILE = "output_save_dir_input_parameters.msg";
43 
44 // TODO: find a way for rviz to read these hard-coded markers_array topic name automatically
45 // Visualization Maker topics
46 const static std::string PATH_VISUAL_TOPIC = "path_visualization";
47 const static std::string PRINT_BED_VISUAL_TOPIC = "print_bed_visualization";
48 
49 // TODO: externalize these action names as ros params
50 // subscribed action server name - note: must be same to client's name
51 const static std::string FRAMEFAB_EXE_ACTION_SERVER_NAME = "choreo_execution_as";
52 const static std::string TASK_SEQUENCE_PROCESSING_ACTION_SERVER_NAME = "task_sequence_processing_action";
53 const static std::string TASK_SEQUENCE_PLANNING_ACTION_SERVER_NAME = "task_sequence_planning_action";
54 const static std::string PROCESS_PLANNING_ACTION_SERVER_NAME = "process_planning_action";
55 
56 // serving action
57 const static std::string SIMULATE_MOTION_PLAN_ACTION_SERVER_NAME = "simulate_motion_plan_as";
58 
59 const static int PROCESS_EXE_BUFFER = 5; // Additional time [s] buffer between when blending should end and timeout
60 
61 namespace
62 {
63 }// util namespace
64 
66  : save_data_(false),
67  selected_task_id_(0),
68  assembly_type_(""),
69  choreo_exe_client_(FRAMEFAB_EXE_ACTION_SERVER_NAME, true),
70  task_sequence_processing_server_(nh_, TASK_SEQUENCE_PROCESSING_ACTION_SERVER_NAME,
71  boost::bind(&ChoreoCoreService::taskSequenceProcessingActionCallback, this, _1), false),
72  task_sequence_planning_server_(nh_, TASK_SEQUENCE_PLANNING_ACTION_SERVER_NAME,
73  boost::bind(&ChoreoCoreService::taskSequencePlanningActionCallback, this, _1), false),
74  process_planning_server_(nh_, PROCESS_PLANNING_ACTION_SERVER_NAME,
75  boost::bind(&ChoreoCoreService::processPlanningActionCallback, this, _1), false),
76  simulate_motion_plan_server_(nh_, SIMULATE_MOTION_PLAN_ACTION_SERVER_NAME,
77  boost::bind(&ChoreoCoreService::simulateMotionPlansActionCallback, this, _1), false)
78 {}
79 
81 {
82  ros::NodeHandle ph("~");
83 
84  // loading parameters
85  // TODO: save location is default to $HOME/.ros/ now,
86  // should be oriented to some customized path
87 
88 // ph.getParam(SAVE_DATA_BOOL_PARAM, save_data_);
89 // ph.getParam(SAVE_LOCATION_PARAM, save_location_);
90 
91  // Load the 'prefix' that will be combined with parameters msg base names to save to disk
92  ph.param<std::string>("param_cache_prefix", param_cache_prefix_, "");
93  ph.param<std::string>("world_frame", world_frame_, "");
94 
95  if (!this->loadModelInputParameters(param_cache_prefix_ + MODEL_INPUT_PARAMS_FILE))
96  ROS_WARN("Unable to load model input parameters.");
97 
98  if (!this->loadTaskSequenceInputParameters(param_cache_prefix_ + TASK_SEQUENCE_INPUT_PARAMS_FILE))
99  ROS_WARN("Unable to load path input parameters.");
100 
101  if (!this->loadRobotInputParameters(param_cache_prefix_ + ROBOT_INPUT_PARAMS_FILE))
102  ROS_WARN("Unable to load robot input parameters.");
103 
105  ROS_WARN("Unable to load output path input parameters.");
106 
107  // load plugins (if-need-be)
108 
109  // TODO: save default parameters
110 
111  // service servers
115 
119 
123 
126 
129 
132 
133  // start local instances
134  visual_tools_.init(world_frame_, PATH_VISUAL_TOPIC);
135 
136  // start server
137 
138  // service clients
141  process_planning_client_ = nh_.serviceClient<choreo_msgs::ProcessPlanning>(PROCESS_PLANNING_SERVICE);
142  move_to_pose_client_ = nh_.serviceClient<choreo_msgs::MoveToTargetPose>(MOVE_TO_TARGET_POSE_SERVICE);
143  output_processing_client_ = nh_.serviceClient<choreo_msgs::OutputProcessing>(OUTPUT_PROCESSING_SERVICE);
144 
145  // publishers
146 
147  // action servers
152 
153  return true;
154 }
155 
157 {
158  ros::Duration loop_duration(1.0f);
159  while (ros::ok())
160  {
161  loop_duration.sleep();
162  }
163 }
164 
165 bool ChoreoCoreService::loadModelInputParameters(const std::string & filename)
166 {
169 
170  bool success = false;
171 
173 
174  if(!success)
175  {
176  // otherwise default to the parameter server
177  ros::NodeHandle nh("~/model_input");
178  success = loadParam(nh, "ref_pt_x", model_input_params_.ref_pt_x) &&
179  loadParam(nh, "ref_pt_y", model_input_params_.ref_pt_y) &&
180  loadParam(nh, "ref_pt_z", model_input_params_.ref_pt_z) &&
181  loadParam(nh, "unit_type", model_input_params_.unit_type) &&
182  loadParam(nh, "element_diameter", model_input_params_.element_diameter) &&
183  loadParam(nh, "shrink_length", model_input_params_.shrink_length);
184  }
185 
186  return success;
187 }
188 
189 
190 void ChoreoCoreService::saveModelInputParameters(const std::string& filename)
191 {
193  {
194  ROS_WARN_STREAM("Unable to save model input parameters to: " << filename);
195  }
196 }
197 
198 bool ChoreoCoreService::loadTaskSequenceInputParameters(const std::string & filename)
199 {
202 
204  {
205  return true;
206  }
207 
208  // otherwise default to the parameter server
209  ros::NodeHandle nh("~/task_sequence_input");
210  return loadParam(nh, "file_path", task_sequence_input_params_.file_path);
211 }
212 
213 void ChoreoCoreService::saveTaskSequenceInputParameters(const std::string & filename)
214 {
216  {
217  ROS_WARN_STREAM("Unable to save path input parameters to: " << filename);
218  }
219 }
220 
221 bool ChoreoCoreService::loadRobotInputParameters(const std::string & filename)
222 {
225 
227  {
228  return true;
229  }
230 
231  // otherwise default to the parameter server
232  ros::NodeHandle nh("~/robot_input");
233  return loadParam(nh, "init_pose", robot_input_params_.init_pose);
234 }
235 
236 void ChoreoCoreService::saveRobotInputParameters(const std::string& filename)
237 {
239  {
240  ROS_WARN_STREAM("Unable to save robot input parameters to: " << filename);
241  }
242 }
243 
244 bool ChoreoCoreService::loadOutputSaveDirInputParameters(const std::string & filename)
245 {
248 
250  {
251  return true;
252  }
253 
254  // otherwise default to the parameter server
255  ros::NodeHandle nh("~/output_save_dir_input");
256  return loadParam(nh, "file_path", output_save_dir_input_params_.file_path);
257 }
258 
259 void ChoreoCoreService::saveOutputSaveDirInputParameters(const std::string & filename)
260 {
262  {
263  ROS_WARN_STREAM("Unable to save output path input parameters to: " << filename);
264  }
265 }
266 
267 int ChoreoCoreService::checkSavedLadderGraphSize(const std::string& filename)
268 {
269  descartes_msgs::LadderGraphList graph_list_msg;
270 
271  if(choreo_param_helpers::fromFile(filename, graph_list_msg))
272  {
273  ROS_INFO_STREAM("[Core] saved ladder graph record found!");
274  return graph_list_msg.graph_list.size();
275  }
276  else
277  {
278  ROS_WARN_STREAM("[Core] NO saved ladder graph record found.");
279  return 0;
280  }
281 }
282 
284  choreo_msgs::ChoreoParameters::Request& req,
285  choreo_msgs::ChoreoParameters::Response& res)
286 {
287  switch (req.action)
288  {
289  case choreo_msgs::ChoreoParameters::Request::GET_CURRENT_PARAMETERS:
290  res.model_params = model_input_params_;
291  res.task_sequence_params = task_sequence_input_params_;
292  res.robot_params = robot_input_params_;
293  res.output_save_dir_params = output_save_dir_input_params_;
294  break;
295 
296  case choreo_msgs::ChoreoParameters::Request::GET_DEFAULT_PARAMETERS:
297  res.model_params = default_model_input_params_;
298  res.task_sequence_params = default_task_sequence_input_params_;
299  res.robot_params = default_robot_input_params_;
300  res.output_save_dir_params = default_output_save_dir_input_params_;
301  break;
302 
303  // Update the current parameters in this service
304  case choreo_msgs::ChoreoParameters::Request::SET_PARAMETERS:
305  case choreo_msgs::ChoreoParameters::Request::SAVE_PARAMETERS:
306  model_input_params_ = req.model_params;
307  task_sequence_input_params_ = req.task_sequence_params;
308  robot_input_params_ = req.robot_params;
309  output_save_dir_input_params_ = req.output_save_dir_params;
310 
311  if (req.action == choreo_msgs::ChoreoParameters::Request::SAVE_PARAMETERS)
312  {
317  }
318 
319  break;
320  }
321 
322  res.succeeded = true;
323  return true;
324 }
325 
327  choreo_msgs::ElementNumberRequest::Request& req,
328  choreo_msgs::ElementNumberRequest::Response& res)
329 {
330  switch (req.action)
331  {
332  case choreo_msgs::ElementNumberRequest::Request::REQUEST_ELEMENT_NUMBER:
333  {
334  // visualization before planning (path selection phase in UI)
335  // TODO: correct this as a unified request
336  // !!! TEMP DUMP FIX!
337  res.element_number =
339 
340  res.grasp_nums.clear();
341  for(const auto& se : as_pnp_.sequenced_elements)
342  {
343  assert(se.grasps.size() > 0);
344  res.grasp_nums.push_back(se.grasps.size());
345  }
346 
347  break;
348  }
349  case choreo_msgs::ElementNumberRequest::Request::REQUEST_SELECTED_TASK_NUMBER:
350  {
351  // for visualization after planning (plan selection phase in UI, visualize traj library)
352  res.element_number = selected_task_id_ + 1;
353 
354  res.grasp_nums.clear();
355  for(const auto& se : as_pnp_.sequenced_elements)
356  {
357  assert(se.grasps.size() > 0);
358  res.grasp_nums.push_back(se.grasps.size());
359  }
360 
361  break;
362  }
363  default:
364  {
365  res.element_number = 0;
366  ROS_ERROR_STREAM("Unknown parameter loading request in selection widget");
367  return false;
368  }
369  }
370 
371  return true;
372 }
373 
375  choreo_msgs::VisualizeSelectedPath::Request& req,
376  choreo_msgs::VisualizeSelectedPath::Response& res)
377 {
378  if(req.index != req.CLEAN_UP)
379  {
380  if(req.PICKNPLACE == req.assembly_type)
381  {
382  // TODO, get seq id and grasp id, trigger visualization, visualize_ee option
384  visual_tools_.visualizeGraspPickNPlace(req.index, req.grasp_id, req.visualize_ee);
385  }
386 
387  if(req.SPATIAL_EXTRUSION == req.assembly_type)
388  {
389  // TODO: this is only used for spatial extrusion
392  }
393 
394  res.succeeded = true;
395  }
396  else
397  {
399  res.succeeded = true;
400  }
401 }
402 
404  choreo_msgs::GetAvailableProcessPlans::Request&,
405  choreo_msgs::GetAvailableProcessPlans::Response& res)
406 {
407  typedef choreo_core_service::TrajectoryLibrary::TrajectoryMap::const_iterator MapIter;
408  for (MapIter it = trajectory_library_.get().begin(); it != trajectory_library_.get().end(); ++it)
409  {
410  res.names.push_back(it->first);
411  }
412  return true;
413 }
414 
416  choreo_msgs::OutputProcessPlans::Request& req,
417  choreo_msgs::OutputProcessPlans::Response& res)
418 {
419  // call output_processing srv
420  choreo_msgs::OutputProcessing srv;
421 
422  // fill in file_path
423  srv.request.file_path = output_save_dir_input_params_.file_path;
424 
425  // fill in plans
426  for(auto id : req.names)
427  {
428  if (trajectory_library_.get().find(id) == trajectory_library_.get().end())
429  {
430  ROS_ERROR_STREAM("Plan #" << id << " does not exist. Cannot output.");
431  return false;
432  }
433  else
434  {
435  srv.request.plans.push_back(trajectory_library_.get()[id]);
436  }
437  }
438 
440  {
441  ROS_WARN_STREAM("[choreo_core_service] Unable to call output processing service");
442  return false;
443  }
444  else
445  {
446  return true;
447  }
448 }
449 
451  choreo_msgs::QueryComputationRecord::Request &req,
452  choreo_msgs::QueryComputationRecord::Response &res)
453 {
454  const int found_saved_graphs_size = checkSavedLadderGraphSize(req.file_name);
455 
456  ROS_INFO_STREAM("[CORE] saved graph query - file name: " << req.file_name);
457 
458  res.record_found = bool(found_saved_graphs_size);
459  res.found_record_size = found_saved_graphs_size;
460 
461  return true;
462 }
463 
464 void ChoreoCoreService::taskSequenceProcessingActionCallback(const choreo_msgs::TaskSequenceProcessingGoalConstPtr &goal_in)
465 {
466  switch (goal_in->action)
467  {
468  // TODO: this action goal here should indicate what type of assembly process: picknplace, 3d extrusion, etc.
469  case choreo_msgs::TaskSequenceProcessingGoal::FIND_AND_PROCESS:
470  {
471  task_sequence_processing_feedback_.last_completed = "[Core] Recieved request to process task sequence plan\n";
473 
474  // call task_sequence_processing srv
475  choreo_msgs::TaskSequenceProcessing srv;
476 
477  // TODO: MAGIC SWITCH!!
478  // TODO: this process type should be a part of MODEL param
479  srv.request.action = srv.request.SPATIAL_EXTRUSION;
480 // srv.request.action = srv.request.PICKNPLACE;
481 
482  srv.request.model_params = model_input_params_;
483  srv.request.task_sequence_params = task_sequence_input_params_;
484  srv.request.world_frame = world_frame_;
485 
487  {
488  ROS_WARN_STREAM("[Core] Unable to call task sequence processing service or find saved task sequence.");
489  task_sequence_processing_feedback_.last_completed = "[Core] Failed to parse saved task sequence!\n";
491  task_sequence_processing_result_.succeeded = false;
493  }
494  else
495  {
496  // take srv output, save them
497  task_sequence_processing_feedback_.last_completed = "Finished task sequence processing. Visualizing...\n";
499 
500  if(srv.request.PICKNPLACE == srv.request.action)
501  {
502  // TODO: insert new setData function for visual tools here
503  visual_tools_.setAssemblySequencePickNPlace(srv.response.assembly_sequence_pnp);
505 
506  as_pnp_ = srv.response.assembly_sequence_pnp;
507 
508  task_sequence_processing_result_.assembly_type = as_pnp_.assembly_type;
509 
510  // set core service's assembly type
512  }
513 
514  if(srv.request.SPATIAL_EXTRUSION == srv.request.action)
515  {
516  // TODO: this is kept here for archive, should be made compatible to new json data type and visualizer
517  // import data into visual_tools (data initialization)
518  visual_tools_.setProcessPath(srv.response.process);
520 
521  // save the parsed data to class variables (later used in generateProcessPlan call)
522  task_sequence_ = srv.response.process;
523  env_objs_ = srv.response.env_collision_objs;
524 
525  // TODO: this is hardcoded temporarily
527 
529  }
530 
531  task_sequence_processing_result_.succeeded = true;
532 
534  }
535  break;
536  }
537  default:
538  {
539  // NOT SUPPORTING OTHER ACTION GOAL NOW
540  ROS_ERROR_STREAM("Unknown action code '" << goal_in->action << "' request");
541  task_sequence_processing_result_.succeeded = false;
543  break;
544  }
545  }
546 }
547 
548 void ChoreoCoreService::taskSequencePlanningActionCallback(const choreo_msgs::TaskSequencePlanningGoalConstPtr &goal_in)
549 {
550  task_sequence_planning_feedback_.last_completed = "[Core] Recieved request to process task sequence plan\n";
552 
553  // TODO: not supporting seq planning for picknplace
554  // call task_sequence_planning srv
555  choreo_msgs::TaskSequencePlanning srv;
556  srv.request.action = srv.request.READ_WIREFRAME;
557  srv.request.model_params = model_input_params_;
558  srv.request.task_sequence_params = task_sequence_input_params_;
559 
561  {
562  ROS_WARN_STREAM("[Core] task sequence planning service read wireframe failed.");
563  task_sequence_planning_feedback_.last_completed = "[Core] task sequence planning service read wireframe failed!\n";
565  task_sequence_planning_result_.succeeded = false;
567  }
568  else
569  {
570  // import data into visual_tools
571  visual_tools_.setVisualWireFrame(srv.response.element_array);
572 
574 
575  srv.request.action = srv.request.TASK_SEQUENCE_SEARCHING;
576 
578  {
579  ROS_WARN_STREAM("[Core] task sequence planning service seq search failed.");
580  task_sequence_planning_feedback_.last_completed =
581  "[Core] task sequence planning service read seq search failed!\n";
583  task_sequence_planning_result_.succeeded = false;
585  }
586  else
587  {
588  // take srv output, save them
589  task_sequence_planning_feedback_.last_completed = "Finished task sequence planning.\n";
591 
592  task_sequence_planning_result_.succeeded = true;
594  }
595  }
596 }
597 
598 void ChoreoCoreService::processPlanningActionCallback(const choreo_msgs::ProcessPlanningGoalConstPtr &goal_in)
599 {
600  switch (goal_in->action)
601  {
602  case choreo_msgs::ProcessPlanningGoal::GENERATE_MOTION_PLAN_AND_PREVIEW:
603  {
604  process_planning_feedback_.last_completed = "Recieved request to generate motion plan\n";
606 
607  selected_task_id_ = goal_in->index;
608  use_saved_graph_ = goal_in->use_saved_graph;
609 
610  // reset Robot's pose to init pose
612  {
613  process_planning_feedback_.last_completed = "Reset to init robot's pose planning & execution failed\n";
615  process_planning_result_.succeeded = false;
617  return;
618  }
619 
621 
623  {
624  assert(as_pnp_.sequenced_elements.size() > 0);
626  }
627 
629  {
630  // TODO: this is only used for spatial extrusion
631  visual_tools_.visualizePathUntil(goal_in->index);
632  visual_tools_.visualizeFeasibleOrientations(goal_in->index, false);
633  }
634 
635  bool success = generateMotionLibrary(goal_in->index, trajectory_library_);
636 
637  if(success)
638  {
639  process_planning_feedback_.last_completed = "Finished planning. Visualizing...\n";
641  process_planning_result_.succeeded = true;
643 
644  return;
645  }
646  else
647  {
648  process_planning_feedback_.last_completed = "Process Planning action failed.\n";
650  process_planning_result_.succeeded = false;
652  }
653  break;
654  }
655  default:
656  {
657  ROS_ERROR_STREAM("[Core] Unknown action code '" << goal_in->action << "' request");
658  break;
659  }
660  }
661 }
662 
663 //namespace{
664 //void appendTrajectoryHeaders(const trajectory_msgs::JointTrajectory &orig_traj,
665 // trajectory_msgs::JointTrajectory &traj,
666 // const double sim_time_scale)
667 //{
668 // traj.joint_names = orig_traj.joint_names;
669 // traj.header.frame_id = orig_traj.header.frame_id;
670 // traj.header.stamp = orig_traj.header.stamp + orig_traj.points.back().time_from_start;
671 //
672 // // set time_from_start relative to first point
673 // ros::Duration base_time = traj.points[0].time_from_start;
674 //
675 // for (int i = 0; i < traj.points.size(); i++)
676 // {
677 // traj.points[i].time_from_start -= base_time;
678 //
679 // //sim speed tuning
680 // traj.points[i].time_from_start *= sim_time_scale;
681 // }
682 //}
683 //}
684 //
685 //void ChoreoCoreService::adjustSimSpeed(double sim_speed)
686 //{
687 // // global time_stamp rescale
688 // trajectory_msgs::JointTrajectory last_filled_jts = trajectory_library_.get().begin()->second.sub_process_array[0].joint_array;
689 //
690 // // shift first jts array
691 // for (int i = 0; i < last_filled_jts.points().size(); i++)
692 // {
693 // last_filled_jts.points[i].time_from_start *= sim_speed;
694 // }
695 //
696 // // inline function for append trajectory headers (adjust time frame)
697 // void adjustTrajectoryHeaders = [sim_speed](trajectory_msgs::JointTrajectory& last_filled_jts, choreo_msgs::SubProcess& sp)
698 // {
699 // appendTrajectoryHeaders(last_filled_jts, sp.joint_array, sim_speed);
700 // last_filled_jts = sp.joint_array;
701 // };
702 //
703 // for(auto it = trajectory_library_.get().begin(); it != trajectory_library_.get().end(); ++it)
704 // {
705 // for (size_t j = 0; j < it->second.sub_process_array.size(); j++)
706 // {
707 // adjustTrajectoryHeaders(last_filled_jts, it->second.sub_process_array[j]);
708 // }
709 // }
710 //}
711 
712 void ChoreoCoreService::simulateMotionPlansActionCallback(const choreo_msgs::SimulateMotionPlanGoalConstPtr& goal_in)
713 {
714  switch (goal_in->action)
715  {
716  case choreo_msgs::SimulateMotionPlanGoal::RESET_TO_DEFAULT_POSE:
717  {
719  {
720  ROS_ERROR("[Core] Reset to init robot's pose planning & execution failed");
721  simulate_motion_plan_result_.code = choreo_msgs::SimulateMotionPlanResult::RESET_POSE_FAIL;
723  }
724  else
725  {
726  simulate_motion_plan_result_.code = choreo_msgs::SimulateMotionPlanResult::SUCCESS;
728  }
729 
730  break;
731  }
732  case choreo_msgs::SimulateMotionPlanGoal::SINGLE_PATH_RUN:
733  case choreo_msgs::SimulateMotionPlanGoal::ALL_PATHS_UNTIL_SELECTED_RUN:
734  {
735  std::string lib_sort_id = std::to_string(goal_in->index);
736 
737  // If plan does not exist, abort and return
738  if (trajectory_library_.get().find(lib_sort_id) == trajectory_library_.get().end())
739  {
740  ROS_WARN_STREAM("[Core] Motion plan #" << lib_sort_id << " does not exist. Cannot execute.");
741  simulate_motion_plan_result_.code = choreo_msgs::SimulateMotionPlanResult::NO_SUCH_NAME;
743  return;
744  }
745  else
746  {
747  ROS_INFO_STREAM("[Core] Motion plan #" << lib_sort_id << " found");
748  }
749 
750  if (0 == goal_in->index)
751  {
752  // reset Robot's pose to init pose
754  {
755  ROS_ERROR("[Core] Reset to init robot's pose planning & execution failed");
756  simulate_motion_plan_result_.code = choreo_msgs::SimulateMotionPlanResult::RESET_POSE_FAIL;
758  }
759  }
760 
761  // Send command to execution server
762  choreo_msgs::ProcessExecutionGoal goal;
763  ros::Duration process_time(0);
764 
765  for (auto sp : trajectory_library_.get()[lib_sort_id].sub_process_array)
766  {
767  goal.joint_traj_array.push_back(sp.joint_array);
768  process_time += sp.joint_array.points.back().time_from_start;
769  }
770 
771  goal.wait_for_execution = goal_in->wait_for_execution;
772  goal.simulate = goal_in->simulate;
773 
774  // communicating with choreo execution gatekeeper server
776  exe_client->sendGoal(goal);
777 
778 // ros::Duration process_time(goal.joint_traj_array.back().points.back().time_from_start);
779  ros::Duration buffer_time(PROCESS_EXE_BUFFER);
780 
782  {
784  }
785 
787  {
788  // TODO: this is only used for spatial extrusion
789  visual_tools_.visualizePathUntil(goal_in->index);
790  }
791 
792  ROS_INFO_STREAM("[Core] Simulation time: " << process_time);
793 
794  if (exe_client->waitForResult(process_time + buffer_time))
795  {
796  simulate_motion_plan_result_.code = choreo_msgs::SimulateMotionPlanResult::SUCCESS;
798  }
799  else
800  {
801  simulate_motion_plan_result_.code = choreo_msgs::SimulateMotionPlanResult::TIMEOUT;
803  }
804 
805  break;
806  }
807  default:
808  {
809  ROS_ERROR_STREAM("[Core] Unknown action code for SimulateMotionPlan " << goal_in->action << "' request");
810  break;
811  }
812  }
813 }
814 
815 int main(int argc, char** argv)
816 {
817  ros::init(argc, argv, "choreo_core_service");
819  spinner.start();
820  ChoreoCoreService core_srv;
821 
822  if (core_srv.init())
823  {
824  ROS_INFO("[Core] choreo core service online.");
825  core_srv.run();
826  }
827 
829 }
static const std::string TASK_SEQUENCE_PLANNING_ACTION_SERVER_NAME
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
ros::ServiceClient task_sequence_processing_srv_client_
choreo_msgs::TaskSequencePlanningFeedback task_sequence_planning_feedback_
static const std::string OUTPUT_SAVE_DIR_INPUT_PARAMS_FILE
bool moveToTargetJointPose(std::vector< double > joint_pose)
static const std::string ELEMENT_NUMBER_REQUEST_SERVICE
void publishFeedback(const FeedbackConstPtr &feedback)
int main(int argc, char **argv)
bool loadModelInputParameters(const std::string &filename)
static const std::string GET_AVAILABLE_PROCESS_PLANS_SERVICE
choreo_msgs::RobotInputParameters default_robot_input_params_
choreo_msgs::TaskSequenceInputParameters default_task_sequence_input_params_
choreo_msgs::OutputSaveDirInputParameters output_save_dir_input_params_
static const std::string TASK_SEQUENCE_PROCESSING_SERVICE
bool generateMotionLibrary(const int selected_path_index, choreo_core_service::TrajectoryLibrary &traj_lib)
static const std::string OUTPUT_PROCESS_PLANS_SERVICE
ros::ServiceClient move_to_pose_client_
static const std::string QUERY_COMPUTATION_RESULT
ros::ServiceServer choreo_parameters_server_
void saveRobotInputParameters(const std::string &filename)
bool loadBoolParam(ros::NodeHandle &nh, const std::string &name, uint8_t &value)
bool fromFile(const std::string &path, T &msg)
bool waitForResult(const ros::Duration &timeout=ros::Duration(0, 0))
void simulateMotionPlansActionCallback(const choreo_msgs::SimulateMotionPlanGoalConstPtr &goal_in)
static const std::string PATH_VISUAL_TOPIC
bool sleep() const
bool loadParam(ros::NodeHandle &nh, const std::string &name, T &value)
f
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
ros::ServiceClient process_planning_client_
void setProcessPath(const PathArray &path_array)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
std::vector< moveit_msgs::CollisionObject > env_objs_
static const std::string TASK_SEQUENCE_PLANNING_SERVICE
choreo_core_service::TrajectoryLibrary trajectory_library_
void taskSequencePlanningActionCallback(const choreo_msgs::TaskSequencePlanningGoalConstPtr &goal)
ros::ServiceClient output_processing_client_
#define ROS_WARN(...)
choreo_msgs::TaskSequencePlanningResult task_sequence_planning_result_
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
choreo_msgs::TaskSequenceProcessingFeedback task_sequence_processing_feedback_
static const std::string MODEL_INPUT_PARAMS_FILE
choreo_msgs::OutputSaveDirInputParameters default_output_save_dir_input_params_
void spinner()
actionlib::SimpleActionServer< choreo_msgs::SimulateMotionPlanAction > simulate_motion_plan_server_
choreo_msgs::TaskSequenceProcessingResult task_sequence_processing_result_
static const std::string TASK_SEQUENCE_INPUT_PARAMS_FILE
void init(std::string frame_name, std::string marker_topic, robot_model::RobotModelConstPtr robot_model=robot_model::RobotModelConstPtr())
bool toFile(const std::string &path, const T &msg)
ros::ServiceClient task_sequence_planning_srv_client_
void setAssemblySequencePickNPlace(const choreo_msgs::AssemblySequencePickNPlace &as_pnp)
bool visualizeSelectedPathServerCallback(choreo_msgs::VisualizeSelectedPath::Request &req, choreo_msgs::VisualizeSelectedPath::Response &res)
void setVisualWireFrame(const PathArray &path_array)
static const std::string ASSEMBLY_TYPE_PICKNPLACE
#define ROS_INFO(...)
bool queryComputationResultCallback(choreo_msgs::QueryComputationRecord::Request &req, choreo_msgs::QueryComputationRecord::Response &res)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void saveOutputSaveDirInputParameters(const std::string &filename)
ROSCPP_DECL bool ok()
choreo_msgs::RobotInputParameters robot_input_params_
static const std::string MOVE_TO_TARGET_POSE_SERVICE
choreo_msgs::ModelInputParameters model_input_params_
choreo_visual_tools::ChoreoVisualTools visual_tools_
bool elementNumberRequestServerCallback(choreo_msgs::ElementNumberRequest::Request &req, choreo_msgs::ElementNumberRequest::Response &res)
void processPlanningActionCallback(const choreo_msgs::ProcessPlanningGoalConstPtr &goal)
static const std::string SAVE_DATA_BOOL_PARAM
void taskSequenceProcessingActionCallback(const choreo_msgs::TaskSequenceProcessingGoalConstPtr &goal)
choreo_msgs::TaskSequenceInputParameters task_sequence_input_params_
ros::ServiceServer element_number_sequest_server_
actionlib::SimpleActionClient< choreo_msgs::ProcessExecutionAction > choreo_exe_client_
bool choreoParametersServerCallback(choreo_msgs::ChoreoParameters::Request &req, choreo_msgs::ChoreoParameters::Response &res)
static const std::string VISUALIZE_SELECTED_PATH_SERVICE
#define ROS_WARN_STREAM(args)
static const std::string PROCESS_PLANNING_ACTION_SERVER_NAME
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
void visualizeGraspPickNPlace(int index, int grasp_id, bool visualize_ee)
actionlib::SimpleActionServer< choreo_msgs::ProcessPlanningAction > process_planning_server_
ros::ServiceServer query_computation_result_server_
void sendGoal(const Goal &goal, SimpleDoneCallback done_cb=SimpleDoneCallback(), SimpleActiveCallback active_cb=SimpleActiveCallback(), SimpleFeedbackCallback feedback_cb=SimpleFeedbackCallback())
void saveModelInputParameters(const std::string &filename)
bool loadOutputSaveDirInputParameters(const std::string &filename)
#define ROS_INFO_STREAM(args)
bool outputProcessPlansCallback(choreo_msgs::OutputProcessPlans::Request &req, choreo_msgs::OutputProcessPlans::Response &res)
bool getAvailableProcessPlansCallback(choreo_msgs::GetAvailableProcessPlans::Request &req, choreo_msgs::GetAvailableProcessPlans::Response &res)
void saveTaskSequenceInputParameters(const std::string &filename)
static const std::string ROBOT_INPUT_PARAMS_FILE
choreo_msgs::ProcessPlanningFeedback process_planning_feedback_
actionlib::SimpleActionServer< choreo_msgs::TaskSequenceProcessingAction > task_sequence_processing_server_
void visualizeFeasibleOrientations(int index, bool solid)
static const std::string ASSEMBLY_TYPE_SPATIAL_EXTRUSION
actionlib::SimpleActionServer< choreo_msgs::TaskSequencePlanningAction > task_sequence_planning_server_
static const std::string FRAMEFAB_PARAMETERS_SERVICE
static const std::string SIMULATE_MOTION_PLAN_ACTION_SERVER_NAME
ros::ServiceServer get_available_process_plans_server_
void visualizeSequencePickNPlaceUntil(int index)
static const std::string SAVE_LOCATION_PARAM
choreo_msgs::ModelInputParameters default_model_input_params_
static const std::string PICKNPLACE_PLANNING_SERVICE
static const std::string TASK_SEQUENCE_PROCESSING_ACTION_SERVER_NAME
#define ROS_ERROR_STREAM(args)
choreo_msgs::ProcessPlanningResult process_planning_result_
ros::ServiceServer output_process_plans_server_
choreo_msgs::SimulateMotionPlanResult simulate_motion_plan_result_
int checkSavedLadderGraphSize(const std::string &filename)
std::vector< choreo_msgs::ElementCandidatePoses > task_sequence_
static const std::string PROCESS_PLANNING_SERVICE
#define ROS_ERROR(...)
bool loadTaskSequenceInputParameters(const std::string &filename)
static const std::string FRAMEFAB_EXE_ACTION_SERVER_NAME
ros::ServiceServer visualize_selected_path_server_
bool loadRobotInputParameters(const std::string &filename)
static const int PROCESS_EXE_BUFFER
std::string param_cache_prefix_
ROSCPP_DECL void waitForShutdown()
static const std::string PRINT_BED_VISUAL_TOPIC
choreo_msgs::AssemblySequencePickNPlace as_pnp_
static const std::string OUTPUT_PROCESSING_SERVICE


choreo_core
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:38