00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 #include <voxel_grid/voxel_grid.h>
00038 #include <sys/time.h>
00039 #include <ros/console.h>
00040 
00041 namespace voxel_grid {
00042   VoxelGrid::VoxelGrid(unsigned int size_x, unsigned int size_y, unsigned int size_z)
00043   {
00044     size_x_ = size_x; 
00045     size_y_ = size_y; 
00046     size_z_ = size_z; 
00047 
00048     if(size_z_ > 16){
00049       ROS_INFO("Error, this implementation can only support up to 16 z values"); 
00050       size_z_ = 16;
00051     }
00052 
00053     data_ = new uint32_t[size_x_ * size_y_];
00054     uint32_t unknown_col = ~((uint32_t)0)>>16;
00055     uint32_t* col = data_;
00056     for(unsigned int i = 0; i < size_x_ * size_y_; ++i){
00057       *col = unknown_col;
00058       ++col;
00059     }
00060   }
00061 
00062   void VoxelGrid::resize(unsigned int size_x, unsigned int size_y, unsigned int size_z)
00063   {
00064     
00065     if(size_x == size_x_ && size_y == size_y_ && size_z == size_z_){
00066       reset();
00067       return;
00068     }
00069 
00070     delete[] data_;
00071     size_x_ = size_x; 
00072     size_y_ = size_y; 
00073     size_z_ = size_z; 
00074 
00075     if(size_z_ > 16){
00076       ROS_INFO("Error, this implementation can only support up to 16 z values"); 
00077       size_z_ = 16;
00078     }
00079 
00080     data_ = new uint32_t[size_x_ * size_y_];
00081     uint32_t unknown_col = ~((uint32_t)0)>>16;
00082     uint32_t* col = data_;
00083     for(unsigned int i = 0; i < size_x_ * size_y_; ++i){
00084       *col = unknown_col;
00085       ++col;
00086     }
00087   }
00088 
00089   VoxelGrid::~VoxelGrid()
00090   {
00091     delete [] data_;
00092   }
00093 
00094   void VoxelGrid::reset(){
00095     uint32_t unknown_col = ~((uint32_t)0)>>16;
00096     uint32_t* col = data_;
00097     for(unsigned int i = 0; i < size_x_ * size_y_; ++i){
00098       *col = unknown_col;
00099       ++col;
00100     }
00101   }
00102 
00103   void VoxelGrid::markVoxelLine(double x0, double y0, double z0, double x1, double y1, double z1, unsigned int max_length){
00104     if(x0 >= size_x_ || y0 >= size_y_ || z0 >= size_z_ || x1>=size_x_ || y1>=size_y_ || z1>=size_z_){
00105       ROS_DEBUG("Error, line endpoint out of bounds. (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f),  size: (%d, %d, %d)", x0, y0, z0, x1, y1, z1, 
00106           size_x_, size_y_, size_z_);
00107       return;
00108     }
00109 
00110     MarkVoxel mv(data_);
00111     raytraceLine(mv, x0, y0, z0, x1, y1, z1, max_length);
00112   }
00113 
00114   void VoxelGrid::clearVoxelLine(double x0, double y0, double z0, double x1, double y1, double z1, unsigned int max_length){
00115     if(x0 >= size_x_ || y0 >= size_y_ || z0 >= size_z_ || x1>=size_x_ || y1>=size_y_ || z1>=size_z_){
00116       ROS_DEBUG("Error, line endpoint out of bounds. (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f),  size: (%d, %d, %d)", x0, y0, z0, x1, y1, z1, 
00117           size_x_, size_y_, size_z_);
00118       return;
00119     }
00120 
00121     ClearVoxel cv(data_);
00122     raytraceLine(cv, x0, y0, z0, x1, y1, z1, max_length);
00123   }
00124 
00125   void VoxelGrid::clearVoxelLineInMap(double x0, double y0, double z0, double x1, double y1, double z1, unsigned char *map_2d, 
00126       unsigned int unknown_threshold, unsigned int mark_threshold, unsigned char free_cost, unsigned char unknown_cost, unsigned int max_length){
00127     costmap = map_2d;
00128     if(map_2d == NULL){
00129       clearVoxelLine(x0, y0, z0, x1, y1, z1, max_length);
00130       return;
00131     }
00132 
00133     if(x0 >= size_x_ || y0 >= size_y_ || z0 >= size_z_ || x1>=size_x_ || y1>=size_y_ || z1>=size_z_){
00134       ROS_DEBUG("Error, line endpoint out of bounds. (%.2f, %.2f, %.2f) to (%.2f, %.2f, %.2f),  size: (%d, %d, %d)", x0, y0, z0, x1, y1, z1, 
00135           size_x_, size_y_, size_z_);
00136       return;
00137     }
00138 
00139     ClearVoxelInMap cvm(data_, costmap, unknown_threshold, mark_threshold, free_cost, unknown_cost);
00140     raytraceLine(cvm, x0, y0, z0, x1, y1, z1, max_length);
00141   }
00142 
00143   VoxelStatus VoxelGrid::getVoxel(unsigned int x, unsigned int y, unsigned int z)
00144   {
00145     if(x >= size_x_ || y >= size_y_ || z >= size_z_){
00146       ROS_DEBUG("Error, voxel out of bounds. (%d, %d, %d)\n", x, y, z);
00147       return UNKNOWN;
00148     }
00149     uint32_t full_mask = ((uint32_t)1<<z<<16) | (1<<z);
00150     uint32_t result = data_[y * size_x_ + x] & full_mask; 
00151     unsigned int bits = numBits(result);
00152 
00153     
00154     if(bits < 2){
00155       if(bits < 1)
00156         return FREE;
00157 
00158       return UNKNOWN;
00159     }
00160 
00161     return MARKED;
00162   }
00163 
00164   VoxelStatus VoxelGrid::getVoxelColumn(unsigned int x, unsigned int y, unsigned int unknown_threshold, unsigned int marked_threshold)
00165   {
00166     if(x >= size_x_ || y >= size_y_){
00167       ROS_DEBUG("Error, voxel out of bounds. (%d, %d)\n", x, y);
00168       return UNKNOWN;
00169     }
00170     
00171     uint32_t* col = &data_[y * size_x_ + x];
00172 
00173     unsigned int unknown_bits = uint16_t(*col>>16) ^ uint16_t(*col);
00174     unsigned int marked_bits = *col>>16;
00175 
00176     
00177     if(!bitsBelowThreshold(marked_bits, marked_threshold)){
00178       return MARKED;
00179     }
00180 
00181     
00182     if(!bitsBelowThreshold(unknown_bits, unknown_threshold))
00183       return UNKNOWN;
00184 
00185     return FREE;
00186   }
00187 
00188   unsigned int VoxelGrid::sizeX(){
00189     return size_x_;
00190   }
00191 
00192   unsigned int VoxelGrid::sizeY(){
00193     return size_y_;
00194   }
00195 
00196   unsigned int VoxelGrid::sizeZ(){
00197     return size_z_;
00198   }
00199 
00200   void VoxelGrid::printVoxelGrid(){
00201     for(unsigned int z = 0; z < size_z_; z++){
00202       printf("Layer z = %d:\n",z);
00203       for(unsigned int y = 0; y < size_y_; y++){
00204         for(unsigned int x = 0 ; x < size_x_; x++){
00205           printf((getVoxel(x, y, z)) == voxel_grid::MARKED? "#" : " ");
00206         }
00207         printf("|\n");
00208       } 
00209     }
00210   }
00211 
00212   void VoxelGrid::printColumnGrid(){
00213     printf("Column view:\n");
00214     for(unsigned int y = 0; y < size_y_; y++){
00215       for(unsigned int x = 0 ; x < size_x_; x++){
00216         printf((getVoxelColumn(x, y, 16, 0) == voxel_grid::MARKED)? "#" : " ");
00217       }
00218       printf("|\n");
00219     } 
00220   }
00221 };