grid_map.h
Go to the documentation of this file.
1 
5 #ifndef _GRID_MAP_H
6 #define _GRID_MAP_H
7 
8 #include <memory>
9 #include <cmath>
10 
12 #include "grid_cell_factory.h"
13 #include "../geometry_utils.h"
14 
15 struct GridMapParams {
16  double width, height, meters_per_cell; // width & height in meters
17 };
18 
22 class GridMap {
23 public: // typedefs
24  using Cell = std::shared_ptr<GridCell>;
25 private: // typedefs
26  using Row = std::vector<Cell>;
27  using Map = std::vector<Row>;
28 
29 public:
30  // TODO: cp, mv ctors, dtor
35  GridMap(std::shared_ptr<GridCellFactory> cell_factory,
36  const GridMapParams &init_params) :
37  _width(std::floor(init_params.width/init_params.meters_per_cell)),
38  _height(std::floor(init_params.height/init_params.meters_per_cell)),
39  _m_per_cell(init_params.meters_per_cell),
40  _cell_factory(cell_factory), _cells(_height) {
41 
42  _map_center_x = std::floor((float)_width /2);
43  _map_center_y = std::floor((float)_height/2);
44 
45  for (auto &row : _cells) {
46  for (int i = 0; i < _width; i++) {
47  row.push_back(cell_factory->create_cell());
48  }
49  }
50  _unvisited_cell = cell_factory->create_cell();
51  }
52 
54  int width() const { return _width; }
55 
57  int height() const { return _height; }
58 
60  double scale() const { return _m_per_cell; }
61 
63  const std::vector<std::vector<Cell>> cells() const { return _cells; }
64 
65  #define COL_IND(cell_coord) \
66  ((cell_coord).x + _map_center_x)
67  #define ROW_IND(cell_coord) \
68  ((cell_coord).y + _map_center_y)
69 
76  void update_cell(const DiscretePoint2D& cell_coord,
77  const Occupancy &new_value, double quality = 1.0) {
78  // TODO: bounds check
79  update_size(cell_coord);
80 
81  int row = ROW_IND(cell_coord);
82  int col = COL_IND(cell_coord);
83  _cells[row][col]->set_value(new_value, quality);
84  }
85 
90  double cell_value(const DiscretePoint2D& cell_coord) const {
91  if (!has_cell(cell_coord))
92  return _unvisited_cell->value();
93 
94  return _cells[ROW_IND(cell_coord)][COL_IND(cell_coord)]->value();
95  }
96 
101  DiscretePoint2D world_to_cell(double x, double y) const {
102  #define METERS_TO_CELLS(var) \
103  std::floor((var)/_m_per_cell)
104 
106  #undef METERS_TO_CELLS
107  }
108 
110  double cell_scale() const { return _m_per_cell; }
111 
118  Rectangle bounds;
119  bounds.bot = cell_coord.y * _m_per_cell;
120  bounds.top = bounds.bot + _m_per_cell;
121  bounds.left = cell_coord.x * _m_per_cell;
122  bounds.right = bounds.left + _m_per_cell;
123  return bounds;
124  }
125 
129  int map_center_x() const { return _map_center_x; }
133  int map_center_y() const { return _map_center_y; }
134 
135 private: // methods
136  bool has_cell(const DiscretePoint2D& cell_coord) const {
137  return 0 <= COL_IND(cell_coord) && COL_IND(cell_coord) < _width &&
138  0 <= ROW_IND(cell_coord) && ROW_IND(cell_coord) < _height;
139  }
140 
141  void update_size(const DiscretePoint2D& cell_coord) {
142  resize_bound(RESIZE_HORZ, COL_IND(cell_coord));
143  resize_bound(RESIZE_VERT, ROW_IND(cell_coord));
144  }
145 
146  #define RESIZE_DIR(DIM,DIR) \
147  (((DIM) << RESIZE_DIM_BIT) | ((DIR) << RESIZE_DIR_BIT))
148 
149  void resize_bound(const int dim, const int container_coord) {
150  if (dim != RESIZE_HORZ && dim != RESIZE_VERT)
151  return;
152 
153  int bound = (dim == RESIZE_HORZ ? width() : height());
154  //find if it needs to resize map
155  int new_bound = calc_sufficient_bound(container_coord, bound);
156  if (new_bound == bound)
157  return;
158  //expands map with the exponential rule
159  // states are +100%, +300%, +700% etc ( -100% + [2^n*100%] )
160  int expand_rate = closest_bounded_power_two(new_bound/bound) - 1;
161  resize_in_direction(expand_rate*bound, RESIZE_DIR(dim, container_coord<0));
162  }
163 
164  int calc_sufficient_bound(const int container_coord, const int map_bound) {
165  if (container_coord < 0)
166  return (-container_coord)+map_bound;
167  if (map_bound <= container_coord)
168  return container_coord + 1;
169  return map_bound;
170  }
171 
172  /* Finds the nearest upper bound value of degree of 2 to the input integer
173  * NOTE: 2-3 are bounded by 4,
174  * 4-7 are bounded by 8,
175  * 8-15 are bounded by 16 etc.
176  */
178  long p2 = 1;
179  while (p2 <= x) {
180  p2 <<= 1;
181  }
182  return p2;
183  }
184 
185  void resize_in_direction(const int delta, const int direction_flag) {
186  if (delta <= 0)
187  return;
188 
189  if (direction_flag == RESIZE_DOWN) {
190  add_rows(delta, _cells.begin());
191  _map_center_y += delta;
192  } else if (direction_flag == RESIZE_UP) {
193  add_rows(delta, _cells.end());
194  } else if (direction_flag == RESIZE_LEFT) {
195  add_cols(delta, [](Row& vector) { return vector.begin(); });
196  _map_center_x += delta;
197  } else if (direction_flag == RESIZE_RIGHT) {
198  add_cols(delta, [](Row& vector) { return vector.end(); });
199  }
200  }
201 
202  void add_rows(const int rows_count, Map::iterator it) {
203  Map new_rows(rows_count, Row(width()));
204  for (auto& row : new_rows) {
205  for (auto& cell : row) {
206  cell = _cell_factory->create_cell();
207  }
208  }
209  _cells.insert(it, new_rows.begin(), new_rows.end());
210  _height += rows_count;
211  }
212 
213  void add_cols(const int cols_count, std::function<Row::iterator(Row&)> it) {
214  Map new_cols(height(), Row(cols_count));
215  for (auto& row : new_cols) {
216  for (auto& cell : row) {
217  cell = _cell_factory->create_cell();
218  }
219  }
220  for (size_t i = 0; i < new_cols.size(); i++) {
221  _cells[i].insert(it(_cells[i]), new_cols[i].begin(), new_cols[i].end());
222  }
223  _width += cols_count;
224  }
225  #undef INDEX_I
226  #undef INDEX_J
227 
228 private: //flag constants
229  const int RESIZE_VERT = 0;
230  const int RESIZE_HORZ = 1;
231  const int RESIZE_DIM_BIT = 1;
232 
233  const int RESIZE_FWD = 0;
234  const int RESIZE_BWD = 1;
235  const int RESIZE_DIR_BIT = 0;
236 
237  const int RESIZE_UP = RESIZE_DIR(RESIZE_VERT, RESIZE_FWD);
238  const int RESIZE_DOWN = RESIZE_DIR(RESIZE_VERT, RESIZE_BWD);
239  const int RESIZE_RIGHT = RESIZE_DIR(RESIZE_HORZ, RESIZE_FWD);
240  const int RESIZE_LEFT = RESIZE_DIR(RESIZE_HORZ, RESIZE_BWD);
241  #undef RESIZE_DIR
242 
243 private: // fields
244  int _width, _height;
245  int _map_center_x, _map_center_y;
246  double _m_per_cell;
248  std::shared_ptr<GridCellFactory> _cell_factory;
250 };
251 
252 #endif
double cell_value(const DiscretePoint2D &cell_coord) const
Definition: grid_map.h:90
#define METERS_TO_CELLS(var)
double top
The top of a rectangle.
GridMap(std::shared_ptr< GridCellFactory > cell_factory, const GridMapParams &init_params)
Definition: grid_map.h:35
double bot
The bottom of a rectangle.
#define ROW_IND(cell_coord)
Definition: grid_map.h:67
int width() const
Returns the width of the map.
Definition: grid_map.h:54
Rectangle world_cell_bounds(const DiscretePoint2D &cell_coord)
Definition: grid_map.h:117
int height() const
Returns thr height of the map.
Definition: grid_map.h:57
double right
The right side of a rectangle.
An occupancy grid implementation.
Definition: grid_map.h:22
std::vector< Row > Map
Definition: grid_map.h:27
#define COL_IND(cell_coord)
Definition: grid_map.h:65
double meters_per_cell
Definition: grid_map.h:16
void update_size(const DiscretePoint2D &cell_coord)
Definition: grid_map.h:141
void resize_in_direction(const int delta, const int direction_flag)
Definition: grid_map.h:185
void update_cell(const DiscretePoint2D &cell_coord, const Occupancy &new_value, double quality=1.0)
Definition: grid_map.h:76
std::shared_ptr< GridCellFactory > _cell_factory
Definition: grid_map.h:248
int calc_sufficient_bound(const int container_coord, const int map_bound)
Definition: grid_map.h:164
Cell _unvisited_cell
Definition: grid_map.h:247
std::vector< Cell > Row
Definition: grid_map.h:26
void add_rows(const int rows_count, Map::iterator it)
Definition: grid_map.h:202
int _map_center_y
Definition: grid_map.h:245
double cell_scale() const
Returnes the scale.
Definition: grid_map.h:110
Defines interface Cell Occupancy Estimator. There are structures Occupancy and Beam that are used in ...
int y
Coordinates of point.
double scale() const
Returns the scale.
Definition: grid_map.h:60
void add_cols(const int cols_count, std::function< Row::iterator(Row &)> it)
Definition: grid_map.h:213
double left
The left side of a rectangle.
void resize_bound(const int dim, const int container_coord)
Definition: grid_map.h:149
long closest_bounded_power_two(long x)
Definition: grid_map.h:177
Defines an axis-aligned rectangle.
double height
Definition: grid_map.h:16
double _m_per_cell
Definition: grid_map.h:246
DiscretePoint2D world_to_cell(double x, double y) const
Definition: grid_map.h:101
double width
Definition: grid_map.h:16
#define RESIZE_DIR(DIM, DIR)
Definition: grid_map.h:146
bool has_cell(const DiscretePoint2D &cell_coord) const
Definition: grid_map.h:136
int map_center_y() const
Definition: grid_map.h:133
std::shared_ptr< GridCell > Cell
Definition: grid_map.h:24
int _width
Definition: grid_map.h:244
Defines a point with integer coordinates on a plane.
int map_center_x() const
Definition: grid_map.h:129
Map _cells
Definition: grid_map.h:249
const std::vector< std::vector< Cell > > cells() const
Returns map&#39;s cells.
Definition: grid_map.h:63
The following classes are defined in this file GridCell - base class for GridMap&#39;s cell; GridCellFact...


tiny_slam
Author(s):
autogenerated on Mon Jun 10 2019 15:30:57