9 sensor_msgs::msg::PointCloud2::SharedPtr& ground_removed_cloud,
11 const auto& cloud_data = trimmed_point_cloud->data;
12 const size_t num_points = trimmed_point_cloud->width * trimmed_point_cloud->height;
17 ground_removed_cloud->header = trimmed_point_cloud->header;
18 ground_removed_cloud->height = 1;
19 ground_removed_cloud->is_bigendian = trimmed_point_cloud->is_bigendian;
20 ground_removed_cloud->is_dense =
true;
21 ground_removed_cloud->fields = trimmed_point_cloud->fields;
22 ground_removed_cloud->point_step = trimmed_point_cloud->point_step;
23 ground_removed_cloud->width = 0;
24 ground_removed_cloud->data.resize(num_points * trimmed_point_cloud->point_step);
26 std::mt19937 rng(std::random_device{}());
27 std::uniform_int_distribution<size_t> dist(0, num_points - 1);
29 double best_a = 0, best_b = 0, best_c = 0, best_d = 0;
30 size_t best_inliers = 0;
32 for (
int i = 0; i <
n_tries; ++i) {
34 size_t idx1 = dist(rng), idx2 = dist(rng), idx3 = dist(rng);
35 if (idx1 == idx2 || idx1 == idx3 || idx2 == idx3) {
40 Eigen::Vector3f p1 = *
reinterpret_cast<const Eigen::Vector3f*
>(&cloud_data[
LidarPoint::PointX(idx1)]);
41 Eigen::Vector3f p2 = *
reinterpret_cast<const Eigen::Vector3f*
>(&cloud_data[
LidarPoint::PointX(idx2)]);
42 Eigen::Vector3f p3 = *
reinterpret_cast<const Eigen::Vector3f*
>(&cloud_data[
LidarPoint::PointX(idx3)]);
44 Eigen::Vector3f v1 = p2 - p1;
45 Eigen::Vector3f v2 = p3 - p1;
46 Eigen::Vector3f n = v1.cross(v2);
48 if (n.norm() < 1e-6) {
52 double a = n.x(), b = n.y(), c = n.z();
53 double d = -n.dot(p1);
56 for (
size_t j = 0; j < num_points; ++j) {
60 double dist = std::abs(a * x + b * y + c * z + d);
66 if (inliers > best_inliers) {
67 best_inliers = inliers;
76 for (
size_t i = 0; i < num_points; ++i) {
80 double dist = std::abs(best_a * x + best_b * y + best_c * z + best_d);
86 size_t write_idx = ground_removed_cloud->width++;
87 std::memcpy(&ground_removed_cloud->data[write_idx * trimmed_point_cloud->point_step],
88 &cloud_data[i * trimmed_point_cloud->point_step],
89 trimmed_point_cloud->point_step);
93 ground_removed_cloud->data.resize(ground_removed_cloud->width * trimmed_point_cloud->point_step);
94 ground_removed_cloud->row_step = ground_removed_cloud->width * trimmed_point_cloud->point_step;
void ground_removal(const sensor_msgs::msg::PointCloud2::SharedPtr &trimmed_point_cloud, sensor_msgs::msg::PointCloud2::SharedPtr &ground_removed_point_cloud, GroundGrid &ground_grid) const override
Perform ground removal using the RANSAC algorithm.