planners/obsolete/PL_SimplexSubdivision.cpp

Go to the documentation of this file.
00001 //## begin module%39864C6600AA.cm preserve=no
00002 //        %X% %Q% %Z% %W%
00003 //## end module%39864C6600AA.cm
00004 
00005 //## begin module%39864C6600AA.cp preserve=no
00006 //## end module%39864C6600AA.cp
00007 
00008 //## Module: PL_SimplexSubdivision%39864C6600AA; Pseudo Package body
00009 //## Source file: C:\project\mpk\code\Planners\PL_SimplexSubdivision.cpp
00010 
00011 //## begin module%39864C6600AA.additionalIncludes preserve=no
00012 //## end module%39864C6600AA.additionalIncludes
00013 
00014 //## begin module%39864C6600AA.includes preserve=yes
00015 #include <assert.h>
00016 #include <math.h>
00017 #pragma warning( disable : 4786 )
00018 //## end module%39864C6600AA.includes
00019 
00020 // PL_SimplexSubdivision
00021 #include "synchronization/semaphore.h"
00022 #include "PL_SimplexSubdivision.h"
00023 #include "opengl/glos.h"
00024 #include <gl/gl.h>
00025 
00026 //=============================================================================
00027 // Constructor
00028 //
00029 // description: constructor
00030 //=============================================================================
00031 PL_SimplexSubdivision::PL_SimplexSubdivision()
00032 :
00033         m_NodeStart( 0 ),
00034         m_NodeGoal( 0 ),
00035         m_Compare( this ),
00036         m_SuspiciousNodesAndVolumes( m_Compare )
00037 {
00038 }
00039 
00040 
00041 //=============================================================================
00042 // Destructor
00043 //
00044 // description: Destructor
00045 //=============================================================================
00046 PL_SimplexSubdivision::~PL_SimplexSubdivision()
00047 {
00048         //nothing
00049 }
00050 
00051 //=============================================================================
00052 // AddEdge
00053 //
00054 // description: Adds an edge between two nodes
00055 //=============================================================================
00056 void PL_SimplexSubdivision::AddEdge( const int node0, const int node1 )
00057 {
00058         if( !IsAdjacent( node0, node1 ) )
00059         {
00060                 return;
00061         }
00062 
00063         Node& n0 = m_Nodes[ node0 ];
00064         Node& n1 = m_Nodes[ node1 ];
00065         n0.AddNeighbor( node1 );
00066         n1.AddNeighbor( node0 );
00067 }
00068 
00069 //=============================================================================
00070 // AddNode
00071 //
00072 // description: Adds a node to the vector of nodes
00073 //=============================================================================
00074 int PL_SimplexSubdivision::AddNode
00075 ( 
00076         const Configuration& min, 
00077         const Configuration& max 
00078 )
00079 {
00080         Node addme;
00081 #pragma message( "##### Magic numbers are bad" )
00082         addme.m_DistanceFromStart = 99999999;   
00083         addme.m_Min = min;
00084         addme.m_Max = max;
00085         addme.m_Alive = true;
00086         addme.m_NodesAdjacent.clear();
00087         addme.m_LocationOfCollision = ( min + max ) / 2;
00088         this->m_Nodes.push_back( addme );
00089         int returnMe = m_Nodes.size() - 1;
00090         this->m_OpenList.insert( returnMe );
00091         return returnMe;
00092 }
00093 
00094 //=============================================================================
00095 // AddSuspiciousNode
00096 //
00097 // description: adds a suspicious node to the set
00098 //=============================================================================
00099 void PL_SimplexSubdivision::AddSuspiciousNode( const int nodeNum )
00100 {
00101         m_SuspiciousNodesAndVolumes.insert( nodeNum );
00102 }
00103 
00104 
00105 //=============================================================================
00106 // AddToOpenList
00107 //
00108 // description: adds a node to the open list - if it's not in the closed list 
00109 // already
00110 //=============================================================================
00111 void PL_SimplexSubdivision::AddToOpenList( const int nodeNum )
00112 {
00113         //
00114         // is the node in the closed list
00115         //
00116         //if( m_ClosedList.find( nodeNum ) == m_ClosedList.end() )
00117         //{
00118         //      return;
00119         //}
00120         //else
00121         {
00122                 m_OpenList.insert( nodeNum );
00123         }
00124 }
00125 
00126 
00127 //=============================================================================
00128 // CollisionCheck
00129 //
00130 // description: checks two nodes for collisions between them
00131 //=============================================================================
00132 PL_SimplexSubdivision::CollisionType PL_SimplexSubdivision::CollisionCheck( const int n0, const int n1 )
00133 {
00134         Node& node0 = m_Nodes[ n0 ];
00135         Node& node1 = m_Nodes[ n1 ];
00136 
00137         //
00138         // figure out the index to the neighbors for each of the nodes
00139         //
00140 
00141         int n0Neighbor = -1;
00142         int n1Neighbor = -1;
00143 
00144         int i;
00145         int size = node0.m_NodesAdjacent.size();
00146         for( i = 0; i < size; i++ )
00147         {
00148                 if( node0.m_NodesAdjacent[ i ] == n1 )
00149                 {
00150                         n0Neighbor = i;
00151                         break;
00152                 }
00153         }
00154         assert( n0Neighbor != -1 );
00155 
00156         size = node1.m_NodesAdjacent.size();
00157         for( i = 0; i < size; i++ )
00158         {
00159                 if( node1.m_NodesAdjacent[ i ] == n0 )
00160                 {
00161                         n1Neighbor = i;
00162                         break;
00163                 }
00164         }
00165         assert( n1Neighbor != -1 );
00166 
00167         //
00168         // Has the collision check already been done?
00169         //
00170         if( node0.m_LinkType[ n0Neighbor ] != CT_UNKNOWN )
00171         {
00172                 return node0.m_LinkType[ n0Neighbor ];
00173         }
00174 
00175         //
00176         // perform collision detection
00177         //
00178 
00179         Configuration c0 = node0.Center();
00180         Configuration c1 = node1.Center();
00181         bool collision = collisionDetector->IsInterfering( c0 );
00182         collision = ( collision || collisionDetector->IsInterfering( c1 ) );
00183         collision = ( collision || collisionDetector->IsInterferingLinear( c0, c1 ) );
00184         CollisionType ct;
00185         if( collision )
00186         {
00187                 ct = CT_COLLISION;
00188 
00189                 //get the location of the collision
00190                 Configuration c = collisionDetector->GetLastValid();
00191                 bool n0contains = node0.ContainsCompletely( c );
00192                 bool n1contains = node1.ContainsCompletely( c );
00193 
00194                 if( n0contains && !n1contains )
00195                 {
00196                         double minx = node0.m_Min[ 0 ];
00197                         double miny = node0.m_Min[ 1 ];
00198                         double maxx = node0.m_Max[ 0 ];
00199                         double maxy = node0.m_Max[ 1 ];
00200                         double cx = c[ 0 ];
00201                         double cy = c[ 1 ];
00202                         node0.m_LocationOfCollision = c;
00203                 }
00204                 else if( n1contains && !n0contains )
00205                 {
00206                         node1.m_LocationOfCollision = c;
00207                 }
00208                 else
00209                 {
00210                         //assert( false );
00211                 }
00212         }
00213         else
00214         {
00215                 ct = CT_FREE;
00216         }
00217         node0.m_LinkType[ n0Neighbor ] = ct;
00218         node1.m_LinkType[ n1Neighbor ] = ct;
00219         return ct;
00220 }
00221 
00222 //=============================================================================
00223 // ConnectStartAndGoal
00224 //
00225 // description: connects the start and the goal to the tree
00226 //=============================================================================
00227 void PL_SimplexSubdivision::ConnectStartAndGoal()
00228 {
00229         //
00230         // Connect the start
00231         //
00232         bool collision = true;
00233         if( collision )
00234         {
00235                 Configuration startNode = m_Nodes[ m_NodeStart ].Center();
00236                 collision = collisionDetector->IsInterferingLinear( GetStartConfig(), startNode );
00237                 if( collision )
00238                 {
00239                         SubdivideNode( m_NodeStart );
00240                 }
00241                 else
00242                 {
00243                         m_Nodes[ m_NodeStart ].m_DistanceFromStart = 0;
00244                 }
00245         }
00246 
00247         //
00248         // Connect the goal
00249         //
00250         collision = true;
00251         if( collision )
00252         {
00253                 Configuration goalNode = m_Nodes[ m_NodeGoal ].Center();
00254                 collision = collisionDetector->IsInterferingLinear( GetGoalConfig(), goalNode );
00255                 if( collision )
00256                 {
00257                         SubdivideNode( m_NodeGoal );
00258                 }
00259         }
00260 }
00261 
00262 
00263 //=============================================================================
00264 // DeleteEdge
00265 //
00266 // description: deletes an already existing edge
00267 //=============================================================================
00268 void PL_SimplexSubdivision::DeleteEdge( const int node0, const int node1 )
00269 {
00270         Node& n0 = m_Nodes[ node0 ];
00271         Node& n1 = m_Nodes[ node1 ];
00272         n0.RemoveNeighbor( node1 );
00273         n1.RemoveNeighbor( node0 );
00274 }
00275 
00276 //=============================================================================
00277 // DeleteNode
00278 //
00279 // description: deletes an already existing node
00280 //=============================================================================
00281 void PL_SimplexSubdivision::DeleteNode( const int nodeNum )
00282 {
00283         Node& node = m_Nodes[ nodeNum ];
00284         node.m_Alive = false;
00285 
00286         //delete all the links associated with this node
00287         int i;
00288         int size = node.m_NodesAdjacent.size();
00289         for( i = size - 1; i >= 0; i-- )
00290         {
00291                 int neighbor = node.m_NodesAdjacent[ i ];
00292                 DeleteEdge( nodeNum, neighbor );
00293         }
00294 
00295         m_OpenList.erase( nodeNum );
00296         m_ClosedList.erase( nodeNum );
00297 }
00298 
00299 //=============================================================================
00300 // DrawExplicit
00301 //
00302 // description: Draws the current snapshot of the planner
00303 //=============================================================================
00304 bool PL_SimplexSubdivision::DrawExplicit () const
00305 {
00306         Semaphore semaphore( this->guid );
00307         semaphore.Lock();
00308 
00309         glClearColor( 0.0f, 0.0f, 0.2f, 1.0f );
00310         glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00311 
00312         //
00313         // Disable lighting and depth test
00314         //
00315         glDisable( GL_LIGHTING );
00316         glDisable( GL_DEPTH_TEST );
00317 
00318         int i = 0;
00319         glColor4d( 1.0, 1.0, 1.0, 1.0 );
00320         glPointSize( 3.0 );
00321 
00322         int dof = GetGoalConfig().DOF();
00323 
00324         //draw all the nodes
00325         int size = m_Nodes.size();
00326         for( i = 0; i < size; i++ )
00327         {
00328                 //
00329                 // draw an individual node
00330                 //
00331                 const Node& node = m_Nodes[ i ];
00332                 node.DrawExplicit();
00333         }
00334         
00335         //
00336         // Draw all the connections
00337         //
00338 
00339         //
00340         // Connections
00341         //
00342         glBegin( GL_LINES );
00343         glLineWidth( 2.0 );
00344 
00345         int n;
00346         int nSize = m_Nodes.size();
00347         for( n = 0; n < nSize; n++ )
00348         {
00349                 const Node& me = m_Nodes[ n ];
00350                 if( !me.m_Alive )
00351                 {
00352                         continue;
00353                 }
00354                 int size = me.m_NodesAdjacent.size();
00355                 for( i = 0; i < size; i++ )
00356                 {
00357                         int neighborInt = me.m_NodesAdjacent[ i ];
00358                         assert( neighborInt >= 0 );
00359                         CollisionType ct = me.m_LinkType[ i ];
00360                         switch( ct )
00361                         {
00362                         case CT_FREE:
00363                                 {
00364                                         glColor4f( 0.0f, 1.0f, 0.0f, 1.0f );
00365                                         break;
00366                                 }
00367                         case CT_COLLISION:
00368                                 {
00369                                         glColor4f( 1.0f, 0.0f, 0.0f, 1.0f );
00370                                         break;
00371                                 }
00372                         default:
00373                                 {
00374                                         glColor4f( 0.5f, 0.5f, 0.5f, 0.3f );
00375                                         break;
00376                                 }
00377                         }
00378                         const Node& neighborNode = m_Nodes[ neighborInt ];
00379                         Configuration neighbor = neighborNode.Center();
00380                         Configuration myC = me.Center();
00381                         double mX = myC[ 0 ];
00382                         double mY = myC[ 1 ];
00383                         double nX = neighbor[ 0 ];
00384                         double nY = neighbor[ 1 ];
00385                         glVertex3d( mX, mY, 0 );
00386                         glVertex3d( nX, nY, 0 );
00387                 }
00388         }
00389         glEnd();
00390 
00391         //
00392         // draw the start/goal
00393         //
00394         glColor3f( 1.0f, 1.0f, 1.0f );
00395         glBegin( GL_POINTS );
00396                 double n0 = 0;
00397                 double n1 = 0;
00398                 double n2 = 0;
00399                 if( dof > 0 )
00400                 {
00401                         n0 = GetGoalConfig()[ 0 ];
00402                 }
00403                 if( dof > 1 )
00404                 {
00405                         n1 = GetGoalConfig()[ 1 ];
00406                 }
00407                 if( dof > 2 )
00408                 {
00409                         n2 = GetGoalConfig()[ 2 ];
00410                 }
00411                 glVertex3f( n0, n1, n2 );
00412                 if( dof > 0 )
00413                 {
00414                         n0 = GetStartConfig()[ 0 ];
00415                 }
00416                 if( dof > 1 )
00417                 {
00418                         n1 = GetStartConfig()[ 1 ];
00419                 }
00420                 if( dof > 2 )
00421                 {
00422                         n2 = GetStartConfig()[ 2 ];
00423                 }
00424                 glVertex3f( n0, n1, n2 );
00425         glEnd();
00426 
00427         semaphore.Unlock();
00428         return true;
00429 }
00430 
00431 //=============================================================================
00432 // IsAdjacent
00433 //
00434 // description: test if two nodes are adjacent 
00435 //=============================================================================
00436 bool PL_SimplexSubdivision::IsAdjacent( int node0, int node1 )
00437 {
00438         int overlapping = 0;
00439         int adjacent = 0;
00440 
00441         Node& n0 = m_Nodes[ node0 ];
00442         Node& n1 = m_Nodes[ node1 ];
00443         int i;
00444         int size = n0.m_Max.DOF();
00445         for( i = 0; i < size; i++ )
00446         {
00447                 double aMin = n0.m_Min[ i ];
00448                 double aMax = n0.m_Max[ i ];
00449                 double bMin = n1.m_Min[ i ];
00450                 double bMax = n1.m_Max[ i ];
00451 
00452                 if( ( aMin <= bMin ) && ( aMax > bMin ) )
00453                 {
00454                         overlapping++;
00455                         continue;
00456                 }
00457                 if( ( bMin <= aMin ) && ( bMax > aMin ) )
00458                 {
00459                         overlapping++;
00460                         continue;
00461                 }
00462                 if( ( aMax == bMin ) || ( bMax == aMin ) )
00463                 {
00464                         adjacent++;
00465                         continue;
00466                 }
00467         }
00468         if( ( adjacent == 1 ) && ( overlapping + adjacent == size ) )
00469         {
00470                 return true;
00471         }
00472         return false;
00473 }
00474 
00475 //=============================================================================
00476 // Plan
00477 //
00478 // description: Does the planning
00479 //=============================================================================
00480 bool PL_SimplexSubdivision::Plan ()
00481 {
00482         // Start the timer
00483         StartTimer();
00484 
00485         m_Nodes.clear();
00486 
00487         //
00488         // Set up min and max configurations
00489         //
00490         Configuration min;
00491         Configuration max;
00492         min = GetStartConfig();
00493         max = GetStartConfig();
00494         int i;
00495         int size = min.DOF();
00496         for( i = 0; i < size; i++ )
00497         {
00498                 min[ i ] = collisionDetector->JointMin( i );
00499                 max[ i ] = collisionDetector->JointMax( i );
00500         }
00501 
00502         //
00503         // Add the 0th node
00504         //
00505         int firstNode = AddNode( min, max );
00506         m_NodeStart = firstNode;
00507         m_NodeGoal = firstNode;
00508 
00509         //
00510         // Connect the start and the goal to the 0th node
00511         //
00512         ConnectStartAndGoal();
00513 
00514         // Add the start node to the open list
00515         AddToOpenList( m_NodeStart );
00516 
00517         bool foundGoal = SearchForGoal();
00518         Semaphore semaphore( this->guid );
00519         //while( !foundGoal && !( HasTimeLimitExpired() ) )
00520         while( !foundGoal )
00521         {
00522                 if( HasTimeLimitExpired() )
00523                 {
00524                         return false;
00525                 }
00526                 if( this->m_UseSemaphores )
00527                 {
00528                         semaphore.Lock();
00529                 }
00530                 SubdivideLargestNode();
00531                 foundGoal = SearchForGoal();
00532 
00533                 if( this->m_UseSemaphores )
00534                 {
00535                         semaphore.Unlock();
00536                 }
00537         }
00538 
00539         //
00540         // Walk backwards from the goal to the start to get the path
00541         //
00542         /*
00543         path.Clear();
00544         path.AppendPointToBeginning( goalConfig );
00545         int currentNodeInt = m_NodeGoal;
00546         while( currentNodeInt != m_NodeStart )
00547         {
00548                 Node& currentNode = m_Nodes[ currentNodeInt ];
00549                 int bestNeighbor = currentNode.m_NodesAdjacent[ -1 ];
00550                 double bestNeighborValue = 9999999;
00551 
00552                 //
00553                 // found the next step in the path
00554                 //
00555                 path.AppendPointToBeginning( currentNode.Center() );
00556 
00557                 int i;
00558                 int size = currentNode.m_NodesAdjacent.size();
00559                 for( i = 0; i < size; i++ )
00560                 {
00561                         int neighborInt = currentNode.m_NodesAdjacent[ i ];
00562                         CollisionType ct = currentNode.m_LinkType[ i ];
00563                         if( ct == CT_FREE )
00564                         {
00565                                 Node& neighbor = m_Nodes[ neighborInt ];
00566                                 if( neighbor.m_DistanceFromStart < bestNeighborValue )
00567                                 {
00568                                         bestNeighborValue = neighbor.m_DistanceFromStart;
00569                                         bestNeighbor = neighborInt;
00570                                 }
00571                         }
00572                 }
00573                 assert( bestNeighbor != 1 );
00574                 currentNodeInt = bestNeighbor;
00575         }
00576 
00577         //
00578         // Add the start point to the path
00579         //
00580         Node& currentNode = m_Nodes[ currentNodeInt ];
00581         path.AppendPointToBeginning( currentNode.Center() );
00582         path.AppendPointToBeginning( startConfig );
00583         */
00584         //StopTimer();
00585         return true;
00586 }
00587 
00588 //=============================================================================
00589 // SearchForGoal
00590 //
00591 // description: searches for the goal until no nodes remain on the open list
00592 //=============================================================================
00593 bool PL_SimplexSubdivision::SearchForGoal()
00594 {
00595         //
00596         // Take the top node off the open list + try to expand it
00597         //
00598         while( m_OpenList.size() != 0 )
00599         {
00600                 int nodesRemainingInOpenList = m_OpenList.size();
00601                 int nodeToExpand = *( m_OpenList.begin() );
00602                 m_OpenList.erase( m_OpenList.begin() );
00603                 Node& n = m_Nodes[ nodeToExpand ];
00604 
00605                 //check if any of the neighbors of this node can reach the start
00606                 int i;
00607                 int size = n.m_NodesAdjacent.size();
00608                 for( i = 0; i < size; i++ )
00609                 {
00610                         int neighbor = n.m_NodesAdjacent[ i ];
00611                         Node& neighborNode = m_Nodes[ neighbor ];
00612                         if( neighborNode.m_DistanceFromStart >= n.m_DistanceFromStart )
00613                         {
00614                                 continue;
00615                         }
00616                         m_ClosedList.insert( nodeToExpand );
00617 
00618                         //test the link for collisions
00619                         PL_SimplexSubdivision::CollisionType ct = CollisionCheck( nodeToExpand, neighbor );
00620                         if( ct == CT_FREE )
00621                         {
00622                                 //
00623                                 // Update the distance from the start
00624                                 //
00625                                 double distance = ( n.Center() - neighborNode.Center() ).Magnitude();
00626                                 double newDistance = neighborNode.m_DistanceFromStart + distance;
00627                                 if( newDistance >= n.m_DistanceFromStart )
00628                                 {
00629                                         continue;
00630                                 }
00631                                 n.m_DistanceFromStart = newDistance;
00632 
00633                                 if( nodeToExpand == m_NodeGoal )
00634                                 {
00635                                         return true;
00636                                 }
00637 
00638                                 //
00639                                 // Add all the neighbors to the open list
00640                                 //
00641                                 int j;
00642                                 int size = n.m_NodesAdjacent.size();
00643                                 for( j = 0; j < size; j++ )
00644                                 {
00645                                         int neighbor = n.m_NodesAdjacent[ j ];
00646                                         AddToOpenList( neighbor );
00647                                 }
00648                         }
00649                         else
00650                         {
00651                                 Configuration collision = collisionDetector->GetLastIntersection();
00652                                 Node& n0 = m_Nodes[ neighbor ];
00653                                 Node& n1 = m_Nodes[ nodeToExpand ];
00654                                 bool n0contains = n0.Contains( collision );
00655                                 bool n1contains = n0.Contains( collision );
00656                                 if( n0contains )
00657                                 {
00658                                         AddSuspiciousNode( neighbor );
00659                                 }
00660                                 if( n1contains )
00661                                 {
00662                                         AddSuspiciousNode( nodeToExpand );
00663                                 }
00664                                 if( !n0contains && !n1contains )
00665                                 {
00666                                         AddSuspiciousNode( neighbor );
00667                                         AddSuspiciousNode( nodeToExpand );
00668                                 }
00669                         }
00670                 }
00671         }
00672         return false;
00673 }
00674 
00675 //=============================================================================
00676 // SubdivideLargestNode
00677 //
00678 // description: Subdivides the largest node in the suspicious list
00679 //=============================================================================
00680 void PL_SimplexSubdivision::SubdivideLargestNode()
00681 {
00682         //
00683         // Are there any suspicious nodes?
00684         //
00685         int size = m_SuspiciousNodesAndVolumes.size();
00686         assert( size != 0 );
00687 
00688         INTSET::value_type value = *( m_SuspiciousNodesAndVolumes.begin() );
00689         m_SuspiciousNodesAndVolumes.erase( m_SuspiciousNodesAndVolumes.begin() );
00690         int mostSuspiciousNode = value;
00691         double howBigWasIt = Volume( mostSuspiciousNode );
00692         SubdivideNode( mostSuspiciousNode );
00693 }
00694 
00695 //=============================================================================
00696 // SubdivideNode
00697 //
00698 // description: Subdivides a specific node along the longest side
00699 //=============================================================================
00700 void PL_SimplexSubdivision::SubdivideNode( int nodeNum )
00701 {
00702         Node subdivideMe = m_Nodes[ nodeNum ];
00703         Configuration min = subdivideMe.m_Min;
00704         Configuration max = subdivideMe.m_Max;
00705 
00706         //
00707         // Figure out the longest edge of the node
00708         //
00709         int longestDimension = 0;
00710         double longestSize = 0;
00711         int i;
00712         int size = subdivideMe.m_Min.Length();
00713         for( i = 0; i < size; i++ )
00714         {
00715                 double size = max[ i ] - min[ i ];
00716                 if( size > longestSize )
00717                 {
00718                         longestSize = size; 
00719                         longestDimension = i;
00720                 }
00721         }
00722 
00723         double maxDim = max[ longestDimension ];
00724         double minDim = min[ longestDimension ];
00725         double halfWayPoint = subdivideMe.m_LocationOfCollision[ longestDimension ];
00726         Configuration minHi = max;
00727         minHi[ longestDimension ] = halfWayPoint;
00728         Configuration maxLo = min;
00729         maxLo[ longestDimension ] = halfWayPoint;
00730         
00731         int loNumber = AddNode( min, minHi );
00732         int hiNumber = AddNode( maxLo, max );
00733         AddEdge( loNumber, hiNumber );
00734 
00735         size = subdivideMe.m_NodesAdjacent.size();
00736         assert( size >= 0 );
00737         for( i = 0; i < size; i++ )
00738         {
00739                 int originalNeighbor = subdivideMe.m_NodesAdjacent[ i ];
00740                 AddEdge( loNumber, originalNeighbor );
00741                 AddEdge( hiNumber, originalNeighbor );
00742         }
00743 
00744         //
00745         // if this was the start node or the goal node, there is more to do
00746         //
00747         bool needReconnect = false;
00748         if( nodeNum == m_NodeStart )
00749         {
00750                 Node& a = m_Nodes[ loNumber ];
00751                 Node& b = m_Nodes[ hiNumber ];
00752                 if( a.Contains( GetStartConfig() ) )
00753                 {
00754                         m_NodeStart = loNumber;
00755                 }
00756                 else
00757                 {
00758                         m_NodeStart = hiNumber;
00759                         assert( b.Contains( GetStartConfig() ) );
00760                 }
00761                 needReconnect = true;
00762         }
00763 
00764         if( nodeNum == m_NodeGoal )
00765         {
00766                 Node& a = m_Nodes[ loNumber ];
00767                 Node& b = m_Nodes[ hiNumber ];
00768                 if( a.Contains( GetGoalConfig()) )
00769                 {
00770                         m_NodeGoal = loNumber;
00771                 }
00772                 else
00773                 {
00774                         m_NodeGoal = hiNumber;
00775                         assert( b.Contains( GetGoalConfig() ) );
00776                 }
00777                 needReconnect = true;
00778         }
00779         DeleteNode( nodeNum );
00780         if( needReconnect )
00781         {
00782                 ConnectStartAndGoal();
00783         }
00784 }
00785 
00786 //=============================================================================
00787 // Volume
00788 //
00789 // description: returns the volume of a node
00790 //=============================================================================
00791 double PL_SimplexSubdivision::Volume( const int i ) const
00792 {
00793         return m_Nodes[ i ].Volume();
00794 }
00795 
00796 
00797 //=============================================================================
00798 // AddNeighbor
00799 //
00800 // description: Adds a neighbor to a node
00801 //=============================================================================
00802 void PL_SimplexSubdivision::Node::AddNeighbor( const int node )
00803 {
00804         //
00805         // check if the neighbor already exists
00806         //
00807         //
00808         // find the neighbor
00809         //
00810         std::vector< int >::iterator it;
00811         for( it = m_NodesAdjacent.begin(); it != m_NodesAdjacent.end(); it++ )
00812         {
00813                 if( *it == node )
00814                 {
00815                         return;
00816                 }
00817         }
00818 
00819 
00820         m_NodesAdjacent.push_back( node );
00821         m_LinkType.push_back( CT_UNKNOWN );
00822 }
00823 
00824 //=============================================================================
00825 // Center
00826 //
00827 // description: gets the center of the node
00828 //=============================================================================
00829 Configuration PL_SimplexSubdivision::Node::Center() const
00830 {
00831         assert( m_Alive );
00832         return ( m_Max + m_Min ) / 2;
00833 }
00834 
00835 //=============================================================================
00836 // Contains
00837 //
00838 // description: does the node contain this point?
00839 //=============================================================================
00840 bool PL_SimplexSubdivision::Node::Contains( const Configuration& c ) const
00841 {
00842         bool returnMe = true;
00843         int i;
00844         int size = m_Min.Length();
00845         for( i = 0; i < size; i++ )
00846         {
00847                 if( m_Min[ i ] > c[ i ] )
00848                 {
00849                         return false;
00850                 }
00851 
00852                 if( m_Max[ i ] < c[ i ] )
00853                 {
00854                         return false;
00855                 }
00856         }
00857         return true;
00858 }
00859 
00860 //=============================================================================
00861 // ContainsCompletely
00862 //
00863 // description: does the node contain this point?
00864 //=============================================================================
00865 bool PL_SimplexSubdivision::Node::ContainsCompletely( const Configuration& c ) const
00866 {
00867         bool returnMe = true;
00868         int i;
00869         int size = m_Min.Length();
00870         for( i = 0; i < size; i++ )
00871         {
00872                 if( m_Min[ i ] >= c[ i ] )
00873                 {
00874                         return false;
00875                 }
00876 
00877                 if( m_Max[ i ] <= c[ i ] )
00878                 {
00879                         return false;
00880                 }
00881         }
00882         return true;
00883 }
00884 
00885 //=============================================================================
00886 // DrawExplicit
00887 //
00888 // description: Draws the node to the screen using OpenGL
00889 //=============================================================================
00890 void PL_SimplexSubdivision::Node::DrawExplicit() const
00891 {
00892         if( !m_Alive )
00893         {
00894                 return;
00895         }
00896 
00897         ::glLineWidth( 1.0 );
00898 
00899         double xMin = m_Min[ 0 ];
00900         double yMin = m_Min[ 1 ];
00901         double xMax = m_Max[ 0 ];
00902         double yMax = m_Max[ 1 ];
00903 
00904         GlColor();
00905 
00906         glBegin( GL_QUADS );
00907                 glVertex3d( xMin, yMin, 0 );
00908                 glVertex3d( xMax, yMin, 0 );
00909                 glVertex3d( xMax, yMax, 0 );
00910                 glVertex3d( xMin, yMax, 0 );
00911         glEnd();
00912 
00913         glBegin( GL_LINE_LOOP );
00914                 glVertex3d( xMin, yMin, 0 );
00915                 glVertex3d( xMax, yMin, 0 );
00916                 glVertex3d( xMax, yMax, 0 );
00917                 glVertex3d( xMin, yMax, 0 );
00918         glEnd();
00919 
00920         glBegin( GL_POINTS );
00921                 glVertex3d( xMin, yMin, 0 );
00922                 glVertex3d( xMax, yMin, 0 );
00923                 glVertex3d( xMax, yMax, 0 );
00924                 glVertex3d( xMin, yMax, 0 );
00925         glEnd();
00926 }
00927 
00928 //=============================================================================
00929 // GlColor
00930 //
00931 // description: sets the color of this node
00932 //=============================================================================
00933 void PL_SimplexSubdivision::Node::GlColor() const
00934 {
00935         bool isUnknown = true;
00936         bool isFree = true;
00937         bool isColliding = true;
00938         int i;
00939         int size = m_LinkType.size();
00940         for( i = 0; i < size; i++ )
00941         {
00942                 if( m_LinkType[ i ] == CT_COLLISION )
00943                 {
00944                         isFree = false;
00945                 }
00946 
00947                 if( m_LinkType[ i ] != CT_UNKNOWN )
00948                 {
00949                         isUnknown = false;
00950                 }
00951 
00952                 if( m_LinkType[ i ] == CT_FREE )
00953                 {
00954                         isColliding = false;
00955                 }
00956         }
00957 
00958         if( isUnknown )
00959         {
00960                 ::glColor4d( 1.0, 1.0, 1.0, 0.3 );
00961         }
00962         else if( isFree )
00963         {
00964                 ::glColor4d( 0.0, 1.0, 0.0, 0.3 );
00965         }
00966         else if( isColliding )
00967         {
00968                 ::glColor4d( 1.0, 0.0, 0.0, 0.3 );
00969         }
00970         else
00971         {
00972                 ::glColor4d( 1.0, 1.0, 0.0, 0.3 );
00973         }
00974 }
00975 
00976 
00977 //=============================================================================
00978 // IsClean
00979 //
00980 // description: determines if the node is free of any colliding neighbors
00981 //=============================================================================
00982 bool PL_SimplexSubdivision::Node::IsClean() const
00983 {
00984         int i;
00985         int size = m_LinkType.size();
00986         for( i = 0; i < size; i++ )
00987         {
00988                 if( m_LinkType[ i ] != CT_FREE )
00989                 {
00990                         return false;
00991                 }
00992         }
00993         return true;
00994 }
00995 
00996 
00997 //=============================================================================
00998 // RemoveNeighbor
00999 //
01000 // description: removes a neighbor
01001 //=============================================================================
01002 void PL_SimplexSubdivision::Node::RemoveNeighbor( const int node )
01003 {
01004         //
01005         // find the neighbor
01006         //
01007         std::vector< int >::iterator it;
01008         std::vector< CollisionType >::iterator ctIt = m_LinkType.begin();
01009         for( it = m_NodesAdjacent.begin(); it != m_NodesAdjacent.end(); it++, ctIt++ )
01010         {
01011                 if( *it == node )
01012                 {
01013                         m_NodesAdjacent.erase( it );
01014                         m_LinkType.erase( ctIt );
01015                         return;
01016                 }
01017         }
01018 
01019         //assert( false );
01020         //
01021         // the neighbor wasn't there to begin with
01022         //
01023 }
01024 
01025 //=============================================================================
01026 // Volume
01027 //
01028 // description: returns the size of the node
01029 //=============================================================================
01030 double PL_SimplexSubdivision::Node::Volume() const
01031 {
01032         double runningTotal = 1.0;
01033         int i;
01034         int size = m_Max.Length();
01035         for( i = 0; i < size; i++ )
01036         {
01037                 double length = m_Max[ i ] - m_Min[ i ];
01038                 runningTotal *= length;
01039         }
01040         return runningTotal;
01041 }
01042 
01043 //=============================================================================
01044 // PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction();
01045 //
01046 // description: constructor
01047 //=============================================================================
01048 PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction( const PL_SimplexSubdivision* planner  )
01049 :
01050         m_Planner( planner )
01051 {
01052 }
01053 
01054 //=============================================================================
01055 // PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction( const ComparisonFunction& right )
01056 //
01057 // description: Copy constructor
01058 //=============================================================================
01059 PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction( const ComparisonFunction& right )
01060 {
01061         m_Planner = right.m_Planner;
01062 }
01063 
01064 //=============================================================================
01065 // PL_SimplexSubdivision::ComparisonFunction::ComparisonFunction
01066 // ( 
01067 //    const PL_SimplexSubdivision* planner 
01068 // )
01069 //
01070 // description: compares two nodes, and sorts based on volume
01071 //=============================================================================
01072 bool PL_SimplexSubdivision::ComparisonFunction::operator()
01073 ( 
01074         const int a, 
01075         const int b 
01076 )
01077 
01078 {
01079         assert( m_Planner != NULL );
01080         double volA = m_Planner->Volume( a );
01081         double volB = m_Planner->Volume( b );
01082 
01083         //yeah, i know this looks backwards, i want the sort in that order
01084         if( volA > volB ) return true;
01085         if( volB > volA ) return false;
01086         if( a > b ) return true;
01087         return false;
01088 }

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