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
00032 #include <sbpl_arm_planner/occupancy_grid.h>
00033 #include <LinearMath/btTransform.h>
00034 #include <LinearMath/btVector3.h>
00035
00036 using namespace std;
00037
00038 OccupancyGrid::OccupancyGrid()
00039 {
00040 origin_[0] = 0.0;
00041 origin_[1] = 0.0;
00042 origin_[2] = 0.0;
00043
00044 grid_resolution_ = 0.01;
00045
00046 world_size_[0] = 2.0;
00047 world_size_[1] = 2.0;
00048 world_size_[2] = 2.0;
00049
00050 grid_size_[0] = world_size_[0] / grid_resolution_;
00051 grid_size_[1] = world_size_[1] / grid_resolution_;
00052 grid_size_[2] = world_size_[2] / grid_resolution_;
00053
00054 prop_distance_ = 0.60;
00055
00056 grid_ = new distance_field::PropagationDistanceField(world_size_[0], world_size_[1], world_size_[2], grid_resolution_, origin_[0], origin_[1], origin_[2], prop_distance_);
00057
00058 grid_->reset();
00059
00060 reference_frame_="base_link";
00061 }
00062
00063 OccupancyGrid::OccupancyGrid(double dim_x, double dim_y, double dim_z, double resolution, double origin_x, double origin_y, double origin_z)
00064 {
00065 origin_[0] = origin_x;
00066 origin_[1] = origin_y;
00067 origin_[2] = origin_z;
00068
00069 grid_resolution_ = resolution;
00070
00071 world_size_[0] = dim_x;
00072 world_size_[1] = dim_y;
00073 world_size_[2] = dim_z;
00074
00075 grid_size_[0] = world_size_[0] / grid_resolution_;
00076 grid_size_[1] = world_size_[1] / grid_resolution_;
00077 grid_size_[2] = world_size_[2] / grid_resolution_;
00078
00079 prop_distance_ = 0.60;
00080
00081 grid_ = new distance_field::PropagationDistanceField(world_size_[0], world_size_[1], world_size_[2], grid_resolution_, origin_[0], origin_[1], origin_[2], prop_distance_);
00082 grid_->reset();
00083
00084 reference_frame_="base_link";
00085 }
00086
00087 OccupancyGrid::~OccupancyGrid()
00088 {
00089 delete grid_;
00090 }
00091
00092 void OccupancyGrid::getGridSize(int &dim_x, int &dim_y, int &dim_z)
00093 {
00094 dim_x = grid_size_[0];
00095 dim_y = grid_size_[1];
00096 dim_z = grid_size_[2];
00097 }
00098
00099 void OccupancyGrid::setWorldSize(double dim_x, double dim_y, double dim_z)
00100 {
00101 world_size_[0] = dim_x;
00102 world_size_[1] = dim_y;
00103 world_size_[2] = dim_z;
00104
00105 SBPL_INFO("[OccupancyGrid] Set internal world dimensions but not distance field\n");
00106 }
00107
00108 void OccupancyGrid::getWorldSize(double &dim_x, double &dim_y, double &dim_z)
00109 {
00110 dim_x = grid_->getSize(distance_field::PropagationDistanceField::DIM_X);
00111 dim_y = grid_->getSize(distance_field::PropagationDistanceField::DIM_Y);
00112 dim_z = grid_->getSize(distance_field::PropagationDistanceField::DIM_Z);
00113 }
00114
00115 void OccupancyGrid::setOrigin(double wx, double wy, double wz)
00116 {
00117 origin_[0] = wx;
00118 origin_[1] = wy;
00119 origin_[2] = wz;
00120 }
00121
00122 void OccupancyGrid::getOrigin(double &wx, double &wy, double &wz)
00123 {
00124 wx = grid_->getOrigin(distance_field::PropagationDistanceField::DIM_X);
00125 wy = grid_->getOrigin(distance_field::PropagationDistanceField::DIM_Y);
00126 wz = grid_->getOrigin(distance_field::PropagationDistanceField::DIM_Z);
00127 }
00128
00129 void OccupancyGrid::setResolution(double resolution_m)
00130 {
00131 grid_resolution_ = resolution_m;
00132 }
00133
00134 double OccupancyGrid::getResolution()
00135 {
00136 return grid_->getResolution(distance_field::PropagationDistanceField::DIM_X);
00137 }
00138
00139 void OccupancyGrid::updateFromCollisionMap(const mapping_msgs::CollisionMap &collision_map)
00140 {
00141 if(collision_map.boxes.empty())
00142 {
00143 SBPL_INFO("[updateFromCollisionMap] collision map received is empty.\n");
00144 return;
00145 }
00146
00147 reference_frame_ = collision_map.header.frame_id;
00148
00149 SBPL_DEBUG("[OccupancyGrid] Resetting grid and updating from collision map");
00150 grid_->reset();
00151
00152 grid_->addCollisionMapToField(collision_map);
00153 }
00154
00155 void OccupancyGrid::addCollisionCuboid(double origin_x, double origin_y, double origin_z, double size_x, double size_y, double size_z)
00156 {
00157 int num_points=0;
00158
00159
00160 for (double x=origin_x-size_x/2.0; x<=origin_x+size_x/2.0; x+=grid_resolution_)
00161 {
00162 for (double y=origin_y-size_y/2.0; y<=origin_y+size_y/2.0; y+=grid_resolution_)
00163 {
00164 for (double z=origin_z-size_z/2.0; z<=origin_z+size_z/2.0; z+=grid_resolution_)
00165 {
00166 cuboid_points_.push_back(btVector3(x,y,z));
00167 ++num_points;
00168 }
00169 }
00170 }
00171
00172 grid_->addPointsToField(cuboid_points_);
00173
00174 ROS_DEBUG("[addCollisionCuboid] Added %d points for collision cuboid (origin: %0.2f %0.2f %0.2f size: %0.2f %0.2f %0.2f).", num_points, origin_x, origin_y, origin_z, size_x, size_y, size_z);
00175 }
00176
00177 void OccupancyGrid::getVoxelsInBox(const geometry_msgs::Pose &pose, const std::vector<double> &dim, std::vector<btVector3> &voxels)
00178 {
00179 btVector3 vin, vout, v(pose.position.x, pose.position.y, pose.position.z);
00180 btMatrix3x3 m(btQuaternion(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w));
00181
00182 for (double x=0-dim[0]/2.0; x<=dim[0]/2.0; x+=grid_resolution_)
00183 {
00184 for (double y=0-dim[1]/2.0; y<=dim[1]/2.0; y+=grid_resolution_)
00185 {
00186 for (double z=0-dim[2]/2.0; z<=dim[2]/2.0; z+=grid_resolution_)
00187 {
00188 vin.setX(x);
00189 vin.setY(y);
00190 vin.setZ(z);
00191 vout = m*vin;
00192 vout += v;
00193
00194 voxels.push_back(vout);
00195 }
00196 }
00197 }
00198 }
00199
00200 void OccupancyGrid::visualize()
00201 {
00202 btTransform trans;
00203 trans.setIdentity();
00204 grid_->visualize(0.01, 0.02, reference_frame_, trans, ros::Time::now());
00205 }
00206
00207 const distance_field::PropagationDistanceField* OccupancyGrid::getDistanceFieldPtr()
00208 {
00209 return grid_;
00210 }
00211
00212 void OccupancyGrid::printGridFromBinaryFile(std::string filename)
00213 {
00214 ifstream fin;
00215 int dimx,dimy,dimz;
00216 unsigned char temp = 0;
00217 struct stat file_stats;
00218
00219 const char *name = filename.c_str();
00220 fin.open(name, ios_base::in | ios_base::binary);
00221
00222 if (fin.is_open())
00223 {
00224 fin.read( (char*) &dimx, sizeof(int));
00225 fin.read( (char*) &dimy, sizeof(int));
00226 fin.read( (char*) &dimz, sizeof(int));
00227
00228 for(int x = 0; x < dimx; x++)
00229 {
00230 for(int y = 0; y < dimy; y++)
00231 {
00232 for(int z = 0; z < dimz; z++)
00233 {
00234 fin.read( (char*) &temp, sizeof(unsigned char));
00235 }
00236 }
00237 }
00238 }
00239 else
00240 {
00241 SBPL_ERROR("[printGridFromBinaryFile] Failed to open file for reading.");
00242 return;
00243 }
00244
00245 if(stat(name, &file_stats) == 0)
00246 SBPL_DEBUG("[printGridFromBinaryFile] The size of the file read is %d kb.", int(file_stats.st_size)/1024);
00247 else
00248 SBPL_DEBUG("[printGridFromBinaryFile] An error occurred when retrieving size of file read.");
00249
00250 fin.close();
00251 }
00252
00253 bool OccupancyGrid::saveGridToBinaryFile(std::string filename)
00254 {
00255 ofstream fout;
00256 int dimx,dimy,dimz;
00257 unsigned char val = 0;
00258 struct stat file_stats;
00259
00260 getGridSize(dimx, dimy, dimz);
00261
00262 const char *name = filename.c_str();
00263 fout.open(name, ios_base::out | ios_base::binary | ios_base::trunc);
00264
00265 if (fout.is_open())
00266 {
00267 fout.write( (char *) &dimx, sizeof(int));
00268 fout.write( (char *) &dimy, sizeof(int));
00269 fout.write( (char *) &dimz, sizeof(int));
00270
00271 for(int x = 0; x < dimx; x++)
00272 {
00273 for(int y = 0; y < dimy; y++)
00274 {
00275 for(int z = 0; z < dimz; z++)
00276 {
00277 val = getCell(x,y,z);
00278 fout.write( (char *) &val, sizeof(unsigned char));
00279 }
00280 }
00281 }
00282 }
00283 else
00284 {
00285 SBPL_ERROR("[saveGridToBinaryFile] Failed to open file for writing.\n");
00286 return false;
00287 }
00288
00289 fout.close();
00290
00291
00292 if(stat(name, &file_stats) == 0)
00293 {
00294 SBPL_INFO("[saveGridToBinaryFile] The size of the file created is %d kb.\n", int(file_stats.st_size)/1024);
00295 if(file_stats.st_size == 0)
00296 {
00297 SBPL_ERROR("[saveGridToBinaryFile] File created is empty. Exiting.\n");
00298 return false;
00299 }
00300 }
00301 else
00302 {
00303 SBPL_ERROR("[saveGridToBinaryFile] An error occurred when retrieving size of file created. Exiting.\n");
00304 return false;
00305 }
00306
00307 return true;
00308 }
00309