HOG2
RoboticArm.cpp
Go to the documentation of this file.
1 /*
2  * RoboticArm.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 11/15/08.
6  * Copyright 2008 __MyCompanyName__. All rights reserved.
7  *
8  */
9 
10 #include "RoboticArm.h"
11 #include "TemplateAStar.h"
12 #include "GLUtil.h"
13 #include <string.h>
14 
16 {
17  switch ((rotations>>(2*which))&0x3)
18  {
19  case 1: return kRotateCCW;
20  case 0: return kNoRotation;
21  case 2: return kRotateCW;
22  }
23  return kNoRotation;
24 }
25 
27 {
28  int value = 0;
29  switch (dir)
30  {
31  case kRotateCW: value = 2; break;
32  case kRotateCCW: value = 1; break;
33  case kNoRotation: value = 0; break;
34  }
35  rotations = (rotations&(~((0x3)<<(2*which))))|(value<<(2*which));
36 }
37 
38 int armAngles::GetAngle(int which) const
39 {
40  return (angles>>(10*which))&0x3FF;
41 }
42 
43 void armAngles::SetAngle(int which, int value)
44 {
45  value %= 1024; if ( value < 0 ) { value += 1024; }
46  value -= value & 1;
47  uint64_t mask = 1023ll<<(10*which);
48  uint64_t val = ((uint64_t)value)<<(10*which);
49  angles = (angles&~mask)|val;
50 }
51 
53 {
54  return angles>>60;
55 }
56 
57 void armAngles::SetNumArms(int count)
58 {
59  uint64_t mask = 0xFFFFFFFFFFFFFFFull;
60  uint64_t newCnt = count;
61  newCnt = newCnt << 60;
62  assert(count <= 6);
63  angles = newCnt|(angles&mask);
64 }
65 
66 void armAngles::SetGoal(double x, double y)
67 {
68  uint64_t fixedDecx, fixedFracx;
69  uint64_t fixedDecy, fixedFracy;
70  x += 512; // avoid unsigned issues...
71  y += 512;
72  fixedDecx = ((uint32_t)x)&0x3FF; // 10 bits
73  fixedFracx = (int)((x-(double)fixedDecx)*1024.0*1024.0); // 20 bits
74  fixedDecy = ((uint32_t)y)&0x3FF; // 10 bits
75  fixedFracy = (int)((y-(double)fixedDecy)*1024.0*1024.0); // 20 bits
76  angles = (0xFll<<60)|(fixedDecx<<50)|(fixedFracx<<30)|(fixedDecy<<20)|fixedFracy;
77 }
78 
79 void armAngles::GetGoal(double &x, double &y) const
80 {
81  assert(IsGoalState());
82 
83  x = ((angles>>50)&0x3FF) + (double)((angles>>30)&0xFFFFF)/(1024.0*1024.0);
84  y = ((angles>>20)&0x3FF) + (double)((angles)&0xFFFFF)/(1024.0*1024.0);
85  x-= 512;
86  y-= 512;
87 }
88 
89 
91 {
92  return ((angles>>60) == 0xF);
93 }
94 
95 
96 RoboticArm::RoboticArm(int dof, double armlength, double fTolerance)
97 :DOF(dof), armLength(armlength), tolerance(fTolerance)
98 {
100  ce = new ConfigEnvironment();
101 }
102 
104 {
105  delete ce;
106 }
107 
108 void RoboticArm::GetTipPosition( armAngles &s, double &x, double &y )
109 {
110  std::vector<line2d> armSegs;
111  GenerateLineSegments( s, armSegs );
112  recVec a = armSegs.back().end;
113  x = a.x;
114  y = a.y;
115 }
116 
118  const double minX, const double minY,
119  const double width )
120 {
121  int idx;
122  double x, y;
123  GetTipPosition(s, x, y);
124  // if we had a guarantee that width was a multiple of
125  // tolerance, we could do a bunch of simplification
126  idx = (int)floor( ( y - minY ) / GetTolerance() );
127  idx *= (int)floor( width / GetTolerance() );
128  idx += (int)floor( ( x - minX ) / GetTolerance() );
129 
130  return idx;
131 }
132 
133 void RoboticArm::GetSuccessors(const armAngles &nodeID, std::vector<armAngles> &neighbors) const
134 {
135  neighbors.resize(0);
136 // for (int x = 0; x < nodeID.GetNumArms(); x++)
137 // {
138 // armAngles s = nodeID;
139 // armRotations a;
140 // a.SetRotation(x, kRotateCW);
141 // ApplyAction(s, a);
142 //
143 // if (LegalState(s))
144 // neighbors.push_back(s);
145 //
146 // s = nodeID;
147 // a.SetRotation(x, kRotateCCW);
148 // ApplyAction(s, a);
149 //
150 // if (LegalState(s))
151 // neighbors.push_back(s);
152 // }
153  int maxVal = pow(3.0, nodeID.GetNumArms());
154  for (int x = 1; x < maxVal; x++)
155  {
156  armAngles s = nodeID;
157  armRotations a;
158  int tmp = x;
159  for (int y = 0; y < s.GetNumArms(); y++)
160  {
161  switch (tmp%3)
162  {
163  case 0: a.SetRotation(y, kNoRotation); break;
164  case 1: a.SetRotation(y, kRotateCW); break;
165  case 2: a.SetRotation(y, kRotateCCW); break;
166  }
167  tmp/=3;
168  }
169 
170  ApplyAction(s, a);
171 
172  if (LegalState(s))
173  neighbors.push_back(s);
174  }
175 }
176 
177 void RoboticArm::GetActions(const armAngles &nodeID, std::vector<armRotations> &actions) const
178 {
179  actions.resize(0);
180  for (int x = 0; x < nodeID.GetNumArms(); x++)
181  {
182  armAngles s = nodeID;
183  armRotations a;
184  a.SetRotation(x, kRotateCW);
185  ApplyAction(s, a);
186 
187  if (LegalState(s))
188  actions.push_back(a);
189 
190  s = nodeID;
191  a.SetRotation(x, kRotateCCW);
192  ApplyAction(s, a);
193 
194  if (LegalState(s))
195  actions.push_back(a);
196  }
197 
198 // actions.resize(0);
199 // for (int x = 0; x < nodeID.GetNumArms(); x++)
200 // {
201 // armAngles a(nodeID);
202 // a.SetAngle(x, nodeID.GetAngle(x)+2);
203 // if (LegalState(a))
204 // {
205 // armRotations rot;
206 // rot.SetRotation(x, kRotateCW);
207 // actions.push_back(rot);
208 // }
209 // a.SetAngle(x, nodeID.GetAngle(x)-2);
210 // if (LegalState(a))
211 // {
212 // armRotations rot;
213 // rot.SetRotation(x, kRotateCCW);
214 // actions.push_back(rot);
215 // }
216 // }
217 }
218 
220 {
221  armRotations ar;
222  for (int x = 0; x < s1.GetNumArms(); x++)
223  {
224  ar.SetRotation(x, (tRotation)(s2.GetAngle(x)-s1.GetAngle(x)));
225  }
226  return ar;
227 }
228 
230 {
231  armAngles newState = s;
232  for (int x = 0; x < newState.GetNumArms(); x++) {
233  newState.SetAngle(x, newState.GetAngle(x)+2*dir.GetRotation(x));
234  }
235  //if (LegalState(newState))
236  s = newState;
237 }
238 
240 {
241  for (int x = 0; x < 6; x++)
242  a.SetRotation(x, (tRotation)(-(int)a.GetRotation(x)));
243  return true;
244 }
245 
246 
248 {
249  obstacles.push_back(obs);
250  ce->AddObstacle(obs);
251 // printf("Found solution %d moves; length %f, %d nodes expanded\n",
252 // states.size(), ce->GetPathLength(states), astar.GetNodesExpanded());
253 }
254 
256 {
257  if (obstacles.size() > 0)
258  {
259  obstacles.pop_back();
260  ce->PopObstacle();
261  }
262 }
263 
265 {
266  armAngles ar;
267  ar.SetNumArms(DOF);
268  for (int x = 0; x < DOF; x++)
269  ar.SetAngle(x, 2*(random()%512));
270  return ar;
271 }
272 
273 double RoboticArm::HCost(const armAngles &node1, const armAngles &node2) const
274 {
275  double h;
276  if (!node1.IsGoalState() && !node2.IsGoalState())
277  {
278  double val = 0;
279  for (int x = 0; x < node1.GetNumArms(); x++)
280  {
281  double tmp = abs(node1.GetAngle(x) - node2.GetAngle(x));
282  val += tmp/2;
283  }
284  //printf("Default heur: %f\n", val);
285  for (unsigned int x = 0; x < heuristics.size(); x++)
286  val = max(val, heuristics[x]->HCost(node1, node2));
287  return val;
288  }
289 
290  if (node1.IsGoalState()) return HCost(node2, node1);
291  assert(node2.IsGoalState());
292 
293  std::vector<line2d> armSegments1;
294  GenerateLineSegments(node1, armSegments1);
295  recVec a = armSegments1.back().end;
296  double x, y;
297  node2.GetGoal(x, y);
298  double actDistance = sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
299  double movementAmount = (node1.GetNumArms()*armLength*sin(TWOPI*4.0/1024.0));
300 
301  {
303  recVec g(x, y, 0);
304  ce->StoreGoal(g);
305  astar.GetPath(ce, a, g, states);
306  actDistance = max(actDistance, ce->GetPathLength(states));
307  }
308 
309  h = actDistance / movementAmount;
310 
311  return h;
312 
313 #if 0
314  recVec a, b;
315  if (node1.IsGoalState())
316  node1.GetGoal(a.x, a.y);
317  else {
319  a = armSegments.back().end;
320  }
321 
322  if (node2.IsGoalState())
323  node2.GetGoal(b.x, b.y);
324  else {
326  b = armSegments.back().end;
327  }
328  return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
329 #endif
330 }
331 
332 #if 0
333 double RoboticArm::GCost(const armAngles &node1, const armAngles &node2)
334 {
335  recVec a, b;
336  if (node1.IsGoalState())
337  node1.GetGoal(a.x, a.y);
338  else {
340  a = armSegments.back().end;
341  }
342 
343  if (node2.IsGoalState())
344  node2.GetGoal(b.x, b.y);
345  else {
347  b = armSegments.back().end;
348  }
349  return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
350 }
351 #endif
352 
353 #if 0
354 double RoboticArm::GCost(const armAngles &node1, const armRotations &act)
355 {
356  armAngles node2;
357  GetNextState(node1, act, node2);
358  return GCost(node1, node2);
359 }
360 #endif
361 
362 bool RoboticArm::GoalTest(const armAngles &node, const armAngles &goal) const
363 {
364  if (!goal.IsGoalState())
365  {
366  return (node == goal);
367  }
368  assert(goal.IsGoalState());
370 
371  recVec a;
372  a = armSegments.back().end;
373  double x, y;
374  goal.GetGoal(x, y);
375  return x-a.x <= tolerance && a.x-x < tolerance
376  && y-a.y <= tolerance && a.y-y < tolerance;
377 }
378 
380 {
381  // want a perfect hash function
382  //return node.angles;
383  uint64_t res = 0;
384  for (int x = 0; x < node.GetNumArms(); x++)
385  res = (uint64_t)(res<<9)|((uint64_t)node.GetAngle(x)/2);
386 // assert(res < 512*512*512);
387  return res;
388 }
389 
390 void RoboticArm::GetStateFromHash(uint64_t hash, armAngles &a) const
391 {
392  for (int x = a.GetNumArms()-1; x >= 0; x--)
393  {
394  a.SetAngle(x, (hash&0x1FF)*2);
395  hash >>= 9;
396  }
397 }
398 
400 {
401  return act.rotations;
402 }
403 
405 {
406 // if (window == 1)
407 // {
408 // ce->OpenGLDraw(1);
409 // return;
410 // }
411  glBegin(GL_QUADS);
412  glColor3f(0, 0, 0.1);
413  glVertex3f(-1, -1, 0.1);
414  glVertex3f(1, -1, 0.1);
415  glVertex3f(1, 1, 0.1);
416  glVertex3f(-1, 1, 0.1);
417  glEnd();
418 
419  glColor3f(1, 0, 0);
420  for (unsigned int x = 0; x < obstacles.size(); x++)
421  {
422  DrawLine(obstacles[x]);
423  }
424 }
425 
426 void RoboticArm::OpenGLDraw(const armAngles &a) const
427 {
428 // if (window == 1)
429 // {
430 // glColor3f(1, 1, 0);
431 // for (unsigned int x = 1; x < states.size(); x++)
432 // {
433 // DrawLine(line2d(states[x-1], states[x]));
434 // }
435 // ce->OpenGLDraw(1);
436 // return;
437 // }
438 
439  recVec e;
440  if (a.IsGoalState())
441  {
442  e.z = 0;
443  a.GetGoal(e.x, e.y);
444  }
445  else {
447 
448  for (unsigned int x = 0; x < armSegments.size(); x++)
449  {
450  glColor3f(1, 1, 1);
451  //printf("Drawing line segment %d of %d\n", x, armSegments.size());
452  DrawLine(armSegments[x]);
453  }
454  e = armSegments.back().end;
455  }
456 
457  glBegin(GL_LINE_LOOP);
458  glColor3f(0, 1.0, 0);
459  glVertex3f(e.x+tolerance, e.y+tolerance, 0);
460  glVertex3f(e.x-tolerance, e.y+tolerance, 0);
461  glVertex3f(e.x-tolerance, e.y-tolerance, 0);
462  glVertex3f(e.x+tolerance, e.y-tolerance, 0);
463  glEnd();
464 
465 }
466 
467 void RoboticArm::OpenGLDraw(const armAngles &, const armRotations &) const
468 {
469 }
470 
471 //void RoboticArm::OpenGLDraw(const armAngles &, const armRotations &, GLfloat, GLfloat, GLfloat) const
472 //{
473 //}
474 //
475 //void RoboticArm::OpenGLDraw(const armAngles &, GLfloat, GLfloat, GLfloat) const
476 //{
477 //}
478 
480 {
481  glLineWidth(5);
482  glBegin(GL_LINES);
483  glVertex3f(l.start.x, l.start.y, 0);
484  glVertex3f(l.end.x, l.end.y, 0);
485  glEnd();
486  glLineWidth(1);
487 }
488 
489 void RoboticArm::GetNextState(const armAngles &currents, armRotations dir, armAngles &news) const
490 {
491  news = currents;
492  ApplyAction(news, dir);
493 }
494 
496 {
497 // if ( legalStateTable != NULL ) {
498 // uint64_t idx;
499 //
500 // idx = ArmAnglesIndex( a );
501 // if ( legalStateTable[ idx >> 3 ] & ( 1 << ( idx & 7 ) ) ) {
502 // return true;
503 // }
504 // return false;
505 // }
506 
508  for (unsigned int x = 0; x < armSegments.size(); x++)
509  {
510  for (unsigned int y = 0; y < obstacles.size(); y++)
511  {
512  if (armSegments[x].crosses(obstacles[y]))
513  return false;
514  }
515  for (unsigned int y = x+2; y < armSegments.size(); y++)
516  if (armSegments[x].crosses(armSegments[y]))
517  return false;
518 
519  if ((x > 0) && (a.GetAngle(x) == 0))
520  return false;
521  }
522  return true;
523 }
524 
526 {
527 // if (m_TableComplete)
528 // return legals[a.GetAngle(1)][a.GetAngle(2)];
530  for (unsigned int x = 0; x < armSegments.size(); x++)
531  {
532  for (unsigned int y = x+2; y < armSegments.size(); y++)
533  if (armSegments[x].crosses(armSegments[y]))
534  return false;
535 
536  if ((x > 0) && (a.GetAngle(x) == 0))
537  return false;
538  }
539  return true;
540 }
541 
542 void RoboticArm::GenerateLineSegments(const armAngles &a, std::vector<line2d> &armSegments1) const
543 {
544  armSegments1.resize(0);
545  for (int x = 0; x < a.GetNumArms(); x++)
546  {
547  recVec prev;
548  recVec start;
549  recVec end;
550 
551  //double angle = TWOPI*a.GetAngle(x)/1024.0;
552  int angle = a.GetAngle(x);
553  if (x == 0)
554  {
555  start.x = 0;
556  start.y = 0;
557  start.z = 0;
558  prev = start;
559  prev.y = -armLength;
560  }
561  else {
562  start = armSegments1.back().end;
563  prev = armSegments1.back().start;
564  }
565 
566  // offset to origin
567  prev.x -= start.x;
568  prev.y -= start.y;
569 
570  end.x = prev.x*GetCos(angle) - prev.y*GetSin(angle) + start.x;
571  end.y = prev.x*GetSin(angle) + prev.y*GetCos(angle) + start.y;
572  end.z = 0;
573 
574  armSegments1.push_back(line2d(start, end));
575  }
576  assert(armSegments1.size() > 0);
577 }
578 
579 double RoboticArm::GetSin(int angle) const
580 {
581  return sinTable[angle];
582 }
583 
584 double RoboticArm::GetCos(int angle) const
585 {
586  return cosTable[angle];
587 }
588 
590 {
591  sinTable.resize(1024);
592  cosTable.resize(1024);
593  for (int x = 0; x < 1024; x++)
594  {
595  sinTable[x] = sin(TWOPI*(double)x/1024.0);
596  cosTable[x] = cos(TWOPI*(double)x/1024.0);
597  }
598 }
599 
601 {
602  ra = r;
603  m_TableComplete = false;
604  legalStateTable = NULL;
605  legalGoalTable = NULL;
606  tipPositionTables = NULL;
607  GenerateCPDB();
608 }
609 
610 double ArmToTipHeuristic::HCost(const armAngles &node1, const armAngles &node2) const
611 {
612  double x, y;
613  node2.GetGoal(x, y);
614 
615  double h = 0;
616  uint16_t tableH;
617  for (unsigned i = 0; i < distancesTables.size(); ++i )
618  {
619  if (node1.GetNumArms() == tablesNumArms[ i ] )
620  {
621  tableH = UseHeuristic( node1, x, y,
622  distancesTables[ i ],
624  maxTipDistancesTables[ i ] );
625  if ((double)tableH > h )
626  {
627  h = (double)tableH;
628  }
629  }
630  }
631  return h;
632 }
633 
634 
636 {
637  int numArms = 3;
638  //void GenerateLegalArmConfigs();
639  armAngles a;
640  a.SetNumArms(numArms);
641  a.SetAngle(0, 0);
642  // 0, 512, 512
643  std::vector<std::vector<bool> > legals;
644  legals.resize(512);
645  for (unsigned int x = 0; x < legals.size(); x++)
646  {
647  legals[x].resize(512);
648  printf("Building table for %d\n", x);
649  for (unsigned int y = 0; y < legals[x].size(); y++)
650  {
651  a.SetAngle(1, 2*x);
652  a.SetAngle(2, 2*y);
653  legals[x][y] = ra->LegalArmConfig(a);
654  }
655  }
656  m_TableComplete = true;
657 }
658 
659 
660 uint64_t ArmToTipHeuristic::ArmAnglesIndex( const armAngles &arm ) const
661 {
662  uint64_t idx;
663  int s;
664 
665  idx = 0;
666  for ( s = 0; s < arm.GetNumArms(); ++s ) {
667  idx <<= 9;
668  idx |= arm.GetAngle( s ) >> 1;
669  }
670 
671  return idx;
672 }
673 
674 int ArmToTipHeuristic::TipPositionIndex( const double x, const double y,
675  const double minX, const double minY,
676  const double width ) const
677 {
678  int idx;
679 
680  // if we had a guarantee that width was a multiple of
681  // tolerance, we could do a bunch of simplification
682 
683  idx = (int)floor( ( y - minY ) / ra->GetTolerance() );
684  idx *= (int)floor( width / ra->GetTolerance() );
685  idx += (int)floor( ( x - minX ) / ra->GetTolerance() );
686 
687  return idx;
688 }
689 
691 {
692  int s;
693  int16_t v;
694 
695  v = a.GetNumArms();
696  if ( fwrite( &v, sizeof( v ), 1, file ) < 1 ) {
697  return 0;
698  }
699  for ( s = 0; s < a.GetNumArms(); ++s ) {
700  v = a.GetAngle( s );
701  if ( fwrite( &v, sizeof( v ), 1, file ) < 1 ) {
702  return 0;
703  }
704  }
705  return 1;
706 }
707 
709 {
710  armAngles angles;
711  int s;
712  int16_t v;
713 
714  if ( fread( &v, sizeof( v ), 1, file ) < 1 ) {
715  return 0;
716  }
717  angles.SetNumArms( v );
718  for ( s = 0; s < angles.GetNumArms(); ++s ) {
719  if ( fread( &v, sizeof( v ), 1, file ) < 1 ) {
720  return 0;
721  }
722  angles.SetAngle( s, v );
723  }
724 
725  a = angles;
726  return 1;
727 }
728 
729 void ArmToTipHeuristic::UpdateTipDistances( armAngles &arm, uint16_t distance,
730  uint16_t *minTipDistances,
731  uint16_t *maxTipDistances )
732 {
733  int idx;
734  double x, y;
735 
736  ra->GetTipPosition( arm, x, y );
737  idx = TipPositionIndex( x, y, -1.0, -1.0, 2.0 );
738  if ( distance < minTipDistances[ idx ] ) {
739  minTipDistances[ idx ] = distance;
740  }
741  if ( distance > maxTipDistances[ idx ] ) {
742  maxTipDistances[ idx ] = distance;
743  }
744 }
745 
746 // this works because of two things
747 // a) clockwise and counterclockwise are each others inverses
748 // and both actions are (potentially) legal moves for every arm segment
749 // b) action costs are uniform, so all children which have not
750 // been examined are in the next frontier
751 // returns the number of states in nextFile
752 uint64_t ArmToTipHeuristic::GenerateNextDepth( FILE *curFile, FILE *nextFile,
753  uint16_t curDistance,
754  uint16_t *distances,
755  uint16_t *minTipDistances,
756  uint16_t *maxTipDistances,
757  armAngles &lastAdded )
758 {
759  uint64_t count = 0, idx;
760  unsigned i;
761  armAngles arm;
762  std::vector<armRotations> actions;
763 
764  while( ReadArmAngles( curFile, arm ) ) {
765  ra->GetActions( arm, actions );
766  for ( i = 0; i < actions.size(); ++i ) {
767  armAngles child = arm;
768  ra->ApplyAction( child, actions[ i ] );
769 
770  idx = ArmAnglesIndex( child );
771  if ( distances[ idx ]
772  > curDistance + 1 ) {
773  // new arm configuration
774 
775  distances[ idx ] = curDistance + 1;
776  WriteArmAngles( nextFile, child );
777  if ( minTipDistances ) {
778  UpdateTipDistances( child, curDistance + 1,
779  minTipDistances,
780  maxTipDistances );
781  }
782  ++count;
783  }
784  }
785  }
786 
787  lastAdded = arm;
788 
789  return count;
790 }
791 
792 
793 /* returns 1 if goal will generate a reasonable heuristic, 0 otherwise */
795  const bool quiet,
796  armAngles *goals, const int numGoals,
797  uint16_t *distances,
798  uint16_t *minTipDistances,
799  uint16_t *maxTipDistances,
800  armAngles &lastAdded )
801 {
802  uint64_t count, i, total;
803  int numArms = sampleArm.GetNumArms(), segment, g;
804  uint16_t distance;
805  armAngles arm;
806  FILE *curFile, *nextFile;
807 
808  arm.SetNumArms( numArms );
809 
810  count = NumArmAnglesIndices( arm );
811  for ( i = 0; i < count; ++i ) {
812  distances[ i ] = 65535;
813  }
814 
815  if ( minTipDistances ) {
816  count = NumTipPositionIndices();
817  for ( i = 0; i < count; ++i ) {
818  minTipDistances[ i ] = 65535;
819  maxTipDistances[ i ] = 0;
820  }
821  }
822 
823  nextFile = tmpfile();
824  assert( nextFile != NULL );
825 
826  count = 0;
827  total = 0;
828 
829  if ( !quiet ) {
830  printf( "populating depth 0\n" );
831  }
832  for ( segment = 0; segment < numArms; ++segment ) {
833  arm.SetAngle( segment, 0 );
834  }
835  while( 1 ) {
836  if ( ra->LegalState( arm ) ) {
837  ++total;
838 
839  for ( g = 0; g < numGoals; ++g ) {
840  if ( ra->GoalTest( arm, goals[ g ] ) ) {
841  // new distance 0 (goal) arm configuration
842 
843  distances[ ArmAnglesIndex( arm ) ] = 0;
844  WriteArmAngles( nextFile, arm );
845  UpdateTipDistances( arm, 0, minTipDistances,
846  maxTipDistances );
847  ++count;
848  break;
849  }
850  }
851  }
852 
853  // next configuration
854  segment = 0;
855  do {
856  armRotations action;
857  action.SetRotation( segment, kRotateCW );
858  ra->ApplyAction( arm, action );
859  if ( arm.GetAngle( segment ) != 0 ) {
860  break;
861  }
862  } while( ++segment < numArms );
863  if ( segment == numArms ) {
864  // tried all configurations
865  break;
866  }
867  }
868 
869  printf( "%" PRId64 " legal states\n", total );
870 
871  if ( !count ) {
872  fclose( nextFile );
873  return 0;
874  }
875 
876  distance = 0;
877  total = 0;
878  do {
879  total += count;
880  if ( !quiet ) {
881  printf( "%" PRId64 " states at distance %u\n",
882  count, distance );
883  }
884  curFile = nextFile;
885  rewind( curFile );
886  nextFile = tmpfile();
887 
888  count = GenerateNextDepth( curFile, nextFile, distance,
889  distances, minTipDistances,
890  maxTipDistances, lastAdded );
891 
892  ++distance;
893  fclose( curFile );
894  } while( count );
895  fclose( nextFile );
896 
897  if ( !quiet ) {
898  printf( "%" PRId64 " total states\n", total );
899  }
900 
901  // there are a number of small disconnected subspaces,
902  // so make sure goal doesn't correspond to this subspace!
903  if ( distances[ ArmAnglesIndex( sampleArm ) ] == 65535 ) {
904  // sample arm not reachable!
905  return 0;
906  }
907 
908  return 1;
909 }
910 
911 /* this function generates a table-based heuristic function for
912  the current environment */
914 {
915  uint16_t *distances, *minTipDistances, *maxTipDistances;
916  armAngles goal, last;
917 
918  distances = new uint16_t[ NumArmAnglesIndices( sampleArm ) ];
919  minTipDistances = new uint16_t[ NumTipPositionIndices() ];
920  maxTipDistances = new uint16_t[ NumTipPositionIndices() ];
921 
922  do {
923  goal.SetGoal( (double)random()/(double)RAND_MAX * 2.0 - 1.0,
924  (double)random()/(double)RAND_MAX * 2.0 - 1.0 );
925  } while( !GenerateHeuristicSub( sampleArm, false, &goal, 1, distances,
926  minTipDistances, maxTipDistances,
927  last ) );
928 
929  distancesTables.push_back( distances );
930  minTipDistancesTables.push_back( minTipDistances );
931  maxTipDistancesTables.push_back( maxTipDistances );
932  tablesNumArms.push_back( sampleArm.GetNumArms() );
933 }
934 
935 /* this function generates a table-based heuristic function for
936  the current environment */
938  armAngles &goal )
939 {
940  uint16_t *distances, *minTipDistances, *maxTipDistances;
941  armAngles last;
942 
943  distances = new uint16_t[ NumArmAnglesIndices( sampleArm ) ];
944  minTipDistances = new uint16_t[ NumTipPositionIndices() ];
945  maxTipDistances = new uint16_t[ NumTipPositionIndices() ];
946 
947  if ( !GenerateHeuristicSub( sampleArm, false, &goal, 1, distances,
948  minTipDistances, maxTipDistances, last ) ) {
949  delete[] maxTipDistances;
950  delete[] minTipDistances;
951  delete[] distances;
952  return 0;
953  }
954 
955  distancesTables.push_back( distances );
956  minTipDistancesTables.push_back( minTipDistances );
957  maxTipDistancesTables.push_back( maxTipDistances );
958  tablesNumArms.push_back( sampleArm.GetNumArms() );
959 
960  return 1;
961 }
962 
963 /* this function generates a table-based heuristic function for
964  the current environment */
966  const int numHeuristics )
967 {
968  int i, ret;
969  uint16_t *distances, *minTipDistances, *maxTipDistances;
970  armAngles last;
971  armAngles *goals;
972  goals = new armAngles[numHeuristics];
973  double x, y;
974 
975  last = sampleArm;
976  ra->GetTipPosition( last, x, y );
977  last.SetGoal( x, y );
978  for ( i = 0; i < numHeuristics; ++i ) {
979  distances = new uint16_t[ NumArmAnglesIndices( sampleArm ) ];
980  minTipDistances = new uint16_t[ NumTipPositionIndices() ];
981  maxTipDistances = new uint16_t[ NumTipPositionIndices() ];
982 
983  printf( "generating next goal position\n" );
984  if ( i ) {
985  ret = GenerateHeuristicSub( sampleArm, true, goals, i,
986  distances, minTipDistances,
987  maxTipDistances, goals[ i ] );
988  } else {
989  ret = GenerateHeuristicSub( sampleArm, true, &last, 1,
990  distances, minTipDistances,
991  maxTipDistances, goals[ i ] );
992  }
993  if ( !ret ) {
994  delete[] maxTipDistances;
995  delete[] minTipDistances;
996  delete[] distances;
997  return i;
998  }
999  ra->GetTipPosition( goals[ i ], x, y );
1000  printf( "new goal position: (%lf,%lf)\n", x, y );
1001  goals[ i ].SetGoal( x, y );
1002 
1003 
1004  if ( !GenerateHeuristicSub( sampleArm, false, &goals[ i ], 1,
1005  distances, minTipDistances,
1006  maxTipDistances, last ) ) {
1007  delete[] maxTipDistances;
1008  delete[] minTipDistances;
1009  delete[] distances;
1010  return i;
1011  }
1012 
1013  distancesTables.push_back( distances );
1014  minTipDistancesTables.push_back( minTipDistances );
1015  maxTipDistancesTables.push_back( maxTipDistances );
1016  tablesNumArms.push_back( sampleArm.GetNumArms() );
1017  }
1018  delete []goals;
1019  return i;
1020 }
1021 
1023  uint16_t *distances ) const
1024 {
1025  uint16_t d_s, d_g;
1026 
1027  d_s = distances[ ArmAnglesIndex( s ) ];
1028  d_g = distances[ ArmAnglesIndex( g ) ];
1029  if ( d_s < d_g ) {
1030  return d_g - d_s;
1031  }
1032  return d_s - d_g;
1033 }
1034 
1036  double goalX, double goalY,
1037  uint16_t *distances,
1038  uint16_t *minTipDistances,
1039  uint16_t *maxTipDistances ) const
1040 {
1041  int32_t mind, maxd, t; // 32 bits because of the subtraction below
1042  int i, j, index;
1043  double x, y;
1044 
1045  mind = 65535;
1046  maxd = 0;
1047  for ( y = goalY - ra->GetTolerance(), i = 0; i < 3; y += ra->GetTolerance(), ++i ) {
1048  for ( x = goalX - ra->GetTolerance(), j = 0; j < 3; x += ra->GetTolerance(), ++j ) {
1049  index = TipPositionIndex( x, y, -1.0, -1.0, 2.0 );
1050  if ( minTipDistances[ index ] < mind ) {
1051  mind = minTipDistances[ index ];
1052  }
1053  if ( maxTipDistances[ index ] > maxd ) {
1054  maxd = maxTipDistances[ index ];
1055  }
1056  }
1057  }
1058 
1059  t = distances[ ArmAnglesIndex( arm ) ];
1060 //printf( "dist(s->g)=%u - max(dist(c->g))=%u\n", (unsigned)t, (unsigned)maxd );
1061 //printf( "min(dist(c->g))=%u - dist(s->g)=%u\n", (unsigned)mind, (unsigned)t );
1062  maxd = t - maxd;
1063  mind = mind - t;
1064  if ( mind > maxd ) {
1065  maxd = mind;
1066  }
1067  if ( maxd < 0 ) {
1068  maxd = 0;
1069  }
1070 
1071 //if ( maxd > 0 ) printf( "%u\n", (unsigned)maxd );
1072 
1073  return maxd;
1074 }
1075 
1076 bool ArmToTipHeuristic::ValidGoalPosition( double goalX, double goalY )
1077 {
1078  int i, j, index;
1079  double x, y, tx, ty;
1080 
1081  if ( legalGoalTable == NULL ) {
1082  // no table to use, can't prove anything
1083  return false;
1084  }
1085 
1086  for ( y = goalY - ra->GetTolerance(), i = 0; i < 3; y += ra->GetTolerance(), ++i ) {
1087  for ( x = goalX - ra->GetTolerance(), j = 0; j < 3; x += ra->GetTolerance(), ++j ) {
1088  tx = x;
1089  if ( tx < -1.0 ) {
1090  tx = -1.0;
1091  } else if ( tx >= 1.0 ) {
1092  tx = 0.999999;
1093  }
1094  ty = y;
1095  if ( ty < -1.0 ) {
1096  ty = -1.0;
1097  } else if ( ty >= 1.0 ) {
1098  ty = 0.999999;
1099  }
1100 
1101  index = TipPositionIndex( tx, ty, -1.0, -1.0, 2.0 );
1102  if ( !( legalGoalTable[ index >> 3 ] & ( 1 << ( index & 7 ) ) ) ) {
1103  // given one unreachable square, there's a possibility
1104  // that even if the rest are reachable, they're
1105  // only reachable because of states that are
1106  // actually further than tolerance away from (x,y)
1107  return false;
1108  }
1109  }
1110  }
1111 
1112  return true;
1113 }
1114 
1116 {
1117  uint64_t numStates, numTip, i;
1118  uint16_t *distances, *minTipDistances, *maxTipDistances, distance;
1119  uint8_t *lst, *lgt;
1120  armAngles arm, lastAdded;
1121  FILE *curFile, *nextFile;
1122 
1123  printf( "generating legal state table\n" );
1124 
1125  numStates = NumArmAnglesIndices( legalArm );
1126  numTip = NumTipPositionIndices();
1127 
1128  lst = new uint8_t[ ( numStates + 7 ) >> 3 ];
1129  memset( lst, 0, ( numStates + 7 ) >> 3 );
1130  lgt = new uint8_t[ ( numTip + 7 ) >> 3 ];
1131  memset( lgt, 0, ( numTip + 7 ) >> 3 );
1132  distances = new uint16_t[ numStates ];
1133  for ( i = 0; i < numStates; ++i ) {
1134  distances[ i ] = 65535;
1135  }
1136  minTipDistances = new uint16_t[ numTip ];
1137  maxTipDistances = new uint16_t[ numTip ];
1138  for ( i = 0; i < numTip; ++i ) {
1139  minTipDistances[ i ] = 65535;
1140  maxTipDistances[ i ] = 0;
1141  }
1142 
1143  nextFile = tmpfile();
1144  assert( nextFile != NULL );
1145 
1146  distances[ ArmAnglesIndex( legalArm ) ] = 0;
1147  UpdateTipDistances( legalArm, 0, minTipDistances, maxTipDistances );
1148  WriteArmAngles( nextFile, legalArm );
1149 
1150  distance = 0;
1151  do {
1152  curFile = nextFile;
1153  rewind( curFile );
1154  nextFile = tmpfile();
1155 
1156  i = GenerateNextDepth( curFile, nextFile, distance,
1157  distances, minTipDistances,
1158  maxTipDistances, lastAdded );
1159 
1160  ++distance;
1161  fclose( curFile );
1162  } while( i );
1163  fclose( nextFile );
1164  printf( "done: maximum distance of %d from chosen state\n",
1165  (int)distance );
1166 
1167  for ( i = 0; i < numStates; ++i ) {
1168  if ( distances[ i ] < 65535 ) {
1169  lst[ i >> 3 ] |= 1 << ( i & 7 );
1170  }
1171  }
1172 
1173  for ( i = 0; i < numTip; ++i ) {
1174  if ( minTipDistances[ i ]
1175  <= maxTipDistances[ i ] ) {
1176  lgt[ i >> 3 ] |= 1 << ( i & 7 );
1177  }
1178  }
1179 
1180  legalStateTable = lst;
1181  legalGoalTable = lgt;
1182  delete[] maxTipDistances;
1183  delete[] minTipDistances;
1184  delete[] distances;
1185 }
1186 
1188 {
1189  int numArms = sampleArm.GetNumArms(), segment;
1190  double x, y;
1191  armAngles arm;
1192 
1193  printf( "generating tip position table\n" );
1194 
1195  if ( tipPositionTables != NULL ) {
1196  return;
1197  }
1198 
1199  tipPositionTables = new std::vector<armAngles>[ NumTipPositionIndices() ];
1200 
1201  arm.SetNumArms( numArms );
1202 
1203  for (segment = 0; segment < numArms; ++segment)
1204  {
1205  arm.SetAngle( segment, 0 );
1206  }
1207 
1208  while( 1 )
1209  {
1210  if ( ra->LegalState( arm ) )
1211  {
1212  ra->GetTipPosition( arm, x, y );
1213  tipPositionTables[TipPositionIndex( x, y, -1.0, -1.0, 2.0 )].push_back( arm );
1214  }
1215 
1216  // next configuration
1217  segment = 0;
1218  do {
1219  armRotations action;
1220  action.SetRotation( segment, kRotateCW );
1221  ra->ApplyAction( arm, action );
1222  if ( arm.GetAngle( segment ) != 0 ) {
1223  break;
1224  }
1225  } while( ++segment < numArms );
1226  if (segment == numArms )
1227  {
1228  // tried all configurations
1229  break;
1230  }
1231  }
1232 
1233 }
1234 
1236 {
1237  optimizeLocations = optimize;
1238  ra = r;
1239  GenerateLegalStates(initial);
1240 }
1241 
1242 double ArmToArmHeuristic::HCost(const armAngles &node1, const armAngles &node2) const
1243 {
1244  if (node1.IsGoalState() || node2.IsGoalState())
1245  {
1246  //printf("Wrong problem type!\n");
1247  return 0.0;
1248  }
1249  double hval = 0.0;
1250  for (unsigned int x = 0; x < distances.size(); x++)
1251  {
1252  double nextval = abs(distances[x][ra->GetStateHash(node1)] - distances[x][ra->GetStateHash(node2)]);
1253 // printf("Heuristic %d: |%d-%d| = %f\n", x,
1254 // distances[x][ra->GetStateHash(node1)],
1255 // distances[x][ra->GetStateHash(node2)],
1256 // nextval);
1257  hval = max(nextval, hval);
1258  }
1259  return hval;
1260 }
1261 
1262 int ArmToArmHeuristic::TipPositionIndex(const double x, const double y,
1263  const double minX, const double minY,
1264  const double width )
1265 {
1266  int idx;
1267 
1268  // if we had a guarantee that width was a multiple of
1269  // tolerance, we could do a bunch of simplification
1270  idx = (int)floor( ( y - minY ) / ra->GetTolerance() );
1271  idx *= (int)floor( width / ra->GetTolerance() );
1272  idx += (int)floor( ( x - minX ) / ra->GetTolerance() );
1273 
1274  return idx;
1275 }
1276 
1278 {
1279  armAngles start = SelectStartNode();
1280 
1281  int which = distances.size();
1282  printf("Building new heuristic table [%d]\n", which);
1283 
1284  distances.resize(which+1);
1285  //distances[which].resize();
1286  std::deque<armAngles> q;
1287  q.push_back(start);
1288  canonicalStates.push_back(start);
1289  while (q.size() > 0)
1290  {
1291 // if ((cnt++%10000) == 0)
1292 // printf("(%d) Q size: %d\n", cnt, (int)q.size());
1293  armAngles a = q.front();
1294  q.pop_front();
1295  uint64_t hash = ra->GetStateHash(a);
1296  if (hash >= distances[which].size())
1297  distances[which].resize(hash+1);
1298  std::vector<armAngles> moves;
1299  ra->GetSuccessors(a, moves);
1300 // printf("Getting successors of node %lld at depth %d\n", hash, distances[which][hash]);
1301  for (unsigned int x = 0; x < moves.size(); x++)
1302  {
1303  uint64_t newHash = ra->GetStateHash(moves[x]);
1304  if (newHash >= distances[which].size())
1305  distances[which].resize(newHash+1);
1306  if (distances[which][newHash] != 0)
1307  continue;
1308 
1309  distances[which][newHash] = distances[which][hash]+1;
1310 // printf("Setting cost of node %lld to %d (1+%d from %lld)\n", newHash, distances[which][newHash],
1311 // distances[which][hash], hash);
1312  q.push_back(moves[x]);
1313  }
1314  }
1315  printf("Done\n");
1316 }
1317 
1319 {
1320  armAngles start;
1321  std::deque<armAngles> q;
1322  std::vector<bool> used;
1323  used.resize(512*512*512);
1324  if ((!optimizeLocations) || (distances.size() == 0))
1325  {
1326  do {
1327  start = ra->GetRandomState();
1328  } while (!IsLegalState(start));
1329  }
1330  if (!optimizeLocations)
1331  return start;
1332  if (distances.size() == 0)
1333  {
1334  used[ra->GetStateHash(start)] = true;
1335  q.push_back(start);
1336  }
1337  for (unsigned int x = 0; x < canonicalStates.size(); x++)
1338  {
1339  q.push_back(canonicalStates[x]);
1340  used[ra->GetStateHash(canonicalStates[x])] = true;
1341  }
1342  armAngles a;
1343  while (q.size() > 0)
1344  {
1345  a = q.front();
1346  q.pop_front();
1347 
1348  std::vector<armAngles> moves;
1349  ra->GetSuccessors(a, moves);
1350  for (unsigned int x = 0; x < moves.size(); x++)
1351  {
1352  if (used[ra->GetStateHash(moves[x])])
1353  continue;
1354  used[ra->GetStateHash(moves[x])] = true;
1355  q.push_back(moves[x]);
1356  }
1357  }
1358  return a;
1359 }
1360 
1362 {
1363  return legalStates[ra->GetStateHash(arm)];
1364 }
1365 
1367 {
1368  int cnt = 0;
1369  //std::vector<bool> legalStates;
1370  printf("Getting legal states and tip positions\n");
1371  legalStates.resize(512*512*512);
1372  std::deque<armAngles> q;
1373  q.push_back(init);
1374  tipPositionTables.resize(200*200);
1375  while (q.size() > 0)
1376  {
1377  if ((cnt++%10000) == 0)
1378  printf("(%d) Q size: %d\n", cnt, (int)q.size());
1379  armAngles a = q.front();
1380  q.pop_front();
1381  std::vector<armAngles> moves;
1382  ra->GetSuccessors(a, moves);
1383  for (unsigned int x = 0; x < moves.size(); x++)
1384  {
1385  if (legalStates[ra->GetStateHash(moves[x])])
1386  continue;
1387  legalStates[ra->GetStateHash(moves[x])] = true;
1388  q.push_back(moves[x]);
1389  double x1, y1;
1390  ra->GetTipPosition(moves[x], x1, y1);
1391  int tipIndex = TipPositionIndex(x1, y1);
1392  tipPositionTables[tipIndex].push_back(moves[x]);
1393  }
1394  }
1395  printf("Done\n");
1396 }
1397 
armAngles::SetAngle
void SetAngle(int which, int value)
Definition: RoboticArm.cpp:43
ArmToTipHeuristic::NumTipPositionIndices
int NumTipPositionIndices() const
Definition: RoboticArm.h:459
RoboticArm::GetAction
armRotations GetAction(const armAngles &s1, const armAngles &s2) const
Definition: RoboticArm.cpp:219
line2d::start
recVec start
Definition: GLUtil.h:160
RoboticArm::GetTolerance
double GetTolerance() const
Definition: RoboticArm.h:94
RoboticArm::GetStateFromHash
void GetStateFromHash(uint64_t hash, armAngles &) const
Definition: RoboticArm.cpp:390
ConfigEnvironment
Definition: ConfigEnvironment.h:15
ConfigEnvironment::PopObstacle
void PopObstacle()
Definition: ConfigEnvironment.h:22
recVec
A generic vector (essentially the same as a point, but offers normalization)
Definition: GLUtil.h:78
armAngles::angles
uint64_t angles
Definition: RoboticArm.h:39
RoboticArm::OpenGLDraw
virtual void OpenGLDraw() const
Definition: RoboticArm.cpp:404
RoboticArm.h
RoboticArm::sinTable
std::vector< double > sinTable
Definition: RoboticArm.h:155
recVec::z
GLdouble z
Definition: GLUtil.h:98
RoboticArm::ApplyAction
virtual void ApplyAction(armAngles &s, armRotations dir) const
Definition: RoboticArm.cpp:229
armRotations
Definition: RoboticArm.h:69
RoboticArm::GoalTest
bool GoalTest(const armAngles &node, const armAngles &goal) const
Definition: RoboticArm.cpp:362
ArmToTipHeuristic::HCost
double HCost(const armAngles &node1, const armAngles &node2) const
Definition: RoboticArm.cpp:610
tRotation
tRotation
Definition: RoboticArm.h:63
ArmToTipHeuristic::minTipDistancesTables
std::vector< uint16_t * > minTipDistancesTables
Definition: RoboticArm.h:442
ArmToTipHeuristic::distancesTables
std::vector< uint16_t * > distancesTables
Definition: RoboticArm.h:441
ArmToTipHeuristic::legalStateTable
uint8_t * legalStateTable
Definition: RoboticArm.h:438
RoboticArm::BuildSinCosTables
void BuildSinCosTables()
Definition: RoboticArm.cpp:589
RoboticArm::GetTipPosition
void GetTipPosition(armAngles &s, double &x, double &y)
Definition: RoboticArm.cpp:108
ArmToArmHeuristic::distances
std::vector< std::vector< uint16_t > > distances
Definition: RoboticArm.h:183
ConfigEnvironment::AddObstacle
void AddObstacle(line2d obs)
Definition: ConfigEnvironment.h:21
RoboticArm::GetSin
double GetSin(int angle) const
Definition: RoboticArm.cpp:579
ArmToTipHeuristic::GenerateMaxDistHeuristics
int GenerateMaxDistHeuristics(const armAngles &sampleArm, const int numHeuristics)
Definition: RoboticArm.cpp:965
ArmToTipHeuristic::GenerateRandomHeuristic
void GenerateRandomHeuristic(const armAngles &sampleArm)
Definition: RoboticArm.cpp:913
line2d::end
recVec end
Definition: GLUtil.h:161
ArmToTipHeuristic::GenerateCPDB
void GenerateCPDB()
Definition: RoboticArm.cpp:635
ArmToTipHeuristic::GenerateNextDepth
uint64_t GenerateNextDepth(FILE *curFile, FILE *nextFile, uint16_t curDistance, uint16_t *distances, uint16_t *minTipDistances, uint16_t *maxTipDistances, armAngles &lastAdded)
Definition: RoboticArm.cpp:752
ArmToTipHeuristic::ArmAnglesIndex
uint64_t ArmAnglesIndex(const armAngles &arm) const
Definition: RoboticArm.cpp:660
ArmToTipHeuristic::GenerateHeuristicSub
int GenerateHeuristicSub(const armAngles &sampleArm, const bool quiet, armAngles *goals, const int numGoals, uint16_t *distances, uint16_t *minTipDistances, uint16_t *maxTipDistances, armAngles &lastAdded)
Definition: RoboticArm.cpp:794
ArmToTipHeuristic::GenerateHeuristic
int GenerateHeuristic(const armAngles &sampleArm, armAngles &goal)
Definition: RoboticArm.cpp:937
width
int width
Definition: SFML_HOG.cpp:54
RoboticArm::AddObstacle
void AddObstacle(line2d obs)
Definition: RoboticArm.cpp:247
RoboticArm::GetStateHash
uint64_t GetStateHash(const armAngles &node) const
Definition: RoboticArm.cpp:379
ArmToTipHeuristic::tablesNumArms
std::vector< uint16_t > tablesNumArms
Definition: RoboticArm.h:444
ArmToArmHeuristic::optimizeLocations
bool optimizeLocations
Definition: RoboticArm.h:181
RoboticArm::InvertAction
virtual bool InvertAction(armRotations &a) const
Definition: RoboticArm.cpp:239
ArmToTipHeuristic::ra
RoboticArm * ra
Definition: RoboticArm.h:435
armAngles::GetAngle
int GetAngle(int which) const
Definition: RoboticArm.cpp:38
TemplateAStar::GetPath
void GetPath(environment *env, const state &from, const state &to, std::vector< state > &thePath)
Perform an A* search between two states.
Definition: TemplateAStar.h:214
ArmToArmHeuristic::TipPositionIndex
int TipPositionIndex(const double x, const double y, const double minX=-1.0, const double minY=-1.0, const double width=2.0)
Definition: RoboticArm.cpp:1262
ArmToArmHeuristic::tipPositionTables
std::vector< std::vector< armAngles > > tipPositionTables
Definition: RoboticArm.h:185
RoboticArm::GetActionHash
uint64_t GetActionHash(armRotations act) const
Definition: RoboticArm.cpp:399
RoboticArm::DOF
int DOF
Definition: RoboticArm.h:148
armRotations::rotations
uint16_t rotations
Definition: RoboticArm.h:73
armRotations::GetRotation
tRotation GetRotation(int which) const
Definition: RoboticArm.cpp:15
ArmToTipHeuristic::TipPositionIndex
int TipPositionIndex(const double x, const double y, const double minX, const double minY, const double width) const
Definition: RoboticArm.cpp:674
RoboticArm::HCost
virtual double HCost(const armAngles &) const
Heuristic value between node and the stored goal.
Definition: RoboticArm.h:112
armAngles::IsGoalState
bool IsGoalState() const
Definition: RoboticArm.cpp:90
armAngles::GetNumArms
int GetNumArms() const
Definition: RoboticArm.cpp:52
RoboticArm::LegalArmConfig
bool LegalArmConfig(armAngles &a) const
Definition: RoboticArm.cpp:525
ArmToArmHeuristic::IsLegalState
bool IsLegalState(armAngles &arm)
Definition: RoboticArm.cpp:1361
RoboticArm::GenerateLineSegments
void GenerateLineSegments(const armAngles &a, std::vector< line2d > &armSegments) const
Definition: RoboticArm.cpp:542
ArmToTipHeuristic::m_TableComplete
bool m_TableComplete
Definition: RoboticArm.h:436
SearchEnvironment::GetPathLength
virtual double GetPathLength(std::vector< state > &neighbors)
Definition: SearchEnvironment.h:144
ArmToTipHeuristic::legalGoalTable
uint8_t * legalGoalTable
Definition: RoboticArm.h:439
ArmToArmHeuristic::HCost
double HCost(const armAngles &node1, const armAngles &node2) const
Definition: RoboticArm.cpp:1242
armAngles::SetNumArms
void SetNumArms(int count)
Definition: RoboticArm.cpp:57
RoboticArm::GetSuccessors
void GetSuccessors(const armAngles &nodeID, std::vector< armAngles > &neighbors) const
Definition: RoboticArm.cpp:133
line2d
‍**
Definition: GLUtil.h:155
ArmToArmHeuristic::legalStates
std::vector< bool > legalStates
Definition: RoboticArm.h:186
RoboticArm::armSegments
std::vector< line2d > armSegments
Definition: RoboticArm.h:158
RoboticArm
Definition: RoboticArm.h:88
TemplateAStar
A templated version of A*, based on HOG genericAStar.
Definition: TemplateAStar.h:73
ArmToTipHeuristic::maxTipDistancesTables
std::vector< uint16_t * > maxTipDistancesTables
Definition: RoboticArm.h:443
ArmToTipHeuristic::NumArmAnglesIndices
uint64_t NumArmAnglesIndices(const armAngles &arm) const
Definition: RoboticArm.h:451
TemplateAStar.h
kRotateCW
@ kRotateCW
Definition: RoboticArm.h:66
ArmToArmHeuristic::canonicalStates
std::vector< armAngles > canonicalStates
Definition: RoboticArm.h:184
armRotations::SetRotation
void SetRotation(int which, tRotation dir)
Definition: RoboticArm.cpp:26
ArmToTipHeuristic::UseHeuristic
uint16_t UseHeuristic(const armAngles &s, armAngles &g, uint16_t *distances) const
Definition: RoboticArm.cpp:1022
RoboticArm::GetCos
double GetCos(int angle) const
Definition: RoboticArm.cpp:584
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
RoboticArm::obstacles
std::vector< line2d > obstacles
Definition: RoboticArm.h:157
GLUtil.h
RoboticArm::GetActions
void GetActions(const armAngles &nodeID, std::vector< armRotations > &actions) const
Definition: RoboticArm.cpp:177
RoboticArm::ce
ConfigEnvironment * ce
Definition: RoboticArm.h:163
ArmToArmHeuristic::AddDiffTable
void AddDiffTable()
Definition: RoboticArm.cpp:1277
RoboticArm::PopObstacle
void PopObstacle()
Definition: RoboticArm.cpp:255
ArmToArmHeuristic::SelectStartNode
armAngles SelectStartNode()
Definition: RoboticArm.cpp:1318
RoboticArm::heuristics
std::vector< RoboticArmHeuristic * > heuristics
Definition: RoboticArm.h:162
RoboticArm::~RoboticArm
virtual ~RoboticArm()
Definition: RoboticArm.cpp:103
ArmToTipHeuristic::UpdateTipDistances
void UpdateTipDistances(armAngles &arm, uint16_t distance, uint16_t *minTipDistances, uint16_t *maxTipDistances)
Definition: RoboticArm.cpp:729
ArmToTipHeuristic::tipPositionTables
std::vector< armAngles > * tipPositionTables
Definition: RoboticArm.h:446
ArmToTipHeuristic::ArmToTipHeuristic
ArmToTipHeuristic(RoboticArm *r)
Definition: RoboticArm.cpp:600
RoboticArm::GetNextState
virtual void GetNextState(const armAngles &currents, armRotations dir, armAngles &news) const
Definition: RoboticArm.cpp:489
ArmToTipHeuristic::ValidGoalPosition
bool ValidGoalPosition(double goalX, double goalY)
Definition: RoboticArm.cpp:1076
ConfigEnvironment::StoreGoal
void StoreGoal(recVec &g)
Stores the goal for use by single-state HCost.
Definition: ConfigEnvironment.h:53
armAngles
Definition: RoboticArm.h:29
RoboticArm::cosTable
std::vector< double > cosTable
Definition: RoboticArm.h:156
RoboticArm::DrawLine
void DrawLine(line2d l) const
Definition: RoboticArm.cpp:479
RoboticArm::tolerance
double tolerance
Definition: RoboticArm.h:149
armAngles::SetGoal
void SetGoal(double x, double y)
Definition: RoboticArm.cpp:66
TWOPI
static const double TWOPI
Definition: GLUtil.h:65
ArmToTipHeuristic::ReadArmAngles
int ReadArmAngles(FILE *file, armAngles &a)
Definition: RoboticArm.cpp:708
RoboticArm::armLength
double armLength
Definition: RoboticArm.h:149
recVec::y
GLdouble y
Definition: GLUtil.h:98
ArmToArmHeuristic::GenerateLegalStates
void GenerateLegalStates(armAngles &init)
Definition: RoboticArm.cpp:1366
ArmToArmHeuristic::ra
RoboticArm * ra
Definition: RoboticArm.h:182
RoboticArm::GCost
virtual double GCost(const armAngles &, const armAngles &) const
Definition: RoboticArm.h:118
ArmToTipHeuristic::GenerateTipPositionTables
void GenerateTipPositionTables(armAngles &sampleArm)
Definition: RoboticArm.cpp:1187
RoboticArm::LegalState
bool LegalState(armAngles &a) const
Definition: RoboticArm.cpp:495
recVec::x
GLdouble x
Definition: GLUtil.h:98
RoboticArm::GetRandomState
armAngles GetRandomState()
Definition: RoboticArm.cpp:264
RoboticArm::RoboticArm
RoboticArm(int DOF, double armLength, double tolerance=0.01)
Definition: RoboticArm.cpp:96
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
ArmToTipHeuristic::WriteArmAngles
int WriteArmAngles(FILE *file, armAngles &a)
Definition: RoboticArm.cpp:690
kNoRotation
@ kNoRotation
Definition: RoboticArm.h:65
kRotateCCW
@ kRotateCCW
Definition: RoboticArm.h:64
ArmToTipHeuristic::GenerateLegalStateTable
void GenerateLegalStateTable(armAngles &legalArm)
Definition: RoboticArm.cpp:1115
ArmToArmHeuristic::ArmToArmHeuristic
ArmToArmHeuristic(RoboticArm *r, armAngles &initial, bool optimize=false)
Definition: RoboticArm.cpp:1235
RoboticArm::TipPositionIndex
int TipPositionIndex(armAngles &s, const double minX=-1, const double minY=-1, const double width=2)
Definition: RoboticArm.cpp:117
RoboticArm::states
std::vector< recVec > states
Definition: RoboticArm.h:160
armAngles::GetGoal
void GetGoal(double &x, double &y) const
Definition: RoboticArm.cpp:79