SeqAnalyzer.cpp
Go to the documentation of this file.
1 #include <ros/console.h>
2 
4 
5 // planning scene
7 
8 // msgs
9 #include <moveit_msgs/CollisionObject.h>
10 #include <moveit_msgs/PlanningSceneComponents.h>
11 #include <moveit_msgs/PlanningScene.h>
12 
13 // srv
14 #include <moveit_msgs/GetPlanningScene.h>
15 
16 // msg-eigen conversion
18 
19 const static std::string GET_PLANNING_SCENE_SERVICE = "get_planning_scene";
20 const static double ROBOT_KINEMATICS_CHECK_TIMEOUT = 10.0;
21 const double STATEMAP_UPDATE_DISTANCE = 300; // mm
22 
23 namespace{
24 // copy from graph_builder.cpp
25 // Generate evenly sampled point at some discretization 'ds' between start and stop.
26 // ds must be > 0
27 std::vector<Eigen::Vector3d> discretizePositions(const Eigen::Vector3d& start, const Eigen::Vector3d& stop, const double ds)
28 {
29  double dist = (stop - start).norm();
30 
31  size_t n_intermediate_points = 0;
32  if (dist > ds)
33  {
34  n_intermediate_points = static_cast<size_t>(std::lround(dist / ds));
35  }
36 
37  const auto total_points = 2 + n_intermediate_points;
38 
39  std::vector<Eigen::Vector3d> result;
40  result.reserve(total_points);
41 
42  for (std::size_t i = 0; i < total_points; ++i)
43  {
44  const double r = i / static_cast<double>(total_points - 1);
45  Eigen::Vector3d point = start + (stop - start) * r;
46  result.push_back(point);
47  }
48  return result;
49 }
50 
51 // copy from descartes_planner::graph_builder.cpp
52 Eigen::Affine3d makePose(const Eigen::Vector3d& position, const Eigen::Matrix3d& orientation,
53  const double z_axis_angle)
54 {
55  Eigen::Affine3d m = Eigen::Affine3d::Identity();
56  m.matrix().block<3,3>(0,0) = orientation;
57  m.matrix().col(3).head<3>() = position;
58 
59  Eigen::AngleAxisd z_rot (z_axis_angle, Eigen::Vector3d::UnitZ());
60 
61  return m * z_rot;
62 }
63 
64 // copy from descartes_planner::capsulated_ladder_tree_RRTstar
65 static int randomSampleInt(int lower, int upper)
66 {
67  std::random_device rd;
68  std::mt19937 gen(rd());
69 
70  if(upper > lower)
71  {
72  std::uniform_int_distribution<int> int_distr(0, upper);
73  return int_distr(gen);
74  }
75  else
76  {
77  return lower;
78  }
79 }
80 
81 static double randomSampleDouble(double lower, double upper)
82 {
83  std::random_device rd;
84  std::mt19937 gen(rd());
85 
86  if(upper > lower)
87  {
88  std::uniform_real_distribution<double> double_distr(lower, upper);
89  return double_distr(gen);
90  }
91  else
92  {
93  return lower;
94  }
95 }
96 
97 std::vector<Eigen::Affine3d> generateSampleEEFPoses(
98  const std::vector<Eigen::Vector3d>& path_pts,
99  const std::vector<Eigen::Matrix3d>& direction_list)
100 {
101  // sample int for orientation
102  int o_sample = randomSampleInt(0, direction_list.size()-1);
103  Eigen::Matrix3d orientation_sample = direction_list[o_sample];
104 
105  // sample [0,1] for axis, z_axis_angle = b_rand * 2 * Pi
106  double x_axis_sample = randomSampleDouble(0.0, 1.0) * 2 * M_PI;
107 
108  std::vector<Eigen::Affine3d> poses;
109  poses.reserve(path_pts.size());
110 
111  for(const auto& pt : path_pts)
112  {
113  poses.push_back(makePose(pt, orientation_sample, x_axis_sample));
114  }
115 
116  return poses;
117 }
118 
119 void convertOrientationVector(
120  const std::vector<Eigen::Vector3d>& vec_orients,
121  std::vector<Eigen::Matrix3d>& m_orients)
122 {
123  m_orients.clear();
124 
125  for(auto eigen_vec : vec_orients)
126  {
127  // eigen_vec = local z axis
128  eigen_vec *= -1.0;
129  eigen_vec.normalize();
130 
131  // construct local x axis & y axis
132  Eigen::Vector3d candidate_dir = Eigen::Vector3d::UnitX();
133  if ( std::abs(eigen_vec.dot(Eigen::Vector3d::UnitX())) > 0.8 )
134  {
135  // if z axis = UnitX,
136  candidate_dir = Eigen::Vector3d::UnitY();
137  }
138 
139  Eigen::Vector3d y_vec = eigen_vec.cross(candidate_dir).normalized();
140 
141  Eigen::Vector3d x_vec = y_vec.cross(eigen_vec).normalized();
142 
143  // JM
144  Eigen::Matrix3d m = Eigen::Matrix3d::Identity();
145  m.col(0) = x_vec;
146  m.col(1) = y_vec;
147  m.col(2) = eigen_vec;
148 
149  m_orients.push_back(m);
150  }
151 }
152 
153 }// util namespace
154 
156  DualGraph *ptr_dualgraph,
157  QuadricCollision *ptr_collision,
158  Stiffness *ptr_stiffness,
159  FiberPrintPARM *ptr_parm,
160  char *ptr_path,
161  bool terminal_output,
162  bool file_output,
163  descartes_core::RobotModelPtr hotend_model,
164  moveit::core::RobotModelConstPtr moveit_model,
165  std::string hotend_group_name
166 ) noexcept
167 {
168  ptr_frame_ = ptr_dualgraph->ptr_frame_;
169  ptr_dualgraph_ = ptr_dualgraph;
170  ptr_collision_ = ptr_collision;
171  ptr_stiffness_ = ptr_stiffness;
172  ptr_path_ = ptr_path;
173 
174  ptr_wholegraph_ = new DualGraph(ptr_frame_);
175 
176  Wp_ = ptr_parm->Wp_;
177  Wa_ = ptr_parm->Wa_;
178  Wi_ = ptr_parm->Wi_;
179  D_tol_ = ptr_parm->seq_D_tol_;
180 
181  Nd_ = 0;
182 
183  terminal_output_ = terminal_output;
184  file_output_ = file_output;
185 
186  update_collision_ = true;
187  search_rerun_ = 0;
188 
189  hotend_model_ = hotend_model;
190  moveit_model_ = moveit_model;
191  hotend_group_name_ = hotend_group_name;
192 }
193 
195 {
196  delete ptr_wholegraph_;
197  ptr_wholegraph_ = NULL;
198 }
199 
201 {
202  return false;
203 }
204 
205 bool SeqAnalyzer::SeqPrintLayer(std::vector<int> layer_id)
206 {
207  return false;
208 }
209 
211 {
212 }
213 
215 {
218 
219  D0_.resize(0);
220  D0_.setZero();
221 
222  print_queue_.clear();
223 
224  angle_state_.clear();
225  angle_state_.resize(Nd_);
226  for(int i = 0; i < Nd_; i++)
227  {
229  }
230 
231  ptr_dualgraph_->Init();
232 
233  // init base planning scene
234  ros::NodeHandle nh;
235  auto planning_scene_client = nh.serviceClient<moveit_msgs::GetPlanningScene>(GET_PLANNING_SCENE_SERVICE);
236 
237  if(!planning_scene_client.waitForExistence())
238  {
239  ROS_ERROR_STREAM("[ts planning] cannot connect with get planning scene server...");
240  }
241 
242  moveit_msgs::GetPlanningScene srv;
243  srv.request.components.components =
244  moveit_msgs::PlanningSceneComponents::ROBOT_STATE
245  | moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
246 
247  if(!planning_scene_client.call(srv))
248  {
249  ROS_ERROR_STREAM("[ts planning] Failed to fetch planning scene srv!");
250  }
251 
252  planning_scene_ = planning_scene::PlanningScenePtr(new planning_scene::PlanningScene(moveit_model_));
253  planning_scene_->getCurrentStateNonConst().setToDefaultValues();
254  planning_scene_->getCurrentStateNonConst().update();
255 
256  planning_scene_->setPlanningSceneDiffMsg(srv.response.scene);
257 
259  num_backtrack_ = 0;
260 }
261 
263 {
264  /* ranked by x */
265  multimap<double, WF_edge*, std::greater<double>>base_queue;
266  multimap<double, WF_edge*, std::greater<double>>::iterator it;
267  for (int dual_i = 0; dual_i < Nd_; dual_i++)
268  {
270  if (e->isPillar())
271  {
272  point center = e->CenterPos();
273  base_queue.insert(make_pair(center.x(), e));
274  // TODO: enable collision checking and greedy tsp here
275  }
276  }
277 
278  if(terminal_output_)
279  {
280  fprintf(stderr, "Size of base queue: %d, full graph domain pruning in progress.\n", (int)base_queue.size());
281  }
282 
283  for(it = base_queue.begin(); it != base_queue.end(); it++)
284  {
285  WF_edge* e = it->second;
286  print_queue_.push_back(e);
287 
288  ROS_INFO_STREAM("pillar # " << std::distance(base_queue.begin(), it) << " domain pruning.");
289 
290  // update printed graph
292 
293  ROS_INFO_STREAM("collision updated.");
294 
295  // update collision (geometric domain)
296  // tmp is the pruned domain by direct arc consistency pruning
297  vector<vector<lld>> tmp_angle(3);
298  UpdateStateMap(e, tmp_angle);
299 
300  ROS_INFO_STREAM("Domain updated.");
301  ROS_INFO_STREAM("--------");
302  }
303 }
304 
305 void SeqAnalyzer::UpdateStructure(WF_edge *e, bool update_collision)
306 {
307  if(update_collision)
308  {
309  // add full collision obj without shrinking
310  UpdateCollisionObjects(e, false);
311  }
312 
313  int dual_upd = ptr_dualgraph_->UpdateDualization(e);
314 
315  /* modify D0 */
316  if (dual_upd != -1)
317  {
318  int Ns = ptr_dualgraph_->SizeOfFreeFace();
319  D0_.conservativeResize(6 * Ns);
320 
321  /* set initiate value by neighbors */
322  int orig_u = ptr_dualgraph_->v_orig_id(dual_upd);
323  WF_edge *eu = ptr_frame_->GetNeighborEdge(orig_u);
324 
325  VX sum_D(6);
326  sum_D.setZero();
327  int sum = 0;
328 
329  while (eu != NULL)
330  {
331  WF_vert *v = eu->pvert_;
332  int dual_v = ptr_dualgraph_->v_dual_id(v->ID());
333  if (dual_v != -1 && !v->isFixed())
334  {
335  VX tmp_D(6);
336  for (int i = 0; i < 6; i++)
337  {
338  tmp_D[i] = D0_[6 * dual_v + i];
339  }
340  sum_D += tmp_D;
341  sum++;
342  }
343  eu = eu->pnext_;
344  }
345 
346  if (sum != 0)
347  {
348  sum_D /= sum;
349  }
350  for (int i = 0; i < 6; i++)
351  {
352  D0_[6 * (Ns - 1) + i] = sum_D[i];
353  }
354  }
355 }
356 
357 void SeqAnalyzer::RecoverStructure(WF_edge *e, bool update_collision)
358 {
359  int dual_del = ptr_dualgraph_->RemoveUpdation(e);
360 
361  /* modify D0 */
362  if (dual_del != -1)
363  {
364  int Ns = ptr_dualgraph_->SizeOfFreeFace();
365  if (dual_del != Ns)
366  {
367  D0_.block(6 * dual_del, 0, 6 * (Ns - dual_del), 1) =
368  D0_.block(6 * (dual_del + 1), 0, 6 * (Ns - dual_del), 1);
369  }
370  D0_.conservativeResize(6 * Ns);
371  }
372 
373  if(update_collision)
374  {
375  // pop full collision obj without dealing with neighnoring edges
376  RecoverCollisionObjects(e, false);
377  }
378 }
379 
380 void SeqAnalyzer::UpdateStateMap(WF_edge *order_e, vector<vector<lld>> &state_map)
381 {
382  int dual_i = ptr_wholegraph_->e_dual_id(order_e->ID());
383  int Nd = ptr_wholegraph_->SizeOfVertList();
384 
385  for (int dual_j = 0; dual_j < Nd; dual_j++)
386  {
387  WF_edge * target_e = ptr_frame_->GetEdge(ptr_wholegraph_->e_orig_id(dual_j));
388 
389  // for each unprinted edge in wireframe, full graph arc consistency
390  // it makes no sense to prune pillar's domain, since we only allow z-axis for pillar's printing
391  // (and they are printed first)
392  if (dual_i != dual_j && !ptr_dualgraph_->isExistingEdge(target_e) && !target_e->isPillar())
393  {
394  if(target_e->CenterDistanceTo(order_e) > STATEMAP_UPDATE_DISTANCE)
395  {
396  continue;
397  }
398 
399 // if(target_e->Layer() >= 17)
400 // {
401 // continue;
402 // }
403 
404  // prune order_e's domain with target_e's existence
405  // arc consistency pruning
406  vector<lld> tmp(3);
407 
408  if(ptr_collision_->DetectCollision(target_e, order_e, tmp))
409  {
410  for (int k = 0; k < 3; k++)
411  {
412  state_map[k].push_back(angle_state_[dual_j][k]);
413  }
414 
415  ptr_collision_->ModifyAngle(angle_state_[dual_j], tmp);
416  }
417  }
418  }
419 }
420 
421 void SeqAnalyzer::RecoverStateMap(WF_edge* order_e, vector<vector<lld>>& state_map)
422 {
423  int dual_i = ptr_wholegraph_->e_dual_id(order_e->ID());
424  int Nd = ptr_wholegraph_->SizeOfVertList();
425  int p = 0;
426 
427  for(int dual_j = 0; dual_j < Nd; dual_j++)
428  {
429  WF_edge * target_e = ptr_frame_->GetEdge(ptr_wholegraph_->e_orig_id(dual_j));
430 
431  if(dual_i != dual_j && !ptr_dualgraph_->isExistingEdge(target_e) && !target_e->isPillar())
432  {
433  if(target_e->CenterDistanceTo(order_e) > STATEMAP_UPDATE_DISTANCE)
434  {
435  continue;
436  }
437 
438  for(int k = 0; k < 3; k++)
439  {
440  angle_state_[dual_j][k] = state_map[k][p];
441  }
442  p++;
443  }
444  }
445 }
446 
447 std::vector<moveit_msgs::CollisionObject> SeqAnalyzer::UpdateCollisionObjects(WF_edge* e, bool shrink)
448 {
449  int orig_j;
450  if (e->ID() < e->ppair_->ID())
451  {
452  orig_j = e->ID();
453  }
454  else
455  {
456  orig_j = e->ppair_->ID();
457  }
458 
459  assert(orig_j < frame_msgs_.size());
460 
461  std::vector<moveit_msgs::CollisionObject> added_collision_objs;
462 
463  if(!shrink)
464  {
465  // add input edge's collision object
466  moveit_msgs::CollisionObject e_collision_obj;
467  e_collision_obj = frame_msgs_[orig_j].full_collision_object;
468  e_collision_obj.operation = moveit_msgs::CollisionObject::ADD;
469 
470  // add this edge to the planning scene
471  if (!planning_scene_->processCollisionObjectMsg(e_collision_obj))
472  {
473  ROS_WARN_STREAM("[ts planning] Failed to add shrinked collision object: edge #" << orig_j);
474  }
475 
476  added_collision_objs.push_back(e_collision_obj);
477  }
478  else
479  {
480  // st node index
481  int uj = ptr_frame_->GetEndu(orig_j);
482  bool exist_uj = ptr_dualgraph_->isExistingVert(uj);
483 
484  // end node index
485  int vj = ptr_frame_->GetEndv(orig_j);
486  bool exist_vj = ptr_dualgraph_->isExistingVert(vj);
487 
488  std::vector<int> shrink_vert_ids;
489 
490  if (exist_uj)
491  {
492  shrink_vert_ids.push_back(uj);
493  }
494 
495  if (exist_vj)
496  {
497  shrink_vert_ids.push_back(vj);
498  }
499 
500  // query connected & existing edges for these nodes, shrink them
501  for (const auto &connect_vert_id : shrink_vert_ids)
502  {
503  WF_edge *eu = ptr_frame_->GetNeighborEdge(connect_vert_id);
504 
505  while (eu != NULL)
506  {
507  if(eu->ID() == e->ID() || eu->ID() == e->ppair_->ID()
509  {
510  // skip if edge = input edge OR current edge doesn't exist yet
511  eu = eu->pnext_;
512  continue;
513  }
514 
515  // pop the neighnor edge from existing planning scene
516  int ne_id = eu->ID();
517  moveit_msgs::CollisionObject ne_collision_obj;
518 
519  // replace with shrinked ones
520  if(connect_vert_id == eu->ppair_->pvert_->ID())
521  {
522  ne_collision_obj = frame_msgs_[ne_id].st_shrinked_collision_object;
523  }
524 
525  if(connect_vert_id == eu->pvert_->ID())
526  {
527  ne_collision_obj = frame_msgs_[ne_id].end_shrinked_collision_object;
528  }
529 
530  // Adds the object to the planning scene. If the object previously existed, it is replaced.
531  ne_collision_obj.operation = moveit_msgs::CollisionObject::ADD;
532 
533  if (!planning_scene_->processCollisionObjectMsg(ne_collision_obj))
534  {
535  ROS_WARN_STREAM("[ts planning] Update collision Obj:"
536  << " Failed to add collision object (shrinked neighnor): edge #" << orig_j);
537  }
538 
539  added_collision_objs.push_back(ne_collision_obj);
540 
541  eu = eu->pnext_;
542  }
543  }
544  }
545 
546  return added_collision_objs;
547 }
548 
549 std::vector<moveit_msgs::CollisionObject> SeqAnalyzer::RecoverCollisionObjects(WF_edge* e, bool shrink)
550 {
551  int orig_j;
552  if (e->ID() < e->ppair_->ID())
553  {
554  orig_j = e->ID();
555  }
556  else
557  {
558  orig_j = e->ppair_->ID();
559  }
560 
561  assert(orig_j < frame_msgs_.size());
562 
563  std::vector<moveit_msgs::CollisionObject> recovered_collision_objs;
564 
565  if(!shrink)
566  {
567  // add input edge's collision object
568  moveit_msgs::CollisionObject e_collision_obj;
569  e_collision_obj = frame_msgs_[orig_j].full_collision_object;
570  e_collision_obj.operation = moveit_msgs::CollisionObject::REMOVE;
571 
572  // add this edge to the planning scene
573  if (!planning_scene_->processCollisionObjectMsg(e_collision_obj))
574  {
575  ROS_WARN_STREAM("[ts planning] Remove collision obj"
576  << "Failed to remove full collision object: edge #" << orig_j);
577  }
578 
579  recovered_collision_objs.push_back(e_collision_obj);
580  }
581  else
582  {
583  // st node index
584  int uj = ptr_frame_->GetEndu(orig_j);
585  bool exist_uj = ptr_dualgraph_->isExistingVert(uj);
586 
587  // end node index
588  int vj = ptr_frame_->GetEndv(orig_j);
589  bool exist_vj = ptr_dualgraph_->isExistingVert(vj);
590 
591  std::vector<int> shrink_vert_ids;
592 
593  if (exist_uj)
594  {
595  shrink_vert_ids.push_back(uj);
596  }
597 
598  if (exist_vj)
599  {
600  shrink_vert_ids.push_back(vj);
601  }
602 
603  // query connected & existing edges for these nodes, shrink them
604  for (const auto &connect_vert_id : shrink_vert_ids)
605  {
606  WF_edge *eu = ptr_frame_->GetNeighborEdge(connect_vert_id);
607 
608  while (eu != NULL)
609  {
610  if(eu->ID() == e->ID() || eu->ID() == e->ppair_->ID()
612  {
613  eu = eu->pnext_;
614  continue;
615  }
616 
617  // pop the neighnor edge from existing planning scene
618  // Adds the object to the planning scene. If the object previously existed, it is replaced.
619  int ne_id = eu->ID();
620  moveit_msgs::CollisionObject ne_collision_obj;
621  ne_collision_obj = frame_msgs_[ne_id].full_collision_object;
622  ne_collision_obj.operation = moveit_msgs::CollisionObject::ADD;
623 
624  if (!planning_scene_->processCollisionObjectMsg(ne_collision_obj))
625  {
626  ROS_WARN_STREAM("[ts planning] Remove collision obj:"
627  << "Failed to replace collision object (shrinked neighnor): edge #" << orig_j);
628  }
629 
630  recovered_collision_objs.push_back(ne_collision_obj);
631 
632  eu = eu->pnext_;
633  }
634  }
635  }
636 
637  return recovered_collision_objs;
638 }
639 
641 {
642  /* insert a trail edge */
643  UpdateStructure(e, false);
644 
645  /* examinate stiffness on printing subgraph */
646  ptr_stiffness_->Init();
647 
648  int Ns = ptr_dualgraph_->SizeOfFreeFace();
649  VX D(Ns * 6);
650  D.setZero();
651 
652  bool bSuccess = ptr_stiffness_->CalculateD(D);
653 
654  if (bSuccess)
655  {
656  for (int k = 0; k < Ns; k++)
657  {
658  VX offset(3);
659  for (int t = 0; t < 3; t++)
660  {
661  offset[t] = D[k * 6 + t];
662  }
663 
664  if (offset.norm() >= D_tol_)
665  {
666  //printf("$$$Stiffness offset: %lf\n", offset.norm());
667  bSuccess = false;
668  break;
669  }
670  }
671  }
672 
673  D0_ = D;
674 
675  /* remove the trail edge */
676  RecoverStructure(e, false);
677 
678  return bSuccess;
679 }
680 
681 bool SeqAnalyzer::TestRobotKinematics(WF_edge* e, const std::vector<lld>& colli_map)
682 {
683  // insert a trail edge, needs to shrink neighnoring edges
684  // to avoid collision check between end effector and elements
685  bool b_success = false;
686  UpdateCollisionObjects(e, true);
687 
688  // st node index
689  int orig_j = e->ID();
690  // ppair vert
691  int uj = ptr_frame_->GetEndu(orig_j);
692  bool exist_uj = ptr_dualgraph_->isExistingVert(uj);
693 
694  // end node index
695  // pvert
696  int vj = ptr_frame_->GetEndv(orig_j);
697  bool exist_vj = ptr_dualgraph_->isExistingVert(vj);
698 
699  auto planning_scene_depart = planning_scene_->diff();
700  moveit_msgs::CollisionObject e_collision_obj;
701  e_collision_obj = frame_msgs_[e->ID()].both_side_shrinked_collision_object;
702  e_collision_obj.operation = moveit_msgs::CollisionObject::ADD;
703 
704  // add this edge to the planning scene
705  if (!planning_scene_depart->processCollisionObjectMsg(e_collision_obj))
706  {
707  ROS_WARN_STREAM("[ts planning robot kinematics] Failed to add shrinked collision object: edge #" << e->ID());
708  }
709 
710  // generate feasible end effector directions for printing edge e
711  std::vector<Eigen::Vector3d> direction_vec_list =
713  std::vector<Eigen::Matrix3d> direction_matrix_list;
714  convertOrientationVector(direction_vec_list, direction_matrix_list);
715 
716  // generate eef path points
717  Eigen::Vector3d st_pt;
718  Eigen::Vector3d end_pt;
719 
720  // for creation type, name the existing vert as start pt
721  // for connection type, it doesn't matter which one is the start
722  if(exist_uj)
723  {
724  tf::pointMsgToEigen(frame_msgs_[e->ID()].start_pt, st_pt);
725  tf::pointMsgToEigen(frame_msgs_[e->ID()].end_pt, end_pt);
726  }
727  else
728  {
729  tf::pointMsgToEigen(frame_msgs_[e->ID()].end_pt, st_pt);
730  tf::pointMsgToEigen(frame_msgs_[e->ID()].start_pt, end_pt);
731  }
732 
733  std::vector<Eigen::Vector3d> path_pts = discretizePositions(st_pt, end_pt, 0.005);
734 
735 // ROS_INFO_STREAM("path pts size: " << path_pts.size());
736 
737  const auto check_start_time = ros::Time::now();
738 
739  while((ros::Time::now() - check_start_time).toSec() < ROBOT_KINEMATICS_CHECK_TIMEOUT * (search_rerun_ + 1))
740  {
741  std::vector<Eigen::Affine3d> poses = generateSampleEEFPoses(path_pts, direction_matrix_list);
742 
743  bool empty_joint_pose_found = false;
744 
745  for(std::size_t c_id=0; c_id < poses.size(); c_id++)
746  {
747  std::vector<std::vector<double>> joint_poses;
748 
749  if(c_id < poses.size() - 1)
750  {
751  hotend_model_->setPlanningScene(planning_scene_);
752  }
753  else
754  {
755  hotend_model_->setPlanningScene(planning_scene_depart);
756  }
757 
758  if(!hotend_model_->getAllIK(poses[c_id], joint_poses))
759  {
760  empty_joint_pose_found = true;
761  break;
762  }
763  }
764 
765  if(!empty_joint_pose_found)
766  {
767  // all poses have feasible joint pose
768  b_success = true;
769  break;
770  }
771  else
772  {
773  b_success = false;
774  continue;
775  }
776  }
777 
778  // remove the trail edge, change shrinked edges back to full collision objects
779  RecoverCollisionObjects(e, true);
780  return b_success;
781 }
782 
784 {
785  int orig_j = e->ID();
786 
787  // st node index
788  int uj = ptr_frame_->GetEndu(orig_j);
789  const trimesh::point uj_pt = ptr_frame_->GetVert(uj)->Position();
790  bool exist_uj = ptr_dualgraph_->isExistingVert(uj);
791 
792  // end node index
793  int vj = ptr_frame_->GetEndv(orig_j);
794  const trimesh::point vj_pt = ptr_frame_->GetVert(vj)->Position();
795  bool exist_vj = ptr_dualgraph_->isExistingVert(vj);
796 
797  if (e->isPillar())
798  {
799  if(uj_pt.z() > vj_pt.z())
800  {
801  return e->ppair_;
802  }
803 
804  return e;
805  }
806 
807  if(exist_uj & exist_vj)
808  {
809  // connect case
810  int endu_valence = 0;
811  int endv_valence = 0;
812 
815 
816  endu_valence = ptr_dualgraph_->getExistingVertValence(uj);
817  endv_valence = ptr_dualgraph_->getExistingVertValence(vj);
818 
819  if (endv_valence > endu_valence)
820  {
821  return e->ppair_;
822  }
823 
824  if(endv_valence == endu_valence)
825  {
826  // valence equals case: use nearest node
827  if (prev_e)
828  {
829  trimesh::point prev_end_node = prev_e->pvert_->Position();
830 
831  // use previous end point as start node if possible
832  // i.e. prefer continuous printing
833  if (prev_end_node == uj_pt || prev_end_node == vj_pt)
834  {
835  if (prev_end_node == vj_pt)
836  {
837  return e->ppair_;
838  }
839  //else start node already agrees with prev_end_node, then keep rolling!
840  }
841  else
842  {
843  // we prefer the start node to be close
844  if (trimesh::dist(vj_pt, prev_end_node) < trimesh::dist(uj_pt, prev_end_node))
845  {
846  return e->ppair_;
847  }
848  }
849  }
850  }
851 
852  return e;
853  }
854  else
855  {
856  // create case
857  assert(exist_uj || exist_vj);
858 
859  if(exist_vj)
860  {
861  // change direction
862  return e->ppair_;
863  }
864 
865  return e;
866  }
867 }
868 
869 bool SeqAnalyzer::InputPrintOrder(const std::vector<int>& print_queue)
870 {
871  print_queue_.clear();
872 
873  int Nq = print_queue.size();
874  for (int i = 0; i < Nq; i++)
875  {
876  WF_edge *e = ptr_frame_->GetEdge(print_queue[i]);
877  if (e == NULL)
878  {
879  print_queue_.clear();
880  return false;
881  }
882  print_queue_.push_back(e);
883  }
884 
885  return true;
886 }
887 
888 bool SeqAnalyzer::ConstructCollisionObjsInQueue(const std::vector<int>& print_queue_edge_ids,
889  std::vector<choreo_msgs::WireFrameCollisionObject>& collision_objs)
890 {
891  // notice that init clear the print_queue_
892  Init();
893 
894  if(!InputPrintOrder(print_queue_edge_ids))
895  {
896  ROS_ERROR_STREAM("[ts planner] edge id error, not matched to wire frame id. "
897  << "Please re-run sequence planner to re-generate sequence result.");
898  return false;
899  }
900 
901  collision_objs.clear();
902  collision_objs.resize(print_queue_.size());
903 
904  for (int i = 0; i < print_queue_.size(); i++)
905  {
906  WF_edge* e = print_queue_[i];
907 
908  if(i > 0)
909  {
910  collision_objs[i].recovered_last_neighbor_objs = RecoverCollisionObjects(print_queue_[i-1], true);
911 
912  moveit_msgs::CollisionObject last_e_collision_obj;
913  last_e_collision_obj = frame_msgs_[print_queue_[i-1]->ID()].full_collision_object;
914  collision_objs[i].last_full_obj = last_e_collision_obj;
915  }
916 
917  collision_objs[i].shrinked_neighbor_objs = UpdateCollisionObjects(e, true);
918 
919  moveit_msgs::CollisionObject e_collision_obj;
920 
921  e_collision_obj = frame_msgs_[e->ID()].full_collision_object;
922  collision_objs[i].full_obj = e_collision_obj;
923 
924  e_collision_obj = frame_msgs_[e->ID()].both_side_shrinked_collision_object;
925  collision_objs[i].both_side_shrinked_obj = e_collision_obj;
926 
928  }
929 
930  return true;
931 }
932 
933 void SeqAnalyzer::OutputPrintOrder(vector<WF_edge*> &print_queue)
934 {
935  print_queue.clear();
936 
937  int Nq = print_queue_.size();
938  for (int i = 0; i < Nq; i++)
939  {
940  print_queue.push_back(print_queue_[i]);
941  }
942 }
943 
944 void SeqAnalyzer::OutputTaskSequencePlanningResult(std::vector<SingleTaskPlanningResult>& planning_result)
945 {
946  int Nq = print_queue_.size();
947  planning_result.reserve(Nq);
948 
949  for (int i = 0; i < Nq; i++)
950  {
951  WF_edge* e = print_queue_[i];
952 
953  int dual_j = ptr_wholegraph_->e_dual_id(e->ID());
954 
955  std::vector<Eigen::Vector3d> direction_vec_list;
956 
957  if(e->isPillar())
958  {
959  direction_vec_list.push_back(Eigen::Vector3d(0,0,1));
960  }
961  else
962  {
963  assert(angle_state_[dual_j].size() > 0);
964  // generate feasible end effector directions for printing edge e
966  }
967 
968  assert(direction_vec_list.size() > 0);
969 
971  result.e_ = e;
972  result.eef_directions_ = direction_vec_list;
973 
974  planning_result.push_back(result);
975  }
976 }
bool ConstructCollisionObjsInQueue(const std::vector< int > &print_queue_edge_ids, std::vector< choreo_msgs::WireFrameCollisionObject > &collision_objs)
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
descartes_core::RobotModelPtr hotend_model_
Definition: SeqAnalyzer.h:175
bool isFixed() const
Definition: WireFrame.h:83
void UpdateStructure(WF_edge *e, bool update_collision=false)
Stiffness * ptr_stiffness_
Definition: SeqAnalyzer.h:134
bool CalculateD(VX &D, VX *ptr_x=NULL, bool cond_num=false, int file_id=0, string file_name="")
Definition: Stiffness.cpp:407
void ModifyAngle(std::vector< lld > &angle_state, const std::vector< lld > &colli_map)
int num_backtrack_
Definition: SeqAnalyzer.h:182
bool update_collision_
Definition: SeqAnalyzer.h:166
int v_orig_id(int i)
Definition: DualGraph.h:154
virtual bool SeqPrintLayer(std::vector< int > layer_id)
const GLfloat * m
moveit::core::RobotModelConstPtr moveit_model_
Definition: SeqAnalyzer.h:176
WF_edge * GetNeighborEdge(int u)
Definition: WireFrame.h:239
GLuint start
void UpdateStateMap(WF_edge *e, vector< vector< lld >> &state_map)
Eigen::VectorXd VX
Definition: SeqAnalyzer.h:75
void PrintPillars()
void Init()
Definition: Stiffness.cpp:54
WF_edge * pnext_
Definition: WireFrame.h:165
std::vector< moveit_msgs::CollisionObject > UpdateCollisionObjects(WF_edge *e, bool shrink=false)
WF_edge * RouteEdgeDirection(const WF_edge *prev_e, WF_edge *e)
WF_edge * GetEdge(int i)
Definition: WireFrame.h:238
double CenterDistanceTo(WF_edge *ej) const
Definition: WireFrame.h:152
void RecoverStructure(WF_edge *e, bool update_collision=false)
reference x()
Definition: Vec.h:194
bool InputPrintOrder(const std::vector< int > &print_queue)
#define M_PI
bool isExistingVert(int u)
Definition: DualGraph.h:163
bool isPillar() const
Definition: WireFrame.h:125
bool TestifyStiffness(WF_edge *e)
point CenterPos() const
Definition: WireFrame.h:135
std::vector< Eigen::Vector3d > ConvertCollisionMapToEigenDirections(const std::vector< lld > &colli_map)
static const T dist(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:905
WireFrame * ptr_frame_
Definition: SeqAnalyzer.h:132
GLsizeiptr size
vector< vector< unsigned long long > > angle_state_
Definition: SeqAnalyzer.h:151
planning_scene::PlanningScenePtr planning_scene_
Definition: SeqAnalyzer.h:179
int getExistingVertValence(int u)
Definition: DualGraph.h:164
void OutputTaskSequencePlanningResult(std::vector< SingleTaskPlanningResult > &planning_result)
int e_orig_id(int u)
Definition: DualGraph.h:152
virtual bool SeqPrint()
int ID() const
Definition: WireFrame.h:123
SeqAnalyzer(DualGraph *ptr_dualgraph, QuadricCollision *ptr_collision, Stiffness *ptr_stiffness, FiberPrintPARM *ptr_parm, char *ptr_path, bool terminal_output, bool file_output, descartes_core::RobotModelPtr hotend_model, moveit::core::RobotModelConstPtr moveit_model, std::string hotend_group_name) noexcept
WF_edge * ppair_
Definition: WireFrame.h:166
bool DetectCollision(WF_edge *target_e, DualGraph *ptr_subgraph, std::vector< lld > &result_map)
virtual ~SeqAnalyzer()
int SizeOfFreeFace()
Definition: DualGraph.h:148
DualGraph * ptr_wholegraph_
Definition: SeqAnalyzer.h:146
virtual void PrintOutTimer()
void pointMsgToEigen(const geometry_msgs::Point &m, Eigen::Vector3d &e)
gte::BSRational< UIntegerType > abs(gte::BSRational< UIntegerType > const &number)
void Init()
Definition: DualGraph.cpp:28
GLdouble GLdouble t
DualGraph * ptr_dualgraph_
Definition: SeqAnalyzer.h:133
Vector2< Real > center
static const double ROBOT_KINEMATICS_CHECK_TIMEOUT
Definition: SeqAnalyzer.cpp:20
QuadricCollision * ptr_collision_
Definition: SeqAnalyzer.h:135
#define ROS_WARN_STREAM(args)
std::vector< moveit_msgs::CollisionObject > RecoverCollisionObjects(WF_edge *e, bool shrink=false)
std::vector< WF_edge * > print_queue_
Definition: SeqAnalyzer.h:148
int e_dual_id(int u)
Definition: DualGraph.h:153
int RemoveUpdation(WF_edge *e)
Definition: DualGraph.cpp:290
int ID() const
Definition: WireFrame.h:80
int GetEndv(int i) const
Definition: WireFrame.h:245
bool isExistingEdge(WF_edge *e)
Definition: DualGraph.h:165
const GLdouble * v
GLboolean r
bool terminal_output_
Definition: SeqAnalyzer.h:163
WF_vert * pvert_
Definition: WireFrame.h:164
#define ROS_INFO_STREAM(args)
int num_p_assign_visited_
Definition: SeqAnalyzer.h:181
bool TestRobotKinematics(WF_edge *e, const std::vector< lld > &colli_map)
const double STATEMAP_UPDATE_DISTANCE
Definition: SeqAnalyzer.cpp:21
int v_dual_id(int i)
Definition: DualGraph.h:155
int SizeOfVertList()
Definition: DualGraph.h:145
static const std::string GET_PLANNING_SCENE_SERVICE
Definition: SeqAnalyzer.cpp:19
static Time now()
double D_tol_
Definition: SeqAnalyzer.h:157
void Dualization()
Definition: DualGraph.cpp:103
void Init(vector< lld > &colli_map)
int GetEndu(int i) const
Definition: WireFrame.h:244
GLintptr offset
int search_rerun_
Definition: SeqAnalyzer.h:184
void RecoverStateMap(WF_edge *e, vector< vector< lld >> &state_map)
#define ROS_ERROR_STREAM(args)
reference z()
Definition: Vec.h:212
std::vector< choreo_msgs::ElementCandidatePoses > frame_msgs_
Definition: SeqAnalyzer.h:138
void OutputPrintOrder(std::vector< WF_edge * > &print_queue)
GLfloat GLfloat p
GLuint64EXT * result
void UpdateDualization(VectorXd *ptr_x)
Definition: DualGraph.cpp:133
point Position() const
Definition: WireFrame.h:78
WF_vert * GetVert(int u)
Definition: WireFrame.h:237


choreo_task_sequence_planner
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:03:14