monte_carlo_scan_matcher.h
Go to the documentation of this file.
00001 
00011 #ifndef __MONTE_CARLO_SCAN_MATCHER_H
00012 #define __MONTE_CARLO_SCAN_MATCHER_H
00013 
00014 #include <functional>
00015 #include <limits>
00016 #include <memory>
00017 
00018 #include "state_data.h"
00019 #include "sensor_data.h"
00020 #include "grid_scan_matcher.h"
00021 
00022 // TODO: move publish transform to observer
00023 
00030 class MonteCarloScanMatcher : public GridScanMatcher {
00031 public:
00032   using ObsPtr = std::shared_ptr<GridScanMatcherObserver>;
00033 public:
00034 
00042   MonteCarloScanMatcher(std::shared_ptr<ScanCostEstimator> estimator,
00043                         unsigned failed_iter, unsigned max_iter):
00044     GridScanMatcher{estimator},
00045     _failed_tries_limit(failed_iter), _total_tries_limit(max_iter) {}
00046 
00056   virtual double process_scan(const RobotState &init_pose,
00057                       const TransformedLaserScan &scan,
00058                       const GridMap &map,
00059                       RobotState &pose_delta) override {
00060     do_for_each_observer([init_pose, scan, map](ObsPtr obs) {
00061       obs->on_matching_start(init_pose, scan, map);
00062     });
00063 
00064     unsigned failed_tries = 0, total_tries = 0;
00065     std::shared_ptr<ScanCostEstimator> sce = GridScanMatcher::cost_estimator();
00066     double min_scan_cost = std::numeric_limits<double>::max();
00067     RobotState optimal_pose = init_pose;
00068 
00069     min_scan_cost = sce->estimate_scan_cost(optimal_pose, scan,
00070                                             map, min_scan_cost);
00071 
00072     do_for_each_observer([optimal_pose, scan, min_scan_cost](ObsPtr obs) {
00073       obs->on_scan_test(optimal_pose, scan, min_scan_cost);
00074       obs->on_pose_update(optimal_pose, scan, min_scan_cost);
00075     });
00076 
00077     while (failed_tries < _failed_tries_limit &&
00078            total_tries < _total_tries_limit) {
00079       total_tries++;
00080 
00081       RobotState sampled_pose = optimal_pose;
00082       sample_pose(sampled_pose);
00083       double sampled_scan_cost = sce->estimate_scan_cost(sampled_pose, scan,
00084                                                          map, min_scan_cost);
00085       do_for_each_observer([sampled_pose, scan, sampled_scan_cost](ObsPtr obs) {
00086         obs->on_scan_test(sampled_pose, scan, sampled_scan_cost);
00087       });
00088 
00089       if (min_scan_cost <= sampled_scan_cost) {
00090         failed_tries++;
00091         continue;
00092       }
00093 
00094       min_scan_cost = sampled_scan_cost;
00095       optimal_pose = sampled_pose;
00096       failed_tries = on_estimate_update(failed_tries, _failed_tries_limit);
00097 
00098       do_for_each_observer([optimal_pose, scan, min_scan_cost](ObsPtr obs) {
00099         obs->on_pose_update(optimal_pose, scan, min_scan_cost);
00100       });
00101     }
00102 
00103     pose_delta.x = optimal_pose.x - init_pose.x;
00104     pose_delta.y = optimal_pose.y - init_pose.y;
00105     pose_delta.theta = optimal_pose.theta - init_pose.theta;
00106 
00107     do_for_each_observer([pose_delta, min_scan_cost](ObsPtr obs) {
00108         obs->on_matching_end(pose_delta, min_scan_cost);
00109     });
00110     return min_scan_cost;
00111   }
00112 
00113 protected:
00118   virtual void sample_pose(RobotState &base_pose) = 0;
00119 
00125   virtual unsigned on_estimate_update(unsigned sample_num,
00126                                       unsigned sample_limit) = 0;
00127 
00128 private:
00129   void do_for_each_observer(std::function<void(ObsPtr)> op) {
00130     for (auto &obs : GridScanMatcher::observers()) {
00131       if (auto obs_ptr = obs.lock()) {
00132         op(obs_ptr);
00133       }
00134     }
00135   }
00136 
00137 private:
00138   unsigned _failed_tries_limit;
00139   unsigned _total_tries_limit;
00140 };
00141 
00142 #endif


tiny_slam
Author(s):
autogenerated on Mon Jul 17 2017 02:33:42