Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
grid_removal.cpp
Go to the documentation of this file.
2
3GridWallRemoval::GridWallRemoval(double angle, double radius, double start_augmentation,
4 double radius_augmentation, double fov, int max_points_per_cluster)
5 : grid_geometry_(angle, radius, start_augmentation, radius_augmentation, fov),
6 max_points_per_cluster_(max_points_per_cluster) {
7 occlusion_bins_.resize(static_cast<int>(std::ceil(fov / angle)));
8}
9
10void GridWallRemoval::remove_walls(const sensor_msgs::msg::PointCloud2::SharedPtr& point_cloud,
11 sensor_msgs::msg::PointCloud2::SharedPtr& output_cloud) {
12 // Initialize output cloud
13 output_cloud->header = point_cloud->header;
14 output_cloud->height = 1;
15 output_cloud->is_bigendian = point_cloud->is_bigendian;
16 output_cloud->point_step = point_cloud->point_step;
17 output_cloud->fields = point_cloud->fields;
18 output_cloud->width = 0;
19 output_cloud->data.resize(point_cloud->width * point_cloud->point_step);
20
21 std::fill(occlusion_bins_.begin(), occlusion_bins_.end(), std::numeric_limits<int>::max());
22
23 const auto& cloud_data = point_cloud->data;
24 const size_t num_points = point_cloud->width * point_cloud->height;
25 if (num_points == 0) {
26 return;
27 }
28
29 std::unordered_map<GridIndex, std::vector<size_t>> grid_map;
30
31 for (size_t i = 0; i < num_points; ++i) {
32 float x = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointX(i)]);
33 float y = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointY(i)]);
34
35 int slice = grid_geometry_.get_slice_index(x, y);
36 int bin_idx = grid_geometry_.get_bin_index(x, y);
37
38 if (slice >= 0 && slice < static_cast<int>(occlusion_bins_.size())) {
39 grid_map[{slice, bin_idx}].push_back(i);
40 }
41 }
42
43 std::unordered_map<GridIndex, bool> visited;
44 for (auto& [start_cell, points] : grid_map) {
45 if (visited[start_cell]) {
46 continue;
47 }
48
49 std::queue<GridIndex> q;
50 q.push(start_cell);
51 visited[start_cell] = true;
52
53 std::vector<GridIndex> cluster_cells;
54 size_t cluster_pts = 0;
55
56 while (!q.empty()) {
57 GridIndex current = q.front();
58 q.pop();
59 cluster_cells.push_back(current);
60 cluster_pts += grid_map[current].size();
61
62 for (int dx = -1; dx <= 1; ++dx) {
63 for (int dy = -1; dy <= 1; ++dy) {
64 if (dx == 0 && dy == 0) {
65 continue;
66 }
67
68 GridIndex neighbor{current.x + dx, current.y + dy};
69 if (grid_map.count(neighbor) > 0 && !visited[neighbor]) {
70 visited[neighbor] = true;
71 q.push(neighbor);
72 }
73 }
74 }
75 }
76
77 // Determine if the cluster has to much points to be a cone
78 if (static_cast<int>(cluster_pts) >= max_points_per_cluster_) {
79 for (const auto& cell : cluster_cells) {
80 // Save the front-most bin of the wall in each slice
81 if (cell.y < occlusion_bins_[cell.x]) {
82 occlusion_bins_[cell.x] = cell.y;
83 }
84 }
85 }
86 }
87
88 // Eliminate bins after the occlusion bin in each slice and store the remaining points in output
89 // cloud
90 for (auto const& [cell, points] : grid_map) {
91 if (cell.y < occlusion_bins_[cell.x]) {
92 for (size_t idx : points) {
93 size_t write_ptr = output_cloud->width * LidarPoint::POINT_STEP;
94 std::memcpy(&output_cloud->data[write_ptr], &cloud_data[idx * LidarPoint::POINT_STEP],
96 output_cloud->width++;
97 }
98 }
99 }
100
101 output_cloud->data.resize(output_cloud->width * LidarPoint::POINT_STEP);
102 output_cloud->row_step = output_cloud->width * LidarPoint::POINT_STEP;
103}
GridWallRemoval(double angle, double radius, double start_augmentation, double radius_augmentation, double fov, int max_points_per_cluster)
Constructor for GridWallRemoval.
GridGeometry grid_geometry_
void remove_walls(const sensor_msgs::msg::PointCloud2::SharedPtr &point_cloud, sensor_msgs::msg::PointCloud2::SharedPtr &output_cloud) override
Removes walls from the input point cloud using a grid-based approach.
std::vector< int > occlusion_bins_
constexpr size_t POINT_STEP
constexpr size_t PointX(size_t idx)
constexpr size_t PointY(size_t idx)
int get_bin_index(double x, double y) const
Compute bin index for a given (x, y)
int get_slice_index(double x, double y) const
Compute slice index for a given (x, y)
Structure to represent a grid index with x and y coordinates, needed for grid mapping.