rescalable_caching_grid_map.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_CORE_RESCALABLE_CACHING_GRID_MAP_H
2 #define SLAM_CTOR_CORE_RESCALABLE_CACHING_GRID_MAP_H
3 
4 #include <memory>
5 #include <cassert>
6 #include <limits>
7 #include <utility>
8 
9 #include "grid_cell.h"
10 #include "grid_map.h"
11 #include "grid_rasterization.h"
12 
13 template <typename BackGridMap>
15 private: // type aliases
16  using MapCache = std::vector<std::unique_ptr<GridMap>>;
17 private: // consts
18  static constexpr int Coarsest_Map_W = 1, Coarsest_Map_H = 1;
19 public: // consts
20  static constexpr unsigned Map_Scale_Factor = 2;
21 public:
22  RescalableCachingGridMap(std::shared_ptr<GridCell> prototype,
23  const GridMapParams& params = MapValues::gmp)
24  : GridMap{prototype, params}
25  , _map_cache{std::make_shared<MapCache>()} {
26 
27  // the finest map
28  _map_cache->push_back(std::make_unique<BackGridMap>(prototype, params));
29  // the coarsest map
30  auto coarsest_mp = GridMapParams{Coarsest_Map_W, Coarsest_Map_H,
31  std::numeric_limits<double>::infinity()};
32  auto coarsest_map = std::make_unique<BackGridMap>(prototype, coarsest_mp);
33  _map_cache->push_back(std::move(coarsest_map));
35 
37  }
38 
43 
44  //----------------------------------------------------------------------------
45  // API for manual scale management.
46 
47  unsigned scales_nm() const {
49  return _map_cache->size();
50  }
51 
52  unsigned scale_id() const { return _scale_id; }
53 
54  static constexpr unsigned finest_scale_id() { return 0; }
55  unsigned coarsest_scale_id() const { return scales_nm() - 1; }
56 
57  void set_scale_id(unsigned scale_id) {
58  assert(scale_id < scales_nm());
61  }
62 
63  //----------------------------------------------------------------------------
64  // RegularSquaresGrid overrides
65 
66  Coord origin() const override { return active_map().origin(); }
67  int width() const override { return active_map().width(); }
68  int height() const override { return active_map().height(); }
69  double scale() const override { return active_map().scale(); }
70  bool has_cell(const Coord &c) const override {
71  return active_map().has_cell(c);
72  }
73 
74  void rescale(double target_scale) override {
76 
77  // TODO: replace the linear probing
78  unsigned scale_id = finest_scale_id();
79  while (1) {
80  if (target_scale <= map(scale_id).scale()) {
81  break;
82  }
83  ++scale_id;
84  }
85  set_scale_id(scale_id);
86  }
87 
88  //----------------------------------------------------------------------------
89  // GridMap overrides
90 
91  const GridCell& operator[](const Coord &coord) const override {
92  return active_map()[coord];
93  }
94 
95  void update(const Coord &area_id,
96  const AreaOccupancyObservation &aoo) override {
97  active_map().update(area_id, aoo);
98  on_area_update(area_id);
99  }
100 
101  void reset(const Coord &area_id,
102  const GridCell &area) override {
103  active_map().reset(area_id, area);
104  on_area_update(area_id);
105  }
106 
107 private:
108 
109  void on_area_update(const Coord &area_id) {
110  using GRRectangle = GridRasterizedRectangle;
111  // TODO: update if a "non-finest" cell is updated?
112  assert(_scale_id == finest_scale_id());
113  auto modified_area = active_map()[area_id];
114  auto modified_space = active_map().world_cell_bounds(area_id);
115 
116  for (unsigned coarser_scale_id = _scale_id + 1;
117  coarser_scale_id <= coarsest_scale_id(); ++coarser_scale_id) {
118  auto& coarser_map = map(coarser_scale_id);
119  bool coarser_area_is_updated = false;
120  auto cm_coords = GRRectangle{coarser_map, modified_space, false};
121  while (cm_coords.has_next()) {
122  auto coord = cm_coords.next();
123  auto &coarser_area = coarser_map[coord];
124  if (double(modified_area) <= double(coarser_area)) { continue; }
125 
126  coarser_map.reset(coord, modified_area);
127  coarser_area_is_updated = true;
128  }
129  if (!coarser_area_is_updated) { break; }
130  }
131  }
132 
133  const GridMap& map(unsigned scale_id) const {
134  return *(*_map_cache)[scale_id];
135  }
136 
137  GridMap& map(unsigned scale_id) {
138  return const_cast<GridMap&>(
139  static_cast<const RescalableCachingGridMap&>(*this).map(scale_id));
140  }
141 
142  const GridMap& active_map() const {
143  return *_active_map;
144  }
145 
147  return const_cast<GridMap&>(
148  static_cast<const RescalableCachingGridMap&>(*this).active_map());
149  }
150 
152  static const int PC_W_Target = Coarsest_Map_W * Map_Scale_Factor,
153  PC_H_Target = Coarsest_Map_H * Map_Scale_Factor;
154 
155  const GridMap& pre_coarsest_map = map(_map_cache->size() - 2);
156  int pc_w = pre_coarsest_map.width(), pc_h = pre_coarsest_map.height();
157  double pc_scale = pre_coarsest_map.scale();
158 
159  if (pc_w <= PC_W_Target && pc_h <= PC_H_Target) { return; }
160 
161  pc_w = ge_pow<Map_Scale_Factor>(pc_w);
162  pc_h = ge_pow<Map_Scale_Factor>(pc_h);
163  // more cache levels have to be added
164  while (PC_W_Target < pc_w || PC_H_Target < pc_h) {
165  pc_w = std::max(PC_W_Target, int(std::ceil(pc_w / Map_Scale_Factor)));
166  pc_h = std::max(PC_H_Target, int(std::ceil(pc_h / Map_Scale_Factor)));
167  pc_scale *= Map_Scale_Factor;
168 
169  auto map_params = GridMapParams{pc_w, pc_h, pc_scale};
170  auto map = std::make_unique<BackGridMap>(cell_prototype(), map_params);
171  _map_cache->insert((_map_cache->rbegin() + 1).base(), std::move(map));
172  }
173  }
174 
175 private:
176  GridMap *_active_map = nullptr;
177  unsigned _scale_id = -1;
178  mutable std::shared_ptr<MapCache> _map_cache;
179 };
180 
181 // a RAII for const grid map rescaling
183 public:
185  : _vanilla_scale{map.scale()}, _map{const_cast<GridMap&>(map)} {}
186  ~SafeRescalableMap() { _map.rescale(_vanilla_scale); }
187  SafeRescalableMap(const SafeRescalableMap&) = delete;
191 
192  operator GridMap&() { return _map; }
193 private:
196 };
197 
198 #endif // header guard
void update(const Coord &area_id, const AreaOccupancyObservation &aoo) override
Updates area with a given observation.
Definition: grid_map.h:41
bool has_cell(const Coord &c) const override
GridMap & map(unsigned scale_id)
static constexpr unsigned Map_Scale_Factor
void on_area_update(const Coord &area_id)
void update(const Coord &area_id, const AreaOccupancyObservation &aoo) override
Updates area with a given observation.
Rectangle world_cell_bounds(const Coord &coord) const
static constexpr GridMapParams gmp
Definition: grid_map.h:19
std::shared_ptr< GridCell > cell_prototype() const
Definition: grid_map.h:69
virtual bool has_cell(const Coord &c) const
static constexpr unsigned finest_scale_id()
const GridCell & operator[](const Coord &coord) const override
virtual DiscretePoint2D origin() const
void rescale(double target_scale) override
void set_scale_id(unsigned scale_id)
SafeRescalableMap(const GridMap &map)
RescalableCachingGridMap & operator=(const RescalableCachingGridMap &)=delete
const GridMap & active_map() const
void reset(const Coord &area_id, const GridCell &area) override
virtual int height() const
std::vector< std::unique_ptr< GridMap >> MapCache
const GridMap & map(unsigned scale_id) const
RescalableCachingGridMap(std::shared_ptr< GridCell > prototype, const GridMapParams &params=MapValues::gmp)
std::shared_ptr< MapCache > _map_cache
virtual void reset(const Coord &area_id, const GridCell &new_area)
Definition: grid_map.h:54
virtual double scale() const
virtual int width() const


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