ndt_conversions.h
Go to the documentation of this file.
00001 #ifndef NDT_CONVERSIONS_HH
00002 #define NDT_CONVERSIONS_HH
00003 
00004 #include <ros/ros.h>
00005 #include <vector>
00006 #include <Eigen/Eigen>
00007 #include <ndt_map/ndt_map.h>
00008 #include <ndt_map/ndt_cell.h>
00009 #include <ndt_map/NDTMapMsg.h>
00010 #include <ndt_map/NDTCellMsg.h>
00011 #include <nav_msgs/OccupancyGrid.h>
00012 #include <string>
00013 
00014 
00015 namespace lslgeneric{
00026   bool toMessage(NDTMap *map, ndt_map::NDTMapMsg &msg,std::string frame_name){
00027     std::vector<lslgeneric::NDTCell*> map_vector=map->getAllInitializedCells();
00028     msg.header.stamp=ros::Time::now();
00029     msg.header.frame_id=frame_name;//is it in *map?    
00030     if(!map->getGridSizeInMeters(msg.x_size,msg.y_size,msg.z_size)){
00031           ROS_ERROR("NO GRID SIZE");
00032           return false;
00033     }
00034     if(!map->getCentroid(msg.x_cen,msg.y_cen,msg.z_cen)){
00035           ROS_ERROR("NO GRID CENTER");
00036           return false;
00037     }
00038     if(!map->getCellSizeInMeters(msg.x_cell_size,msg.y_cell_size,msg.z_cell_size)){
00039           ROS_ERROR("NO CELL SIZE");
00040           return false;
00041     }
00042     for (int cell_idx=0;cell_idx<map_vector.size();cell_idx++){
00043           if(map_vector[cell_idx]->hasGaussian_){ //we only send a cell with gaussian
00044         ndt_map::NDTCellMsg cell;
00045         Eigen::Vector3d means=map_vector[cell_idx]->getMean();
00046         cell.mean_x=means(0);
00047         cell.mean_y=means(1);
00048         cell.mean_z=means(2);
00049         cell.occupancy=map_vector[cell_idx]->getOccupancyRescaled();
00050         Eigen::Matrix3d cov=map_vector[cell_idx]->getCov();
00051         for(int i=0;i<3;i++){
00052                   for(int j=0;j<3;j++){
00053             cell.cov_matrix.push_back(cov(i,j));
00054                   }
00055         }
00056         cell.N=map_vector[cell_idx]->getN();
00057         msg.cells.push_back(cell);
00058           }
00059           delete map_vector[cell_idx];
00060     }
00061     return true;
00062   }
00073   bool fromMessage(LazyGrid* &idx, NDTMap* &map, ndt_map::NDTMapMsg msg, std::string &frame_name){
00074     if(!(msg.x_cell_size==msg.y_cell_size&&msg.y_cell_size==msg.z_cell_size)){ //we assume that voxels are cubes
00075           ROS_ERROR("SOMETHING HAS GONE VERY WRONG YOUR VOXELL IS NOT A CUBE"); 
00076           return false;
00077     }
00078     idx=new LazyGrid(msg.x_cell_size);
00079     map = new NDTMap(idx,msg.x_cen,msg.y_cen,msg.z_cen,msg.x_size,msg.y_size,msg.z_size);
00080     frame_name=msg.header.frame_id;
00081     int gaussians=0;
00082     for(int itr=0;itr<msg.cells.size();itr++){
00083           Eigen::Vector3d mean;
00084           Eigen::Matrix3d cov;
00085           mean<<msg.cells[itr].mean_x,msg.cells[itr].mean_y,msg.cells[itr].mean_z;
00086           int m_itr=0;
00087           for(int i=0;i<3;i++){
00088         for(int j=0;j<3;j++){
00089                   cov(i,j)=msg.cells[itr].cov_matrix[m_itr];
00090                   m_itr++;
00091         }
00092           }
00093           map->addDistributionToCell(cov,mean,msg.cells[itr].N);
00094     }
00095     return true;
00096   }
00107   bool toOccupancyGrid(NDTMap *ndt_map, nav_msgs::OccupancyGrid &occ_grid, double resolution,std::string frame_id){//works only for 2D case
00108     double size_x, size_y, size_z;
00109     int size_x_cell_count, size_y_cell_count;
00110     double cen_x, cen_y, cen_z;
00111     double orig_x, orig_y;
00112     ndt_map->getGridSizeInMeters(size_x,size_y,size_z);
00113     ndt_map->getCentroid(cen_x,cen_y,cen_z);
00114     orig_x=cen_x-size_x/2.0;
00115     orig_y=cen_y-size_y/2.0;
00116     size_x_cell_count=int(size_x/resolution);
00117     size_y_cell_count=int(size_y/resolution);
00118     occ_grid.info.width=size_x_cell_count;
00119     occ_grid.info.height=size_y_cell_count;
00120     occ_grid.info.resolution=resolution;
00121     occ_grid.header.stamp=ros::Time::now();
00122     occ_grid.header.frame_id=frame_id;
00123     for(double px=orig_x+resolution/2.0;px<orig_x+size_x;px+=resolution){
00124       for(double py=orig_y+resolution/2.0;py<orig_y+size_x;py+=resolution){
00125         pcl::PointXYZ pt(px,py,0);
00126         lslgeneric::NDTCell *cell;
00127         if(!ndt_map->getCellAtPoint(pt, cell)){
00128           occ_grid.data.push_back(-1);
00129         }
00130         else if(cell == NULL){
00131           occ_grid.data.push_back(-1);
00132         }
00133         else{
00134           Eigen::Vector3d vec (pt.x,pt.y,pt.z);
00135           vec = vec-cell->getMean();                  
00136           double likelihood = vec.dot(cell-> getInverseCov()*vec);
00137           char s_likelihood;
00138           if(cell->getOccupancy()!=0.0){
00139             if(cell->getOccupancy()>0.0){
00140             if(std::isnan(likelihood)) s_likelihood = -1;
00141             likelihood = exp(-likelihood/2.0) + 0.1;
00142             likelihood = (0.5+0.5*likelihood);
00143             s_likelihood=char(likelihood*100.0);
00144             if(likelihood >1.0) s_likelihood =100;
00145             occ_grid.data.push_back(s_likelihood);
00146             }
00147             else{
00148               occ_grid.data.push_back(0);
00149             }
00150           }
00151           else{
00152              occ_grid.data.push_back(-1);
00153           }
00154         }
00155       }
00156     }    
00157     return true;
00158   } 
00159 }
00160 #endif


ndt_map
Author(s): Todor Stoyanov, Jari Saarinen, Henrik Andreasson
autogenerated on Wed Aug 26 2015 15:24:40