grid_map_scan_adders.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_CORE_GRID_MAP_SCAN_ADDERS_H
2 #define SLAM_CTOR_CORE_GRID_MAP_SCAN_ADDERS_H
3 
4 #include <cmath>
5 #include <limits>
6 #include <memory>
7 
8 #include "grid_map.h"
10 #include "../states/sensor_data.h"
11 #include "../states/world.h"
12 
14 public:
15  GridMapScanAdder(std::shared_ptr<CellOccupancyEstimator> e)
16  : _occ_est{e} {}
17 
18  GridMap& append_scan(GridMap &map, const RobotPose &pose,
19  const LaserScan2D &scan,
20  double scan_quality,
21  double scan_margin = 0.0) const {
22  if (scan.points().empty()) { return map; }
23 
24  const auto rp = pose.point();
25  scan.trig_provider->set_base_angle(pose.theta);
26  size_t last_pt_i = scan.points().size() - scan_margin - 1;
27  for (size_t pt_i = scan_margin; pt_i <= last_pt_i; ++pt_i) {
28  const auto &sp = scan.points()[pt_i];
29  // move to world frame assume sensor is in robots' (0,0)
30  const auto &wp = sp.move_origin(rp, scan.trig_provider);
31  handle_scan_point(map, sp.is_occupied(), scan_quality, {rp, wp});
32  }
33 
34  return map;
35  }
36 
37 protected:
39  auto estimate_occupancy(const Segment2D &beam,
40  const Rectangle &area_bnds,
41  bool is_occupied) const {
42  return _occ_est->estimate_occupancy(beam, area_bnds, is_occupied);
43  }
44 
45  virtual void handle_scan_point(GridMap &map, bool is_occ, double scan_quality,
46  const Segment2D &beam) const = 0;
47 
48 public:
49  std::shared_ptr<CellOccupancyEstimator> _occ_est;
50 };
51 
53 private:
55  #define ADD_SETTER(type, prop_name) \
56  private: \
57  type _##prop_name; \
58  public: \
59  auto& set_##prop_name(decltype(_##prop_name) prop_name) { \
60  _##prop_name = prop_name; \
61  return *this; \
62  } \
63  const auto& prop_name() const { return _##prop_name; }
64 
65  ADD_SETTER(double, blur_distance);
66  ADD_SETTER(std::shared_ptr<CellOccupancyEstimator>, occupancy_estimator);
67  ADD_SETTER(double, max_usable_range);
68  #undef ADD_SETTER
69 
70  public:
72  : _blur_distance{0}
73  , _max_usable_range{std::numeric_limits<double>::infinity()} {}
74 
75  auto build() const {
76  return std::make_shared<WallDistanceBlurringScanAdder>(*this);
77  }
78  };
79 public:
82  }
83 
86  : GridMapScanAdder{props.occupancy_estimator()}
87  , _props{props}
88  , _max_usable_range_sq{std::pow(_props.max_usable_range(), 2)}{}
89 protected:
90 
91  // TODO: limit beam randering by distance
92  // either from a robot or a from obstace
93  // TODO: consider renaming blur to distortion
94  void handle_scan_point(GridMap &map, bool is_occ, double scan_quality,
95  const Segment2D &beam) const override {
96  if (_max_usable_range_sq < beam.length_sq()) {
97  return;
98  }
99  // TODO: simplify, consider performance if _blur_dist is not set
100  // (a static factory method)
101  auto robot_pt = map.world_to_cell(beam.beg());
102  auto obst_pt = map.world_to_cell(beam.end());
103  auto obst_dist_sq = robot_pt.dist_sq(obst_pt);
104  auto hole_dist_sq = std::pow(blur_cell_dist(map, beam, is_occ), 2);
105 
106  auto pts = map.world_to_cells(beam);
107  auto pt_bounds = map.world_cell_bounds(pts.back());
108  auto base_occup = estimate_occupancy(beam, pt_bounds, is_occ);
109  auto occ_aoo = AOO{is_occ, base_occup, beam.end(), scan_quality};
110  map.update(pts.back(), occ_aoo);
111  pts.pop_back();
112 
113  auto empty_aoo = AOO{false, {0, 0}, beam.end(), scan_quality};
114  for (const auto &pt : pts) {
115  const auto dist_sq = pt.dist_sq(obst_pt);
116  auto pt_bounds = map.world_cell_bounds(pt);
117  empty_aoo.is_occupied = false;
118  empty_aoo.occupancy = estimate_occupancy(beam, pt_bounds, false);
119 
120  if (dist_sq < hole_dist_sq && hole_dist_sq < obst_dist_sq) {
121  // NB: empty cell occupancy quality is not changed
122  empty_aoo.is_occupied = true;
123  auto prob_scale = 1.0 - dist_sq / hole_dist_sq;
124  empty_aoo.occupancy.prob_occ = base_occup.prob_occ * prob_scale;
125  }
126  map.update(pt, empty_aoo);
127  }
128  }
129 
130 private:
131  // return obstacle blur distance in cells
132  double blur_cell_dist(const GridMap &map, const Segment2D &beam,
133  bool is_occ) const {
134  if (!is_occ) { // no wall -> no blurring
135  return 0;
136  }
137 
138  auto blur_dist = _props.blur_distance() / map.scale();
139  if (blur_dist < 0) {
140  // dynamic wall blurring, Hole_Width is a scaling coefficient
141  double dist_sq = beam.length_sq();
142  blur_dist *= -dist_sq;
143  }
144  return blur_dist;
145  }
146 
147 private:
150 };
151 
152 #endif
void update(const Coord &area_id, const AreaOccupancyObservation &aoo) override
Updates area with a given observation.
Definition: grid_map.h:41
std::shared_ptr< CellOccupancyEstimator > _occ_est
void handle_scan_point(GridMap &map, bool is_occ, double scan_quality, const Segment2D &beam) const override
Coord world_to_cell(const Point2D &pt) const
Rectangle world_cell_bounds(const Coord &coord) const
double theta
Definition: robot_pose.h:131
double dist_sq(const Point2D &pt) const
virtual void handle_scan_point(GridMap &map, bool is_occ, double scan_quality, const Segment2D &beam) const =0
WallDistanceBlurringScanAdder(const ScanAdderProperties &props)
#define ADD_SETTER(type, prop_name)
double dist_sq(const DiscretePoint2D &pt) const
static WallDistanceBlurringScanAdderBuilder builder()
auto estimate_occupancy(const Segment2D &beam, const Rectangle &area_bnds, bool is_occupied) const
const Point2D & end() const
const Points & points() const
Definition: sensor_data.h:148
std::vector< Coord > world_to_cells(const Segment2D &s) const
double blur_cell_dist(const GridMap &map, const Segment2D &beam, bool is_occ) const
std::shared_ptr< TrigonometryProvider > trig_provider
Definition: sensor_data.h:171
GridMapScanAdder(std::shared_ptr< CellOccupancyEstimator > e)
auto point() const
Definition: robot_pose.h:129
const Point2D & beg() const
double length_sq() const
GridMap & append_scan(GridMap &map, const RobotPose &pose, const LaserScan2D &scan, double scan_quality, double scan_margin=0.0) const
virtual double scale() const


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