atlasrrt.c
Go to the documentation of this file.
1 #include "atlasrrt.h"
2 
3 #include "chart.h"
4 #include "filename.h"
5 #include "random.h"
6 #include "algebra.h"
7 #include "samples.h"
8 #include "vector.h"
9 #include "heap.h"
10 
11 #include "boolean.h"
12 
13 #include <string.h>
14 #include <math.h>
15 
31 #define ADD_ALL 0
32 
38 #define ADD_LAST 1
39 
46 #define ADD_LAST_NO_REP 2
47 
53 #define ADD_NONE 3
54 
55 /**********************************************************************************************************/
56 /**********************************************************************************************************/
57 /**********************************************************************************************************/
58 
66 #define EXTEND_RRT 0
67 
76 #define CONNECT_RRTs 1
77 
83 #define CONNECT_SAMPLES 2
84 
92 #define CONNECT_SAFE 3
93 
94 
104 typedef struct {
105  unsigned int addMode;
106  boolean revisitCharts;
108  boolean checkCollisions;
109  boolean onManifold;
113  double maxLength;
114  double (*costF)(Tparameters*,boolean,double*,void*);
115  void *costData;
117 
118 /**********************************************************************************************************/
119 /**********************************************************************************************************/
120 
129 typedef struct {
130  boolean reachedGoal;
131  boolean reachedQrand;
136  boolean blocked;
137  boolean tooFar;
138  boolean collision;
139  boolean validChart;
142  unsigned int lastID;
145  unsigned int nCreatedCharts;
147  unsigned int tree;
149  double *deltaParam;
153  double desiredLength;
155  double maxLength;
156  double length;
157  double stepLength;
159  double distQrand;
161  double distGoal;
163  double distOrigin;
164  double maxDistOrigin;
166  double delta;
168  double cost;
170 
171 /**********************************************************************************************************/
172 /**********************************************************************************************************/
173 
186 void InitBranchConfig(unsigned int mode,TAtlasRRTBranchConfig *config);
187 
188 
189 /**********************************************************************************************************/
190 /**********************************************************************************************************/
191 
206 void InitBranchStatus(double epsilon,double delta,TAtlasRRTBranchConfig *config,
207  TSampleInfo *near,double *randSample,double *goalSample,
208  Tatlasrrt *ar,TAtlasRRTBranchStatus *status);
209 
221 
230 
231 /**********************************************************************************************************/
232 /**********************************************************************************************************/
233 
243 void InitSampleInfo(unsigned int m,unsigned int k,TSampleInfo *si);
244 
255 void SetSampleInfo(unsigned int m,unsigned int k,TSampleInfo *si_dst,TSampleInfo *si_src);
256 
268 void SetSampleInfoFromNode(unsigned int n,Tatlasrrt *ar,TSampleInfo *si);
269 
277 void DeleteSampleInfo(TSampleInfo *si);
278 
279 /**********************************************************************************************************/
280 /**********************************************************************************************************/
281 /**********************************************************************************************************/
282 
295 
309 
319 
330 
341 void NewAtlasRRTDistanceQrand(double dqr,TAtlasRRTStatistics *arst);
342 
351 
361 
370 
380 
390 
400 
411 
421 
432 
443 
455 
465 
478 
488 
498 
507 
526 
533 
540 
547 
548 
549 /******************************************************************************/
550 /******************************************************************************/
551 /******************************************************************************/
552 
554 {
555  if (arst!=NULL)
556  {
557  arst->n=0;
558 
559  arst->nBranch=0;
560  arst->nNoEmptyBranch=0;
561 
562  arst->nTreeConnection=0;
563  arst->nNoEmptyTreeConnection=0;
564 
565  arst->nStep=0;
566  arst->dQrand=0.0;
567 
568  arst->nQrandReached=0;
569  arst->nNotInDomain=0;
570  arst->nCollision=0;
571  arst->nTooFar=0;
572  arst->nTooLong=0;
573  arst->nOverlap=0;
574 
575  arst->nErrorNewChart=0;
576  arst->nNoConvergent=0;
577  arst->nOutOfChart=0;
578  arst->nLargeCurvature=0;
579  arst->nDirLargeCurvature=0;
580 
581  arst->nStepReduction=0;
582 
583  arst->nSample=0;
584  arst->nChart=0;
585  arst->nNoConnect=0;
586  arst->nSingular=0;
587 
588  arst->nRandom=0;
589  arst->nRejections=0;
590 
591  arst->nCollisionChecks=0;
592  }
593 }
594 
596 {
597  if (arst!=NULL) arst->nBranch++;
598 }
599 
601 {
602  if (arst!=NULL) arst->nNoEmptyBranch++;
603 }
604 
606 {
607  if (arst!=NULL) arst->nTreeConnection++;
608 }
609 
611 {
612  if (arst!=NULL) arst->nNoEmptyTreeConnection++;
613 }
614 
616 {
617  if (arst!=NULL) arst->dQrand+=dqr;
618 }
619 
621 {
622  if (arst!=NULL) arst->nStep++;
623 }
624 
626 {
627  if (arst!=NULL) arst->nNoConvergent++;
628 }
629 
631 {
632  if (arst!=NULL) arst->nQrandReached++;
633 }
634 
636 {
637  if (arst!=NULL) arst->nNotInDomain++;
638 }
639 
641 {
642  if (arst!=NULL) arst->nCollision++;
643 }
644 
646 {
647  if (arst!=NULL) arst->nTooLong++;
648 }
649 
651 {
652  if (arst!=NULL) arst->nTooFar++;
653 }
654 
656 {
657  if (arst!=NULL) arst->nOverlap++;
658 }
659 
661 {
662  if (arst!=NULL) arst->nOutOfChart++;
663 }
664 
666 {
667  if (arst!=NULL) arst->nErrorNewChart++;
668 }
669 
671 {
672  if (arst!=NULL) arst->nLargeCurvature++;
673 }
674 
676 {
677  if (arst!=NULL) arst->nDirLargeCurvature++;
678 }
679 
681 {
682  if (arst!=NULL) arst->nStepReduction++;
683 }
684 
686 {
687  if (arst!=NULL) arst->nSample++;
688 }
689 
691 {
692  if (arst!=NULL) arst->nChart++;
693 }
694 
696 {
697  if (arst!=NULL) arst->nNoConnect++;
698 }
699 
701 {
702  if (arst!=NULL) arst->nSingular++;
703 }
704 
706 {
707  if (arst!=NULL) arst->nRandom++;
708 }
709 
711 {
712  if (arst!=NULL) arst->nRejections++;
713 }
714 
716 {
717  if (arst!=NULL) arst->nCollisionChecks++;
718 }
719 
721 {
722  if ((arst1!=NULL)&&(arst2!=NULL))
723  {
724  if (arst1->n==0)
725  arst2->n++;
726  else
727  arst2->n+=arst1->n;
728 
729  arst2->nBranch+=arst1->nBranch;
730  arst2->nNoEmptyBranch+=arst1->nNoEmptyBranch;
731 
732  arst2->nTreeConnection+=arst1->nTreeConnection;
734 
735  arst2->nStep+=arst1->nStep;
736  arst2->dQrand+=arst1->dQrand;
737 
738  arst2->nQrandReached+=arst1->nQrandReached;
739  arst2->nNotInDomain+=arst1->nNotInDomain;
740  arst2->nCollision+=arst1->nCollision;
741  arst2->nTooLong+=arst1->nTooLong;
742  arst2->nTooFar+=arst1->nTooFar;
743  arst2->nOverlap+=arst1->nOverlap;
744 
745  arst2->nErrorNewChart+=arst1->nErrorNewChart;
746  arst2->nNoConvergent+=arst1->nNoConvergent;
747  arst2->nOutOfChart+=arst1->nOutOfChart;
748  arst2->nLargeCurvature+=arst1->nLargeCurvature;
749  arst2->nDirLargeCurvature+=arst1->nDirLargeCurvature;
750 
751  arst2->nStepReduction+=arst1->nStepReduction;
752 
753  arst2->nSample+=arst1->nSample;
754  arst2->nChart+=arst1->nChart;
755 
756  arst2->nNoConnect+=arst1->nNoConnect;
757  arst2->nSingular+=arst1->nSingular;
758 
759  arst2->nRandom+=arst1->nRandom;
760  arst2->nRejections+=arst1->nRejections;
761 
762  arst2->nCollisionChecks+=arst1->nCollisionChecks;
763  }
764 }
765 
767 {
768  if (arst!=NULL)
769  {
770  unsigned int m,nExt;
771 
772  if (arst->n==0)
773  arst->n=1;
774 
775  nExt=arst->nBranch+arst->nTreeConnection;
776 
777  fprintf(stderr,"%% **************************************************\n");
778  if (arst->n>1)
779  fprintf(stderr,"AtlasRRT Statistics (averaged over %u repetitions)\n",arst->n);
780  else
781  fprintf(stderr,"AtlasRRT Statistics\n\n");
782  fprintf(stderr," Num. random samples : %.2f\n",
783  (double)arst->nRandom/(double)arst->n);
784  fprintf(stderr," Num. rejected random samples : %.2f (%.2f)\n",
785  (double)arst->nRejections/(double)arst->n,
786  (double)arst->nRejections/(double)arst->nRandom);
787  fprintf(stderr," Num. accepted random samples : %.2f (%.2f)\n",
788  (double)(arst->nRandom-arst->nRejections)/(double)arst->n,
789  (double)(arst->nRandom-arst->nRejections)/(double)arst->nRandom);
790 
791  /* if the chart sampling radius is potentially different for each chart
792  we print information about the extreme/average chart sampling radius. */
793  #if (ADJUST_SA==1)
794  if ((arst->n==1)&&(ar!=NULL))
795  {
796  unsigned int i;
797  double miSr,maSr,avSr,sr;
798 
799  miSr=+INF;
800  maSr=-INF;
801  avSr=0.0;
802  for(i=0;i<ar->nc;i++)
803  {
805  if (sr<miSr)
806  miSr=sr;
807  if (sr>maSr)
808  maSr=sr;
809  avSr+=sr;
810  }
811  fprintf(stderr," Sampling radius info : %.2f <-- %.2f --> %.2f\n",
812  miSr,avSr/(double)ar->nc,maSr);
813  }
814  #endif
815 
816  if ((arst->n==1)&&(ar!=NULL)&&(DynamicDomainRRT(&(ar->rrt))))
817  {
818  unsigned int i,n;
819  double miDD,maDD,avDD,r;
820 
821  miDD=+INF;
822  maDD=-INF;
823  avDD=0.0;
824  n=0;
825  for(i=0;i<ar->ns;i++)
826  {
827  r=GetDynamicDomainRadius(i,&(ar->rrt));
828  if (r>0)
829  {
830  if (r<miDD)
831  miDD=r;
832  if (r>maDD)
833  maDD=r;
834  avDD+=r;
835  n++;
836  }
837  }
838  if (n==0)
839  fprintf(stderr," No dynamic domain effect.");
840  else
841  fprintf(stderr," Dynamic domain radius : %.2f <-- %.2f --> %.2f (%u/%u)\n",
842  miDD,avDD/(double)n,maDD,n,ar->ns);
843  }
844  fprintf(stderr," Average distance to Qrand : %.2f\n",
845  arst->dQrand/(double)arst->nBranch);
846 
847  if (arst->nTreeConnection>0)
848  {
849  fprintf(stderr," Num. direct RRT extensions : %.2f\n",
850  (double)arst->nBranch/(double)arst->n);
851  m=arst->nNoEmptyBranch;
852  fprintf(stderr," Num. no-empty direct extensions : %.2f (%.2f)\n",
853  (double)m/(double)arst->n,
854  (double)m/(double)arst->nBranch);
855 
856  fprintf(stderr," Num. RRT connections : %.2f\n",
857  (double)arst->nTreeConnection/(double)arst->n);
858  m=arst->nNoEmptyTreeConnection;
859  fprintf(stderr," Num. no-empty RRT connections : %.2f (%.2f)\n",
860  (double)m/(double)arst->n,
861  (double)m/(double)arst->nTreeConnection);
862 
863  fprintf(stderr," Total branches : %.2f\n",
864  (double)nExt/(double)arst->n);
865  m=(arst->nNoEmptyBranch+arst->nNoEmptyTreeConnection);
866  fprintf(stderr," Total no-empty branches : %.2f (%.2f)\n",
867  (double)m/(double)arst->n,
868  (double)m/(double)nExt);
869  }
870  else
871  {
872  fprintf(stderr," Total branches : %.2f\n",
873  (double)arst->nBranch/(double)arst->n);
874  m=arst->nNoEmptyBranch;
875  fprintf(stderr," Total no-empty branches : %.2f (%.2f)\n",
876  (double)m/(double)arst->n,
877  (double)m/(double)arst->nBranch);
878  }
879  fprintf(stderr," Reasons to stop the branch/connection\n");
880  m=arst->nQrandReached;
881  fprintf(stderr," q_rand reached : %.2f (%.2f)\n",
882  (double)m/(double)arst->n,
883  (double)m/(double)nExt);
884 
885  m=arst->nNotInDomain;
886  fprintf(stderr," Out of domain : %.2f (%.2f)\n",
887  (double)m/(double)arst->n,
888  (double)m/(double)nExt);
889 
890  m=arst->nCollision;
891  fprintf(stderr," Collision : %.2f (%.2f)\n",
892  (double)m/(double)arst->n,
893  (double)m/(double)nExt);
894 
895  m=arst->nTooLong;
896  fprintf(stderr," Long branch : %.2f (%.2f)\n",
897  (double)m/(double)arst->n,
898  (double)m/(double)nExt);
899 
900  m=arst->nTooFar;
901  fprintf(stderr," Too far from q_near : %.2f (%.2f)\n",
902  (double)m/(double)arst->n,
903  (double)m/(double)nExt);
904 
905  m=arst->nOverlap;
906  fprintf(stderr," Avoid overlap : %.2f (%.2f)\n",
907  (double)m/(double)arst->n,
908  (double)m/(double)nExt);
909 
910  m=arst->nSingular;
911  fprintf(stderr," Singularity : %.2f (%.2f)\n",
912  (double)m/(double)arst->n,
913  (double)m/(double)nExt);
914 
915  fprintf(stderr," Num. extension steps : %.2f\n",
916  (double)arst->nStep/(double)arst->n);
917  fprintf(stderr," Num. steps per branch : %.2f\n",
918  (double)arst->nStep/(double)nExt);
919  fprintf(stderr," Num. step reductions : %.2f\n",
920  (double)arst->nStepReduction/(double)arst->n);
921 
922  fprintf(stderr," Num. collision checks : %.2f\n",
923  (double)arst->nCollisionChecks/(double)arst->n);
924 
925 
926  fprintf(stderr," Num. samples in (bi)RRT : %.2f\n",
927  (double)arst->nSample/(double)arst->n);
928  fprintf(stderr," Samples per non-empty extens. : %.2f\n",
929  (double)arst->nSample/(double)(arst->nNoEmptyBranch+arst->nNoEmptyTreeConnection));
930 
931  fprintf(stderr," Num. charts : %.2f\n",
932  (double)arst->nChart/(double)arst->n);
933 
934  fprintf(stderr," Reasons to create charts\n");
935 
936  m=arst->nErrorNewChart;
937  fprintf(stderr," Error defining chart : %.2f (%.2f)\n",
938  (double)m/(double)arst->n,
939  (double)m/(double)arst->nChart);
940 
941  m=arst->nOutOfChart;
942  fprintf(stderr," Out of radius : %.2f (%.2f)\n",
943  (double)m/(double)arst->n,
944  (double)m/(double)arst->nChart);
945 
946  m=arst->nNoConvergent;
947  fprintf(stderr," Large or convergence error : %.2f (%.2f)\n",
948  (double)m/(double)arst->n,
949  (double)m/(double)arst->nChart);
950 
951  #if (GET_ATLASRRT_GLOBAL_CURV_CHECK)
952  m=arst->nLargeCurvature;
953  fprintf(stderr," Curvature error : %.2f (%.2f)\n",
954  (double)m/(double)arst->n,
955  (double)m/(double)arst->nChart);
956  #endif
957 
958  m=arst->nDirLargeCurvature;
959  fprintf(stderr," Directional curvature error : %.2f (%.2f)\n",
960  (double)m/(double)arst->n,
961  (double)m/(double)arst->nChart);
962 
963  m=arst->nNoConnect;
964  fprintf(stderr," Num. no-intersect with parent : %.2f (%.2f)\n",
965  (double)m/(double)arst->n,
966  (double)m/(double)arst->nChart);
967 
968  fprintf(stderr," Samples per chart : %.2f\n",
969  (double)arst->nSample/(double)arst->nChart);
970  }
971 }
972 
974 {
975 }
976 
977 
978 /******************************************************************************/
979 /******************************************************************************/
980 /******************************************************************************/
1018 double New_AddBranchToAtlasRRT(Tparameters *pr,unsigned int it,TAtlasRRTBranchConfig *config,
1019  unsigned int i_near,double *randSample,double *goalSample,
1020  void *st,TAtlasRRTBranchStatus *status,
1021  unsigned int *ns,double ***path,
1022  Tatlasrrt *ar);
1023 
1097 double AddBranchToAtlasRRT(Tparameters *pr,unsigned int it,
1098  unsigned int addMode,boolean revisitCharts,
1099  boolean checkCollisions,boolean onManifold,
1100  boolean explorationSample,
1101  double maxLength,unsigned int i_near,
1102  double *origRandSample,
1103  double *goalSample,void *st,
1104  unsigned int *lastSampleID,
1105  boolean *reachedQRand,boolean *reachedGoal,
1106  unsigned int *ns,double ***path,
1107  double (*costF)(Tparameters*,boolean,double*,void*),
1108  void *costData,
1109  Tatlasrrt *ar);
1110 
1111 
1136 void New_NewTemptativeSample(Tparameters *pr,unsigned int it,
1137  TAtlasRRTBranchConfig *config,
1138  TAtlasRRTBranchStatus *status,
1139  TSampleInfo *current,TSampleInfo *next,
1140  TSampleInfo *rand,double *randSample,
1141  void * st,Tatlasrrt *ar);
1142 
1203 void NewTemptativeSample(Tparameters *pr,unsigned int it,unsigned int *nChanges,
1204  boolean revisitCharts,boolean chartCreated,
1205  boolean checkCollisions,boolean onManifold,
1206  TSampleInfo *currentSampleInfo,double *currentParam,
1207  double *origRandSample,
1208  unsigned int *randChart,double *randParam,double *randSample,
1209  double currentDelta,double d,double *deltaParam,
1210  unsigned int *nextChart,double *nextParam,double *nextSample,
1211  void *st,double (*costF)(Tparameters*,boolean,double*,void*),
1212  void *costData,double *cost,boolean *blocked,
1213  boolean *inCollision,boolean *valid,
1214  Tatlasrrt *ar);
1215 
1239 double AddSample2AtlasRRT(Tparameters *pr,unsigned int tree,
1240  unsigned int *currentID,
1241  unsigned int nextChart,double *nextParam,double *nextSample,
1242  double dp,double cost,Tatlasrrt *ar);
1272 boolean AddChart2AtlasRRT(Tparameters *pr,unsigned int tree,unsigned int it,
1273  TSampleInfo *currentSampleInfo,
1274  boolean* intersectParent,Tatlasrrt *ar);
1275 
1287 void PopulateWithSamples(Tparameters *pr,unsigned int id,Tatlasrrt *ar);
1288 
1298 void AddChart2Tree(unsigned int tree,unsigned int chartId,Tatlasrrt* ar);
1299 
1300 
1319  unsigned int samplingMode,double *randSample,
1320  TAtlasRRTBranchStatus *status,
1321  TSampleInfo *current,TSampleInfo *rand,Tatlasrrt *ar);
1322 
1353 boolean PointTowardRandSample(unsigned int cId,double d,double *t,
1354  unsigned int samplingMode,
1355  boolean onManifold,double *origRandSample,
1356  unsigned int *randChart,
1357  double *randParam,double *randSample,
1358  double *deltaParam,Tatlasrrt* ar);
1359 
1377 unsigned int ReconstructAtlasRRTPath(Tparameters *pr,unsigned int sID,
1378  double *pl,unsigned int *ns,
1379  double ***path,Tatlasrrt *ar);
1380 
1399 unsigned int Steps2PathinAtlasRRT(Tparameters *pr,Tvector *steps,double *pl,double* pc,
1400  unsigned int *ns,double ***path,Tatlasrrt *ar);
1401 
1413 void SmoothPathInAtlasRRT(Tparameters *pr,unsigned int sID,Tatlasrrt* ar);
1414 
1434 unsigned int AddStepToAtlasRRTstar(Tparameters* pr,
1435  unsigned int it,boolean expand2Goal,
1436  unsigned int i_near,double *q_rand,
1437  unsigned int *id_goal,double *goal,
1438  TAtlasRRTStatistics *arst,
1439  Tatlasrrt *ar);
1440 
1465 void WireAtlasRRTstar(Tparameters *pr,
1466  unsigned int id_new,unsigned int i_near,double gamma,
1467  unsigned int nn,unsigned int *n,double **c,
1468  double h,Theap *q,unsigned int *t,
1469  TAtlasRRTStatistics *arst,Tatlasrrt *ar);
1470 
1493  unsigned int id_new,double gamma,
1494  unsigned int nn,unsigned int *n,double *c,
1495  Tvector *steps,double *l,
1496  TAtlasRRTStatistics *arst,Tatlasrrt *ar);
1497 
1513 void AtlasRRTstarCloseIteration(unsigned int it,unsigned int id_goal,
1514  double time,double gamma,
1515  double *times,double *costs,
1516  Tatlasrrt *ar);
1517 
1533 void AtlasBiRRTstarCloseIteration(unsigned int it,double l,
1534  double time,double gamma,
1535  double *times,double *costs,
1536  Tatlasrrt *ar);
1537 
1547 void SaveAtlasRRTSampleInfo(FILE *f,TSampleInfo *si,Tatlasrrt *ar);
1548 
1558 void SaveAtlasRRTChartInfo(FILE *f,TChartInfo *ci,Tatlasrrt *ar);
1559 
1560 
1570 void LoadAtlasRRTSampleInfo(FILE *f,TSampleInfo *si,Tatlasrrt *ar);
1571 
1581 void LoadAtlasRRTChartInfo(FILE *f,TChartInfo *ci,Tatlasrrt *ar);
1582 
1602 void PlotQrand(Tparameters *pr,char *prefix,unsigned int inear,
1603  unsigned int c_rand,double *t_rand,double *q_rand,
1604  unsigned int xID,unsigned int yID,unsigned int zID,
1605  Tatlasrrt *ar);
1606 
1625 void PlotConnection(Tparameters *pr,char *prefix,
1626  unsigned int target,unsigned int near,unsigned int end,
1627  unsigned int xID,unsigned int yID,unsigned int zID,
1628  Tatlasrrt *ar);
1629 
1630 /******************************************************************************/
1631 /******************************************************************************/
1632 /******************************************************************************/
1633 
1634 void InitBranchStatus(double epsilon,double delta,TAtlasRRTBranchConfig *config,
1635  TSampleInfo *near,double *randSample,double *goalSample,
1636  Tatlasrrt *ar,TAtlasRRTBranchStatus *status)
1637 {
1638  /* Check if q_rand is already in the tree almost reached by the tree */
1639  status->distQrand=DistanceTopology(ar->m,ar->tp,near->s,randSample);
1640  if (config->onManifold)
1641  status->reachedQrand=(status->distQrand<epsilon);
1642  else
1643  status->reachedQrand=FALSE;
1644  /* initially the temporay q_rand will be the same as q_rand */
1645  status->reachedTmpQrand=status->reachedQrand;
1646 
1647  /* Check if goal is already reached */
1648  #if (EXPLORATION_RRT)
1649  status->distGoal=INF;
1650  #else
1651  if (goalSample!=NULL)
1652  status->distGoal=DistanceTopology(ar->m,ar->tp,near->s,goalSample);
1653  else
1654  status->distGoal=INF;
1655  #endif
1656  status->reachedGoal=(status->distGoal<delta);
1657 
1658  /* The new brach will belong to the tree of i_near */
1659  status->tree=GetRRTNodeTree(near->id,&(ar->rrt));
1660 
1661  status->nCreatedCharts=0;
1662 
1663  /* last sample in the branch */
1664  status->lastID=near->id;
1665 
1666  /* Interpolation step */
1667  status->delta=delta;
1668 
1669  /* Advance direction in tangent space (this is set in
1670  PointTowardRandSample) */
1671  NEW(status->deltaParam,ar->k,double);
1672 
1673  /* Vector of visited charts */
1674  InitVector(sizeof(unsigned int),CopyID,NULL,100,&(status->traversedCharts));
1675  NewVectorElement((void*)&(near->c),&(status->traversedCharts));
1676 
1677  /* Severeral branh advance diagnostics */
1678  status->blocked=FALSE; /* The branch is stopped for whatever reason */
1679  status->tooFar=FALSE; /* The end of the branch is too far */
1680  status->collision=FALSE; /* The branch collides with an obstacle */
1681  status->validChart=TRUE; /* The current chart is not valid. */
1682 
1683  /* Cost of the next node (this value is actually not used) */
1684  status->cost=0;
1685 
1686  /* Set the parameters defining the maximum span of the branch */
1687  if (config->maxLength<=0.0)
1688  {
1689  /* maxLenght not set -> auto-setting of the parameres */
1690  status->desiredLength=status->distQrand;
1691  status->maxLength=2.0*status->distQrand;
1692  }
1693  else
1694  {
1695  /* Use the parameters given by the user.
1696  Set desired=max to make the branch to grow to its maximum, if needed. */
1697  status->desiredLength=config->maxLength;
1698  status->maxLength=config->maxLength;
1699  }
1700 
1701  /* Branch length so far */
1702  status->length=0.0;
1703 
1704  /* maximum distance to origin */
1705  status->maxDistOrigin=status->distQrand;
1706  if (config->onManifold)
1707  status->maxDistOrigin*=1.1; /* add some margin */
1708 
1709  /* distance from the last node of the branch (so far) to the first one */
1710  status->distOrigin=0;
1711 
1712  /* Length of the last step along the branch */
1713  status->stepLength=0.0;
1714 }
1715 
1716 
1718 {
1719  free(status->deltaParam);
1720  DeleteVector(&(status->traversedCharts));
1721 }
1722 
1724  TAtlasRRTBranchStatus *status)
1725 {
1726  /* collision -> blocked but we include in anyway */
1727  return((!status->blocked)&&(!status->collision)&&
1728  (status->length<status->maxLength)&&
1729  (!status->reachedTmpQrand)&&(!status->reachedGoal)&&
1730  (!status->reachedQrand)&&(!status->tooFar));
1731 }
1732 
1733 void InitBranchConfig(unsigned int mode,TAtlasRRTBranchConfig *config)
1734 {
1735  switch (mode)
1736  {
1737  case EXTEND_RRT:
1738  config->addMode=ADD_ALL;
1739  config->revisitCharts=TRUE;
1740  config->checkCollisions=TRUE;
1741  config->onManifold=FALSE; /* will vary */
1742  config->explorationSample=FALSE; /* vary */
1743  config->maxLength=0.0;
1744  config->costF=NULL;
1745  config->costData=NULL;
1746  break;
1747  case CONNECT_RRTs:
1748  config->addMode=ADD_ALL;
1749  config->revisitCharts=FALSE;
1750  config->checkCollisions=TRUE;
1751  config->onManifold=TRUE;
1752  config->explorationSample=FALSE;
1753  config->maxLength=0.0;
1754  config->costF=NULL;
1755  config->costData=NULL;
1756  break;
1757  case CONNECT_SAMPLES:
1758  config->addMode=ADD_NONE;
1759  config->revisitCharts=TRUE;
1760  config->checkCollisions=TRUE;
1761  config->onManifold=TRUE;
1762  config->explorationSample=FALSE;
1763  config->maxLength=0.0;
1764  config->costF=NULL;
1765  config->costData=NULL;
1766  break;
1767  case CONNECT_SAFE:
1768  config->addMode=ADD_NONE;
1769  config->revisitCharts=TRUE;
1770  config->checkCollisions=FALSE;
1771  config->onManifold=TRUE;
1772  config->explorationSample=FALSE;
1773  config->maxLength=0.0;
1774  config->costF=NULL;
1775  config->costData=NULL;
1776  break;
1777  default:
1778  Error("Unknown mode in InitBranchConfig");
1779  }
1780 }
1781 
1782 void InitSampleInfo(unsigned int m,unsigned int k,TSampleInfo *si)
1783 {
1784  si->id=NO_UINT;
1785  NEW(si->s,m,double);
1786  NEW(si->t,k,double);
1787  si->pc=NO_UINT;
1788  si->c=NO_UINT;
1789  si->generateChart=0; /* FALSE */
1790  si->lsc=NO_UINT;
1791 }
1792 
1793 void SetSampleInfo(unsigned int m,unsigned int k,
1794  TSampleInfo *si_dst,TSampleInfo *si_src)
1795 {
1796  si_dst->id=si_src->id;
1797  memcpy(si_dst->s,si_src->s,m*sizeof(double));
1798  memcpy(si_dst->t,si_src->t,k*sizeof(double));
1799  si_dst->pc=si_src->pc;
1800  si_dst->c=si_src->c;
1801  si_dst->generateChart=si_src->generateChart;
1802  si_dst->lsc=si_src->lsc;
1803 }
1804 
1805 void SetSampleInfoFromNode(unsigned int n,Tatlasrrt *ar,TSampleInfo *si)
1806 {
1807  SetSampleInfo(ar->m,ar->k,si,ar->si[n]);
1808 }
1809 
1811 {
1812  free(si->s);
1813  free(si->t);
1814 }
1815 
1816 double New_AddBranchToAtlasRRT(Tparameters *pr,unsigned int it,
1817  TAtlasRRTBranchConfig *config,
1818  unsigned int i_near,
1819  double *randSample,double *goalSample,
1820  void *st,TAtlasRRTBranchStatus *status,
1821  unsigned int *ns,double ***path,
1822  Tatlasrrt *ar)
1823 {
1824  TSampleInfo current,next,rand,*near;
1825  boolean initData,intersectParent;
1826  double epsilon,delta;
1827  unsigned int ms,maxNodes,samplingMode;
1828 
1829  /* Sanity check */
1830  if (i_near==NO_UINT)
1831  Error("Extending a branch from nowhere");
1832 
1833  /* Get the parameters */
1834  epsilon=GetParameter(CT_EPSILON,pr);
1835  delta=GetParameter(CT_DELTA,pr);
1836  maxNodes=(unsigned int)GetParameter(CT_MAX_NODES_RRT,pr);
1837  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
1838 
1839  /* Info on the neareast sample */
1840  near=ar->si[i_near];
1841 
1842  /* Initialize the status of the branch */
1843  InitBranchStatus(epsilon,delta,config,near,randSample,goalSample,ar,status);
1844 
1845  /* If we have to store the path, init the storage*/
1846  if ((ns!=NULL)&&(path!=NULL))
1847  InitSamples(&ms,ns,path);
1848 
1849  if ((status->reachedQrand)||(status->reachedGoal))
1850  /* If q_rand/goal are alrady reached, there is not point
1851  in initializing the structures. */
1852  initData=FALSE;
1853  else
1854  {
1855  /* If the goal sample is not already reached, we prepare for the
1856  branch extension */
1857  initData=TRUE;
1858 
1859  /* q_near is the first 'current' (sample) of the branch */
1860  InitSampleInfo(ar->m,ar->k,&current);
1861  SetSampleInfoFromNode(i_near,ar,&current);
1862 
1863  InitSampleInfo(ar->m,ar->k,&next);
1864  InitSampleInfo(ar->m,ar->k,&rand);
1865 
1866  /* get a copy of the random sample. This will be modified while
1867  extending the branch. 'rand' is a temporary representation of
1868  'randSample' in the current chart, which changes along the
1869  branch */
1870  memcpy(rand.s,randSample,ar->m*sizeof(double));
1871 
1872  /* Detemine the direction of motion toward 'rand' from the 'current' */
1873  status->blocked=New_PointTowardRandSample(config,samplingMode,randSample,status,
1874  &current,&rand,ar);
1875  }
1876 
1877  #if (_DEBUG>1)
1878  printf(" Adding branch to RRT from sample %u (chart %u)\n",current.id,current.c);
1879  #endif
1880 
1881  /* We stop if blocked, after a maximum dist extansion or
1882  if it gets farther than the ambient dist to the randSample. This
1883  is measured in two ways: the distance traveled over the monifold
1884  (status->length) and the distance from the current sample to q_near
1885  (flag status->tooFar).
1886  The new branch should not scape the ball of radious maxR centered
1887  at q_near. We allow for a larger displacement over the manifold to
1888  account for curvature effects.
1889  */
1890  while (canContinueBranch(config,status)&&((config->addMode==ADD_NONE)||(ar->ns<maxNodes)))
1891  {
1892  /* Generate the new sample from current and rand. */
1893  New_NewTemptativeSample(pr,it,config,status,&current,&next,
1894  &rand,randSample,st,ar);
1895 
1896  if (!status->blocked)
1897  {
1898  /* If we actually managed to generate the temptative sample */
1899  if (!status->validChart)
1900  {
1901  /* We need to create a new chart in the current sample
1902  (i.e., the new temptative sample is not valid) */
1903  if (current.generateChart)
1904  {
1905  /* But current samples was already been used to create
1906  a chart. We reduce the step size with the aim of finding
1907  a point close to the current one where to create a chart. */
1908  status->delta*=0.5;
1909  status->validChart=TRUE; /* re-try with the previous chart */
1910  #if (GET_ATLASRRT_STATISTICS)
1912  #endif
1913  }
1914  else
1915  {
1916  /* We generate the new chart (this will change 'current') */
1917  if (AddChart2AtlasRRT(pr,status->tree,it,&current,
1918  &intersectParent,ar))
1919  {
1920  /* the chart generation was fine */
1921  #if (GET_ATLASRRT_STATISTICS)
1923  if(!intersectParent)
1925  #endif
1926 
1927  /* Keep track of the new visited chart */
1928  NewVectorElement((void*)&(current.c),&(status->traversedCharts));
1929 
1930  /* The branch created one new more chart */
1931  status->nCreatedCharts++;
1932 
1933  /* We have a new valid chart */
1934  status->validChart=TRUE;
1935 
1936  /* Reset the advance step */
1937  status->delta=delta;
1938 
1939  /* Re-define the advance direction (i.e., rand and
1940  status.deltaParam) in the new chart */
1941  status->blocked=New_PointTowardRandSample(config,samplingMode,
1942  randSample,status,
1943  &current,&rand,ar);
1944 
1945  #if (GET_ATLASRRT_STATISTICS)
1946  if (status->blocked)
1948  #endif
1949  }
1950  else
1951  {
1952  /* There was an error creating the chart: Stop the
1953  branch extension.
1954  TODO: Implement a more sophisticated stratetgy to deal
1955  with singular regions.
1956  */
1957  status->blocked=TRUE;
1958  fprintf(stderr," Point in singularity (decrease epsilon?)\n");
1959  #if (GET_ATLASRRT_STATISTICS)
1962  #endif
1963  }
1964  }
1965  }
1966  else
1967  {
1968  /* The temptative sample is correct. We can advance along the branch. */
1969  status->reachedTmpQrand=((rand.c==next.c)&&
1970  (Distance(ar->k,rand.t,next.t)<epsilon));
1971 
1972  status->distQrand=DistanceTopology(ar->m,ar->tp,
1973  next.s,randSample);
1974  if (config->onManifold)
1975  status->reachedQrand=(status->distQrand<epsilon);
1976 
1977  #if (!EXPLORATION_RRT)
1978  if (goalSample!=NULL)
1979  {
1980  status->distGoal=DistanceTopology(ar->m,ar->tp,
1981  next.s,goalSample);
1982  status->reachedGoal=(status->distGoal<epsilon);
1983  }
1984  #endif
1985 
1986  #if (GET_ATLASRRT_STATISTICS)
1987  if ((status->reachedQrand)||(status->reachedTmpQrand)||
1988  (status->reachedGoal))
1990  #endif
1991 
1992  status->distOrigin=DistanceTopology(ar->m,ar->tp,next.s,near->s);
1993  status->tooFar=(status->distOrigin>status->maxDistOrigin);
1994 
1995  if (!status->tooFar)
1996  {
1997  /* Add the sample to the tree, if required */
1998  status->stepLength=DistanceTopology(ar->m,ar->tp,
1999  current.s,next.s);
2000 
2001  if (config->addMode==ADD_ALL)
2002  {
2003  status->length+=AddSample2AtlasRRT(pr,status->tree,
2004  &(status->lastID),
2005  next.c,next.t,next.s,
2006  status->stepLength,
2007  status->cost,ar);
2008  /* Current is the last node added to the AtlasRRT */
2009  SetSampleInfoFromNode(status->lastID,ar,&current);
2010  }
2011  else
2012  {
2013  status->length+=status->stepLength;
2014  /* current <- next (this sets current.generateChart=0) */
2015  SetSampleInfo(ar->m,ar->k,&current,&next);
2016  }
2017 
2018  /* Reset the advance step */
2019  status->delta=delta;
2020 
2021  #if (GET_ATLASRRT_STATISTICS)
2022  if (status->length>=status->maxLength)
2024 
2026  #endif
2027 
2028  /* Add the sample the path, if required */
2029  if ((ns!=NULL)&&(path!=NULL)&&
2030  (!status->reachedTmpQrand)&&(!status->reachedQrand)&&
2031  (!status->reachedGoal))
2032  AddSample2Samples(ar->m,next.s,ar->m,NULL,&ms,ns,path);
2033  }
2034  #if (GET_ATLASRRT_STATISTICS)
2035  else
2037  #endif
2038  }
2039  }
2040  }
2041 
2042  /* The branch is alrady defined. Check what to do with the last sample along
2043  the branch, release memory, and adjust the final branch lenght. */
2044  if (initData)
2045  {
2046  if ((status->length>0)&&
2047  ((config->addMode==ADD_LAST)||((config->addMode==ADD_LAST_NO_REP))))
2048  {
2049  boolean noRep;
2050 
2051  /* In some branch configurations, the last sample has to be added
2052  to the RRT, in some cases avoiding repetitions. */
2053  if (config->addMode==ADD_LAST_NO_REP)
2054  {
2055  unsigned int nn;
2056 
2057  nn=GetRRTNN(status->tree,current.s,&(ar->rrt));
2058  noRep=(DistanceTopology(ar->m,ar->tp,
2059  ar->si[nn]->s,current.s)>epsilon);
2060  }
2061  else
2062  noRep=TRUE;
2063 
2064  if (noRep)
2065  {
2066  if ((!current.generateChart)&&(Norm(ar->k,current.t)<epsilon))
2067  Warning("Adding a sample on a chart center");
2068 
2069  /* If it was required to advance toward q_rand and we actually
2070  moved in that direction and we have to add the last computed
2071  sample -> add it (with distance to parent = branch length) */
2072  /* Here lastID will be i_near if no sample was added yet */
2073  AddSample2AtlasRRT(pr,status->tree,&(status->lastID),
2074  current.c,current.t,current.s,
2075  status->length,status->cost,ar);
2076  /* In some rare ocassions, the last sample of the branch
2077  (the one we just added to the tree) has been used to
2078  generate a chart. Mark it to avoid the generation of
2079  a new chart on this same sample latter on. When adding
2080  all samples along the branch to the RRT, none of the
2081  added charts can be the center of a chart (charts are
2082  only defined on samples already in the tree). When adding
2083  only the last sample to the tree, charts are created on
2084  temporary samples that might be included in the tree if
2085  they are the last sample along a branch. */
2086  ar->si[status->lastID]->generateChart=current.generateChart;
2087  }
2088  }
2089 
2090  /* Update the statistic of how far we can get from i_near */
2091  /* This only has effect if paramter DYNAMIC_DOMAIN is >0 */
2092  AdjustDynamicDomain(i_near,status->collision,&(ar->rrt));
2093 
2094  DeleteSampleInfo(&current);
2095  DeleteSampleInfo(&next);
2096  DeleteSampleInfo(&rand);
2097  }
2098 
2099  /* Final adjust of the branch lenght: Add the distance from the last
2100  sample in the branch to the goal/q_rand (this is epsilon size) */
2101  if (status->reachedQrand)
2102  status->length+=status->distQrand;
2103  else
2104  {
2105  if (status->reachedGoal)
2106  status->length+=status->distGoal;
2107  }
2108 
2109  /* Release the possible memory allocated by the InitBranchStatus, if any */
2110  DeleteBranchStatus(status);
2111 
2112  return(status->length);
2113 }
2114 
2115 void New_NewTemptativeSample(Tparameters *pr,unsigned int it,
2116  TAtlasRRTBranchConfig *config,
2117  TAtlasRRTBranchStatus *status,
2118  TSampleInfo *current,TSampleInfo *next,
2119  TSampleInfo *rand,double *randSample,
2120  void *st,Tatlasrrt *ar)
2121 {
2122  double epsilon;
2123  unsigned int samplingMode;
2124  double dif;
2125  Tchart *nextChart;
2126 
2127  #if (GET_ATLASRRT_STATISTICS)
2129  #endif
2130 
2131  epsilon=GetParameter(CT_EPSILON,pr);
2132  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
2133 
2134  /* new samples do not generated a chart (yet) */
2135  next->generateChart=0;
2136 
2137  if (status->delta<epsilon)
2138  {
2139  /* The advance step is too small. This means we are trying to generate
2140  a sample (i.e., a chart center) very close to another sample and
2141  even being very close we didn't manage to to it. This should never
2142  happen for smooth manifolds. */
2143  Warning("The impossible happened (III)");
2144  status->blocked=TRUE;
2145  }
2146  else
2147  {
2148  /* Move a step of (max) size 'delta' from current towards rand */
2149  dif=Distance(ar->k,current->t,rand->t);
2150  if (dif<status->delta)
2151  memcpy(next->t,rand->t,ar->k*sizeof(double));
2152  else
2153  SumVectorScale(ar->k,current->t,status->delta,
2154  status->deltaParam,next->t);
2155 
2156  if (Norm(ar->k,next->t)>ar->r)
2157  {
2158  /* 'next' is out of the validity area (ball) of the current
2159  chart. Its time to generate a new chart (in the previous
2160  sample that is still inside the chart). */
2161  status->validChart=FALSE;
2162  #if (GET_ATLASRRT_STATISTICS)
2164  #endif
2165  }
2166  else
2167  {
2168  /* In principle, 'next' sampple is in the same chart as the
2169  'current' sample */
2170  next->c=current->c;
2171  nextChart=GetAtlasChart(next->c,&(ar->atlas));
2172 
2173  if (!InsideChartPolytope(next->t,nextChart))
2174  {
2175  /* 'next' is outside the polytope of the chart -> it might
2176  be in a neighbouring chart */
2177  if ((!config->onManifold)&&
2178  ((config->explorationSample)||(status->nCreatedCharts>0)))
2179  {
2180  /* A branch aiming a random point in tangent space that is
2181  a exploration branch or that generated new charts while
2182  growing. It is stopped to enter a pre-existing chart.
2183  This tries to avoid branch crossing. */
2184  status->blocked=TRUE;
2185  #if (GET_ATLASRRT_STATISTICS)
2187  #endif
2188  #if (ATLASRRT_VERBOSE)
2189  if (status->nCreatedCharts>0)
2190  fprintf(stderr," Branch stopped (created charts>1)\n");
2191  else
2192  fprintf(stderr," Branch stopped (exploration)\n");
2193  #endif
2194  }
2195  else
2196  {
2197  /* Determine the neighbouring chart including the
2198  'next' sample */
2199  next->c=DetermineChartNeighbour(epsilon,next->t,nextChart);
2200 
2201  if ((ElementInVector((void*)&(next->c),CmpID,&(status->traversedCharts)))||
2202  ((!config->revisitCharts)&&
2203  ((!ar->birrt)||
2204  ((ar->ci[current->c]->tree)&(ar->ci[next->c]->tree)))))
2205  {
2206  /* The branch can not re-enter charts already traversed
2207  Moreover, if revisitCharts is FALSE, we have to avoid
2208  branches to enter charts in the same tree. In
2209  oneDirectional trees all charts are in the same tree.
2210  This reduces branch crossing.
2211  Observe that this does not prevent the connection
2212  between different trees. */
2213  status->blocked=TRUE;
2214  #if (GET_ATLASRRT_STATISTICS)
2216  #endif
2217  #if (ATLASRRT_VERBOSE)
2218  fprintf(stderr," Branch stopped (non-revisited)\n");
2219  #endif
2220  }
2221  else
2222  {
2223  /* Transition between pre-existing charts -> continue normally.
2224  We basically repeat all the steps for the new chart */
2225  #if (ATLASRRT_VERBOSE>1)
2226  fprintf(stderr," Branch moved to chart: %u\n",next->c);
2227  #endif
2228 
2229  /* Get the new chart */
2230  nextChart=GetAtlasChart(next->c,&(ar->atlas));
2231 
2232  /* Project the current sample to the new chart */
2233  Manifold2Chart(current->s,ar->tp,current->t,nextChart);
2234  current->c=next->c;
2235 
2236  /* Keep track of the visited charts */
2237  NewVectorElement((void*)&(current->c),&(status->traversedCharts));
2238 
2239  /* Ensure some overlap between neighbouring charts: current is in both charts */
2240  EnlargeChart(current->t,nextChart);
2241 
2242  /* Determine the advance direction in the new chart */
2243  status->blocked=New_PointTowardRandSample(config,samplingMode,randSample,
2244  status,current,rand,ar);
2245 
2246  if (!status->blocked)
2247  {
2248  /* Moved to a new chart and succesfully projected the random sample to it
2249  Now recompute the advance step */
2250  dif=Distance(ar->k,current->t,rand->t);
2251  if (dif<status->delta)
2252  memcpy(next->t,rand->t,ar->k*sizeof(double));
2253  else
2254  SumVectorScale(ar->k,current->t,status->delta,
2255  status->deltaParam,next->t);
2256 
2257  /* and just check that it is inside the ball */
2258  if (Norm(ar->k,next->t)>ar->r)
2259  {
2260  /* 'next' is out of the validity area (ball) of the current
2261  chart. Its time to generate a new chart (in the previous
2262  sample that is still inside the chart). */
2263  status->validChart=FALSE;
2264  #if (GET_ATLASRRT_STATISTICS)
2266  #endif
2267  }
2268  }
2269  #if (GET_ATLASRRT_STATISTICS)
2270  else
2272  #endif
2273  }
2274  }
2275  }
2276  }
2277 
2278  /* Here we have a sample that is correctly parametrized inside
2279  the validity area (ball) of a given chart.
2280  Now we have to check for the sample validity like in any
2281  other path planner. */
2282 
2283  if ((status->validChart)&&(!status->blocked)&&
2284  (Chart2Manifold(pr,&(ar->J),next->t,
2285  ar->tp,current->s,
2286  next->s,nextChart)<ar->e))
2287  {
2288  double dp;
2289  boolean inDomain,tooCurved;
2290  boolean trans=TRUE;
2291 
2292  /* Check error curvature (only along the expansion direction) */
2293  dp=DistanceTopology(ar->m,ar->tp,current->s,next->s);
2294 
2295  tooCurved=((status->delta/dp)<(1-ar->ce));
2296  if (!tooCurved)
2297  {
2298  /* Check the bounds respect to the ambient space */
2299  inDomain=((PointInBoxTopology(NULL,FALSE,ar->m,next->s,
2300  epsilon,ar->tp,
2301  &(ar->ambient)))&&
2302  (CS_WD_SIMP_INEQUALITIES_HOLD(pr,next->s,ar->w)));
2303  if (inDomain)
2304  {
2305  /* Check if the transition test is passed */
2306  if (config->costF!=NULL)
2307  trans=TransitionTestRRT(pr,current->id,next->s,dp,
2308  &(status->cost),
2309  config->costF,config->costData,
2310  &(ar->rrt));
2311 
2312  if (trans)
2313  {
2314  /* Check the collisions (only if necessary) */
2315  if (config->checkCollisions)
2316  {
2317  CS_WD_IN_COLLISION(status->collision,pr,next->s,
2318  current->s,ar->w);
2319  #if (GET_ATLASRRT_STATISTICS)
2321  #endif
2322  }
2323 
2324  if (status->collision)
2325  {
2326  status->blocked=TRUE;
2327  #if (GET_ATLASRRT_STATISTICS)
2329  #endif
2330  }
2331  #if (GET_ATLASRRT_GLOBAL_CURV_CHECK)
2332  else
2333  {
2334  Tchart cTmp;
2335  boolean closeEnough,canInitChart;
2336 
2337  /* The curvature check (tooCurved) can be computed
2338  in a more accurate way than the test above.
2339  This is expensive and not commontly used. */
2340 
2341  /* We further check if we are able to create a
2342  chart at the current sample and if this chart
2343  is not too different from its parent chart. */
2344 
2345  /* Create a temporary chart at 'next' */
2346  canInitChart=(InitChart(pr,TRUE,&(ar->ambient),
2347  ar->tp,ar->m,ar->k,
2348  next->s,ar->e,ar->ce,
2349  ar->r,&(ar->J),
2350  ar->w,&cTmp)==0);
2351  if (canInitChart)
2352  {
2353  /* Check if new chart respects distance
2354  and angular tolerances */
2355  closeEnough=CloseCharts(pr,ar->tp,
2356  nextChart,&cTmp);
2357  if (!closeEnough)
2358  {
2359  /* next sample is out of the domain of the
2360  current chart due to excesive curvature
2361  We generate a new chart closer to the
2362  area of interst. */
2363  status->validChart=FALSE;
2364  #if (GET_ATLASRRT_STATISTICS)
2366  #endif
2367  }
2368  DeleteChart(&cTmp); /* Delete only if canInit */
2369  }
2370  else
2371  {
2372  /* We did not manage to create the chart:
2373  - Point not on manifold
2374  - error in QR
2375  - singular point
2376  (typically the last one).
2377  We could implement more complex procedures
2378  to skip the singular area. */
2379  status->blocked=TRUE;
2380  #if (GET_ATLASRRT_STATISTICS)
2382  #endif
2383  }
2384  }
2385  #endif
2386  }
2387  else
2388  {
2389  /*Transition test failed -> rejected step */
2390  status->blocked=TRUE;
2391  }
2392  }
2393  else
2394  {
2395  /* next sample is out of the domain */
2396  #if (GET_ATLASRRT_STATISTICS)
2398  #endif
2399  status->blocked=TRUE;
2400  }
2401  }
2402  else
2403  {
2404  /* The new sample is out of the validity area of the chart
2405  due to a excesive curvature. */
2406  #if (GET_ATLASRRT_STATISTICS)
2408  #endif
2409  status->validChart=FALSE;
2410  }
2411  }
2412  else
2413  {
2414  /* The projection from the sample in tangent space to the
2415  manifold failed */
2416  #if (GET_ATLASRRT_STATISTICS)
2417  if ((!status->blocked)&&(status->validChart))
2419  #endif
2420  status->validChart=FALSE;
2421  }
2422  }
2423 }
2424 
2426  unsigned int samplingMode,double *randSample,
2427  TAtlasRRTBranchStatus *status,
2428  TSampleInfo *current,TSampleInfo *rand,
2429  Tatlasrrt *ar)
2430 {
2431  Tchart *c;
2432  double n;
2433 
2434  /* We will project 'rand' to the chat of the current sample */
2435  rand->c=current->c;
2436 
2437  /* Get current chart */
2438  c=GetAtlasChart(current->c,&(ar->atlas));
2439 
2440  /* The random sample to pursue changes depending on whether it
2441  is on the manifold of in the tangent space */
2442  if ((samplingMode!=TANGENT_SAMPLING)||(config->onManifold))
2443  Manifold2Chart(randSample,ar->tp,rand->t,c); /* sample not in the tangent space */
2444  else
2445  Manifold2Chart(rand->s,ar->tp,rand->t,c); /* sample in the tangent space (of previous chart)
2446  In the first call, this is the same as randSample */
2447 
2448  /* deltaParam: Vector from 'current' to 'rand' (in tangent space) */
2449  DifferenceVector(ar->k,rand->t,current->t,status->deltaParam);
2450 
2451  /* Ensure that the new rand far from 'current' */
2452  n=Norm(ar->k,status->deltaParam);
2453  if (n>1e-3)
2454  {
2455  Normalize(ar->k,status->deltaParam);
2456  /* Displace rand->t far enough, but without modifying the
2457  advance direction. */
2458  if ((samplingMode==TANGENT_SAMPLING)&&(!config->onManifold))
2459  SumVectorScale(ar->k,current->t,status->maxLength,
2460  status->deltaParam,rand->t);
2461 
2462  /* Update rand->s so that it correspond to the new rand->t */
2463  Local2Global(rand->t,ar->tp,rand->s,c);
2464 
2465  #if (ATLASRRT_VERBOSE)
2466  fprintf(stderr," New random sample in chart %u: [%f %f] [%f %f %f]\n",rand->c,rand->t[0],rand->t[1],rand->s[0],rand->s[1],rand->s[2]);
2467  #endif
2468 
2469  return(FALSE);
2470  }
2471  else
2472  /* The projection of 'rand' to the current chart coincides
2473  with the current sample -> the direction of adavance is
2474  not clear -> stop the branch extension*/
2475  return(TRUE);
2476 }
2477 
2478 double AddBranchToAtlasRRT(Tparameters *pr,unsigned int it,
2479  unsigned int addMode,boolean revisitCharts,
2480  boolean checkCollisions,boolean onManifold,
2481  boolean explorationSample,
2482  double maxLength,unsigned int i_near,
2483  double *origRandSample,
2484  double *goalSample,void *st,
2485  unsigned int *lastSampleID,
2486  boolean *reachedQRand,boolean *reachedGoal,
2487  unsigned int *ns,double ***path,
2488  double (*costF)(Tparameters*,boolean,double*,void*),
2489  void *costData,Tatlasrrt *ar)
2490 {
2491  /*
2492  In this function
2493  current -> refers to the sample already in the altlasRRT that
2494  will be extended with a new child
2495  rand -> is the sample to reach in this particular expansion
2496  goal -> is the final point to reach in the whole tree.
2497  next -> is the sample to add just after current.
2498 
2499  for each one of the previous we have
2500  param -> are the parametes on the corresponding chart
2501  sample -> is the corresponding point on the manifold.
2502  */
2503 
2504  boolean blocked,collision,valid,tooFar,init,intersectParent,canInitChart,noRep;
2505  double epsilon,d,dg,dqr,dnn; /* current branch lenght. */
2506 
2507  /* Next sample */
2508  unsigned int nextChart; /* Chart to which this sample belongs to. */
2509  double *currentParam; /* The parameters for the current sample. Can be different
2510  from those stored in the AtlasRRT */
2511  double *nextParam; /* Parameters in the chart. */
2512  double *nextSample; /* Point on manifolf for next sample. */
2513 
2514  double *deltaParam; /* Normal vector indicating the direction toward
2515  q_rand in the current chart. */
2516 
2517  /* Interpolation step */
2518  double delta; /* Max step size. */
2519  double currentDelta; /* Current size. */
2520  double distQrand; /* Initial distance to q_rand = max length for the
2521  new branch. */
2522  double *nnSample; /* Sample from where to extend the tree. */
2523  TSampleInfo *currentSampleInfo;
2524  unsigned int randChart;
2525  double *randParam;
2526  double dist,maxDist;
2527  TSampleInfo tmpSI; /* Temporary sample info used when addMode!=ADD_ALL */
2528  double *randSample;
2529  boolean tmpQrandReached;
2530  unsigned int ms,nn;
2531  double cost;
2532  unsigned int maxNodes;
2533  unsigned int samplingMode;
2534  unsigned int nChanges; /* only one transition between charts is allowed */
2535  unsigned int tree;
2536 
2537  tree=GetRRTNodeTree(i_near,&(ar->rrt));
2538 
2539  if (i_near==NO_UINT)
2540  Error("Extending a branch from nowhere");
2541 
2542  epsilon=GetParameter(CT_EPSILON,pr);
2543  delta=GetParameter(CT_DELTA,pr);
2544  maxNodes=(unsigned int)GetParameter(CT_MAX_NODES_RRT,pr);
2545  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
2546 
2547  nnSample=ar->si[i_near]->s;
2548  distQrand=DistanceTopology(ar->m,ar->tp,nnSample,origRandSample);
2549  #if (ATLASRRT_VERBOSE)
2550  if (distQrand<epsilon)
2551  Warning("Repeated points in the AtlasRRT?");
2552  #endif
2553 
2554  nChanges=0;
2555 
2556  /* Interpolation parameters */
2557  currentDelta=delta;
2558 
2559  /* Identifier for current point, used to retive current Chart/Param/Sample
2560  from the AtlasRRT structure */
2561  *lastSampleID=i_near;
2562 
2563  blocked=FALSE;
2564  tooFar=FALSE;
2565  collision=FALSE;
2566  cost=0;
2567  #if (EXPLORATION_RRT)
2568  *reachedGoal=FALSE;
2569  dg=INF;
2570  #else
2571  /* The projection on the manifold can be larger than that
2572  on the tangent space */
2573  if (goalSample!=NULL)
2574  {
2575  dg=DistanceTopology(ar->m,ar->tp,nnSample,goalSample);
2576  *reachedGoal=(dg<delta);
2577  }
2578  else
2579  *reachedGoal=FALSE;
2580  #endif
2581  if (onManifold)
2582  *reachedQRand=(distQrand<epsilon);
2583  else
2584  *reachedQRand=FALSE;
2585  tmpQrandReached=*reachedQRand;
2586 
2587  if ((ns!=NULL)&&(path!=NULL))
2588  InitSamples(&ms,ns,path);
2589 
2590  if ((*reachedQRand)||(*reachedGoal))
2591  {
2592  init=FALSE; /* not data structre was initialized */
2593  maxDist=0.0;
2594  d=0.0;
2595  }
2596  else
2597  {
2598  /* If the goal sample is not already reached, we prepare for the
2599  branch extension */
2600  init=TRUE;
2601 
2602  /* Each sample can have many different representations due to the
2603  ambient space topology. Select the one that is closer to
2604  the nearest neighbour. In this wqy we ensure to move towards
2605  the randSample along the shortest path. */
2606  if (ar->tp!=NULL)
2607  {
2608  DifferenceVectorTopology(ar->m,ar->tp,origRandSample,nnSample,origRandSample);
2609  AccumulateVector(ar->m,nnSample,origRandSample);
2610  }
2611  /* the nn can have different parameters in the same tangent space. We store
2612  the ones closer to its chart center (obtained using the topology), but
2613  the direct parameters are better to extend the branch. */
2614  NEW(currentParam,ar->k,double);
2615  Manifold2Chart(nnSample,NULL,currentParam,
2616  GetAtlasChart(ar->si[i_near]->c,&(ar->atlas)));
2617 
2618  d=0.0;
2619  /* get a copy of the random sample since we will modify it while the branch
2620  is extended */
2621  NEW(randSample,ar->m,double);
2622  memcpy(randSample,origRandSample,ar->m*sizeof(double));
2623 
2624  if (maxLength<=0.0)
2625  {
2626  dist=distQrand;
2627  maxDist=2*distQrand;
2628  }
2629  else
2630  {
2631  dist=maxLength;
2632  maxDist=maxLength;
2633  }
2634 
2635  /* if the targed is on the manifold we allow for some tolerance in
2636  the maximum distance from nn to end of path. */
2637  if (onManifold)
2638  distQrand*=1.1;
2639 
2640  /* Detemine the direction of motion toward q_rand from the current sample */
2641  NEW(deltaParam,ar->k,double);
2642 
2643  /* Space for next samples */
2644  NEW(nextParam,ar->k,double);
2645  NEW(nextSample,ar->m,double);
2646 
2647  /* Space for the parameters of q_rand */
2648  NEW(randParam,ar->k,double);
2649 
2650  if (addMode==ADD_ALL)
2651  currentSampleInfo=ar->si[i_near];
2652  else
2653  {
2654  /* Get a copy of the info for sample i_near (many fields are not used
2655  but copied for completeness) */
2656  tmpSI.id=NO_UINT;
2657  NEW(tmpSI.s,ar->m,double);
2658  memcpy(tmpSI.s,ar->si[i_near]->s,ar->m*sizeof(double));
2659  NEW(tmpSI.t,ar->k,double);
2660  memcpy(tmpSI.t,ar->si[i_near]->t,ar->k*sizeof(double));
2661  tmpSI.pc=ar->si[i_near]->pc;
2662  tmpSI.c=ar->si[i_near]->c;
2663  tmpSI.generateChart=ar->si[i_near]->generateChart;
2664  tmpSI.lsc=ar->si[i_near]->lsc;
2665 
2666  /* And the sample from where to extend is the temporal one that will
2667  be modified as we grow the branch */
2668  currentSampleInfo=&tmpSI;
2669  }
2670 
2671  blocked=PointTowardRandSample(currentSampleInfo->c,dist,currentParam,
2672  samplingMode,onManifold,origRandSample,
2673  &randChart,randParam,randSample,deltaParam,ar);
2674  }
2675 
2676  #if (_DEBUG>1)
2677  printf(" Adding branch to RRT from sample %u (chart %u)\n",i_near,ar->si[i_near]->c);
2678  #endif
2679 
2680  /* We stop if blocked, after a maximum dist extansion or
2681  if it gets farther than the ambient dist to the randSample. This
2682  is measured in two ways: the distance traveled over the monifold (d)
2683  and the Euclidian distance from the current sample to q_near (tooFar).
2684  The new branch should not scape the ball of radious maxDist centered
2685  at q_near. We allow for a larger displacement over the manifold to
2686  account for curvature effects.
2687  */
2688  while ((!blocked)&&(!collision)&&(d<maxDist)&&(!tmpQrandReached)&&(!(*reachedGoal))&&
2689  (!(*reachedQRand))&&(!tooFar)&&((addMode==ADD_NONE)||(ar->ns<maxNodes)))
2690  {
2691  NewTemptativeSample(pr,it,&nChanges,
2692  revisitCharts,explorationSample,checkCollisions,onManifold,
2693  currentSampleInfo,currentParam,origRandSample,
2694  &randChart,randParam,randSample,
2695  currentDelta,dist-d,deltaParam,
2696  &nextChart,nextParam,nextSample,
2697  st,costF,costData,&cost,&blocked,&collision,&valid,ar);
2698 
2699  if (!blocked)
2700  {
2701  if (!valid)
2702  {
2703  if (currentSampleInfo->generateChart)
2704  {
2705  currentDelta*=0.5;
2706  #if (GET_ATLASRRT_STATISTICS)
2708  #endif
2709  }
2710  else
2711  {
2712  canInitChart=AddChart2AtlasRRT(pr,tree,it,currentSampleInfo,
2713  &intersectParent,ar);
2714  if (canInitChart)
2715  {
2716  #if (GET_ATLASRRT_STATISTICS)
2718  if(!intersectParent)
2720  #endif
2721 
2722  Manifold2Chart(currentSampleInfo->s,NULL,currentParam,
2723  GetAtlasChart(currentSampleInfo->c,&(ar->atlas)));
2724  blocked=PointTowardRandSample(currentSampleInfo->c,dist-d,
2725  currentParam,samplingMode,
2726  onManifold,origRandSample,
2727  &randChart,randParam,randSample,
2728  deltaParam,ar);
2729  #if (GET_ATLASRRT_STATISTICS)
2730  if (blocked)
2732  #endif
2733  /* Samples that trigger the creation of a chart are considered
2734  exploration samples */
2735  explorationSample=TRUE;
2736  }
2737  else
2738  {
2739  /* Stop the branch extension.
2740  TODO: Implement a more sophisticated stratetgy to deal
2741  with singular regions.
2742  */
2743  blocked=TRUE;
2744  fprintf(stderr," Point in singularity (decrease epsilon?)\n");
2745  #if (GET_ATLASRRT_STATISTICS)
2748  #endif
2749  }
2750  }
2751  }
2752  else
2753  {
2754  tmpQrandReached=((randChart==nextChart)&&
2755  (Distance(ar->k,randParam,nextParam)<epsilon));
2756 
2757  if (onManifold)
2758  {
2759  dqr=DistanceTopology(ar->m,ar->tp,nextSample,origRandSample);
2760  *reachedQRand=(dqr<epsilon);
2761  }
2762 
2763  #if (!EXPLORATION_RRT)
2764  if (goalSample!=NULL)
2765  {
2766  dg=DistanceTopology(ar->m,ar->tp,nextSample,goalSample);
2767  *reachedGoal=(dg<epsilon);
2768  }
2769  #endif
2770 
2771  #if (GET_ATLASRRT_STATISTICS)
2772  if ((*reachedQRand)||(tmpQrandReached)||(*reachedGoal))
2774  #endif
2775 
2776  dnn=DistanceTopology(ar->m,ar->tp,nextSample,nnSample);
2777  tooFar=(dnn>distQrand);
2778 
2779  if (!tooFar)
2780  {
2781  /* Add the sample to the tree, if required */
2782  dnn=DistanceTopology(ar->m,ar->tp,currentSampleInfo->s,nextSample);
2783  if (addMode==ADD_ALL)
2784  {
2785  d+=AddSample2AtlasRRT(pr,tree,lastSampleID,
2786  nextChart,nextParam,nextSample,dnn,cost,ar);
2787 
2788  currentSampleInfo=ar->si[*lastSampleID];
2789  }
2790  else
2791  {
2792  /* If the sample is not added to the tree, we update the
2793  current sample info. */
2794  d+=dnn;
2795 
2796  /* Update the info for the temporary sample */
2797  memcpy(currentSampleInfo->s,nextSample,ar->m*sizeof(double));
2798  memcpy(currentSampleInfo->t,nextParam,ar->k*sizeof(double));
2799  currentSampleInfo->c=nextChart;
2800  currentSampleInfo->pc=nextChart;
2801  currentSampleInfo->generateChart=0;
2802  currentSampleInfo->lsc=NO_UINT;
2803  }
2804  memcpy(currentParam,nextParam,ar->k*sizeof(double));
2805 
2806  currentDelta=delta;
2807 
2808  #if (GET_ATLASRRT_STATISTICS)
2809  if (d>=maxDist)
2811 
2813  #endif
2814 
2815  /* Add the sample the path, if required */
2816  if ((ns!=NULL)&&(path!=NULL)&&
2817  (!tmpQrandReached)&&(!(*reachedGoal))&&(!(*reachedQRand)))
2818  AddSample2Samples(ar->m,nextSample,ar->m,NULL,&ms,ns,path);
2819  }
2820  #if (GET_ATLASRRT_STATISTICS)
2821  else
2823  #endif
2824  }
2825  }
2826  }
2827 
2828  /* Add the distance from the last sample in the branch to the
2829  goal/q_rand (this is epsilon size) */
2830  if (*reachedQRand)
2831  d+=dqr;
2832  else
2833  {
2834  if (*reachedGoal)
2835  d+=dg;
2836  }
2837 
2838  if ((init)&&(d>0)&&((addMode==ADD_LAST)||((addMode==ADD_LAST_NO_REP))))
2839  {
2840  if (addMode==ADD_LAST_NO_REP)
2841  {
2842  nn=GetRRTNN(tree,tmpSI.s,&(ar->rrt));
2843  noRep=(DistanceTopology(ar->m,ar->tp,ar->si[nn]->s,tmpSI.s)>epsilon);
2844  }
2845  else
2846  noRep=TRUE;
2847 
2848  if (noRep)
2849  {
2850  /* If it was required to advance toward q_rand and we actually
2851  moved in that direction and we have to add the last computed
2852  sample -> add it */
2853  AddSample2AtlasRRT(pr,tree,lastSampleID,
2854  tmpSI.c,tmpSI.t,tmpSI.s,d,cost,ar);
2855  }
2856  }
2857 
2858  if (init)
2859  {
2860  /* Update the statistic of how far we can get from i_near */
2861  /* This only has effect if paramter DYNAMIC_DOMAIN is >0 */
2862  AdjustDynamicDomain(i_near,collision,&(ar->rrt));
2863 
2864  /* Release allocated space */
2865  if (addMode!=ADD_ALL)
2866  {
2867  free(tmpSI.s);
2868  free(tmpSI.t);
2869  }
2870  free(currentParam);
2871  free(deltaParam);
2872  free(nextParam);
2873  free(nextSample);
2874  free(randParam);
2875  free(randSample);
2876  }
2877 
2878  return(d);
2879 }
2880 
2881 void NewTemptativeSample(Tparameters *pr,unsigned int it,unsigned int *nChanges,
2882  boolean revisitCharts,boolean explorationSample,
2883  boolean checkCollisions,boolean onManifold,
2884  TSampleInfo *currentSampleInfo,double *currentParam,
2885  double *origRandSample,
2886  unsigned int *randChart,double *randParam,double *randSample,
2887  double currentDelta,double d,double *deltaParam,
2888  unsigned int *nextChart,double *nextParam,double *nextSample,
2889  void *st,double (*costF)(Tparameters*,boolean,double*,void*),
2890  void *costData,double *cost,boolean *blocked,
2891  boolean *inCollision,boolean *valid,
2892  Tatlasrrt *ar)
2893 {
2894  double epsilon;
2895  unsigned int samplingMode;
2896  double dif;
2897 
2898  #if (GET_ATLASRRT_STATISTICS)
2900  #endif
2901 
2902  epsilon=GetParameter(CT_EPSILON,pr);
2903  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
2904 
2905  if (currentDelta<epsilon)
2906  {
2907  Warning("The impossible happened (III)");
2908  *blocked=TRUE;
2909  }
2910  else
2911  {
2912  dif=Distance(ar->k,currentParam,randParam);
2913  if (dif<currentDelta)
2914  memcpy(nextParam,randParam,ar->k*sizeof(double));
2915  else
2916  SumVectorScale(ar->k,currentParam,currentDelta,deltaParam,nextParam);
2917 
2918  *valid=TRUE;
2919  *blocked=FALSE;
2920  *inCollision=FALSE; /* default no collision */
2921 
2922  if (Norm(ar->k,nextParam)>ar->r)
2923  {
2924  *valid=FALSE;
2925  #if (GET_ATLASRRT_STATISTICS)
2927  #endif
2928  }
2929  else
2930  {
2931  Tchart *nChart;
2932  double *currentSample;
2933  double dp;
2934  boolean inDomain,tooCurved;
2935  boolean trans;
2936 
2937  trans=TRUE; /* default no cost function is considered */
2938 
2939  /* currentSample = sample from where to move forward */
2940  currentSample=currentSampleInfo->s;
2941 
2942  /* In principle, nextChart is currentChart */
2943  *nextChart=currentSampleInfo->c;
2944  nChart=GetAtlasChart(*nextChart,&(ar->atlas));
2945 
2946  if (!InsideChartPolytope(nextParam,nChart))
2947  {
2948  if ((!onManifold)&&((explorationSample)||(*nChanges>0)))
2949  {
2950  /* A branch aiming a random point (in tangent space) that potentially generated
2951  new charts along its way, is stopped to enter a pre-existing chart.
2952  This tries to avoid branch crossing. */
2953  *blocked=TRUE;
2954  #if (GET_ATLASRRT_STATISTICS)
2956  #endif
2957  #if (ATLASRRT_VERBOSE)
2958  if (*nChanges>0)
2959  fprintf(stderr," Branch stopped (visited charts>1)\n");
2960  else
2961  fprintf(stderr," Branch stopped (exploration)\n");
2962  #endif
2963  }
2964  else
2965  {
2966  double *tc;
2967 
2968  *nextChart=DetermineChartNeighbour(epsilon,nextParam,nChart);
2969 
2970  if ((!revisitCharts)&&((!ar->birrt)||((ar->ci[currentSampleInfo->c]->tree)&(ar->ci[*nextChart]->tree))))
2971  {
2972  /* When trying to connect two trees, the branch should not enter other charts in the
2973  same tree. When this happens it means that the sample from where we extend the tree was
2974  not the nearest node to the other tree. Extending this branch results in branch crossing.
2975  Even the part of the branch already created shoud be removed to improve the quality of the
2976  RRT, but this is not implemented yet.
2977  One option would be not to add any node along this "connection" branches. Or implement
2978  a sort of delayed add to the RRT,.... */
2979  *blocked=TRUE;
2980  #if (GET_ATLASRRT_STATISTICS)
2982  #endif
2983  #if (ATLASRRT_VERBOSE)
2984  fprintf(stderr," Branch stopped (non-revisited)\n");
2985  #endif
2986  }
2987  else
2988  {
2989  (*nChanges)++;
2990  #if (ATLASRRT_VERBOSE>1)
2991  fprintf(stderr," Branch moved to chart: %u [num Changes: %u]\n",*nextChart,*nChanges);
2992  #endif
2993  /* Transition between pre-existing charts -> continue */
2994  nChart=GetAtlasChart(*nextChart,&(ar->atlas));
2995 
2996  NEW(tc,ar->k,double);
2997  Manifold2Chart(currentSample,ar->tp,tc,nChart);
2998  *blocked=PointTowardRandSample(*nextChart,d,tc,samplingMode,
2999  onManifold,origRandSample,
3000  randChart,randParam,randSample,
3001  deltaParam,ar);
3002  if (!(*blocked))
3003  {
3004  dif=Distance(ar->k,tc,randParam);
3005  if (dif<currentDelta)
3006  memcpy(nextParam,randParam,ar->k*sizeof(double));
3007  else
3008  SumVectorScale(ar->k,tc,currentDelta,deltaParam,nextParam);
3009  free(tc);
3010 
3011  if (Norm(ar->k,nextParam)>ar->r)
3012  {
3013  #if (GET_ATLASRRT_STATISTICS)
3015  #endif
3016  *valid=FALSE;
3017  }
3018  else
3019  EnlargeChart(nextParam,nChart);
3020  }
3021  #if (GET_ATLASRRT_STATISTICS)
3022  else
3024  #endif
3025  }
3026  }
3027  }
3028 
3029  /* Check error projection (distance) */
3030  if ((*valid)&&(!*blocked)&&
3031  (Chart2Manifold(pr,&(ar->J),nextParam,
3032  ar->tp,currentSample,
3033  nextSample,nChart)<ar->e))
3034  {
3035  /* Check error curvature (only along the expansion direction) */
3036  dp=DistanceTopology(ar->m,ar->tp,currentSample,nextSample);
3037 
3038  tooCurved=((currentDelta/dp)<(1-ar->ce));
3039  if (!tooCurved)
3040  {
3041  /* Check the bounds respect to the ambient space */
3042  inDomain=((PointInBoxTopology(NULL,FALSE,ar->m,nextSample,epsilon,
3043  ar->tp,&(ar->ambient)))&&
3044  (CS_WD_SIMP_INEQUALITIES_HOLD(pr,nextSample,ar->w)));
3045  if (inDomain)
3046  {
3047  *cost=0;
3048 
3049  if (costF!=NULL)
3050  trans=TransitionTestRRT(pr,currentSampleInfo->id,nextSample,dp,cost,
3051  costF,costData,&(ar->rrt));
3052 
3053  if (trans)
3054  {
3055  /* Check the collisions (only if necessary) */
3056  if (checkCollisions)
3057  {
3058  CS_WD_IN_COLLISION(*inCollision,pr,nextSample,currentSample,ar->w);
3059  #if (GET_ATLASRRT_STATISTICS)
3061  #endif
3062  }
3063 
3064  if (*inCollision)
3065  {
3066  *blocked=TRUE;
3067  #if (GET_ATLASRRT_STATISTICS)
3069  #endif
3070  }
3071  #if (GET_ATLASRRT_GLOBAL_CURV_CHECK)
3072  else
3073  {
3074  Tchart cTmp;
3075  boolean closeEnough,canInitChart;
3076 
3077  /* We further check if we are able to create a chart
3078  at the current sample and if this chart is not
3079  too different from its parent chart. */
3080 
3081  /* Check the possibility of a chart creation */
3082  canInitChart=(InitChart(pr,TRUE,&(ar->ambient),
3083  ar->tp,ar->m,ar->k,nextSample,
3084  ar->e,ar->ce,ar->r,&(ar->J),
3085  ar->w,&cTmp)==0);
3086  if (canInitChart)
3087  {
3088  /* Check if new chart respects distance
3089  and angular tolerances */
3090  closeEnough=CloseCharts(pr,ar->tp,nChart,&cTmp);
3091  if (!closeEnough)
3092  {
3093  *valid=FALSE;
3094  #if (GET_ATLASRRT_STATISTICS)
3096  #endif
3097  }
3098  DeleteChart(&cTmp); /* Delete only if init was OK */
3099  }
3100  else
3101  {
3102  /* Point not on manifold, error in QR, singular point
3103  (typically the last one) */
3104  *blocked=TRUE; /* valid=FALSE ?? */
3105  #if (GET_ATLASRRT_STATISTICS)
3107  #endif
3108  }
3109  }
3110  #endif
3111  }
3112  else
3113  {
3114  /*Transition test failed -> rejected step */
3115  *blocked = TRUE;
3116  }
3117  }
3118  else
3119  {
3120  #if (GET_ATLASRRT_STATISTICS)
3122  #endif
3123  *blocked=TRUE;
3124  }
3125  }
3126  else
3127  {
3128  #if (GET_ATLASRRT_STATISTICS)
3130  #endif
3131  *valid=FALSE;
3132  }
3133  }
3134  else
3135  {
3136  #if (GET_ATLASRRT_STATISTICS)
3137  if ((*valid)&&(!*blocked))
3139  #endif
3140  *valid=FALSE;
3141  }
3142  }
3143  }
3144 }
3145 
3146 double AddSample2AtlasRRT(Tparameters *pr,unsigned int tree,
3147  unsigned int *currentID,
3148  unsigned int nextChart,double *nextParam,double *nextSample,
3149  double dp,double cost,
3150  Tatlasrrt *ar)
3151 {
3152  double d;
3153  double *currentSample;
3154  unsigned int k;
3155  TSampleInfo *currentSampleInfo;
3156  TChartInfo *currentChartInfo;
3157 
3158  /* Distance to parent sample */
3159  currentSample=ar->si[*currentID]->s;
3160  d=DistanceTopology(ar->m,ar->tp,nextSample,currentSample);
3161 
3162  #if (_DEBUG>1)
3163  printf(" New sample %u (dp:%f)\n",ar->ns,d);
3164  #endif
3165 
3166  /* Add the sample to the RRT */
3167  if (ar->ns==ar->ms)
3168  MEM_DUP(ar->si,ar->ms,TSampleInfo *);
3169 
3170  /* Store the new sample in the RRT */
3171  AddNodeToRRT(pr,tree,*currentID,nextSample,nextSample,&k,NULL,dp,cost,NULL,&(ar->rrt));
3172  if (k!=ar->ns)
3173  Error("Incongruent node identifier in AtlasRRT (vs RRT inside)");
3174 
3175  /* Set up the information for the new sample */
3176  NEW(ar->si[ar->ns],1,TSampleInfo);
3177  currentSampleInfo=ar->si[ar->ns];
3178  currentChartInfo=ar->ci[nextChart];
3179 
3180  /* Pointer to the just added sample. The sample is stored in the RRT. */
3181  currentSampleInfo->s=GetRRTNode(ar->ns,&(ar->rrt));
3182  currentSampleInfo->id=ar->ns;
3183 
3184  /* Parent chart: Chart at which the sample is created.
3185  At initialization this is the same as currentSampleInfo->c
3186  but currentSampleInfo->c can change as new charts are
3187  created and currentSampleInfo->pc will remain the same */
3188  currentSampleInfo->pc=nextChart;
3189 
3190  /* There is no chart at the new sample (yet) */
3191  currentSampleInfo->generateChart=0;
3192 
3193  /* The chart including the current sample must be associated with
3194  the tree including this sample. */
3195  AddChart2Tree(tree,nextChart,ar);
3196 
3197  /* Store the projection into the current chart */
3198  NEW(currentSampleInfo->t,ar->k,double);
3199  memcpy(currentSampleInfo->t,nextParam,ar->k*sizeof(double));
3200  /*Manifold2Chart(currentSampleInfo->s,ar->tp,currentSampleInfo->t,
3201  GetAtlasChart(nextChart,&(ar->atlas)));*/
3202 
3203  /* Assign the sample to the corresponding chart */
3204  currentSampleInfo->c=nextChart;
3205 
3206  /* Add the sample to the list of samples of the corresponding chart */
3207  currentSampleInfo->lsc=currentChartInfo->lc;
3208  currentChartInfo->lc=ar->ns;
3209 
3210  /*Move the pointer to current to the new sample */
3211  *currentID=ar->ns;
3212 
3213  ar->ns++;
3214 
3215  return(d);
3216 }
3217 
3218 void AddChart2Tree(unsigned int tree,unsigned int chartId,Tatlasrrt* ar)
3219 {
3220  if ((ar->birrt)&&(!(ar->ci[chartId]->tree&tree)))
3221  {
3222  ar->ci[chartId]->tree|=tree;
3223  if (tree==START2GOAL)
3224  {
3225  if(ar->nct1==ar->mct1)
3226  MEM_DUP(ar->chartsAtTree1,ar->mct1,unsigned int);
3227  ar->chartsAtTree1[ar->nct1]=chartId;
3228  ar->nct1++;
3229  }
3230  else
3231  {
3232  if(ar->nct2==ar->mct2)
3233  MEM_DUP(ar->chartsAtTree2,ar->mct2,unsigned int);
3234  ar->chartsAtTree2[ar->nct2]=chartId;
3235  ar->nct2++;
3236  }
3237  }
3238 }
3239 
3240 boolean PointTowardRandSample(unsigned int cId,double d,double *t,
3241  unsigned int samplingMode,
3242  boolean onManifold,double *origRandSample,
3243  unsigned int *randChart,
3244  double *randParam,double *randSample,
3245  double *deltaParam,
3246  Tatlasrrt* ar)
3247 {
3248  Tchart *c;
3249  double n;
3250 
3251  *randChart=cId;
3252 
3253  /* Get current chart */
3254  c=GetAtlasChart(cId,&(ar->atlas));
3255 
3256  /* w: Project randSample on the chart. Do not use topoogy here
3257  We already used it to fix origRandSample and randSample. If we
3258  take into account the topology we might end up not moving along
3259  the shortest path connecting two samples */
3260  if ((samplingMode!=TANGENT_SAMPLING)||(onManifold))
3261  Manifold2Chart(origRandSample,NULL,randParam,c);
3262  else
3263  Manifold2Chart(randSample,NULL,randParam,c);
3264  /* deltaParam: Vector from current parameters 't' to 'w' */
3265  DifferenceVector(ar->k,randParam,t,deltaParam);
3266  /* Ensure that the new randSample is at least at
3267  distance 'd' from 't' */
3268  n=Norm(ar->k,deltaParam);
3269  if (n>1e-3)
3270  {
3271  Normalize(ar->k,deltaParam);
3272  if ((samplingMode==TANGENT_SAMPLING)&&(!onManifold))
3273  SumVectorScale(ar->k,t,d,deltaParam,randParam);
3274  /* Transform randSample to ambient space. Again, skip
3275  the topology to keep the advance direction.*/
3276  Local2Global(randParam,NULL,randSample,c);
3277 
3278  return(FALSE);
3279  }
3280  else
3281  return(TRUE);
3282 }
3283 
3284 boolean AddChart2AtlasRRT(Tparameters *pr,unsigned int tree,unsigned int it,
3285  TSampleInfo *currentSampleInfo,boolean* intersectParent,
3286  Tatlasrrt *ar)
3287 {
3288  unsigned int j,ncp,newChart;
3289  unsigned nn,i,id;
3290  Tchart* ce;
3291  TChartInfo *currentChartInfo;
3292  unsigned int currentID;
3293  boolean sing;
3294 
3295  currentID=currentSampleInfo->id;
3296 
3297  /* need to generate a new chart at the current sample */
3298  /* change cID */
3299  ncp=ar->nc;
3300 
3301  /* This does not enforce the neighbouring relation with parent chart !!
3302  but tries to detect singularities, if any (and enabled) */
3303  newChart=AddTrustedChart2Atlas(pr,currentSampleInfo->s,
3304  currentSampleInfo->pc,&sing,&(ar->atlas));
3305 
3306  if (newChart!=NO_UINT)
3307  {
3308  ar->nc=GetAtlasNumCharts(&(ar->atlas));
3309 
3310  /* Check if the newChart is neighbour with its parent chart */
3311  if (ncp<(ar->birrt?2:1))
3312  *intersectParent=TRUE; /* for the chart at the query points -> do not check */
3313  else
3314  {
3315  (*intersectParent)=FALSE;
3316  ce=GetAtlasChart(newChart,&(ar->atlas));
3317  if (SingularChart(GetAtlasChart(newChart,&(ar->atlas))))
3318  Warning("Singular chart in AtlasRRT (decrease epsilon?)");
3319  nn=ChartNumNeighbours(ce);
3320 
3321  for(i=0;((!(*intersectParent))&&(i<nn));i++)
3322  {
3323  id=ChartNeighbourID(i,ce);
3324  if ((id!=NO_UINT)&&(id==currentSampleInfo->pc))
3325  (*intersectParent)=TRUE;
3326  }
3327 
3328  if ((!(*intersectParent))&&(currentSampleInfo->pc!=NO_UINT))
3329  {
3330  Tchart *parentChart;
3331 
3332  parentChart=GetAtlasChart(currentSampleInfo->pc,&(ar->atlas));
3333  ForceChartCut(pr,ar->tp,&(ar->ambient),newChart,ce,currentSampleInfo->pc,parentChart);
3334  }
3335  }
3336 
3337  #if (ATLASRRT_VERBOSE>1)
3338  fprintf(stderr," Sample at chart %u generated a new chart (%u): [%f %f ...] [%.16f %.16f %.16f ...]\n",
3339  currentSampleInfo->c,newChart,currentSampleInfo->t[0],currentSampleInfo->t[1],
3340  currentSampleInfo->s[0],currentSampleInfo->s[1],currentSampleInfo->s[2]);
3341  #endif
3342 
3343  /* expand chart info if necessary */
3344  if (ar->nc>ar->mc)
3345  {
3346  ar->mc=ar->nc+INIT_NUM_CHARTS;
3347  MEM_EXPAND(ar->ci,ar->mc,TChartInfo *);
3348  }
3349 
3350  /* and initialize an empty list of samples for the new charts */
3351  for(j=ncp;j<ar->nc;j++)
3352  {
3353  NEW(ar->ci[j],1,TChartInfo);
3354  ar->ci[j]->lc=NO_UINT;
3355  ar->ci[j]->it=it;
3356  ar->ci[j]->tree=0; /* chart in no tree initially */
3357  AddChart2Tree(tree,j,ar);
3358  }
3359 
3360  /* Now that the list of samples for the new charts is already initialized,
3361  we assign samples to the newly created charts */
3362  for(j=ncp;j<ar->nc;j++)
3363  PopulateWithSamples(pr,j,ar);
3364 
3365  /* Up to here we accomodated the new chart in the atlas and populated it
3366  with samples. Now we have to set up the information in the sample. */
3367 
3368  if (currentID==NO_UINT)
3369  {
3370  /* Sample not in the tree: temporary sample. The new chart is defined on a
3371  temporary sample. The sample is the center of the chart (just enforce it) */
3372  currentSampleInfo->c=newChart;
3373  currentSampleInfo->pc=newChart;
3374  for(j=0;j<ar->k;j++)
3375  currentSampleInfo->t[j]=0;
3376  /* 1+newChart -> we can find out which chart was created at each
3377  sample just by substracting one (used for debug). */
3378  currentSampleInfo->generateChart=1+newChart;
3379  }
3380  else
3381  {
3382  TSampleInfo *sampleInTree;
3383 
3384  /* A sample that is in the tree -> operate with the copy in the tree */
3385 
3386  sampleInTree=ar->si[currentID];
3387  sampleInTree->generateChart=1+newChart; /* just created a chart on the tree sample */
3388  if (sampleInTree->c!=newChart)
3389  {
3390  unsigned int n;
3391  boolean found;
3392  Tchart *ce;
3393  TChartInfo *newChartInfo;
3394  TSampleInfo *previousSampleInfo,*sampleInfo;
3395 
3396  /* For some reason the sample in the tree is not assigned to the
3397  new chart. Correct the situation, stealing the sample from
3398  the chart where it is currently assigned */
3399 
3400  n=sampleInTree->c; /*Chart from where to steal the center*/
3401  currentChartInfo=ar->ci[n];
3402  newChartInfo=ar->ci[newChart]; /* The new chart -> this must receive the sample */
3403 
3404  /* iterate over the samples assigned to 'currentChart' until we find
3405  'currentSampleID'. Then we re-assign it to 'newChart', properly adjusting
3406  the lists of samples. */
3407 
3408  previousSampleInfo=NULL; /* previous sample in the list */
3409  j=currentChartInfo->lc; /* first sample in the list */
3410  found=FALSE;
3411  while((j!=NO_UINT)&&(!found))
3412  {
3413  sampleInfo=ar->si[j];
3414  if (j==currentID)
3415  {
3416  /* remove the sample from the list of chart c*/
3417  if (previousSampleInfo==NULL)
3418  currentChartInfo->lc=sampleInfo->lsc;
3419  else
3420  previousSampleInfo->lsc=sampleInfo->lsc;
3421 
3422  /* add to the list of the new chart */
3423  sampleInfo->lsc=newChartInfo->lc;
3424  newChartInfo->lc=j;
3425  sampleInfo->c=newChart;
3426 
3427  /* Project the sample to the chart. This must result
3428  in zero but....*/
3429  ce=GetAtlasChart(newChart,&(ar->atlas));
3430  Manifold2Chart(sampleInfo->s,ar->tp,sampleInfo->t,ce);
3431  EnlargeChart(sampleInfo->t,ce);
3432 
3433  found=TRUE;
3434  }
3435  else
3436  {
3437  /* Move to next */
3438  previousSampleInfo=sampleInfo;
3439  j=sampleInfo->lsc;
3440  }
3441  }
3442  if (!found)
3443  Error("A sample is not where it should be");
3444  }
3445 
3446  if (currentSampleInfo!=sampleInTree)
3447  {
3448  /* The input parameter is a copy of the node in the tree
3449  We have to update the copy too (basically copy the
3450  sample, the chartID, the parent chart, and the
3451  projection to the chart) */
3452  SetSampleInfo(ar->m,ar->k,currentSampleInfo,sampleInTree);
3453  }
3454  }
3455  return(TRUE); /* The chart could be actually created */
3456  }
3457  else
3458  return(FALSE); /* The chart could not be created (the given point
3459  is in a singular region?) */
3460 }
3461 
3462 
3463 void PopulateWithSamples(Tparameters *pr,unsigned int id,Tatlasrrt *ar)
3464 {
3465  Tchart *c,*c1,*ce;
3466  unsigned int i,j,jt,n,nn,ne;
3467  double *t;
3468  double epsilon;
3469  TSampleInfo *currentSampleInfo;
3470  TSampleInfo *previousSampleInfo;
3471  TChartInfo *currentChartInfo;
3472  TChartInfo *newChartInfo;
3473 
3474  epsilon=GetParameter(CT_EPSILON,pr);
3475 
3476  NEW(t,ar->k,double);
3477 
3478  c=GetAtlasChart(id,&(ar->atlas));
3479  nn=ChartNumNeighbours(c);
3480 
3481  for(i=0;i<nn;i++)
3482  {
3483  /* The neighbouring chart from where to steal some samples */
3484  n=ChartNeighbourID(i,c);
3485  if (n!=NO_UINT)
3486  {
3487  currentChartInfo=ar->ci[n];
3488  c1=GetAtlasChart(n,&(ar->atlas));
3489 
3490  previousSampleInfo=NULL; /* previous sample in the list */
3491  j=currentChartInfo->lc; /* first sample in the list */
3492  while(j!=NO_UINT)
3493  {
3494  currentSampleInfo=ar->si[j];
3495  ne=DetermineChartNeighbour(epsilon,currentSampleInfo->t,c1);
3496  if (ne!=NO_UINT)
3497  {
3498  /* Sample 'j' is not any more in chart 'c1' (chart 'n') but in a
3499  neighbouring one, typically the one just created (ne==id),
3500  but can be any other neighbour */
3501 
3502  newChartInfo=ar->ci[ne]; /* This should be the new chart */
3503 
3504  #if (_DEBUG>2)
3505  fprintf(stderr," Sample %u moves from chart %u to %u\n",j,n,ne);
3506  #endif
3507 
3508  /* Typically 'ce' will be 'c', but not for sure */
3509  ce=GetAtlasChart(ne,&(ar->atlas));
3510  Manifold2Chart(currentSampleInfo->s,ar->tp,currentSampleInfo->t,ce);
3511  EnlargeChart(currentSampleInfo->t,ce);
3512 
3513  currentSampleInfo->c=ne;
3514 
3515  /* we will change lsc[j] in the following -> backup it */
3516  jt=currentSampleInfo->lsc;
3517 
3518  /* remove the sample from the list of chart c*/
3519  if (previousSampleInfo==NULL)
3520  currentChartInfo->lc=currentSampleInfo->lsc;
3521  else
3522  previousSampleInfo->lsc=currentSampleInfo->lsc;
3523 
3524  /* add to the list of chart 'ne' (typically ne==id) */
3525  currentSampleInfo->lsc=newChartInfo->lc;
3526  newChartInfo->lc=j;
3527 
3528  /* The chart importing the sample must be associated with
3529  the tree including this sample. */
3530  AddChart2Tree(GetRRTNodeTree(j,&(ar->rrt)),ne,ar);
3531 
3532  /* Set 'j' to the next in the list of samples for the current
3533  chart (previously backed up) */
3534  j=jt;
3535 
3536  /* Since we removed one element from the list the
3537  previous pointed by 'previousSampleInfo' remains the same. */
3538  }
3539  else
3540  {
3541  /* move to next sample in the list of samples assigned to
3542  chart 'n' */
3543  previousSampleInfo=currentSampleInfo;
3544  j=currentSampleInfo->lsc;
3545  }
3546  }
3547  }
3548  }
3549 
3550  free(t);
3551 }
3552 
3553 unsigned int ReconstructAtlasRRTPath(Tparameters *pr,unsigned int sID,
3554  double *pl,unsigned int *ns,double ***path,Tatlasrrt *ar)
3555 {
3556  unsigned int nv,nvs,i,ms;
3557  signed int j;
3558  double *o,c;
3559  boolean *systemVars;
3560  unsigned int lns;
3561  double **lpath;
3562  unsigned int p;
3563  #if (NEW_BRANCH_EXTENSION)
3564  TAtlasRRTBranchConfig configConnect;
3565  TAtlasRRTBranchStatus statusConnect;
3566 
3567  InitBranchConfig(CONNECT_SAFE,&configConnect);
3568  #else
3569  unsigned int ls;
3570  boolean reachedParent,reachedG;
3571  #endif
3572 
3573  *pl=0;
3574 
3575  /* Get the sample in the tree close to the goal */
3576  nv=CS_WD_GET_SYSTEM_VARS(&systemVars,ar->w);
3577  nvs=0;
3578  for(i=0;i<nv;i++)
3579  {
3580  if (systemVars[i])
3581  nvs++;
3582  }
3583 
3584  InitSamples(&ms,ns,path);
3585 
3586  i=sID;
3587  while (i!=NO_UINT)
3588  {
3589  CS_WD_REGENERATE_ORIGINAL_POINT(pr,ar->si[i]->s,&o,ar->w);
3590  AddSample2Samples(nv,o,nvs,systemVars,&ms,ns,path);
3591  free(o);
3592  p=GetRRTParent(i,&(ar->rrt));
3593  if (p!=NO_UINT)
3594  {
3595  /* Check that the two samples can be actually connected and
3596  measure the distance between them. */
3597  #if (NEW_BRANCH_EXTENSION)
3598  c=New_AddBranchToAtlasRRT(pr,NO_UINT,&configConnect,p,ar->si[i]->s,NULL,NULL,
3599  &statusConnect,&lns,&lpath,ar);
3600  #else
3602  0.0,p,ar->si[i]->s,NULL,NULL,&ls,&reachedParent,&reachedG,
3603  &lns,&lpath,NULL,NULL,ar);
3604  #endif
3605 
3606  #if (NEW_BRANCH_EXTENSION)
3607  if (!statusConnect.reachedQrand)
3608  #else
3609  if (!reachedParent)
3610  #endif
3611  Warning("Path segment could not be reconstructed in ReconstructAtlasRRTPath");
3612 
3613  (*pl)+=c;
3614  #if (ATLASRRT_VERBOSE)
3615  fprintf(stderr,"{%u->%u}[%g]",i,p,c);
3616  #endif
3617 
3618  for(j=lns-1;j>=0;j--)
3619  {
3620  CS_WD_REGENERATE_ORIGINAL_POINT(pr,lpath[j],&o,ar->w);
3621  AddSample2Samples(nv,o,nvs,systemVars,&ms,ns,path);
3622  free(o);
3623  }
3624 
3625  DeleteSamples(lns,lpath);
3626  }
3627  i=p;
3628  }
3629  ReverseSamples(*ns,*path);
3630 
3631  free(systemVars);
3632 
3633  return(nvs);
3634 }
3635 
3636 
3637 unsigned int Steps2PathinAtlasRRT(Tparameters *pr,Tvector *steps,double *pl,double *pc,
3638  unsigned int *ns,double ***path,Tatlasrrt *ar)
3639 {
3640  unsigned int nv,nvs,ms,n,i,k,current,next;
3641  signed int j;
3642  double *o,c;
3643  boolean *systemVars;
3644  unsigned int lns;
3645  double **lpath;
3646  double epsilon,dc;
3647  #if (NEW_BRANCH_EXTENSION)
3648  double delta;
3649  TAtlasRRTBranchConfig configConnect;
3650  TAtlasRRTBranchStatus statusConnect;
3651 
3652  InitBranchConfig(CONNECT_SAFE,&configConnect);
3653  delta=GetParameter(CT_DELTA,pr);
3654  #else
3655  unsigned int ls;
3656  boolean reachedG,reachedNext;
3657  #endif
3658 
3659  #if (ATLASRRT_VERBOSE)
3660  fprintf(stderr,"*****************************************************\n");
3661  fprintf(stderr,"Defining the solution path\n");
3662  fprintf(stderr,"*****************************************************\n");
3663  #endif
3664 
3665  *pl=0; /* path length */
3666  if (pc!=NULL) /* path cost (mechanical work) */
3667  {
3668  *pc=0;
3669  epsilon=GetParameter(CT_EPSILON,pr);
3670  }
3671 
3672  /* Identify system variables */
3673  nv=CS_WD_GET_SYSTEM_VARS(&systemVars,ar->w);
3674  nvs=0;
3675  for(i=0;i<nv;i++)
3676  {
3677  if (systemVars[i])
3678  nvs++;
3679  }
3680 
3681  InitSamples(&ms,ns,path);
3682 
3683  current=*(unsigned int *)GetVectorElement(0,steps);
3684  n=VectorSize(steps);
3685  k=1;
3686  while (k<n)
3687  {
3688  next=*(unsigned int *)GetVectorElement(k,steps);
3689 
3690  CS_WD_REGENERATE_ORIGINAL_POINT(pr,ar->si[current]->s,&o,ar->w);
3691  AddSample2Samples(nv,o,nvs,systemVars,&ms,ns,path);
3692  free(o);
3693 
3694  #if (NEW_BRANCH_EXTENSION)
3695  c=New_AddBranchToAtlasRRT(pr,NO_UINT,&configConnect,current,ar->si[next]->s,NULL,NULL,
3696  &statusConnect,&lns,&lpath,ar);
3697  #else
3699  0.0,current,ar->si[next]->s,NULL,NULL,&ls,&reachedNext,&reachedG,
3700  &lns,&lpath,NULL,NULL,ar);
3701  #endif
3702 
3703  #if (ATLASRRT_VERBOSE)
3704  fprintf(stderr,"{%u->%u}[%g]",current,next,c);
3705  #endif
3706 
3707  (*pl)+=c; /* Update the path length */
3708  if(pc!=NULL) /* Update the path cost (mechanical work) */
3709  {
3710  dc=GetRRTNodeCost(current,&(ar->rrt))-GetRRTNodeCost(next,&(ar->rrt));
3711  (*pc)+=(dc>0?dc:0)+epsilon*c;
3712  }
3713 
3714  #if (NEW_BRANCH_EXTENSION)
3715  if (statusConnect.distQrand>delta)
3716  #else
3717  if (!reachedNext)
3718  #endif
3719  Warning("Path segment could not be reconstructed in Steps2PathinAtlasRRT");
3720  else
3721  {
3722  for(j=0;j<lns;j++)
3723  {
3724  CS_WD_REGENERATE_ORIGINAL_POINT(pr,lpath[j],&o,ar->w);
3725  AddSample2Samples(nv,o,nvs,systemVars,&ms,ns,path);
3726  free(o);
3727  }
3728  DeleteSamples(lns,lpath);
3729  }
3730 
3731  current=next;
3732  k++;
3733  }
3734 
3735  free(systemVars);
3736 
3737  #if (ATLASRRT_VERBOSE)
3738  fprintf(stderr,"*****************************************************\n");
3739  fprintf(stderr,"*****************************************************\n");
3740  #endif
3741 
3742  return(nvs);
3743 }
3744 
3745 void SmoothPathInAtlasRRT(Tparameters *pr,unsigned int sID,Tatlasrrt* ar)
3746 {
3747  signed int l;
3748  unsigned int i,j,k,s,n,n1,n2,o;
3749  unsigned int *path;
3750  double c12,c2_new,c1,c2;
3751  #if (NEW_BRANCH_EXTENSION)
3752  TAtlasRRTBranchConfig configConnect;
3753  TAtlasRRTBranchStatus statusConnect;
3754 
3755  InitBranchConfig(CONNECT_SAMPLES,&configConnect);
3756  #else
3757  boolean reachedQRand,reachedGoal;
3758  unsigned int lastID;
3759  #endif
3760 
3761  n=StepsToRoot(sID,&(ar->rrt));
3762  NEW(path,n,unsigned int);
3763  l=n-1;
3764  s=sID;
3765  while (s!=NO_UINT)
3766  {
3767  path[l]=s;
3768  s=GetRRTParent(s,&(ar->rrt));
3769  l--;
3770  }
3771  s=n; /* initial size of the path */
3772  for(l=0;l<s;l++)
3773  {
3774  /* Select a node at random in the path */
3775  i=randomMax(n-2);
3776  j=i+1+randomMax(n-2-i);
3777 
3778  n1=path[i];
3779  n2=path[j];
3780 
3781  c1=GetRRTNodeCost(n1,&(ar->rrt));
3782  c2=GetRRTNodeCost(n2,&(ar->rrt));
3783 
3784  /* Try to connect the two samples with a shorcut and measure its length */
3785  #if (NEW_BRANCH_EXTENSION)
3786  configConnect.maxLength=c2-c1;
3787  c12=New_AddBranchToAtlasRRT(pr,NO_UINT,&configConnect,n1,ar->si[n2]->s,NULL,NULL,
3788  &statusConnect,NULL,NULL,ar);
3789  #else
3791  c2-c1,n1,ar->si[n2]->s,NULL,
3792  NULL,&lastID,&reachedQRand,&reachedGoal,NULL,NULL,
3793  NULL,NULL,ar);
3794  #endif
3795 
3796  /* If node n2 can be reached from node n1 */
3797  #if (NEW_BRANCH_EXTENSION)
3798  if (statusConnect.reachedQrand)
3799  #else
3800  if (reachedQRand)
3801  #endif
3802  {
3803  /* and the cost is smaller */
3804  c2_new=c1+c12;
3805  if (c2_new<c2)
3806  {
3807  /* Set n1 as a parent of n2*/
3808  SetRRTNodeCost(n2,c12,c2_new,&(ar->rrt));
3809  SetRRTParent(n2,n1,&(ar->rrt));
3810 
3811  /* Shrink the path */
3812  for(k=j,o=i+1;k<n;k++,o++)
3813  path[o]=path[k];
3814  n=o;
3815  }
3816  }
3817  }
3818  free(path);
3819 }
3820 
3822  double scale,unsigned int tree,
3823  unsigned int *nm,double *t,double *p,
3824  Tatlasrrt* ar)
3825 {
3826  boolean havePoint;
3827 
3828  /* This is the place where to implement different sampling strategies,
3829  if desired. We can, for instance, we can select the charts taking
3830  into account the number of samples (more samples, less probability
3831  of selecting them). This will approximate the AtlasRRT to an EST. */
3832 
3833  if ((ar->birrt)&&(tree!=BOTHTREES))
3834  {
3835  /* If the sampling radius is potentially different for each chart,
3836  we have to take into account the size of sampling area for each chart to
3837  uniformly sample on the part of the C-space explored so far. */
3838  #if (ADJUST_SA==1)
3839  {
3840  double *w,s;
3841  unsigned int i,nc;
3842  unsigned int *c;
3843 
3844  if (tree==START2GOAL)
3845  {
3846  nc=ar->nct1;
3847  c=ar->chartsAtTree1;
3848  }
3849  else
3850  {
3851  nc=ar->nct2;
3852  c=ar->chartsAtTree2;
3853  }
3854  NEW(w,nc,double);
3855  s=0.0;
3856  for(i=0;i<nc;i++)
3857  {
3858  /* The 'scale' factor, if any affects all charts and, thus it can be
3859  ruled out. */
3860  w[i]=GetChartSamplingRadius(GetAtlasChart(c[i],&(ar->atlas)));
3861  w[i]=pow(w[i],(double)ar->k);
3862  s+=w[i];
3863  }
3864  *nm=c[randomWithDistribution(nc,s,w)];
3865  free(w);
3866  }
3867  #else
3868  /* Uniform distribution on charts of the tree */
3869  if (tree==START2GOAL)
3870  *nm=ar->chartsAtTree1[randomMax(ar->nct1-1)];
3871  else
3872  *nm=ar->chartsAtTree2[randomMax(ar->nct2-1)];
3873  #endif
3874 
3875  /* Get a point from the selected chart */
3876  havePoint=RandomPointInChart(pr,scale,ar->tp,t,p,GetAtlasChart(*nm,&(ar->atlas)));
3877  }
3878  else
3879  {
3880  double *w=NULL;
3881 
3882  #if (ADJUST_SA==1)
3883  {
3884  double s;
3885  unsigned int i,nc;
3886 
3887  nc=GetAtlasNumCharts(&(ar->atlas));
3888  NEW(w,nc,double);
3889  s=0.0;
3890  for(i=0;i<nc;i++)
3891  {
3892  w[i]=GetChartSamplingRadius(GetAtlasChart(i,&(ar->atlas)));
3893  w[i]=pow(w[i],(double)ar->k);
3894  s+=w[i];
3895  }
3896  *nm=randomWithDistribution(nc,s,w);
3897  }
3898  #endif
3899 
3900  havePoint=RandomPointInAtlas(pr,scale,w,nm,t,p,&(ar->atlas));
3901 
3902  #if (ADJUST_SA==1)
3903  free(w);
3904  #endif
3905  }
3906 
3907  return(havePoint);
3908 }
3909 
3910 
3911 void PlotQrand(Tparameters *pr,char *prefix,unsigned int inear,
3912  unsigned int c_rand,double *t_rand,double *q_rand,
3913  unsigned int xID,unsigned int yID,unsigned int zID,
3914  Tatlasrrt *ar)
3915 {
3916  Tfilename fplot;
3917  double *point,*center,*near;
3918  double *o1,*o2,*o3;
3919  Tchart *chart;
3920  Tcolor color;
3921  Tplot3d p3d;
3922  double x[2],y[2],z[2];
3923 
3924  CreateFileName(NULL,prefix,"_qrand",PLOT3D_EXT,&fplot);
3925  fprintf(stderr,"Plotting Qrand to : %s\n",GetFileFullName(&fplot));
3926 
3927  NewColor(1,0,1,&color); /*magenta*/
3928  InitPlot3d(GetFileFullName(&fplot),FALSE,0,NULL,&p3d);
3929  DeleteFileName(&fplot);
3930 
3931  NEW(point,ar->m,double);
3932  chart=GetAtlasChart(c_rand,&(ar->atlas));
3933 
3934  Local2Global(t_rand,ar->tp,point,chart); /* point must be the same as q_rand */
3935  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point,&o1,ar->w);
3936 
3937  center=GetChartCenter(chart);
3938  CS_WD_REGENERATE_ORIGINAL_POINT(pr,center,&o2,ar->w);
3939 
3940  StartNew3dObject(&color,&p3d);
3941 
3942  /* A large cross at q_rand */
3943  x[0]=o1[xID]-0.15;
3944  y[0]=o1[yID];
3945  z[0]=o1[zID];
3946 
3947  x[1]=o1[xID]+0.15;
3948  y[1]=o1[yID];
3949  z[1]=o1[zID];
3950 
3951  PlotVect3d(2,x,y,z,&p3d);
3952 
3953  x[0]=o1[xID];
3954  y[0]=o1[yID]-0.15;
3955  z[0]=o1[zID];
3956 
3957  x[1]=o1[xID];
3958  y[1]=o1[yID]+0.15;
3959  z[1]=o1[zID];
3960 
3961  PlotVect3d(2,x,y,z,&p3d);
3962 
3963  x[0]=o1[xID];
3964  y[0]=o1[yID];
3965  z[0]=o1[zID]-0.15;
3966 
3967  x[1]=o1[xID];
3968  y[1]=o1[yID];
3969  z[1]=o1[zID]+0.15;
3970 
3971  PlotVect3d(2,x,y,z,&p3d);
3972 
3973  /* A line from q_rand to its chart center */
3974  x[0]=o1[xID];
3975  y[0]=o1[yID];
3976  z[0]=o1[zID];
3977 
3978  x[1]=o2[xID];
3979  y[1]=o2[yID];
3980  z[1]=o2[zID];
3981 
3982  PlotVect3d(2,x,y,z,&p3d);
3983 
3984  /* A line to q_near */
3985  near=ar->si[inear]->s;
3986  CS_WD_REGENERATE_ORIGINAL_POINT(pr,near,&o3,ar->w);
3987 
3988  x[0]=o1[xID];
3989  y[0]=o1[yID];
3990  z[0]=o1[zID];
3991 
3992  x[1]=o3[xID];
3993  y[1]=o3[yID];
3994  z[1]=o3[zID];
3995 
3996  PlotVect3d(2,x,y,z,&p3d);
3997 
3998  DeleteColor(&color);
3999  Close3dObject(&p3d);
4000  ClosePlot3d(FALSE,0,0,0,&p3d);
4001 
4002  free(o1);
4003  free(o2);
4004  free(o3);
4005  free(point);
4006 }
4007 
4008 void PlotConnection(Tparameters *pr,char *prefix,
4009  unsigned int target,unsigned int near,unsigned int end,
4010  unsigned int xID,unsigned int yID,unsigned int zID,
4011  Tatlasrrt *ar)
4012 {
4013  Tfilename fplot;
4014  double *point;
4015  double *o1,*o2,*o3;
4016  Tcolor color;
4017  Tplot3d p3d;
4018  double x[2],y[2],z[2];
4019 
4020  CreateFileName(NULL,prefix,"_connect",PLOT3D_EXT,&fplot);
4021  fprintf(stderr,"Plotting connection to : %s\n",GetFileFullName(&fplot));
4022 
4023  NewColor(1,0,1,&color); /*magenta*/
4024  InitPlot3d(GetFileFullName(&fplot),FALSE,0,NULL,&p3d);
4025  DeleteFileName(&fplot);
4026 
4027  point=ar->si[target]->s;
4028  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point,&o1,ar->w);
4029 
4030  point=ar->si[near]->s;
4031  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point,&o2,ar->w);
4032 
4033  point=ar->si[end]->s;
4034  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point,&o3,ar->w);
4035 
4036  StartNew3dObject(&color,&p3d);
4037 
4038  x[0]=o1[xID];
4039  y[0]=o1[yID];
4040  z[0]=o1[zID];
4041 
4042  x[1]=o2[xID];
4043  y[1]=o2[yID];
4044  z[1]=o2[zID];
4045 
4046  PlotVect3d(2,x,y,z,&p3d);
4047 
4048  x[0]=o1[xID];
4049  y[0]=o1[yID];
4050  z[0]=o1[zID];
4051 
4052  x[1]=o3[xID];
4053  y[1]=o3[yID];
4054  z[1]=o3[zID];
4055 
4056  PlotVect3d(2,x,y,z,&p3d);
4057 
4058  DeleteColor(&color);
4059  Close3dObject(&p3d);
4060  ClosePlot3d(FALSE,0,0,0,&p3d);
4061 
4062  free(o1);
4063  free(o2);
4064  free(o3);
4065 }
4066 
4068 {
4069  unsigned int i;
4070 
4071  fprintf(f,"%u\n",si->id);
4072  for(i=0;i<ar->k;i++)
4073  fprintf(f,"%.16f ",si->t[i]);
4074  fprintf(f,"\n");
4075  fprintf(f,"%u\n",si->pc);
4076  fprintf(f,"%u\n",si->c);
4077  fprintf(f,"%u\n",si->generateChart);
4078  fprintf(f,"%u\n",si->lsc);
4079 }
4080 
4082 {
4083  fprintf(f,"%u\n",ci->lc);
4084  fprintf(f,"%u\n",ci->tree);
4085  fprintf(f,"%u\n",ci->it);
4086 }
4087 
4089 {
4090  unsigned int i;
4091 
4092  fscanf(f,"%u",&(si->id));
4093  si->s=GetRRTNode(si->id,&(ar->rrt));
4094  NEW(si->t,ar->k,double);
4095  for(i=0;i<ar->k;i++)
4096  fscanf(f,"%lf",&(si->t[i]));
4097  fscanf(f,"%u",&(si->pc));
4098  fscanf(f,"%u",&(si->c));
4099  fscanf(f,"%u",&(si->generateChart));
4100  fscanf(f,"%u",&(si->lsc));
4101 }
4102 
4104 {
4105  fscanf(f,"%u",&(ci->lc));
4106  fscanf(f,"%u",&(ci->tree));
4107  fscanf(f,"%u",&(ci->it));
4108 }
4109 
4110 /******************************************************************************/
4111 /******************************************************************************/
4112 /******************************************************************************/
4113 
4114 void InitAtlasRRT(Tparameters *pr,boolean parallel,double *ps,unsigned int mode,boolean graph,
4115  double *pg,TAtlasBase *w,Tatlasrrt *ar)
4116 {
4117  unsigned int i;
4118  boolean intersectParent;
4119  TSampleInfo *currentSampleInfo;
4120 
4121 
4122  /*************************************************************/
4123  /* Init the basic AtlasRRT information */
4124  ar->w=w;
4125  CS_WD_GENERATE_SIMP_INITIAL_BOX(pr,&(ar->ambient),ar->w);
4126  ar->m=GetBoxNIntervals(&(ar->ambient));
4127  ar->e=GetParameter(CT_E,pr);;
4128  ar->ce=GetParameter(CT_CE,pr);
4129  ar->r=GetParameter(CT_R,pr);
4130  /* Exploration trees are forced to be one-directional */
4131  ar->birrt=((!EXPLORATION_RRT)&&(mode!=ONE_TREE));
4132  ar->parallel=parallel;
4133 
4134  /*************************************************************/
4135  /* Init the Atlas */
4136  /* The atlas is initilized on the initial point only, latter
4137  on we add a chart for the final point if the AtlasRRT is
4138  bidirectional. */
4139  if (!InitAtlasFromPoint(pr,FALSE,TRUE,ps,w,&(ar->atlas)))
4140  Error("Can not start the atlas at the given point");
4141  ar->mc=INIT_NUM_CHARTS;
4142 
4143  ar->nc=GetAtlasNumCharts(&(ar->atlas));
4144 
4145  /* Note that InitAtlasFromPoint can change this parameter */
4146  ar->k=(unsigned int)GetParameter(CT_N_DOF,pr);
4147 
4148  /*************************************************************/
4149  /* Init the RRT */
4150  /* This verifies that the initial point are valid (on
4151  the manifold, collision free, in domain,...). It also
4152  checks this for the final point on bidirectional RRTs */
4154  InitRRT(pr,ar->parallel,FALSE,ps,mode,graph,pg,ar->m,w,&(ar->rrt));
4155  ar->ns=GetRRTNumNodes(&(ar->rrt));
4156 
4157  /*************************************************************/
4158  /* Init the mapping from samples to charts */
4159  NEW(ar->ci,ar->mc,TChartInfo*);
4160  for(i=0;i<ar->nc;i++)
4161  {
4162  NEW(ar->ci[i],1,TChartInfo);
4163  ar->ci[i]->lc=NO_UINT; /* No samples in any chart */
4164  ar->ci[i]->tree=START2GOAL;
4165  ar->ci[i]->it=0;
4166  }
4167 
4168  NEW(ar->si,ar->ms,TSampleInfo*);
4169 
4170  NEW(ar->si[0],1,TSampleInfo);
4171  /* This sets t[0] to zero (sample[0] is the center of the first chart) */
4172  currentSampleInfo=ar->si[0];
4173 
4174  NEW(currentSampleInfo->t,ar->k,double);
4175  for(i=0;i<ar->k;i++)
4176  currentSampleInfo->t[i]=0.0;
4177 
4178  /* Chart 0 is not generated from any other chart */
4179  currentSampleInfo->pc=NO_UINT;
4180 
4181  /* Pointer to the first sample in the RRT */
4182  currentSampleInfo->s=GetRRTNode(0,&(ar->rrt));
4183  currentSampleInfo->id=0;
4184 
4185  /* assign the first sample to the first chart */
4186  currentSampleInfo->c=0; /* fist sample is in chart 0 */
4187  ar->ci[0]->lc=0; /* list of samples for chart 0 start at sample 0 */
4188  currentSampleInfo->lsc=NO_UINT; /* and there is no other sample next */
4189 
4190  /* we have a chart on sample 0 */
4191  currentSampleInfo->generateChart=1;
4192 
4193  /*************************************************************/
4194  /* Init the mapping betwen charts and trees */
4195  if (ar->birrt)
4196  {
4197  NEW(ar->si[1],1,TSampleInfo);
4198  currentSampleInfo=ar->si[1];
4199 
4200  /* The goal samples has param 0 in its own chart */
4201  NEW(currentSampleInfo->t,ar->k,double);
4202 
4203  for(i=0;i<ar->k;i++)
4204  currentSampleInfo->t[i]=0.0;
4205 
4206  /* Allocate the samples 2 tree mapping */
4207  ar->mct1=ar->mc;
4208  NEW(ar->chartsAtTree1,ar->mct1,unsigned int);
4209 
4210  ar->mct2=ar->mc;
4211  NEW(ar->chartsAtTree2,ar->mct2,unsigned int);
4212 
4213  /* Assign char 0 to the first tree */
4214  ar->chartsAtTree1[0]=0;
4215  ar->nct1=1;
4216 
4217  ar->nct2=0;
4218  /* The chart for the goal sample is added to the tree
4219  using AddChart2AtlasRRT (see below) and this automatically
4220  updates ar->chartsAtTree2, ar->nct2,...*/
4221 
4222  /* Chart 1 is not generated from any other chart */
4223  currentSampleInfo->pc=NO_UINT;
4224 
4225  /* Pointer to the sample in the RRT */
4226  currentSampleInfo->s=GetRRTNode(1,&(ar->rrt));
4227  currentSampleInfo->id=1;
4228 
4229  /* By setting c[1]=1, AddChart2AtlasRRT does not
4230  re-assigns the new sample. We do it manually
4231  after the chart creation. */
4232  currentSampleInfo->c=1;
4233 
4234  if (!AddChart2AtlasRRT(pr,GOAL2START,0,currentSampleInfo,&intersectParent,ar))
4235  Error("Could not init the AtlasRRT on the given point (is it singular? decrease epsilon?)");
4236 
4237  /* Manually assign sample 1 to chart 1 */
4238  ar->ci[1]->lc=1;
4239  currentSampleInfo->lsc=NO_UINT;
4240  }
4241 
4242  /*************************************************************/
4243  /* Get the topology for all variables */
4244  ar->tp=GetRRTTopology(&(ar->rrt));
4245 
4246  /*************************************************************/
4247  /* Since atlas are defined on the simplified system we get the
4248  corresponding Jacobian. */
4249  CS_WD_GET_SIMP_JACOBIAN(pr,&(ar->J),ar->w);
4250 }
4251 
4252 boolean AtlasRRTSample(Tparameters *pr,unsigned int samplingMode,
4253  unsigned int it,unsigned int tree,
4254  double *goal,double scale,boolean *exploration,
4255  unsigned int *c_rand,double *t_rand,double *q_rand,
4256  TAtlasRRTStatistics *arst,Tatlasrrt *ar)
4257 {
4258  boolean expand2Goal,validSample;
4259  #if (ATLASRRT_VERBOSE)
4260  unsigned int s;
4261  #endif
4262 
4263  expand2Goal=((goal!=NULL)&&((it==0)||((!ar->birrt)&&(randomDouble()<0.01))));
4264 
4265  if (expand2Goal)
4266  {
4267  memcpy(q_rand,goal,ar->m*sizeof(double));
4268  #if (GET_ATLASRRT_STATISTICS)
4270  #endif
4271  #if (ATLASRRT_VERBOSE)
4272  fprintf(stderr," Expanding to goal-----------------------------------------------------------------\n");
4273  #endif
4274  *exploration=FALSE;
4275  *c_rand=NO_UINT;
4276  }
4277  else
4278  {
4279  #if (ATLASRRT_VERBOSE)
4280  s=0;
4281  #endif
4282  switch(samplingMode)
4283  {
4284  case AMBIENT_SAMPLING:
4285  case KDTREE_SAMPLING:
4286  do {
4287  RRTSample(samplingMode,tree,NULL,q_rand,NULL,&(ar->rrt));
4288  validSample=CS_WD_SIMP_INEQUALITIES_HOLD(pr,q_rand,ar->w);
4289  #if (ATLASRRT_VERBOSE)
4290  s++;
4291  #endif
4292  #if (GET_ATLASRRT_STATISTICS)
4294  if (!validSample)
4296  #endif
4297  } while (!validSample);
4298  *exploration=FALSE;
4299  *c_rand=NO_UINT;
4300  #if (ATLASRRT_VERBOSE)
4301  fprintf(stderr," Random point in ambient. Rej: %u\n",s);
4302  #endif
4303  break;
4304 
4305  case TANGENT_SAMPLING:
4306  do {
4307  validSample=RandomPointInAtlasTree(pr,scale,tree,c_rand,t_rand,q_rand,ar);
4308  #if (ATLASRRT_VERBOSE)
4309  s++;
4310  #endif
4311  #if (ADJUST_SA==1)
4312  if (!validSample)
4314  #endif
4315  #if (GET_ATLASRRT_STATISTICS)
4317  if (!validSample)
4319  #endif
4320  } while (!validSample);
4321 
4322  #if (ADJUST_SA==1)
4324  #endif
4325  *exploration=(Norm(ar->k,t_rand)>ar->r);
4326  #if (ATLASRRT_VERBOSE)
4327  fprintf(stderr," Random point on chart %u (rej: %u) [%g:%s]\n",*c_rand,s,
4328  Norm(ar->k,t_rand),(*exploration?"exp":"non-exp"));
4329  #endif
4330  break;
4331  default:
4332  Error("Unknow sampling mode in AtlasRRTSample");
4333  break;
4334  }
4335  }
4336 
4337  return(expand2Goal);
4338 }
4339 
4340 boolean AtlasRRTValidateSample(Tparameters *pr,double *q_rand,unsigned int tree,boolean expand2goal,
4341  unsigned int lastNN2Goal,double *goal,double l,double *h,unsigned int *i_near,
4342  TAtlasRRTStatistics *arst,Tatlasrrt *ar)
4343 {
4344  boolean validSample=TRUE;
4345 
4346  /* check if the sample in invalid due to a heuristic used in optimal path planning */
4347  if ((expand2goal)||(goal==NULL))
4348  *h=0;
4349  else
4350  {
4351  *h=DistanceTopology(ar->m,ar->tp,q_rand,goal);
4352  if ((l<INF)&&((HEURISTIC_RRT_STAR)&(1)))
4353  validSample=((DistanceTopology(ar->m,ar->tp,ar->si[0]->s,q_rand)+*h)<=l);
4354  }
4355 
4356  /* Now check if the sample is invalid due to its nearest neighbour (dynamic domain et al.) */
4357  if (validSample)
4358  {
4359  #if (ATLASRRT_GLOBAL_NN)
4360  /*search in the entire atlas */
4361  *i_near=GetRRTNN(tree,q_rand,&(ar->rrt));
4362  #else
4363  if (expand2Goal)
4364  *i_near=GetRRTNN(tree,q_rand,&(ar->rrt));
4365  else
4366  {
4367  /* limit the search to q_rand chart and neigbors charts */
4368  *i_near=GetRRTNNInNeighbourChart(tree,c_rand,t_rand,q_rand,ar);
4369  if (*i_near==NO_UINT)
4370  *i_near=GetRRTNN(tree,q_rand,&(ar->rrt));
4371  }
4372  #endif
4373  #if (ATLASRRT_VERBOSE)
4374  fprintf(stderr," Nearest point %u on chart %u \n",*i_near,ar->si[*i_near]->c);
4375  fflush(stdout);
4376  #endif
4377 
4378  /* Check if the random sample is in the domain of the nearest neighbour */
4379  /* This only has effect if paramter DYNAMIC_DOMAIN is >0 */
4380  validSample=(((!expand2goal)||(lastNN2Goal!=*i_near))&&
4381  (InDynamicDomain(*i_near,q_rand,&(ar->rrt))));
4382  }
4383 
4384  #if (GET_ATLASRRT_STATISTICS)
4385  if (!validSample)
4387  #endif
4388 
4389  return(validSample);
4390 }
4391 
4392 boolean AtlasRRT(Tparameters *pr,double *pg,double *time,
4393  double *pl,unsigned int *ns,double ***path,
4394  TAtlasRRTStatistics *str,Tatlasrrt *ar)
4395 {
4396  boolean done;
4397  double dst;
4398  unsigned int it,n;
4399  double er,epsilon,h;
4400  double *pWithDummies,*initialPoint,*finalPoint,*q_rand,*q_goal,*t_rand;
4401  boolean expand2Goal,pathFound;
4402  unsigned int samplingMode;
4403  unsigned int i_near1,i_near2;
4404  unsigned int t1,t2;
4405  unsigned int lastSample;
4406  unsigned int lastSample2;
4407  TAtlasRRTStatistics *arst;
4408  Tstatistics stime; /* used just to measure execution time */
4409  boolean collision=FALSE;
4410  unsigned int target;
4411  unsigned int lastNN2Goal;
4412  unsigned int db;
4413  double maxTime;
4414  unsigned int maxNodes;
4415  boolean exploration;
4416  double scale; /* Global scale factor for the sampling areas */
4417  boolean validSample;
4418  unsigned int c_rand;
4419  #if (NEW_BRANCH_EXTENSION)
4420  TAtlasRRTBranchConfig configExtend,configConnect;
4421  TAtlasRRTBranchStatus statusExtend,statusConnect;
4422 
4423  InitBranchConfig(EXTEND_RRT,&configExtend);
4424  InitBranchConfig(CONNECT_RRTs,&configConnect);
4425  #else
4426  boolean reachedQRand,reachedGoal;
4427  #endif
4428 
4429  db=(unsigned int)GetParameter(CT_DETECT_BIFURCATIONS,pr);
4430  if (db>0)
4431  Error("AtlasRRT can not deal with bifurcations (yet)");
4432 
4433  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
4434 
4435  scale=1.0; /* Not used yet... */
4436 
4437  /* Initially the AtlasRRT must only include one sample and one chart or
4438  two sample and two chart for bidirectional trees */
4439  n=(ar->birrt?2:1);
4440  if ((ar->ns!=n)||(ar->nc!=n))
4441  Error("AtlasRRT must be used on a just initialized AtlasRRT");
4442 
4443  #if (GET_ATLASRRT_STATISTICS)
4444  {
4445  unsigned int i;
4446 
4447  NEW(arst,1,TAtlasRRTStatistics);
4448  InitAtlasRRTStatistics(arst);
4449  for(i=0;i<ar->nc;i++)
4450  NewAtlasRRTChart(arst);
4451  for(i=0;i<ar->ns;i++)
4452  NewAtlasRRTSample(arst);
4453  }
4454  #else
4455  arst=NULL;
4456  #endif
4457 
4458  /* Init the RRT structure */
4459  epsilon=GetParameter(CT_EPSILON,pr);
4460  maxTime=GetParameter(CT_MAX_PLANNING_TIME,pr);
4461  maxNodes=(unsigned int)GetParameter(CT_MAX_NODES_RRT,pr);
4462 
4463  /* For bi-directional AtlasRRTs the goal is already in the RRT
4464  and it is already verified */
4465  initialPoint=ar->si[0]->s;
4466  if (ar->birrt)
4467  finalPoint=ar->si[1]->s;
4468  else
4469  {
4470  if (EXPLORATION_RRT)
4471  finalPoint=NULL;
4472  else
4473  {
4474  /* For one-directional RRTS, the goal is given as a parameter when
4475  calling this function and we must ensure that it is valid */
4476  CS_WD_REGENERATE_SOLUTION_POINT(pr,pg,&pWithDummies,ar->w);
4477  CS_WD_GENERATE_SIMPLIFIED_POINT(pr,pWithDummies,&finalPoint,ar->w);
4478 
4479  if ((!PointInBoxTopology(NULL,TRUE,ar->m,finalPoint,epsilon,ar->tp,&(ar->ambient)))||
4480  (!CS_WD_SIMP_INEQUALITIES_HOLD(pr,finalPoint,ar->w)))
4481  Error("The goal point for the RRT is not in domain");
4482 
4483  if (ar->m==ar->k) /* empty system of equations */
4484  er=0;
4485  else
4486  er=CS_WD_ERROR_IN_SIMP_EQUATIONS(pr,finalPoint,ar->w);
4487  if (er>epsilon)
4488  Error("The target point is not on the manifold");
4489 
4490  collision=CS_WD_ORIGINAL_IN_COLLISION(pr,pWithDummies,NULL,ar->w);
4491  if (collision)
4492  Error("Target point for the RRT is in collision");
4493  free(pWithDummies);
4494  }
4495  }
4496 
4497  NEW(q_rand,ar->m,double);
4498  if (ar->birrt)
4499  NEW(q_goal,ar->m,double);
4500  NEW(t_rand,ar->k,double);
4501 
4502  done=FALSE;
4503  lastNN2Goal=NO_UINT;
4504  it=0;
4505  InitStatistics(0,0,&stime);
4506  *time=0.0;
4507 
4508  /* The two trees. This is only used for bidirectiononal RRTs. In norma
4509  RRTs only the START2GOAL tree is extended*/
4510  t1=START2GOAL;
4511  t2=GOAL2START;
4512 
4513  while((!done)&&(*time<maxTime)&&(ar->ns<maxNodes))
4514  {
4515  #if (!ATLASRRT_VERBOSE)
4516  if ((it%1000)==0)
4517  #endif
4518  fprintf(stderr,"Iteration: %u (s:%u c:%u t:%u tm:%g sc:%.2f)\n",it,ar->ns,ar->nc,t1,*time,scale);
4519 
4520  /*******************************************************************/
4521  /* Sample */
4522  exploration=FALSE;
4523  do {
4524  /* Generate a random sample */
4525  expand2Goal=AtlasRRTSample(pr,samplingMode,it,t1,finalPoint,scale,
4526  &exploration,&c_rand,t_rand,q_rand,arst,ar);
4527 
4528  /* validate the random sample */
4529  validSample=AtlasRRTValidateSample(pr,q_rand,t1,expand2Goal,lastNN2Goal,NULL,INF,
4530  &h,&i_near1,arst,ar);
4531  } while (!validSample);
4532 
4533  if (expand2Goal)
4534  lastNN2Goal=i_near1;
4535 
4536  /*******************************************************************/
4537  /* Extend the RRT from q_near toward q_rand */
4538  #if (GET_ATLASRRT_STATISTICS)
4539  NewAtlasRRTBranch(arst);
4540  NewAtlasRRTDistanceQrand(DistanceTopology(ar->m,ar->tp,ar->si[i_near1]->s,q_rand),arst);
4541  #endif
4542  #if (NEW_BRANCH_EXTENSION)
4543  configExtend.onManifold=expand2Goal; /* can eventually be true for oneDirectional RRTs */
4544  configExtend.explorationSample=exploration;
4545  dst=New_AddBranchToAtlasRRT(pr,it,&configExtend,i_near1,q_rand,
4546  (((!ar->birrt)||(t1==START2GOAL))?finalPoint:initialPoint),
4547  (void*)arst,&statusExtend,NULL,NULL,ar);
4548 
4549  lastSample=statusExtend.lastID;
4550  done=((!EXPLORATION_RRT)&&(!ar->birrt)&&(statusExtend.reachedGoal));
4551  #else
4552  dst=AddBranchToAtlasRRT(pr,it,ADD_ALL,TRUE,TRUE,expand2Goal,exploration,
4553  0.0,i_near1,q_rand,
4554  (((!ar->birrt)||(t1==START2GOAL))?finalPoint:initialPoint),
4555  (void*)arst,&lastSample,&reachedQRand,&reachedGoal,NULL,NULL,
4556  NULL,NULL,ar);
4557 
4558  done=((!EXPLORATION_RRT)&&(!ar->birrt)&&(reachedGoal));
4559  #endif
4560 
4561  #if (GET_ATLASRRT_STATISTICS)
4562  if (dst>0)
4564  #endif
4565 
4566  if ((!done)&&(ar->birrt))
4567  {
4568  if (dst>0)
4569  {
4570  #if (ADJUST_SA)
4571  if (samplingMode==TANGENT_SAMPLING)
4572  {
4573  #if (ADJUST_SA==2)
4574  /* No trouble extending branches: increase sampling area to focus on exploration */
4575  //scale=1.0;
4576  scale=scale*(1+MOV_AVG_UP);
4577  if (scale>1.0) scale=1.0;
4578  #else
4579  /* an alternative is to adjust the sampling radius locally (ADJUST_SA==1) */
4580  if (!expand2Goal)
4582  #endif
4583  }
4584  #endif
4585 
4586  /* Try to connect to the other tree */
4587 
4588  /* Get the node of the just added branch closer to the other tree (and the node of
4589  the other tree closer to this just added node). */
4590  GetRRTNNInBranch(t2,i_near1,lastSample,&target,&i_near2,&(ar->rrt));
4591 
4592  lastSample=target;
4593  memcpy(q_rand,ar->si[target]->s,ar->m*sizeof(double));
4594 
4595  memcpy(q_goal,q_rand,ar->m*sizeof(double)); /* copy of Qrand */
4596 
4597  /* Try to connect the '2nd' tree to the last node added to the '1st' tree */
4598  #if (GET_ATLASRRT_STATISTICS)
4600  #endif
4601  #if (NEW_BRANCH_EXTENSION)
4602  dst=New_AddBranchToAtlasRRT(pr,it,&configConnect,i_near2,q_rand,q_goal,
4603  (void*)arst,&statusConnect,NULL,NULL,ar);
4604 
4605  lastSample2=statusConnect.lastID;
4606  done=((!EXPLORATION_RRT)&&(statusConnect.reachedGoal));
4607  #else
4609  0.0,i_near2,q_rand,q_goal,
4610  (void*)arst,&lastSample2,&reachedQRand,&reachedGoal,NULL,NULL,
4611  NULL,NULL,ar);
4612 
4613  done=((!EXPLORATION_RRT)&&(reachedGoal));
4614  #endif
4615 
4616  #if (GET_ATLASRRT_STATISTICS)
4617  if (dst>0)
4619  #endif
4620  }
4621  #if (ADJUST_SA)
4622  else
4623  {
4624  if (samplingMode==TANGENT_SAMPLING)
4625  {
4626  #if (ADJUST_SA==2)
4627  /* Troubles extending branches: reduce the sampling areas to focus on refinement */
4628  scale=scale*(1-MOV_AVG_DOWN);
4629  if (scale<0.05) scale=0.05;
4630  #else
4631  /* an alternative is to adjust the sampling radius locally */
4632  if (!expand2Goal)
4634  #endif
4635  }
4636  }
4637  #endif
4638 
4639  /* Swap the trees */
4640  if ((it%2)==0)
4641  {
4642  t1=START2GOAL;
4643  t2=GOAL2START;
4644  }
4645  else
4646  {
4647  t1=GOAL2START;
4648  t2=START2GOAL;
4649  }
4650  }
4651 
4652  it++;
4653  *time=GetElapsedTime(&stime);
4654  }
4655  DeleteStatistics(&stime);
4656 
4657  #if (GET_ATLASRRT_STATISTICS)
4658  if (str==NULL)
4659  PrintAtlasRRTStatistics(ar,arst);
4660  else
4661  AccumulateAtlasRRTStatistics(arst,str);
4663  free(arst);
4664  #endif
4665 
4666  fprintf(stderr,"Final number of samples: %u\n",ar->ns);
4667 
4668  /* Reconstruct the path (if any) */
4669  if (EXPLORATION_RRT)
4670  pathFound=FALSE;
4671  else
4672  pathFound=PathStart2GoalInRRT(pr,finalPoint,lastSample,lastSample2,
4673  pl,NULL,ns,path,&(ar->rrt));
4674 
4675  free(t_rand);
4676  free(q_rand);
4677  if (ar->birrt)
4678  free(q_goal);
4679  else
4680  {
4681  if (finalPoint!=NULL)
4682  free(finalPoint);
4683  }
4684 
4685  return(pathFound);
4686 }
4687 
4688 boolean AtlasTRRT(Tparameters *pr,double *pg,double *time,
4689  double *pl,double *pc,unsigned int *ns,double ***path,
4690  double (*costF)(Tparameters*,boolean,double*,void*),
4691  void *costData,TAtlasRRTStatistics *str,Tatlasrrt *ar)
4692 {
4693  boolean done;
4694  unsigned int it;
4695  double er,epsilon,h;
4696  unsigned int samplingMode;
4697  double *pWithDummies,*finalPoint,*q_rand,*t_rand;
4698  unsigned int c_rand;
4699  boolean expand2Goal,pathFound,exploration;
4700  unsigned int i_near1;
4701  TAtlasRRTStatistics *arst;
4702  Tstatistics stime; /* used just to measure execution time */
4703  boolean collision=FALSE;
4704  unsigned int lastNN2Goal;
4705  unsigned int db;
4706  double maxTime;
4707  unsigned int maxNodes;
4708  double scale; /* Global scale factor for sampling areas */
4709  boolean validSample;
4710  #if (NEW_BRANCH_EXTENSION)
4711  TAtlasRRTBranchConfig configExtend;
4712  TAtlasRRTBranchStatus statusExtend;
4713 
4714  InitBranchConfig(EXTEND_RRT,&configExtend);
4715  configExtend.costF=costF;
4716  configExtend.costData=costData;
4717  #else
4718  boolean reachedQRand,reachedGoal;
4719  unsigned int lastSample;
4720  #endif
4721 
4722  if (ar->birrt)
4723  Error("AtlasTRRT operates on one-directional RRTs");
4724 
4725  db=(unsigned int)GetParameter(CT_DETECT_BIFURCATIONS,pr);
4726  if (db>0)
4727  Error("AtlasRRT can not deal with bifurcations (yet)");
4728 
4729  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
4730 
4731  scale=1.0; /* not used yet */
4732 
4733  /* Initially the AtlasRRT must only include one sample and one chart or
4734  two sample and two chart for bidirectional trees */
4735  if (ar->ns>1)
4736  Error("AtlasRRTstar must be used to a just initilized RRT");
4737 
4738  #if (GET_ATLASRRT_STATISTICS)
4739  {
4740  unsigned int i;
4741 
4742  NEW(arst,1,TAtlasRRTStatistics);
4743  InitAtlasRRTStatistics(arst);
4744  for(i=0;i<ar->nc;i++)
4745  NewAtlasRRTChart(arst);
4746  for(i=0;i<ar->ns;i++)
4747  NewAtlasRRTSample(arst);
4748  }
4749  #else
4750  arst=NULL;
4751  #endif
4752 
4753  /* Init the RRT structure */
4754  epsilon=GetParameter(CT_EPSILON,pr);
4755  maxTime=GetParameter(CT_MAX_PLANNING_TIME,pr);
4756  maxNodes=(unsigned int)GetParameter(CT_MAX_NODES_RRT,pr);
4757 
4758  if (EXPLORATION_RRT)
4759  finalPoint=NULL;
4760  else
4761  {
4762  /* One-directional RRTs, the goal is given as a parameter
4763  and we must ensure that it is valid */
4764  CS_WD_REGENERATE_SOLUTION_POINT(pr,pg,&pWithDummies,ar->w);
4765  CS_WD_GENERATE_SIMPLIFIED_POINT(pr,pWithDummies,&finalPoint,ar->w);
4766 
4767  if ((!PointInBoxTopology(NULL,TRUE,ar->m,finalPoint,epsilon,ar->tp,&(ar->ambient)))||
4768  (!CS_WD_SIMP_INEQUALITIES_HOLD(pr,finalPoint,ar->w)))
4769  Error("The goal point for the RRT is not in domain");
4770 
4771  if (ar->m==ar->k)
4772  er=0;
4773  else
4774  er=CS_WD_ERROR_IN_SIMP_EQUATIONS(pr,finalPoint,ar->w);
4775  if (er>epsilon)
4776  Error("The target point is not on the manifold");
4777 
4778  collision=CS_WD_ORIGINAL_IN_COLLISION(pr,pWithDummies,NULL,ar->w);;
4779  if (collision)
4780  Error("Target point for the RRT is in collision");
4781  free(pWithDummies);
4782  }
4783 
4784  /*init the cost of the first node*/
4785  SetRRTNodeCost(0,0,costF(pr,TRUE,GetRRTNode(0,&(ar->rrt)),costData),&(ar->rrt));
4786 
4787  NEW(q_rand,ar->m,double);
4788  NEW(t_rand,ar->k,double);
4789 
4790  done=FALSE;
4791  lastNN2Goal=NO_UINT;
4792  it=1;
4793  InitStatistics(0,0,&stime);
4794  *time=0.0;
4795 
4796  while((!done)&&(*time<maxTime)&&(ar->ns<maxNodes))
4797  {
4798  #if (!ATLASRRT_VERBOSE)
4799  if ((it%1000)==0)
4800  #endif
4801  fprintf(stderr,"Iteration: %u (s:%u c:%u t:%u tm:%g tmp:%g)\n",it,ar->ns,ar->nc,
4802  START2GOAL,*time,GetTRRTTemperature(&(ar->rrt)));
4803 
4804 
4805  /*******************************************************************/
4806  /* Sample */
4807  exploration=FALSE;
4808  do {
4809  /* generate the random sample */
4810  expand2Goal=AtlasRRTSample(pr,samplingMode,it,START2GOAL,finalPoint,scale,
4811  &exploration,&c_rand,t_rand,q_rand,arst,ar);
4812 
4813  /* validate the random sample */
4814  validSample=AtlasRRTValidateSample(pr,q_rand,START2GOAL,expand2Goal,lastNN2Goal,NULL,INF,
4815  &h,&i_near1,arst,ar);
4816 
4817  /* There is no point in expanding the same node towards the goal twice */
4818  } while (!validSample);
4819 
4820  if (expand2Goal)
4821  lastNN2Goal=i_near1;
4822 
4823  /*******************************************************************/
4824  /* Extend the RRT from q_near toward q_rand */
4825  #if (NEW_BRANCH_EXTENSION)
4826  configExtend.onManifold=expand2Goal;
4827  configExtend.explorationSample=exploration;
4828  New_AddBranchToAtlasRRT(pr,it,&configExtend,i_near1,q_rand,finalPoint,
4829  (void*)arst,&statusExtend,NULL,NULL,ar);
4830  done=((!EXPLORATION_RRT)&&(statusExtend.reachedGoal));
4831  #else
4832  AddBranchToAtlasRRT(pr,it,ADD_ALL,TRUE,TRUE,expand2Goal,exploration,
4833  0.0,i_near1,q_rand,finalPoint,
4834  (void*)arst,&lastSample,&reachedQRand,&reachedGoal,
4835  NULL,NULL,costF,costData,ar);
4836 
4837  done=((!EXPLORATION_RRT)&&(reachedGoal));
4838  #endif
4839 
4840  it++;
4841  *time=GetElapsedTime(&stime);
4842  }
4843  DeleteStatistics(&stime);
4844 
4845  #if (GET_ATLASRRT_STATISTICS)
4846  if (str==NULL)
4847  PrintAtlasRRTStatistics(ar,arst);
4848  else
4849  AccumulateAtlasRRTStatistics(arst,str);
4851  free(arst);
4852  #endif
4853 
4854  fprintf(stderr,"Final number of samples: %u\n",ar->ns);
4855 
4856  /* Reconstruct the path (if any) */
4857  #if (NEW_BRANCH_EXTENSION)
4858  pathFound=PathStart2GoalInRRT(pr,finalPoint,statusExtend.lastID,
4859  NO_UINT,pl,pc,ns,path,&(ar->rrt));
4860  #else
4861  pathFound=PathStart2GoalInRRT(pr,finalPoint,lastSample,
4862  NO_UINT,pl,pc,ns,path,&(ar->rrt));
4863  #endif
4864 
4865  free(t_rand);
4866  free(q_rand);
4867  free(finalPoint);
4868 
4869  return(pathFound);
4870 }
4871 
4873  unsigned int it,boolean expand2Goal,
4874  unsigned int i_near,double *q_rand,
4875  unsigned int *id_goal,double *goal,
4876  TAtlasRRTStatistics *arst,
4877  Tatlasrrt *ar)
4878 {
4879  double d,epsilon;
4880  unsigned int id_new;
4881  #if (NEW_BRANCH_EXTENSION)
4882  TAtlasRRTBranchConfig configExtend;
4883  TAtlasRRTBranchStatus statusExtend;
4884 
4885  InitBranchConfig(CONNECT_SAMPLES,&configExtend);
4886  #else
4887  boolean reachedQRand,reachedGoal;
4888  #endif
4889 
4890  epsilon=GetParameter(CT_EPSILON,pr);
4891 
4892  /* Try to advance as much as possible in the direction of q_rand. Only
4893  the last node is added to the tree. */
4894  #if (NEW_BRANCH_EXTENSION)
4895  configExtend.addMode=(expand2Goal?ADD_LAST_NO_REP:ADD_LAST);
4896  configExtend.onManifold=expand2Goal;
4897  d=New_AddBranchToAtlasRRT(pr,it,&configExtend,i_near,q_rand,goal,
4898  (void*)arst,&statusExtend,NULL,NULL,ar);
4899  id_new=statusExtend.lastID;
4900  #else
4901  d=AddBranchToAtlasRRT(pr,it,(expand2Goal?ADD_LAST_NO_REP:ADD_LAST),TRUE,TRUE,expand2Goal,FALSE,
4902  0.0,i_near,q_rand,goal,
4903  (void*)arst,&id_new,&reachedQRand,&reachedGoal,NULL,NULL,NULL,NULL,ar);
4904  #endif
4905 
4906  /* if we actually added a node */
4907  if (id_new!=i_near)
4908  {
4909  /* Store the cost of the new node. The cost to the parent is already correct (we
4910  need it if 'graph's is set to TRUE) but the total cost is not set */
4911  SetRRTNodeCost(id_new,d,GetRRTNodeCost(i_near,&(ar->rrt))+d,&(ar->rrt));
4912 
4913  #if (ATLASRRT_VERBOSE)
4914  fprintf(stderr," {%u->%u}[%g]\n",id_new,GetRRTParent(id_new,&(ar->rrt)),d);
4915  #endif
4916 
4917  /* if the new point is actually the goal record it */
4918  #if (NEW_BRANCH_EXTENSION)
4919  if ((goal!=NULL)&&(*id_goal==NO_UINT)&&
4920  ((statusExtend.reachedGoal)||((expand2Goal)&&(statusExtend.reachedQrand))))
4921  #else
4922  if ((goal!=NULL)&&(*id_goal==NO_UINT)&&
4923  ((reachedGoal)||((expand2Goal)&&(reachedQRand))))
4924  #endif
4925  {
4926  #if (NEW_BRANCH_EXTENSION)
4927  if (statusExtend.distGoal<epsilon)
4928  #else
4929  double dg;
4930 
4931  dg=DistanceTopology(ar->m,ar->tp,ar->si[id_new]->s,goal);
4932  if (dg<epsilon)
4933  #endif
4934  /* The new node is actually the goal */
4935  *id_goal=id_new;
4936  else
4937  {
4938  /* If the branch stopped very close to the goal, we add a small
4939  branch from the end of the branch to the goal and the goal itself. */
4940  #if (NEW_BRANCH_EXTENSION)
4941  configExtend.addMode=ADD_LAST;
4942  configExtend.onManifold=TRUE;
4943  d=New_AddBranchToAtlasRRT(pr,it,&configExtend,i_near,goal,NULL,
4944  (void*)arst,&statusExtend,NULL,NULL,ar);
4945  *id_goal=statusExtend.lastID;
4946 
4947  if (!statusExtend.reachedQrand)
4948  #else
4949  d=AddBranchToAtlasRRT(pr,it,ADD_LAST,TRUE,TRUE,TRUE,FALSE,
4950  0.0,id_new,goal,NULL,
4951  (void*)arst,id_goal,&reachedQRand,&reachedGoal,NULL,NULL,
4952  NULL,NULL,ar);
4953  if (!reachedQRand)
4954  #endif
4955  Error("Could not reach goal from near-goal");
4956 
4957  SetRRTNodeCost(*id_goal,d,GetRRTNodeCost(*id_goal,&(ar->rrt))+d,&(ar->rrt));
4958 
4959  #if (ATLASRRT_VERBOSE)
4960  fprintf(stderr," {%u->%u}[%g] **\n",*id_goal,GetRRTParent(*id_goal,&(ar->rrt)),d);
4961  #endif
4962  }
4963  }
4964  }
4965  return(id_new);
4966 }
4967 
4969  unsigned int id_new,unsigned int i_near,double gamma,
4970  unsigned int nn,unsigned int *n,double **c,
4971  double h,Theap *q,unsigned int *t,
4972  TAtlasRRTStatistics *arst,Tatlasrrt *ar)
4973 {
4974  unsigned int i;
4975  double ic,cn,epsilon,c_new;
4976  double *cost;
4977  boolean *reachedQRand;
4978  double *q_new;
4979  TDoublePair pair;
4980  unsigned int rrtMode;
4981  boolean graph;
4982  #if (NEW_BRANCH_EXTENSION)
4983  TAtlasRRTBranchConfig configExtend;
4984  TAtlasRRTBranchStatus *statusExtend;
4985 
4986  InitBranchConfig(CONNECT_SAMPLES,&configExtend);
4987  NEW(statusExtend,nn,TAtlasRRTBranchStatus);
4988  #endif
4989 
4990  epsilon=GetParameter(CT_EPSILON,pr);
4991 
4992  /*******************************************************************/
4993  /* Wire: Search for the lowest cost path to the new node */
4994  #if (ATLASRRT_VERBOSE)
4995  fprintf(stderr," Wire %u [nn:%u g:%g]\n",id_new,nn,gamma);
4996  #endif
4997  rrtMode=GetRRTMode(&(ar->rrt));
4998  graph=IsRRTGraph(&(ar->rrt));
4999  #if (RRTSTAR_SYMMETRIC_COST)
5000  if (!graph)
5001  NEW(*c,nn,double);
5002  #endif
5003  ic=GetRRTNodeCostFromParent(id_new,&(ar->rrt)); /*cost to i_near*/
5004  q_new=ar->si[id_new]->s;
5005  *t=0; /* initially no tree in the set of neighbours */
5006 
5007  NEW(cost,nn,double);
5008  NEW(reachedQRand,nn,boolean);
5009 
5010  #pragma omp parallel for private(i) schedule(dynamic) if (ar->parallel)
5011  for(i=0;i<nn;i++)
5012  {
5013  if (n[i]==id_new)
5014  reachedQRand[i]=FALSE;
5015  else
5016  {
5017  if (n[i]==i_near)
5018  {
5019  cost[i]=ic;
5020  reachedQRand[i]=TRUE;
5021  }
5022  else
5023  {
5024  if (ar->parallel)
5025  {
5026  boolean collision;
5027 
5028  /* When executing in parallel we:
5029  - Do not collect statistics about the connection process.
5030  - Do not add new charts to the atlas. We only generate temporary charts. */
5031  cost[i]=ConnectSamplesChart(pr,ar->tp,NULL,&(ar->ambient),
5032  ar->m,ar->m-ar->k,ar->si[n[i]]->s,q_new,gamma,
5033  TRUE,&(ar->J),&(reachedQRand[i]),&collision,NULL,NULL,NULL,ar->w);;
5034  }
5035  else
5036  {
5037  #if (NEW_BRANCH_EXTENSION)
5038  configExtend.maxLength=gamma;
5039  cost[i]=New_AddBranchToAtlasRRT(pr,NO_UINT,&configExtend,n[i],q_new,NULL,
5040  (void*)arst,&(statusExtend[i]),NULL,NULL,ar);
5041  reachedQRand[i]=statusExtend[i].reachedQrand;
5042  #else
5043  boolean reachedGoal;
5044  unsigned int lastID;
5045 
5047  gamma,n[i],q_new,NULL,
5048  (void*)arst,&lastID,&(reachedQRand[i]),&reachedGoal,NULL,NULL,
5049  NULL,NULL,ar);
5050  #endif
5051  }
5052  }
5053  }
5054  }
5055 
5056  for(i=0;i<nn;i++)
5057  {
5058  if (n[i]!=id_new)
5059  {
5060  #if (GET_ATLASRRT_STATISTICS)
5061  NewAtlasRRTBranch(arst);
5062  #endif
5063  (*t)|=GetRRTNodeTree(n[i],&(ar->rrt)); /* take note of the tree of this neighbour (even if not reached)*/
5064  }
5065 
5066  if (reachedQRand[i])
5067  {
5068  cn=cost[i];
5069 
5070  #if (GET_ATLASRRT_STATISTICS)
5072  #endif
5073 
5074  /* update the cost of the reached neighbour */
5075  #if (!RRTSTAR_UPDATE_COSTS)
5076  if (rrtMode==TWO_TREES_WITH_SWAP)
5077  #endif
5078  UpdateCostAndTree(n[i],&(ar->rrt));
5079 
5080  /* There is an edge connecting id_new and n[i] */
5081  if (graph)
5082  AddEdgeToRRT(id_new,n[i],cn,&(ar->rrt));
5083 
5084  c_new=GetRRTNodeCost(n[i],&(ar->rrt))+cn;
5085  if (c_new<(GetRRTNodeCost(id_new,&(ar->rrt))-epsilon))
5086  {
5087  #if (ATLASRRT_VERBOSE)
5088  fprintf(stderr," {%u->%u}[%g %g] ->",id_new,GetRRTParent(id_new,&(ar->rrt)),
5089  GetRRTNodeCostFromParent(id_new,&(ar->rrt)),
5090  GetRRTNodeCost(id_new,&(ar->rrt)));
5091  #endif
5092 
5093  SetRRTCostAndParent(id_new,n[i],cn,c_new,&(ar->rrt));
5094 
5095  #if (ATLASRRT_VERBOSE)
5096  fprintf(stderr,"{%u->%u}[%g %g]\n",id_new,GetRRTParent(id_new,&(ar->rrt)),
5097  GetRRTNodeCostFromParent(id_new,&(ar->rrt)),
5098  GetRRTNodeCost(id_new,&(ar->rrt)));
5099  #endif
5100  }
5101  }
5102  else
5103  cn=INF;
5104 
5105  #if (RRTSTAR_SYMMETRIC_COST)
5106  if (!graph)
5107  (*c)[i]=cn;
5108  #endif
5109  }
5110 
5111  free(cost);
5112  free(reachedQRand);
5113  #if (NEW_BRANCH_EXTENSION)
5114  free(statusExtend);
5115  #endif
5116 
5117  if (graph)
5118  {
5119  if (!q)
5120  Error("RRT must be in graph mode to use a heap");
5121  c_new=GetRRTNodeCost(id_new,&(ar->rrt));
5122  NewDoublePair(c_new+h,c_new,&pair);
5123  AddElement2Heap(id_new,(void *)&pair,q);
5124  }
5125 }
5126 
5128  unsigned int id_new,double gamma,
5129  unsigned int nn,unsigned int *n,double *c,
5130  Tvector *steps,double *l,
5131  TAtlasRRTStatistics *arst,Tatlasrrt *ar)
5132 {
5133 
5134  unsigned int i,parent;
5135  double cn,epsilon,c_new;
5136  unsigned int rrtMode;
5137  boolean reachedQRand;
5138  #if (!RRTSTAR_SYMMETRIC_COST)
5139  #if (NEW_BRANCH_EXTENSION)
5140  TAtlasRRTBranchConfig configExtend;
5141  TAtlasRRTBranchStatus statusExtend;
5142 
5143  InitBranchConfig(CONNECT_SAMPLES,&configExtend);
5144  #else
5145  unsigned int lastID;
5146  boolean reachedGoal;
5147  #endif
5148  #endif
5149 
5150  epsilon=GetParameter(CT_EPSILON,pr);
5151 
5152  #if (ATLASRRT_VERBOSE)
5153  fprintf(stderr," Rewire\n");
5154  #endif
5155  rrtMode=GetRRTMode(&(ar->rrt));
5156  /* best parent for the new node */
5157  parent=GetRRTParent(id_new,&(ar->rrt));
5158  for(i=0;i<nn;i++)
5159  {
5160  if ((n[i]==id_new)||(n[i]==parent))
5161  reachedQRand=FALSE;
5162  else
5163  {
5164  #if (RRTSTAR_SYMMETRIC_COST)
5165  cn=c[i];
5166  reachedQRand=(cn<INF);
5167  #else
5168  /* cost to go from id_new to n[i] */
5169  /* the branch is virtual-> nothing is added to the RRT */
5170  #if (NEW_BRANCH_EXTENSION)
5171  configExtend.maxLength=gamma;
5172  cn=New_AddBranchToAtlasRRT(pr,NO_UINT,&configExtend,id_new,ar->si[n[i]]->s,NULL,
5173  (void*)arst,&statusExtend,NULL,NULL,ar);
5174  reachedQRand=statusExtend.reachedQrand;
5175  #else
5177  gamma,id_new,ar->si[n[i]]->s,NULL,
5178  (void*)arst,&lastID,&reachedQRand,&reachedGoal,NULL,NULL,NULL,NULL,ar);
5179  #endif
5180  #endif
5181  }
5182 
5183  if (reachedQRand)
5184  {
5185  /* Ensure that any previous-rewire is propagated to the currently tested node */
5186  if (rrtMode==TWO_TREES_WITH_SWAP)
5187  UpdateCostAndTree(n[i],&(ar->rrt));
5188 
5189  c_new=GetRRTNodeCost(id_new,&(ar->rrt))+cn;
5190  if (c_new<(GetRRTNodeCost(n[i],&(ar->rrt))-epsilon))
5191  {
5192  #if (ATLASRRT_VERBOSE)
5193  fprintf(stderr," {%u->%u}[%g] ->",n[i],GetRRTParent(n[i],&(ar->rrt)),
5194  GetRRTNodeCostFromParent(n[i],&(ar->rrt)));
5195  #endif
5196 
5197  SetRRTCostAndParent(n[i],id_new,cn,c_new,&(ar->rrt));
5198 
5199  #if (ATLASRRT_VERBOSE)
5200  fprintf(stderr,"{%u->%u}[%g]\n",n[i],GetRRTParent(n[i],&(ar->rrt)),
5201  GetRRTNodeCostFromParent(n[i],&(ar->rrt)));
5202  #endif
5203  }
5204  else
5205  {
5206  /* if the node is connected to a sample in a different tree, update the optimal path */
5207  if ((rrtMode==TWO_TREES_WITH_SWAP)&&(steps!=NULL)&&(l!=NULL)&&
5208  (GetRRTNodeTree(n[i],&(ar->rrt))!=GetRRTNodeTree(id_new,&(ar->rrt))))
5209  {
5210  c_new+=GetRRTNodeCost(n[i],&(ar->rrt)); /* cost of start to goal via this connection
5211  between trees.*/
5212  if (c_new<*l)
5213  *l=ChangeBiRRTSteps(n[i],id_new,cn,steps,&(ar->rrt));
5214  }
5215  }
5216  }
5217  }
5218 }
5219 
5220 void AtlasRRTstarCloseIteration(unsigned int it,unsigned int id_goal,
5221  double time,double gamma,
5222  double *times,double *costs,
5223  Tatlasrrt *ar)
5224 {
5225  /* Print information about the quality of the path so far */
5226 
5227  if ((ATLASRRT_VERBOSE)||((it%1000)==0))
5228  {
5229  if (id_goal!=NO_UINT)
5230  {
5231  fprintf(stderr,"Iteration: %u (s:%u nc:%u t:%g g:%g c:%g [%g] [%u])\n",it,ar->ns,ar->nc,
5232  time,gamma,GetRRTNodeCost(id_goal,&(ar->rrt)),CostToRoot(id_goal,&(ar->rrt)),id_goal);
5233  }
5234  else
5235  fprintf(stderr,"Iteration: %u (s:%u t:%g)\n",it,ar->ns,time);
5236  fflush(stdout);
5237  }
5238 
5239  /*******************************************************************/
5240  /* Store information about the quality of the path so far and
5241  conclude the iteration */
5242 
5243  if (times!=NULL)
5244  times[it]=time;
5245 
5246  if (costs!=NULL)
5247  {
5248  if (id_goal==NO_UINT)
5249  costs[it]=-1.0;
5250  else
5251  costs[it]=GetRRTNodeCost(id_goal,&(ar->rrt)); //CostToRoot(id_goal,&(ar->rrt));
5252  }
5253 }
5254 
5255 void AtlasBiRRTstarCloseIteration(unsigned int it,double l,
5256  double time,double gamma,
5257  double *times,double *costs,
5258  Tatlasrrt *ar)
5259 {
5260  if ((ATLASRRT_VERBOSE)||((it%1000)==0))
5261  {
5262  if (l<INF)
5263  {
5264  fprintf(stderr,"Iteration: %u (s:%u nc: %u t:%g g:%g c:%g)\n",it,ar->ns,ar->nc,
5265  time,gamma,l);
5266  }
5267  else
5268  fprintf(stderr,"Iteration: %u (s:%u t:%g)\n",it,ar->ns,time);
5269  fflush(stdout);
5270  }
5271 
5272  if (times!=NULL)
5273  times[it]=time;
5274 
5275  if (costs!=NULL)
5276  {
5277  if (l<INF)
5278  costs[it]=l;
5279  else
5280  costs[it]=-1.0;
5281  }
5282 }
5283 
5284 
5285 boolean AtlasRRTstar(Tparameters *pr,double *pg,
5286  unsigned int *it,double *times,double *costs,
5287  double *planningTime,double *pl,unsigned int *ns,double ***path,
5288  TAtlasRRTStatistics *str,Tatlasrrt *ar)
5289 {
5290  if (EXPLORATION_RRT)
5291  Error("AtlasRRTstart is not designed for exploration RRTs");
5292 
5293  if (ar->birrt)
5294  return(AtlasBiRRTstar(pr,pg,it,times,costs,planningTime,pl,ns,path,str,ar));
5295  else
5296  {
5297  double *pWithDummies,*pgs,*t_rand,*q_rand,*q_new;
5298  unsigned int i,id_new,id_goal,c_rand,samplingMode;
5299  unsigned int i_near;
5300  double time,epsilon,delta,er,gamma,ct_gamma;
5301  Tstatistics st; /* used just to measure execution time */
5302  boolean collision,expand2Goal,done,optimal,validSample,exploration;
5303  /* cost of paths to neighbouring nodes */
5304  double *c;
5305  /* neighbours for each new node */
5306  unsigned int nn;
5307  unsigned int *n;
5308  TAtlasRRTStatistics *arst;
5309  double maxTime;
5310  unsigned int maxIterations;
5311  double h,l;
5312  Theap q;
5313  boolean graph;
5314  unsigned int vt; /* trees in set of neighbours, only relevant in bi-RRTs */
5315  double numSamples;
5316  double scale; /* Global adjustment of sampling areas */
5317 
5318  if (ar->ns>1)
5319  Error("AtlasRRTstart must be used to a just initilized RRT");
5320 
5321  #if (GET_ATLASRRT_STATISTICS)
5322  {
5323  unsigned int i;
5324 
5325  NEW(arst,1,TAtlasRRTStatistics);
5326  InitAtlasRRTStatistics(arst);
5327  for(i=0;i<ar->nc;i++)
5328  NewAtlasRRTChart(arst);
5329  for(i=0;i<ar->ns;i++)
5330  NewAtlasRRTSample(arst);
5331  }
5332  #else
5333  arst=NULL;
5334  #endif
5335 
5336  scale=1.0; /* not used yet */
5337 
5338  /* Init the AtlasRRT structure */
5339  epsilon=GetParameter(CT_EPSILON,pr);
5340  delta=GetParameter(CT_DELTA,pr);
5341  ct_gamma=GetParameter(CT_GAMMA,pr);
5342  maxTime=GetParameter(CT_MAX_PLANNING_TIME,pr);
5343  maxIterations=(unsigned int)GetParameter(CT_MAX_PLANNING_ITERATIONS,pr);
5344  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
5345 
5346  graph=IsRRTGraph(&(ar->rrt));
5347 
5348  CS_WD_REGENERATE_SOLUTION_POINT(pr,pg,&pWithDummies,ar->w);
5349  CS_WD_GENERATE_SIMPLIFIED_POINT(pr,pWithDummies,&pgs,ar->w);
5350 
5351  if ((!PointInBoxTopology(NULL,TRUE,ar->m,pgs,epsilon,ar->tp,&(ar->ambient)))||
5352  (!CS_WD_SIMP_INEQUALITIES_HOLD(pr,pgs,ar->w)))
5353  Error("The targed point for the AtlasRRTstar is not in domain");
5354 
5355  if (ar->m==ar->k)
5356  er=0;
5357  else
5358  er=CS_WD_ERROR_IN_SIMP_EQUATIONS(pr,pgs,ar->w);
5359  if (er>epsilon)
5360  Error("The target point for the AtlasRRTstar is not on the manifold");
5361 
5362  collision=CS_WD_ORIGINAL_IN_COLLISION(pr,pWithDummies,NULL,ar->w);
5363  if (collision)
5364  Error("The target point for the AtlasRRTstar is in collision");
5365  free(pWithDummies);
5366 
5367  /* Room for the randomly generated samples (and its correspoinding point
5368  on the manifold) */
5369  NEW(q_rand,ar->m,double);
5370  NEW(t_rand,ar->k,double);
5371 
5372  /* Reset the output statistics (just in case maxIterations
5373  is not reached) */
5374  for(i=0;i<maxIterations;i++)
5375  {
5376  times[i]=0;
5377  costs[i]=-1;
5378  }
5379 
5380  if (graph)
5381  InitHeap(sizeof(TDoublePair),CopyDoublePair,NULL,
5382  LessThanDoublePair,NULL,TRUE,ar->ms,&q);
5383 
5384  gamma=ct_gamma;
5385  optimal=(ct_gamma>0);
5386 
5387  id_goal=NO_UINT;
5388  *it=0;
5389 
5390  InitStatistics((ar->parallel?2:1),0,&st); /* 2 just to indicated multi-core process */
5391  time=0.0;
5392  done=FALSE;
5393  l=INF; /* cost to goal (INF while goal not found) */
5394  c=NULL; /* default -> no cache of costs to neighbours */
5395 
5396  while ((!done)&&(time<maxTime)&&(*it<maxIterations))
5397  {
5398  #if (HEURISTIC_RRT_STAR&(1))
5399  /* keep the cost to goal up to date so that the heuristic
5400  is more effective*/
5401  if (id_goal!=NO_UINT)
5402  UpdateCostAndTree(id_goal,&(ar->rrt));
5403  #endif
5404 
5405  /*******************************************************************/
5406  /* best estimation of the cost to goal (up to now) */
5407  if (id_goal==NO_UINT)
5408  l=INF;
5409  else
5410  l=GetRRTNodeCost(id_goal,&(ar->rrt));
5411 
5412  /*******************************************************************/
5413  /* Generate a random sample */
5414  do {
5415  /* Generate the sample */
5416  expand2Goal=AtlasRRTSample(pr,samplingMode,*it,START2GOAL,(id_goal==NO_UINT?pgs:NULL),
5417  scale,&exploration,&c_rand,t_rand,q_rand,arst,ar);
5418 
5419 
5420  /* validate the random sample */
5421  validSample=AtlasRRTValidateSample(pr,q_rand,START2GOAL,expand2Goal,NO_UINT,
5422  pgs,l,&h,&i_near,arst,ar);
5423  } while (!validSample);
5424 
5425  /*******************************************************************/
5426  /* Extend the AtlasRRT from q_near to q_rand */
5427  /* Note that here we use a connect strategy but we only add the last sample */
5428  id_new=AddStepToAtlasRRTstar(pr,*it,expand2Goal,i_near,q_rand,
5429  &id_goal,pgs,(void*)arst,ar);
5430 
5431  /*******************************************************************/
5432  if (!optimal)
5433  {
5434  if (id_goal!=NO_UINT)
5435  done=TRUE;
5436  }
5437  else
5438  {
5439  /* If we actually added something */
5440  if ((id_new!=i_near)&&((((HEURISTIC_RRT_STAR)&(2))==0)||(id_goal!=NO_UINT)))
5441  {
5442  /* q_new is the last samples added to the tree */
5443  q_new=ar->si[id_new]->s;
5444  h=DistanceTopology(ar->m,ar->tp,q_new,pgs);
5445 
5446  /* Wire and re-wire the tree, only we we are interested in an optimal path
5447  If heristic #4 is active optimization is delayed until the goal is found */
5448 
5449  /*******************************************************************/
5450  /* Search for the set of potential neighbours */
5451  numSamples=(double)(ar->ns<3?3:ar->ns);
5452  gamma=ct_gamma*pow(log(numSamples)/numSamples,1.0/(double)ar->k);
5453  gamma=(gamma<delta?delta:gamma);
5454 
5455  GetRRTNNInBall(START2GOAL,q_new,gamma,&nn,&n,&(ar->rrt));
5456 
5457  /*******************************************************************/
5458  /* Wire: Search for the lowest cost path to the new node */
5459  WireAtlasRRTstar(pr,id_new,i_near,gamma,nn,n,&c,h,(graph?&q:NULL),&vt,arst,ar);
5460 
5461  /*******************************************************************/
5462  /* Rewire the tree around the new point */
5463  if (graph)
5464  RecursiveReWireRRTstar(pr,&q,pgs,NULL,&l,&(ar->rrt));
5465  else
5466  ReWireAtlasRRTstar(pr,id_new,gamma,nn,n,c,NULL,&l,arst,ar);
5467 
5468  /*******************************************************************/
5469  /* release the data for this iteration */
5470  if (c!=NULL)
5471  free(c);
5472  free(n);
5473  }
5474  #if (ATLASRRT_VERBOSE)
5475  else
5476  {
5477  if (id_new==i_near)
5478  fprintf(stderr," Blocked [%u]\n",i_near);
5479  }
5480  #endif
5481  }
5482 
5483  /*******************************************************************/
5484  /* Print a summary about this iteration */
5485  time=GetElapsedTime(&st);
5486 
5487  AtlasRRTstarCloseIteration(*it,id_goal,time,gamma,times,costs,ar);
5488 
5489  (*it)++;
5490  }
5491 
5492  if (graph)
5493  DeleteHeap(&q);
5494 
5495  *planningTime=time;
5496 
5497  DeleteStatistics(&st);
5498 
5499  fprintf(stderr,"Final number of samples: %u\n",ar->ns);
5500 
5501  /* Reconstruct the path (if any) */
5502  if (id_goal!=NO_UINT)
5503  ReconstructAtlasRRTPath(pr,id_goal,pl,ns,path,ar);
5504 
5505  /* Release memory */
5506  free(t_rand);
5507  free(q_rand);
5508  free(pgs);
5509 
5510  #if (GET_ATLASRRT_STATISTICS)
5511  if (str==NULL)
5512  PrintAtlasRRTStatistics(ar,arst);
5513  else
5514  AccumulateAtlasRRTStatistics(arst,str);
5516  free(arst);
5517  #endif
5518 
5519  return(id_goal!=NO_UINT);
5520  }
5521 }
5522 
5523 boolean AtlasBiRRTstar(Tparameters *pr,double *pg,
5524  unsigned int *it,double *times,double *costs,
5525  double *planningTime,double *pl,unsigned int *ns,double ***path,
5526  TAtlasRRTStatistics *str,Tatlasrrt *ar)
5527 {
5528 
5529  if (EXPLORATION_RRT)
5530  Error("AtlasBiRRTstart is not designed for exploration RRTs");
5531 
5532  if (!ar->birrt)
5533  return(AtlasRRTstar(pr,pg,it,times,costs,planningTime,pl,ns,path,str,ar));
5534  else
5535  {
5536  double *q_rand,*t_rand,*g;
5537  unsigned int c_rand;
5538  unsigned int i_near;
5539  double delta;
5540  Tstatistics st; /* used just to measure execution time */
5541  double time;
5542  /* if the cost function is symmetrical, we cache
5543  the evaluation of the cost to neighbour. */
5544  double *c;
5545  /* neighbours for each new node */
5546  unsigned int nn;
5547  unsigned int *n;
5548  /* distance q_rand,tree */
5549  double gamma,ct_gamma;
5550  unsigned int i,id_new,samplingMode;
5551  double *q_new;
5552  boolean done,optimal,validSample,exploration;
5553  double l; /* length of the shortest path so far */
5554  double h;
5555  Theap q;
5556  Tvector steps;
5557  TAtlasRRTStatistics *arst;
5558  double maxTime;
5559  unsigned int maxIterations;
5560  boolean graph;
5561  unsigned int vt;
5562  double l1,c12;
5563  double numSamples;
5564  double scale; /* Global adjust of sampling areas */
5565  #if (NEW_BRANCH_EXTENSION)
5566  TAtlasRRTBranchConfig configExtend;
5567  TAtlasRRTBranchStatus statusExtend;
5568 
5569  InitBranchConfig(CONNECT_SAMPLES,&configExtend);
5570  #else
5571  boolean reachedQRand,reachedGoal;
5572  unsigned int lastID;
5573  #endif
5574 
5575  if (ar->ns>2)
5576  Error("AtlasBiRRTstart must be used to a just initilized RRT");
5577 
5578  #if (GET_ATLASRRT_STATISTICS)
5579  {
5580  unsigned int i;
5581 
5582  NEW(arst,1,TAtlasRRTStatistics);
5583  InitAtlasRRTStatistics(arst);
5584  for(i=0;i<ar->nc;i++)
5585  NewAtlasRRTChart(arst);
5586  for(i=0;i<ar->ns;i++)
5587  NewAtlasRRTSample(arst);
5588  }
5589  #else
5590  arst=NULL;
5591  #endif
5592 
5593  scale=1.0; /* not used yet */
5594 
5595  /* Init the RRT structure */
5596  delta=GetParameter(CT_DELTA,pr);
5597  ct_gamma=GetParameter(CT_GAMMA,pr);
5598  maxTime=GetParameter(CT_MAX_PLANNING_TIME,pr);
5599  maxIterations=(unsigned int)GetParameter(CT_MAX_PLANNING_ITERATIONS,pr);
5600  samplingMode=(unsigned int)GetParameter(CT_SAMPLING,pr);
5601 
5602  graph=IsRRTGraph(&(ar->rrt));
5603 
5604  /* Room for the randomly generated samples (and its correspoinding point
5605  on the manifold) */
5606  NEW(q_rand,ar->m,double);
5607  NEW(t_rand,ar->k,double);
5608 
5609  /* Reset the output statistics (just in case maxIterations
5610  is not reached) */
5611  for(i=0;i<maxIterations;i++)
5612  {
5613  times[i]=0;
5614  costs[i]=-1;
5615  }
5616 
5617  if (graph)
5618  InitHeap(sizeof(TDoublePair),CopyDoublePair,NULL,
5619  LessThanDoublePair,NULL,TRUE,ar->ms,&q);
5620 
5621  gamma=ct_gamma;
5622  optimal=(ct_gamma>0);
5623 
5624  *it=0;
5625 
5626  InitStatistics((ar->parallel?2:1),0,&st); /* if parallel 2 indicates multi-core */
5627  time=0.0;
5628  done=FALSE;
5629 
5630  InitVector(sizeof(TRRTStep),CopyRRTStep,NULL,100,&steps);
5631  l=INF;
5632  c=NULL;
5633 
5634  while ((!done)&&(time<maxTime)&&(*it<maxIterations))
5635  {
5636  /* keep the optimal path up to date (if any) */
5637  if (l<INF)
5638  l=UpdateBiRRTSteps(&steps,&(ar->rrt));
5639 
5640  /*******************************************************************/
5641  do {
5642  /* Geerate a random sample */
5643  AtlasRRTSample(pr,samplingMode,*it,BOTHTREES,NULL,scale,
5644  &exploration,&c_rand,t_rand,q_rand,arst,ar);
5645 
5646  /* validate the random sample */
5647  validSample=AtlasRRTValidateSample(pr,q_rand,BOTHTREES,FALSE,NO_UINT,
5648  ar->si[1]->s,l,&h,&i_near,arst,ar);
5649  } while (!validSample);
5650 
5651  /*******************************************************************/
5652  /* decide who is the goal (for the heuristic) */
5653  if (GetRRTNodeTree(i_near,&(ar->rrt))==START2GOAL)
5654  g=ar->si[1]->s;
5655  else
5656  g=ar->si[0]->s;
5657  h=DistanceTopology(ar->m,ar->tp,q_rand,g);
5658 
5659 
5660  /*******************************************************************/
5661  /* Extend the AtlasRRT from q_near to q_rand using the cbiRRT extend method */
5662  /* Note that here we use a extend strategy (we only add one sample) */
5663 
5664  id_new=AddStepToAtlasRRTstar(pr,*it,FALSE,i_near,q_rand,
5665  NULL,NULL,(void*)arst,ar);
5666 
5667  /* If we actually added something */
5668  if ((id_new!=i_near)&&((((HEURISTIC_RRT_STAR)&(2))==0)||(l<INF)))
5669  {
5670  /* q_new is the last samples added to the tree */
5671  q_new=ar->si[id_new]->s;
5672  h=DistanceTopology(ar->m,ar->tp,q_new,g);
5673 
5674  /*******************************************************************/
5675  /* Search for the set of potential neighbours */
5676  numSamples=(double)(ar->ns<3?3:ar->ns);
5677  gamma=ct_gamma*pow(log(numSamples)/numSamples,1.0/(double)ar->k);
5678  gamma=(gamma<delta?delta:gamma);
5679 
5680  GetRRTNNInBall(BOTHTREES,q_new,gamma,&nn,&n,&(ar->rrt));
5681 
5682  /*******************************************************************/
5683  /* Wire: Search for the lowest cost path to the new node */
5684  WireAtlasRRTstar(pr,id_new,i_near,gamma,nn,n,&c,h,(graph?&q:NULL),&vt,arst,ar);
5685 
5686  /*******************************************************************/
5687  /* Rewire the tree around the new point */
5688  if (graph)
5689  RecursiveReWireRRTstar(pr,&q,g,&steps,&l,&(ar->rrt));
5690  else
5691  ReWireAtlasRRTstar(pr,id_new,gamma,nn,n,c,&steps,&l,arst,ar);
5692 
5693  /*******************************************************************/
5694  /* release the data for this iteration (cost and neighbours) */
5695  if (c!=NULL)
5696  free(c);
5697  free(n);
5698 
5699  /*******************************************************************/
5700  /* If the set of neighbours does not include nodes in the two trees
5701  and we do not have a path start<->goal we try to connect the two
5702  trees (this is hardly used since when l=INF, gamma is large and
5703  the neighbours always include nodes in the two trees) */
5704  //if ((vt!=BOTHTREES)&&(l==INF))
5705  if (vt!=BOTHTREES)
5706  {
5707  /* In the re-wire the current sample might end up in tree 't2'
5708  and the connection must be always with the other tree */
5709  if (GetRRTNodeTree(id_new,&(ar->rrt))==START2GOAL)
5710  i_near=GetRRTNN(GOAL2START,q_new,&(ar->rrt));
5711  else
5712  i_near=GetRRTNN(START2GOAL,q_new,&(ar->rrt));
5713 
5714  l1=GetRRTNodeCost(id_new,&(ar->rrt))+GetRRTNodeCost(i_near,&(ar->rrt));
5715 
5716  #if (NEW_BRANCH_EXTENSION)
5717  configExtend.maxLength=(l<INF?l-l1:0.0);
5718  c12=New_AddBranchToAtlasRRT(pr,NO_UINT,&configExtend,id_new,ar->si[i_near]->s,NULL,
5719  (void*)arst,&statusExtend,NULL,NULL,ar);
5720 
5721  if (statusExtend.reachedQrand)
5722  #else
5724  (l<INF?l-l1:0.0),id_new,ar->si[i_near]->s,NULL,
5725  (void*)arst,&lastID,&reachedQRand,&reachedGoal,NULL,NULL,NULL,NULL,ar);
5726 
5727  if (reachedQRand)
5728  #endif
5729  {
5730  if (graph)
5731  AddEdgeToRRT(id_new,i_near,c12,&(ar->rrt));
5732  l1+=c12;
5733  if (l1<l)
5734  l=ChangeBiRRTSteps(id_new,i_near,c12,&steps,&(ar->rrt));
5735  }
5736  }
5737  }
5738  #if (ATLASRRT_VERBOSE)
5739  else
5740  {
5741  if (id_new==i_near)
5742  fprintf(stderr," Blocked [%u]\n",i_near);
5743  }
5744  #endif
5745 
5746  if (!optimal)
5747  done=(l<INF);
5748 
5749  /*******************************************************************/
5750  /* Conclude the iteration */
5751  time=GetElapsedTime(&st);
5752 
5753  AtlasBiRRTstarCloseIteration(*it,l,time,gamma,times,costs,ar);
5754 
5755  (*it)++;
5756  }
5757 
5758  if (graph)
5759  DeleteHeap(&q);
5760 
5761  *planningTime=GetElapsedTime(&st);
5762 
5763  DeleteStatistics(&st);
5764 
5765  fprintf(stderr,"Final number of samples: %u\n",ar->ns);
5766 
5767  /* Reconstruct the path (if any) */
5768  if (l<INF)
5769  Steps2PathinAtlasRRT(pr,&steps,pl,NULL,ns,path,ar);
5770 
5771  /* Release memory */
5772  free(q_rand);
5773  free(t_rand);
5774  DeleteVector(&steps);
5775 
5776  #if (GET_ATLASRRT_STATISTICS)
5777  if (str==NULL)
5778  PrintAtlasRRTStatistics(ar,arst);
5779  else
5780  AccumulateAtlasRRTStatistics(arst,str);
5782  free(arst);
5783  #endif
5784 
5785  return(l<INF);
5786  }
5787 }
5788 
5790 {
5791  return(ar->ns);
5792 }
5793 
5795 {
5796  return(ar->nc);
5797 }
5798 
5799 
5800 unsigned int GetRRTNNInNeighbourChart(unsigned int tree,
5801  unsigned int c_rand,double *t_rand,double *q_rand,
5802  Tatlasrrt *ar)
5803 {
5804  double d,d1;
5805  unsigned int inear,inear1;
5806  Tchart *chart;
5807  unsigned int i,nn,nID;
5808 
5809  inear=GetRRTNNInChart(tree,c_rand,q_rand,INF,&d,ar);
5810 
5811  chart=GetAtlasChart(c_rand,&(ar->atlas));
5812  nn=ChartNumNeighbours(chart);
5813  for(i=0;i<nn;i++)
5814  {
5815  nID=ChartNeighbourID(i,chart);
5816  if (nID!=NO_UINT)
5817  {
5818  //if ((!ar->birrt)||(ar->ci[nID]->tree&tree))
5819  {
5820  inear1=GetRRTNNInChart(tree,nID,q_rand,d,&d1,ar);
5821  if (d1<d)
5822  {
5823  d=d1;
5824  inear=inear1;
5825  }
5826  }
5827  }
5828  }
5829  return(inear);
5830 }
5831 
5832 unsigned int GetRRTNNInChart(unsigned int tree,
5833  unsigned int chartId,double *q_rand,
5834  double t,double *d,Tatlasrrt *ar)
5835 {
5836  double d1;
5837  unsigned int j,inear;
5838 
5839  *d=t;
5840  inear=NO_UINT;
5841  j=ar->ci[chartId]->lc;
5842  while(j!=NO_UINT)
5843  {
5844  if ((!ar->birrt)||(GetRRTNodeTree(j,&(ar->rrt))==tree))
5845  {
5846  d1=DistanceTopologyMin(*d,ar->m,ar->tp,q_rand,ar->si[j]->s);
5847  if (d1<*d)
5848  {
5849  *d=d1;
5850  inear=j;
5851  }
5852  }
5853  j=ar->si[j]->lsc;
5854  }
5855 
5856  return(inear);
5857 }
5858 
5859 void PlotAtlasRRT(char *prefix,int argc,char **arg,Tparameters *pr,
5860  unsigned int xID,unsigned int yID,unsigned int zID,Tatlasrrt *ar)
5861 {
5862  Tfilename fplot;
5863  unsigned int i;
5864  Tchart *chart1,*chart2;
5865  double *sample1,*sample2;
5866  unsigned int parent;
5867  double x[4],y[4],z[4];
5868  double *point1,*point2;
5869  double *o1,*o2,*o3,*o4;
5870  Tcolor color;
5871  Tplot3d p3d;
5872 
5873  CreateFileName(NULL,prefix,"_rrt",PLOT3D_EXT,&fplot);
5874  fprintf(stderr,"Plotting RRT to : %s\n",GetFileFullName(&fplot));
5875  PlotRRT(GetFileFullName(&fplot),argc,arg,pr,xID,yID,zID,&(ar->rrt));
5876  DeleteFileName(&fplot);
5877 
5878  if ((!PLOT_AS_POLYGONS)||(ar->k<4))
5879  {
5880  CreateFileName(NULL,prefix,"_atlas",PLOT3D_EXT,&fplot);
5881  fprintf(stderr,"Plotting Atlas to : %s\n",GetFileFullName(&fplot));
5882  PlotAtlas(GetFileFullName(&fplot),argc,arg,pr,NULL,xID,yID,zID,&(ar->atlas));
5883  DeleteFileName(&fplot);
5884  }
5885  else
5886  fprintf(stderr,"Skipping the plot of the atlas (too large dimension)\n");
5887 
5888  /* Now we plot the RRT in the tangent space and a line from tangent space to
5889  the RRT. This basically replicates the plot of the RRT but in the tangent
5890  space */
5891 
5892  CreateFileName(NULL,prefix,"_atlasrrt",PLOT3D_EXT,&fplot);
5893  fprintf(stderr,"Plotting AtlasRRT to : %s\n",GetFileFullName(&fplot));
5894 
5895  InitPlot3d(GetFileFullName(&fplot),FALSE,argc,arg,&p3d);
5896  DeleteFileName(&fplot);
5897 
5898  NEW(point1,ar->m,double);
5899  NEW(point2,ar->m,double);
5900 
5901  NewColor(0.5,0,0,&color); /*red*/
5902  StartNew3dObject(&color,&p3d);
5903 
5904  for(i=(ar->birrt?2:1);i<ar->ns;i++)
5905  {
5906  if ((!ar->birrt)||(GetRRTNodeTree(i,&(ar->rrt))==START2GOAL))
5907  {
5908  parent=GetRRTParent(i,&(ar->rrt));
5909 
5910  chart1=GetAtlasChart(ar->si[i]->c,&(ar->atlas));
5911  chart2=GetAtlasChart(ar->si[parent]->c,&(ar->atlas));
5912 
5913  if (chart1==chart2)
5914  {
5915  sample1=ar->si[i]->s;
5916  sample2=ar->si[parent]->s;
5917 
5918  CS_WD_REGENERATE_ORIGINAL_POINT(pr,sample1,&o1,ar->w);
5919  CS_WD_REGENERATE_ORIGINAL_POINT(pr,sample2,&o2,ar->w);
5920 
5921  Local2Global(ar->si[i]->t,NULL,point1,chart1);
5922  Local2Global(ar->si[parent]->t,NULL,point2,chart2);
5923 
5924  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point1,&o3,ar->w);
5925  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point2,&o4,ar->w);
5926 
5927  x[0]=o1[xID];
5928  y[0]=o1[yID];
5929  z[0]=o1[zID];
5930 
5931  x[1]=o3[xID];
5932  y[1]=o3[yID];
5933  z[1]=o3[zID];
5934 
5935  x[2]=o4[xID];
5936  y[2]=o4[yID];
5937  z[2]=o4[zID];
5938 
5939  x[3]=o2[xID];
5940  y[3]=o2[yID];
5941  z[3]=o2[zID];
5942 
5943  PlotVect3d(4,x,y,z,&p3d);
5944 
5945  free(o1);
5946  free(o2);
5947  free(o3);
5948  free(o4);
5949  }
5950  }
5951  }
5952  DeleteColor(&color);
5953  Close3dObject(&p3d);
5954 
5955  if (ar->birrt)
5956  {
5957  NewColor(0,0.5,0,&color); /*green*/
5958  StartNew3dObject(&color,&p3d);
5959 
5960  for(i=2;i<ar->ns;i++)
5961  {
5962  if (GetRRTNodeTree(i,&(ar->rrt))==GOAL2START)
5963  {
5964  parent=GetRRTParent(i,&(ar->rrt));
5965 
5966  chart1=GetAtlasChart(ar->si[i]->c,&(ar->atlas));
5967  chart2=GetAtlasChart(ar->si[parent]->c,&(ar->atlas));
5968 
5969  if (chart1==chart2)
5970  {
5971  sample1=ar->si[i]->s;
5972  sample2=ar->si[parent]->s;
5973 
5974  CS_WD_REGENERATE_ORIGINAL_POINT(pr,sample1,&o1,ar->w);
5975  CS_WD_REGENERATE_ORIGINAL_POINT(pr,sample2,&o2,ar->w);
5976 
5977  Local2Global(ar->si[i]->t,NULL,point1,chart1);
5978  Local2Global(ar->si[parent]->t,NULL,point2,chart2);
5979 
5980  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point1,&o3,ar->w);
5981  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point2,&o4,ar->w);
5982 
5983  x[0]=o1[xID];
5984  y[0]=o1[yID];
5985  z[0]=o1[zID];
5986 
5987  x[1]=o3[xID];
5988  y[1]=o3[yID];
5989  z[1]=o3[zID];
5990 
5991  x[2]=o4[xID];
5992  y[2]=o4[yID];
5993  z[2]=o4[zID];
5994 
5995  x[3]=o2[xID];
5996  y[3]=o2[yID];
5997  z[3]=o2[zID];
5998 
5999  PlotVect3d(4,x,y,z,&p3d);
6000 
6001  free(o1);
6002  free(o2);
6003  free(o3);
6004  free(o4);
6005  }
6006  }
6007  }
6008  DeleteColor(&color);
6009  Close3dObject(&p3d);
6010  }
6011 
6012  #if (RRT_PLOT_NODES)
6013  /* Dots, one per node */
6014  NewColor(0,0,0,&color); /*black*/
6015  StartNew3dObject(&color,&p3d);
6016 
6017  for(i=0;i<ar->ns;i++)
6018  {
6019  chart1=GetAtlasChart(ar->si[i]->c,&(ar->atlas));
6020  Local2Global(ar->si[i]->t,NULL,point1,chart1);
6021  CS_WD_REGENERATE_ORIGINAL_POINT(pr,point1,&o1,ar->w);
6022 
6023  x[0]=o1[xID]-0.005;
6024  y[0]=o1[yID];
6025  z[0]=o1[zID];
6026 
6027  x[1]=o1[xID]+0.005;
6028  y[1]=o1[yID];
6029  z[1]=o1[zID];
6030 
6031  PlotVect3d(2,x,y,z,&p3d);
6032 
6033  x[0]=o1[xID];
6034  y[0]=o1[yID]-0.005;
6035  z[0]=o1[zID];
6036 
6037  x[1]=o1[xID];
6038  y[1]=o1[yID]+0.005;
6039  z[1]=o1[zID];
6040 
6041  PlotVect3d(2,x,y,z,&p3d);
6042 
6043  x[0]=o1[xID];
6044  y[0]=o1[yID];
6045  z[0]=o1[zID]-0.005;
6046 
6047  x[1]=o1[xID];
6048  y[1]=o1[yID];
6049  z[1]=o1[zID]+0.005;
6050 
6051  PlotVect3d(2,x,y,z,&p3d);
6052 
6053  free(o1);
6054  }
6055 
6056  DeleteColor(&color);
6057  Close3dObject(&p3d);
6058  #endif
6059 
6060  ClosePlot3d(FALSE,0,0,0,&p3d);
6061 
6062  free(point1);
6063  free(point2);
6064 }
6065 
6066 unsigned int AtlasRRTMemSize(Tatlasrrt *ar)
6067 {
6068  unsigned int b;
6069 
6070  b=RRTMemSize(&(ar->rrt));
6071  b+=AtlasMemSize(&(ar->atlas));
6072 
6073  return(b);
6074 }
6075 
6076 void SaveAtlasRRT(Tparameters *pr,char *prefix,Tatlasrrt *ar)
6077 {
6078  Tfilename fsave;
6079  FILE *f;
6080  unsigned int i;
6081 
6082  CreateFileName(NULL,prefix,NULL,RRT_EXT,&fsave);
6083  fprintf(stderr,"Writing RRT to : %s\n",GetFileFullName(&fsave));
6084  SaveRRT(&fsave,&(ar->rrt));
6085  DeleteFileName(&fsave);
6086 
6087  CreateFileName(NULL,prefix,NULL,ATLAS_EXT,&fsave);
6088  fprintf(stderr,"Writing atlas to : %s\n",GetFileFullName(&fsave));
6089  SaveAtlas(pr,&fsave,&(ar->atlas));
6090  DeleteFileName(&fsave);
6091 
6092  CreateFileName(NULL,prefix,NULL,ATLAS_RRT_EXT,&fsave);
6093  fprintf(stderr,"Writing AtlasRRT to : %s\n",GetFileFullName(&fsave));
6094  f=fopen(GetFileFullName(&fsave),"w");
6095  if (!f)
6096  Error("Could not open file to write the AtlasRRT information");
6097  DeleteFileName(&fsave);
6098 
6099  fprintf(f,"%u\n",ar->m);
6100  fprintf(f,"%u\n",ar->k);
6101  fprintf(f,"%.12f\n",ar->e);
6102  fprintf(f,"%.12f\n",ar->ce);
6103  fprintf(f,"%.12f\n",ar->r);
6104  fprintf(f,"%u\n",ar->birrt);
6105 
6106  fprintf(f,"%u\n",ar->ms);
6107  fprintf(f,"%u\n",ar->ns);
6108  for(i=0;i<ar->ns;i++)
6109  SaveAtlasRRTSampleInfo(f,ar->si[i],ar);
6110 
6111  fprintf(f,"%u\n",ar->mc);
6112  fprintf(f,"%u\n",ar->nc);
6113  for(i=0;i<ar->nc;i++)
6114  SaveAtlasRRTChartInfo(f,ar->ci[i],ar);
6115 
6116  if (ar->birrt)
6117  {
6118  fprintf(f,"%u\n",ar->mct1);
6119  fprintf(f,"%u\n",ar->nct1);
6120  for(i=0;i<ar->nct1;i++)
6121  fprintf(f,"%u ",ar->chartsAtTree1[i]);
6122  fprintf(f,"\n");
6123 
6124  fprintf(f,"%u\n",ar->mct2);
6125  fprintf(f,"%u\n",ar->nct2);
6126  for(i=0;i<ar->nct2;i++)
6127  fprintf(f,"%u ",ar->chartsAtTree2[i]);
6128  fprintf(f,"\n");
6129  }
6130  fclose(f);
6131 }
6132 
6133 void LoadAtlasRRT(Tparameters *pr,char *prefix,TAtlasBase *w,Tatlasrrt *ar)
6134 {
6135  Tfilename fload;
6136  FILE *f;
6137  unsigned int i;
6138 
6139  CreateFileName(NULL,prefix,NULL,RRT_EXT,&fload);
6140  fprintf(stderr,"Reading RRT from : %s\n",GetFileFullName(&fload));
6141  LoadRRT(pr,&fload,w,&(ar->rrt));
6142  DeleteFileName(&fload);
6143 
6144  CreateFileName(NULL,prefix,NULL,ATLAS_EXT,&fload);
6145  fprintf(stderr,"Reading atlas from : %s\n",GetFileFullName(&fload));
6146  LoadAtlas(pr,&fload,w,&(ar->atlas));
6147  DeleteFileName(&fload);
6148 
6149  CreateFileName(NULL,prefix,NULL,ATLAS_RRT_EXT,&fload);
6150  fprintf(stderr,"Reading AtlasRRT from : %s\n",GetFileFullName(&fload));
6151  f=fopen(GetFileFullName(&fload),"r");
6152  if (!f)
6153  Error("Could not open file to load the AtlasRRT information");
6154  DeleteFileName(&fload);
6155 
6156  ar->w=w;
6157 
6158  fscanf(f,"%u",&(ar->m));
6159  fscanf(f,"%u",&(ar->k));
6160  fscanf(f,"%lf",&(ar->e));
6161  fscanf(f,"%lf",&(ar->ce));
6162  fscanf(f,"%lf",&(ar->r));
6163  fscanf(f,"%u",&(ar->birrt));
6164  ar->parallel=FALSE; /* AtlasRRts loaded from files are not processed in parallel */
6165 
6166  fscanf(f,"%u",&(ar->ms));
6167  fscanf(f,"%u",&(ar->ns));
6168  NEW(ar->si,ar->ms,TSampleInfo *);
6169  for(i=0;i<ar->ns;i++)
6170  {
6171  NEW(ar->si[i],1,TSampleInfo);
6172  LoadAtlasRRTSampleInfo(f,ar->si[i],ar);
6173  }
6174 
6175  fscanf(f,"%u",&(ar->mc));
6176  fscanf(f,"%u",&(ar->nc));
6177  NEW(ar->ci,ar->mc,TChartInfo *);
6178  for(i=0;i<ar->nc;i++)
6179  {
6180  NEW(ar->ci[i],1,TChartInfo);
6181  LoadAtlasRRTChartInfo(f,ar->ci[i],ar);
6182  }
6183 
6184  if (ar->birrt)
6185  {
6186  fscanf(f,"%u",&(ar->mct1));
6187  fscanf(f,"%u",&(ar->nct1));
6188  NEW(ar->chartsAtTree1,ar->mct1,unsigned int);
6189  for(i=0;i<ar->nct1;i++)
6190  fscanf(f,"%u",&(ar->chartsAtTree1[i]));
6191 
6192  fscanf(f,"%u",&(ar->mct2));
6193  fscanf(f,"%u",&(ar->nct2));
6194  NEW(ar->chartsAtTree2,ar->mct2,unsigned int);
6195  for(i=0;i<ar->nct2;i++)
6196  fscanf(f,"%u",&(ar->chartsAtTree2[i]));
6197  }
6198  fclose(f);
6199 
6200 
6201  CS_WD_GENERATE_SIMP_INITIAL_BOX(pr,&(ar->ambient),ar->w);
6202  ar->tp=GetRRTTopology(&(ar->rrt));
6203  CS_WD_GET_SIMP_JACOBIAN(pr,&(ar->J),ar->w);
6204 }
6205 
6207 {
6208  unsigned int i;
6209 
6210  DeleteBox(&(ar->ambient));
6211 
6212  DeleteAtlas(&(ar->atlas));
6213  DeleteRRT(&(ar->rrt));
6214 
6215  /* Release sample info */
6216  for(i=0;i<ar->ns;i++)
6217  {
6218  free(ar->si[i]->t);
6219  free(ar->si[i]);
6220  /* The sample info is a pointer to an array
6221  stored in the RRT -> no need to free here */
6222  }
6223  free(ar->si);
6224 
6225  /* Release chart info */
6226  for(i=0;i<ar->nc;i++)
6227  free(ar->ci[i]);
6228 
6229  free(ar->ci);
6230 
6231  /* Release the assignment of charts to trees */
6232  if (ar->birrt)
6233  {
6234  free(ar->chartsAtTree1);
6235  free(ar->chartsAtTree2);
6236  }
6237 
6238  DeleteJacobian(&(ar->J));
6239 }
6240 
#define CT_R
Ball radius in atlas.
Definition: parameters.h:257
Definition of the boolean type.
void NewAtlasRRTNoConnectToParent(TAtlasRRTStatistics *arst)
A chart that does not intersect with its parent.
Definition: atlasrrt.c:695
unsigned int nStepReduction
Definition: atlasrrt.h:139
boolean IsRRTGraph(Trrt *rrt)
Identifies RRT with a graph structure.
Definition: rrt.c:1465
unsigned int GetRRTParent(unsigned int i, Trrt *rrt)
Returns identifier of the parent of one of the nodes of the RRT.
Definition: rrt.c:3552
void AdjustDynamicDomain(unsigned int i, boolean collision, Trrt *rrt)
Sets the dynamic domain.
Definition: rrt.c:3481
void PlotVect3d(unsigned int n, double *x, double *y, double *z, Tplot3d *p)
Adds a polyline to the current object.
Definition: plot3d.c:447
unsigned int k
Definition: atlasrrt.h:207
Tvector traversedCharts
Definition: atlasrrt.c:151
void DeleteVector(void *vector)
Destructor.
Definition: vector.c:389
#define TANGENT_SAMPLING
One of the possible sampling modes.
Definition: parameters.h:174
void LoadAtlas(Tparameters *pr, Tfilename *fname, TAtlasBase *w, Tatlas *a)
Defines an atlas from the information on a file.
Definition: atlas.c:3973
Definition of the combination of an atlas with a RRT.
unsigned int nct2
Definition: atlasrrt.h:243
void NewAtlasRRTBranch(TAtlasRRTStatistics *arst)
New branch creation.
Definition: atlasrrt.c:595
unsigned int nc
Definition: atlasrrt.h:235
unsigned int tree
Definition: atlasrrt.c:147
unsigned int VectorSize(Tvector *vector)
Gets the number of elements in a vector.
Definition: vector.c:173
#define CS_WD_ERROR_IN_SIMP_EQUATIONS(pr, p, wcs)
Computes the error in the simplified system for a given point.
Definition: wcs.h:509
double GetRRTNodeCostFromParent(unsigned int i, Trrt *rrt)
Returns the cost from the parent node, if defined.
Definition: rrt.c:3601
unsigned int * tp
Definition: atlasrrt.h:223
#define CT_EPSILON
Numerical tolerance.
Definition: parameters.h:194
void NewAtlasRRTOverlap(TAtlasRRTStatistics *arst)
New overlap.
Definition: atlasrrt.c:655
#define FALSE
FALSE.
Definition: boolean.h:30
double ConnectSamplesChart(Tparameters *pr, unsigned int *tp, boolean *sv, Tbox *domain, unsigned int m, unsigned int n, double *s1, double *s2, double md, boolean checkCollisions, TJacobian *sJ, boolean *reached, boolean *collision, double *lastSample, unsigned int *ns, double ***path, TAtlasBase *w)
Determines the connection between two points on the manifold.
Definition: samples.c:694
unsigned int nCollisionChecks
Definition: atlasrrt.h:155
boolean AtlasRRTstar(Tparameters *pr, double *pg, unsigned int *it, double *times, double *costs, double *planningTime, double *pl, unsigned int *ns, double ***path, TAtlasRRTStatistics *str, Tatlasrrt *ar)
Optimal AtlasRRT on manifolds.
Definition: atlasrrt.c:5285
#define CS_WD_GENERATE_SIMPLIFIED_POINT(pr, p, r, wcs)
Generates a simplified point from an original one.
Definition: wcs.h:495
void LoadAtlasRRTSampleInfo(FILE *f, TSampleInfo *si, Tatlasrrt *ar)
Reads the information associated with a sample in an AtlasRRT.
Definition: atlasrrt.c:4088
void DeleteRRT(Trrt *rrt)
Destructor.
Definition: rrt.c:4201
unsigned int nSample
Definition: atlasrrt.h:142
boolean New_PointTowardRandSample(TAtlasRRTBranchConfig *config, unsigned int samplingMode, double *randSample, TAtlasRRTBranchStatus *status, TSampleInfo *current, TSampleInfo *rand, Tatlasrrt *ar)
Determines the motion on the current chart to approach q_rand.
Definition: atlasrrt.c:2425
double DistanceTopology(unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the distance of two points.
unsigned int n
Definition: atlasrrt.h:110
unsigned int lastID
Definition: atlasrrt.c:142
unsigned int ms
Definition: atlasrrt.h:230
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
boolean canContinueBranch(TAtlasRRTBranchConfig *config, TAtlasRRTBranchStatus *status)
Tests if the branch can be continued.
Definition: atlasrrt.c:1723
unsigned int nCollision
Definition: atlasrrt.h:125
boolean RRTSample(unsigned int samplingMode, unsigned int tree, double *goal, double *q_rand, TRRTStatistics *rst, Trrt *rrt)
Generates a random sample to expand the RRT.
Definition: rrt.c:1470
Data structure to hold the information about the name of a file.
Definition: filename.h:271
#define RRT_EXT
File extension for files storing rrt's.
Definition: filename.h:213
unsigned int ns
Definition: atlasrrt.h:231
A pair of dubles.
Definition: vector.h:114
void NewAtlasRRTTooLong(TAtlasRRTStatistics *arst)
New long branch.
Definition: atlasrrt.c:645
boolean RandomPointInAtlas(Tparameters *pr, double scale, double *w, unsigned int *nm, double *t, double *p, Tatlas *a)
Samples a random point on the atlas.
Definition: atlas.c:4048
void NewAtlasRRTDistanceQrand(double dqr, TAtlasRRTStatistics *arst)
New distance to q_rand.
Definition: atlasrrt.c:615
void PlotRRT(char *fname, int argc, char **arg, Tparameters *pr, unsigned int xID, unsigned int yID, unsigned int zID, Trrt *rrt)
Pots a projection of a RRT.
Definition: rrt.c:3734
void NewAtlasRRTOutOfChart(TAtlasRRTStatistics *arst)
New chart due to radius.
Definition: atlasrrt.c:660
unsigned int nTooLong
Definition: atlasrrt.h:126
TChartInfo ** ci
Definition: atlasrrt.h:236
void * GetVectorElement(unsigned int i, Tvector *vector)
Returns a pointer to a vector element.
Definition: vector.c:270
unsigned int nOutOfChart
Definition: atlasrrt.h:133
unsigned int randomMax(unsigned int m)
Returns a random integer in the range [0,m].
Definition: random.c:77
void NewAtlasRRTSample(TAtlasRRTStatistics *arst)
New sample.
Definition: atlasrrt.c:685
#define ADD_ALL
One of the addition modes for AddBranchToAtlasRRT.
Definition: atlasrrt.c:31
Information for each sample in an AtlasRRT.
Definition: atlasrrt.h:169
void AddEdgeToRRT(unsigned int i, unsigned int j, double c, Trrt *rrt)
Adds a neighbouring relation to an RRT.
Definition: rrt.c:781
unsigned int mct2
Definition: atlasrrt.h:242
unsigned int nCreatedCharts
Definition: atlasrrt.c:145
boolean reachedTmpQrand
Definition: atlasrrt.c:132
void NewAtlasRRTNoEmptyTreeConnection(TAtlasRRTStatistics *arst)
New non-void attempt to connect the two trees.
Definition: atlasrrt.c:610
void InitStatistics(unsigned int np, double v, Tstatistics *t)
Constructor.
Definition: statistics.c:21
CBLAS_INLINE double Norm(unsigned int s, double *v)
Computes the norm of a vector.
boolean AddNodeToRRT(Tparameters *pr, unsigned int tree, unsigned int i_near, double *sample, double *goal, unsigned int *lastSample, void *info, double costp, double cost, TRRTStatistics *rst, Trrt *rrt)
Adds a point to a RRT.
Definition: rrt.c:1868
void PlotConnection(Tparameters *pr, char *prefix, unsigned int target, unsigned int near, unsigned int end, unsigned int xID, unsigned int yID, unsigned int zID, Tatlasrrt *ar)
Graphical representation of the attempt to connect two trees.
Definition: atlasrrt.c:4008
unsigned int nStep
Definition: atlasrrt.h:119
unsigned int tree
Definition: atlasrrt.h:190
void DeleteJacobian(TJacobian *j)
Destructor.
Definition: jacobian.c:255
#define CT_MAX_PLANNING_TIME
Maximum time for path planning.
Definition: parameters.h:475
void DifferenceVectorTopology(unsigned int s, unsigned int *tp, double *v1, double *v2, double *v)
Substracts two vectors.
TJacobian J
Definition: atlasrrt.h:225
double(* costF)(Tparameters *, boolean, double *, void *)
Definition: atlasrrt.c:114
void NewAtlasRRTQrandReached(TAtlasRRTStatistics *arst)
Random sample reached.
Definition: atlasrrt.c:630
CBLAS_INLINE void AccumulateVector(unsigned int s, double *v1, double *v2)
Adds a vector to another vectors.
Definition: basic_algebra.c:55
boolean AtlasTRRT(Tparameters *pr, double *pg, double *time, double *pl, double *pc, unsigned int *ns, double ***path, double(*costF)(Tparameters *, boolean, double *, void *), void *costData, TAtlasRRTStatistics *str, Tatlasrrt *ar)
Extends a Atlas-TRRT until we reach a targed point.
Definition: atlasrrt.c:4688
#define CT_SAMPLING
Sampling mode.
Definition: parameters.h:563
void PlotQrand(Tparameters *pr, char *prefix, unsigned int inear, unsigned int c_rand, double *t_rand, double *q_rand, unsigned int xID, unsigned int yID, unsigned int zID, Tatlasrrt *ar)
Plots a point where q_rang is and a line to its chart.
Definition: atlasrrt.c:3911
void InitBranchConfig(unsigned int mode, TAtlasRRTBranchConfig *config)
Initializes a branch configuration.
Definition: atlasrrt.c:1733
void LoadAtlasRRTChartInfo(FILE *f, TChartInfo *ci, Tatlasrrt *ar)
Reads the information associated with a chart in an AtlasRRT.
Definition: atlasrrt.c:4103
void InitRRT(Tparameters *pr, boolean parallel, boolean simp, double *ps, unsigned int mode, boolean graph, double *pg, unsigned int m, TAtlasBase *w, Trrt *rrt)
Defines a RRT from a given point.
Definition: rrt.c:1203
unsigned int randomWithDistribution(unsigned int m, double s, double *d)
Random number with a given discrete distribution.
Definition: random.c:86
unsigned int GetRRTNN(unsigned int tree, double *q_rand, Trrt *rrt)
Locates the nearest sample in the tree of samples.
Definition: rrt.c:1546
Definition of the Tfilename type and the associated functions.
void PlotAtlasRRT(char *prefix, int argc, char **arg, Tparameters *pr, unsigned int xID, unsigned int yID, unsigned int zID, Tatlasrrt *ar)
Pots a projection of an atlasRRT.
Definition: atlasrrt.c:5859
#define START2GOAL
One of the possible trees.
Definition: rrt.h:168
#define ONE_TREE
One of the modes for the RRT.
Definition: rrt.h:132
void InitPlot3d(char *name, boolean axes, int argc, char **arg, Tplot3d *p)
Constructor.
Definition: plot3d.c:41
void DeleteAtlasRRT(Tatlasrrt *ar)
Destructor.
Definition: atlasrrt.c:6206
#define CT_GAMMA
Contant part of the search radius for nearest neightours in RRT*.
Definition: parameters.h:325
#define TRUE
TRUE.
Definition: boolean.h:21
void IncreaseChartSamplingRadius(Tchart *c)
Increase the sampling radious of the chart.
Definition: chart.c:1382
CBLAS_INLINE void Normalize(unsigned int s, double *v)
Normalizes a vector.
boolean TransitionTestRRT(Tparameters *pr, unsigned int parent, double *q_next, double deltaStep, double *cost, double(*costF)(Tparameters *, boolean, double *, void *), void *costData, Trrt *rrt)
transition Test for Transition RRT
Definition: rrt.c:806
void InitAtlasRRTStatistics(TAtlasRRTStatistics *arst)
Init the Atlas RRT statistics.
Definition: atlasrrt.c:553
double AddSample2AtlasRRT(Tparameters *pr, unsigned int tree, unsigned int *currentID, unsigned int nextChart, double *nextParam, double *nextSample, double dp, double cost, Tatlasrrt *ar)
Adds a sample to the AtlasRRT.
Definition: atlasrrt.c:3146
double Chart2Manifold(Tparameters *pr, TJacobian *sJ, double *t, unsigned int *tp, double *pInit, double *p, Tchart *c)
Returns the point in the manifold for a given set of parameteres.
Definition: chart.c:1069
void DeleteAtlas(Tatlas *a)
Destructor.
Definition: atlas.c:4634
void Error(const char *s)
General error function.
Definition: error.c:80
void NewTemptativeSample(Tparameters *pr, unsigned int it, unsigned int *nChanges, boolean revisitCharts, boolean chartCreated, boolean checkCollisions, boolean onManifold, TSampleInfo *currentSampleInfo, double *currentParam, double *origRandSample, unsigned int *randChart, double *randParam, double *randSample, double currentDelta, double d, double *deltaParam, unsigned int *nextChart, double *nextParam, double *nextSample, void *st, double(*costF)(Tparameters *, boolean, double *, void *), void *costData, double *cost, boolean *blocked, boolean *inCollision, boolean *valid, Tatlasrrt *ar)
Generates a new sample in between q_near and q_rand.
Definition: atlasrrt.c:2881
unsigned int GetRRTNNInNeighbourChart(unsigned int tree, unsigned int c_rand, double *t_rand, double *q_rand, Tatlasrrt *ar)
Selects the nearest point in the chart of Id ChartId, or in a neighbour.
Definition: atlasrrt.c:5800
A color.
Definition: color.h:86
double GetTRRTTemperature(Trrt *rrt)
Temperature of the T-RRT.
Definition: rrt.c:1460
unsigned int nNoEmptyBranch
Definition: atlasrrt.h:114
void NewAtlasRRTSampleRejection(TAtlasRRTStatistics *arst)
New sample rejection.
Definition: atlasrrt.c:710
double ChangeBiRRTSteps(unsigned int l1, unsigned int l2, double c12, Tvector *steps, Trrt *rrt)
Changes the optimal path in a bidirectional RRT.
Definition: rrt.c:3297
unsigned int RRTMemSize(Trrt *rrt)
Memory used by a given RRT.
Definition: rrt.c:3973
unsigned int nErrorNewChart
Definition: atlasrrt.h:131
#define CONNECT_SAFE
One of the pre-defined branch configurations.
Definition: atlasrrt.c:92
#define EXTEND_RRT
One of the pre-defined branch configurations.
Definition: atlasrrt.c:66
#define INIT_NUM_SAMPLES_RRT
Initial room for samples of an rrt.
Definition: rrt.h:125
unsigned int ReconstructAtlasRRTPath(Tparameters *pr, unsigned int sID, double *pl, unsigned int *ns, double ***path, Tatlasrrt *ar)
Collects samples from the tree root to a given sample.
Definition: atlasrrt.c:3553
boolean AddChart2AtlasRRT(Tparameters *pr, unsigned int tree, unsigned int it, TSampleInfo *currentSampleInfo, boolean *intersectParent, Tatlasrrt *ar)
Adds a chart to the Atlas RRT.
Definition: atlasrrt.c:3284
double * t
Definition: atlasrrt.h:173
void NewAtlasRRTChart(TAtlasRRTStatistics *arst)
New Chart.
Definition: atlasrrt.c:690
A chart on a manifold.
Definition: chart.h:70
double r
Definition: atlasrrt.h:210
unsigned int lc
Definition: atlasrrt.h:189
#define CT_MAX_PLANNING_ITERATIONS
Maximum iterations for path planning.
Definition: parameters.h:483
unsigned int GetBoxNIntervals(Tbox *b)
Box dimensionality.
Definition: box.c:1016
void SetRRTParent(unsigned int i, unsigned int p, Trrt *rrt)
Changes the parent for a given node.
Definition: rrt.c:3560
void AtlasRRTstarCloseIteration(unsigned int it, unsigned int id_goal, double time, double gamma, double *times, double *costs, Tatlasrrt *ar)
Prints information about the AtlasRRT* iteration.
Definition: atlasrrt.c:5220
double randomDouble()
Returns a random double in the [0,1] interval.
Definition: random.c:33
void LoadRRT(Tparameters *pr, Tfilename *fname, TAtlasBase *w, Trrt *rrt)
Defines a RRT from the information on a file.
Definition: rrt.c:4041
void AddElement2Heap(unsigned int id, void *e, Theap *heap)
Adds an element to the heap.
Definition: heap.c:294
Tbox ambient
Definition: atlasrrt.h:222
unsigned int GetAtlasNumCharts(Tatlas *a)
Number of charts in the atlas.
Definition: atlas.c:4035
boolean PathStart2GoalInRRT(Tparameters *pr, double *pgs, unsigned int l1, unsigned int l2, double *pl, double *pc, unsigned int *ns, double ***path, Trrt *rrt)
Determines the path from start to goal using an RRT.
Definition: rrt.c:3401
void DeleteFileName(Tfilename *fn)
Destructor.
Definition: filename.c:205
double * GetRRTNode(unsigned int i, Trrt *rrt)
Returns one of the nodes of the RRT.
Definition: rrt.c:3531
#define PLOT_AS_POLYGONS
Set to 1 to get a nicer plot for 2D manifolds.
Definition: chart.h:50
unsigned int StepsToRoot(unsigned int sID, Trrt *rrt)
Computes the number of steps from a node to the root.
Definition: rrt.c:3719
A 3D plot.
Definition: plot3d.h:54
Tatlas atlas
Definition: atlasrrt.h:228
unsigned int id
Definition: atlasrrt.h:170
unsigned int nChart
Definition: atlasrrt.h:143
Definition of a binary heap used to implement priority queues.
boolean InDynamicDomain(unsigned int i, double *q, Trrt *rrt)
Checks if a sample is in the dynamic domaiin of a given node.
Definition: rrt.c:3473
unsigned int nTooFar
Definition: atlasrrt.h:127
double Distance(unsigned int s, double *v1, double *v2)
Computes the distance of two points.
void AddSample2Samples(unsigned int nv, double *sample, unsigned int nvs, boolean *systemVars, unsigned int *ms, unsigned int *ns, double ***path)
Adds a sample to a set of samples.
Definition: samples.c:672
boolean LessThanDoublePair(void *a, void *b, void *userData)
Comparison operator for paris of doubles.
Definition: heap.c:224
void RecursiveReWireRRTstar(Tparameters *pr, Theap *q, double *g, Tvector *steps, double *l, Trrt *rrt)
A rewire that is propagates as much as necessary over the graph.
Definition: rrt.c:2144
#define ATLAS_EXT
File extension for files storing atlas.
Definition: filename.h:200
unsigned int c
Definition: atlasrrt.h:175
boolean CmpID(void *a, void *b)
Comparison operator for identifiers.
Definition: vector.c:19
unsigned int InitChart(Tparameters *pr, boolean simple, Tbox *domain, unsigned int *tp, unsigned int m, unsigned int k, double *p, double e, double eCurv, double r, TJacobian *sJ, TAtlasBase *w, Tchart *c)
Constructor.
Definition: chart.c:795
void NewAtlasRRTStepReduction(TAtlasRRTStatistics *arst)
Step reduction.
Definition: atlasrrt.c:680
double UpdateBiRRTSteps(Tvector *steps, Trrt *rrt)
Updates the current optimal path.
Definition: rrt.c:3356
unsigned int AtlasRRTMemSize(Tatlasrrt *ar)
Memory used by a given atlasRRT.
Definition: atlasrrt.c:6066
void DeleteSampleInfo(TSampleInfo *si)
Deallocates a paramterized point.
Definition: atlasrrt.c:1810
boolean AtlasBiRRTstar(Tparameters *pr, double *pg, unsigned int *it, double *times, double *costs, double *planningTime, double *pl, unsigned int *ns, double ***path, TAtlasRRTStatistics *str, Tatlasrrt *ar)
Bidirectional version of AtlasRRTstar.
Definition: atlasrrt.c:5523
Configuration of the branch extension.
Definition: atlasrrt.c:104
#define CS_WD_SIMP_INEQUALITIES_HOLD(pr, p, wcs)
Cheks if all inequalities hold.
Definition: wcs.h:207
#define KDTREE_SAMPLING
One of the possible sampling modes.
Definition: parameters.h:162
boolean RandomPointInChart(Tparameters *pr, double scale, unsigned int *tp, double *t, double *p, Tchart *c)
Samples a random point in the area covered by the chart.
Definition: chart.c:1367
void AtlasBiRRTstarCloseIteration(unsigned int it, double l, double time, double gamma, double *times, double *costs, Tatlasrrt *ar)
Prints information about the BiAtlasRRT* iteration.
Definition: atlasrrt.c:5255
void InitVector(unsigned int ele_size, void(*Copy)(void *, void *), void(*Delete)(void *), unsigned int max_ele, Tvector *vector)
Constructor.
Definition: vector.c:100
void NewAtlasRRTNoEmptyBranch(TAtlasRRTStatistics *arst)
New no empty branch.
Definition: atlasrrt.c:600
void ReWireAtlasRRTstar(Tparameters *pr, unsigned int id_new, double gamma, unsigned int nn, unsigned int *n, double *c, Tvector *steps, double *l, TAtlasRRTStatistics *arst, Tatlasrrt *ar)
Rewires an AtlasRRT star.
Definition: atlasrrt.c:5127
unsigned int GetRRTMode(Trrt *rrt)
Identifies mode of the RRTs.
Definition: rrt.c:3468
unsigned int nNotInDomain
Definition: atlasrrt.h:124
double GetChartSamplingRadius(Tchart *c)
Returns de sampling range of the chart.
Definition: chart.c:946
#define HEURISTIC_RRT_STAR
Whether to use an heuristic in AtlarRRT*.
Definition: rrt.h:54
void NewAtlasRRTTooFar(TAtlasRRTStatistics *arst)
New large step.
Definition: atlasrrt.c:650
void DifferenceVector(unsigned int s, double *v1, double *v2, double *v)
Substracts two vectors.
unsigned int pc
Definition: atlasrrt.h:174
Statistics associated with a solving process.
Definition: statistics.h:28
double * s
Definition: atlasrrt.h:171
unsigned int GetRRTNNInChart(unsigned int tree, unsigned int chartId, double *q_rand, double t, double *d, Tatlasrrt *ar)
Selects the nearest neighbour from the random point in the chart of Id ChartId.
Definition: atlasrrt.c:5832
unsigned int nNoEmptyTreeConnection
Definition: atlasrrt.h:117
#define MOV_AVG_UP
Weight of new data when computing moving averages.
Definition: defines.h:451
boolean AtlasRRT(Tparameters *pr, double *pg, double *time, double *pl, unsigned int *ns, double ***path, TAtlasRRTStatistics *str, Tatlasrrt *ar)
Extends a Atlas-RRT until we reach a targed point.
Definition: atlasrrt.c:4392
void DeleteHeap(Theap *heap)
Destructor.
Definition: heap.c:388
void Warning(const char *s)
General warning function.
Definition: error.c:116
A table of parameters.
unsigned int mc
Definition: atlasrrt.h:234
unsigned int m
Definition: atlasrrt.h:206
#define BOTHTREES
Used for samples in both trees.
Definition: rrt.h:183
void CreateFileName(char *path, char *name, char *suffix, char *ext, Tfilename *fn)
Constructor.
Definition: filename.c:22
unsigned int nNoConvergent
Definition: atlasrrt.h:132
void DeleteAtlasRRTStatistics(TAtlasRRTStatistics *arst)
Destructor.
Definition: atlasrrt.c:973
void NewAtlasRRTLargeCurvature(TAtlasRRTStatistics *arst)
New chart due large curvature between two charts.
Definition: atlasrrt.c:670
void SetSampleInfo(unsigned int m, unsigned int k, TSampleInfo *si_dst, TSampleInfo *si_src)
Initializes a parametrized point from another parametrized point.
Definition: atlasrrt.c:1793
#define CS_WD_GET_SIMP_JACOBIAN(pr, J, wcs)
Computes the Jacobian of the simplified system.
Definition: wcs.h:553
boolean AtlasRRTSample(Tparameters *pr, unsigned int samplingMode, unsigned int it, unsigned int tree, double *goal, double scale, boolean *exploration, unsigned int *c_rand, double *t_rand, double *q_rand, TAtlasRRTStatistics *arst, Tatlasrrt *ar)
Generates a random sample to expand the AtlasRRT.
Definition: atlasrrt.c:4252
TSampleInfo ** si
Definition: atlasrrt.h:232
boolean birrt
Definition: atlasrrt.h:213
boolean checkCollisions
Definition: atlasrrt.c:108
boolean explorationSample
Definition: atlasrrt.c:111
void DeleteChart(Tchart *c)
Destructor.
Definition: chart.c:2014
#define ADD_LAST
One of the addition modes for AddBranchToAtlasRRT.
Definition: atlasrrt.c:38
void NewAtlasRRTTreeConnection(TAtlasRRTStatistics *arst)
New attempt to connect the two trees.
Definition: atlasrrt.c:605
Type defining the equations on which the atlas is defined.
Definition: wcs.h:30
void NewAtlasRRTInitChartError(TAtlasRRTStatistics *arst)
New chart due to error when trying to create a chart.
Definition: atlasrrt.c:665
unsigned int nNoConnect
Definition: atlasrrt.h:144
Definition of a local chart on a manifold.
A generic vector.
Definition: vector.h:227
#define CS_WD_GET_SYSTEM_VARS(sv, wcs)
Gets the system variables.
Definition: wcs.h:238
Trrt rrt
Definition: atlasrrt.h:227
char * GetFileFullName(Tfilename *fn)
Gets the file full name (paht+name+extension).
Definition: filename.c:151
void GetRRTNNInBranch(unsigned int tree, unsigned int n1, unsigned int n2, unsigned int *n, unsigned int *nn, Trrt *rrt)
Locates the nearest sample in the tree to a branch.
Definition: rrt.c:1774
void NewAtlasRRTCollision(TAtlasRRTStatistics *arst)
New collision.
Definition: atlasrrt.c:640
void AccumulateAtlasRRTStatistics(TAtlasRRTStatistics *arst1, TAtlasRRTStatistics *arst2)
Accumulates two sets of Atlas RRT statistics.
Definition: atlasrrt.c:720
#define EXPLORATION_RRT
Select between exploration and goal driven RRT.
Definition: rrt.h:98
#define CS_WD_REGENERATE_ORIGINAL_POINT(pr, p, o, wcs)
Completes an original point from a simplified one.
Definition: wcs.h:293
void InitHeap(unsigned int ele_size, void(*Copy)(void *, void *), void(*Delete)(void *), boolean(*LessThan)(void *, void *, void *), void *userData, boolean hasIDs, unsigned int max_ele, Theap *heap)
Constructor.
Definition: heap.c:237
#define ADD_LAST_NO_REP
One of the addition modes for AddBranchToAtlasRRT.
Definition: atlasrrt.c:46
void InitSampleInfo(unsigned int m, unsigned int k, TSampleInfo *si)
Initializes the space to hold a parametrized point.
Definition: atlasrrt.c:1782
unsigned int AtlasMemSize(Tatlas *a)
Memory used by a given atlas.
Definition: atlas.c:3935
unsigned int GetRRTNodeTree(unsigned int i, Trrt *rrt)
Returns the tree for a given node.
Definition: rrt.c:3539
unsigned int lsc
Definition: atlasrrt.h:177
double ce
Definition: atlasrrt.h:209
double GetRRTNodeCost(unsigned int i, Trrt *rrt)
Returns the cost associated with a node.
Definition: rrt.c:3593
void ReverseSamples(unsigned int ns, double **path)
Reverses a set of samples.
Definition: samples.c:2752
void WireAtlasRRTstar(Tparameters *pr, unsigned int id_new, unsigned int i_near, double gamma, unsigned int nn, unsigned int *n, double **c, double h, Theap *q, unsigned int *t, TAtlasRRTStatistics *arst, Tatlasrrt *ar)
Wires a node to the AtlasRRT star.
Definition: atlasrrt.c:4968
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
unsigned int addMode
Definition: atlasrrt.c:105
unsigned int GetAtlasRRTNumCharts(Tatlasrrt *ar)
Number of charts in the AtlasRRT.
Definition: atlasrrt.c:5794
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
CBLAS_INLINE void SumVectorScale(unsigned int s, double *v1, double w, double *v2, double *v)
Adds two vectors with a scale.
Definition: basic_algebra.c:86
void SaveRRT(Tfilename *fname, Trrt *rrt)
Stores the RRT information on a file.
Definition: rrt.c:3990
double New_AddBranchToAtlasRRT(Tparameters *pr, unsigned int it, TAtlasRRTBranchConfig *config, unsigned int i_near, double *randSample, double *goalSample, void *st, TAtlasRRTBranchStatus *status, unsigned int *ns, double ***path, Tatlasrrt *ar)
Adds a new branch to the AtlasRRT.
Definition: atlasrrt.c:1816
unsigned int generateChart
Definition: atlasrrt.h:176
void InitSamples(unsigned int *ms, unsigned int *ns, double ***path)
Initializes a set of samples.
Definition: samples.c:665
double * GetChartCenter(Tchart *c)
Returns the center of the chart.
Definition: chart.c:936
boolean RandomPointInAtlasTree(Tparameters *pr, double scale, unsigned int tree, unsigned int *nm, double *t, double *p, Tatlasrrt *ar)
Selects a random point in the set of charts of the tree.
Definition: atlasrrt.c:3821
void NewAtlasRRTNotInDomain(TAtlasRRTStatistics *arst)
New node not in the given domain.
Definition: atlasrrt.c:635
void SmoothPathInAtlasRRT(Tparameters *pr, unsigned int sID, Tatlasrrt *ar)
Local optimiziation of the path to a node.
Definition: atlasrrt.c:3745
void GetRRTNNInBall(unsigned int tree, double *q_rand, double r, unsigned int *nn, unsigned int **n, Trrt *rrt)
Locates the all the sample closer than a given distance.
Definition: rrt.c:1653
Definition of the Tvector type and the associated functions.
void InitBranchStatus(double epsilon, double delta, TAtlasRRTBranchConfig *config, TSampleInfo *near, double *randSample, double *goalSample, Tatlasrrt *ar, TAtlasRRTBranchStatus *status)
Initializes the branch status.
Definition: atlasrrt.c:1634
Step in a solution path.
Definition: rrt.h:248
Tchart * GetAtlasChart(unsigned int id, Tatlas *a)
Gets one of the charts of the chart.
Definition: atlas.c:4040
void LoadAtlasRRT(Tparameters *pr, char *prefix, TAtlasBase *w, Tatlasrrt *ar)
Defines an atlasRRT from the information on a file.
Definition: atlasrrt.c:6133
Statistics on the AtlasRRT constrution.
Definition: atlasrrt.h:109
unsigned int nLargeCurvature
Definition: atlasrrt.h:134
void SaveAtlas(Tparameters *pr, Tfilename *fname, Tatlas *a)
Stores the atlas information on a file.
Definition: atlas.c:3946
boolean InsideChartPolytope(double *t, Tchart *c)
Checks if a parameter point is inside the chart polytope.
Definition: chart.c:1316
void DeleteBox(void *b)
Destructor.
Definition: box.c:1283
double e
Definition: atlasrrt.h:208
unsigned int nBranch
Definition: atlasrrt.h:113
#define ATLASRRT_VERBOSE
Vebosity of the AtlasRRT operations.
Definition: atlasrrt.h:41
void NewDoublePair(double f, double s, TDoublePair *p)
Constructor.
Definition: vector.c:49
#define PLOT3D_EXT
File extension for 3D plot files.
Definition: filename.h:168
#define AMBIENT_SAMPLING
One of the possible sampling modes.
Definition: parameters.h:151
void Local2Global(double *t, unsigned int *tp, double *p, Tchart *c)
Transforms a parameter in tangent space to a point in ambient space.
Definition: chart.c:1215
unsigned int AddTrustedChart2Atlas(Tparameters *pr, double *ps, unsigned int parentID, boolean *singular, Tatlas *a)
Defines a new chart and adds it to the atlas.
Definition: atlas.c:2905
unsigned int nRandom
Definition: atlasrrt.h:150
boolean ElementInVector(void *e, boolean(*cmp)(void *, void *), Tvector *vector)
Search for an element in a vector.
Definition: vector.c:188
void SetSampleInfoFromNode(unsigned int n, Tatlasrrt *ar, TSampleInfo *si)
Sets the sample info to taking data from an AtlasRRT node.
Definition: atlasrrt.c:1805
#define CT_E
Chart error in atlas.
Definition: parameters.h:243
RRT with an atlas for sampling.
Definition: atlasrrt.h:203
void SetRRTCostAndParent(unsigned int i, unsigned int p, double costp, double cost, Trrt *rrt)
Changes the cost and the parent associated with a node.
Definition: rrt.c:3620
double Manifold2Chart(double *p, unsigned int *tp, double *t, Tchart *c)
Returns the parametrization of a point.
Definition: chart.c:1039
double DistanceTopologyMin(double t, unsigned int s, unsigned int *tp, double *v1, double *v2)
Computes the distance of two points, if it is below a given threshold.
#define MEM_EXPAND(_var, _n, _type)
Expands a previously allocated memory space.
Definition: defines.h:404
#define TWO_TREES_WITH_SWAP
One of the modes for the RRT.
Definition: rrt.h:154
boolean CloseCharts(Tparameters *pr, unsigned int *tp, Tchart *c1, Tchart *c2)
Identifies close local charts.
Definition: chart.c:1267
double GetParameter(unsigned int n, Tparameters *p)
Gets the value for a particular parameter.
Definition: parameters.c:93
void PopulateWithSamples(Tparameters *pr, unsigned int id, Tatlasrrt *ar)
Assign samples to a newly created chart.
Definition: atlasrrt.c:3463
unsigned int Steps2PathinAtlasRRT(Tparameters *pr, Tvector *steps, double *pl, double *pc, unsigned int *ns, double ***path, Tatlasrrt *ar)
Defines a path from a vector of steps.
Definition: atlasrrt.c:3637
A generic binary heap.
Definition: heap.h:105
#define CS_WD_REGENERATE_SOLUTION_POINT(pr, p, r, wcs)
Compleates a solution point with the dummy variables.
Definition: wcs.h:480
void NewAtlasRRTStep(TAtlasRRTStatistics *arst)
New step in branch extension.
Definition: atlasrrt.c:620
void DeleteBranchStatus(TAtlasRRTBranchStatus *status)
Destructor.
Definition: atlasrrt.c:1717
unsigned int boolean
Boolean type.
Definition: boolean.h:13
unsigned int ChartNumNeighbours(Tchart *c)
Number of neighbours of the chart.
Definition: chart.c:1678
boolean DynamicDomainRRT(Trrt *rrt)
TRUE if the dynamic domain is active.
Definition: rrt.c:3521
unsigned int GetRRTNumNodes(Trrt *rrt)
Number of nodes in the RRT.
Definition: rrt.c:3526
void SaveAtlasRRTSampleInfo(FILE *f, TSampleInfo *si, Tatlasrrt *ar)
Saves the information associated with a sample in an AtlasRRT.
Definition: atlasrrt.c:4067
void DeleteColor(Tcolor *c)
Destructor.
Definition: color.c:143
double CostToRoot(unsigned int sID, Trrt *rrt)
Computes the cost from a node to the root.
Definition: rrt.c:3643
void ForceChartCut(Tparameters *pr, unsigned int *tp, Tbox *ambient, unsigned int id1, Tchart *c1, unsigned int id2, Tchart *c2)
Intersect two charts that might be non-neighbours.
Definition: chart.c:265
void UpdateCostAndTree(unsigned int sID, Trrt *rrt)
A combination of UpdateCostToRoot and UpdateTree.
Definition: rrt.c:3692
void NewAtlasRRTCollisionCheck(TAtlasRRTStatistics *arst)
New collision check.
Definition: atlasrrt.c:715
Satus of the branch extension.
Definition: atlasrrt.c:129
#define CS_WD_IN_COLLISION(f, pr, s, sPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:355
#define INF
Infinite.
Definition: defines.h:70
void SetRRTNodeCost(unsigned int i, double costp, double cost, Trrt *rrt)
Changes the cost associated with a node.
Definition: rrt.c:3609
void EnlargeChart(double *t, Tchart *c)
Ensures that a chart includes a given point.
Definition: chart.c:1335
unsigned int mct1
Definition: atlasrrt.h:238
#define ATLAS_RRT_EXT
File extension for files storing AtlasRTT's.
Definition: filename.h:220
unsigned int * chartsAtTree2
Definition: atlasrrt.h:244
#define CT_DELTA
Size of the steps in the path connecting two configurations.
Definition: parameters.h:282
void NewAtlasRRTDirLargeCurvature(TAtlasRRTStatistics *arst)
New chart due to the curvature in the expansion direction.
Definition: atlasrrt.c:675
void NewAtlasRRTBlockBySingularity(TAtlasRRTStatistics *arst)
Number of times we try to create a char at a singular regions.
Definition: atlasrrt.c:700
#define CT_N_DOF
Dimensionality of the solution space for the mechanism at hand.
Definition: parameters.h:318
Auxiliary functions to deal with sets of samples.
#define GOAL2START
One of the possible trees.
Definition: rrt.h:176
#define CT_DETECT_BIFURCATIONS
TRUE (or 1) if bifurcation must be detected.
Definition: parameters.h:468
unsigned int ChartNeighbourID(unsigned int n, Tchart *c)
Returns the identifier of one of the neighbours of a chart.
Definition: chart.c:1690
boolean InitAtlasFromPoint(Tparameters *pr, boolean parallel, boolean simpleChart, double *p, TAtlasBase *w, Tatlas *a)
Initializes an atlas from a given point.
Definition: atlas.c:2782
void InitAtlasRRT(Tparameters *pr, boolean parallel, double *ps, unsigned int mode, boolean graph, double *pg, TAtlasBase *w, Tatlasrrt *ar)
Defines a Atlas-RRT from a given point.
Definition: atlasrrt.c:4114
Definition of basic randomization functions.
double GetElapsedTime(Tstatistics *t)
Elapsed time.
Definition: statistics.c:92
void NewColor(double r, double g, double b, Tcolor *c)
Constructor.
Definition: color.c:14
unsigned int nQrandReached
Definition: atlasrrt.h:123
boolean parallel
Definition: atlasrrt.h:217
boolean PointTowardRandSample(unsigned int cId, double d, double *t, unsigned int samplingMode, boolean onManifold, double *origRandSample, unsigned int *randChart, double *randParam, double *randSample, double *deltaParam, Tatlasrrt *ar)
Determines the motion on the current chart to approach q_rand.
Definition: atlasrrt.c:3240
void New_NewTemptativeSample(Tparameters *pr, unsigned int it, TAtlasRRTBranchConfig *config, TAtlasRRTBranchStatus *status, TSampleInfo *current, TSampleInfo *next, TSampleInfo *rand, double *randSample, void *st, Tatlasrrt *ar)
Generates a new sample in between q_near and q_rand.
Definition: atlasrrt.c:2115
void NewAtlasRRTRandomSample(TAtlasRRTStatistics *arst)
New random sample.
Definition: atlasrrt.c:705
unsigned int it
Definition: atlasrrt.h:191
void CopyDoublePair(void *a, void *b)
Copy constructor for pairs of doubles.
Definition: vector.c:71
unsigned int nOverlap
Definition: atlasrrt.h:128
unsigned int nTreeConnection
Definition: atlasrrt.h:116
void DeleteSamples(unsigned int ns, double **path)
Deletes the space used by a set of samples.
Definition: samples.c:3159
unsigned int nRejections
Definition: atlasrrt.h:152
unsigned int AddStepToAtlasRRTstar(Tparameters *pr, unsigned int it, boolean expand2Goal, unsigned int i_near, double *q_rand, unsigned int *id_goal, double *goal, TAtlasRRTStatistics *arst, Tatlasrrt *ar)
Adds a node to an AtlasRRT*.
Definition: atlasrrt.c:4872
#define ADD_NONE
One of the addition modes for AddBranchToAtlasRRT.
Definition: atlasrrt.c:53
void NewAtlasRRTNoConvergentStep(TAtlasRRTStatistics *arst)
Problems with convergence.
Definition: atlasrrt.c:625
#define CONNECT_RRTs
One of the pre-defined branch configurations.
Definition: atlasrrt.c:76
#define CS_WD_GENERATE_SIMP_INITIAL_BOX(pr, b, wcs)
Computes the global box for the simplified system.
Definition: wcs.h:539
#define CONNECT_SAMPLES
One of the pre-defined branch configurations.
Definition: atlasrrt.c:83
TAtlasBase * w
Definition: atlasrrt.h:204
unsigned int nDirLargeCurvature
Definition: atlasrrt.h:135
unsigned int GetAtlasRRTNumNodes(Tatlasrrt *ar)
Number of nodes in the AtlasRRT.
Definition: atlasrrt.c:5789
void SaveAtlasRRTChartInfo(FILE *f, TChartInfo *ci, Tatlasrrt *ar)
Saves the information associated with a chart in an AtlasRRT.
Definition: atlasrrt.c:4081
boolean AtlasRRTValidateSample(Tparameters *pr, double *q_rand, unsigned int tree, boolean expand2goal, unsigned int lastNN2Goal, double *goal, double l, double *h, unsigned int *i_near, TAtlasRRTStatistics *arst, Tatlasrrt *ar)
Validates a sample generate with AtlasRRTSample.
Definition: atlasrrt.c:4340
#define INIT_NUM_CHARTS
Initial number of charts of an atlas.
Definition: atlas.h:60
unsigned int StartNew3dObject(Tcolor *c, Tplot3d *p)
Start a composed object.
Definition: plot3d.c:157
void DeleteStatistics(Tstatistics *t)
Destructor.
Definition: statistics.c:274
void DecreaseChartSamplingRadius(Tchart *c)
Decrease the sampling radious of the chart.
Definition: chart.c:1388
double AddBranchToAtlasRRT(Tparameters *pr, unsigned int it, unsigned int addMode, boolean revisitCharts, boolean checkCollisions, boolean onManifold, boolean explorationSample, double maxLength, unsigned int i_near, double *origRandSample, double *goalSample, void *st, unsigned int *lastSampleID, boolean *reachedQRand, boolean *reachedGoal, unsigned int *ns, double ***path, double(*costF)(Tparameters *, boolean, double *, void *), void *costData, Tatlasrrt *ar)
Adds a new branch to the AtlasRRT.
Definition: atlasrrt.c:2478
#define CT_CE
Chart error in atlas.
Definition: parameters.h:250
boolean SingularChart(Tchart *c)
Identify charts defined on singularities.
Definition: chart.c:983
void AddChart2Tree(unsigned int tree, unsigned int chartId, Tatlasrrt *ar)
Add a chart to a tree.
Definition: atlasrrt.c:3218
unsigned int nct1
Definition: atlasrrt.h:239
void CopyRRTStep(void *a, void *b)
Copy constructor for RRTSteps.
Definition: rrt.c:750
void PlotAtlas(char *fname, int argc, char **arg, Tparameters *pr, FILE *fcost, unsigned int xID, unsigned int yID, unsigned int zID, Tatlas *a)
Pots a projection of an atlas.
Definition: atlas.c:4227
void Close3dObject(Tplot3d *p)
Closes a composed object.
Definition: plot3d.c:171
Information for each chart in an AtlasRRT.
Definition: atlasrrt.h:188
unsigned int nSingular
Definition: atlasrrt.h:146
unsigned int * GetRRTTopology(Trrt *rrt)
Returns a pointer to an array with the topology for each variable.
Definition: rrt.c:3638
void ClosePlot3d(boolean quit, double average_x, double average_y, double average_z, Tplot3d *p)
Destructor.
Definition: plot3d.c:473
unsigned int * chartsAtTree1
Definition: atlasrrt.h:240
#define CT_MAX_NODES_RRT
Maximum number of nodes in an RRT.
Definition: parameters.h:497
unsigned int NewVectorElement(void *e, Tvector *vector)
Adds an element to the vector.
Definition: vector.c:216
boolean PointInBoxTopology(boolean *used, boolean update, unsigned int n, double *v, double tol, unsigned int *tp, Tbox *b)
Checks if a point is included in a(sub-) box.
Definition: box.c:374
void PrintAtlasRRTStatistics(Tatlasrrt *ar, TAtlasRRTStatistics *arst)
Prints the summary of atlasRRT statistics.
Definition: atlasrrt.c:766
void CopyID(void *a, void *b)
Copy constructor for identifiers.
Definition: vector.c:24
unsigned int DetermineChartNeighbour(double epsilon, double *t, Tchart *c)
Determines the neighbouring chart containing a given point.
Definition: chart.c:1324
double GetDynamicDomainRadius(unsigned int i, Trrt *rrt)
Returns the current dynamic domain radius for a given sample.
Definition: rrt.c:3513
#define CS_WD_ORIGINAL_IN_COLLISION(pr, o, oPrev, wcs)
Checks if a configuration is in collision.
Definition: wcs.h:397
void SaveAtlasRRT(Tparameters *pr, char *prefix, Tatlasrrt *ar)
Stores the Atlas-RRT information on a file.
Definition: atlasrrt.c:6076
#define MOV_AVG_DOWN
Weight of new data when computing moving averages.
Definition: defines.h:467