Skip to content

Commit 5d79c9a

Browse files
committed
use rtree for the stop lines
Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp>
1 parent 49231bc commit 5d79c9a

File tree

5 files changed

+119
-44
lines changed

5 files changed

+119
-44
lines changed

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/filter_predicted_objects.cpp

+38-30
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,25 @@
1515
#include "filter_predicted_objects.hpp"
1616

1717
#include <autoware/motion_utils/trajectory/trajectory.hpp>
18+
#include <autoware/universe_utils/geometry/boost_geometry.hpp>
1819
#include <traffic_light_utils/traffic_light_utils.hpp>
1920

21+
#include <boost/geometry/algorithms/detail/intersects/interface.hpp>
2022
#include <boost/geometry/algorithms/intersects.hpp>
23+
#include <boost/geometry/index/predicates.hpp>
2124

2225
#include <lanelet2_core/geometry/LaneletMap.h>
2326
#include <lanelet2_core/primitives/BasicRegulatoryElements.h>
2427

2528
#include <algorithm>
29+
#include <iterator>
30+
#include <vector>
2631

2732
namespace autoware::motion_velocity_planner::out_of_lane
2833
{
2934
void cut_predicted_path_beyond_line(
3035
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)
3237
{
3338
if (predicted_path.path.empty() || stop_line.size() < 2) return;
3439

@@ -58,43 +63,46 @@ void cut_predicted_path_beyond_line(
5863
}
5964
}
6065

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)
6468
{
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+
}
8093
}
8194
}
8295
}
83-
return std::nullopt;
96+
return earliest_stop_line;
8497
}
8598

8699
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)
89102
{
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);
91104
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);
98106
}
99107
}
100108

@@ -141,7 +149,7 @@ autoware_perception_msgs::msg::PredictedObjects filter_predicted_objects(
141149
if (params.objects_cut_predicted_paths_beyond_red_lights)
142150
for (auto & predicted_path : predicted_paths)
143151
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);
145153
predicted_paths.erase(
146154
std::remove_if(
147155
predicted_paths.begin(), predicted_paths.end(),

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/filter_predicted_objects.hpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,21 @@ namespace autoware::motion_velocity_planner::out_of_lane
3030
/// @param [in] object_front_overhang extra distance to cut ahead of the stop line
3131
void cut_predicted_path_beyond_line(
3232
autoware_perception_msgs::msg::PredictedPath & predicted_path,
33-
const lanelet::BasicLineString2d & stop_line, const double object_front_overhang);
33+
const universe_utils::LineString2d & stop_line, const double object_front_overhang);
3434

3535
/// @brief find the next red light stop line along the given path
3636
/// @param [in] path predicted path to check for a stop line
37-
/// @param [in] planner_data planner data with stop line information
37+
/// @param [in] ego_data ego data with the stop lines information
3838
/// @return the first red light stop line found along the path (if any)
39-
std::optional<const lanelet::BasicLineString2d> find_next_stop_line(
40-
const autoware_perception_msgs::msg::PredictedPath & path,
41-
const std::shared_ptr<const PlannerData> planner_data);
39+
std::optional<universe_utils::LineString2d> find_next_stop_line(
40+
const autoware_perception_msgs::msg::PredictedPath & path, const EgoData & ego_data);
4241

4342
/// @brief cut predicted path beyond stop lines of red lights
4443
/// @param [inout] predicted_path predicted path to cut
45-
/// @param [in] planner_data planner data to get the map and traffic light information
44+
/// @param [in] ego_data ego data with the stop lines information
4645
void cut_predicted_path_beyond_red_lights(
47-
autoware_perception_msgs::msg::PredictedPath & predicted_path,
48-
const std::shared_ptr<const PlannerData> planner_data, const double object_front_overhang);
46+
autoware_perception_msgs::msg::PredictedPath & predicted_path, const EgoData & ego_data,
47+
const double object_front_overhang);
4948

5049
/// @brief filter predicted objects and their predicted paths
5150
/// @param [in] planner_data planner data

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/out_of_lane_module.cpp

