planners/rangesensor/PL_Range_Sensor.cpp

Go to the documentation of this file.
00001 #include <synchronization/semaphore.h>
00002 #include "PL_Range_Sensor.h"
00003 #include <gl\gl.h>
00004 
00005 
00006 
00007 PL_Range_Sensor::~PL_Range_Sensor()
00008 {
00009 }
00010 
00011 void PL_Range_Sensor::SetCollisionDetector (CD_BasicStyle* collisionDetector)
00012 {
00013   const CD_Range_Sensor * cd_range_sensor  = dynamic_cast< const CD_Range_Sensor * >( collisionDetector ) ;
00014   if( cd_range_sensor != NULL )
00015   {
00016         //set up the ACA planner which will be used for path planning through free space
00017     PL_HasCollisionDetector::SetCollisionDetector(collisionDetector);
00018     pl_juan.PL_HasCollisionDetector::SetCollisionDetector(collisionDetector);
00019     return;
00020   }
00021   //PL_Range_Sensor won't work without CD_Range_Sensor.
00022   assert(false);
00023 }
00024 
00025 bool PL_Range_Sensor::Plan ()
00026 {
00027   int i;
00028   Semaphore semaphore( guid );
00029 
00030   //TRACE("\nPL_Range_Sensor::Plan called");
00031   
00032   std::vector<Configuration> prevconfigs;
00033   Configuration current = GetStartConfig();
00034   Configuration offset ; 
00035   Configuration loopstartconfig;
00036   
00037   //we will return the path given by pl_juan
00038   path.Clear() ;
00039 
00040   SetTimeLimitInSeconds(120);
00041   StartTimer();
00042 
00043   prevconfigs.push_back( GetStartConfig() );
00044   Configuration intermediate = GetGoalConfig();
00045 
00046   //needed to display the local octree vcollide mesh
00047   dynamic_cast< CD_Range_Sensor* >(collisionDetector)->isMultiThreaded = this->isMultiThreaded;
00048   dynamic_cast< CD_Range_Sensor* >(collisionDetector)->cWindow_ptr = this->cWindow_ptr;
00049   dynamic_cast< CD_Range_Sensor* >(collisionDetector)->hglrc_var = this->hglrc_var;
00050 
00051   //utility feature: just take a picture if we're already at the goal
00052   if( GetStartConfig() == GetGoalConfig() )
00053   {
00054     //TRACE("\nstartConfig == goalConfig, just taking a picture");
00055     collisionDetector->SetConfiguration( GetStartConfig() ) ;
00056     //take a picture which deletes the planner window information for a time, so grab semaphore
00057     semaphore.Lock();
00058     dynamic_cast< CD_Range_Sensor * >(collisionDetector)->Take_Picture( GetStartConfig() );
00059     semaphore.Unlock();
00060     return false;
00061   }
00062     
00063   while (1)
00064   {    
00065     //try to make it from startConfig to goalConfig, using PL_Juan;
00066     if (pl_juan.Plan() == true)
00067     {
00068       //if made it to goal successfully, exit
00069       PA_Points* pathp;
00070           //copy path known by pl_juan to our returned path
00071       pathp = dynamic_cast<PA_Points*>(const_cast<PathBase*>(pl_juan.GetPath()));
00072       assert(pathp != NULL);
00073       path = *pathp;
00074       return true;
00075     }
00076     
00077     //else, move arm to midpoint between current spot and collision, using PL_Linear's method
00078 
00079         //these finite # steps will simulate movement untill we hit occupied/unknown space
00080     const long int steps = 50 ;
00081     
00082     //on 1st run, current == startConfig;
00083     loopstartconfig = current;
00084     offset = intermediate - current ; //IMPROVE: joint limits mean that it won't be as simple as this
00085     for( i = 0; i <= steps; i++ )
00086     {
00087       if( collisionDetector->IsInterfering( current ) )
00088       {
00089         break;
00090       }
00091       
00092       current += ( offset * (1.0 / steps ) ) ;
00093     }
00094 
00095     //if we hit something, move to halfway point between hit and loop start configs
00096         if (i <= steps)
00097     {
00098       current = (current + loopstartconfig) / 2;
00099     }
00100     
00101     //we better not be hitting anything at this halfway point.
00102     //if we are, then grab another random point and try again.
00103     if (collisionDetector->IsInterfering( current ) == false)
00104     {      
00105       collisionDetector->SetConfiguration( current ) ;
00106       
00107       //take a picture which deletes the planner window information for a time, so grab semaphore
00108       semaphore.Lock();
00109       dynamic_cast< CD_Range_Sensor * >(collisionDetector)->Take_Picture( current );
00110           semaphore.Unlock();
00111     } else
00112     {
00113       current = loopstartconfig;
00114       //TRACE("\nHalfway point interferrence detected");
00115     }
00116     
00117     //GenerateRandomConfig
00118     intermediate = GenerateRandomConfig() ;
00119     //check the timer 
00120     //if not timeout, return to start of the loop
00121     if( HasTimeLimitExpired() == true )
00122     {
00123       return false ;
00124     }
00125   }
00126 
00127   //control should never get here
00128   assert (false);
00129   return false ;
00130 }
00131 
00132 void PL_Range_Sensor::SetStartConfig (const Configuration& configuration)
00133 {
00134   PL_HasCollisionDetector::SetStartConfig( configuration );
00135   pl_juan.SetStartConfig( configuration ) ;
00136 }
00137 
00138 void PL_Range_Sensor::SetGoalConfig (const Configuration& configuration)
00139 {
00140   PL_HasCollisionDetector::SetGoalConfig( configuration );
00141   pl_juan.SetGoalConfig( configuration ) ;
00142 }
00143 
00144 Configuration PL_Range_Sensor::GenerateRandomConfig () const
00145 {
00146   int dof = GetStartConfig().DOF() ;
00147   Configuration returnme ;
00148   returnme.SetLength( dof ) ;
00149   
00150   //TRACE("\nPL_Range_Sensor::GenerateRandomConfig");
00151   
00152   //a chance for intermediate config to be set to goal config
00153   if (rand() > RAND_MAX*0.8)
00154   {
00155     //TRACE("\nIntermediate config set to goal config");
00156     return GetGoalConfig();
00157   }
00158   
00159   //generate a random value for all joint variables
00160   for( int i = 0; i < dof; i++ )
00161   {
00162     double max = collisionDetector->JointMax( i ) ;
00163     double min = collisionDetector->JointMin( i ) ;
00164     double random = double( rand() ) / RAND_MAX ; //this is a random number between [0..1]
00165     returnme[ i ] = min + ( max - min ) * random ;
00166   }
00167   
00168   return returnme ;
00169 }
00170 
00171 bool PL_Range_Sensor::DrawExplicit () const
00172 {
00173         Semaphore semaphore( this->guid );
00174         semaphore.Lock();
00175         CD_Range_Sensor* cdRangeSensor = dynamic_cast< CD_Range_Sensor* >( this->collisionDetector );
00176         //use dataFuser to display contents of collision detector
00177         cdRangeSensor->dataFuser.GL_Display_Octree();
00178         semaphore.Unlock();
00179         return true;
00180 };

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