|
20 | 20 |
|
21 | 21 | #include "deprecated.hpp" |
22 | 22 |
|
23 | | -// TODO(sarun-hub): lanelet2_extension will be removed when toLaneletPoint is deprecated. |
24 | | -#include <autoware_lanelet2_extension/utility/message_conversion.hpp> // For toLaneletPoint |
25 | 23 | #include <tf2/utils.hpp> |
26 | 24 |
|
27 | 25 | #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp> |
28 | 26 |
|
29 | 27 | #include <lanelet2_core/geometry/Lanelet.h> |
30 | 28 |
|
| 29 | +#include <algorithm> |
31 | 30 | #include <iostream> |
32 | 31 | #include <limits> |
| 32 | +#include <utility> |
| 33 | +#include <vector> |
33 | 34 |
|
34 | 35 | using lanelet::utils::to2D; |
35 | 36 |
|
@@ -63,6 +64,96 @@ void copyZ(const T1 & from, T2 & to) |
63 | 64 | to[i_to].z() = from[i_from - 1].z() + ratio * (from[i_from].z() - from[i_from - 1].z()); |
64 | 65 | } |
65 | 66 | } |
| 67 | + |
| 68 | +std::vector<double> calculateSegmentDistances(const lanelet::ConstLineString3d & line_string) |
| 69 | +{ |
| 70 | + std::vector<double> segment_distances; |
| 71 | + segment_distances.reserve(line_string.size() - 1); |
| 72 | + |
| 73 | + for (size_t i = 1; i < line_string.size(); ++i) { |
| 74 | + const auto distance = lanelet::geometry::distance(line_string[i], line_string[i - 1]); |
| 75 | + segment_distances.push_back(distance); |
| 76 | + } |
| 77 | + |
| 78 | + return segment_distances; |
| 79 | +} |
| 80 | + |
| 81 | +std::vector<double> calculateAccumulatedLengths(const lanelet::ConstLineString3d & line_string) |
| 82 | +{ |
| 83 | + const auto segment_distances = calculateSegmentDistances(line_string); |
| 84 | + |
| 85 | + std::vector<double> accumulated_lengths{0}; |
| 86 | + accumulated_lengths.reserve(segment_distances.size() + 1); |
| 87 | + std::partial_sum( |
| 88 | + std::begin(segment_distances), std::end(segment_distances), |
| 89 | + std::back_inserter(accumulated_lengths)); |
| 90 | + |
| 91 | + return accumulated_lengths; |
| 92 | +} |
| 93 | + |
| 94 | +std::pair<size_t, size_t> findNearestIndexPair( |
| 95 | + const std::vector<double> & accumulated_lengths, const double target_length) |
| 96 | +{ |
| 97 | + // List size |
| 98 | + const auto N = accumulated_lengths.size(); |
| 99 | + |
| 100 | + // Front |
| 101 | + if (target_length < accumulated_lengths.at(1)) { |
| 102 | + return std::make_pair(0, 1); |
| 103 | + } |
| 104 | + |
| 105 | + // Back |
| 106 | + if (target_length > accumulated_lengths.at(N - 2)) { |
| 107 | + return std::make_pair(N - 2, N - 1); |
| 108 | + } |
| 109 | + |
| 110 | + // Middle |
| 111 | + for (std::size_t i = 1; i < N; ++i) { |
| 112 | + if ( |
| 113 | + accumulated_lengths.at(i - 1) <= target_length && |
| 114 | + target_length <= accumulated_lengths.at(i)) { |
| 115 | + return std::make_pair(i - 1, i); |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + // Throw an exception because this never happens |
| 120 | + throw std::runtime_error("No nearest point found."); |
| 121 | +} |
| 122 | + |
| 123 | +std::vector<lanelet::BasicPoint3d> resamplePoints( |
| 124 | + const lanelet::ConstLineString3d & line_string, const int num_segments) |
| 125 | +{ |
| 126 | + // Calculate length |
| 127 | + const auto line_length = static_cast<double>(lanelet::geometry::length(line_string)); |
| 128 | + |
| 129 | + // Calculate accumulated lengths |
| 130 | + const auto accumulated_lengths = calculateAccumulatedLengths(line_string); |
| 131 | + if (accumulated_lengths.size() < 2) return {}; |
| 132 | + |
| 133 | + // Create each segment |
| 134 | + std::vector<lanelet::BasicPoint3d> resampled_points; |
| 135 | + for (auto i = 0; i <= num_segments; ++i) { |
| 136 | + // Find two nearest points |
| 137 | + const auto target_length = (static_cast<double>(i) / num_segments) * line_length; |
| 138 | + const auto index_pair = findNearestIndexPair(accumulated_lengths, target_length); |
| 139 | + |
| 140 | + // Apply linear interpolation |
| 141 | + const lanelet::BasicPoint3d back_point = line_string[index_pair.first]; |
| 142 | + const lanelet::BasicPoint3d front_point = line_string[index_pair.second]; |
| 143 | + const auto direction_vector = (front_point - back_point); |
| 144 | + |
| 145 | + const auto back_length = accumulated_lengths.at(index_pair.first); |
| 146 | + const auto front_length = accumulated_lengths.at(index_pair.second); |
| 147 | + const auto segment_length = front_length - back_length; |
| 148 | + const auto target_point = |
| 149 | + back_point + (direction_vector * (target_length - back_length) / segment_length); |
| 150 | + |
| 151 | + // Add to list |
| 152 | + resampled_points.emplace_back(target_point); |
| 153 | + } |
| 154 | + |
| 155 | + return resampled_points; |
| 156 | +} |
66 | 157 | } // namespace detail |
67 | 158 |
|
68 | 159 | lanelet::ConstLineString3d getClosestSegment( |
@@ -240,15 +331,6 @@ bool getClosestLanelet( |
240 | 331 | return found; |
241 | 332 | } |
242 | 333 |
|
243 | | -bool isInLanelet( |
244 | | - const geometry_msgs::msg::Pose & current_pose, const lanelet::ConstLanelet & lanelet, |
245 | | - const double radius) |
246 | | -{ |
247 | | - constexpr double eps = 1.0e-9; |
248 | | - const lanelet::BasicPoint2d p(current_pose.position.x, current_pose.position.y); |
249 | | - return boost::geometry::distance(p, lanelet.polygon2d().basicPolygon()) < radius + eps; |
250 | | -} |
251 | | - |
252 | 334 | double getLateralDistanceToCenterline( |
253 | 335 | const lanelet::ConstLanelet & lanelet, const geometry_msgs::msg::Pose & pose) |
254 | 336 | { |
@@ -432,4 +514,32 @@ lanelet::ConstPoint3d toLaneletPoint(const geometry_msgs::msg::Point & src) |
432 | 514 | toLaneletPoint(src, &dst); |
433 | 515 | return dst; |
434 | 516 | } |
| 517 | + |
| 518 | +lanelet::LineString3d generateFineCenterline( |
| 519 | + const lanelet::ConstLanelet & lanelet_obj, const double resolution) |
| 520 | +{ |
| 521 | + // Get length of longer border |
| 522 | + const double left_length = |
| 523 | + static_cast<double>(lanelet::geometry::length(lanelet_obj.leftBound())); |
| 524 | + const double right_length = |
| 525 | + static_cast<double>(lanelet::geometry::length(lanelet_obj.rightBound())); |
| 526 | + const double longer_distance = (left_length > right_length) ? left_length : right_length; |
| 527 | + const int num_segments = std::max(static_cast<int>(ceil(longer_distance / resolution)), 1); |
| 528 | + |
| 529 | + // Resample points |
| 530 | + const auto left_points = detail::resamplePoints(lanelet_obj.leftBound(), num_segments); |
| 531 | + const auto right_points = detail::resamplePoints(lanelet_obj.rightBound(), num_segments); |
| 532 | + |
| 533 | + // Create centerline |
| 534 | + lanelet::LineString3d centerline(lanelet::utils::getId()); |
| 535 | + for (int i = 0; i < num_segments + 1; i++) { |
| 536 | + // Add ID for the average point of left and right |
| 537 | + const auto center_basic_point = (right_points.at(i) + left_points.at(i)) / 2; |
| 538 | + const lanelet::Point3d center_point( |
| 539 | + lanelet::utils::getId(), center_basic_point.x(), center_basic_point.y(), |
| 540 | + center_basic_point.z()); |
| 541 | + centerline.push_back(center_point); |
| 542 | + } |
| 543 | + return centerline; |
| 544 | +} |
435 | 545 | } // namespace deprecated |
0 commit comments