laser_scan_generator.h
Go to the documentation of this file.
1 #ifndef SLAM_CTOR_UTILS_DG_LASER_SCAN_GENERATOR_H
2 #define SLAM_CTOR_UTILS_DG_LASER_SCAN_GENERATOR_H
3 
4 #include <memory>
5 #include <cmath>
6 
7 #include "../../core/math_utils.h"
8 #include "../../core/maps/grid_map.h"
9 #include "../../core/states/sensor_data.h"
10 #include "../../core/geometry_utils.h"
11 
13  constexpr LaserScannerParams(double mx_dist, double h_a_inc,
14  double h_half_sector)
15  : max_dist{mx_dist}, h_angle_inc{h_a_inc}, h_hsector{h_half_sector} {}
16  constexpr LaserScannerParams()
17  : LaserScannerParams{15, deg2rad(90), deg2rad(180)} {}
18 
19  const double max_dist; // meters
20  // "h" is for "horizontal"
21  const double h_angle_inc; // radians
22  const double h_hsector; // half of horizontal sector (FoW), radians
23 };
24 
25 // TODO: give proper name
26 constexpr static auto to_lsp(double max_dist, double fow_deg, unsigned pts_nm) {
28  deg2rad(fow_deg / pts_nm), deg2rad(fow_deg / 2.0)};
29 }
30 
32 public:
33  LaserScanGenerator(LaserScannerParams ls_params = {}) : _lsp{ls_params} {}
34 
35  LaserScan2D laser_scan_2D(const GridMap& map, const RobotPose& pose,
36  double occ_threshold = 1) {
37 
38  LaserScan2D scan;
39  scan.trig_provider = std::make_shared<RawTrigonometryProvider>();
40  auto robot_point = pose.point();
41  auto robot_coord = map.world_to_cell(robot_point);
42  assert(!are_equal(robot_point.x, robot_coord.x * map.scale()) &&
43  !are_equal(robot_point.y, robot_coord.y * map.scale()) &&
44  "LS Gen: robot at cell boundary is not supported");
45 
46  auto hhsector = _lsp.h_hsector; // horiz. half-sector
47  for (double a = -hhsector; a <= hhsector; a += _lsp.h_angle_inc) {
48  if (2*M_PI <= hhsector + a) { break; }
49  auto beam_dir = Point2D{_lsp.max_dist * std::cos(a + pose.theta),
50  _lsp.max_dist * std::sin(a + pose.theta)};
51  auto area_ids = map.world_to_cells({robot_point, robot_point + beam_dir});
52  for (auto& area_id : area_ids) {
53  if (map[area_id] < occ_threshold) { continue; }
54  // NB: Beam-goes-through-the-cell-center assumption is not safe,
55  // so use more sophisticated analysis based on intersections.
56  auto ray = Ray{robot_point.x, beam_dir.x, robot_point.y, beam_dir.y};
57  auto inters = map.world_cell_bounds(area_id).find_intersections(ray);
58  if (inters.size() == 1) { // Assume beam touches the cell.
59  // NB: Ignores "pierce" case for simplicity,
60  // increase max_dist in this case.
61  continue;
62  }
63 
64  assert(2 == inters.size() && "BUG! LS Gen: obstacle is not pierced");
65  auto obst_pnt = Point2D{(inters[0].x + inters[1].x) / 2,
66  (inters[0].y + inters[1].y) / 2};
67  auto range = std::sqrt(robot_point.dist_sq(obst_pnt));
68  auto scan_point = ScanPoint2D::make_polar(range, a, true);
69  scan.points().push_back(scan_point);
70 
71  auto added_wp = scan_point.move_origin(pose.x, pose.y, pose.theta);
72  auto sp_area_id = map.world_to_cell(added_wp);
73  assert(area_id == sp_area_id &&
74  "[BUG] Estimated scan point doesn't lie is expected area");
75  //std::cout << "==> Add point " << range << " " << a << std::endl;
76  break;
77  }
78  }
79  return scan;
80  }
81 
82 private:
84 };
85 
86 #endif
static ScanPoint2D make_polar(double range, double angle, bool is_occ)
Definition: sensor_data.h:19
static constexpr auto to_lsp(double max_dist, double fow_deg, unsigned pts_nm)
constexpr LaserScannerParams()
LaserScanGenerator(LaserScannerParams ls_params={})
Coord world_to_cell(const Point2D &pt) const
Rectangle world_cell_bounds(const Coord &coord) const
CONSTEXPR bool are_equal(const T &a, const T &b, const T &eps)
Definition: math_utils.h:17
double theta
Definition: robot_pose.h:131
TFSIMD_FORCE_INLINE const tfScalar & y() const
constexpr LaserScannerParams(double mx_dist, double h_a_inc, double h_half_sector)
LaserScannerParams _lsp
Intersections find_intersections(const Segment2D &s) const
const Points & points() const
Definition: sensor_data.h:148
std::vector< Coord > world_to_cells(const Segment2D &s) const
LaserScan2D laser_scan_2D(const GridMap &map, const RobotPose &pose, double occ_threshold=1)
std::shared_ptr< TrigonometryProvider > trig_provider
Definition: sensor_data.h:171
double y
Definition: robot_pose.h:131
constexpr double deg2rad(double angle_deg)
Definition: math_utils.h:56
auto point() const
Definition: robot_pose.h:129
double x
Definition: robot_pose.h:131
virtual double scale() const


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