planners/rrt/PL_RRT_Connect.cpp

Go to the documentation of this file.
00001 
00002 #include <assert.h>
00003 #include "synchronization/semaphore.h"
00004 #include "PL_RRT_CONNECT.h"
00005 #include "planners/aca/jma_switch.h"
00006 #include "planners/aca/jma_aca_macros.h" //IMPROVE: these should be c++ function calls
00007 #include <iosfwd>
00008 #include <iostream>
00009 #include "kinematics/configuration.h"
00010 #include "opengl/glos.h"
00011 #include <gl/gl.h>
00012 
00013 #define THICKNESS 3
00014 #define WIN_WIDTH  1000
00015 #define WIN_HEIGHT 500
00016 #define EPSILON  1.0e-3
00017 #define BIG_NUMBER 1.0e+37
00018 #define STEP_SIZE       (5*collisionDetector->DOF())
00019 
00020 
00021 //IMPROVE: these definitions should be constants, or removed
00022 //## end module%376A87F4037E.additionalDeclarations
00023 
00024 PL_RRT_CONNECT::~PL_RRT_CONNECT()
00025 {
00026 
00027 }
00028 
00029 bool PL_RRT_CONNECT::Plan()
00030 {
00031         //MessageBox(NULL, "This is Rex's RRT_CONNECT planner", "Hello", MB_OK);
00032         //return false;
00033 
00034         PlannerBase::StartTimer() ;
00035         path.Clear() ;
00036 //      StartOutput() ;         //IMPROVE: this is for the output window - shouldnt be here
00037  
00038         if( collisionDetector->IsInterfering( GetStartConfig() ) )
00039         {
00040                 path.AppendPoint( GetGoalConfig() ) ;
00041                 path.AppendPoint( GetGoalConfig() ) ;
00042                 return false ;
00043         }
00044         if( collisionDetector->IsInterfering( GetGoalConfig() ) )
00045         {
00046                 path.AppendPoint( GetStartConfig() ) ;
00047                 path.AppendPoint( GetStartConfig() ) ;
00048                 return false ;
00049         }
00050 
00051 //set start and goal configuration and initialize two trees.
00052 
00053     SetStart_and_GoalConfig (GetStartConfig(), GetGoalConfig());
00054 
00055         int i;
00056         int n_landmarks1, n_landmarks2;
00057         bool path_found=false;
00058     JMA_Roadmap_Tree *temp_tree, *temp_tree1, *temp_tree2;
00059 
00060         temp_tree1 = &tree1;
00061         temp_tree2 = &tree2;
00062         Semaphore semaphore( guid );
00063         semaphore.Lock();
00064         //int _MAX_LANDMARKS = 3.5*MAX_LANDMARKS;
00065     //for(i=1; i<_MAX_LANDMARKS;i++)
00066         do
00067         {
00068                 Get_random_config(&random_config);
00069                 if ((Extend_trapped(temp_tree1, &(temp_tree1->n_nodes), &random_config))!=3)
00070                 {
00071                         old_new_config=new_config;
00072                         if (connect(temp_tree2, old_new_config))
00073                         {
00074                                 path_found=true;
00075                                 break;
00076                         }
00077                 }
00078                 // swap the two trees
00079                 
00080                 temp_tree=temp_tree1;
00081                 temp_tree1=temp_tree2;
00082                 temp_tree2=temp_tree;
00083 
00084                 semaphore.Unlock();
00085                 semaphore.Lock();
00086         } while ((!path_found) && (HasTimeLimitExpired() == false) );
00087 
00088         semaphore.Unlock();
00089 
00090         //if ((!(path_found))||( HasTimeLimitExpired() == true )||( (tree1.n_nodes +tree2.n_nodes)> _MAX_LANDMARKS/2 ))
00091         //    return false ;
00092 
00093         //double elapsedTime = timer.ElapsedTime();
00094         //int mmmmm=tree1.n_nodes +tree2.n_nodes;
00095         //int m1=tree1.n_nodes;
00096         //int m2=tree2.n_nodes;
00097 
00098         if (path_found)
00099     {
00100 // get ids of landmarks of the two paths of the two trees
00101                 GetIdsPath(&tree1,&tree2, tree1.n_nodes-1,tree2.n_nodes-1, ids_list1,&n_landmarks1, ids_list2,&n_landmarks2);
00102 
00103                 for( i = n_landmarks1-1; i >=0; i--)
00104                 {
00105                         int pointIndex = ids_list1[ i ] ;
00106                         Configuration point = tree1.node[ pointIndex ].landmark.dof ;
00107                         path.AppendPoint( point ) ;
00108                 }
00109                 for( i =1; i <n_landmarks2; i++)
00110                 {
00111                         int pointIndex = ids_list2[ i ] ;
00112                         Configuration point = tree2.node[ pointIndex ].landmark.dof ;
00113                         path.AppendPoint( point ) ;
00114                 }
00115         }
00116         else
00117     {
00118                 if( path.Size() == 0 )
00119                 {
00120                         path.AppendPoint( GetStartConfig() ) ;
00121                 }
00122                 return false ;
00123         }
00124 
00125 //optimize the found path
00126 #ifdef _PATH_OPTIMIZATION_
00127          PA_Points the_path;
00128          int size=path.Size();
00129          the_path.AppendPoint(path[0]);
00130          Configuration p1 = path[ 0 ] ;
00131          int n=size-1;
00132          int indicater=0;
00133      while (indicater!=size-1)
00134          {
00135             Configuration p2 = path[n];
00136                 while (collisionDetector->IsInterferingLinear( p1, p2 ))
00137                 {
00138                         n=n-1;
00139                         if (n==indicater)
00140                                 assert(false);
00141                         p2=path[n];
00142                 }
00143                 the_path.AppendPoint (p2);
00144                 p1=p2;
00145                 indicater=n;
00146                 n=size-1;
00147          }
00148          path.Clear();
00149          for (n=0;n<the_path.Size();n++)
00150                  path.AppendPoint(the_path[n]);
00151          the_path.Clear();
00152 
00153         //verify the outputs
00154         for( i = 0; i < path.Size() - 1 ; i++ )
00155         {
00156                 Configuration p1 = path[ i ] ;
00157                 Configuration p2 = path[ i + 1 ] ;
00158                 int e=i;
00159 
00160                 assert( !collisionDetector->IsInterferingLinear( p1, p2 ) ) ;
00161                 if( collisionDetector->IsInterferingLinear( p1, p2 ) )
00162                 {
00163                         assert( false ) ;
00164                 }
00165         }
00166 #endif
00167 
00168         return true ;
00169 }
00170 
00171 int PL_RRT_CONNECT::Get_random_config(Configuration* the_random_config)
00172 {
00173         Configuration config= GetStartConfig() ;        //this just initializes the config
00174         //bool isConfigInCollision = collisionDetector->IsInterfering( config ) ;
00175         //assert( isConfigInCollision == false ) ;
00176         //Configuration current = init_conf.dof ;
00177         do
00178         {
00179                 for( int j = 0; j < config.DOF(); j++ )
00180                 {
00181                         double jointMax = collisionDetector->JointMax( j ) ;
00182                         double jointMin = collisionDetector->JointMin( j ) ;
00183                         double random01 = (double) switch_random()/BIGEST_RND_NUMBER ;
00184                         double jointVal = jointMin + random01 * ( jointMax - jointMin );
00185                         config[ j ] = jointVal ;
00186                 }
00187         } while( collisionDetector->IsInterfering(config ) );
00188         (*the_random_config) = config ;
00189         return 0;
00190 }
00191 
00192 int PL_RRT_CONNECT::Extend_trapped(JMA_Roadmap_Tree* Ptr_tree, int* the_n_nodes, Configuration* the_random_config)
00193 {
00194         //get nearest neighbour of random_config
00195         int near_neighbour_id=Get_nearest_neighbour(Ptr_tree, the_random_config);
00196 
00197 //      Get_new_config(&random_config, &near_config, &new_config);
00198         if(!( collisionDetector->IsInterferingLinear(near_config,random_config)))
00199         {
00200             (*Ptr_tree).node[*the_n_nodes].landmark.dof=random_config;
00201                         new_config=random_config;
00202                         (*Ptr_tree).node[*the_n_nodes].father_id=near_neighbour_id;
00203             ++(*the_n_nodes);
00204                         return 1;  //reach the random_config
00205         }
00206         return 3; // trapped
00207 }
00208 
00209 int PL_RRT_CONNECT::Simple_Extend_trapped(JMA_Roadmap_Tree* Ptr_tree, 
00210                                                                                   int* the_n_nodes, Configuration old_new_config)
00211 {
00212         Get_new_config(&old_new_config, &near_config, &new_config);
00213         if((!(collisionDetector->IsInterferingLinear(near_config,new_config))) && ((!(collisionDetector->IsInterfering(new_config)))))
00214         {
00215                 if (MyDistanceFunc(near_config, new_config)>=MyDistanceFunc(near_config, old_new_config))
00216                 {
00217             (*Ptr_tree).node[*the_n_nodes].landmark.dof=old_new_config;//double use of this Configuration
00218                         //new_config=random_config;
00219                         (*Ptr_tree).node[*the_n_nodes].father_id=near_neighbour_id;
00220             (*the_n_nodes)=(*the_n_nodes)+1;
00221                         return 1;  //two trees get connected
00222                 }
00223                 else
00224                 {
00225 
00226                     (*Ptr_tree).node[*the_n_nodes].landmark.dof=new_config;     
00227                         (*Ptr_tree).node[*the_n_nodes].father_id=near_neighbour_id;
00228             (*the_n_nodes)=(*the_n_nodes)+1;
00229                     near_config=new_config;
00230                         near_neighbour_id=(*the_n_nodes)-1;
00231                         return 2;//advance
00232                 }
00233         }
00234         return 3;
00235 
00236 }
00237 
00238 
00239 
00240 int PL_RRT_CONNECT::Get_nearest_neighbour(JMA_Roadmap_Tree* Ptr_tree, Configuration* the_random_config)
00241 {
00242         double min_distance=100000.0;
00243         double temp_distance;
00244         int indicator;
00245         for (int i=0; i<(*Ptr_tree).n_nodes; i++)
00246         {
00247         temp_distance=MyDistanceFunc((*Ptr_tree).node[i].landmark.dof, *the_random_config);
00248                 if(min_distance>temp_distance)
00249                 {
00250                         min_distance=temp_distance;
00251                         indicator=i;
00252                 }
00253         }
00254         near_config=(*Ptr_tree).node[indicator].landmark.dof;
00255         return indicator;
00256 }
00257 
00258 
00259 int PL_RRT_CONNECT::Get_new_config(Configuration* the_random_config, Configuration* the_near_config, Configuration* the_new_config)
00260 {
00261         double Fixed_Distance=STEP_SIZE;
00262         double pp=MyDistanceFunc((*the_random_config),(*the_near_config));
00263         (*the_new_config)=(*the_near_config)*(1-Fixed_Distance/pp)+(*the_random_config)*(Fixed_Distance/pp);
00264         return 0;
00265 }
00266 
00267 
00268 //int PL_RRT_CONNECT::Get_new_config(Configuration* the_random_config, Configuration* the_near_config, Configuration* the_new_config)
00269 //{
00270 //      double Fixed_Distance=0.1;///////need to adjust
00271 //      double pp=MyDistanceFunc((*the_random_config),(*the_near_config));
00272 //      (*the_new_config)=(*the_random_config)*(1-Fixed_Distance/pp)+(*the_near_config)*(Fixed_Distance/pp);
00273 //      return 0;
00274 //}
00275 
00276 
00277 
00278 bool PL_RRT_CONNECT::connect(JMA_Roadmap_Tree* My_tree, Configuration old_new_config)
00279 {
00280     near_neighbour_id=Get_nearest_neighbour(My_tree, &old_new_config);
00281         int i=2;
00282     while (i==2)
00283         {
00284 
00285             i=Simple_Extend_trapped(My_tree, &((*My_tree).n_nodes), old_new_config);
00286         }
00287         if(i==1)
00288                 return true;
00289         else 
00290                 return false;
00291 }
00292 
00293 double PL_RRT_CONNECT::MyDistanceFunc (const Configuration& conf1, const Configuration& conf2) const
00294 { 
00295 
00296   return collisionDetector->DistanceBetween( conf1, conf2 ) ;
00297 
00298 }
00299 
00300 
00301 void PL_RRT_CONNECT::InitRoadmapTree( JMA_Roadmap_Tree* Ptr_tree1, 
00302                                                                          JMA_Roadmap_Tree* Ptr_tree2, 
00303                                                                          const int n_dof1, 
00304                                                                          const int n_dof2, 
00305                                                                          const JMA_Configuration init_conf, 
00306                                                                          const JMA_Configuration goal_conf) const
00307 {
00308   double dist;  
00309   (*Ptr_tree1).N_dof = n_dof1;
00310   (*Ptr_tree1).n_nodes = 1;
00311   (*Ptr_tree1).max_dist = 0.0;
00312   (*Ptr_tree1).last_max_dist = -1.0;
00313   (*Ptr_tree1).best_father_id = 0;
00314   (*Ptr_tree1).node[0].N_embryos = 0;
00315   (*Ptr_tree1).node[0].father_id = NIL;
00316 
00317 
00318   (*Ptr_tree1).node[0].landmark.dof = init_conf.dof;            //can't just assign JMA_Configurations
00319   (*Ptr_tree1).node[0].landmark.dist = init_conf.dist;
00320 
00321   (*Ptr_tree2).N_dof = n_dof2;
00322   (*Ptr_tree2).n_nodes = 1;
00323   (*Ptr_tree2).max_dist = 0.0;
00324   (*Ptr_tree2).last_max_dist = -1.0;
00325   (*Ptr_tree2).best_father_id = 0;
00326   (*Ptr_tree2).node[0].N_embryos = 0;
00327   (*Ptr_tree2).node[0].father_id = NIL;
00328 
00329 
00330   (*Ptr_tree2).node[0].landmark.dof = goal_conf.dof;            //can't just assign JMA_Configurations
00331   (*Ptr_tree2).node[0].landmark.dist = goal_conf.dist;
00332 
00333 
00334   dist = 0.0;
00335 }
00336                                                                                      
00337 
00338 void PL_RRT_CONNECT::GetIdsPath (JMA_Roadmap_Tree* Ptr_tree1,JMA_Roadmap_Tree* Ptr_tree2, 
00339                                                                  const int landmark_id1, const int landmark_id2, int ids_list1[], 
00340                                                                  int* n_landmarks1, int ids_list2[], int* n_landmarks2)
00341 {
00342   //landmark_id1 and landmark_id2 are the ids of the last landkmark of the two trees.
00343   //and the two trees are connected by the two landmarks
00344 
00345 
00346     int counter=1;
00347         int id;
00348 
00349     id = landmark_id1;
00350     ids_list1[counter-1]=id; 
00351         while (id!=0)
00352         {
00353             id = (*Ptr_tree1).node[id].father_id;         
00354                 ids_list1[counter]=id; 
00355                 ++counter;
00356         }
00357     (*n_landmarks1) = counter;
00358 
00359         counter=1;
00360     id = landmark_id2;
00361     ids_list2[counter-1]=id; 
00362         while (id!=0)
00363         {
00364             id = (*Ptr_tree2).node[id].father_id;         
00365                 ids_list2[counter]=id; 
00366                 ++counter;
00367         }
00368     (*n_landmarks2) = counter;
00369 
00370 
00371 
00372 //...............................................
00373 
00374 // // This function also performs path smothing
00375 //    int counter=1,id1,id2,marker;
00376 //    Configuration ppp1,ppp2;
00377 //    id1 = landmark_id1;
00378  //   ids_list1[counter-1]=id1; 
00379 //      while (id1!=0)
00380 //      {
00381   //      ppp1=(*Ptr_tree1).node[id1].landmark.dof;
00382         //    id1 = (*Ptr_tree1).node[id1].father_id;     
00383         //      marker=1;
00384         //      while (id1 != 0 && marker==1)
00385         //      {
00386         //        id2 = (*Ptr_tree1).node[id1].father_id;
00387         //        ppp2=(*Ptr_tree1).node[id2].landmark.dof;
00388         //              if (!( collisionDetector->IsInterferingLinear(ppp1, ppp2)))
00389         //              {
00390         //                      id1=id2;
00391         //                      marker=1;
00392         //              }
00393         //              else
00394         //                      marker=0;
00395         //      }
00396         //      ids_list1[counter]=id1; 
00397         //      ++counter;
00398 //      }
00399   //  (*n_landmarks1) = counter;
00400 
00401 
00402  //   id1 = landmark_id2;
00403 //      counter=1;
00404   //  ids_list2[counter-1]=id1; 
00405         //while (id1!=0)
00406 //      {
00407   //      ppp1=(*Ptr_tree2).node[id1].landmark.dof;
00408         //    id1 = (*Ptr_tree2).node[id1].father_id;     
00409         //      marker=1;
00410         //      while (id1 != 0 && marker==1)
00411         //      {
00412         //        id2 = (*Ptr_tree2).node[id1].father_id;
00413         //        ppp2=(*Ptr_tree2).node[id2].landmark.dof;
00414         //              if (!( collisionDetector->IsInterferingLinear(ppp1, ppp2)))
00415         //              {
00416         //                      id1=id2;
00417         //                      marker=1;
00418         //              }
00419         //              else
00420         //                      marker=0;
00421         //      }
00422         //      ids_list2[counter]=id1; 
00423         //      ++counter;
00424 //      }
00425   //  (*n_landmarks2) = counter;
00426 //...................................................
00427 }
00428 
00429 
00430 void PL_RRT_CONNECT::SetStart_and_GoalConfig (const Configuration& configuration1,const Configuration& configuration2)
00431 {
00432         init_conf.dof = configuration1 ;
00433         init_conf.dist = 0 ;
00434         goal_conf.dof = configuration2 ;
00435         goal_conf.dist = 0 ;
00436         InitRoadmapTree( &tree1, &tree2, GetStartConfig().DOF(), GetGoalConfig().DOF(), init_conf, goal_conf );
00437 }
00438 
00439 
00440 bool PL_RRT_CONNECT::DrawExplicit () const
00441 {
00442         Semaphore semaphore( this->guid );
00443         semaphore.Lock();
00444 
00445         glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
00446         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00447 
00448         //disable lighting
00449         BOOL lightingState = glIsEnabled( GL_LIGHTING );
00450         glDisable( GL_LIGHTING );
00451 
00452         //disable Z buffering too
00453         BOOL zbufferState = glIsEnabled( GL_DEPTH_TEST );
00454         glDisable( GL_DEPTH_TEST );
00455 
00456         //enable smooth shading too
00457         glShadeModel( GL_SMOOTH );
00458         
00459 
00460         int i = 0;
00461         glColor4d( 1.0, 1.0, 1.0, 1.0 );
00462         glPointSize( 3.0 );
00463 
00464         int dof = this->GetGoalConfig().DOF();
00465 
00466         glColor3f( 1.0f, 1.0f, 0.0f );
00467         glBegin( GL_POINTS );
00468                 double g0 = 0;
00469                 double g1 = 0;
00470                 double g2 = 0;
00471                 double v0 = 0; 
00472                 double v1 = 0; 
00473                 double v2 = 0; 
00474                 double p0 = 0;
00475                 double p1 = 0;
00476                 double p2 = 0;
00477                 if( dof > 0 )
00478                 {
00479                         g0 = this->GetGoalConfig()[ 0 ];
00480                 }
00481                 if( dof > 1 )
00482                 {
00483                         g1 = this->GetGoalConfig()[ 1 ];
00484                 }
00485                 if( dof > 2 )
00486                 {
00487                         g2 = this->GetGoalConfig()[ 2 ];
00488                 }
00489                 glVertex3f( g0, g1, g2 );
00490         glEnd();
00491 
00492         for( i = 0; i < tree1.n_nodes; i++ )
00493         {
00494                 JMA_Node node = tree1.node[ i ];
00495                 JMA_Configuration current = node.landmark;
00496 
00497 
00498                 v0 = current.dof[ 0 ];
00499                 v1 = current.dof[ 1 ];
00500                 if( dof > 2 )
00501                 {
00502                         v2 = current.dof[ 2 ];
00503                 }
00504 
00505                 glBegin( GL_POINTS );
00506                         glVertex3f( v0, v1, 0 );
00507                 glEnd();
00508 
00509                 int parent = node.father_id;
00510                 if( parent == -1 )
00511                 {
00512                 }
00513                 else
00514                 {
00515                         JMA_Node parentNode = tree1.node[ parent ];
00516                         JMA_Configuration parentConfig = parentNode.landmark;
00517 
00518 
00519                         p0 = parentConfig.dof[ 0 ];
00520                         p1 = parentConfig.dof[ 1 ];
00521                         if( dof > 2 )
00522                         {
00523                                 p2 = parentConfig.dof[ 2 ];
00524                         }
00525 
00526                         glColor4d( 1.0, 1.0, 1.0, 1.0 );
00527                         glBegin( GL_LINES );
00528                                 glVertex3f( v0, v1, v2 );
00529                                 glVertex3f( p0, p1, p2 );
00530                         glEnd();
00531                 }
00532 
00533 
00534         }
00535         for( i = 0; i < tree2.n_nodes; i++ )
00536         {
00537                 JMA_Node node = tree2.node[ i ];
00538                 JMA_Configuration current = node.landmark;
00539 
00540 
00541                 v0 = current.dof[ 0 ];
00542                 v1 = current.dof[ 1 ];
00543                 if( dof > 2 )
00544                 {
00545                         v2 = current.dof[ 2 ];
00546                 }
00547 
00548                 glBegin( GL_POINTS );
00549                         glVertex3f( v0, v1, 0 );
00550                 glEnd();
00551 
00552                 int parent = node.father_id;
00553                 if( parent == -1 )
00554                 {
00555                 }
00556                 else
00557                 {
00558                         JMA_Node parentNode = tree2.node[ parent ];
00559                         JMA_Configuration parentConfig = parentNode.landmark;
00560 
00561                         p0 = parentConfig.dof[ 0 ];
00562                         p1 = parentConfig.dof[ 1 ];
00563                         if( dof > 2 )
00564                         {
00565                                 p2 = parentConfig.dof[ 2 ];
00566                         }
00567 
00568                         glColor4d( 1.0, 1.0, 1.0, 1.0 );
00569                         glBegin( GL_LINES );
00570                                 glVertex3f( v0, v1, v2 );
00571                                 glVertex3f( p0, p1, p2 );
00572                         glEnd();
00573                 }
00574 
00575 
00576         }
00577 
00578         
00579         if( lightingState != 0x00 )
00580         {
00581                 glEnable( GL_LIGHTING );
00582         }
00583 
00584         //disable Z buffering too
00585         if( zbufferState )
00586         {
00587                 glEnable( GL_DEPTH_TEST );
00588         }
00589         else
00590         {
00591                 glDisable( GL_DEPTH_TEST );
00592         }
00593 
00594         semaphore.Unlock();
00595         return true;
00596 }

Generated on Sat Apr 1 21:30:45 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO