Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
path_calculation.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cmath>
5#include <map>
6#include <queue>
7#include <set>
8#include <utility>
9#include <vector>
10
11// ===================== Path Calculation (Core) =====================
12
13std::vector<PathPoint> PathCalculation::calculate_path(const std::vector<Cone>& cone_array) {
14 if (cone_array.size() < 4) {
15 RCLCPP_ERROR(rclcpp::get_logger("planning"), "Not enough cones to create a path.");
16 return {};
17 }
18
20
21 // Determine if we should regenerate all midpoints (path reset)
23 bool rebuild_all_midpoints = should_reset || !config_.use_sliding_window_;
24
25 // Generate midpoints using the generator
26 midpoints_ = midpoint_generator_.generate_midpoints(cone_array, rebuild_all_midpoints);
27
28 visited_midpoints_.reserve(midpoints_.size());
29 // Map for quick access from Point to corresponding Midpoint
30 point_to_midpoint_.reserve(midpoints_.size());
31 for (const auto& mp : midpoints_) {
32 point_to_midpoint_[mp->point] = mp;
33 }
34
36
37 // Find the point in the past_path_ closest to the car
38 int cutoff_index = -1;
39 double min_dist = std::numeric_limits<double>::max();
40 for (size_t i = 0; i < past_path_.size(); ++i) {
41 double dist = CGAL::squared_distance(past_path_[i].point, car_point);
42 if (dist < min_dist) {
43 min_dist = dist;
44 cutoff_index = static_cast<int>(i);
45 }
46 }
47
48 if (cutoff_index == -1) {
49 RCLCPP_WARN(rclcpp::get_logger("planning"), "No valid path points found near the car.");
50 }
51
52 path_to_car_.reserve(past_path_.size());
53 // Retain part of the existing path leading to the car
54 if (cutoff_index != -1 && cutoff_index > config_.lookback_points_) {
55 (void)path_to_car_.insert(path_to_car_.end(), past_path_.begin(),
56 past_path_.begin() + cutoff_index - config_.lookback_points_);
57 }
58
59 int max_points = reset_path(should_reset);
60
61 // Build initial path segment
62 if (path_to_car_.size() <= 2) {
64 } else {
66 }
67
68 extend_path(max_points);
69
70 yellow_cones_.reserve(current_path_.size());
71 blue_cones_.reserve(current_path_.size());
72
74
75 past_path_ = current_path_; // Update the path for next iteration
76
78}
79
80bool PathCalculation::is_map_closed(std::vector<PathPoint>& path) const {
81 if (path.size() < 3) {
82 return false;
83 }
84
85 auto [best_cutoff_index, combined_cost] = find_best_loop_closure(path);
86
87 if (combined_cost < config_.close_cost_) {
88 if (best_cutoff_index + 1 < static_cast<int>(path.size())) {
89 (void)path.erase(path.begin() + best_cutoff_index + 1, path.end());
90 }
91 path.push_back(path[0]);
92
93 RCLCPP_DEBUG(rclcpp::get_logger("planning"), "Loop closure cost: %.4f (threshold: %.4f)",
94 combined_cost, config_.close_cost_);
95 return true;
96 }
97
98 return false;
99}
100
101std::vector<PathPoint> PathCalculation::calculate_trackdrive(const std::vector<Cone>& cone_array) {
103 std::vector<PathPoint> result = calculate_path(cone_array);
104
105 // Check if we have enough points to form a loop
106 if (result.size() < 3) {
107 RCLCPP_WARN(rclcpp::get_logger("planning"), "Not enough points to create trackdrive loop");
108 return result;
109 }
110
111 // Find the best point to close the loop
112 auto [best_cutoff_index, _] = find_best_loop_closure(result);
113
114 if (result.begin() + best_cutoff_index + 1 != result.end()) {
115 // Trim the path to the best cutoff point
116 (void)result.erase(result.begin() + best_cutoff_index + 1, result.end());
117 // If the path change we need to estimate the boundaries again
118 RCLCPP_WARN(rclcpp::get_logger("planning"), "The path change to create trackdrive loop");
119 yellow_cones_.clear();
120 blue_cones_.clear();
121 (void)current_path_.erase(current_path_.begin() + best_cutoff_index + 1, current_path_.end());
123 }
124
125 // Close the loop by adding the first point again
126 result.push_back(result[0]);
127 yellow_cones_.push_back(yellow_cones_[0]);
128 blue_cones_.push_back(blue_cones_[0]);
129
130 return result;
131}
132
133// ===================== State Management =====================
134
136 current_path_.clear();
137 path_to_car_.clear();
138 point_to_midpoint_.clear();
139 visited_midpoints_.clear();
140 discarded_cones_.clear();
141 yellow_cones_.clear();
142 blue_cones_.clear();
143}
144
145int PathCalculation::reset_path(bool should_reset) {
146 int max_points = config_.max_points_;
148
149 if (should_reset) {
150 max_points = static_cast<int>(path_to_car_.size()) + config_.max_points_;
151 path_to_car_.clear();
152 past_path_.clear();
154 RCLCPP_INFO(rclcpp::get_logger("planning"), "Global path reset");
155 }
156
157 return max_points;
158}
159
162 vehicle_pose_ = vehicle_pose;
163}
164
165// ===================== Path Initialization =====================
166
168 if (!initial_pose_set_) {
170 initial_pose_set_ = true;
171 }
172
173 const auto [first_midpoint, second_midpoint] = select_starting_midpoints();
174
175 if (first_midpoint && second_midpoint) {
176 Colorpoint first_colorpoint =
177 Colorpoint(first_midpoint->point, *first_midpoint->cone1, *first_midpoint->cone2);
178 Colorpoint second_colorpoint =
179 Colorpoint(second_midpoint->point, *second_midpoint->cone1, *second_midpoint->cone2);
180 current_path_.push_back(first_colorpoint);
181 current_path_.push_back(second_colorpoint);
182 (void)visited_midpoints_.insert(first_midpoint);
183 (void)visited_midpoints_.insert(second_midpoint);
184 } else {
185 RCLCPP_ERROR(rclcpp::get_logger("planning"), "Failed to find valid starting points.");
186 }
187}
188
190 RCLCPP_DEBUG(rclcpp::get_logger("planning"), "Selecting initial path from %zu points.",
191 path_to_car_.size());
192
193 current_path_.reserve(path_to_car_.size());
194
195 Point last_added_point;
196 bool first_point_added = false;
197
198 for (const Colorpoint& path_to_car_colorpoint : path_to_car_) {
199 // By default, use the original point
200 Colorpoint candidate_colorpoint = path_to_car_colorpoint;
201
202 // Snap to nearest valid midpoint
203 std::shared_ptr<Midpoint> candidate_midpoint =
204 find_nearest_midpoint(path_to_car_colorpoint.point);
205
206 // If found a valid midpoint, use it
207 if (candidate_midpoint) {
208 candidate_colorpoint = Colorpoint(candidate_midpoint->point, *candidate_midpoint->cone1,
209 *candidate_midpoint->cone2);
210 }
211
212 // Check if already visited
213 if (candidate_midpoint && visited_midpoints_.count(candidate_midpoint) > 0) {
214 RCLCPP_DEBUG(rclcpp::get_logger("planning"), "Skipping point: Already visited.");
215 continue;
216 }
217
218 // For non-first points, check distance from last added point
219 if (first_point_added) {
220 double distance =
221 std::sqrt(CGAL::squared_distance(last_added_point, candidate_colorpoint.point));
222 if (distance <= config_.minimum_point_distance_) {
223 RCLCPP_DEBUG(rclcpp::get_logger("planning"),
224 "Skipping point: Too close to last added point.");
225 continue;
226 }
227 }
228
229 // If the candidate_midpoint is valid, add it to visited set
230 if (candidate_midpoint) {
231 (void)visited_midpoints_.insert(candidate_midpoint);
232 }
233
234 current_path_.push_back(candidate_colorpoint);
235 last_added_point = candidate_colorpoint.point;
236 first_point_added = true;
237
238 }
239}
240
241// ===================== Path Extension =====================
242
243void PathCalculation::extend_path(int max_points) {
244 int n_points = 0;
245 // Define cost threshold for discarding poor path options
246 const double worst_cost = config_.max_cost_ * config_.search_depth_;
247 // Reserve space for expected path growth
248 current_path_.reserve(current_path_.size() + max_points);
249
250 while (true) {
251 if (current_path_.size() < 2) {
252 break;
253 }
254
255 const Colorpoint& prev = current_path_[current_path_.size() - 2];
256 const Colorpoint& last = current_path_.back();
257
258 std::shared_ptr<Midpoint> prev_mp = find_nearest_midpoint(prev.point);
259 std::shared_ptr<Midpoint> last_mp = find_nearest_midpoint(last.point);
260
261 // Abort if midpoints can't be matched
262 if (!prev_mp || !last_mp) {
263 RCLCPP_WARN(rclcpp::get_logger("planning"), "No valid midpoints found for path extension.");
264 break;
265 }
266
267 // Search for the best continuation from the current midpoint
268 auto [best_cost, best_midpoint] =
270
271 // Stop if no good extension is found or point was already visited
272 if (best_cost > worst_cost || !best_midpoint || visited_midpoints_.count(best_midpoint) > 0) {
273 break;
274 }
275
276 current_path_.push_back(
277 Colorpoint(best_midpoint->point, *best_midpoint->cone1, *best_midpoint->cone2));
278 (void)visited_midpoints_.insert(best_midpoint);
279 n_points++;
280
281 if (n_points >= max_points) {
282 break;
283 }
284
285 // Update midpoints validity and discard cones if needed
286 if (current_path_.size() > 2) {
288 }
289 }
290}
291
292// ================================ Path Search ================================
293
294std::pair<std::shared_ptr<Midpoint>, std::shared_ptr<Midpoint>>
296 std::pair<std::shared_ptr<Midpoint>, std::shared_ptr<Midpoint>> result{nullptr, nullptr};
297
298 Midpoint anchor_pose_midpoint{Point(initial_pose_.position.x, initial_pose_.position.y), nullptr,
299 nullptr};
300
301 // Get candidate midpoints
302 anchor_pose_midpoint.close_points = select_candidate_midpoints(anchor_pose_midpoint, 8);
303
304 double best_cost = std::numeric_limits<double>::max();
305
306 for (const auto& first : anchor_pose_midpoint.close_points) {
307 std::shared_ptr<Midpoint> anchor_mp = std::make_shared<Midpoint>(anchor_pose_midpoint);
308
309 auto [cost, midpoint] = find_best_next_midpoint(config_.search_depth_, anchor_mp, first,
310 std::numeric_limits<double>::max());
311
312 double dx = first->point.x() - anchor_pose_midpoint.point.x();
313 double dy = first->point.y() - anchor_pose_midpoint.point.y();
314 double distance = std::sqrt(dx * dx + dy * dy);
315
316 // Calculate the deviation angle relative to the car’s heading
317 double angle_to_point = std::atan2(dy, dx);
318 double angle_deviation =
319 std::abs(std::atan2(std::sin(angle_to_point - initial_pose_.orientation),
320 std::cos(angle_to_point - initial_pose_.orientation)));
321
322 double initial_cost = std::pow(distance, config_.distance_exponent_) * config_.distance_gain_ +
323 std::pow(angle_deviation, config_.angle_exponent_) * config_.angle_gain_;
324
325 cost += initial_cost;
326 cost += initial_cost;
327
328 if (cost < best_cost) {
329 result.first = first;
330 result.second = midpoint;
331 best_cost = cost;
332 }
333 }
334
335 return result;
336}
337
338std::vector<std::shared_ptr<Midpoint>> PathCalculation::select_candidate_midpoints(
339 const Midpoint& anchor_pose, int num_candidates) const {
340 auto cmp = [](const std::pair<double, std::shared_ptr<Midpoint>>& cost1,
341 const std::pair<double, std::shared_ptr<Midpoint>>& cost2) {
342 return cost1.first > cost2.first;
343 };
344
345 std::priority_queue<std::pair<double, std::shared_ptr<Midpoint>>,
346 std::vector<std::pair<double, std::shared_ptr<Midpoint>>>, decltype(cmp)>
347 pq(cmp);
348
349 double car_direction_x = std::cos(initial_pose_.orientation);
350 double car_direction_y = std::sin(initial_pose_.orientation);
351
352 // Find midpoints that are in front of the car
353 for (const auto& mp : midpoints_) {
354 double dx = mp->point.x() - anchor_pose.point.x();
355 double dy = mp->point.y() - anchor_pose.point.y();
356
357 // Skip points behind the car
358 if ((dx * car_direction_x + dy * car_direction_y) <= 0.0) {
359 continue;
360 }
361
362 double dist = std::sqrt(dx * dx + dy * dy);
363
364 // Calculate the deviation angle relative to the car’s heading
365 double angle_to_point = std::atan2(dy, dx);
366 double angle_deviation =
367 std::abs(std::atan2(std::sin(angle_to_point - initial_pose_.orientation),
368 std::cos(angle_to_point - initial_pose_.orientation)));
369
370 double cost = std::pow(angle_deviation, config_.angle_exponent_) * config_.angle_gain_ +
372
373 pq.push({cost, mp});
374 }
375
376 // Get the closest midpoints in front of the car
377 std::vector<std::shared_ptr<Midpoint>> candidate_points;
378 int count = 0;
379 while (count < num_candidates && !pq.empty()) {
380 candidate_points.push_back(pq.top().second);
381 pq.pop();
382 count++;
383 }
384
385 return candidate_points;
386}
387
388std::pair<double, std::shared_ptr<Midpoint>> PathCalculation::find_best_next_midpoint(
389 int depth, const std::shared_ptr<Midpoint>& previous, const std::shared_ptr<Midpoint>& current,
390 double max_cost) const {
391 if (depth == 0) {
392 return {0.0, current};
393 }
394
395 double min_cost = config_.max_cost_ * config_.search_depth_;
396 std::shared_ptr<Midpoint> min_point = current;
397
398 for (const auto& next : current->close_points) {
399 // Avoid revisiting the previous point
400 if (next == previous) {
401 continue;
402 }
403
404 double local_cost = calculate_cost(previous->point.x(), previous->point.y(), current->point.x(),
405 current->point.y(), next->point.x(), next->point.y());
406
407 // Skip if local cost exceeds maximum allowed cost
408 if (local_cost > max_cost) {
409 continue;
410 }
411
412 // Recursive cost calculation
413 auto [best_cost, best_point] = find_best_next_midpoint(depth - 1, current, next, max_cost);
414
415 double total_cost = local_cost + best_cost;
416
417 // Update minimum cost and corresponding point
418 if (total_cost < min_cost) {
419 min_cost = total_cost;
420 min_point = next;
421 }
422 }
423
424 return {min_cost, min_point};
425}
426
427double PathCalculation::calculate_cost(double previous_x, double previous_y, double current_x,
428 double current_y, double next_x, double next_y) const {
429 double dx_dist = current_x - next_x;
430 double dy_dist = current_y - next_y;
431 double distance = std::sqrt(dx_dist * dx_dist + dy_dist * dy_dist);
432
433 // Angle calculation
434 double angle_with_previous = std::atan2(current_y - previous_y, current_x - previous_x);
435 double angle_with_next = std::atan2(next_y - current_y, next_x - current_x);
436
437 // Normalize angle to be between 0 and π
438 double angle = abs(angle_with_next - angle_with_previous);
439 if (angle > M_PI) {
440 angle = 2 * M_PI - angle;
441 }
442
443 // Local cost calculation
444 return std::pow(angle, config_.angle_exponent_) * config_.angle_gain_ +
445 std::pow(distance, config_.distance_exponent_) * config_.distance_gain_;
446}
447
448// ===================== Cone Discarding =====================
449
451 if (current_path_.size() < 2) {
452 return;
453 }
454
455 const Colorpoint& last = current_path_[current_path_.size() - 2];
456 const Colorpoint& current = current_path_.back();
457
458 std::shared_ptr<Midpoint> last_mp = find_nearest_midpoint(last.point);
459 std::shared_ptr<Midpoint> current_midpoint = find_nearest_midpoint(current.point);
460
461 if (!last_mp || !current_midpoint) {
462 RCLCPP_WARN(rclcpp::get_logger("planning"), "No valid midpoints found for discarding cones.");
463 return;
464 }
465
466 // Discard a cone that was likely passed and should be discarded
467 discard_cone(last_mp, current_midpoint);
468
469 // Invalidate midpoints that rely on discarded cones
471
472 // Remove invalid neighbors from each midpoint's connections
474}
475
476void PathCalculation::discard_cone(const std::shared_ptr<Midpoint>& last_mp,
477 const std::shared_ptr<Midpoint>& current_mp) {
478 if (last_mp->cone1 == current_mp->cone1 || last_mp->cone1 == current_mp->cone2) {
479 if (last_mp->cone2 != current_mp->cone1 && last_mp->cone2 != current_mp->cone2) {
480 (void)discarded_cones_.insert(last_mp->cone2);
481 }
482 } else if (last_mp->cone2 == current_mp->cone1 || last_mp->cone2 == current_mp->cone2) {
483 if (last_mp->cone1 != current_mp->cone1 && last_mp->cone1 != current_mp->cone2) {
484 (void)discarded_cones_.insert(last_mp->cone1);
485 }
486 } else {
487 RCLCPP_DEBUG(rclcpp::get_logger("planning"), "No valid cones found for discarding.");
488 }
489}
490
492 for (const auto& mp : midpoints_) {
493 if (!mp->valid) {
494 continue;
495 }
496 if (discarded_cones_.count(mp->cone1) > 0 || discarded_cones_.count(mp->cone2) > 0) {
497 mp->valid = false;
498 }
499 }
500}
501
503 for (const auto& mp : midpoints_) {
504 if (!mp->valid) {
505 continue;
506 }
507 (void)mp->close_points.erase(
508 remove_if(mp->close_points.begin(), mp->close_points.end(),
509 [](const std::shared_ptr<Midpoint>& neighbor) { return !neighbor->valid; }),
510 mp->close_points.end());
511 }
512}
513
514// ===================== Utility Methods =====================
515
516std::shared_ptr<Midpoint> PathCalculation::find_nearest_midpoint(const Point& target) const {
518 std::shared_ptr<Midpoint> nearest = nullptr;
519
520 for (const auto& [pt, mp] : point_to_midpoint_) {
521 double dx = pt.x() - target.x();
522 double dy = pt.y() - target.y();
523 double dist_sq = dx * dx + dy * dy;
524
525 if (dist_sq < min_dist_sq) {
526 min_dist_sq = dist_sq;
527 nearest = mp;
528 }
529 }
530
531 return nearest;
532}
533
535 const std::vector<PathPoint>& path) const {
536 if (path.size() < 3) {
537 return {static_cast<int>(path.size()) - 1, std::numeric_limits<double>::max()};
538 }
539
540 const PathPoint& first = path[0];
541 const PathPoint& second = path[1];
542 double min_cost = std::numeric_limits<double>::max();
543 int best_cutoff_index = static_cast<int>(path.size() - 1);
544
545 for (int i = 2; i < static_cast<int>(path.size()); ++i) {
546 const PathPoint& current = path[i];
547 const PathPoint& previous = path[i - 1];
548
549 double cost = calculate_cost(previous.position.x, previous.position.y, current.position.x,
550 current.position.y, first.position.x, first.position.y);
551
552 double cost_into_second =
553 calculate_cost(current.position.x, current.position.y, first.position.x, first.position.y,
554 second.position.x, second.position.y);
555
556 double combined_cost = cost + cost_into_second;
557
558 if (combined_cost < min_cost) {
559 min_cost = combined_cost;
560 best_cutoff_index = i;
561 }
562 }
563
564 return {best_cutoff_index, min_cost};
565}
566
568 const std::vector<Colorpoint>& colorpoints) const {
569 std::vector<PathPoint> path_points;
570 path_points.reserve(colorpoints.size());
571
572 for (const Colorpoint& pt : colorpoints) {
573 (void)path_points.emplace_back(pt.point.x(), pt.point.y());
574 }
575
576 return path_points;
577}
578// ===================== Accessor Methods =====================
579
580std::vector<PathPoint> PathCalculation::get_path_to_car() const {
582}
583
584const std::vector<std::pair<Point, Point>>& PathCalculation::get_triangulations() const {
586}
587
588const std::vector<PathPoint>& PathCalculation::get_yellow_cones() const { return yellow_cones_; }
589
590const std::vector<PathPoint>& PathCalculation::get_blue_cones() const { return blue_cones_; }
Path point with two boundary cones, provides cone classification into left/right boundaries.
Point point
The path point (midpoint between cones).
static void extract_cones(std::vector< Colorpoint > &colorpoints, std::vector< PathPoint > &yellow_cones, std::vector< PathPoint > &blue_cones)
Extracts and classifies all cones from a sequence of colorpoints.
Definition colorpoint.cpp:3
void set_vehicle_pose(const Pose &vehicle_pose)
Updates the vehicle pose for dynamic filtering.
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.
const std::vector< std::pair< Point, Point > > & get_triangulations() const
Returns the current set of Delaunay edges used for visualization.
std::pair< std::shared_ptr< Midpoint >, std::shared_ptr< Midpoint > > select_starting_midpoints()
Select the first two midpoints to start the path.
std::vector< Colorpoint > past_path_
int reset_path(bool should_reset)
Handle path reset when completing a lap.
const std::vector< PathPoint > & get_yellow_cones() const
Gets the list of yellow cones detected or used in the path calculation.
std::vector< std::shared_ptr< Midpoint > > select_candidate_midpoints(const Midpoint &anchor_pose, int num_candidates) const
Select candidate midpoints in front of the vehicle.
std::unordered_set< std::shared_ptr< Midpoint > > visited_midpoints_
void discard_cone(const std::shared_ptr< Midpoint > &last_mp, const std::shared_ptr< Midpoint > &current_mp)
Determine which cone to discard between two consecutive midpoints.
double calculate_cost(double previous_x, double previous_y, double current_x, double current_y, double next_x, double next_y) const
Calculate the cost of transitioning through three consecutive points.
std::vector< PathPoint > get_path_to_car() const
Get the path from the start to a lookback distance behind the car’s current position.
common_lib::structures::Pose vehicle_pose_
std::vector< PathPoint > calculate_path(const std::vector< Cone > &cone_array)
Generate a path from an array of cones.
void initialize_path_from_initial_pose()
Initialize the path from the vehicle's initial pose.
void remove_invalid_neighbors()
Remove invalid neighbors from all midpoint connection lists.
bool is_map_closed(std::vector< PathPoint > &path) const
Checks if the path forms a closed loop and closes it if the transition cost is below config_....
std::unordered_set< std::shared_ptr< Cone > > discarded_cones_
std::vector< PathPoint > yellow_cones_
std::shared_ptr< Midpoint > find_nearest_midpoint(const Point &target) const
Find the nearest valid midpoint to a target position.
void extend_path(int max_points)
Extend the path by adding midpoints.
void clear_path_state()
Reset path construction state.
MidpointGenerator midpoint_generator_
void update_path_from_past_path()
Initialize the path from the previous path.
void invalidate_midpoints_with_discarded_cones()
Mark midpoints as invalid if they use discarded cones.
const std::vector< PathPoint > & get_blue_cones() const
Gets the list of blue cones detected or used in the path calculation.
std::vector< PathPoint > blue_cones_
const std::vector< std::pair< Point, Point > > & get_triangulations() const
Get the triangulation segments used in path generation.
std::pair< double, std::shared_ptr< Midpoint > > find_best_next_midpoint(int depth, const std::shared_ptr< Midpoint > &previous, const std::shared_ptr< Midpoint > &current, double max_cost) const
Recursively find the best next midpoint using depth-first search.
std::vector< PathPoint > calculate_trackdrive(const std::vector< Cone > &cone_array)
Generate a closed loop path for trackdrive competition.
common_lib::structures::Pose initial_pose_
std::vector< std::shared_ptr< Midpoint > > midpoints_
std::pair< int, double > find_best_loop_closure(const std::vector< PathPoint > &path) const
Finds the best loop closure point in a path.
std::vector< Colorpoint > current_path_
std::unordered_map< Point, std::shared_ptr< Midpoint > > point_to_midpoint_
void discard_cones_along_path()
Invalidate cones and midpoints along the last path segment.
void set_vehicle_pose(const common_lib::structures::Pose &vehicle_pose)
Set the current vehicle position and orientation.
std::vector< PathPoint > get_path_points_from_colorpoints(const std::vector< Colorpoint > &colorpoints) const
Converts a vector of Colorpoint objects into a vector of PathPoint objects.
std::vector< Colorpoint > path_to_car_
PathCalculationConfig config_
K::Point_2 Point
Definition marker.hpp:18
int max_points_
Maximum number of points added in an iteration.
int lookback_points_
Number of recent path points discarded and recalculated each iteration.
double angle_exponent_
Exponent applied to the angle term in the cost function.
double distance_exponent_
Exponent applied to the distance term in the cost function.
double minimum_point_distance_
Minimum allowed distance between consecutive points in the generated path.
double angle_gain_
Gain applied to the angle term in the cost function.
double distance_gain_
Gain applied to the distance term in the cost function.
double close_cost_
Cost threshold to determine whether the path is considered closed.
double max_cost_
Maximum allowed cost for a path.
bool use_sliding_window_
Flag to enable/disable the sliding window for path calculation.
bool use_reset_path_
Flag to enable/disable path reset logic.
int search_depth_
Maximum search depth when exploring candidate paths.
MidPoint struct represents a potential path point with connections.
Definition midpoint.hpp:17
std::vector< std::shared_ptr< Midpoint > > close_points
Definition midpoint.hpp:19
Struct for pose representation.
Definition pose.hpp:13