00001 #pragma warning( disable : 4786 )
00002
00003 #include <synchronization/semaphore.h>
00004 #include <algorithm>
00005 #include "CollisionDetectors/CD_Bool.h"
00006 #include "color/colorf.h"
00007 #include "debug/debug.h"
00008 #include "math/astar.h"
00009 #include "PL_PrmIjg.h"
00010 #include <gl\gl.h>
00011 #include "smoothers\SmootherBase.h"
00012
00013 PL_PrmIjg::PL_PrmIjg():
00014 m_PlanComplete( false ),
00015 m_NumberOfTimesContinued( 0 )
00016 {
00017 m_Graphs.reserve( 10000 );
00018 }
00019
00020 PL_PrmIjg::~PL_PrmIjg()
00021 {
00022 }
00023
00024
00025
00026
00027
00028
00029 bool PL_PrmIjg::AddNodeToGraph( const int graphNum, const Configuration& config )
00030 {
00031 bool configInCollision = collisionDetector->IsInterfering( config );
00032 bool graphInCollision = !m_GraphInFreeSpace[ graphNum ];
00033 if( configInCollision != graphInCollision )
00034 {
00035 return false;
00036 }
00037
00038
00039
00040
00041 PrmGraph& graph = m_Graphs[ graphNum ];
00042
00043
00044
00045
00046 int closestNode = -1;
00047 double closestNodeValue = 9999999999;
00048 unsigned size = graph.GetNumNodes();
00049 unsigned i;
00050 for( i = 0; i < size; ++i )
00051 {
00052 const Configuration& c = graph.GetNodeData( i );
00053 double distance = ( c - config ).MagSquared();
00054 if( distance < closestNodeValue )
00055 {
00056 closestNodeValue = distance;
00057 closestNode = i;
00058 }
00059 }
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 if( closestNode != -1 )
00112 {
00113 Configuration closestConfig = graph.GetNodeData( closestNode );
00114 IJG_Assert( config.DOF() != 0 );
00115 IJG_Assert( closestConfig.DOF() != 0 );
00116
00117 if( graphInCollision )
00118 {
00119 bool completelyInCollision = collisionDetector->IsCompletelyWithinObstacles( config, closestConfig );
00120 if( completelyInCollision )
00121 {
00122 int nodeNum = graph.AddNode( config );
00123 graph.AddEdge( nodeNum, closestNode );
00124 return true;
00125 }
00126 }
00127
00128 if( !graphInCollision )
00129 {
00130 bool completelyFree = !collisionDetector->IsInterferingLinear( config, closestConfig );
00131 if( completelyFree )
00132 {
00133 int nodeNum = graph.AddNode( config );
00134 graph.AddEdge( nodeNum, closestNode );
00135 return true;
00136 }
00137 }
00138 }
00139 return false;
00140 }
00141
00142
00143
00144
00145
00146
00147 int PL_PrmIjg::CreateNewGraph( const Configuration& config )
00148 {
00149
00150
00151
00152 int currentSize = m_Graphs.size();
00153 m_Graphs.resize( currentSize + 1 );
00154 int size = currentSize + 1;
00155 PrmGraph& graph = m_Graphs[ size - 1 ];
00156 graph.AddNode( config );
00157
00158
00159
00160
00161 bool interfering = collisionDetector->IsInterfering( config );
00162 m_GraphInFreeSpace.push_back( !interfering );
00163 return size - 1;
00164 }
00165
00166
00167
00168
00169
00170
00171 bool PL_PrmIjg::DrawExplicit() const
00172 {
00173
00174 Semaphore semaphore( this->guid );
00175 semaphore.Lock();
00176
00177
00178
00179
00180 glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
00181 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00182 glDisable( GL_LIGHTING );
00183 glShadeModel( GL_SMOOTH );
00184 glPointSize( 2.0 );
00185
00186 Color::Colorf freeNodeColor = Color::green;
00187 Color::Colorf obstacleNodeColor = Color::red;
00188 Color::Colorf freeEdgeColor = freeNodeColor - Color::opaque * 0.5;
00189 Color::Colorf obstacleEdgeColor = obstacleNodeColor - Color::opaque * 0.5;
00190
00191
00192 int i;
00193 int size = m_Graphs.size();
00194 for( i = 0; i < size; ++i )
00195 {
00196
00197
00198
00199 const PrmGraph& graph = m_Graphs[ i ];
00200 const bool isInFreeSpace = m_GraphInFreeSpace[ i ];
00201 if( isInFreeSpace )
00202 {
00203 freeNodeColor.GlDraw();
00204 }
00205 else
00206 {
00207 obstacleNodeColor.GlDraw();
00208 }
00209 SetColor( i );
00210
00211
00212
00213
00214 glBegin( GL_POINTS );
00215 {
00216 const int size = graph.GetNumNodes();
00217 int i;
00218 for( i = 0; i < size; ++i )
00219 {
00220 const Configuration& node = graph.GetNodeData( i );
00221 Draw( node );
00222 }
00223 }
00224 glEnd();
00225
00226
00227
00228
00229 if( isInFreeSpace )
00230 {
00231 Color::green;
00232 freeEdgeColor.GlDraw();
00233 }
00234 else
00235 {
00236 obstacleEdgeColor.GlDraw();
00237 }
00238 SetColor( i );
00239
00240
00241 glLineWidth( 1.0f );
00242 glBegin( GL_LINES );
00243 {
00244 const int size = graph.GetNumEdges();
00245 int i;
00246 for( i = 0; i < size; ++i )
00247 {
00248 const Graph::Edge& e = graph.GetEdge( i );
00249 const Configuration& c0 = graph.GetNodeData( e.m_Node0 );
00250 const Configuration& c1 = graph.GetNodeData( e.m_Node1 );
00251 Draw( c0 );
00252 Draw( c1 );
00253 }
00254 }
00255 glEnd();
00256 }
00257
00258
00259 semaphore.Unlock();
00260 Sleep( 15 );
00261
00262 return true;
00263 }
00264
00265
00266
00267
00268
00269
00270 void PL_PrmIjg::DrawOverlay( const Configuration& config ) const
00271 {
00272 float x = 0.0f;
00273 float y = 0.0f;
00274 float z = 0.0f;
00275 const unsigned int DOF = config.DOF();
00276 if( DOF > 0 )
00277 {
00278 x = config[ 0 ];
00279 }
00280 if( DOF > 1 )
00281 {
00282 y = config[ 1 ];
00283 }
00284 if( DOF > 2 )
00285 {
00286 z = config[ 2 ];
00287 }
00288 glVertex3f( y, -x, z );
00289 }
00290
00291
00292
00293
00294
00295
00296 void PL_PrmIjg::DrawUniversePortion() const
00297 {
00298
00299
00300
00301 unsigned int dof = collisionDetector->DOF();
00302 if( dof != 2 )
00303 {
00304 return;
00305 }
00306
00307
00308 Semaphore semaphore( this->guid );
00309 semaphore.Lock();
00310
00311
00312
00313
00314 glDisable( GL_LIGHTING );
00315 glShadeModel( GL_SMOOTH );
00316 glPointSize( 2.0 );
00317
00318 Color::Colorf freeNodeColor = Color::green;
00319 Color::Colorf obstacleNodeColor = Color::red;
00320 Color::Colorf freeEdgeColor = freeNodeColor - Color::opaque * 0.5;
00321 Color::Colorf obstacleEdgeColor = obstacleNodeColor - Color::opaque * 0.5;
00322
00323
00324 int i;
00325 int size = m_Graphs.size();
00326 for( i = 0; i < size; ++i )
00327 {
00328
00329
00330
00331 const PrmGraph& graph = m_Graphs[ i ];
00332 const bool isInFreeSpace = m_GraphInFreeSpace[ i ];
00333 if( isInFreeSpace )
00334 {
00335 freeNodeColor.GlDraw();
00336 }
00337 else
00338 {
00339 obstacleNodeColor.GlDraw();
00340 }
00341 SetColor( i );
00342
00343
00344
00345
00346 glBegin( GL_POINTS );
00347 {
00348 const int size = graph.GetNumNodes();
00349 int i;
00350 for( i = 0; i < size; ++i )
00351 {
00352 const Configuration& node = graph.GetNodeData( i );
00353 DrawOverlay( node );
00354 }
00355 }
00356 glEnd();
00357
00358
00359
00360
00361 if( isInFreeSpace )
00362 {
00363 Color::green;
00364 freeEdgeColor.GlDraw();
00365 }
00366 else
00367 {
00368 obstacleEdgeColor.GlDraw();
00369 }
00370 SetColor( i );
00371
00372
00373 glLineWidth( 1.0f );
00374 glBegin( GL_LINES );
00375 {
00376 const int size = graph.GetNumEdges();
00377 int i;
00378 for( i = 0; i < size; ++i )
00379 {
00380 const Graph::Edge& e = graph.GetEdge( i );
00381 const Configuration& c0 = graph.GetNodeData( e.m_Node0 );
00382 const Configuration& c1 = graph.GetNodeData( e.m_Node1 );
00383 DrawOverlay( c0 );
00384 DrawOverlay( c1 );
00385 }
00386 }
00387 glEnd();
00388 }
00389
00390
00391 semaphore.Unlock();
00392 Sleep( 15 );
00393 }
00394
00395
00396
00397
00398
00399
00400 Configuration PL_PrmIjg::GenerateRandomConfig() const
00401 {
00402 int dof = GetStartConfig().DOF() ;
00403 Configuration returnme ;
00404 returnme.SetLength( dof ) ;
00405
00406 for( int i = 0; i < dof; i++ )
00407 {
00408 double max = collisionDetector->JointMax( i ) ;
00409 double min = collisionDetector->JointMin( i ) ;
00410 double random = double( rand() ) / RAND_MAX ;
00411 returnme[ i ] = min + ( max - min ) * random ;
00412 }
00413
00414 return returnme ;
00415 }
00416
00417
00418
00419
00420
00421
00422 void PL_PrmIjg::MergeGraphs( const int base, const int merge, const Configuration& config )
00423 {
00424
00425
00426
00427 if( ( base == 0 ) && ( merge == 1 ) )
00428 {
00429 m_PlanComplete = true;
00430 }
00431
00432 PrmGraph& baseGraph = m_Graphs[ base ];
00433 PrmGraph& mergeGraph = m_Graphs[ merge ];
00434
00435 baseGraph.Add( mergeGraph );
00436 mergeGraph.Clear();
00437
00438
00439
00440
00441 int firstMatch = -1;
00442 int i;
00443 int size = baseGraph.GetNumNodes();
00444 for( i = 0; i < size; ++i )
00445 {
00446 const Configuration& baseConfig = baseGraph.GetNodeData( i );
00447 double difference = ( baseConfig - config ).Magnitude();
00448 if( baseConfig == config )
00449 {
00450 firstMatch = i;
00451 break;
00452 }
00453 }
00454
00455 bool graphsConnected = false;
00456 IJG_Assert( firstMatch != -1 );
00457 for( ++i; i < size; ++i )
00458 {
00459 if( baseGraph.GetNodeData( i ) == config )
00460 {
00461 graphsConnected = true;
00462 baseGraph.AddEdge( firstMatch, i );
00463 }
00464 }
00465 IJG_Assert( graphsConnected );
00466 }
00467
00468
00469
00470
00471
00472
00473 bool PL_PrmIjg::Plan ()
00474 {
00475
00476 Semaphore semaphore( this->guid );
00477 semaphore.Lock();
00478
00479
00480
00481
00482 if( m_Graphs.size() == 0 )
00483 {
00484
00485
00486
00487
00488 CreateNewGraph( GetStartConfig() );
00489 CreateNewGraph( GetGoalConfig() );
00490 }
00491 else
00492 {
00493
00494
00495
00496 ++m_NumberOfTimesContinued;
00497 srand( m_NumberOfTimesContinued );
00498 }
00499
00500
00501 StartTimer();
00502
00503 while( ( !m_PlanComplete ) && ( !HasTimeLimitExpired() ) )
00504 {
00505 semaphore.Unlock();
00506 semaphore.Lock();
00507 Configuration config = GenerateRandomConfig();
00508
00509
00510
00511
00512 std::vector< int > graphsAddedTo;
00513 int i;
00514 int size = m_Graphs.size();
00515 bool successfullyAdded = false;
00516 for( i = 0; i < size; ++i )
00517 {
00518 bool addedToThisGraph = AddNodeToGraph( i, config );
00519 successfullyAdded |= addedToThisGraph;
00520 if( addedToThisGraph )
00521 {
00522 IJG_Assert( m_Graphs[ i ].ContainsNode( config ) );
00523 graphsAddedTo.push_back( i );
00524 }
00525 }
00526
00527
00528
00529
00530 if( graphsAddedTo.size() > 1 )
00531 {
00532 std::sort( graphsAddedTo.begin(), graphsAddedTo.end() );
00533 int baseGraphNum = graphsAddedTo[ 0 ];
00534 int i;
00535 int size = graphsAddedTo.size();
00536 for( i = 1; i < size; ++i )
00537 {
00538 int mergeGraphNum = graphsAddedTo[ i ];
00539 MergeGraphs( baseGraphNum, mergeGraphNum, config );
00540 Graph::GraphBase& g = m_Graphs[ baseGraphNum ];
00541 bool ok = g.CheckIntegrity();
00542 if( !ok )
00543 {
00544 this->PrintGraph( baseGraphNum );
00545 }
00546 IJG_Assert( ok );
00547 }
00548 }
00549
00550
00551
00552
00553 if( !successfullyAdded )
00554 {
00555 if( !collisionDetector->IsInterfering( config ) )
00556 {
00557 CreateNewGraph( config );
00558 }
00559 }
00560 }
00561
00562
00563
00564
00565 if( !HasTimeLimitExpired() )
00566 {
00567
00568
00569
00570 int goalNodeNum = -1;
00571 int i;
00572 int size = m_Graphs[ 0 ].GetNumNodes();
00573 for( i = 0; i < size; ++i )
00574 {
00575 const Configuration& c = m_Graphs[ 0 ].GetNodeData( i );
00576 if( c == GetGoalConfig() )
00577 {
00578 goalNodeNum = i;
00579 break;
00580 }
00581 }
00582 IJG_Assert( goalNodeNum != -1 );
00583
00584 Graph::Astar search;
00585 search.Search( m_Graphs[ 0 ], 0, goalNodeNum );
00586 std::vector< int > results = search.GetPath();
00587
00588 size = results.size();
00589 for( i = 0; i < size; ++i )
00590 {
00591 int nodeNumber = results[ i ];
00592 const Configuration& c = m_Graphs[ 0 ].GetNodeData( nodeNumber );
00593 path.AppendPoint( c );
00594 }
00595 }
00596
00597 if( this->m_Smoother != NULL )
00598 {
00599 this->m_Smoother->SetPath( &this->path );
00600 this->m_Smoother->SetCollisionDetector( this->collisionDetector );
00601 m_Smoother->Smooth();
00602 this->path = m_Smoother->GetPath();
00603 m_Smoother->SetPath( NULL );
00604 }
00605
00606 semaphore.Unlock();
00607 if( HasTimeLimitExpired() )
00608 {
00609 return false;
00610 }
00611 return true ;
00612 }
00613
00614
00615
00616
00617
00618
00619 void PL_PrmIjg::PlanMultiThread (void* data)
00620 {
00621
00622 }
00623
00624
00625
00626
00627
00628
00629 void PL_PrmIjg::PrintGraph( const int graphNum ) const
00630 {
00631 const PrmGraph& graph = m_Graphs[ graphNum ];
00632
00633
00634
00635
00636 int i;
00637 int size = graph.GetNumNodes();
00638 for( i = 0; i < size; ++i )
00639 {
00640 const Configuration& config = graph.GetNodeData( i );
00641 printf( "%d\t", i );
00642 config.Output();
00643 printf( "\n" );
00644 }
00645
00646
00647
00648
00649 printf( "Edges\n" );
00650 size = graph.GetNumEdges();
00651 for( i = 0; i < size; ++i )
00652 {
00653 const Graph::Edge& e = graph.GetEdge( i );
00654 printf( "[%d]\t%d\t%d\n", i, e.m_Node0, e.m_Node1 );
00655 }
00656
00657
00658
00659
00660 printf( "Nodes\n" );
00661 size = graph.GetNumNodes();
00662 for( i = 0; i < size; ++i )
00663 {
00664 printf( "[%d]\t", i );
00665 const Graph::Node& n = graph.GetNode( i );
00666 int edgeSize = n.GetNumEdges();
00667 int j;
00668 for( j = 0; j < edgeSize; ++j )
00669 {
00670 int edge = n.GetEdgeNumber( j );
00671 printf( "%d\t", edge );
00672 }
00673 printf( "\n" );
00674 }
00675 }
00676
00677
00678
00679
00680
00681
00682 void PL_PrmIjg::SetColor( const int i )
00683 {
00684 int modulo = i % 4;
00685 switch( modulo )
00686 {
00687 case 0:
00688 {
00689 Color::red_50.GlDraw();
00690 return;
00691 }
00692 case 1:
00693 {
00694 Color::green_50.GlDraw();
00695 return;
00696 }
00697 case 2:
00698 {
00699 Color::yellow_50.GlDraw();
00700 return;
00701 }
00702 case 3:
00703 {
00704 Color::cyan_50.GlDraw();
00705 return;
00706 }
00707 default:
00708 Color::white.GlDraw();
00709 return;
00710 }
00711 }