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