planners/neural/PL_Neural.cpp

Go to the documentation of this file.
00001 #pragma warning( disable : 4786 )
00002 
00003 #include <synchronization/semaphore.h>
00004 #include "debug/debug.h"
00005 #include "color/colorf.h"
00006 #include "math/math2.h"
00007 #include "planners/neural/pl_neural.h"
00008 #include <gl\gl.h>
00009 
00010 //=============================================================================
00011 // PL_Neural::PL_Neural
00012 //=============================================================================
00013 PL_Neural::PL_Neural()
00014 {
00015 }
00016 
00017 //=============================================================================
00018 // PL_Neural::~PL_Neural
00019 //=============================================================================
00020 PL_Neural::~PL_Neural()
00021 {
00022 }
00023 
00024 //=============================================================================
00025 // PL_Neural::DrawExplicit
00026 //=============================================================================
00027 void PL_Neural::AddObstaclePoint( const Configuration& c ) const
00028 {
00029     m_ObstacleLocations.push_back( c );
00030 }
00031 
00032 //=============================================================================
00033 // PL_Neural::CheckPathForObstacles
00034 //=============================================================================
00035 bool PL_Neural::CheckPathForObstacles()
00036 {
00037     int n = NodesInCollision();
00038     int e = EdgeInCollision();
00039 
00040     if( ( n == -1 ) && ( e == -1 ) )
00041     {
00042         return false;
00043     }
00044     return true;
00045 }
00046 
00047 //=============================================================================
00048 // PL_Neural::ClampAllPointsToDofLimits
00049 //=============================================================================
00050 void PL_Neural::ClampAllPointsToJointLimits()
00051 {
00052     int i;
00053     int size = m_Path.Size();
00054     for( i = 0; i < size; ++i )
00055     {
00056         Configuration& c = m_Path[ i ];
00057         c = ClampToJointLimits( c );
00058     }
00059 }
00060 
00061 //=============================================================================
00062 // PL_Neural::ClampAllPointsToDofLimits
00063 //=============================================================================
00064 Configuration PL_Neural::ClampToJointLimits( const Configuration& c ) const
00065 {
00066     int i;
00067     int size = c.DOF();
00068     Configuration returnMe = c;
00069     for( i = 0; i < size; ++i )
00070     {
00071         double min = collisionDetector->JointMin( i );
00072         double max = collisionDetector->JointMax( i );
00073         returnMe[ i ] = Clamp( returnMe[ i ], min, max );
00074     }
00075     return returnMe;
00076 }
00077 
00078 //=============================================================================
00079 // PL_Neural::ClosestObstacleToEdge
00080 //=============================================================================
00081 int PL_Neural::ClosestObstacleToEdge ( const unsigned int edgeNum ) const
00082 {
00083     int size = m_ObstacleLocations.size();
00084     if( size == 0 )
00085     {
00086         return -1;
00087     }
00088     const Configuration& c0 = m_Path[ edgeNum + 0 ];
00089     const Configuration& c1 = m_Path[ edgeNum + 1 ];
00090 
00091     double bestDist = DistanceSquared( c0, c1, m_ObstacleLocations[ 0 ] );
00092     int    bestObstacle = 0;
00093     int i;
00094     for( i = 0; i < size; ++i )
00095     {
00096         const Configuration& p = m_ObstacleLocations[ i ];
00097         double distanceSqr = DistanceSquared( c0, c1, p );
00098         if( distanceSqr < bestDist )
00099         {
00100             bestDist = distanceSqr;
00101             bestObstacle = i;
00102         }
00103     }
00104     return bestObstacle;
00105 }
00106 
00107 //=============================================================================
00108 // PL_Neural::ClosestObstacleToPoint
00109 //=============================================================================
00110 int PL_Neural::ClosestObstacleToPoint( const Configuration& c ) const
00111 {
00112     int size = m_ObstacleLocations.size();
00113     if( size == 0 )
00114     {
00115         return -1;
00116     }
00117 
00118     double closestDistanceSquared = ( m_ObstacleLocations[ 0 ] - c ).MagSquared();
00119     int bestPoint = 0;
00120     int i;
00121     for( i = 0; i < size; ++i )
00122     {
00123         double distanceSqr = ( m_ObstacleLocations[ i ] - c ).MagSquared();
00124         if( distanceSqr < closestDistanceSquared )
00125         {
00126             closestDistanceSquared = distanceSqr;
00127             bestPoint = i;
00128         }
00129     }
00130     return bestPoint;
00131 }
00132 
00133 //=============================================================================
00134 // PL_Neural::DrawExplicit
00135 //=============================================================================
00136 bool PL_Neural::DrawExplicit() const
00137 {
00138         Semaphore semaphore( this->guid );
00139         semaphore.Lock();
00140     Color::yellow_50.GlDraw();
00141     Draw( m_Path );
00142 
00143     //
00144     // Draw obstacle locations
00145     //
00146     Color::red.GlDraw();
00147     glBegin( GL_POINTS );
00148     int i;
00149     int size = m_ObstacleLocations.size();
00150     for( i = 0; i < size; ++i )
00151     {
00152         const Configuration& c = m_ObstacleLocations[ i ];
00153         Draw( c );
00154     }
00155     glEnd();
00156 
00157     semaphore.Unlock();
00158     return false;
00159 }
00160 
00161 //=============================================================================
00162 // PL_Neural::DrawUniversePortion
00163 //=============================================================================
00164 void PL_Neural::DrawUniversePortion() const
00165 {
00166         Semaphore semaphore( guid );
00167         semaphore.Lock();
00168 
00169         glDisable( GL_LIGHTING );
00170         glShadeModel( GL_SMOOTH );
00171     glPointSize( 2.0 );
00172 
00173     Color::yellow_50.GlDraw();
00174     glPointSize( 2.0f );
00175     glLineWidth( 1.0f );
00176     DrawOverlay( m_Path );
00177 
00178     glDisable( GL_DEPTH_TEST );
00179     //
00180     // Draw obstacle locations
00181     //
00182     glBegin( GL_POINTS );
00183     Color::red.GlDraw();
00184     int i;
00185     int size = m_ObstacleLocations.size();
00186     for( i = 0; i < size; ++i )
00187     {
00188         const Configuration& c = m_ObstacleLocations[ i ];
00189         DrawOverlay( c );
00190     }
00191     glEnd();
00192 
00193     //
00194     // draw repulsion vectors
00195     //
00196 /*
00197     int x;
00198     int y;
00199     Color::cyan.GlDraw();
00200     for( x = -10; x < 10; ++x )
00201     {
00202         for( y = -10; y < 10; ++y )
00203         {
00204             Configuration config( VectorN( x, y, 0 ) );
00205             Configuration r = RepulsiveVector( config );
00206             r.Normalize();
00207             r *= 0.5;
00208             DrawArrorOverlay( config, r );
00209         }
00210     }
00211 */
00212     semaphore.Unlock();
00213 }
00214 
00215 //=============================================================================
00216 // PL_Neural::EdgeInCollision
00217 //=============================================================================
00218 int PL_Neural::EdgeInCollision() const
00219 {
00220     int i;
00221     int size = m_Path.Size() - 1;
00222     int returnMe = -1;
00223     for( i = 0; i < size; ++i )
00224     {
00225         const Configuration& c0 = m_Path[ i + 0 ];
00226         const Configuration& c1 = m_Path[ i + 1 ];
00227         bool collision = collisionDetector->IsInterferingLinear( c0, c1 );
00228         if( collision )
00229         {
00230             Configuration c = collisionDetector->GetLastIntersection();
00231             AddObstaclePoint( c );
00232             returnMe = i;
00233         }
00234     }
00235     return returnMe;
00236 }
00237 
00238 //=============================================================================
00239 // PL_Neural::GenerateRandomConfig 
00240 //=============================================================================
00241 Configuration PL_Neural::EdgeRepulsion( const unsigned int edgeNum ) const
00242 {
00243     Configuration repulsion = m_Path[ 0 ] * 0.0;
00244     Configuration c0 = m_Path[ edgeNum + 0 ];
00245     Configuration c1 = m_Path[ edgeNum + 1 ];
00246 
00247     int i;
00248     int size = m_ObstacleLocations.size();
00249     for( i = 0; i < size; ++i )
00250     {
00251         Configuration obstacleLocation = m_ObstacleLocations[ i ];
00252         VectorN closestPoint = ClosestPoint( c0, c1, obstacleLocation );
00253         closestPoint -= obstacleLocation;
00254         double magSquared = closestPoint.MagSquared();
00255         if( magSquared == 0.0 )
00256         {
00257             closestPoint *= 0.0;
00258         }
00259         else
00260         {
00261             closestPoint /= magSquared;
00262         }
00263         repulsion += closestPoint;
00264     }
00265 
00266     return repulsion;
00267 }
00268 
00269 //=============================================================================
00270 // PL_Neural::GenerateRandomConfig 
00271 //=============================================================================
00272 Configuration PL_Neural::GenerateRandomConfig () const
00273 {
00274     Configuration returnMe = GetStartConfig();
00275     int i;
00276     int size = returnMe.Size();
00277     for( i = 0; i < size; ++i )
00278     {
00279         double max = collisionDetector->JointMax( i );
00280         double min = collisionDetector->JointMin( i );
00281         double random = rand() / static_cast< double >( RAND_MAX );
00282         random = min + random * ( max - min );
00283         returnMe[ i ] = random;
00284     }
00285     return returnMe;
00286 }
00287 
00288 //=============================================================================
00289 // PL_Neural::NodesInCollision
00290 //=============================================================================
00291 int PL_Neural::NodesInCollision() const
00292 {
00293     int nodeInCollision = -1;
00294     int i;
00295     int size = m_Path.Size();
00296     for( i = 1; i < size - 1; ++i )
00297     {
00298         const Configuration& c = m_Path[ i ];
00299         bool collision = collisionDetector->IsInterfering( c );
00300         if( collision )
00301         {
00302             AddObstaclePoint( c );
00303             nodeInCollision = i;
00304         }
00305     }
00306     return nodeInCollision;
00307 }
00308 
00309 //=============================================================================
00310 // PL_Neural::Perturb
00311 //=============================================================================
00312 void PL_Neural::Perturb( const unsigned int pointNum )
00313 {
00314     if( pointNum == 0 )
00315     {
00316         return;
00317     }
00318     unsigned int size = m_Path.Size();
00319     if( pointNum == size - 1 )
00320     {
00321         return;
00322     }
00323     
00324     Configuration randomDirection = GenerateRandomConfig();
00325     m_Path[ pointNum ] += randomDirection * 0.5;
00326 }
00327 
00328 //=============================================================================
00329 // PL_Neural::Plan 
00330 //=============================================================================
00331 bool PL_Neural::Plan()
00332 {
00333     //
00334     // Initialize the planner
00335     //
00336     const Configuration& start = GetStartConfig();
00337     const Configuration& goal =  GetGoalConfig();
00338 
00339     int i;
00340     int size = 10;
00341     for( i = 0; i <= size; ++i )
00342     {
00343         double percent = static_cast< double >( i ) / size;
00344         m_Path.AppendPoint( start + ( goal - start ) * percent );
00345     }
00346 
00347     for( i = 0; i <= size; ++i )
00348     {
00349         Perturb( i );
00350     }
00351 
00352 
00353         StartTimer();
00354         while( !HasTimeLimitExpired() )
00355         {
00356                 Semaphore semaphore( guid );
00357                 semaphore.Lock();
00358             RelaxUntilSettled();
00359             bool obstaclesPresent = CheckPathForObstacles();        
00360                 semaphore.Unlock();
00361 
00362         if( !obstaclesPresent )
00363         {
00364             path = m_Path;
00365             return true;
00366         }
00367         else
00368         {
00369             int i;
00370             int size = m_Path.Size() - 1;
00371             for( i = 1; i < size; ++i )
00372             {
00373                 //Perturb( i );
00374             }
00375         }
00376         }
00377         return false;
00378 }
00379 
00380 //=============================================================================
00381 // PL_Neural::Relax
00382 //=============================================================================
00383 void PL_Neural::Relax( const unsigned int pointNum )
00384 {
00385     if( pointNum == 0 )
00386     {
00387         return;
00388     }
00389     unsigned int size = m_Path.Size();
00390     if( pointNum == size - 1 )
00391     {
00392         return;
00393     }
00394 
00395     double length = m_Path.PhysicalLength();
00396     length /= size;
00397     length *= 0.8;
00398     
00399     const Configuration& p0 = m_Path[ pointNum - 1 ];
00400     const Configuration& p1 = m_Path[ pointNum - 0 ];
00401     const Configuration& p2 = m_Path[ pointNum + 1 ];
00402 
00403     const Configuration v0 = p1 - p0;
00404     const Configuration v1 = p1 - p2;
00405 
00406     double d0 = ( v0 ).Magnitude();
00407     double d1 = ( v1 ).Magnitude();
00408     d0 -= length;
00409     d1 -= length;
00410     Configuration repulsiveVector = v0 * ( -d0 ) + v1 * ( -d1 );
00411     //const Configuration repulsiveForce = RepulsiveVector( p1 ) * 0.0;
00412     //Configuration attractionForce = 0.5 * p0 - p1 + 0.5 * p2;
00413     Configuration offset = 0.01 * repulsiveVector;
00414     m_Path[ pointNum ] += offset;
00415 }
00416 
00417 //=============================================================================
00418 // PL_Neural::RelaxUntilSettled
00419 //=============================================================================
00420 void PL_Neural::RelaxUntilSettled()
00421 {
00422     //
00423     // relax all the nodes until they settle down
00424     //
00425     int count;
00426     for( count = 0; count < 20; ++count )
00427     {
00428         ClampAllPointsToJointLimits();
00429         int size = m_Path.Size();
00430         int i;
00431         for( i = 1; i < size; ++i )
00432         {
00433             Relax( i );
00434         }
00435 
00436         size = m_Path.Size() - 1;
00437         for( i = 1; i < size; ++i )
00438         {
00439             Configuration repulsion = EdgeRepulsion( i ) * 0.01;
00440             double repusiveForce = repulsion.Magnitude();
00441             if( i != 0 )
00442             {
00443                 m_Path[ i + 0 ] += repulsion;
00444             }
00445             if( i != size - 1 )
00446             {
00447                 m_Path[ i + 1 ] += repulsion;
00448             }
00449         }
00450     }
00451 }
00452 
00453 //=============================================================================
00454 // PL_Neural::RepulsiveVector
00455 //=============================================================================
00456 Configuration PL_Neural::RepulsiveVector( const Configuration& c ) const
00457 {
00458     Configuration returnMe = c * 0.0;
00459     int size = m_ObstacleLocations.size();
00460     int i;
00461     for( i = 0; i < size; ++i )
00462     {
00463         Configuration ob = m_ObstacleLocations[ i ];
00464         ob -= c;
00465         ob *= -1;
00466         double mag = ob.MagSquared();
00467         if( mag != 0.0 )
00468         {
00469             ob /= mag;   
00470         }
00471         returnMe += ob;
00472     }
00473     return returnMe;
00474 }

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