1 #ifndef SLAM_CTOR_CORE_WEIGHTED_MEAN_DISCREPANCY_SP_ESTIMATOR 2 #define SLAM_CTOR_CORE_WEIGHTED_MEAN_DISCREPANCY_SP_ESTIMATOR 6 #include "../math_utils.h" 7 #include "../maps/grid_rasterization.h" 8 #include "../features/angle_histogram.h" 15 using PointId = LaserScan2D::Points::size_type;
24 _common_weight = 1.0 / scan.
points().size();
28 return _common_weight;
39 auto v = _hist.value(pts,
id);
40 assert(v &&
"[BUG] AHR-SPW. Unknown point.");
50 const auto &sp = pts[id];
51 auto angle = sp.angle();
53 if (0.9 < std::abs(std::cos(
angle))) {
55 }
else if (0.8 < std::abs(std::cos(
angle))) {
58 return weight * std::sqrt(sp.range());
67 using SPW = std::shared_ptr<ScanPointWeighting>;
70 unsigned skip_rate = 0,
71 double max_usable_range = -1)
73 , _pts_skip_rate{skip_rate}, _pt_max_usable_range{max_usable_range} {}
81 auto &scan_pts = scan.
points();
82 const auto &raw_points = raw_scan.
points();
83 for (LaserScan2D::Points::size_type i = 0; i < raw_points.size(); ++i) {
84 if (_pts_skip_rate && i % _pts_skip_rate) {
continue; }
85 auto &sp = raw_points[i];
88 if (should_skip_point(sp, map, area_id)) {
continue; }
90 scan_pts.push_back(sp);
100 const SPEParams ¶ms)
const override {
101 auto total_weight =
double{0};
102 auto total_probability =
double{0};
104 auto observation = expected_scan_point_observation();
106 const auto &points = scan.
points();
107 for (LaserScan2D::Points::size_type i = 0; i < points.size(); ++i) {
108 auto &sp = points[i];
113 sp.move_origin(pose.
x, pose.
y) :
120 auto aoo_prob = occupancy_observation_probability(observation,
123 auto sp_weight = _spw->weight(points, i);
124 total_probability += aoo_prob * sp_weight * sp.factor();
125 total_weight += sp_weight;
127 if (total_weight == 0) {
129 std::clog <<
"WARNING: unknown probability" << std::endl;
130 return unknown_probability();
132 return total_probability / total_weight;
138 return {
true, {1.0, 1.0}, {0, 0}, 1.0};
LaserScan2D::Points::size_type PointId
double _pt_max_usable_range
double weight(const LaserScan2D::Points &, PointId) const override
Coord world_to_cell(const Point2D &pt) const
LaserScan2D filter_scan(const LaserScan2D &raw_scan, const RobotPose &pose, const GridMap &map) override
virtual bool has_cell(const Coord &c) const
LVRect move_center(const Point2D &new_center) const
WeightedMeanPointProbabilitySPE(OOPE oope, SPW spw, unsigned skip_rate=0, double max_usable_range=-1)
virtual ~ScanPointWeighting()
virtual void reset(const LaserScan2D &scan)
virtual AreaOccupancyObservation expected_scan_point_observation() const
std::shared_ptr< OccupancyObservationProbabilityEstimator > OOPE
std::shared_ptr< ScanPointWeighting > SPW
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
LightWeightRectangle sp_analysis_area
double weight(const LaserScan2D::Points &pts, PointId id) const override
double estimate_scan_probability(const LaserScan2D &scan, const RobotPose &pose, const GridMap &map, const SPEParams ¶ms) const override
void reset(const LaserScan2D &scan) override
double weight(const LaserScan2D::Points &pts, PointId id) const override
const Points & points() const
virtual double weight(const LaserScan2D::Points &, PointId) const =0
std::shared_ptr< TrigonometryProvider > trig_provider
virtual bool should_skip_point(const ScanPoint2D &sp, const GridMap &map, const GridMap::Coord &area_id) const
std::vector< ScanPoint2D > Points
void reset(const LaserScan2D &scan) override
bool are_strictly_ordered(double a, double b, double c)