connect_the_dots_ambiguous_drift_detector.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_CORE_CONNECT_THE_DOTS_AMBIOUS_DRIFT_DETECTOR_H
2 #define SLAM_CTOR_CORE_CONNECT_THE_DOTS_AMBIOUS_DRIFT_DETECTOR_H
3 
4 #include "grid_scan_matcher.h"
5 #include "pose_enumerators.h"
6 #include "../features/angle_histogram.h"
7 
8 // TODO: do we need it to be a scan matcher?
9 // TEMP: implemented as a 'decorator' to be in sync with fmwk
11 public:
12  ConnectTheDotsAmbiguousDriftDetector(std::shared_ptr<GridScanMatcher> sm)
14 
15  // GridScanMatcher API implementation
16 
17  void reset_state() override {
18  _sm->reset_state();
19  }
20 
21  double process_scan(const TransformedLaserScan &raw_scan,
22  const RobotPose &init_pose,
23  const GridMap &map,
24  RobotPoseDelta &pose_delta) override {
25  // Estimate best pose delta with wrapped sm
26  auto sm_best_prob = _sm->process_scan(raw_scan, init_pose, map, pose_delta);
27  auto best_pose = init_pose + pose_delta;
28 
29  // Remove points with most popular antigradient
30  auto scan = filter_scan(raw_scan.scan, init_pose, map);
31  auto angle_histogram = AngleHistogram{20}.reset(scan);
32  auto drift_dir_i = angle_histogram.max_i();
33  auto drift_dir = angle_histogram[drift_dir_i];
34  std::cout << drift_dir * 1.0 / scan.points().size() << std::endl;
35  if (drift_dir < 0.4 * scan.points().size()) {
36  return sm_best_prob;
37  }
38  std::cout << "ANALYSIS: " << drift_dir * 1.0 / scan.points().size() << std::endl;
39  // TODO: max is close to avg => ok
40 
41  // TODO: move filtering to AngleHistogram
42  LaserScan2D filtered_scan;
43  filtered_scan.trig_provider = scan.trig_provider;
44  auto &scan_pts = filtered_scan.points();
45  for (LaserScan2D::Points::size_type i = 1; i < scan.points().size(); ++i) {
46  auto &sp = scan.points()[i];
47  // TODO: rm by ah index range
48  if (drift_dir == angle_histogram.value(scan.points(), i)) {
49  continue;
50  }
51  scan_pts.push_back(sp);
52  }
53 
54  // Matching agaists filtered scan; BruteForce; move polar
55  auto probs = std::vector<double>{};
56 
57  auto hist_step = angle_histogram.angle_step();
58  // FIXME: a hack to exclude base_pose
59 
60  auto ang = drift_dir_i * hist_step + hist_step / 2;
62  //drift_dir_i * hist_step, (drift_dir_i + 1) * hist_step, hist_step / 2,
63  ang, ang, hist_step,
64  -0.25, 0.25, 0.1 /* Q: map scale? */
65  };
66 
67  // TODO: Refactoring. Replace with BF sm + observer to log probs
68  auto best_prob = scan_probability(filtered_scan, best_pose, map);
69  while (poses.has_next()) {
70  auto next_pose = poses.next(best_pose);
71  auto next_prob = scan_probability(filtered_scan, next_pose, map);
72  probs.push_back(next_prob);
73  auto next_pose_is_better = best_prob < next_prob;
74  if (next_pose_is_better) {
75  best_prob = next_prob;
76  best_pose = next_pose;
77  std::cout << "2ND Pass Update: " << best_prob << " --> "
78  << best_pose << std::endl;
79  }
80  poses.feedback(next_pose_is_better);
81  }
82 
83  if (1 < probs.size()) {
84  std::sort(probs.begin(), probs.end(), std::greater<double>{});
85  if (are_equal(probs[0], probs[1], 1e-6)) { // or both are shero
86  std::cout << "ALARM: " << probs[0] << " == " << probs[1] << std::endl;
87  }
88  }
89 
90  pose_delta = best_pose - init_pose;
91  auto corrected_best_prob = scan_probability(scan, best_pose, map);
92  if (corrected_best_prob < sm_best_prob) {
93  std::cout << "[CtD][Bug] " << corrected_best_prob << " "
94  << sm_best_prob << std::endl;
95  }
96  return corrected_best_prob;
97  }
98 
99 private:
100  std::shared_ptr<GridScanMatcher> _sm;
101 };
102 
103 
104 #endif
CONSTEXPR bool are_equal(const T &a, const T &b, const T &eps)
Definition: math_utils.h:17
ConnectTheDotsAmbiguousDriftDetector(std::shared_ptr< GridScanMatcher > sm)
double process_scan(const TransformedLaserScan &raw_scan, const RobotPose &init_pose, const GridMap &map, RobotPoseDelta &pose_delta) override
const Points & points() const
Definition: sensor_data.h:148
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
std::shared_ptr< TrigonometryProvider > trig_provider
Definition: sensor_data.h:171
SPE scan_probability_estimator() const
auto reset(const LaserScan2D &scan)


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