lazy_tiled_grid_map.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_CORE_LAZY_TILED_GRID_MAP_H_INCLUDED
2 #define SLAM_CTOR_CORE_LAZY_TILED_GRID_MAP_H_INCLUDED
3 
4 #include <memory>
5 #include <cmath>
6 #include <cstring>
7 #include <vector>
8 #include <array>
9 #include <algorithm>
10 #include <tuple>
11 
13 #include "grid_cell.h"
14 #include "grid_map.h"
15 #include "../geometry_utils.h"
16 #include <iostream>
17 
18 class LazyTiledGridMap : public GridMap {
19 protected:
20  static constexpr unsigned Tile_Size_Bits = 7;
21  static constexpr unsigned Tile_Size = 1 << Tile_Size_Bits;
22  static constexpr unsigned Tile_Coord_Mask = Tile_Size - 1;
23 protected:
24  struct Tile;
25 public:
26  LazyTiledGridMap(std::shared_ptr<GridCell> prototype,
27  const GridMapParams& params = MapValues::gmp)
28  : GridMap{prototype, params}
29  , _unknown_cell{prototype->clone()}
30  , _unknown_tile{std::make_shared<Tile>(_unknown_cell)}
31  , _tiles_nm_x{(GridMap::width() + Tile_Size - 1) / Tile_Size}
32  , _tiles_nm_y{(GridMap::height() + Tile_Size - 1) / Tile_Size}
34 
35  void update(const Coord &area_id,
36  const AreaOccupancyObservation &aoo) override {
37  ensure_sole_owning(area_id);
38  GridMap::update(area_id, aoo);
39  }
40 
41  void reset(const Coord &area_id, const GridCell &new_area) override {
42  ensure_sole_owning(area_id);
43  GridMap::reset(area_id, new_area);
44  }
45 
46  const GridCell &operator[](const Coord& c) const override {
48  }
49 
50 protected: // methods & types
51 
52  const GridCell& cell_internal(const Coord& ic) const {
53  return *tile(ic)->cell(ic);
54  }
55 
56  void ensure_sole_owning(const Coord &area_id) {
57  auto coord = external2internal(area_id);
58  std::shared_ptr<Tile> &tile = this->tile(coord);
59  if (!tile) {
60  tile = std::make_shared<Tile>(_unknown_cell);
61  }
62  if (1 < tile.use_count()) {
63  tile.reset(new Tile{*tile});
64  }
65 
66  std::shared_ptr<GridCell> &cell = tile->cell(coord);
67  if (1 < cell.use_count()) {
68  cell = cell->clone();
69  }
70  }
71 
72  const std::shared_ptr<GridCell> unknown_cell() const { return _unknown_cell; }
73  std::shared_ptr<Tile> unknown_tile() { return _unknown_tile; }
74 
75  std::tuple<unsigned, unsigned>
76  extra_tiles_nm(int min, int val, int max) const {
77  assert(min <= max);
78  unsigned prepend_nm = 0, append_nm = 0;
79  if (val < min) {
80  prepend_nm = 1 + ((min - val) >> Tile_Size_Bits);
81  } else if (max <= val) {
82  append_nm = 1 + ((val - max) >> Tile_Size_Bits);
83  }
84  return std::make_tuple(prepend_nm, append_nm);
85  }
86 
87  struct Tile {
88  Tile(std::shared_ptr<GridCell> dflt) {
89  std::fill(_cells.begin(), _cells.end(), dflt);
90  }
91 
92  std::shared_ptr<GridCell> &cell(const Coord& cell_coord) {
93  return const_cast<std::shared_ptr<GridCell> &>(
94  static_cast<const Tile*>(this)->cell(cell_coord));
95  }
96 
97  const std::shared_ptr<GridCell> &cell(const Coord& cell_coord) const {
98  return _cells[(cell_coord.x & Tile_Coord_Mask) * Tile_Size +
99  (cell_coord.y & Tile_Coord_Mask)];
100  }
101  private:
102  std::array<std::shared_ptr<GridCell>, Tile_Size*Tile_Size> _cells;
103  };
104 
105 private: // methods
106  std::shared_ptr<Tile> &tile(const Coord &c) const {
107  return _tiles[(c.y >> Tile_Size_Bits) * _tiles_nm_x +
108  (c.x >> Tile_Size_Bits)];
109  }
110 
111 private: // fields
112  std::shared_ptr<GridCell> _unknown_cell;
113  std::shared_ptr<Tile> _unknown_tile;
114 protected: // fields
116  mutable std::vector<std::shared_ptr<Tile>> _tiles;
117 };
118 
119 /* Unbounded implementation */
120 
122 public:
123  UnboundedLazyTiledGridMap(std::shared_ptr<GridCell> prototype,
124  const GridMapParams& params = MapValues::gmp)
125  : LazyTiledGridMap{prototype, params}
126  , _origin{GridMap::origin()} {}
127 
128  void update(const Coord& area_id,
129  const AreaOccupancyObservation &aoo) override {
130  ensure_inside(area_id);
131  return LazyTiledGridMap::update(area_id, aoo);
132  }
133 
134  void reset(const Coord &area_id, const GridCell &new_area) override {
135  ensure_inside(area_id);
136  LazyTiledGridMap::reset(area_id, new_area);
137  }
138 
139  const GridCell &operator[](const Coord& ec) const override {
140  auto ic = external2internal(ec);
142  return *unknown_cell();
143  }
144 
146  }
147 
148  DiscretePoint2D origin() const override { return _origin; }
149  bool has_cell(const Coord &) const override { return true; }
150 
151 protected:
152 
154  auto coord = external2internal(c);
155  if (LazyTiledGridMap::has_internal_cell(coord)) return false;
156 
157  unsigned prep_x = 0, app_x = 0, prep_y = 0, app_y = 0;
158  std::tie(prep_x, app_x) = extra_tiles_nm(0, coord.x, width());
159  std::tie(prep_y, app_y) = extra_tiles_nm(0, coord.y, height());
160 
161  unsigned new_tiles_nm_x = prep_x + _tiles_nm_x + app_x;
162  unsigned new_tiles_nm_y = prep_y + _tiles_nm_y + app_y;
163  assert(_tiles_nm_x <= new_tiles_nm_x && _tiles_nm_y <= new_tiles_nm_y);
164 
165  std::vector<std::shared_ptr<Tile>> new_tiles{new_tiles_nm_x*new_tiles_nm_y,
166  unknown_tile()};
167  for (unsigned row_i = 0; row_i != _tiles_nm_y; ++row_i) {
168  std::move(&_tiles[row_i * _tiles_nm_x], // row begin
169  &_tiles[(row_i + 1) * _tiles_nm_x], // row end
170  &new_tiles[(prep_y + row_i)* new_tiles_nm_x + prep_x]);
171  }
172 
173  _tiles_nm_x = new_tiles_nm_x;
174  _tiles_nm_y = new_tiles_nm_y;
175  std::swap(_tiles, new_tiles);
177  set_width(_tiles_nm_x * Tile_Size);
178  _origin += Coord(prep_x * Tile_Size, prep_y * Tile_Size);
179 
180  assert(LazyTiledGridMap::has_cell(c));
181  return true;
182  }
183 
184 private: // fields
186 };
187 
188 #endif
std::shared_ptr< Tile > & tile(const Coord &c) const
void update(const Coord &area_id, const AreaOccupancyObservation &aoo) override
Updates area with a given observation.
Definition: grid_map.h:41
Coord external2internal(const Coord &coord) const
static constexpr unsigned Tile_Size
UnboundedLazyTiledGridMap(std::shared_ptr< GridCell > prototype, const GridMapParams &params=MapValues::gmp)
static constexpr GridMapParams gmp
Definition: grid_map.h:19
std::array< std::shared_ptr< GridCell >, Tile_Size *Tile_Size > _cells
void ensure_sole_owning(const Coord &area_id)
virtual bool has_cell(const Coord &c) const
const std::shared_ptr< GridCell > unknown_cell() const
void set_width(unsigned w)
std::vector< std::shared_ptr< Tile > > _tiles
virtual DiscretePoint2D origin() const
bool has_internal_cell(const Coord &c) const
static constexpr unsigned Tile_Size_Bits
static constexpr unsigned Tile_Coord_Mask
LazyTiledGridMap(std::shared_ptr< GridCell > prototype, const GridMapParams &params=MapValues::gmp)
void update(const Coord &area_id, const AreaOccupancyObservation &aoo) override
Updates area with a given observation.
std::shared_ptr< Tile > _unknown_tile
const GridCell & operator[](const Coord &c) const override
void set_height(unsigned h)
void update(const Coord &area_id, const AreaOccupancyObservation &aoo) override
Updates area with a given observation.
std::shared_ptr< GridCell > _unknown_cell
std::tuple< unsigned, unsigned > extra_tiles_nm(int min, int val, int max) const
bool ensure_inside(const DiscretePoint2D &c)
bool has_cell(const Coord &) const override
std::shared_ptr< GridCell > & cell(const Coord &cell_coord)
void reset(const Coord &area_id, const GridCell &new_area) override
virtual int height() const
Tile(std::shared_ptr< GridCell > dflt)
const GridCell & operator[](const Coord &ec) const override
const GridCell & cell_internal(const Coord &ic) const
std::shared_ptr< Tile > unknown_tile()
DiscretePoint2D origin() const override
virtual void reset(const Coord &area_id, const GridCell &new_area)
Definition: grid_map.h:54
void reset(const Coord &area_id, const GridCell &new_area) override
virtual int width() const
const std::shared_ptr< GridCell > & cell(const Coord &cell_coord) const


slam_constructor
Author(s): JetBrains Research, OSLL team
autogenerated on Mon Jun 10 2019 15:08:25