Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
circunference_center_calculation.cpp
Go to the documentation of this file.
2
4 const sensor_msgs::msg::PointCloud2::SharedPtr& point_cloud,
5 const std::vector<int>& point_indices, const Plane& plane) const {
6 Eigen::Vector4f centroid;
7
8 // Get the centroid cone of the point_cloud;
9 double sum_x = 0.0;
10 double sum_y = 0.0;
11 double sum_z = 0.0;
12
13 const auto& cloud_data = point_cloud->data;
14
15 for (int idx : point_indices) {
16 float x = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointX(idx)]);
17 float y = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointY(idx)]);
18 float z = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointZ(idx)]);
19
20 sum_x += x;
21 sum_y += y;
22 sum_z += z;
23 }
24
25 size_t n = point_indices.size();
26 centroid << sum_x / n, sum_y / n, sum_z / n, 1.0f;
27
28 // Get the parallel plane that passes through that point
29 double d = -(plane.get_a() * centroid.x() + plane.get_b() * centroid.y() +
30 plane.get_c() * centroid.z()); // d component of the plane
31
32 Plane middle_plane(plane.get_a(), plane.get_b(), plane.get_c(), d);
33
34 // Gets the 3 closest points to that plane
35 std::vector<Eigen::Vector3f> closest_points(3, Eigen::Vector3f::Zero());
36 std::vector<double> distances(3, std::numeric_limits<double>::max());
37
38 for (int idx : point_indices) {
39 float x = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointX(idx)]);
40 float y = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointY(idx)]);
41 float z = *reinterpret_cast<const float*>(&cloud_data[LidarPoint::PointZ(idx)]);
42
43 Eigen::Vector3f point(x, y, z);
44 double distance = middle_plane.get_distance_to_point(x, y, z);
45
46 // Update distances/closest point -> Do the vector shifting and place the right points on the
47 // vector
48 for (int i = 0; i < 3; ++i) {
49 if (distance < distances[i]) {
50 for (int j = 2; j > i; --j) {
51 closest_points[j] = closest_points[j - 1];
52 distances[j] = distances[j - 1];
53 }
54 closest_points[i] = point;
55 distances[i] = distance;
56 break;
57 }
58 }
59 }
60
61 // Calculates the center of the circumference that passes on those 3 points
62 // Source: https://codeforces.com/blog/entry/17313
63 Eigen::Vector4f center;
64
65 double x1 = closest_points[0].x();
66 double y1 = closest_points[0].y();
67 double x2 = closest_points[1].x();
68 double y2 = closest_points[1].y();
69 double x3 = closest_points[2].x();
70 double y3 = closest_points[2].y();
71
72 double D = 2 * (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2));
73 center.x() = ((x1 * x1 + y1 * y1) * (y2 - y3) + (x2 * x2 + y2 * y2) * (y3 - y1) +
74 (x3 * x3 + y3 * y3) * (y1 - y2)) /
75 D;
76 center.y() = ((x1 * x1 + y1 * y1) * (x3 - x2) + (x2 * x2 + y2 * y2) * (x1 - x3) +
77 (x3 * x3 + y3 * y3) * (x2 - x1)) /
78 D;
79 center.z() = centroid.z();
80
81 return center;
82}
Eigen::Vector4f calculate_center(const sensor_msgs::msg::PointCloud2::SharedPtr &point_cloud, const std::vector< int > &point_indices, const Plane &plane=Plane()) const override
Estimates the center position of a cone using a circumference-based approach.
The Plane class represents a 3D plane defined by its equation ax + by + cz + d = 0.
Definition plane.hpp:12
double get_b() const
Getter - Get the b component of the plane.
Definition plane.cpp:9
double get_a() const
Getter - Get the a component of the plane.
Definition plane.cpp:7
double get_c() const
Getter - Get the c component of the plane.
Definition plane.cpp:11
double get_distance_to_point(float x, float y, float z) const
Calculates the distance from a point to the plane.
Definition plane.cpp:15
constexpr size_t PointZ(size_t idx)
constexpr size_t PointX(size_t idx)
constexpr size_t PointY(size_t idx)