Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
map_cspace.cpp
1 /*
2  * Player - One Hell of a Robot Server
3  * Copyright (C) 2000 Brian Gerkey & Kasper Stoy
4  * gerkey@usc.edu kaspers@robotics.usc.edu
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include <math.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <queue>
26 #include "nav2_amcl/map/map.hpp"
27 
28 /*
29  * @class CellData
30  * @brief Data about map cells
31  */
32 class CellData
33 {
34 public:
35  map_t * map_;
36  unsigned int i_, j_;
37  unsigned int src_i_, src_j_;
38 };
39 
40 /*
41  * @class CachedDistanceMap
42  * @brief Cached map with distances
43  */
45 {
46 public:
47  /*
48  * @brief CachedDistanceMap constructor
49  */
50  CachedDistanceMap(double scale, double max_dist)
51  : distances_(NULL), scale_(scale), max_dist_(max_dist)
52  {
53  cell_radius_ = max_dist / scale;
54  distances_ = new double *[cell_radius_ + 2];
55  for (int i = 0; i <= cell_radius_ + 1; i++) {
56  distances_[i] = new double[cell_radius_ + 2];
57  for (int j = 0; j <= cell_radius_ + 1; j++) {
58  distances_[i][j] = sqrt(i * i + j * j);
59  }
60  }
61  }
62 
63  /*
64  * @brief CachedDistanceMap destructor
65  */
67  {
68  if (distances_) {
69  for (int i = 0; i <= cell_radius_ + 1; i++) {
70  delete[] distances_[i];
71  }
72  delete[] distances_;
73  }
74  }
75  double ** distances_;
76  double scale_;
77  double max_dist_;
78  int cell_radius_;
79 };
80 
81 /*
82  * @brief operator<
83  */
84 bool operator<(const CellData & a, const CellData & b)
85 {
86  return a.map_->cells[MAP_INDEX(
87  a.map_, a.i_,
88  a.j_)].occ_dist > a.map_->cells[MAP_INDEX(b.map_, b.i_, b.j_)].occ_dist;
89 }
90 
91 /*
92  * @brief get_distance_map
93  * @param scale of cost information wrt distance
94  * @param max_dist Maximum distance to cache from occupied information
95  * @return Pointer to cached distance map
96  */
98 get_distance_map(double scale, double max_dist)
99 {
100  static CachedDistanceMap * cdm = NULL;
101 
102  if (!cdm || (cdm->scale_ != scale) || (cdm->max_dist_ != max_dist)) {
103  if (cdm) {
104  delete cdm;
105  }
106  cdm = new CachedDistanceMap(scale, max_dist);
107  }
108 
109  return cdm;
110 }
111 
112 /*
113  * @brief enqueue cell data for caching
114  */
115 void enqueue(
116  map_t * map, int i, int j,
117  int src_i, int src_j,
118  std::priority_queue<CellData> & Q,
119  CachedDistanceMap * cdm,
120  unsigned char * marked)
121 {
122  if (marked[MAP_INDEX(map, i, j)]) {
123  return;
124  }
125 
126  int di = abs(i - src_i);
127  int dj = abs(j - src_j);
128  double distance = cdm->distances_[di][dj];
129 
130  if (distance > cdm->cell_radius_) {
131  return;
132  }
133 
134  map->cells[MAP_INDEX(map, i, j)].occ_dist = distance * map->scale;
135 
136  CellData cell;
137  cell.map_ = map;
138  cell.i_ = i;
139  cell.j_ = j;
140  cell.src_i_ = src_i;
141  cell.src_j_ = src_j;
142 
143  Q.push(cell);
144 
145  marked[MAP_INDEX(map, i, j)] = 1;
146 }
147 
148 /*
149  * @brief Update the cspace distance values
150  * @param map Map to update
151  * @param max_occ_distance Maximum distance for occpuancy interest
152  */
153 void map_update_cspace(map_t * map, double max_occ_dist)
154 {
155  unsigned char * marked;
156  std::priority_queue<CellData> Q;
157 
158  marked = new unsigned char[map->size_x * map->size_y];
159  memset(marked, 0, sizeof(unsigned char) * map->size_x * map->size_y);
160 
161  map->max_occ_dist = max_occ_dist;
162 
163  CachedDistanceMap * cdm = get_distance_map(map->scale, map->max_occ_dist);
164 
165  // Enqueue all the obstacle cells
166  CellData cell;
167  cell.map_ = map;
168  for (int i = 0; i < map->size_x; i++) {
169  cell.src_i_ = cell.i_ = i;
170  for (int j = 0; j < map->size_y; j++) {
171  if (map->cells[MAP_INDEX(map, i, j)].occ_state == +1) {
172  map->cells[MAP_INDEX(map, i, j)].occ_dist = 0.0;
173  cell.src_j_ = cell.j_ = j;
174  marked[MAP_INDEX(map, i, j)] = 1;
175  Q.push(cell);
176  } else {
177  map->cells[MAP_INDEX(map, i, j)].occ_dist = max_occ_dist;
178  }
179  }
180  }
181 
182  while (!Q.empty()) {
183  CellData current_cell = Q.top();
184  if (current_cell.i_ > 0) {
185  enqueue(
186  map, current_cell.i_ - 1, current_cell.j_,
187  current_cell.src_i_, current_cell.src_j_,
188  Q, cdm, marked);
189  }
190  if (current_cell.j_ > 0) {
191  enqueue(
192  map, current_cell.i_, current_cell.j_ - 1,
193  current_cell.src_i_, current_cell.src_j_,
194  Q, cdm, marked);
195  }
196  if (static_cast<int>(current_cell.i_) < map->size_x - 1) {
197  enqueue(
198  map, current_cell.i_ + 1, current_cell.j_,
199  current_cell.src_i_, current_cell.src_j_,
200  Q, cdm, marked);
201  }
202  if (static_cast<int>(current_cell.j_) < map->size_y - 1) {
203  enqueue(
204  map, current_cell.i_, current_cell.j_ + 1,
205  current_cell.src_i_, current_cell.src_j_,
206  Q, cdm, marked);
207  }
208 
209  Q.pop();
210  }
211 
212  delete[] marked;
213 }
Definition: map.hpp:61