00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "synchronization/semaphore.h"
00013 #include "PL_PRM.h"
00014 #include "smoothers\SmootherBase.h"
00015
00016 #include <LEDA/node_map.h>
00017 #include <LEDA/node_pq.h>
00018 #include "math/math2.h"
00019 #include <iosfwd>
00020 #include <iostream>
00021
00022
00023
00024
00025 #include "opengl/glos.h"
00026 #include <gl/gl.h>
00027
00028 using std::endl;
00029 using std::istrstream;
00030
00031
00032 static const double DEFAULT_TOL = 0.1;
00033 static const int DEFAULT_INIT_QUANT = 100;
00034 static const int DEFAULT_ENHANCE_QUANT = 50;
00035 static const double DEFAULT_SEED_RATIO = 0.5;
00036 static const int DEFAULTBASECONNECTID = 0;
00037
00038 static const char FILEEXT[] = ".prm";
00039 static const char FILEHEADER[] = "PL_PRM";
00040
00041
00042
00043
00044 PL_PRM::PL_PRM()
00045 {
00046
00047 strcpy( fileext, FILEEXT );
00048 strcpy( fileheader, FILEHEADER );
00049
00050
00051
00052 edgeChecked.init(G,FALSE);
00053 nodeChecked.init(G,FALSE);
00054
00055
00056 uniformlyAdded.init(G,TRUE);
00057
00058
00059 openp = NULL;
00060
00061
00062 baseConnectID = DEFAULTBASECONNECTID;
00063 connectIDp = NULL;
00064
00065
00066 SetRadiusTol( DEFAULT_TOL );
00067 lazyMode = TRUE;
00068 validNodesOnly = FALSE;
00069 validEdgesOnly = FALSE;
00070 useMidPts = FALSE;
00071
00072 initQuant = DEFAULT_INIT_QUANT;
00073 enhanceQuant = DEFAULT_ENHANCE_QUANT;
00074 seedRatio = DEFAULT_SEED_RATIO;
00075
00076
00077 config_seeds.clear();
00078
00079
00080
00081 diagonal_squared = 0;
00082
00083
00084 lastPlanningState = PRM_START;
00085 }
00086
00087
00088 PL_PRM::~PL_PRM()
00089 {
00090
00091 if ( openp != NULL )
00092 {
00093 delete openp;
00094 openp = NULL;
00095 }
00096
00097
00098 if ( connectIDp != NULL )
00099 {
00100 delete connectIDp;
00101 connectIDp = NULL;
00102 }
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 bool PL_PRM::DrawExplicit () const
00115 {
00116
00117 double Xcor, Ycor, Zcor;
00118 node n1;
00119 edge e1;
00120
00121
00122 Semaphore semaphore( this->guid );
00123 semaphore.Lock();
00124
00125
00126 glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
00127 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00128 BOOL lightingState = glIsEnabled( GL_LIGHTING );
00129 glDisable( GL_LIGHTING );
00130
00131
00132
00133
00134 glShadeModel( GL_SMOOTH );
00135
00136
00137
00138
00139
00140
00141 DrawSpecific();
00142
00143
00144
00145 glPointSize(5.0f);
00146
00147
00148 glBegin(GL_POINTS);
00149
00150 if ( startNode != nil )
00151 {
00152 glColor3f(1.0f,1.0f,0.0f);
00153 GetCoords( startNode, Xcor, Ycor, Zcor );
00154 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00155 }
00156
00157
00158 if ( goalNode != nil )
00159 {
00160 glColor3f(0.0f,1.0f,1.0f);
00161 GetCoords( goalNode, Xcor, Ycor, Zcor );
00162 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00163 }
00164 glEnd();
00165
00166
00167 glBegin(GL_POINTS);
00168
00169 forall_nodes( n1, G )
00170 {
00171 if ( ( n1 != startNode ) && ( n1 != goalNode ) )
00172 {
00173 if ( nodeChecked[n1] )
00174 {
00175 if ( uniformlyAdded[n1] )
00176 {
00177
00178 glColor3f(1.0f,0.0f,0.0f);
00179 }
00180 else
00181 {
00182
00183 glColor3f(0.0f,1.0f,0.0f);
00184 }
00185 }
00186 else if ( uniformlyAdded[n1] )
00187 {
00188
00189 glColor3f(0.75f,0.4f,0.0f);
00190 }
00191 else
00192 {
00193
00194 glColor3f(0.0f,0.5f,0.0f);
00195 }
00196
00197 GetCoords( n1, Xcor, Ycor, Zcor );
00198 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00199 }
00200 }
00201 glEnd();
00202
00203
00204
00205
00206
00207 if ( !graphPath.empty() )
00208 {
00209 glLineWidth( 3.0f );
00210 glBegin(GL_LINES);
00211 node n1 = graphPath.tail();
00212
00213
00214
00215 node firstNode = graphPath.head();
00216 while ( n1 != firstNode )
00217 {
00218
00219 GetCoords( n1, Xcor, Ycor, Zcor );
00220 glColor3f(1.0f,0.5f,0.0f);
00221 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00222
00223
00224 n1 = graphPath.pred(n1);
00225
00226
00227 GetCoords( n1, Xcor, Ycor, Zcor );
00228 glColor3f(1.0f,1.0f,0.0f);
00229 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00230
00231
00232
00233
00234 }
00235
00236 glEnd();
00237 }
00238
00239
00240
00241 glLineWidth( 1.0f );
00242 glBegin(GL_LINES);
00243
00244 forall_edges(e1,G)
00245 {
00246 GetCoords( G.source(e1), Xcor, Ycor, Zcor );
00247 if (edgeChecked[e1])
00248 {
00249 glColor3f(0.0f,0.0f,1.0f);
00250 }
00251 else
00252 {
00253 glColor3f(0.0f,0.3f,0.5f);
00254 }
00255 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00256
00257 GetCoords( G.target(e1), Xcor, Ycor, Zcor );
00258 if (edgeChecked[e1])
00259 {
00260 glColor3f(1.0f,1.0f,1.0f);
00261 }
00262 else
00263 {
00264 glColor3f(0.5f,0.5f,0.5f);
00265 }
00266 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00267 }
00268 glEnd();
00269
00270
00271 if( lightingState != FALSE )
00272 {
00273 glEnable( GL_LIGHTING );
00274 }
00275
00276
00277 semaphore.Unlock();
00278 Sleep( 15 );
00279
00280 return true;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 bool PL_PRM::LoadContents( std::ifstream& infile )
00293 {
00294
00295 bool success = PL_GraphBase::LoadContents( infile );
00296 if ( !success )
00297 {
00298 return false;
00299 }
00300
00301
00302 infile >> radiusTol;
00303 infile >> initQuant >> enhanceQuant >> seedRatio;
00304 infile >> lazyMode >> validNodesOnly >> validEdgesOnly >> useMidPts;
00305
00306
00307
00308
00309
00310 if ( !lazyMode )
00311 {
00312
00313 infile >> baseConnectID;
00314
00315 if ( connectIDp != NULL )
00316 {
00317 delete connectIDp;
00318 }
00319 connectIDp = new node_map<int>(G);
00320 }
00321 else
00322 {
00323
00324 baseConnectID = DEFAULTBASECONNECTID;
00325 if ( connectIDp != NULL )
00326 {
00327 delete connectIDp;
00328 connectIDp = NULL;
00329 }
00330 }
00331
00332
00333
00334 node n0;
00335 forall_nodes( n0, G )
00336 {
00337 int nodeID;
00338 infile >> nodeID;
00339 infile >> nodeChecked[n0] >> uniformlyAdded[n0];
00340
00341 if ( !lazyMode )
00342 {
00343
00344 infile >> (*connectIDp)[n0];
00345 }
00346 }
00347
00348
00349 int id;
00350 infile >> id;
00351 if ( id != NIL_ID )
00352 {
00353
00354 MessageBox( NULL, "Node and Edge information do not align with current Graph.", "ERROR", MB_OK );
00355 return false;
00356 }
00357
00358
00359 edge e1;
00360 forall_edges( e1, G )
00361 {
00362 int edgeID;
00363 infile >> edgeID;
00364 infile >> edgeChecked[e1];
00365 }
00366
00367
00368 lastPlanningState = PRM_START;
00369
00370 return true;
00371
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 bool PL_PRM::SaveContents ( std::ofstream& outfile ) const
00383 {
00384
00385 bool success = PL_GraphBase::SaveContents( outfile );
00386 if ( !success )
00387 {
00388 return false;
00389 }
00390
00391
00392 outfile << radiusTol << endl;
00393 outfile << initQuant << " " << enhanceQuant << " " << seedRatio << endl;
00394 outfile << lazyMode << " " << validNodesOnly << " " << validEdgesOnly << " " << useMidPts << endl;
00395
00396
00397
00398
00399 if ( !lazyMode )
00400 {
00401 outfile << baseConnectID << endl;
00402 }
00403
00404
00405 node n1;
00406 forall_nodes( n1, G )
00407 {
00408 outfile << n1->id() << " " << nodeChecked[n1] << " " << uniformlyAdded[n1];
00409
00410
00411 if ( !lazyMode )
00412 {
00413 outfile << " " << (*connectIDp)[n1];
00414 }
00415
00416
00417 outfile << endl;
00418
00419 }
00420
00421
00422 outfile << NIL_ID << endl;
00423
00424
00425 edge e1;
00426 forall_edges( e1, G )
00427 {
00428 outfile << e1->id() << " " << edgeChecked[e1] << endl;
00429 }
00430
00431
00432
00433 return true;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 bool PL_PRM::Plan ()
00446 {
00447 srand( (unsigned)time( NULL ) );
00448
00449 PRM_StateMachineType currentState = lastPlanningState;
00450
00451
00452
00453 if ( lastPlanningState == PRM_FAILURE )
00454 {
00455 currentState = PRM_START;
00456 }
00457
00458
00459 StartTimer();
00460
00461
00462 Semaphore semaphore( guid );
00463 if( this->m_UseSemaphores == true )
00464 {
00465 semaphore.Lock();
00466 }
00467
00468
00469
00470 if ( (currentState != PRM_DONE ) && (currentState != PRM_FAILURE) )
00471 {
00472 if ( startNode == goalNode )
00473 {
00474
00475 currentState = PRM_DONE;
00476
00477
00478 path.Clear();
00479 path.AppendPoint( GetStartConfig() );
00480 }
00481 else if ( (IsInterfering(startNode)) || (IsInterfering(goalNode)) )
00482 {
00483
00484
00485 currentState = PRM_FAILURE;
00486 }
00487 }
00488 if( this->m_UseSemaphores == true )
00489 {
00490 semaphore.Unlock();
00491 }
00492
00493
00494 diagonal_squared = GetCspaceRange();
00495
00496
00497 while (( currentState != PRM_DONE ) && ( currentState != PRM_FAILURE ))
00498
00499 {
00500 SuccessResultType success;
00501
00502 if( this->m_UseSemaphores == true )
00503 {
00504 semaphore.Lock();
00505 }
00506
00507 switch ( currentState )
00508 {
00509 case PRM_BUILD_INIT_ROADMAP :
00510 success = BuildInitRoadMap();
00511 break;
00512 case PRM_FIND_PATH :
00513 success = FindPath();
00514 break;
00515 case PRM_VERIFY_PATH :
00516 success = VerifyPath();
00517 break;
00518 case PRM_TRANSLATE_PATH :
00519 success = TranslatePath();
00520 break;
00521 case PRM_ENHANCE_ROADMAP :
00522 success = EnhanceRoadMap();
00523 break;
00524 default :
00525
00526
00527 success = PASS;
00528 }
00529
00530
00531
00532 if ( success == TIMER_EXPIRED )
00533 {
00534
00535 break;
00536 }
00537
00538
00539 switch ( currentState )
00540 {
00541 case PRM_START :
00542
00543 currentState = PRM_BUILD_INIT_ROADMAP;
00544 break;
00545 case PRM_BUILD_INIT_ROADMAP :
00546
00547 currentState = PRM_FIND_PATH;
00548 break;
00549 case PRM_FIND_PATH :
00550 if ( success == PASS )
00551 {
00552
00553 currentState = PRM_VERIFY_PATH;
00554 }
00555 else
00556 {
00557
00558 currentState = PRM_ENHANCE_ROADMAP;
00559
00560
00561 }
00562 break;
00563 case PRM_VERIFY_PATH :
00564 if ( success == PASS )
00565 {
00566
00567
00568 currentState = PRM_TRANSLATE_PATH;
00569 }
00570 else
00571 {
00572
00573
00574 currentState = PRM_FIND_PATH;
00575 }
00576 break;
00577 case PRM_TRANSLATE_PATH :
00578
00579 currentState = PRM_DONE;
00580 break;
00581 case PRM_ENHANCE_ROADMAP :
00582
00583 currentState = PRM_FIND_PATH;
00584 break;
00585 default :
00586
00587 ASSERT( FALSE );
00588 }
00589
00590
00591 if( this->m_UseSemaphores == true )
00592 {
00593 semaphore.Unlock();
00594 }
00595 }
00596
00597
00598
00599 lastPlanningState = currentState;
00600
00601
00602 if ( currentState == PRM_DONE )
00603 {
00604
00605
00606
00607 if( this->m_UseSemaphores == true )
00608 {
00609 semaphore.Unlock();
00610 }
00611
00612
00613 if( m_Smoother != NULL )
00614 {
00615 this->m_Smoother->SetPath( &this->path );
00616 this->m_Smoother->SetCollisionDetector( this->collisionDetector );
00617 m_Smoother->Smooth();
00618 this->path = m_Smoother->GetPath();
00619 m_Smoother->SetPath( NULL );
00620 }
00621
00622 return true;
00623 }
00624 else
00625 {
00626
00627 graphPath.clear();
00628
00629
00630 path.Clear();
00631 path.AppendPoint( GetStartConfig() );
00632
00633
00634 if( this->m_UseSemaphores == true )
00635 {
00636 semaphore.Unlock();
00637 }
00638
00639 return false;
00640 }
00641
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651 void PL_PRM::SetRadiusTol( double tol )
00652 {
00653
00654 radiusTol = tol;
00655
00656 }
00657
00658
00659
00660
00661
00662
00663
00664 double PL_PRM::GetRadiusTol()
00665 {
00666
00667 return radiusTol;
00668 }
00669
00670
00671
00672
00673
00674
00675 void PL_PRM::SetPRMMode ( BOOL& isLazy, BOOL& validNodes, BOOL& validEdges )
00676 {
00677
00678
00679
00680
00681
00682 if ( lazyMode != isLazy )
00683 {
00684
00685 if ( !isLazy )
00686 {
00687
00688 validNodes = TRUE;
00689 validEdges = TRUE;
00690 }
00691 }
00692 else
00693 {
00694
00695 if ( (!validNodes) || (!validEdges) )
00696 {
00697 isLazy = TRUE;
00698 }
00699 }
00700
00701
00702 if ( lazyMode != isLazy )
00703 {
00704
00705 SetGraphMode( !isLazy );
00706 }
00707
00708
00709 lazyMode = isLazy;
00710 validNodesOnly = validNodes;
00711 validEdgesOnly = validEdges;
00712
00713 }
00714
00715
00716
00717
00718
00719
00720
00721 void PL_PRM::GetPRMMode ( BOOL& isLazy, BOOL& validNodes, BOOL& validEdges ) const
00722 {
00723
00724 isLazy = lazyMode;
00725 validNodes = validNodesOnly;
00726 validEdges = validEdgesOnly;
00727
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 void PL_PRM::SetCollisionDetector (CD_BasicStyle* collisionDetector)
00737 {
00738
00739 PL_GraphBase::SetCollisionDetector( collisionDetector );
00740
00741
00742 diagonal_squared = GetCspaceRange();
00743
00744
00745 }
00746
00747
00748
00749
00750
00751
00752
00753 void PL_PRM::SetStartConfig( const Configuration& config )
00754 {
00755
00756 if (( GetStartConfig() == config ) && ( startNode != nil ) )
00757 {
00758
00759 return;
00760 }
00761
00762
00763
00764 PL_GraphBase::SetStartConfig( config );
00765
00766
00767 ASSERT( startNode != nil );
00768
00769
00770
00771 if ( G.degree( startNode ) < 1 )
00772 {
00773
00774 ConnectNode( startNode );
00775 }
00776
00777
00778
00779 lastPlanningState = PRM_START;
00780
00781 }
00782
00783
00784
00785
00786
00787
00788
00789 void PL_PRM::SetGoalConfig( const Configuration& config )
00790 {
00791
00792 if (( GetGoalConfig() == config ) && ( goalNode != nil ))
00793 {
00794
00795 return;
00796 }
00797
00798
00799
00800 PL_GraphBase::SetGoalConfig( config );
00801
00802
00803 ASSERT( goalNode != nil );
00804
00805
00806
00807 if ( G.degree( goalNode ) < 1 )
00808 {
00809
00810 ConnectNode( goalNode );
00811 }
00812
00813
00814
00815 lastPlanningState = PRM_START;
00816
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 void PL_PRM::SetGraphMode ( const bool& treeGraph )
00831 {
00832 if ( treeGraph )
00833
00834 {
00835
00836 ClearGraph();
00837
00838
00839 baseConnectID = DEFAULTBASECONNECTID;
00840 if ( connectIDp != NULL )
00841 {
00842 delete connectIDp;
00843 }
00844 connectIDp = new node_map<int>(G,0);
00845 }
00846
00847 else {
00848
00849 if ( connectIDp != NULL )
00850 {
00851 delete connectIDp;
00852 connectIDp = NULL;
00853 }
00854
00855 baseConnectID = DEFAULTBASECONNECTID;
00856 }
00857
00858
00859 }
00860
00861
00862
00863
00864
00865
00866
00867 bool PL_PRM::NodeInConnectionList( const node& n1, const list<int>& connectIDs)
00868 {
00869 if ( connectIDp == NULL )
00870 {
00871 return false;
00872 }
00873
00874 int id;
00875
00876 forall( id, connectIDs )
00877 {
00878 if ( (*connectIDp)[n1] == id )
00879 {
00880 return true;
00881 }
00882 }
00883
00884
00885 return false;
00886
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896 BOOL PL_PRM::AddNode()
00897 {
00898 Configuration newConfig;
00899
00900 bool validConfig = FALSE;
00901 while ( !validConfig )
00902 {
00903 newConfig = GenerateRandomConfig();
00904
00905 if ( validNodesOnly )
00906
00907 {
00908
00909 if ( IsInterfering( newConfig ) )
00910 {
00911 validConfig = FALSE;
00912
00913
00914 config_seeds.append( newConfig );
00915 }
00916 else
00917 {
00918 validConfig = TRUE;
00919 }
00920 }
00921 else
00922 {
00923
00924 validConfig = TRUE;
00925 }
00926
00927 if ( HasTimeLimitExpired() )
00928 {
00929 return FALSE;
00930 }
00931 }
00932
00933
00934 node newNode = G.new_node( newConfig );
00935
00936 if (newNode != nil)
00937 {
00938
00939 nodeChecked[newNode] = validNodesOnly;
00940
00941
00942 uniformlyAdded[newNode] = TRUE;
00943
00944
00945 ConnectNode( newNode );
00946
00947 return TRUE;
00948 }
00949 else
00950 {
00951 return FALSE;
00952 }
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 void PL_PRM::ConnectNode( const node& newnode )
00965 {
00966 if ( lazyMode )
00967 {
00968
00969
00970
00971 ConnectEdgesLazy( newnode, radiusTol*radiusTol*diagonal_squared );
00972 }
00973 else
00974 {
00975
00976 ConnectEdgesFull( newnode, radiusTol*radiusTol*diagonal_squared );
00977 }
00978
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 void PL_PRM::ConnectEdgesLazy( const node& newnode, const double& radius_squared )
00990 {
00991
00992 Configuration nodeconfig = G.inf(newnode);
00993
00994
00995 node testnode;
00996 forall_nodes( testnode, G )
00997 {
00998 if ( newnode != testnode)
00999 {
01000 double edgelength_squared = Distance( nodeconfig, G.inf(testnode) );
01001
01002 if ( edgelength_squared <= radius_squared )
01003 {
01004 bool addedge = TRUE;
01005
01006
01007 if ( validEdgesOnly )
01008 {
01009 if ( IsInterfering( nodeconfig, G.inf(testnode) ) )
01010 {
01011 addedge = FALSE;
01012
01013
01014 if ( useMidPts )
01015 {
01016 Configuration midpt = GetMidPoint( nodeconfig, G.inf(testnode) );
01017 config_seeds.append( midpt );
01018 }
01019 }
01020 }
01021
01022 if ( addedge )
01023 {
01024
01025 double edgelength = sqrt( edgelength_squared );
01026 edge newedge = G.new_edge ( newnode, testnode, edgelength );
01027
01028
01029 edgeChecked[newedge] = validEdgesOnly;
01030 }
01031 }
01032 }
01033 }
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047 void PL_PRM::ConnectEdgesFull(const node& newnode, const double& radius_squared)
01048 {
01049
01050 ASSERT( connectIDp != NULL );
01051
01052
01053 Configuration nodeconfig = G.inf(newnode);
01054
01055 node n1;
01056
01057
01058 node_pq<double> neighbours(G);
01059 forall_nodes( n1, G)
01060 {
01061 if ( newnode != n1)
01062 {
01063 double edgelength_squared = Distance( nodeconfig, G.inf(n1) );
01064
01065 if ( edgelength_squared <= radius_squared )
01066 {
01067
01068 neighbours.insert( n1, edgelength_squared );
01069 }
01070 }
01071 }
01072
01073
01074 (*connectIDp)[newnode] = NIL_ID;
01075
01076
01077 list<int> connectIDs;
01078
01079
01080
01081 while ( !neighbours.empty() )
01082 {
01083
01084 node neighbour = neighbours.find_min();
01085 double dist_sq = neighbours.inf( neighbour );
01086 neighbours.del( neighbour );
01087
01088
01089
01090
01091 if ( ((*connectIDp)[neighbour] == NIL_ID) ||
01092 ( ((*connectIDp)[neighbour] != (*connectIDp)[newnode]) &&
01093 ( !NodeInConnectionList(neighbour, connectIDs) ) )
01094 )
01095 {
01096
01097 if ( !IsInterfering( nodeconfig, G.inf(neighbour) ) )
01098 {
01099 double edgelength = sqrt( dist_sq );
01100 edge newedge = G.new_edge( newnode, neighbour, edgelength );
01101 edgeChecked[newedge] = TRUE;
01102
01103
01104 if ( (*connectIDp)[neighbour] != NIL_ID )
01105
01106 {
01107 if ( (*connectIDp)[newnode] == NIL_ID )
01108 {
01109
01110 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
01111 }
01112 else if ( (*connectIDp)[neighbour] < (*connectIDp)[newnode] )
01113 {
01114
01115
01116
01117
01118 connectIDs.push( (*connectIDp)[newnode] );
01119
01120
01121 (*connectIDp)[newnode] = (*connectIDp)[neighbour];
01122 }
01123 else
01124 {
01125
01126
01127
01128 connectIDs.push( (*connectIDp)[neighbour] );
01129
01130
01131 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
01132 }
01133 }
01134 else
01135
01136 {
01137 if ( (*connectIDp)[newnode] != NIL_ID )
01138 {
01139
01140 (*connectIDp)[neighbour] = (*connectIDp)[newnode];
01141 }
01142 else
01143 {
01144
01145
01146 (*connectIDp)[newnode] = baseConnectID;
01147 (*connectIDp)[neighbour] = baseConnectID;
01148
01149
01150 baseConnectID++;
01151 }
01152 }
01153
01154 }
01155 else
01156 {
01157
01158
01159 if ( useMidPts )
01160 {
01161 Configuration midpt = GetMidPoint( nodeconfig, G.inf(neighbour) );
01162 config_seeds.append( midpt );
01163 }
01164 }
01165
01166 }
01167
01168 }
01169
01170
01171
01172 if ( ((*connectIDp)[newnode] != NIL_ID) && ( !connectIDs.empty() ) )
01173 {
01174
01175
01176 int newID = (*connectIDp)[newnode];
01177
01178 forall_nodes( n1, G )
01179 {
01180 if ( ((*connectIDp)[n1] != newID ) && (NodeInConnectionList( n1, connectIDs )) )
01181 {
01182 (*connectIDp)[n1] = newID;
01183 }
01184 }
01185 }
01186
01187
01188 return;
01189 }
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 SuccessResultType PL_PRM::BuildInitRoadMap()
01201 {
01202
01203 for (int i = NodeCount(); i < initQuant; i++ )
01204 {
01205
01206 AddNode();
01207
01208
01209 if ( HasTimeLimitExpired() )
01210 {
01211 return TIMER_EXPIRED;
01212 }
01213
01214 }
01215
01216 return PASS;
01217 }
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 SuccessResultType PL_PRM::FindPath()
01229 {
01230
01231
01232 node n1;
01233
01234
01235
01236 graphPath.clear();
01237
01238
01239
01240 if ( lastPlanningState != PRM_FIND_PATH )
01241
01242 {
01243
01244 pred.init(G,nil);
01245 dist.init(G,0);
01246
01247
01248 dist[startNode] = 0;
01249
01250
01251 if ( openp != NULL )
01252 {
01253 delete openp;
01254 }
01255 openp = new node_pq<double>(G);
01256 openp->clear();
01257
01258
01259 openp->insert(startNode,0);
01260 }
01261 else
01262
01263 {
01264
01265
01266 lastPlanningState = PRM_TIMER_EXPIRED;
01267
01268 }
01269
01270
01271
01272 while ( !openp->empty() )
01273 {
01274
01275 if ( HasTimeLimitExpired() )
01276 {
01277
01278
01279
01280
01281
01282 return TIMER_EXPIRED;
01283 }
01284
01285
01286 n1 = openp->del_min();
01287
01288
01289 if ( n1 == goalNode )
01290
01291 {
01292
01293 graphPath.clear();
01294 graphPath.push( n1 );
01295
01296
01297
01298 while ( n1 != startNode )
01299 {
01300 node n0 = pred[n1];
01301
01302
01303 graphPath.push( n0 );
01304
01305
01306 n1 = n0;
01307 }
01308
01309
01310 delete openp;
01311 openp = NULL;
01312
01313
01314 return PASS;
01315
01316 }
01317 else
01318 {
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328 node n2;
01329 edge e1;
01330
01331
01332 forall_inout_edges(e1, n1)
01333 {
01334
01335
01336
01337
01338 n2 = G.source(e1);
01339 if ( n2 == n1)
01340 {
01341
01342 n2 = G.target(e1);
01343 }
01344
01345
01346 if ( ( pred[n2] == nil ) && ( n2 != startNode ) )
01347 {
01348
01349 pred[n2] = n1;
01350
01351
01352 dist[n2] = dist[n1] + G.inf(e1);
01353
01354
01355 openp->insert( n2, Astar_f(n2, dist[n2]) );
01356 }
01357 else
01358 {
01359
01360 double currcost = dist[n2];
01361 double newcost = dist[n1] + G.inf(e1);
01362
01363
01364 if ( newcost < currcost )
01365 {
01366
01367 pred[n2] = n1;
01368
01369
01370 dist[n2] = newcost;
01371
01372
01373 double priority = Astar_f(n2, dist[n2]);
01374
01375
01376 if ( openp->member(n2) )
01377 {
01378
01379 openp->decrease_p( n2, priority );
01380 }
01381 else
01382 {
01383
01384 openp->insert( n2, priority );
01385 }
01386 }
01387 }
01388 }
01389
01390 }
01391
01392
01393 }
01394
01395
01396 delete openp;
01397 openp = NULL;
01398
01399
01400 return FAIL;
01401 }
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413 SuccessResultType PL_PRM::VerifyPath()
01414 {
01415
01416
01417
01418 if ( graphPath.empty() )
01419 {
01420
01421 return FAIL;
01422 }
01423
01424
01425 node n0 = graphPath.head();
01426 node n1 = graphPath.tail();
01427
01428
01429 while ( TRUE )
01430 {
01431
01432 if ( HasTimeLimitExpired() )
01433 {
01434 return TIMER_EXPIRED;
01435 }
01436
01437 if (!nodeChecked[n0])
01438 {
01439
01440 if ( IsInterfering( n0 ) )
01441 {
01442
01443
01444 if ( uniformlyAdded[n0] )
01445 {
01446 Configuration midpoint = GetMidPoint( G.inf(n0), G.inf( graphPath.cyclic_pred( n0 ) ) );
01447 config_seeds.append( midpoint );
01448 }
01449
01450
01451 G.del_node( n0 );
01452
01453
01454 return FAIL;
01455 }
01456 else
01457 {
01458
01459 nodeChecked[n0] = TRUE;
01460 }
01461
01462 }
01463
01464
01465 if ( n0 == n1 )
01466 {
01467 break;
01468 }
01469
01470 if (!nodeChecked[n1])
01471 {
01472
01473 if ( IsInterfering( n1 ) )
01474 {
01475
01476
01477 if ( uniformlyAdded[n1] )
01478 {
01479 Configuration midpoint = GetMidPoint( G.inf(n1), G.inf( graphPath.cyclic_succ( n1 ) ) );
01480 config_seeds.append( midpoint );
01481 }
01482
01483
01484 G.del_node( n1 );
01485
01486
01487 return FAIL;
01488 }
01489 else
01490 {
01491
01492 nodeChecked[n1] = TRUE;
01493 }
01494 }
01495
01496
01497 n0 = graphPath.succ( n0 );
01498
01499
01500 if ( n0 == n1 )
01501 {
01502 break;
01503 }
01504
01505 n1 = graphPath.pred( n1 );
01506
01507 }
01508
01509
01510
01511
01512
01513
01514
01515 node front0 = graphPath.head();
01516 node front1 = graphPath.succ( front0 );
01517
01518
01519 node back1 = graphPath.tail();
01520 node back0 = graphPath.pred( back1 );
01521
01522 while ( TRUE )
01523 {
01524
01525 if ( HasTimeLimitExpired() )
01526 {
01527 return TIMER_EXPIRED;
01528 }
01529
01530
01531 edge e0 = FindEdge( front0, front1 );
01532 if ( e0 == nil )
01533 {
01534
01535 return FAIL;
01536 }
01537
01538
01539 if ( !edgeChecked[e0] )
01540 {
01541
01542 if ( IsInterfering( e0 ) )
01543 {
01544
01545
01546 if ( (useMidPts) && ( uniformlyAdded[front1] ) )
01547 {
01548 Configuration midpt = GetMidPoint( G.inf(front0), G.inf(front1) );
01549 config_seeds.append( midpt );
01550 }
01551
01552
01553 G.del_edge( e0 );
01554
01555
01556 return FAIL;
01557 }
01558 else
01559 {
01560
01561 edgeChecked[e0] = TRUE;
01562 }
01563 }
01564
01565
01566 if ( front1 == back1 )
01567 {
01568
01569 break;
01570 }
01571
01572
01573 e0 = FindEdge( back0, back1 );
01574 if ( e0 == nil )
01575 {
01576
01577 return FAIL;
01578 }
01579
01580
01581 if ( !edgeChecked[e0] )
01582 {
01583
01584 if ( IsInterfering( e0 ) )
01585 {
01586
01587
01588 if ( (useMidPts) && ( uniformlyAdded[back0] ) )
01589 {
01590 Configuration midpt = GetMidPoint( G.inf(back1), G.inf(back0) );
01591 config_seeds.append( midpt );
01592 }
01593
01594
01595 G.del_edge( e0 );
01596
01597
01598 return FAIL;
01599 }
01600 else
01601 {
01602
01603 edgeChecked[e0] = TRUE;
01604 }
01605 }
01606
01607
01608 front0 = front1;
01609 front1 = graphPath.succ( front1 );
01610
01611
01612
01613 if ( front1 == back1 )
01614 {
01615
01616 break;
01617 }
01618
01619 back1 = back0;
01620 back0 = graphPath.pred( back0 );
01621
01622 }
01623
01624
01625
01626 return PASS;
01627 }
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640 SuccessResultType PL_PRM::EnhanceRoadMap()
01641 {
01642
01643
01644
01645
01646
01647 int uniformQuant = enhanceQuant;
01648
01649 if ( !config_seeds.empty() )
01650 {
01651
01652 int seedQuant = double(enhanceQuant * seedRatio);
01653 uniformQuant = enhanceQuant - seedQuant;
01654
01655
01656
01657 list_item seedindex = config_seeds.first();
01658
01659
01660
01661 double std_dev = 0.5 * radiusTol * sqrt( diagonal_squared );
01662
01663 for ( int i = 0; i < seedQuant; i++ )
01664 {
01665
01666 Configuration newConfig;
01667
01668 bool validConfig = FALSE;
01669 while (!validConfig)
01670 {
01671 newConfig = GenerateRandomConfig( config_seeds.inf( seedindex ), std_dev );
01672
01673
01674 if ( (validNodesOnly) && (IsInterfering( newConfig )) )
01675
01676 {
01677 validConfig = FALSE;
01678 }
01679 else
01680 {
01681 validConfig = TRUE;
01682 }
01683 }
01684
01685 node newNode = G.new_node( newConfig );
01686
01687 ASSERT ( newNode != nil );
01688
01689
01690 nodeChecked[newNode] = validNodesOnly;
01691
01692
01693 uniformlyAdded[newNode] = FALSE;
01694
01695
01696 ConnectNode( newNode );
01697
01698
01699 if ( HasTimeLimitExpired() )
01700 {
01701 return TIMER_EXPIRED;
01702 }
01703
01704
01705 seedindex = config_seeds.cyclic_succ( seedindex );
01706
01707
01708
01709
01710
01711
01712 }
01713
01714
01715 config_seeds.clear();
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732 }
01733
01734
01735
01736 for (int i = 0; i < uniformQuant; i++ )
01737 {
01738
01739 AddNode();
01740
01741
01742 if ( HasTimeLimitExpired() )
01743 {
01744 return TIMER_EXPIRED;
01745 }
01746
01747 }
01748
01749
01750
01751 return PASS;
01752 }
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762 double PL_PRM::Astar_f( const node& n, const double& currcost ) const
01763 {
01764 return currcost + sqrt(Distance( n, goalNode ));
01765 }
01766
01767
01768
01769
01770
01771
01772 void PL_PRM::CopySettings( PlannerBase* original )
01773 {
01774 PL_GraphBase::CopySettings( original );
01775 PL_PRM* originalPrm = dynamic_cast< PL_PRM* >( original );
01776 if( originalPrm == NULL )
01777 {
01778 return;
01779 }
01780 this->validEdgesOnly = originalPrm->validEdgesOnly;
01781 this->validNodesOnly = originalPrm->validNodesOnly;
01782 this->seedRatio = originalPrm->seedRatio;
01783 this->radiusTol = originalPrm->radiusTol;
01784 this->useMidPts = originalPrm->useMidPts;
01785 this->initQuant = originalPrm->initQuant;
01786 this->enhanceQuant = originalPrm->enhanceQuant;
01787 this->lazyMode = originalPrm->lazyMode;
01788
01789
01790 SetGraphMode( !lazyMode );
01791 }
01792
01793
01794 void *PL_PRM::GetParameters()
01795 {
01796 PL_GraphBase::GetParameters();
01797
01798
01799
01800 char szLine[255];
01801
01802
01803 int bufferLen = 0;
01804 sprintf(szLine, "Validate Edges Only: %d\n", validEdgesOnly);
01805 bufferLen += strlen(szLine);
01806 sprintf(szLine, "Validate Nodes Only: %d\n", validNodesOnly);
01807 bufferLen += strlen(szLine);
01808 sprintf(szLine, "Use Middle Points: %d\n", useMidPts);
01809 bufferLen += strlen(szLine);
01810 sprintf(szLine, "Use Lazy Mode: %d\n", lazyMode);
01811 bufferLen += strlen(szLine);
01812 sprintf(szLine, "Initial Quantity: %d\n", initQuant);
01813 bufferLen += strlen(szLine);
01814 sprintf(szLine, "Enhance Quantity: %d\n", enhanceQuant);
01815 bufferLen += strlen(szLine);
01816 sprintf(szLine, "Seed Ratio: %f\n", seedRatio);
01817 bufferLen += strlen(szLine);
01818 sprintf(szLine, "Radius Tolerance: %f\n", radiusTol);
01819 bufferLen += strlen(szLine);
01820
01821
01822 bufferLen += 100;
01823 if (paramBuffer != NULL)
01824 bufferLen += strlen(paramBuffer);
01825 if (bufferLen > sizeOfParameterBuffer)
01826 {
01827 char *pNewBuffer = (char *)malloc(bufferLen);
01828 if (pNewBuffer)
01829 {
01830 memset(pNewBuffer, 0, bufferLen);
01831 if (paramBuffer)
01832 {
01833 strcpy(pNewBuffer, paramBuffer);
01834 delete paramBuffer;
01835 }
01836 paramBuffer = pNewBuffer;
01837 sizeOfParameterBuffer = bufferLen;
01838 }
01839 else
01840 {
01841 return paramBuffer;
01842 }
01843 }
01844
01845
01846 sprintf(szLine, "Validate Edges Only: %d\n", validEdgesOnly);
01847 strcat(paramBuffer, szLine);
01848 sprintf(szLine, "Validate Nodes Only: %d\n", validNodesOnly);
01849 strcat(paramBuffer, szLine);
01850 sprintf(szLine, "Use Middle Points: %d\n", useMidPts);
01851 strcat(paramBuffer, szLine);
01852 sprintf(szLine, "Use Lazy Mode: %d\n", lazyMode);
01853 strcat(paramBuffer, szLine);
01854 sprintf(szLine, "Initial Quantity: %d\n", initQuant);
01855 strcat(paramBuffer, szLine);
01856 sprintf(szLine, "Enhance Quantity: %d\n", enhanceQuant);
01857 strcat(paramBuffer, szLine);
01858 sprintf(szLine, "Seed Ratio: %f\n", seedRatio);
01859 strcat(paramBuffer, szLine);
01860 sprintf(szLine, "Radius Tolerance: %f\n", radiusTol);
01861 strcat(paramBuffer, szLine);
01862
01863 return paramBuffer;
01864 }
01865
01866 bool PL_PRM::SetParameters(const void *param)
01867 {
01868 if (PL_GraphBase::SetParameters(param)==false)
01869 return false;
01870
01871 istrstream paramStream(paramBuffer);
01872 char szLine[255];
01873 while (!paramStream.eof())
01874 {
01875 paramStream.getline(szLine, 255);
01876 _strlwr(szLine);
01877 char *pValue = strchr(szLine, ':');
01878 if (pValue == NULL)
01879 {
01880 pValue = szLine;
01881
01882 while(*pValue==' ')
01883 pValue++;
01884
01885
01886 if (strlen(pValue) != 0)
01887 return false;
01888 else
01889 break;
01890 }
01891 else
01892 {
01893 pValue += 1;
01894 }
01895
01896 if (strstr(szLine, "validate edges only"))
01897 {
01898 validEdgesOnly = atoi(pValue);
01899 }
01900 else if (strstr(szLine, "validate nodes only"))
01901 {
01902 validNodesOnly = atoi(pValue);
01903 }
01904 else if (strstr(szLine, "use middle points"))
01905 {
01906 useMidPts = atoi(pValue);
01907 }
01908 else if (strstr(szLine, "use lazy mode"))
01909 {
01910 lazyMode = atoi(pValue);
01911 }
01912 else if (strstr(szLine, "initial quantity"))
01913 {
01914 initQuant = atoi(pValue);
01915 }
01916 else if (strstr(szLine, "enhance quantity"))
01917 {
01918 enhanceQuant = atoi(pValue);
01919 }
01920 else if (strstr(szLine, "seed ratio"))
01921 {
01922 seedRatio = atof(pValue);
01923 }
01924 else if (strstr(szLine, "radius tolerance"))
01925 {
01926 radiusTol = atof(pValue);
01927 }
01928 }
01929 return true;
01930 }
01931
01932 bool PL_PRM::ValidateParameters()
01933 {
01934 return true;
01935 }
01936