+52
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,29 @@
2323
#include "overlapping_range.hpp"
2424
#include "types.hpp"
2525

26+
#include <autoware/universe_utils/ros/update_param.hpp>
2627
#include <autoware/motion_utils/trajectory/interpolation.hpp>
2728
#include <autoware/motion_utils/trajectory/trajectory.hpp>
29+
#include <autoware/motion_velocity_planner_common/planner_data.hpp>
30+
#include <autoware/route_handler/route_handler.hpp>
31+
#include <autoware/universe_utils/geometry/boost_geometry.hpp>
32+
#include <autoware/universe_utils/geometry/geometry.hpp>
2833
#include <autoware/universe_utils/ros/parameter.hpp>
2934
#include <autoware/universe_utils/ros/update_param.hpp>
3035
#include <autoware/universe_utils/system/stop_watch.hpp>
36+
#include <traffic_light_utils/traffic_light_utils.hpp>
3137

38+
#include <boost/geometry/algorithms/detail/disjoint/interface.hpp>
39+
#include <boost/geometry/algorithms/detail/envelope/interface.hpp>
3240
#include <boost/geometry/algorithms/intersects.hpp>
3341

42+
#include <lanelet2_core/geometry/BoundingBox.h>
3443
#include <lanelet2_core/geometry/LaneletMap.h>
44+
#include <lanelet2_core/geometry/Polygon.h>
45+
#include <lanelet2_core/primitives/BasicRegulatoryElements.h>
46+
#include <lanelet2_core/primitives/CompoundPolygon.h>
47+
#include <lanelet2_core/primitives/Lanelet.h>
48+
#include <lanelet2_core/primitives/Polygon.h>
3549

3650
#include <map>
3751
#include <memory>
@@ -155,6 +169,42 @@ void OutOfLaneModule::update_parameters(const std::vector<rclcpp::Parameter> & p
155169
updateParam(parameters, ns_ + ".ego.extra_right_offset", pp.extra_right_offset);
156170
}
157171

172+
void prepare_stop_lines_rtree(
173+
out_of_lane::EgoData & ego_data, const PlannerData & planner_data, const double search_distance)
174+
{
175+
std::vector<out_of_lane::StopLineNode> rtree_nodes;
176+
const auto bbox = lanelet::BoundingBox2d(
177+
lanelet::BasicPoint2d{
178+
ego_data.pose.position.x - search_distance, ego_data.pose.position.y - search_distance},
179+
lanelet::BasicPoint2d{
180+
ego_data.pose.position.x + search_distance, ego_data.pose.position.y + search_distance});
181+
out_of_lane::StopLineNode stop_line_node;
182+
for (const auto & ll :
183+
planner_data.route_handler->getLaneletMapPtr()->laneletLayer.search(bbox)) {
184+
for (const auto & element : ll.regulatoryElementsAs<lanelet::TrafficLight>()) {
185+
const auto traffic_signal_stamped = planner_data.get_traffic_signal(element->id());
186+
if (
187+
traffic_signal_stamped.has_value() && element->stopLine().has_value() &&
188+
traffic_light_utils::isTrafficSignalStop(ll, traffic_signal_stamped.value().signal)) {
189+
stop_line_node.second.stop_line.clear();
190+
for (const auto & p : element->stopLine()->basicLineString()) {
191+
stop_line_node.second.stop_line.emplace_back(p.x(), p.y());
192+
}
193+
// use a longer stop line to also cut predicted paths that slightly go around the stop line
194+
const auto diff =
195+
stop_line_node.second.stop_line.back() - stop_line_node.second.stop_line.front();
196+
stop_line_node.second.stop_line.front() -= diff * 0.5;
197+
stop_line_node.second.stop_line.back() += diff * 0.5;
198+
stop_line_node.second.lanelets = planner_data.route_handler->getPreviousLanelets(ll);
199+
stop_line_node.first =
200+
boost::geometry::return_envelope<universe_utils::Box2d>(stop_line_node.second.stop_line);
201+
rtree_nodes.push_back(stop_line_node);
202+
}
203+
}
204+
}
205+
ego_data.stop_lines_rtree = {rtree_nodes.begin(), rtree_nodes.end()};
206+
}
207+
158208
VelocityPlanningResult OutOfLaneModule::plan(
159209
const std::vector<autoware_planning_msgs::msg::TrajectoryPoint> & ego_trajectory_points,
160210
const std::shared_ptr<const PlannerData> planner_data)
@@ -169,6 +219,8 @@ VelocityPlanningResult OutOfLaneModule::plan(
169219
autoware::motion_utils::findNearestSegmentIndex(ego_trajectory_points, ego_data.pose.position);
170220
ego_data.velocity = planner_data->current_odometry.twist.twist.linear.x;
171221
ego_data.max_decel = planner_data->velocity_smoother_->getMinDecel();
222+
prepare_stop_lines_rtree(ego_data, *planner_data, 100.0);
223+
172224
stopwatch.tic("calculate_trajectory_footprints");
173225
const auto current_ego_footprint =
174226
out_of_lane::calculate_current_ego_footprint(ego_data, params_, true);

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/types.hpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
#include <autoware_planning_msgs/msg/trajectory_point.hpp>
2323
#include <geometry_msgs/msg/pose.hpp>
2424

25+
#include <boost/geometry/geometries/multi_polygon.hpp>
26+
#include <boost/geometry/index/rtree.hpp>
27+
#include <autoware/universe_utils/geometry/boost_geometry.hpp>
28+
29+
#include <lanelet2_core/Forward.h>
2530
#include <lanelet2_core/LaneletMap.h>
2631

2732
#include <algorithm>
@@ -172,6 +177,16 @@ struct OtherLane
172177
}
173178
};
174179

