|
15 | 15 | #include "filter_predicted_objects.hpp"
|
16 | 16 |
|
17 | 17 | #include <autoware/motion_utils/trajectory/trajectory.hpp>
|
| 18 | +#include <autoware/universe_utils/geometry/boost_geometry.hpp> |
18 | 19 | #include <traffic_light_utils/traffic_light_utils.hpp>
|
19 | 20 |
|
| 21 | +#include <boost/geometry/algorithms/detail/intersects/interface.hpp> |
20 | 22 | #include <boost/geometry/algorithms/intersects.hpp>
|
| 23 | +#include <boost/geometry/index/predicates.hpp> |
21 | 24 |
|
22 | 25 | #include <lanelet2_core/geometry/LaneletMap.h>
|
23 | 26 | #include <lanelet2_core/primitives/BasicRegulatoryElements.h>
|
24 | 27 |
|
25 | 28 | #include <algorithm>
|
| 29 | +#include <iterator> |
| 30 | +#include <vector> |
26 | 31 |
|
27 | 32 | namespace autoware::motion_velocity_planner::out_of_lane
|
28 | 33 | {
|
29 | 34 | void cut_predicted_path_beyond_line(
|
30 | 35 | autoware_perception_msgs::msg::PredictedPath & predicted_path,
|
31 |
| - const lanelet::BasicLineString2d & stop_line, const double object_front_overhang) |
| 36 | + const universe_utils::LineString2d & stop_line, const double object_front_overhang) |
32 | 37 | {
|
33 | 38 | if (predicted_path.path.empty() || stop_line.size() < 2) return;
|
34 | 39 |
|
@@ -58,43 +63,46 @@ void cut_predicted_path_beyond_line(
|
58 | 63 | }
|
59 | 64 | }
|
60 | 65 |
|
61 |
| -std::optional<const lanelet::BasicLineString2d> find_next_stop_line( |
62 |
| - const autoware_perception_msgs::msg::PredictedPath & path, |
63 |
| - const std::shared_ptr<const PlannerData> planner_data) |
| 66 | +std::optional<universe_utils::LineString2d> find_next_stop_line( |
| 67 | + const autoware_perception_msgs::msg::PredictedPath & path, const EgoData & ego_data) |
64 | 68 | {
|
65 |
| - lanelet::ConstLanelets lanelets; |
66 |
| - lanelet::BasicLineString2d query_line; |
67 |
| - for (const auto & p : path.path) query_line.emplace_back(p.position.x, p.position.y); |
68 |
| - const auto query_results = lanelet::geometry::findWithin2d( |
69 |
| - planner_data->route_handler->getLaneletMapPtr()->laneletLayer, query_line); |
70 |
| - for (const auto & r : query_results) lanelets.push_back(r.second); |
71 |
| - for (const auto & ll : lanelets) { |
72 |
| - for (const auto & element : ll.regulatoryElementsAs<lanelet::TrafficLight>()) { |
73 |
| - const auto traffic_signal_stamped = planner_data->get_traffic_signal(element->id()); |
74 |
| - if ( |
75 |
| - traffic_signal_stamped.has_value() && element->stopLine().has_value() && |
76 |
| - traffic_light_utils::isTrafficSignalStop(ll, traffic_signal_stamped.value().signal)) { |
77 |
| - lanelet::BasicLineString2d stop_line; |
78 |
| - for (const auto & p : *(element->stopLine())) stop_line.emplace_back(p.x(), p.y()); |
79 |
| - return stop_line; |
| 69 | + universe_utils::LineString2d query_path; |
| 70 | + for (const auto & p : path.path) query_path.emplace_back(p.position.x, p.position.y); |
| 71 | + std::vector<StopLineNode> query_results; |
| 72 | + ego_data.stop_lines_rtree.query( |
| 73 | + boost::geometry::index::intersects(query_path), std::back_inserter(query_results)); |
| 74 | + auto earliest_intersecting_index = query_path.size(); |
| 75 | + std::optional<universe_utils::LineString2d> earliest_stop_line; |
| 76 | + universe_utils::Segment2d path_segment; |
| 77 | + for (const auto & stop_line_node : query_results) { |
| 78 | + const auto & stop_line = stop_line_node.second; |
| 79 | + for (auto index = 0UL; index + 1 < query_path.size(); ++index) { |
| 80 | + path_segment.first = query_path[index]; |
| 81 | + path_segment.second = query_path[index + 1]; |
| 82 | + if (boost::geometry::intersects(path_segment, stop_line.stop_line)) { |
| 83 | + bool within_stop_line_lanelet = |
| 84 | + std::any_of(stop_line.lanelets.begin(), stop_line.lanelets.end(), [&](const auto & ll) { |
| 85 | + return boost::geometry::within(path_segment.first, ll.polygon2d().basicPolygon()); |
| 86 | + }); |
| 87 | + for (const auto & ll : stop_line.lanelets) { |
| 88 | + } |
| 89 | + if (within_stop_line_lanelet) { |
| 90 | + earliest_intersecting_index = std::min(index, earliest_intersecting_index); |
| 91 | + earliest_stop_line = stop_line.stop_line; |
| 92 | + } |
80 | 93 | }
|
81 | 94 | }
|
82 | 95 | }
|
83 |
| - return std::nullopt; |
| 96 | + return earliest_stop_line; |
84 | 97 | }
|
85 | 98 |
|
86 | 99 | void cut_predicted_path_beyond_red_lights(
|
87 |
| - autoware_perception_msgs::msg::PredictedPath & predicted_path, |
88 |
| - const std::shared_ptr<const PlannerData> planner_data, const double object_front_overhang) |
| 100 | + autoware_perception_msgs::msg::PredictedPath & predicted_path, const EgoData & ego_data, |
| 101 | + const double object_front_overhang) |
89 | 102 | {
|
90 |
| - const auto stop_line = find_next_stop_line(predicted_path, planner_data); |
| 103 | + const auto stop_line = find_next_stop_line(predicted_path, ego_data); |
91 | 104 | if (stop_line) {
|
92 |
| - // we use a longer stop line to also cut predicted paths that slightly go around the stop line |
93 |
| - auto longer_stop_line = *stop_line; |
94 |
| - const auto diff = stop_line->back() - stop_line->front(); |
95 |
| - longer_stop_line.front() -= diff * 0.5; |
96 |
| - longer_stop_line.back() += diff * 0.5; |
97 |
| - cut_predicted_path_beyond_line(predicted_path, longer_stop_line, object_front_overhang); |
| 105 | + cut_predicted_path_beyond_line(predicted_path, *stop_line, object_front_overhang); |
98 | 106 | }
|
99 | 107 | }
|
100 | 108 |
|
@@ -141,7 +149,7 @@ autoware_perception_msgs::msg::PredictedObjects filter_predicted_objects(
|
141 | 149 | if (params.objects_cut_predicted_paths_beyond_red_lights)
|
142 | 150 | for (auto & predicted_path : predicted_paths)
|
143 | 151 | cut_predicted_path_beyond_red_lights(
|
144 |
| - predicted_path, planner_data, filtered_object.shape.dimensions.x); |
| 152 | + predicted_path, ego_data, filtered_object.shape.dimensions.x); |
145 | 153 | predicted_paths.erase(
|
146 | 154 | std::remove_if(
|
147 | 155 | predicted_paths.begin(), predicted_paths.end(),
|
|
0 commit comments