grid_scan_matcher.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_CORE_GRID_SCAN_MATCHER_H
2 #define SLAM_CTOR_CORE_GRID_SCAN_MATCHER_H
3 
4 #include <vector>
5 #include <memory>
6 #include <algorithm>
7 #include <limits>
8 
9 #include "../states/state_data.h"
10 #include "../states/sensor_data.h"
11 #include "../states/robot_pose.h"
12 #include "../maps/occupancy_map.h"
13 #include "../maps/grid_map.h"
14 
16 public:
17  virtual void on_matching_start(const RobotPose &, /*pose*/
18  const TransformedLaserScan &, /*scan*/
19  const GridMap &) {} /*map*/
20  virtual void on_scan_test(const RobotPose &, /*pose*/
21  const LaserScan2D &, /*scan*/
22  double) {}; /*score*/
23  virtual void on_pose_update(const RobotPose &, /*pose*/
24  const LaserScan2D &, /*scan*/
25  double) {}; /*score*/
26  virtual void on_matching_end(const RobotPose &, /*delta*/
27  const LaserScan2D &, /* applied scan */
28  double) {}; /*best_score*/
29 };
30 
31 /* Estimates p(observation | map & area) */
33 public:
34  // TODO: [API Clean Up] GridMap -> OccupancyMap
35  virtual double probability(const AreaOccupancyObservation &aoo,
36  const LightWeightRectangle &area,
37  const GridMap &map) const = 0;
38  virtual ~OccupancyObservationProbabilityEstimator() = default;
39 };
40 
41 /* Client (e.g. a scan matcher) code example:
42  * ...
43  * ScanProbabilityEstimator &spe = spe();
44  * auto scan = spe.filter_scan(raw_scan, map);
45  * auto scan_prob = spe.enstimate_scan_probability(scan, ...);
46  * ...
47  * NB: the _filter_scan_ call isn't obligatory (depends on spe),
48  * but it may improve _spe_ performance.
49  */
51 public: // types
52  struct SPEParams {
53  // area in the neighborhood of a scan point that should be analyzed
54  LightWeightRectangle sp_analysis_area = {0, 0, 0, 0};
55  bool scan_is_prerotated = false;
56  };
57  using OOPE = std::shared_ptr<OccupancyObservationProbabilityEstimator>;
58 public:
59  ScanProbabilityEstimator(OOPE oope) : _oope{oope} {}
60 
61  constexpr static double unknown_probability() {
62  return std::numeric_limits<double>::quiet_NaN();
63  }
64 
65  static bool is_prob_unknown(double probability) {
66  return probability == unknown_probability();
67  }
68 
70  void set_oope(OOPE occ_obs_prob_est) { _oope = occ_obs_prob_est; }
71 
73  const LightWeightRectangle &area,
74  const GridMap &map) const {
75  return _oope->probability(aoo, area, map);
76  }
77 
78  virtual LaserScan2D filter_scan(const LaserScan2D &scan, const RobotPose &,
79  const GridMap &) {
80  return scan;
81  }
82 
84  const RobotPose &pose,
85  const GridMap &map) const {
86  return estimate_scan_probability(scan, pose, map, SPEParams{});
87  }
88 
89  virtual double estimate_scan_probability(const LaserScan2D &scan,
90  const RobotPose &pose,
91  const GridMap &map,
92  const SPEParams &params) const = 0;
93 
94  virtual ~ScanProbabilityEstimator() = default;
95 private:
97 };
98 
100 public:
101  using ObsPtr = std::shared_ptr<GridScanMatcherObserver>;
102  using SPE = std::shared_ptr<ScanProbabilityEstimator>;
104 public:
105  GridScanMatcher(SPE estimator,
106  double max_x_error = 0, double max_y_error = 0,
107  double max_th_error = 0)
108  : _scan_prob_estimator{estimator}
109  , _max_x_error{max_x_error}, _max_y_error{max_y_error}
110  , _max_th_error{max_th_error} {}
111  virtual ~GridScanMatcher() = default;
112 
113  // TODO: fix method's name; add pose_delta to return value
114  virtual double process_scan(const TransformedLaserScan &scan,
115  const RobotPose &init_pose,
116  const GridMap &map,
117  RobotPoseDelta &pose_delta) = 0;
118 
119  virtual void reset_state() {};
120 
121  void subscribe(std::shared_ptr<GridScanMatcherObserver> obs) {
122  _observers.push_back(obs);
123  }
124 
125  void unsubscribe(std::shared_ptr<GridScanMatcherObserver> obs) {
126  // TODO: replace with more ideomatic C++
127  std::vector<std::weak_ptr<GridScanMatcherObserver>> new_observers;
128  for (auto &raw_obs : GridScanMatcher::observers()) {
129  auto obs_ptr = raw_obs.lock();
130  if (obs_ptr && obs_ptr != obs) {
131  new_observers.push_back(raw_obs);
132  }
133  }
134  _observers = new_observers;
135  }
136 
137  void set_lookup_ranges(double x, double y = 0, double th = 0) {
138  _max_x_error = x;
139  _max_y_error = y;
140  _max_th_error = th;
141  }
142 
143  LaserScan2D filter_scan(const LaserScan2D &scan, const RobotPose &pose,
144  const GridMap &map) {
145  return scan_probability_estimator()->filter_scan(scan, pose, map);
146  }
147 
148  double scan_probability(const LaserScan2D &scan, const RobotPose &pose,
149  const GridMap &map) const {
150  return _scan_prob_estimator->estimate_scan_probability(scan, pose, map);
151  }
152 
153  double scan_probability(const LaserScan2D &scan, const RobotPose &pose,
154  const GridMap &map, const SPEParams &p) const {
155  return _scan_prob_estimator->estimate_scan_probability(scan, pose, map, p);
156  }
157 
159  return _scan_prob_estimator;
160  }
161 
163  _scan_prob_estimator = spe;
164  }
165 
166 protected:
167 
168  std::vector<std::weak_ptr<GridScanMatcherObserver>> & observers() {
169  return _observers;
170  }
171 
172  void do_for_each_observer(std::function<void(ObsPtr)> op) {
173  for (auto &obs : observers()) {
174  if (auto obs_ptr = obs.lock()) {
175  op(obs_ptr);
176  }
177  }
178  }
179 
180  double max_x_error() { return _max_x_error; }
181  double max_y_error() { return _max_y_error; }
182  double max_th_error() { return _max_th_error; }
183 
184 private:
185  std::vector<std::weak_ptr<GridScanMatcherObserver>> _observers;
187  double _max_x_error = 0, _max_y_error = 0, _max_th_error = 0;
188 };
189 
190 #endif
virtual void on_scan_test(const RobotPose &, const LaserScan2D &, double)
virtual LaserScan2D filter_scan(const LaserScan2D &scan, const RobotPose &, const GridMap &)
std::shared_ptr< ScanProbabilityEstimator > SPE
void subscribe(std::shared_ptr< GridScanMatcherObserver > obs)
static constexpr double unknown_probability()
double occupancy_observation_probability(const AreaOccupancyObservation &aoo, const LightWeightRectangle &area, const GridMap &map) const
virtual void on_matching_end(const RobotPose &, const LaserScan2D &, double)
std::shared_ptr< GridScanMatcherObserver > ObsPtr
std::shared_ptr< OccupancyObservationProbabilityEstimator > OOPE
OOPE occupancy_observation_probability_estimator() const
TFSIMD_FORCE_INLINE const tfScalar & y() const
virtual void on_pose_update(const RobotPose &, const LaserScan2D &, double)
virtual void on_matching_start(const RobotPose &, const TransformedLaserScan &, const GridMap &)
void set_lookup_ranges(double x, double y=0, double th=0)
std::vector< std::weak_ptr< GridScanMatcherObserver > > & observers()
std::vector< std::weak_ptr< GridScanMatcherObserver > > _observers
double estimate_scan_probability(const LaserScan2D &scan, const RobotPose &pose, const GridMap &map) const
void unsubscribe(std::shared_ptr< GridScanMatcherObserver > obs)
GridScanMatcher(SPE estimator, double max_x_error=0, double max_y_error=0, double max_th_error=0)
static bool is_prob_unknown(double probability)
LaserScan2D filter_scan(const LaserScan2D &scan, const RobotPose &pose, const GridMap &map)
double scan_probability(const LaserScan2D &scan, const RobotPose &pose, const GridMap &map, const SPEParams &p) const
void set_scan_probability_estimator(SPE spe)
void set_oope(OOPE occ_obs_prob_est)
double scan_probability(const LaserScan2D &scan, const RobotPose &pose, const GridMap &map) const
void do_for_each_observer(std::function< void(ObsPtr)> op)
virtual void reset_state()
SPE scan_probability_estimator() const


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