MapInflationTool.cpp
Go to the documentation of this file.
2 
3 CellData::CellData(double d, double i, unsigned int sx, unsigned int sy):distance(d), index(i), sx(sx), sy(sy){
4 }
5 
7 {
8  mInflationMarkers = NULL;
9  mCachedCosts = NULL;
10  mCachedDistances = NULL;
11  mCostObstacle = 100;
12 }
13 
15 {
16  delete[] mInflationMarkers;
17  delete[] mCachedCosts;
18  delete[] mCachedDistances;
19 }
20 
21 // This method calculates two different lookup-tables:
22 // 1. The distance of cells arount an obstacle towards this obstacle
23 // 2. The cost that is applied to these cells around an obstacle
24 void MapInflationTool::computeCaches(unsigned int radius)
25 {
26  mCellInflationRadius = radius;
27 
28  mCachedCosts = new signed char*[mCellInflationRadius + 2];
29  mCachedDistances = new double*[mCellInflationRadius + 2];
30 
31  for(unsigned int i = 0; i < mCellInflationRadius + 2; i++)
32  {
33  mCachedCosts[i] = new signed char[mCellInflationRadius + 2];
34  mCachedDistances[i] = new double[mCellInflationRadius + 2];
35  for(unsigned int j = 0; j < mCellInflationRadius + 2; j++)
36  {
37  double d = sqrt(i*i + j*j);
38  mCachedDistances[i][j] = d;
39  d /= mCellInflationRadius;
40  if(d > 1) d = 1;
41  mCachedCosts[i][j] = (1.0 - d) * mCostObstacle;
42  }
43  }
44 }
45 
46 // Method used to query the cache for a distance.
47 inline double MapInflationTool::distanceLookup(int mx, int my, int src_x, int src_y)
48 {
49  unsigned int dx = abs(mx - src_x);
50  unsigned int dy = abs(my - src_y);
51  if(dx > mCellInflationRadius + 1 || dy > mCellInflationRadius + 1)
52  {
53  ROS_ERROR("Error in distanceLookup! Asked for (%d, %d), but CellInflationRadius is %d!", dx, dy, mCellInflationRadius);
54  return 50.0;
55  }
56  return mCachedDistances[dx][dy];
57 }
58 
59 // Method used to query the cache for the cell cost.
60 inline signed char MapInflationTool::costLookup(int mx, int my, int src_x, int src_y)
61 {
62  unsigned int dx = abs(mx - src_x);
63  unsigned int dy = abs(my - src_y);
64  if(dx > mCellInflationRadius + 1 || dy > mCellInflationRadius + 1)
65  {
66  ROS_ERROR("Error in costLookup! Asked for (%d, %d), but CellInflationRadius is %d!", dx, dy, mCellInflationRadius);
67  return 50.0;
68  }
69  return mCachedCosts[dx][dy];
70 }
71 
72 // Main method to start the inflation on the given map in-place.
74 {
75  ROS_DEBUG("Started map inflation ...");
76 
77  // 0. Do some initialization
78  mGridMap = map;
79  int mapSize = mGridMap->getSize();
80 
81  if(mInflationMarkers) delete[] mInflationMarkers;
82  mInflationMarkers = new unsigned char[mapSize];
83  for(int i = 0; i < mapSize; i++)
84  {
85  mInflationMarkers[i] = 0;
86  }
87 
88  // 1. Put all real obstacles in a queue
89  while(!mInflationQueue.empty()) mInflationQueue.pop();
90 
91  for(int index = 0; index < mapSize; index++)
92  {
93  if(mGridMap->getData(index) > 0)
94  {
95  unsigned int sx, sy;
96  mGridMap->getCoordinates(sx, sy, index);
97  enqueueObstacle(index, sx, sy);
98  }else if(mGridMap->getData(index) == -1)
99  {
100  mInflationMarkers[index] = 1;
101  }
102  }
103 
104  // 2. Inflate them by the given inflation radius
105  int count = 0;
106  while(!mInflationQueue.empty())
107  {
108  CellData cell = mInflationQueue.top();
109  mInflationQueue.pop();
110  unsigned int x,y;
111  if(!mGridMap->getCoordinates(x, y, cell.index)) continue;
112  if(x >= 1)
113  enqueueObstacle(cell.index-1, cell.sx, cell.sy);
114  if(x < mGridMap->getWidth() - 1)
115  enqueueObstacle(cell.index+1, cell.sx, cell.sy);
116  if(y >= 1)
117  enqueueObstacle(cell.index-mGridMap->getWidth(), cell.sx, cell.sy);
118  if(y < mGridMap->getHeight() - 1)
119  enqueueObstacle(cell.index+mGridMap->getWidth(), cell.sx, cell.sy);
120  count++;
121  }
122 
123  ROS_DEBUG("Finished inflation. (%d cells)", count);
124 }
125 
126 void MapInflationTool::enqueueObstacle(unsigned int index, unsigned int sx, unsigned int sy)
127 {
128  unsigned int mx, my;
129  if(!mGridMap->getCoordinates(mx, my, index)) return;
130  if(mInflationMarkers[index] != 0) return;
131 
132  double distance = distanceLookup(mx, my, sx, sy);
133  if(distance == 50)
134  ROS_INFO("Tried to add cell (%u, %u) -> (%u, %u) to inflation queue!", sx, sy, mx, my);
135 
136  if(distance > mCellInflationRadius) return;
137 
138  CellData cell(distance, index, sx, sy);
139  mInflationQueue.push(cell);
140  mInflationMarkers[index] = 1;
141  signed char value = costLookup(mx, my, sx, sy);
142  mGridMap->setData(index, value);
143 // ROS_DEBUG("Set cell %d cost to %d", index, value);
144 }
d
Definition: GridMap.h:7
unsigned int index
CellData(double d, double i, unsigned int sx, unsigned int sy)
TFSIMD_FORCE_INLINE const tfScalar & y() const
unsigned int getSize()
Definition: GridMap.h:20
void enqueueObstacle(unsigned int index, unsigned int sx, unsigned int sy)
double distance(double x0, double y0, double x1, double y1)
#define ROS_INFO(...)
TFSIMD_FORCE_INLINE const tfScalar & x() const
void inflateMap(GridMap *map)
signed char costLookup(int mx, int my, int src_x, int src_y)
unsigned int sy
double distanceLookup(int mx, int my, int src_x, int src_y)
unsigned int sx
double distance
#define ROS_ERROR(...)
void computeCaches(unsigned int radius)
#define ROS_DEBUG(...)


nav2d_navigator
Author(s): Sebastian Kasperski
autogenerated on Tue Nov 7 2017 06:02:48