dynamicEDTOctomap.cpp
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2011-2012, C. Sprunk, B. Lau, W. Burgard, University of Freiburg
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * * Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  * * Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  * * Neither the name of the University of Freiburg nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
39 
42 
43 DynamicEDTOctomap::DynamicEDTOctomap(float maxdist, octomap::OcTree* _octree, octomap::point3d bbxMin, octomap::point3d bbxMax, bool treatUnknownAsOccupied)
44 : DynamicEDT3D(((int) (maxdist/_octree->getResolution()+1)*((int) (maxdist/_octree->getResolution()+1)))), octree(_octree), unknownOccupied(treatUnknownAsOccupied)
45 {
48  initializeOcTree(bbxMin, bbxMax);
50 }
51 
53 
54 }
55 
56 
57 void DynamicEDTOctomap::update(bool updateRealDist){
58 
59  for(octomap::KeyBoolMap::const_iterator it = octree->changedKeysBegin(), end=octree->changedKeysEnd(); it!=end; ++it){
60  //the keys in this list all go down to the lowest level!
61 
62  octomap::OcTreeKey key = it->first;
63 
64  //ignore changes outside of bounding box
65  if(key[0] < boundingBoxMinKey[0] || key[1] < boundingBoxMinKey[1] || key[2] < boundingBoxMinKey[2])
66  continue;
67  if(key[0] > boundingBoxMaxKey[0] || key[1] > boundingBoxMaxKey[1] || key[2] > boundingBoxMaxKey[2])
68  continue;
69 
70  octomap::OcTreeNode* node = octree->search(key);
71  assert(node);
72  //"node" is not necessarily at lowest level, BUT: the occupancy value of this node
73  //has to be the same as of the node indexed by the key *it
74 
76  }
78 
79  DynamicEDT3D::update(updateRealDist);
80 }
81 
83 
86 
90 
91  int _sizeX = boundingBoxMaxKey[0] - boundingBoxMinKey[0] + 1;
92  int _sizeY = boundingBoxMaxKey[1] - boundingBoxMinKey[1] + 1;
93  int _sizeZ = boundingBoxMaxKey[2] - boundingBoxMinKey[2] + 1;
94 
95  initializeEmpty(_sizeX, _sizeY, _sizeZ, false);
96 
97 
98  if(unknownOccupied == false){
99  for(octomap::OcTree::leaf_bbx_iterator it = octree->begin_leafs_bbx(bbxMin,bbxMax), end=octree->end_leafs_bbx(); it!= end; ++it){
100  if(octree->isNodeOccupied(*it)){
101  int nodeDepth = it.getDepth();
102  if( nodeDepth == treeDepth){
103  insertMaxDepthLeafAtInitialize(it.getKey());
104  } else {
105  int cubeSize = 1 << (treeDepth - nodeDepth);
106  octomap::OcTreeKey key=it.getIndexKey();
107  for(int dx = 0; dx < cubeSize; dx++)
108  for(int dy = 0; dy < cubeSize; dy++)
109  for(int dz = 0; dz < cubeSize; dz++){
110  unsigned short int tmpx = key[0]+dx;
111  unsigned short int tmpy = key[1]+dy;
112  unsigned short int tmpz = key[2]+dz;
113 
114  if(boundingBoxMinKey[0] > tmpx || boundingBoxMinKey[1] > tmpy || boundingBoxMinKey[2] > tmpz)
115  continue;
116  if(boundingBoxMaxKey[0] < tmpx || boundingBoxMaxKey[1] < tmpy || boundingBoxMaxKey[2] < tmpz)
117  continue;
118 
120  }
121  }
122  }
123  }
124  } else {
125  octomap::OcTreeKey key;
126  for(int dx=0; dx<sizeX; dx++){
127  key[0] = boundingBoxMinKey[0] + dx;
128  for(int dy=0; dy<sizeY; dy++){
129  key[1] = boundingBoxMinKey[1] + dy;
130  for(int dz=0; dz<sizeZ; dz++){
131  key[2] = boundingBoxMinKey[2] + dz;
132 
133  octomap::OcTreeNode* node = octree->search(key);
134  if(!node || octree->isNodeOccupied(node)){
136  }
137  }
138  }
139  }
140  }
141 }
142 
144  bool isSurrounded = true;
145 
146 
147  for(int dx=-1; dx<=1; dx++)
148  for(int dy=-1; dy<=1; dy++)
149  for(int dz=-1; dz<=1; dz++){
150  if(dx==0 && dy==0 && dz==0)
151  continue;
152  octomap::OcTreeNode* node = octree->search(octomap::OcTreeKey(key[0]+dx, key[1]+dy, key[2]+dz));
153  if((!unknownOccupied && node==NULL) || ((node!=NULL) && (octree->isNodeOccupied(node)==false))){
154  isSurrounded = false;
155  break;
156  }
157  }
158 
159  if(isSurrounded){
160  //obstacles that are surrounded by obstacles do not need to be put in the queues,
161  //hence this initialization
162  dataCell c;
163  int x = key[0]+offsetX;
164  int y = key[1]+offsetY;
165  int z = key[2]+offsetZ;
166  c.obstX = x;
167  c.obstY = y;
168  c.obstZ = z;
169  c.sqdist = 0;
170  c.dist = 0.0;
171  c.queueing = fwProcessed;
172  c.needsRaise = false;
173  data[x][y][z] = c;
174  } else {
175  setObstacle(key[0]+offsetX, key[1]+offsetY, key[2]+offsetZ);
176  }
177 }
178 
180  if(occupied)
181  setObstacle(key[0]+offsetX, key[1]+offsetY, key[2]+offsetZ);
182  else
183  removeObstacle(key[0]+offsetX, key[1]+offsetY, key[2]+offsetZ);
184 }
185 
186 void DynamicEDTOctomap::worldToMap(const octomap::point3d &p, int &x, int &y, int &z) const {
188  x = key[0] + offsetX;
189  y = key[1] + offsetY;
190  z = key[2] + offsetZ;
191 }
192 
193 void DynamicEDTOctomap::mapToWorld(int x, int y, int z, octomap::point3d &p) const {
195 }
196 
197 void DynamicEDTOctomap::mapToWorld(int x, int y, int z, octomap::OcTreeKey &key) const {
198  key = octomap::OcTreeKey(x-offsetX, y-offsetY, z-offsetZ);
199 }
200 
201 
202 void DynamicEDTOctomap::getDistanceAndClosestObstacle(const octomap::point3d& p, float &distance, octomap::point3d& closestObstacle) const {
203  int x,y,z;
204  worldToMap(p, x, y, z);
205  if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
206  dataCell c= data[x][y][z];
207 
208  distance = c.dist*treeResolution;
209  if(c.obstX != invalidObstData){
210  mapToWorld(c.obstX, c.obstY, c.obstZ, closestObstacle);
211  } else {
212  //If we are at maxDist, it can very well be that there is no valid closest obstacle data for this cell, this is not an error.
213  }
214  } else {
215  distance = distanceValue_Error;
216  }
217 }
218 
219 
220 void DynamicEDTOctomap::getDistanceAndClosestObstacle_unsafe(const octomap::point3d& p, float &distance, octomap::point3d& closestObstacle) const {
221  int x,y,z;
222  worldToMap(p, x, y, z);
223 
224  dataCell c= data[x][y][z];
225 
226  distance = c.dist*treeResolution;
227  if(c.obstX != invalidObstData){
228  mapToWorld(c.obstX, c.obstY, c.obstZ, closestObstacle);
229  } else {
230  //If we are at maxDist, it can very well be that there is no valid closest obstacle data for this cell, this is not an error.
231  }
232 }
233 
234 
236  int x,y,z;
237  worldToMap(p, x, y, z);
238  if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
239  return data[x][y][z].dist*treeResolution;
240  } else {
241  return distanceValue_Error;
242  }
243 }
244 
246  int x,y,z;
247  worldToMap(p, x, y, z);
248  return data[x][y][z].dist*treeResolution;
249 }
250 
251 
253  int x = k[0] + offsetX;
254  int y = k[1] + offsetY;
255  int z = k[2] + offsetZ;
256 
257  if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
258  return data[x][y][z].dist*treeResolution;
259  } else {
260  return distanceValue_Error;
261  }
262 }
263 
264 
266  int x = k[0] + offsetX;
267  int y = k[1] + offsetY;
268  int z = k[2] + offsetZ;
269 
270  return data[x][y][z].dist*treeResolution;
271 }
272 
273 
275  int x,y,z;
276  worldToMap(p, x, y, z);
277  if(x>=0 && x<sizeX && y>=0 && y<sizeY && z>=0 && z<sizeZ){
278  return data[x][y][z].sqdist;
279  } else {
281  }
282 }
283 
285  int x,y,z;
286  worldToMap(p, x, y, z);
287  return data[x][y][z].sqdist;
288 }
289 
290 
292 
293  for(octomap::KeyBoolMap::const_iterator it = octree->changedKeysBegin(), end=octree->changedKeysEnd(); it!=end; ++it){
294  //std::cerr<<"Cannot check consistency, you must execute the update() method first."<<std::endl;
295  return false;
296  }
297 
298  for(int x=0; x<sizeX; x++){
299  for(int y=0; y<sizeY; y++){
300  for(int z=0; z<sizeZ; z++){
301 
302  octomap::point3d point;
303  mapToWorld(x,y,z,point);
304  octomap::OcTreeNode* node = octree->search(point);
305 
306  bool mapOccupied = isOccupied(x,y,z);
307  bool treeOccupied = false;
308  if(node){
309  treeOccupied = octree->isNodeOccupied(node);
310  } else {
311  if(unknownOccupied)
312  treeOccupied = true;
313  }
314 
315  if(mapOccupied != treeOccupied){
316  //std::cerr<<"OCCUPANCY MISMATCH BETWEEN TREE AND MAP at "<<x<<","<<y<<","<<z<<std::endl;
317  //std::cerr<<"Tree "<<treeOccupied<<std::endl;
318  //std::cerr<<"Map "<<mapOccupied<<std::endl;
319  return false;
320  }
321  }
322  }
323  }
324 
325  return true;
326 }
327 
328 
329 
int getSquaredDistanceInCells(const octomap::point3d &p) const
retrieves squared distance in cells at point. Returns DynamicEDTOctomap::distanceInCellsValue_Error i...
bool checkConsistency() const
Brute force method used for debug purposes. Checks occupancy state consistency between octomap and in...
void setObstacle(int x, int y, int z)
unsigned short int coordToKey(double coordinate) const
void mapToWorld(int x, int y, int z, octomap::point3d &p) const
leaf_bbx_iterator begin_leafs_bbx(const OcTreeKey &min, const OcTreeKey &max, unsigned char maxDepth=0) const
void worldToMap(const octomap::point3d &p, int &x, int &y, int &z) const
OcTreeNode * search(double x, double y, double z, unsigned int depth=0) const
void getDistanceAndClosestObstacle_unsafe(const octomap::point3d &p, float &distance, octomap::point3d &closestObstacle) const
DynamicEDTOctomap(float maxdist, octomap::OcTree *_octree, octomap::point3d bbxMin, octomap::point3d bbxMax, bool treatUnknownAsOccupied)
octomap::OcTreeKey boundingBoxMaxKey
float getDistance_unsafe(const octomap::point3d &p) const
dataCell *** data
Definition: dynamicEDT3D.h:137
double keyToCoord(unsigned short int key, unsigned depth) const
octomap::OcTree * octree
int getSquaredDistanceInCells_unsafe(const octomap::point3d &p) const
static float distanceValue_Error
distance value returned when requesting distance for a cell outside the map
void initializeEmpty(int _sizeX, int _sizeY, int sizeZ, bool initGridMap=true)
Initialization with an empty map.
void getDistanceAndClosestObstacle(const octomap::point3d &p, float &distance, octomap::point3d &closestObstacle) const
A DynamicEDT3D object computes and updates a 3D distance map.
Definition: dynamicEDT3D.h:47
void insertMaxDepthLeafAtInitialize(octomap::OcTreeKey key)
float getDistance(const octomap::point3d &p) const
retrieves distance at point. Returns DynamicEDTOctomap::distanceValue_Error if point is outside the m...
virtual void update(bool updateRealDist=true)
static int distanceInCellsValue_Error
distance value returned when requesting distance in cell units for a cell outside the map ...
KeyBoolMap::const_iterator changedKeysBegin() const
bool isOccupied(int x, int y, int z) const
checks whether the specficied location is occupied
virtual void update(bool updateRealDist=true)
update distance map to reflect the changes
void removeObstacle(int x, int y, int z)
void initializeOcTree(octomap::point3d bbxMin, octomap::point3d bbxMax)
void enableChangeDetection(bool enable)
bool isNodeOccupied(const OcTreeNode *occupancyNode) const
octomap::OcTreeKey boundingBoxMinKey
void updateMaxDepthLeaf(octomap::OcTreeKey &key, bool occupied)
KeyBoolMap::const_iterator changedKeysEnd() const


dynamicEDT3D
Author(s): Christoph Sprunk
autogenerated on Mon Jun 10 2019 14:00:23