180+
namespace bgi = boost::geometry::index;
181+
struct StopLine
182+
{
183+
universe_utils::LineString2d stop_line;
184+
lanelet::ConstLanelets lanelets;
185+
};
186+
using StopLineNode = std::pair<universe_utils::Box2d, StopLine>;
187+
using StopLinesRtree = bgi::rtree<StopLineNode, bgi::rstar<16>>;
188+
using OutAreaRtree = bgi::rtree<std::pair<universe_utils::Box2d, size_t>, bgi::rstar<16>>;
189+
175190
/// @brief data related to the ego vehicle
176191
struct EgoData
177192
{
@@ -180,16 +195,17 @@ struct EgoData
180195
double velocity{}; // [m/s]
181196
double max_decel{}; // [m/s²]
182197
geometry_msgs::msg::Pose pose{};
198+
StopLinesRtree stop_lines_rtree;
183199
};
184200

185201
/// @brief data needed to make decisions
186202
struct DecisionInputs
187203
{
188-
OverlapRanges ranges{};
189-
EgoData ego_data{};
190-
autoware_perception_msgs::msg::PredictedObjects objects{};
191-
std::shared_ptr<const route_handler::RouteHandler> route_handler{};
192-
lanelet::ConstLanelets lanelets{};
204+
OverlapRanges ranges;
205+
EgoData ego_data;
206+
autoware_perception_msgs::msg::PredictedObjects objects;
207+
std::shared_ptr<const route_handler::RouteHandler> route_handler;
208+
lanelet::ConstLanelets lanelets;
193209
};
194210

195211
/// @brief debug data

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/test/test_filter_predicted_objects.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ TEST(TestCollisionDistance, CutPredictedPathBeyondLine)
2525
{
2626
using autoware::motion_velocity_planner::out_of_lane::cut_predicted_path_beyond_line;
2727
autoware_perception_msgs::msg::PredictedPath predicted_path;
28-
lanelet::BasicLineString2d stop_line;
28+
autoware::universe_utils::LineString2d stop_line;
2929
double object_front_overhang = 0.0;
3030
const auto eps = 1e-9;
3131

0 commit comments

Comments
 (0)