collisiondetectors/CD_rangesensor/CD_Range_Sensor.cpp

Go to the documentation of this file.
00001 // CD_Range_Sensor
00002 #include "CD_Range_Sensor.h"
00003 
00004 //#include <stdlib.h>
00005 
00006 
00007 CD_Range_Sensor::CD_Range_Sensor(Universe& universe)
00008 //note: is CD_BasicStyle the appropriate parent???
00009 //I hope this doesn't do anything with the universe because it's not the universe
00010 //we want to use for the sensor based collison dectection
00011 : 
00012         CollisionDetectorBase( universe ),
00013         CD_BasicStyle( universe ),
00014         CD_LinearContinuous( universe ),
00015         CD_Linear( universe )
00016 {
00017         //TRACE("\nCD_Range_Sensor::CD_Range_Sensor(u) constructor");
00018         int i,numfreeblocks;
00019         unsigned int randseed;
00020         bool loadfromfile;
00021         
00023         //  It is REQUIRED that the universe passed into the object
00024         //  does not move for the life of the CD_Range_Sensor object.
00025         //  (used in the take_picture method)
00027         up = &universe;
00028         char marker[ 300 ] = "" ;
00029         cubic worldextents; //the maximum volume of scannable space around robot
00030         cubic newblocksize; //the assumed free space around robot
00031                 
00032         ifstream is(CD_Range_Sensor_Settings_Filename);
00033         
00034         eatwhite( is ) ;
00035         is.getline( marker, 300, ' ' ) ;
00036         assert( strcmp( marker, "#maxlevel" ) == 0 ) ;
00037         is >> dataFuser.maxlevel ;
00038         assert (dataFuser.maxlevel > 0);
00039         
00040         eatwhite( is ) ;
00041         is.getline( marker, 300, ' ' ) ;
00042         assert( strcmp( marker, "#octree_display_mode" ) == 0 ) ;
00043         //Only display octree in mesh form in multithreaded mode
00044         is >> dataFuser.octree_display_mode ;
00045         if (isMultiThreaded == false)
00046         {
00047                 dataFuser.octree_display_mode = octree_nodisplay;
00048         }
00049 
00050   eatwhite( is ) ;
00051         is.getline( marker, 300, ' ' ) ;
00052         assert( strcmp( marker, "#track_sensed_obstacles" ) == 0 ) ;
00053         is >> dataFuser.track_sensed_obstacles ;
00054         
00055         eatwhite( is ) ;
00056         is.getline( marker, 300, ' ' ) ;
00057         assert( strcmp( marker, "#savetofile" ) == 0 ) ;
00058         is >> savetofile ;
00059         
00060         eatwhite( is ) ;
00061         is.getline( marker, 300, ' ' ) ;
00062         assert( strcmp( marker, "#loadfromfile" ) == 0 ) ;
00063         is >> loadfromfile ;
00064         
00065         eatwhite( is ) ;
00066         is.getline( marker, 300, ' ' ) ;
00067         assert( strcmp( marker, "#worldextents" ) == 0 ) ;
00068         is >> dataFuser.scalefactor ;
00069         //constant 128.0 due to octree algorithim hard coded limit of world extents
00070         dataFuser.scalefactor = float(128.0/dataFuser.scalefactor);
00071         
00072         eatwhite( is ) ;
00073         is.getline( marker, 300, ' ' ) ;
00074         assert( strcmp( marker, "#expected_vertexes" ) == 0 ) ;
00075         is >> dataFuser.expected_vertexes ;
00076         dataFuser.expected_facets = dataFuser.expected_vertexes/2;
00077         dataFuser.expected_squarevectors = dataFuser.expected_vertexes*2/3;
00078 
00079         eatwhite( is ) ;
00080         is.getline( marker, 300, ' ' ) ;
00081         assert( strcmp( marker, "#randseed" ) == 0 ) ;
00082         is >> randseed ;
00083         srand(randseed);
00084         
00085         if (loadfromfile)
00086         {
00087                 dataFuser.Load_State(CD_Range_Sensor_Octree_Filename);
00088         } else
00089         {
00090                 eatwhite( is ) ;
00091                 is.getline( marker, 300, ' '  ) ;
00092                 assert( strcmp( marker, "#worldlowpoint" ) == 0 ) ;
00093                 is >> worldextents.x0;
00094                 is >> worldextents.y0;
00095                 is >> worldextents.z0;
00096         
00097                 eatwhite( is ) ;
00098                 is.getline( marker, 300, ' '  ) ;
00099                 assert( strcmp( marker, "#worldhighpoint" ) == 0 ) ;
00100                 is >> worldextents.x1;
00101                 is >> worldextents.y1;
00102                 is >> worldextents.z1;
00103         
00104                 eatwhite( is ) ;
00105                 is.getline( marker, 300, ' ' ) ;
00106                 assert( strcmp( marker, "#numfreeblocks" ) == 0 ) ;
00107                 is >> numfreeblocks ;
00108                 assert (numfreeblocks > 0);
00109         
00110                 for (i= 0; i < numfreeblocks; i++)
00111                 {
00112                         eatwhite( is ) ;
00113                         is.getline( marker, 300, ' '  ) ;
00114                         assert( strcmp( marker, "#freelowpoint" ) == 0 ) ;
00115                         is >> newblocksize.x0;
00116                         is >> newblocksize.y0;
00117                         is >> newblocksize.z0;
00118                         
00119                         eatwhite( is ) ;
00120                         is.getline( marker, 300, ' '  ) ;
00121                         assert( strcmp( marker, "#freehighpoint" ) == 0 ) ;
00122                         is >> newblocksize.x1;
00123                         is >> newblocksize.y1;
00124                         is >> newblocksize.z1;
00125                         
00126                         dataFuser.Add_Block( worldextents, newblocksize );
00127                 }
00128         }
00129         
00130         is.close();
00131         
00132         //grab a universe with only the robot in it:
00133     
00134         allorigEntities.clear();
00135         allorigEntities = universe.GetAllEntities() ;
00136         
00137         //note: the universe copy constructor seems unreliable
00138         //robot_universe = universe;
00139         
00140         //  Take the passed in Universe object, and scan through to the find all
00141         //  RobotBase objects.
00142         robot_universe.Empty();
00143         int size = allorigEntities.size() ;
00144         for( i = 0; i < size; i++ )
00145         {
00146                 const R_OpenChain* r_openchain = dynamic_cast< const R_OpenChain* >( allorigEntities[ i ] ) ;
00147                 if( r_openchain != NULL )
00148                 {
00149                         //  Then, using AddEntity() add them to a custom universe object.  This will
00150                         //  have the effect of copying all the robot geometries but none of geometries
00151                         //  for the rest of the world.
00152                         Entity* addme = allorigEntities[ i ]->Clone() ;
00153                         addme->SetFrameManager( robot_universe.GetFrameManager() ) ;
00154                         robot_universe.AddEntity( addme );
00155                         //int size = robot_universe.GetFrameManager()->GetNumberOfFrames() ;
00156                         delete addme;
00157                         //TRACE("\nR_OpenChain found.");
00158                 }
00159         }
00160   lv = NULL;
00161   lv_obstacle = NULL;
00162         
00163         //always create white octree node mesh in beginning in case user wants to use it later
00164         dataFuser.Convert(lv, lv_obstacle, robot_universe, false);
00165 
00166 }
00167 
00168 CD_Range_Sensor::CD_Range_Sensor (const CD_Range_Sensor& right)
00169 //I hope this doesn't do anything with the universe because it's not the universe
00170 //we want to use for the sensor based collison dectection
00171 : 
00172         CollisionDetectorBase( right ),
00173         CD_BasicStyle( right ),
00174         CD_LinearContinuous( right ),
00175         CD_Linear( right )
00176 {
00177         this->dataFuser = right.dataFuser;
00178         this->savetofile = right.savetofile;
00179         this->isMultiThreaded = right.isMultiThreaded;
00180         this->allorigEntities = right.allorigEntities;
00181         this->lv = dynamic_cast<CD_Vcollide *>(right.lv->Clone());
00182         this->lv_obstacle = dynamic_cast<CD_Vcollide *>(right.lv_obstacle->Clone());
00183         
00184         //  Take the passed in right Universe object, and scan through to the find all
00185         //  RobotBase objects.
00186         
00187         //note: the universe copy constructor seems unreliable
00188         //      this->robot_universe = right.robot_universe;
00189 
00190         std::vector< Entity* > tempEntities;
00191         tempEntities.clear();
00192         tempEntities = right.robot_universe.GetAllEntities() ;
00193         
00194         this->robot_universe.Empty();
00195         int size = tempEntities.size() ;
00196         for( int i = 0; i < size; i++ )
00197         {
00198                 const R_OpenChain* r_openchain = dynamic_cast< const R_OpenChain* >( tempEntities[ i ] ) ;
00199                 if( r_openchain != NULL )
00200                 {
00201                         //  Then, using AddEntity() add them to a custom universe object.  This will
00202                         //  have the effect of copying all the robot geometries but none of geometries
00203                         //  for the rest of the world.
00204                         Entity* addme = tempEntities[ i ]->Clone() ;
00205                         addme->SetFrameManager( this->robot_universe.GetFrameManager() ) ;
00206                         this->robot_universe.AddEntity( addme );
00207                         delete addme;
00208                 }
00209         }
00210         
00211 }
00212 
00213 //note: the following was just copied and converted from CD_Vcollide()
00214 CollisionDetectorBase* CD_Range_Sensor::Clone () const
00215 {
00216         CD_Range_Sensor* newCD_J = new CD_Range_Sensor( *this ) ;
00217         CD_InterfaceToCollisionQueries* CDitc = dynamic_cast< CD_Bool* >( newCD_J ) ;
00218         CollisionDetectorBase* returnMe = dynamic_cast< CollisionDetectorBase* >( CDitc );
00219         return returnMe ;
00220 }
00221 
00222 CD_Range_Sensor::~CD_Range_Sensor()
00223 {
00224         //TRACE("\nCD_Range_Sensor::~CD_Range_Sensor()");
00225 
00226         allorigEntities.clear();
00227 
00228         //delete local vcollide universe
00229         delete lv;
00230   delete lv_obstacle;
00231 }
00232 
00233 
00234 Range_Sensor* CD_Range_Sensor::FindFirstCamera (Entity* entity)
00235 {
00236         //TRACE("\nCD_Range_Sensor::FindFirstCamera()");
00237         
00238         Range_Sensor* camera;
00239         
00240         ObjectGroup* group = dynamic_cast< ObjectGroup* >( entity ) ;
00241         if( group != NULL )
00242         {
00243                 for( int i = 0; i < group->Size(); i++ )
00244                 {
00245                         const ObjectBase* addme = ( *group )[ i ] ;
00246                         //recursively look into objects for something a sensor can detect
00247                         camera = FindFirstCamera( dynamic_cast< Entity *> (const_cast<ObjectBase*>(addme)) ) ;
00248                 }
00249                 return camera;
00250         }
00251         
00252         camera = dynamic_cast< Range_Sensor* >( entity ) ;
00253         if( camera != NULL )
00254         {
00255                 //TRACE ("\ncamera found");
00256                 //Make sure the pointer to allorigEntites is still valid. (original Universe cannot move)
00257                 //only display 2D map when not multithreaded
00258                 camera->Take_Picture(allorigEntities, !isMultiThreaded);
00259                 dataFuser.Update(camera);
00260 
00261                 return camera;
00262         }
00263         //TRACE("\nFailed to find camera in bottom of objectgroup");
00264         return NULL;
00265 }
00266 
00267 void CD_Range_Sensor::Take_Picture(Configuration newconfig)
00268 {
00269         //TRACE("\nCD_Range_Sensor::Take_Picture()");
00270         //probe the first camera you find.
00271         
00272         //delete the huge lv var as soon as possible (they will always be replaced here)
00273         delete lv;
00274   delete lv_obstacle;
00275         
00276         Configuration oldconfig = up->GetConfiguration();
00277         //temporarily change the universe's configuration to the new "planning stage" one
00278         up->SetConfiguration(newconfig);
00279         
00280         Range_Sensor* camera;
00281         
00282         int size = allorigEntities.size() ;
00283         
00284         for( int i = 0; i < size; i++ )
00285         {
00286                 Entity* entity = allorigEntities[ i ] ;
00287                 //look for all cameras, and have them all take pictures
00288                 camera = FindFirstCamera (entity);
00289                 if (camera != NULL)
00290                 {
00291                         //TRACE("\nCamera found in Universe");
00292                 }
00293         }
00294                 
00295         //for debugging
00296         if (savetofile)
00297         {
00298                 dataFuser.Save_State(CD_Range_Sensor_Octree_Filename);
00299         }
00300         
00301 #ifdef WIN32
00302         dataFuser.cWindow_ptr = cWindow_ptr;
00303     dataFuser.hglrc_var = hglrc_var;
00304 #endif
00305         dataFuser.showconfig = newconfig;
00306 
00307         //next time local universe lu is used (possibly to display onscreen), it will have the right robot config
00308         //always create white octree node mesh in beginning in case user wants to see it later
00309         dataFuser.Convert(lv, lv_obstacle, robot_universe, true);
00310         
00311         //make sure we're not damaging anything else by resetting the old configuration.
00312         //(not sure if this is neccesscary)
00313         up->SetConfiguration(oldconfig);
00314         
00315 }
00316 
00317 
00318 bool CD_Range_Sensor::IsInterfering (const Configuration& config)
00319 {
00320         //TRACE("\nCD_Range_Sensor::IsInterfering");
00321   bool isinterfere = lv->IsInterfering (config);
00322 
00323   if (isinterfere == true)
00324   {
00325     if ( (lv_obstacle != NULL) && (lv_obstacle->IsInterfering (config)) )
00326     {
00327     }
00328   }
00329         
00330         //using the CD_vcollide, determine collision with this config
00331         return( isinterfere );  
00332 }

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