collisiondetectors/CD_rangesensor/Octree_Data_Fuser.cpp

Go to the documentation of this file.
00001 #pragma warning( disable : 4786 )
00002 
00003 //Octree_Data_Fuser
00004 #include "Octree_Data_Fuser.h"
00005 #include <gl/gl.h>
00006 #include <opengl/gl_material.h>
00007 
00008 
00009 Octree_Data_Fuser::Octree_Data_Fuser()
00010 {
00011   this->maxlevel = 6;
00012   this->octree_display_mode = octree_whitedisplay;
00013   this->scalefactor = 128.0;  //<- the default used by Yong's octree code
00014   this->expected_vertexes = 80000;
00015   this->expected_facets =  40000;
00016   this->expected_squarevectors = 53333;
00017   
00018   root2 = create_node (BLACK);
00019   root2->father = NULL;
00020   this->lu = NULL;
00021   this->display_lu = NULL;
00022   this->track_sensed_obstacles = false;
00023   
00024   obstacle_points.clear();
00025   
00026 }
00027 
00028 Octree_Data_Fuser::Octree_Data_Fuser (const Octree_Data_Fuser& right)
00029 //I hope this doesn't do anything with the universe because it's not the universe
00030 //we want to use for the sensor based collison dectection
00031 {
00032   TRACE("\n(**warning: untested)Octree_Data_Fuser copy constructor");
00033   
00034   this->maxlevel = right.maxlevel;
00035   this->octree_display_mode = right.octree_display_mode;
00036   this->scalefactor = right.scalefactor;  //where 30.0 is the world x,y and z extents from (0,0,0)
00037   this->expected_vertexes = right.expected_vertexes;
00038   this->expected_facets =  right.expected_facets;
00039   this->expected_squarevectors =  right.expected_squarevectors;
00040   
00041   this->root2 = copy (right.root2); //(ie. deep copy) (assumed free space around robot also copied)
00042   this->lu = dynamic_cast<GL_Universe *>(right.lu->Clone());
00043   this->display_lu = dynamic_cast<GL_Universe *>(right.display_lu->Clone());
00044   this->track_sensed_obstacles = right.track_sensed_obstacles;
00045   
00046   this->obstacle_points = right.obstacle_points;
00047   
00048 }
00049 
00050 
00051 
00052 Octree_Data_Fuser::~Octree_Data_Fuser()
00053 {
00054   //delete all octree nodes, free_space struct
00055   delete_node (root2);
00056   //delete display local universe
00057   if (display_lu != NULL)
00058   {
00059     delete display_lu;
00060     display_lu = NULL;
00061   }
00062 }
00063 
00064 
00065 void Octree_Data_Fuser::new_local_universe (Universe &robot_universe)
00066 {
00067   std::vector< Entity* > tempEntities;
00068   tempEntities.clear();
00069   tempEntities = robot_universe.GetAllEntities() ;
00070   
00071   //  Take the passed in Universe object, and scan through to the find all
00072   //  RobotBase objects.
00073   
00074   lu = new GL_Universe; 
00075   lu->Empty();
00076   int tsize = tempEntities.size() ;
00077   for( int i = 0; i < tsize; i++ )
00078   {
00079     const R_OpenChain* r_openchain = dynamic_cast< const R_OpenChain* >( tempEntities[ i ] ) ;
00080     if( r_openchain != NULL )
00081     {
00082       //  Then, using AddEntity() add them to a custom universe object.  This will
00083       //  have the effect of copying all the robot geometries but none of geometries
00084       //  for the rest of the world.
00085       Entity* addme = tempEntities[ i ]->Clone() ;
00086       addme->SetFrameManager( lu->GetFrameManager() ) ;
00087       lu->AddEntity( addme );
00088       //int size = lu->GetFrameManager()->GetNumberOfFrames() ;
00089       delete addme;
00090       addme = NULL;
00091       //TRACE("\nR_OpenChain found.");
00092     }
00093   }
00094 }
00095 
00096 void Octree_Data_Fuser::Add_Block(cubic worldextents, cubic newblocksize)
00097 {
00098   OctreeNode *root,*union_result;
00099   
00100   root = create_block_node(0,&newblocksize,&worldextents,maxlevel);
00101   root->father = NULL;
00102   union_result = union_node (root,root2);
00103   delete_node (root);
00104   delete_node (root2);
00105   root2 = union_result;
00106 }
00107 
00108 void Octree_Data_Fuser::Save_State(const char * filename)
00109 //saves current octree to disk.
00110 {
00111   //TRACE("\nOctree_Data_Fuser::Save_State()");
00112   FILE *fpointer;
00113   
00114   fpointer = fopen (filename,"w");
00115   
00116   //root2 should already be cleaned
00117   //clean (root2);
00118   reset_bitbuckets ();
00119   save_node(root2,fpointer);  
00120   fclose (fpointer);
00121   
00122 }
00123 
00124 void Octree_Data_Fuser::Load_State(const char * filename)
00125 //loads inital octree file from disk.
00126 {
00127   //TRACE("\nOctree_Data_Fuser::Load_State()");
00128   //struct node * retvalue;
00129   FILE *fpointer;
00130   
00131   delete_node(root2);
00132   fpointer = NULL;
00133   fpointer = fopen (filename,"rb");
00134   assert(fpointer != NULL);
00135   reset_bitbuckets ();
00136   root2 = read_node(fpointer);
00137   root2->father = NULL;
00138   
00139   fclose (fpointer);
00140 }
00141 
00142 void Octree_Data_Fuser::GL_Display_Octree ()
00143 {
00144   //display robot and octree mesh in main robot window
00145   //    BOOL success = wglMakeCurrent( this->cWindow_ptr->GetDC()->m_hDC, hglrc_var ); // call OpenGL APIs as desired ... 
00146   if( display_lu != NULL )
00147   {
00148     ::glClearColor( 1.0, 1.0, 1.0, 1.0 );
00149     ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00150     
00151     glEnable(GL_LIGHTING) ;             
00152     glEnable(GL_BLEND) ;        
00153     glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, 1 );
00154     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
00155     //glShadeModel( GL_FLAT ) ;
00156     glShadeModel( GL_SMOOTH ) ;
00157     
00158     double r = 0.8f ;
00159     double g = 0.8f ;
00160     double b = 0.8f ;
00161     float ambient[]             = { 0, 0, 0 } ; 
00162     float diffuse[]             = { r, g, b } ; 
00163     float specular[]    = { r, g, b } ; 
00164     float position[ ]   = {50, 50, 50, 1};
00165     
00166     glEnable( GL_LIGHTING );
00167     glEnable( GL_LIGHT0 ) ;
00168     glLightfv( GL_LIGHT0, GL_POSITION, position ) ;
00169     glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
00170     glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
00171     glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
00172     
00173     //::glDisable( GL_DEPTH_TEST );
00174     GL_Material& matTransparentGreen = GL_Material::matGreenPlastic ;
00175     matTransparentGreen.SetTransparancy( 1.0 );
00176     matTransparentGreen.GLDraw() ;
00177     display_lu->GLDraw();
00178   }
00179   //::glFlush();
00180   //glUniverse->GLDraw();
00181   //    HDC hdc = this->cWindow_ptr->GetSafeHdc();
00182   //    BOOL swapSuccess = wglSwapLayerBuffers( this->cWindow_ptr->GetDC()->m_hDC, WGL_SWAP_MAIN_PLANE );
00183   //    success = wglMakeCurrent( NULL, NULL );
00184 }
00185 
00186 
00187 
00188 
00189 
00190 void Octree_Data_Fuser::Update (Range_Sensor *camera)
00191 {
00192                 //TRACE("\nAfter.Ray Depth map maxrange is: %f, angle is %f",camera->GetMaxRange(), camera->GetAngle());
00193                 //TRACE("\nAfter.Ray Coord map middle is: %f,%f,%f",camera->ray_coord_map[128][128][0],camera->ray_coord_map[128][128][1],camera->ray_coord_map[128][128][2]);
00194                 //keep the huge free_space var alive for as short a time as possible
00195     
00196     //adjust scalefactor before passing pic into octree library
00197     for (int i=0; i< 256; i++)
00198     {
00199       for (int j=0; j < 256; j++)
00200       {  
00201         camera->ray_coord_map[i][j][0] = camera->ray_coord_map[i][j][0] * scalefactor ;
00202         camera->ray_coord_map[i][j][1] = camera->ray_coord_map[i][j][1] * scalefactor ;
00203         camera->ray_coord_map[i][j][2] = camera->ray_coord_map[i][j][2] * scalefactor ;
00204       }
00205     }
00206     
00207     //update set containing obstacle points
00208     if (track_sensed_obstacles)
00209     {
00210       cubic_d worldsize;
00211   
00212       // using scalefactor, scale worldsize to fit with Yong's octree algorithim worldsize
00213       worldsize.x0 = worldsize.y0 = worldsize.z0 = -128.0 ;
00214       worldsize.x1 = worldsize.y1 = worldsize.z1 = 127.0 ; 
00215 
00216       update_cubes_set (obstacle_points, camera, root2, worldsize);
00217     }
00218 
00219     //update octree containing free/unknown space
00220     OctreeNode *root,*union_result;
00221         struct free_space* pic;
00222 
00223     pic = new free_space;
00224     pic->apex.x = camera->ray_source[0] * scalefactor ;
00225     pic->apex.y = camera->ray_source[1] * scalefactor ;
00226     pic->apex.z = camera->ray_source[2] * scalefactor ;
00227 
00228     //am passing in camera only to give the ray_coord_map
00229     root = construct_octree_wrapper(pic,maxlevel,camera);
00230     delete pic;
00231     pic = NULL;
00232     
00233     union_result = union_node (root,root2);
00234     delete_node(root);
00235     delete_node(root2);
00236     root2 = union_result;               
00237     //root is deleted by union_node?
00238     
00239     clean (root2);
00240 
00241 }
00242 
00243 
00244 
00245 void Octree_Data_Fuser::Convert ( CD_Vcollide* &lv_free,  CD_Vcollide* &lv_obstacle, 
00246                             Universe &robot_universe, bool valid_config)
00247 {
00248   //CD_Vcollide* lv;
00249   GL_Mesh* mesh;
00250   
00251   std::vector<Square> squarevector;
00252   squarevector.reserve(expected_squarevectors);
00253   
00254   
00255   cubic_d worldsize;
00256   
00257   // using scalefactor, scale worldsize to scale with Yong's octree algorithim size
00258   // back up to orginal size
00259   worldsize.x0 = worldsize.y0 = worldsize.z0 = -(1.0/scalefactor)*128.0 ;
00260   worldsize.x1 = worldsize.y1 = worldsize.z1 = (1.0/scalefactor)*127.0 ; 
00261   
00262   if (lu != NULL)
00263   {
00264     delete lu;
00265     lu = NULL;
00266   }
00267   if (display_lu != NULL)
00268   {
00269     delete display_lu;
00270     display_lu = NULL;
00271   }
00272   
00273   new_local_universe (robot_universe);
00274   
00275   //only care about updating config if we currently have a valid one
00276   if (valid_config)
00277   {    
00278     if (track_sensed_obstacles)
00279     {
00280       mesh = new GL_Mesh(lu->GetFrameManager());
00281       
00282       mesh->GetVertexes().reserve( expected_vertexes );
00283       mesh->GetVertexes().reserve( expected_facets );
00284       mesh->SetName( "octreeMeshRed" );
00285       
00286       squarevector.clear();
00287       
00288       extract_cubes_set (obstacle_points, 1.0/scalefactor, squarevector, maxlevel);
00289       
00290       if (obstacle_points.size() > 0)
00291       {
00292         calc_cube_facets (squarevector, *mesh);
00293         //TRACE ("\nSize of (RED) intermediate mesh-> sqcap %d, vert %d, face %d",squarevector.size(),mesh->vertexes.size(), mesh->facets.size());
00294         
00295         //updating info on robot arm position is unnecesscary when the known/unknown boundary is not transparent
00296         lu->SetConfiguration(showconfig);
00297         
00298         lu->AddEntity(mesh);
00299         
00300         lv_obstacle = new CD_Vcollide (*lu);
00301         
00302         if (octree_display_mode == octree_obstacledisplay)
00303         {
00304           //display this local universe in Planner window (don't delete it, we need to display it)
00305           display_lu = lu;
00306         } else
00307         {
00308           //delete this lu if we don't need to display it
00309           delete lu;
00310         }
00311         
00312         new_local_universe(robot_universe);
00313       }
00314       delete mesh;
00315       mesh = NULL;
00316     }
00317     
00318     //updating info on robot arm position is unnecesscary when the known/unknown boundary is not transparent
00319     lu->SetConfiguration(showconfig);
00320   }
00321   
00322   if (octree_display_mode == octree_whitedisplay)
00323   {
00324     mesh = new GL_Mesh(lu->GetFrameManager());
00325     //expect to get an octree -> vcollide mesh of this size, to avoid costly resizing
00326     mesh->GetVertexes().reserve( expected_vertexes );
00327     mesh->GetFacets().reserve( expected_facets );
00328     mesh->SetName( "octreeMeshWhite" );
00329     
00330     squarevector.clear();
00331     
00332     //create a list of squares from the octree
00333     extract_block_node(root2, &worldsize, squarevector, true, WHITE);
00334     //create a GL_Mesh from optimized list of squares
00335     calc_cube_facets(squarevector, *mesh);
00336     
00337     //output the octree, in mesh form to a vcollide mesh
00338     lu->AddEntity(mesh);
00339     //TRACE ("\nSize of (WHITE) intermediate mesh: sqcap %d, vert %d, face %d",squarevector.capacity(),mesh->vertexes.size(), mesh->facets.size());
00340     
00341     //clone of mesh has been placed in universe, don't need the original anymore
00342     delete mesh;
00343     mesh = NULL;
00344     //display this local universe in Planner window (don't delete it, we need to display it)
00345     display_lu = lu;
00346     new_local_universe(robot_universe);
00347   }
00348   
00349   mesh = new GL_Mesh(lu->GetFrameManager());
00350   
00351   //expect to get an octree -> vcollide mesh of this size, to avoid costly resizing
00352   mesh->GetVertexes().reserve( expected_vertexes );
00353   mesh->GetFacets().reserve( expected_facets );
00354   mesh->SetName( "octreeMeshBlack" );
00355   
00356   squarevector.clear();
00357                 
00358   extract_block_node(root2, &worldsize, squarevector, true, BLACK);
00359   //push_back the facets
00360   calc_cube_facets(squarevector, *mesh);
00361   
00362   //free memory used by squarevector now, its not needed anymore
00363   squarevector.reserve(0);
00364   
00365   //output the octree, in mesh form to a vcollide mesh
00366   lu->AddEntity(mesh);
00367   //TRACE ("\nSize of (BLACK) intermediate mesh: vert %d, face %d",mesh->vertexes.size(), mesh->facets.size());
00368   
00369                 
00370   delete mesh;
00371   mesh = NULL;
00372   lv_free = new CD_Vcollide (*lu);
00373   
00374   if (octree_display_mode == octree_blackdisplay)
00375   {
00376     //display this local universe in Planner window
00377     display_lu = lu;
00378   } else
00379   {
00380     delete lu; //if we don't care about displaying it, delete it to save memory
00381     lu = NULL;
00382   }
00383   
00384   //void extract_cubes_set (std::set<PointClass> &s1, struct cubic_d *worldsize, 
00385   //                                                        std::vector<Square> &squarevector, int maxlevel);
00386   //void extract_block_node(struct node *node, struct cubic_d *worldsize, 
00387   //                        std::vector<Square> &squarevector, bool firstlevel, int colour);
00388   //void calc_cube_facets(std::vector<Square> &squarevector, GL_Mesh &mesh);
00389   
00390   //return lv_white;
00391 }
00392 

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