Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
deskew.cpp
Go to the documentation of this file.
1#include "deskew/deskew.hpp"
2
3void Deskew::deskew_point_cloud(sensor_msgs::msg::PointCloud2::SharedPtr& input_cloud,
4 const common_lib::structures::Velocities& vehicle_velocity) const {
5 const size_t num_points = input_cloud->width * input_cloud->height;
6 if (num_points == 0) {
7 return;
8 }
9
10 constexpr double scan_duration = 0.1;
11 constexpr double one_over_two_pi = 1.0 / (2.0 * M_PI);
12
13 // Vehicle velocities
14 const Eigen::Vector3d linear_velocity(vehicle_velocity.velocity_x, vehicle_velocity.velocity_y,
15 0.0);
16
17 const double angular_velocity_z = static_cast<double>(vehicle_velocity.rotational_velocity);
18
19 auto& cloud = input_cloud->data;
20
21 // Reference point
22 double ref_x;
23 double ref_y;
24 double reference_azimuth = std::numeric_limits<double>::lowest();
25 for (size_t i = 0; i < num_points; ++i) {
26 ref_x = *reinterpret_cast<const float*>(&cloud[LidarPoint::PointX(i)]);
27 ref_y = *reinterpret_cast<const float*>(&cloud[LidarPoint::PointY(i)]);
28 double azimuth = -std::atan2(ref_y, ref_x);
29 if (azimuth > reference_azimuth) {
30 reference_azimuth = azimuth;
31 }
32 }
33
34 // Deskew each point
35 for (size_t i = 0; i < num_points; ++i) {
36 float x = *reinterpret_cast<const float*>(&cloud[LidarPoint::PointX(i)]);
37 float y = *reinterpret_cast<const float*>(&cloud[LidarPoint::PointY(i)]);
38 float z = *reinterpret_cast<const float*>(&cloud[LidarPoint::PointZ(i)]);
39
40 double azimuth = -std::atan2(y, x);
41
42 double delta_angle = reference_azimuth - azimuth;
43
44 double time_offset = delta_angle * one_over_two_pi * scan_duration;
45
46 Eigen::Vector3d original_point(x, y, z);
47 Eigen::Vector3d deskewed_point = original_point;
48
49 // Reverse rotation around Z
50 if (angular_velocity_z != 0.0) {
51 double theta = -angular_velocity_z * time_offset;
52 double cos_theta = std::cos(theta);
53 double sin_theta = std::sin(theta);
54
55 double x_rot = cos_theta * deskewed_point.x() - sin_theta * deskewed_point.y();
56 double y_rot = sin_theta * deskewed_point.x() + cos_theta * deskewed_point.y();
57
58 deskewed_point.x() = x_rot;
59 deskewed_point.y() = y_rot;
60 }
61
62 // Reverse translation
63 deskewed_point -= linear_velocity * time_offset;
64
65 // Write all 3 floats in one memcpy
66 float deskewed_xyz[3] = {static_cast<float>(deskewed_point.x()),
67 static_cast<float>(deskewed_point.y()),
68 static_cast<float>(deskewed_point.z())};
69
70 std::memcpy(&cloud[LidarPoint::PointX(i)], deskewed_xyz, sizeof(deskewed_xyz));
71 }
72}
void deskew_point_cloud(sensor_msgs::msg::PointCloud2::SharedPtr &input_cloud, const common_lib::structures::Velocities &vehicle_velocity) const
deskews the point cloud, i.e.
Definition deskew.cpp:3
constexpr size_t PointZ(size_t idx)
constexpr size_t PointX(size_t idx)
constexpr size_t PointY(size_t idx)