00001 
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 
00038 #include <dynamicEDT3D/dynamicEDTOctomap.h>
00039 
00040 float DynamicEDTOctomap::distanceValue_Error = -1.0;
00041 int DynamicEDTOctomap::distanceInCellsValue_Error = -1;
00042 
00043 DynamicEDTOctomap::DynamicEDTOctomap(float maxdist, octomap::OcTree* _octree, octomap::point3d bbxMin, octomap::point3d bbxMax, bool treatUnknownAsOccupied)
00044 : DynamicEDT3D(((int) (maxdist/_octree->getResolution()+1)*((int) (maxdist/_octree->getResolution()+1)))), octree(_octree), unknownOccupied(treatUnknownAsOccupied)
00045 {
00046         treeDepth = octree->getTreeDepth();
00047         treeResolution = octree->getResolution();
00048         initializeOcTree(bbxMin, bbxMax);
00049         octree->enableChangeDetection(true);
00050 }
00051 
00052 DynamicEDTOctomap::~DynamicEDTOctomap() {
00053 
00054 }
00055 
00056 
00057 void DynamicEDTOctomap::update(bool updateRealDist){
00058 
00059         for(octomap::KeyBoolMap::const_iterator it = octree->changedKeysBegin(), end=octree->changedKeysEnd(); it!=end; ++it){
00060                 
00061 
00062                 octomap::OcTreeKey key = it->first;
00063 
00064                 
00065                 if(key[0] < boundingBoxMinKey[0] || key[1] < boundingBoxMinKey[1] || key[2] < boundingBoxMinKey[2])
00066                         continue;
00067                 if(key[0] > boundingBoxMaxKey[0] || key[1] > boundingBoxMaxKey[1] || key[2] > boundingBoxMaxKey[2])
00068                         continue;
00069 
00070                 octomap::OcTreeNode* node = octree->search(key);
00071                 assert(node);
00072                 
00073                 
00074 
00075                 updateMaxDepthLeaf(key, octree->isNodeOccupied(node));
00076         }
00077         octree->resetChangeDetection();
00078 
00079         DynamicEDT3D::update(updateRealDist);
00080 }
00081 
00082 void DynamicEDTOctomap::initializeOcTree(octomap::point3d bbxMin, octomap::point3d bbxMax){
00083 
00084     boundingBoxMinKey = octree->coordToKey(bbxMin);
00085     boundingBoxMaxKey = octree->coordToKey(bbxMax);
00086 
00087         offsetX = -boundingBoxMinKey[0];
00088         offsetY = -boundingBoxMinKey[1];
00089         offsetZ = -boundingBoxMinKey[2];
00090 
00091         int _sizeX = boundingBoxMaxKey[0] - boundingBoxMinKey[0] + 1;
00092         int _sizeY = boundingBoxMaxKey[1] - boundingBoxMinKey[1] + 1;
00093         int _sizeZ = boundingBoxMaxKey[2] - boundingBoxMinKey[2] + 1;
00094 
00095         initializeEmpty(_sizeX, _sizeY, _sizeZ, false);
00096 
00097 
00098         if(unknownOccupied == false){
00099                 for(octomap::OcTree::leaf_bbx_iterator it = octree->begin_leafs_bbx(bbxMin,bbxMax), end=octree->end_leafs_bbx(); it!= end; ++it){
00100                         if(octree->isNodeOccupied(*it)){
00101                                 int nodeDepth = it.getDepth();
00102                                 if( nodeDepth == treeDepth){
00103                                         insertMaxDepthLeafAtInitialize(it.getKey());
00104                                 } else {
00105                                         int cubeSize = 1 << (treeDepth - nodeDepth);
00106                                         octomap::OcTreeKey key=it.getIndexKey();
00107                                         for(int dx = 0; dx < cubeSize; dx++)
00108                                                 for(int dy = 0; dy < cubeSize; dy++)
00109                                                         for(int dz = 0; dz < cubeSize; dz++){
00110                                                                 unsigned short int tmpx = key[0]+dx;
00111                                                                 unsigned short int tmpy = key[1]+dy;
00112                                                                 unsigned short int tmpz = key[2]+dz;
00113 
00114                                                                 if(boundingBoxMinKey[0] > tmpx || boundingBoxMinKey[1] > tmpy || boundingBoxMinKey[2] > tmpz)
00115                                                                         continue;
00116                                                                 if(boundingBoxMaxKey[0] < tmpx || boundingBoxMaxKey[1] < tmpy || boundingBoxMaxKey[2] < tmpz)
00117                                                                         continue;
00118 
00119                                                                 insertMaxDepthLeafAtInitialize(octomap::OcTreeKey(tmpx, tmpy, tmpz));
00120                                                         }
00121                                 }
00122                         }
00123                 }
00124         } else {
00125                 octomap::OcTreeKey key;
00126                 for(int dx=0; dx<sizeX; dx++){
00127                         key[0] = boundingBoxMinKey[0] + dx;
00128                         for(int dy=0; dy<sizeY; dy++){
00129                                 key[1] = boundingBoxMinKey[1] + dy;
00130                                 for(int dz=0; dz<sizeZ; dz++){
00131                                         key[2] = boundingBoxMinKey[2] + dz;
00132 
00133                                         octomap::OcTreeNode* node = octree->search(key);
00134                                         if(!node || octree->isNodeOccupied(node)){
00135                                                 insertMaxDepthLeafAtInitialize(key);
00136                                         }
00137                                 }
00138                         }
00139                 }
00140         }
00141 }
00142 
00143 void DynamicEDTOctomap::insertMaxDepthLeafAtInitialize(octomap::OcTreeKey key){
00144         bool isSurrounded = true;
00145 
00146 
00147         for(int dx=-1; dx<=1; dx++)
00148                 for(int dy=-1; dy<=1; dy++)
00149                         for(int dz=-1; dz<=1; dz++){
00150                                 if(dx==0 && dy==0 && dz==0)
00151                                         continue;
00152                                 octomap::OcTreeNode* node = octree->search(octomap::OcTreeKey(key[0]+dx, key[1]+dy, key[2]+dz));
00153                                 if((!unknownOccupied && node==NULL) || ((node!=NULL) && (octree->isNodeOccupied(node)==false))){
00154                                         isSurrounded = false;
00155                                         break;
00156                                 }
00157                         }
00158 
00159         if(isSurrounded){
00160                 
00161                 
00162                 dataCell c;
00163                 int x = key[0]+offsetX;
00164                 int y = key[1]+offsetY;
00165                 int z = key[2]+offsetZ;
00166                 c.obstX = x;
00167                 c.obstY = y;
00168                 c.obstZ = z;
00169                 c.sqdist = 0;
00170                 c.dist = 0.0;
00171                 c.queueing = fwProcessed;
00172                 c.needsRaise = false;
00173                 data[x][y][z] = c;
00174         } else {
00175                 setObstacle(key[0]+offsetX, key[1]+offsetY, key[2]+offsetZ);
00176         }
00177 }
00178 
00179 void DynamicEDTOctomap::updateMaxDepthLeaf(octomap::OcTreeKey& key, bool occupied){
00180         if(occupied)
00181                 setObstacle(key[0]+offsetX, key[1]+offsetY, key[2]+offsetZ);
00182         else
00183                 removeObstacle(key[0]+offsetX, key[1]+offsetY, key[2]+offsetZ);
00184 }
00185 
00186 void DynamicEDTOctomap::worldToMap(const octomap::point3d &p, int &x, int &y, int &z) const {
00187         octomap::OcTreeKey key = octree->coordToKey(p);
00188         x = key[0] + offsetX;
00189         y = key[1] + offsetY;
00190         z = key[2] + offsetZ;
00191 }
00192 
00193 void DynamicEDTOctomap::mapToWorld(int x, int y, int z, octomap::point3d &p) const {
00194         p = octree->keyToCoord(octomap::OcTreeKey(x-offsetX, y-offsetY, z-offsetZ));
00195 }
00196 
00197 void DynamicEDTOctomap::mapToWorld(int x, int y, int z, octomap::OcTreeKey &key) const {
00198         key = octomap::OcTreeKey(x-offsetX, y-offsetY, z-offsetZ);
00199 }
00200 
00201 
00202 void DynamicEDTOctomap::getDistanceAndClosestObstacle(const octomap::point3d& p, float &distance, octomap::point3d& closestObstacle) const {
00203         int x,y,z;
00204         worldToMap(p, x, y, z);
00205         if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
00206                 dataCell c= data[x][y][z];
00207 
00208                 distance = c.dist*treeResolution;
00209                 if(c.obstX != invalidObstData){
00210                         mapToWorld(c.obstX, c.obstY, c.obstZ, closestObstacle);
00211                 } else {
00212                   
00213                 }
00214         } else {
00215           distance = distanceValue_Error;
00216         }
00217 }
00218 
00219 
00220 void DynamicEDTOctomap::getDistanceAndClosestObstacle_unsafe(const octomap::point3d& p, float &distance, octomap::point3d& closestObstacle) const {
00221         int x,y,z;
00222         worldToMap(p, x, y, z);
00223 
00224         dataCell c= data[x][y][z];
00225 
00226         distance = c.dist*treeResolution;
00227         if(c.obstX != invalidObstData){
00228                 mapToWorld(c.obstX, c.obstY, c.obstZ, closestObstacle);
00229         } else {
00230                 
00231         }
00232 }
00233 
00234 
00235 float DynamicEDTOctomap::getDistance(const octomap::point3d& p) const {
00236   int x,y,z;
00237   worldToMap(p, x, y, z);
00238   if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
00239       return data[x][y][z].dist*treeResolution;
00240   } else {
00241       return distanceValue_Error;
00242   }
00243 }
00244 
00245 float DynamicEDTOctomap::getDistance_unsafe(const octomap::point3d& p) const {
00246   int x,y,z;
00247   worldToMap(p, x, y, z);
00248   return data[x][y][z].dist*treeResolution;
00249 }
00250 
00251 
00252 float DynamicEDTOctomap::getDistance(const octomap::OcTreeKey& k) const {
00253   int x = k[0] + offsetX;
00254   int y = k[1] + offsetY;
00255   int z = k[2] + offsetZ;
00256 
00257   if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
00258       return data[x][y][z].dist*treeResolution;
00259   } else {
00260       return distanceValue_Error;
00261   }
00262 }
00263 
00264 
00265 float DynamicEDTOctomap::getDistance_unsafe(const octomap::OcTreeKey& k) const {
00266   int x = k[0] + offsetX;
00267   int y = k[1] + offsetY;
00268   int z = k[2] + offsetZ;
00269 
00270   return data[x][y][z].dist*treeResolution;
00271 }
00272 
00273 
00274 int DynamicEDTOctomap::getSquaredDistanceInCells(const octomap::point3d& p) const {
00275   int x,y,z;
00276   worldToMap(p, x, y, z);
00277   if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
00278     return data[x][y][z].sqdist;
00279   } else {
00280     return distanceInCellsValue_Error;
00281   }
00282 }
00283 
00284 int DynamicEDTOctomap::getSquaredDistanceInCells_unsafe(const octomap::point3d& p) const {
00285   int x,y,z;
00286   worldToMap(p, x, y, z);
00287   return data[x][y][z].sqdist;
00288 }
00289 
00290 
00291 bool DynamicEDTOctomap::checkConsistency() const {
00292 
00293         for(octomap::KeyBoolMap::const_iterator it = octree->changedKeysBegin(), end=octree->changedKeysEnd(); it!=end; ++it){
00294                 
00295                 return false;
00296         }
00297 
00298         for(int x=0; x<sizeX; x++){
00299                 for(int y=0; y<sizeY; y++){
00300                         for(int z=0; z<sizeZ; z++){
00301 
00302                                 octomap::point3d point;
00303                                 mapToWorld(x,y,z,point);
00304                                 octomap::OcTreeNode* node = octree->search(point);
00305 
00306                                 bool mapOccupied = isOccupied(x,y,z);
00307                                 bool treeOccupied = false;
00308                                 if(node){
00309                                         treeOccupied = octree->isNodeOccupied(node);
00310                                 } else {
00311                                         if(unknownOccupied)
00312                                                 treeOccupied = true;
00313                                 }
00314 
00315                                 if(mapOccupied != treeOccupied){
00316                                         
00317                                         
00318                                         
00319                                         return false;
00320                                 }
00321                         }
00322                 }
00323         }
00324 
00325         return true;
00326 }
00327 
00328 
00329