FFAnalyzer.cpp
Go to the documentation of this file.
2 
4 {
5 }
6 
8 {
10 
11  Init();
12 
13  ROS_INFO_STREAM("[TSP] FF Analyzer init.");
14 
15  /* split layers */
16  /* label stores layer index of each dual node */
17  int layer_size = ptr_frame_->SizeOfLayer();
18  layers_.clear();
19  layers_.resize(layer_size);
20  for (int i = 0; i < Nd_; i++)
21  {
23  assert(e);
24  layers_[e->Layer()].push_back(e);
25  }
26 
27  int print_until = layer_size;
28 // int print_until = 17;
29 
30  assert(print_until <= layer_size);
31 
32  for (int l = 0; l < print_until; l++)
33  {
34  fprintf(stderr, "Size of layer %d is %d\n", l, (int)layers_[l].size());
35  assert((int)layers_[l].size() != 0);
36  }
37 
38  /* print starting from the first layer */
39  bool bSuccess;
40  for (int l = 0; l < print_until; l++)
41  {
42  /*
43  * Nl: number of dual verts in current layer
44  * h : head for printing queue of the layer
45  * t : tail for printing queue of the layer
46  */
47  int Nl = layers_[l].size();
48  int h = print_queue_.size(); // print queue size so far
49  int t;
50 
51  t = h + Nl;
52 
53  if (h == t)
54  {
55  continue;
56  }
57 
58  /* max_z_ and min_z_ in current layer */
59  min_base_dist_ = min_z_ = 1e20;
60  max_base_dist_ = max_z_ = -1e20;
61 
62  for (int i = 0; i < Nl; i++)
63  {
64  WF_edge* e = layers_[l][i];
65  point u = e->pvert_->Position();
66  point v = e->ppair_->pvert_->Position();
67  min_z_ = min(min_z_, (double)min(u.z(), v.z()));
68  max_z_ = max(max_z_, (double)max(u.z(), v.z()));
69 
70  const auto& st_pt_msg = frame_msgs_[e->ID()].start_pt;
71  const auto& end_pt_msg = frame_msgs_[e->ID()].end_pt;
72 
73  // distance to robot base (world_frame 0,0,0)
74  double dist = sqrt(pow((st_pt_msg.x + end_pt_msg.x)/2, 2)
75  + pow((st_pt_msg.y + end_pt_msg.y)/2, 2)
76  + pow((st_pt_msg.z + end_pt_msg.z)/2, 2));
77 
78 
79  min_base_dist_ = min(min_base_dist_, dist);
80  max_base_dist_ = max(max_base_dist_, dist);
81  }
82 
83  search_rerun_ = 0;
84  bSuccess = false;
85 
86  while(!bSuccess && search_rerun_ < 2)
87  {
88  bSuccess = GenerateSeq(l, h, t);
89  search_rerun_++;
90  }
91 
92  if(!bSuccess)
93  {
94  ROS_ERROR("All possible start edge at layer %d has been tried but no feasible sequence is obtained after %d iterations.", l, search_rerun_);
95  break;
96  }
97  }
98 
99  fprintf(stderr, "\n\nFFAnalyzer seq search finished:\n Number of edges: %d\nNumber of partial assignment visited: %d, Number of backtrack: %d\n\n",
101 
102  FF_analyzer_.Stop();
103  return bSuccess;
104 }
105 
106 bool FFAnalyzer::SeqPrintLayer(std::vector<int> layer_ids)
107 {
108  assert(ptr_frame_->SizeOfLayer()
109  > *std::max_element(layer_ids.begin(), layer_ids.end()));
110 
111  ROS_INFO_STREAM("[TSP] Target layers search test.");
112 
114 
115  Init();
116 
117  ROS_INFO_STREAM("[TSP] FF Analyzer init.");
118 
119  /* split layers */
120  /* label stores layer index of each dual node */
121  int layer_size = ptr_frame_->SizeOfLayer();
122  layers_.clear();
123  layers_.resize(layer_size);
124  for (int i = 0; i < Nd_; i++)
125  {
127  assert(e);
128  layers_[e->Layer()].push_back(e);
129  }
130 
131  for(const int& layer_id : layer_ids)
132  {
133  fprintf(stderr, "Size of target layer %d is %d\n", layer_id, (int)layers_[layer_id].size());
134  }
135 
136  int min_tid = *std::min_element(layer_ids.begin(), layer_ids.end());
137 
138  bool bSuccess = true;
139 
140  for(int l=0; l < min_tid; l++)
141  {
142  std::cout << "layer #" << l << std::endl;
143 
144  for(int s=0; s < layers_[l].size(); s++)
145  {
146  WF_edge* e = layers_[l][s];
147 
148  print_queue_.push_back(e);
149 
150  // update printed graph
152 
153  for(const int& layer_id : layer_ids)
154  {
155  vector <vector<lld>> state_map(3);
156  int dual_i = ptr_wholegraph_->e_dual_id(e->ID());
157 
158  for (int j = 0; j < layers_[layer_id].size(); j++)
159  {
160  WF_edge* target_e = layers_[layer_id][j];
161  int dual_j = ptr_wholegraph_->e_dual_id(target_e->ID());
162 
163  // prune order_e's domain with target_e's existence
164  // arc consistency pruning
165  vector <lld> tmp(3);
166  if (ptr_collision_->DetectCollision(target_e, e, tmp))
167  {
168  for (int k = 0; k < 3; k++)
169  {
170  state_map[k].push_back(angle_state_[dual_j][k]);
171  }
172 
173  ptr_collision_->ModifyAngle(angle_state_[dual_j], tmp);
174  }
175  }
176  } // loop thru target layers
177  }
178  }
179 
180  std::cout << "Update finished." << std::endl;
181 
182  int target_size = 0;
183 
184  for(const int& lb : layer_ids)
185  {
186  // search in target layer
187  int Nl = layers_[lb].size();
188  int h = print_queue_.size(); // print queue size so far
189  int t = h + Nl;
190 
191  target_size += Nl;
192 
193  /* max_z_ and min_z_ in current layer */
194  min_base_dist_ = min_z_ = 1e20;
195  max_base_dist_ = max_z_ = -1e20;
196 
197  for (int i = 0; i < Nl; i++)
198  {
199  WF_edge *e = layers_[lb][i];
200  point u = e->pvert_->Position();
201  point v = e->ppair_->pvert_->Position();
202  min_z_ = min(min_z_, (double) min(u.z(), v.z()));
203  max_z_ = max(max_z_, (double) max(u.z(), v.z()));
204 
205  const auto& st_pt_msg = frame_msgs_[e->ID()].start_pt;
206  const auto& end_pt_msg = frame_msgs_[e->ID()].end_pt;
207 
208  // distance to robot base (world_frame 0,0,0)
209  double dist = sqrt(pow((st_pt_msg.x + end_pt_msg.x)/2, 2)
210  + pow((st_pt_msg.y + end_pt_msg.y)/2, 2)
211  + pow((st_pt_msg.z + end_pt_msg.z)/2, 2));
212 
213  min_base_dist_ = min(min_base_dist_, dist);
214  max_base_dist_ = max(max_base_dist_, dist);
215  }
216 
217  search_rerun_ = 0;
218  bSuccess = false;
219 
220  while(!bSuccess && search_rerun_ < 2)
221  {
222  bSuccess = GenerateSeq(lb, h, t);
223  search_rerun_++;
224  }
225 
226  if(!bSuccess)
227  {
228  ROS_ERROR("All possible start edge at layer %d has been tried but no feasible sequence is obtained after %d iterations.",
229  lb, search_rerun_);
230  break;
231  }
232  }
233 
234  fprintf(stderr, "****Reminder: Start of target layers is %d\n", Nd_ - target_size);
235 
236  FF_analyzer_.Stop();
237  return bSuccess;
238 }
239 
240 bool FFAnalyzer::GenerateSeq(int l, int h, int t)
241 {
242  /* last edge */
243  if(0 != h)
244  {
245  WF_edge *ei = print_queue_[h - 1];
246 
247  if (terminal_output_)
248  {
249  fprintf(stderr, "-----------------------------------\n");
250  fprintf(stderr, "Searching edge #%d in layer %d, head %d, tail %d\n",
251  ei->ID() / 2, l, h, t);
252  }
253  }
254  else
255  {
256  if (terminal_output_)
257  {
258  fprintf(stderr, "-----------------------------------\n");
259  fprintf(stderr, "Searching starts in layer %d, head %d, tail %d\n", l, h, t);
260  }
261  }
262 
263  /* exit */
264  if (h == t)
265  {
266  if (terminal_output_)
267  {
268  fprintf(stderr, "++++ Head meets tail! Current layer solution found.\n\n");
269  }
270 
271  return true;
272  }
273 
274  /* next choice */
275  multimap<double, WF_edge*> choice;
276  multimap<double, WF_edge*>::iterator it;
277 
278  /* next edge in current layer */
279  int Nl = layers_[l].size();
280 
281  // for all the edges in current layer, generate cost (pruning in cost generation)
282  // constraint propagation (arc-consistency) in current layer
283  for (int j = 0; j < Nl; j++)
284  {
285  WF_edge *ej = layers_[l][j];
286 
287  /* cost weight */
288  double cost = GenerateCost(ej, h, t, l);
289 
290  if (cost == -2)
291  {
292  return false;
293  }
294 
295  if (cost != -1)
296  {
297  // eligible candidate, cost = -1 if stiffness or kinematic check not pass
298  choice.insert(pair<double, WF_edge*>(cost, ej));
299  }
300  }
301 
302  int cnt = 0;
303  WF_edge* prev_e = NULL;
304 
305  /* ranked by weight */
306  for (it = choice.begin(); it != choice.end(); it++)
307  {
308  if(print_queue_.size() > 0)
309  {
310  prev_e = print_queue_.back();
311  }
312 
313 // WF_edge* ej = it->second;
314 
315  WF_edge* ej = RouteEdgeDirection(prev_e, it->second);
316  print_queue_.push_back(ej);
317 
318  /* update printed subgraph */
320 
321  // update collision (geometric domain)
322  // tmp is the pruned domain by direct arc consistency pruning
323  std::vector<std::vector<lld>> tmp_angle(3);
324  UpdateStateMap(ej, tmp_angle);
325 
327 
328  if (terminal_output_)
329  {
330  fprintf(stderr, "Choose edge #%d in with cost %lf - candidates %d/%d \n\n",
331  ej->ID() / 2, it->first, cnt, (int)choice.size());
332  }
333 
334  if (GenerateSeq(l, h + 1, t))
335  {
336  return true;
337  }
338 
339  // backtrack
340  RecoverStateMap(ej, tmp_angle);
342 
343  print_queue_.pop_back();
344 
345  num_backtrack_++;
346 
347  if (terminal_output_)
348  {
349  fprintf(stderr, "---- Backtrack - head %d/tail %d\n", h, t);
350  }
351 
352  cnt++;
353  }
354 
355  return false;
356 }
357 
358 
359 double FFAnalyzer::GenerateCost(WF_edge *ej, const int h, const int t, const int l)
360 {
361  int orig_j = ej->ID();
362  int dual_j = ptr_wholegraph_->e_dual_id(orig_j);
363 
364  // check arc consistency for all unprinted elements
365  if (!ptr_dualgraph_->isExistingEdge(ej))
366  {
367  double P = 0; // stabiliy weight
368  double A = 0; // adjacency weight
369  double I = 0; // influence weight
370 
371  if (terminal_output_)
372  {
373  fprintf(stderr, "Look-ahead in layer %d/%d - head %d/tail %d: Attempting edge #%d, queue size %d\n",
374  l, (int)layers_.size(), h, t, orig_j / 2, (int)print_queue_.size());
375  }
376 
377  /* stabiliy weight */
378  int uj = ptr_frame_->GetEndu(orig_j);
379  int vj = ptr_frame_->GetEndv(orig_j);
380  bool exist_uj = ptr_dualgraph_->isExistingVert(uj);
381  bool exist_vj = ptr_dualgraph_->isExistingVert(vj);
382  double z = 0.0;
383 
384  if(max_z_ != min_z_)
385  {
386  z = (ej->CenterPos().z() - min_z_) / (max_z_ - min_z_);
387  }
388  else
389  {
390  z = 0.0;
391  }
392 
393  // prune floating edge
394  if(!ej->isPillar())
395  {
396  if (exist_uj && exist_vj)
397  {
398  /* edge j share two ends with printed structure */
399  P = z;
400  }
401  else
402  {
403  if (exist_uj || exist_vj)
404  {
405  /* edge j share one end with printed structure */
406  double ang;
407  point pos_uj = ptr_frame_->GetPosition(uj);
408  point pos_vj = ptr_frame_->GetPosition(vj);
409 
410  if (exist_uj)
411  {
412  ang = Geometry::angle(point(0, 0, 1), pos_vj - pos_uj);
413  }
414  else
415  {
416  ang = Geometry::angle(point(0, 0, 1), pos_uj - pos_vj);
417  }
418 
419  P = z * exp(ang);
420  }
421  else
422  {
423  if (terminal_output_)
424  {
425  fprintf(stderr, "...floating edge, skip\n\n");
426  }
427  return -1;
428  }
429  }
430  }
431 
432  /* collision test */
433  int free_angle = ptr_collision_->ColFreeAngle(angle_state_[dual_j]);
434  if (free_angle == 0)
435  {
436  if (terminal_output_)
437  {
438  fprintf(stderr, "...collision test failed at edge #%d.\n", ej->ID() / 2);
439  }
440 
441  fprintf(stderr, "fail edge vert u: (%f, %f, %f), vert v: (%f, %f, %f)\n\n",
442  ej->pvert_->Position().x(), ej->pvert_->Position().y(), ej->pvert_->Position().z(),
443  ej->ppair_->pvert_->Position().x(), ej->ppair_->pvert_->Position().y(), ej->ppair_->pvert_->Position().z());
444 
445  return -2;
446  }
447  else
448  {
449  /* robot kinematics test */
451  {
452  if (!TestRobotKinematics(ej, angle_state_[dual_j]))
453  {
454  /* examination failed */
455  if (terminal_output_)
456  {
457  fprintf(stderr, "...robot kinematics test failed at edge #%d.\n", ej->ID() / 2);
458  fprintf(stderr, "fail edge vert u: (%f, %f, %f), vert v: (%f, %f, %f)\n\n",
459  ej->pvert_->Position().x(), ej->pvert_->Position().y(), ej->pvert_->Position().z(),
460  ej->ppair_->pvert_->Position().x(), ej->ppair_->pvert_->Position().y(), ej->ppair_->pvert_->Position().z());
461  }
462 
463  return -2;
464  }
465  }
466  }
467 
468  /* stiffness test */
469 // if (!ej->isPillar() && !TestifyStiffness(ej))
470 // {
471 // /* examination failed */
472 // if (terminal_output_)
473 // {
474 // fprintf(stderr, "...stiffness examination failed at edge #%d.\n\n", ej->ID() / 2);
475 // }
476 // return -1;
477 // }
478 
479  // Forward Checking
480  // limit forward checking only to current layer
481  /* influence weight */
482  int Nl = layers_[l].size();
483  int remaining_num = 0;
484  double forward_checking_factor = 1.0;
485 
486  for (int k = 0; k < Nl; k++)
487  {
488  WF_edge* ek = layers_[l][k];
489  int dual_k = ptr_wholegraph_->e_dual_id(ek->ID());
490 
491  // considered edge is not ej itself and it's not printed yet
492  if (dual_j != dual_k && !ptr_dualgraph_->isExistingEdge(ek))
493  {
494  vector<lld> tmp(3);
495  ptr_collision_->DetectCollision(ek, ej, tmp);
496 
497  for (int o = 0; o < 3; o++)
498  {
499  tmp[o] |= angle_state_[dual_k][o];
500  }
501 
502  int future_angle = ptr_collision_->ColFreeAngle(tmp);
503 
504  if(0 == future_angle)
505  {
506  fprintf(stderr, "...FC pruning - collision test failed at edge #%d to future edge #%d.\n\n",
507  ej->ID() / 2, ek->ID() / 2);
508  return -1;
509  }
510 
511  double d_ratio = (double)future_angle / (double)ptr_collision_->Divide();
512  I += exp(- forward_checking_factor * d_ratio * d_ratio);
513 
514  remaining_num++;
515  }
516  }
517 
518  if(0 != remaining_num)
519  {
520  I /= remaining_num;
521  }
522  else
523  {
524  I = 0.0;
525  }
526 
527  /* adjacency weight (A) */
528  if(ej->isPillar())
529  {
530  // use dist to robot base as heuristic
531  const auto &st_pt_msg = frame_msgs_[ej->ID()].start_pt;
532  const auto &end_pt_msg = frame_msgs_[ej->ID()].end_pt;
533 
534  // distance to robot base (world_frame 0,0,0)
535  double dist = sqrt(pow((st_pt_msg.x + end_pt_msg.x) / 2, 2)
536  + pow((st_pt_msg.y + end_pt_msg.y) / 2, 2)
537  + pow((st_pt_msg.z + end_pt_msg.z) / 2, 2));
539  {
540  A = 1 - (dist - min_base_dist_) / (max_base_dist_ - min_base_dist_);
541  }
542  }
543 
544  double cost = Wp_ * P + Wa_ * A + Wi_ * I;
545 
546  if (terminal_output_)
547  {
548  fprintf(stderr, "P: %lf, A: %lf, I: %lf\ncost: %f\n\n", P, A, I, cost);
549  }
550 
551  return cost;
552  } // end if exist_edge ej
553 
554  // ej exists already, skip
555  return -1;
556 }
557 
559 {
560  printf("***FFAnalyzer timer result:\n");
561  FF_analyzer_.Print("FFAnalyzer:");
562 
563  if (terminal_output_)
564  {
565  upd_struct_.Print("UpdateStructure:");
566  rec_struct_.Print("RecoverStructure:");
567  upd_map_.Print("UpdateStateMap:");
568  upd_map_collision_.Print("DetectCollision:");
569  rec_map_.Print("RecoverStateMap:");
570  test_stiff_.Print("TestifyStiffness:");
571  }
572  else
573  {
574  printf("***FFAnalyzer detailed timing turned off.\n");
575  }
576 }
int ColFreeAngle(const std::vector< lld > &colli_map)
Timer test_stiff_
Definition: SeqAnalyzer.h:173
double max_z_
Definition: FFAnalyzer.h:98
void UpdateStructure(WF_edge *e, bool update_collision=false)
void ModifyAngle(std::vector< lld > &angle_state, const std::vector< lld > &colli_map)
int num_backtrack_
Definition: SeqAnalyzer.h:182
double Wp_
Definition: SeqAnalyzer.h:158
Timer FF_analyzer_
Definition: FFAnalyzer.h:103
bool update_collision_
Definition: SeqAnalyzer.h:166
trimesh::point point
Definition: WireFrame.h:51
void UpdateStateMap(WF_edge *e, vector< vector< lld >> &state_map)
static double angle(Vector3d vec1, Vector3d vec2)
Definition: Geometry.h:158
bool GenerateSeq(int l, int h, int t)
Definition: FFAnalyzer.cpp:240
WF_edge * RouteEdgeDirection(const WF_edge *prev_e, WF_edge *e)
WF_edge * GetEdge(int i)
Definition: WireFrame.h:238
Timer upd_struct_
Definition: SeqAnalyzer.h:168
void RecoverStructure(WF_edge *e, bool update_collision=false)
reference x()
Definition: Vec.h:194
bool isExistingVert(int u)
Definition: DualGraph.h:163
Timer rec_struct_
Definition: SeqAnalyzer.h:169
bool isPillar() const
Definition: WireFrame.h:125
bool SeqPrintLayer(std::vector< int > layer_id)
Definition: FFAnalyzer.cpp:106
point CenterPos() const
Definition: WireFrame.h:135
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
void Stop()
Definition: Timer.cpp:21
int e_orig_id(int u)
Definition: DualGraph.h:152
double min_base_dist_
Definition: FFAnalyzer.h:100
int ID() const
Definition: WireFrame.h:123
WF_edge * ppair_
Definition: WireFrame.h:166
int Layer() const
Definition: WireFrame.h:124
bool DetectCollision(WF_edge *target_e, DualGraph *ptr_subgraph, std::vector< lld > &result_map)
double min_z_
Definition: FFAnalyzer.h:97
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
DualGraph * ptr_wholegraph_
Definition: SeqAnalyzer.h:146
double Wi_
Definition: SeqAnalyzer.h:160
double Wa_
Definition: SeqAnalyzer.h:159
reference y()
Definition: Vec.h:203
GLdouble GLdouble t
DualGraph * ptr_dualgraph_
Definition: SeqAnalyzer.h:133
bool SeqPrint()
Definition: FFAnalyzer.cpp:7
QuadricCollision * ptr_collision_
Definition: SeqAnalyzer.h:135
double GenerateCost(WF_edge *ej, const int h, const int t, const int layer_id)
Definition: FFAnalyzer.cpp:359
int SizeOfLayer() const
Definition: WireFrame.h:233
std::vector< WF_edge * > print_queue_
Definition: SeqAnalyzer.h:148
void Start()
Definition: Timer.cpp:15
int e_dual_id(int u)
Definition: DualGraph.h:153
GLdouble GLdouble GLdouble z
GLfloat GLfloat GLfloat GLfloat h
Timer rec_map_
Definition: SeqAnalyzer.h:172
int GetEndv(int i) const
Definition: WireFrame.h:245
bool isExistingEdge(WF_edge *e)
Definition: DualGraph.h:165
const GLdouble * v
bool terminal_output_
Definition: SeqAnalyzer.h:163
WF_vert * pvert_
Definition: WireFrame.h:164
#define ROS_INFO_STREAM(args)
GLdouble s
int num_p_assign_visited_
Definition: SeqAnalyzer.h:181
bool TestRobotKinematics(WF_edge *e, const std::vector< lld > &colli_map)
double max_base_dist_
Definition: FFAnalyzer.h:101
int SizeOfVertList()
Definition: DualGraph.h:145
void Print(char *item)
Definition: Timer.cpp:37
int GetEndu(int i) const
Definition: WireFrame.h:244
int search_rerun_
Definition: SeqAnalyzer.h:184
void RecoverStateMap(WF_edge *e, vector< vector< lld >> &state_map)
reference z()
Definition: Vec.h:212
std::vector< choreo_msgs::ElementCandidatePoses > frame_msgs_
Definition: SeqAnalyzer.h:138
std::vector< std::vector< WF_edge * > > layers_
Definition: FFAnalyzer.h:95
point GetPosition(int u) const
Definition: WireFrame.h:241
void PrintOutTimer()
Definition: FFAnalyzer.cpp:558
#define ROS_ERROR(...)
Timer upd_map_
Definition: SeqAnalyzer.h:170
Timer upd_map_collision_
Definition: SeqAnalyzer.h:171
point Position() const
Definition: WireFrame.h:78


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