Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
midpoint_generator.cpp
Go to the documentation of this file.
2
3std::vector<std::shared_ptr<Midpoint>>& MidpointGenerator::generate_midpoints(
4 const std::vector<Cone>& cone_array, bool rebuild_all_midpoints) {
5 DT dt;
6
7 std::vector<std::shared_ptr<Cone>> filtered_cones;
8 filtered_cones.reserve(cone_array.size());
9
10 filter_cones(cone_array, filtered_cones, rebuild_all_midpoints);
11
12 midpoints_.clear();
13 midpoints_.reserve(3 * filtered_cones.size());
14 triangulations_.clear();
15 triangulations_.reserve(3 * filtered_cones.size());
16
17 // Insert all cone positions into the Delaunay triangulation
18 for (const auto& cone : filtered_cones) {
19 (void)dt.insert(Point(cone->position.x, cone->position.y));
20 }
21
22 // Avoid duplicate midpoints for the same cone pair
23 std::map<std::pair<int, int>, std::shared_ptr<Midpoint>> segment_to_midpoint;
24
25 for (auto triangle_it = dt.finite_faces_begin(); triangle_it != dt.finite_faces_end();
26 ++triangle_it) {
27 std::array<std::shared_ptr<Midpoint>, 3> triangle_midpoints;
28
29 // Iterate over the 3 edges of the triangle
30 for (int i = 0; i < 3; ++i) {
31 Vertex_handle va = triangle_it->vertex((i + 1) % 3);
32 Vertex_handle vb = triangle_it->vertex((i + 2) % 3);
33
34 triangle_midpoints[i] = process_triangle_edge(va, vb, filtered_cones, segment_to_midpoint);
35 }
36
37 // Connect midpoints if they share the same triangle
38 connect_triangle_midpoints(triangle_midpoints);
39 }
40
41 return midpoints_;
42}
43
44void MidpointGenerator::filter_cones(const std::vector<Cone>& cone_array,
45 std::vector<std::shared_ptr<Cone>>& filtered_cones,
46 bool rebuild_all_midpoints) {
47 if (!rebuild_all_midpoints) {
48 for (const auto& cone : cone_array) {
49 double dx = cone.position.x - vehicle_pose_.position.x;
50 double dy = cone.position.y - vehicle_pose_.position.y;
51
53
54 if (dx * dx + dy * dy <= sq_window_radius) {
55 filtered_cones.push_back(std::make_shared<Cone>(cone));
56 }
57 }
58 } else {
59 for (const auto& cone : cone_array) {
60 filtered_cones.push_back(std::make_shared<Cone>(cone));
61 }
62 }
63
64 if (filtered_cones.size() < 2) {
65 RCLCPP_WARN(rclcpp::get_logger("planning"), "[Planning] Not enough cones to compute midpoints");
66 }
67}
68
70 const Vertex_handle& va, const Vertex_handle& vb,
71 std::vector<std::shared_ptr<Cone>>& filtered_cones,
72 std::map<std::pair<int, int>, std::shared_ptr<Midpoint>>& segment_to_midpoint) {
73 Point p1 = va->point();
74 Point p2 = vb->point();
75
76 // Find corresponding cone IDs
77 int id1 = find_cone(filtered_cones, p1.x(), p1.y());
78 int id2 = find_cone(filtered_cones, p2.x(), p2.y());
79
80 if (id1 == -1 || id2 == -1) {
81 return nullptr;
82 }
83
84 // Check distance constraints
85 if (double squared_distance = CGAL::squared_distance(p1, p2);
88 return nullptr;
89 }
90
91 // Use ordered cone IDs to uniquely identify the segment
92 auto key = std::minmax(id1, id2);
93
94 // Check if this segment was already processed. If so, return existing midpoint
95 if (auto it = segment_to_midpoint.find(key); it != segment_to_midpoint.end()) {
96 return it->second;
97 }
98
99 // Create new midpoint
100 auto midpoint =
101 std::make_shared<Midpoint>(CGAL::midpoint(p1, p2), filtered_cones[id1], filtered_cones[id2]);
102
103 segment_to_midpoint[key] = midpoint;
104 midpoints_.push_back(midpoint);
105 triangulations_.push_back({p1, p2});
106
107 return midpoint;
108}
109
111 const std::array<std::shared_ptr<Midpoint>, 3>& triangle_midpoints) {
112 for (int i = 0; i < 3; ++i) {
113 if (!triangle_midpoints[i]) {
114 continue;
115 }
116 for (int j = 0; j < 3; ++j) {
117 if (i == j || !triangle_midpoints[j]) {
118 continue;
119 }
120 triangle_midpoints[i]->close_points.push_back(triangle_midpoints[j]);
121 }
122 }
123}
124
125const std::vector<std::pair<Point, Point>>& MidpointGenerator::get_triangulations() const {
126 return triangulations_;
127}
128
129void MidpointGenerator::set_vehicle_pose(const Pose& vehicle_pose) {
130 vehicle_pose_ = vehicle_pose;
131}
132
133int MidpointGenerator::find_cone(std::vector<std::shared_ptr<Cone>>& cones, double x, double y) {
134 for (int i = 0; i < static_cast<int>(cones.size()); i++) {
135 if (cones[i]->position.x == x && cones[i]->position.y == y) {
136 return i;
137 }
138 }
139 return -1;
140}
int find_cone(std::vector< std::shared_ptr< Cone > > &cones, double x, double y)
Finds a cone in a vector based on its position coordinates.
void connect_triangle_midpoints(const std::array< std::shared_ptr< Midpoint >, 3 > &triangle_midpoints)
Connects midpoints that belong to the same Delaunay triangle.
void filter_cones(const std::vector< Cone > &cone_array, std::vector< std::shared_ptr< Cone > > &filtered_cones, bool rebuild_all_midpoints)
Filters input cones based on proximity to the vehicle pose.
std::shared_ptr< Midpoint > process_triangle_edge(const Vertex_handle &va, const Vertex_handle &vb, std::vector< std::shared_ptr< Cone > > &filtered_cones, std::map< std::pair< int, int >, std::shared_ptr< Midpoint > > &segment_to_midpoint)
Processes a single edge of a Delaunay triangle and creates its midpoint if valid.
void set_vehicle_pose(const Pose &vehicle_pose)
Updates the vehicle pose for dynamic filtering.
MidpointGeneratorConfig config_
std::vector< std::shared_ptr< Midpoint > > & generate_midpoints(const std::vector< Cone > &cone_array, bool rebuild_all_midpoints)
Generates midpoints from a set of cones.
std::vector< std::pair< Point, Point > > triangulations_
std::vector< std::shared_ptr< Midpoint > > midpoints_
const std::vector< std::pair< Point, Point > > & get_triangulations() const
Returns the current set of Delaunay edges used for visualization.
K::Point_2 Point
CGAL::Delaunay_triangulation_2< K > DT
DT::Vertex_handle Vertex_handle
double maximum_cone_distance_
Maximum distance between cones.
double sliding_window_radius_
Sliding window radius for midpoint generation.
double minimum_cone_distance_
Minimum distance between cones.
Struct for pose representation.
Definition pose.hpp:13