Skip to content

Commit 317df4d

Browse files
authored
perf(out_of_lane): use intersection with other lanes instead of difference with ego lane (#8870)
Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp>
1 parent e9468b7 commit 317df4d

12 files changed

+216
-122
lines changed

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/README.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ The length of the trajectory used for generating the footprints is limited by th
2727

2828
![ego_footprints](./docs/footprints.png)
2929

30-
### 2. Ego lanelets
30+
### 2. Other lanelets
3131

32-
In the second step, we calculate the lanelets followed by the ego trajectory.
33-
We select all lanelets crossed by the trajectory linestring (sequence of trajectory points), as well as their preceding lanelets.
32+
In the second step, we calculate the lanelets where collisions should be avoided.
33+
We consider all lanelets around the ego vehicle that are not crossed by the trajectory linestring (sequence of trajectory points) or their preceding lanelets.
3434

35-
![ego_lane](./docs/ego_lane.png)
35+
![other_lanes](./docs/other_lanes.png)
3636

37-
In the debug visualization the combination of all ego lanelets is shown as a blue polygon.
37+
In the debug visualization, these other lanelets are shown as blue polygons.
3838

3939
### 3. Out of lane areas
4040

41-
Next, for each trajectory point, we create the corresponding out of lane areas by subtracting the ego lanelets (from step 2) from the trajectory point footprint (from step 1).
41+
Next, for each trajectory point, we create the corresponding out of lane areas by intersection the other lanelets (from step 2) with the trajectory point footprint (from step 1).
4242
Each area is associated with the lanelets overlapped by the area and with the corresponding ego trajectory point.
4343

4444
![out_of_lane_areas](./docs/out_of_lane_areas.png)

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/calculate_slowdown_points.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
#include <autoware/motion_utils/trajectory/trajectory.hpp>
2222
#include <autoware/universe_utils/geometry/boost_geometry.hpp>
2323

24-
#include <autoware_planning_msgs/msg/detail/trajectory_point__struct.hpp>
25-
#include <geometry_msgs/msg/detail/pose__struct.hpp>
24+
#include <autoware_planning_msgs/msg/trajectory_point.hpp>
2625
#include <geometry_msgs/msg/pose.hpp>
2726

2827
#include <boost/geometry/algorithms/disjoint.hpp>
@@ -78,7 +77,7 @@ std::optional<geometry_msgs::msg::Pose> calculate_pose_ahead_of_collision(
7877
const auto interpolated_pose =
7978
motion_utils::calcInterpolatedPose(ego_data.trajectory_points, l);
8079
const auto interpolated_footprint = project_to_pose(footprint, interpolated_pose);
81-
if (boost::geometry::intersects(interpolated_footprint, point_to_avoid.outside_ring)) {
80+
if (!boost::geometry::disjoint(interpolated_footprint, point_to_avoid.out_overlaps)) {
8281
return interpolated_pose;
8382
}
8483
}

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/debug.cpp

+66-39
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121
#include <autoware/universe_utils/geometry/geometry.hpp>
2222
#include <autoware/universe_utils/ros/marker_helper.hpp>
2323

24-
#include <geometry_msgs/msg/detail/point__struct.hpp>
25-
#include <geometry_msgs/msg/detail/pose__struct.hpp>
26-
#include <std_msgs/msg/detail/color_rgba__struct.hpp>
27-
#include <visualization_msgs/msg/detail/marker__struct.hpp>
24+
#include <autoware_planning_msgs/msg/trajectory_point.hpp>
25+
#include <geometry_msgs/msg/point.hpp>
26+
#include <geometry_msgs/msg/pose.hpp>
27+
#include <std_msgs/msg/color_rgba.hpp>
2828
#include <visualization_msgs/msg/marker.hpp>
29+
#include <visualization_msgs/msg/marker_array.hpp>
2930

3031
#include <boost/geometry/algorithms/centroid.hpp>
3132
#include <boost/geometry/algorithms/for_each.hpp>
@@ -36,6 +37,7 @@
3637
#include <lanelet2_core/primitives/Polygon.h>
3738

3839
#include <string>
40+
#include <vector>
3941

4042
namespace autoware::motion_velocity_planner::out_of_lane::debug
4143
{
@@ -151,63 +153,88 @@ size_t add_stop_line_markers(
151153
}
152154
return max_id;
153155
}
154-
} // namespace
155156

156-
visualization_msgs::msg::MarkerArray create_debug_marker_array(
157-
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data,
158-
const autoware_perception_msgs::msg::PredictedObjects & objects, DebugData & debug_data)
157+
void add_out_lanelets(
158+
visualization_msgs::msg::MarkerArray & marker_array, visualization_msgs::msg::Marker base_marker,
159+
const lanelet::ConstLanelets & out_lanelets)
159160
{
160-
const auto z = ego_data.pose.position.z;
161-
visualization_msgs::msg::MarkerArray debug_marker_array;
162-
163-
auto base_marker = get_base_marker();
164-
base_marker.pose.position.z = z + 0.5;
165-
base_marker.ns = "footprints";
166-
base_marker.color = universe_utils::createMarkerColor(1.0, 1.0, 1.0, 1.0);
167-
// TODO(Maxime): move the debug marker publishing AFTER the trajectory generation
168-
// disabled to prevent performance issues when publishing the debug markers
169-
// add_polygons_markers(debug_marker_array, base_marker, ego_data.trajectory_footprints);
170-
171161
lanelet::BasicPolygons2d drivable_lane_polygons;
172-
for (const auto & poly : ego_data.drivable_lane_polygons) {
173-
drivable_lane_polygons.push_back(poly.outer);
162+
for (const auto & ll : out_lanelets) {
163+
drivable_lane_polygons.push_back(ll.polygon2d().basicPolygon());
174164
}
175-
base_marker.ns = "ego_lane";
165+
base_marker.ns = "out_lanelets";
176166
base_marker.color = universe_utils::createMarkerColor(0.0, 0.0, 1.0, 1.0);
177-
add_polygons_markers(debug_marker_array, base_marker, drivable_lane_polygons);
167+
add_polygons_markers(marker_array, base_marker, drivable_lane_polygons);
168+
}
178169

179-
lanelet::BasicPolygons2d out_of_lane_areas;
180-
for (const auto & p : out_of_lane_data.outside_points) {
181-
out_of_lane_areas.push_back(p.outside_ring);
170+
void add_out_of_lane_overlaps(
171+
visualization_msgs::msg::MarkerArray & marker_array, visualization_msgs::msg::Marker base_marker,
172+
const std::vector<OutOfLanePoint> & outside_points,
173+
const std::vector<autoware_planning_msgs::msg::TrajectoryPoint> & trajectory)
174+
{
175+
lanelet::BasicPolygons2d out_of_lane_overlaps;
176+
lanelet::BasicPolygon2d out_of_lane_overlap;
177+
for (const auto & p : outside_points) {
178+
for (const auto & overlap : p.out_overlaps) {
179+
boost::geometry::convert(overlap, out_of_lane_overlap);
180+
out_of_lane_overlaps.push_back(out_of_lane_overlap);
181+
}
182182
}
183183
base_marker.ns = "out_of_lane_areas";
184184
base_marker.color = universe_utils::createMarkerColor(1.0, 0.0, 0.0, 1.0);
185-
add_polygons_markers(debug_marker_array, base_marker, out_of_lane_areas);
186-
for (const auto & [bbox, i] : out_of_lane_data.outside_areas_rtree) {
187-
const auto & a = out_of_lane_data.outside_points[i];
188-
debug_marker_array.markers.back().points.push_back(
189-
ego_data.trajectory_points[a.trajectory_index].pose.position);
190-
const auto centroid = boost::geometry::return_centroid<lanelet::BasicPoint2d>(a.outside_ring);
191-
debug_marker_array.markers.back().points.push_back(
192-
geometry_msgs::msg::Point().set__x(centroid.x()).set__y(centroid.y()));
185+
add_polygons_markers(marker_array, base_marker, out_of_lane_overlaps);
186+
for (const auto & p : outside_points) {
187+
for (const auto & a : p.out_overlaps) {
188+
marker_array.markers.back().points.push_back(trajectory[p.trajectory_index].pose.position);
189+
const auto centroid = boost::geometry::return_centroid<lanelet::BasicPoint2d>(a);
190+
marker_array.markers.back().points.push_back(
191+
geometry_msgs::msg::Point().set__x(centroid.x()).set__y(centroid.y()));
192+
}
193193
}
194-
194+
}
195+
void add_predicted_paths(
196+
visualization_msgs::msg::MarkerArray & marker_array, visualization_msgs::msg::Marker base_marker,
197+
const autoware_perception_msgs::msg::PredictedObjects & objects,
198+
const geometry_msgs::msg::Pose & ego_pose)
199+
{
200+
base_marker.ns = "objects";
201+
base_marker.color = universe_utils::createMarkerColor(0.0, 1.0, 0.0, 1.0);
195202
lanelet::BasicPolygons2d object_polygons;
203+
constexpr double max_draw_distance = 50.0;
196204
for (const auto & o : objects.objects) {
197205
for (const auto & path : o.kinematics.predicted_paths) {
198206
for (const auto & pose : path.path) {
199207
// limit the draw distance to improve performance
200-
if (universe_utils::calcDistance2d(pose, ego_data.pose) < 50.0) {
208+
if (universe_utils::calcDistance2d(pose, ego_pose) < max_draw_distance) {
201209
const auto poly = universe_utils::toPolygon2d(pose, o.shape).outer();
202210
lanelet::BasicPolygon2d ll_poly(poly.begin(), poly.end());
203211
object_polygons.push_back(ll_poly);
204212
}
205213
}
206214
}
207215
}
208-
base_marker.ns = "objects";
209-
base_marker.color = universe_utils::createMarkerColor(0.0, 1.0, 0.0, 1.0);
210-
add_polygons_markers(debug_marker_array, base_marker, object_polygons);
216+
add_polygons_markers(marker_array, base_marker, object_polygons);
217+
}
218+
} // namespace
219+
220+
visualization_msgs::msg::MarkerArray create_debug_marker_array(
221+
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data,
222+
const autoware_perception_msgs::msg::PredictedObjects & objects, DebugData & debug_data)
223+
{
224+
const auto z = ego_data.pose.position.z;
225+
visualization_msgs::msg::MarkerArray debug_marker_array;
226+
227+
auto base_marker = get_base_marker();
228+
base_marker.pose.position.z = z + 0.5;
229+
base_marker.ns = "footprints";
230+
base_marker.color = universe_utils::createMarkerColor(1.0, 1.0, 1.0, 1.0);
231+
// TODO(Maxime): move the debug marker publishing AFTER the trajectory generation
232+
// disabled to prevent performance issues when publishing the debug markers
233+
// add_polygons_markers(debug_marker_array, base_marker, ego_data.trajectory_footprints);
234+
add_out_lanelets(debug_marker_array, base_marker, ego_data.out_lanelets);
235+
add_out_of_lane_overlaps(
236+
debug_marker_array, base_marker, out_of_lane_data.outside_points, ego_data.trajectory_points);
237+
add_predicted_paths(debug_marker_array, base_marker, objects, ego_data.pose);
211238

212239
add_current_overlap_marker(debug_marker_array, ego_data.current_footprint, z);
213240

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/footprint.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#include <geometry_msgs/msg/pose.hpp>
2020

21+
#include <boost/geometry/algorithms/correct.hpp>
22+
2123
#include <lanelet2_core/geometry/Polygon.h>
2224
#include <tf2/utils.h>
2325

@@ -37,6 +39,7 @@ universe_utils::Polygon2d make_base_footprint(const PlannerParam & p, const bool
3739
{p.front_offset + front_offset, p.right_offset - right_offset},
3840
{p.rear_offset - rear_offset, p.right_offset - right_offset},
3941
{p.rear_offset - rear_offset, p.left_offset + left_offset}};
42+
boost::geometry::correct(base_footprint);
4043
return base_footprint;
4144
}
4245

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/lanelets_selection.cpp

+74-42
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,24 @@
1616

1717
#include "types.hpp"
1818

19+
#include <autoware/motion_utils/trajectory/trajectory.hpp>
20+
#include <autoware/universe_utils/geometry/boost_geometry.hpp>
1921
#include <autoware/universe_utils/geometry/geometry.hpp>
2022

23+
#include <boost/geometry/algorithms/buffer.hpp>
2124
#include <boost/geometry/algorithms/disjoint.hpp>
25+
#include <boost/geometry/algorithms/envelope.hpp>
2226
#include <boost/geometry/algorithms/union.hpp>
27+
#include <boost/geometry/strategies/cartesian/buffer_point_square.hpp>
2328

2429
#include <lanelet2_core/Forward.h>
30+
#include <lanelet2_core/LaneletMap.h>
2531
#include <lanelet2_core/geometry/BoundingBox.h>
32+
#include <lanelet2_core/primitives/BoundingBox.h>
2633
#include <lanelet2_routing/RoutingGraph.h>
2734

2835
#include <algorithm>
36+
#include <vector>
2937

3038
namespace autoware::motion_velocity_planner::out_of_lane
3139
{
@@ -77,15 +85,13 @@ lanelet::ConstLanelets get_missing_lane_change_lanelets(
7785
}
7886

7987
lanelet::ConstLanelets calculate_trajectory_lanelets(
80-
const EgoData & ego_data, const route_handler::RouteHandler & route_handler)
88+
const universe_utils::LineString2d & trajectory_ls,
89+
const route_handler::RouteHandler & route_handler)
8190
{
8291
const auto lanelet_map_ptr = route_handler.getLaneletMapPtr();
8392
lanelet::ConstLanelets trajectory_lanelets;
84-
lanelet::BasicLineString2d trajectory_ls;
85-
for (const auto & p : ego_data.trajectory_points)
86-
trajectory_ls.emplace_back(p.pose.position.x, p.pose.position.y);
87-
const auto candidates =
88-
lanelet_map_ptr->laneletLayer.search(lanelet::geometry::boundingBox2d(trajectory_ls));
93+
const auto candidates = lanelet_map_ptr->laneletLayer.search(
94+
boost::geometry::return_envelope<lanelet::BoundingBox2d>(trajectory_ls));
8995
for (const auto & ll : candidates) {
9096
if (
9197
is_road_lanelet(ll) &&
@@ -115,51 +121,77 @@ lanelet::ConstLanelets calculate_ignored_lanelets(
115121
return ignored_lanelets;
116122
}
117123

118-
void calculate_drivable_lane_polygons(
119-
EgoData & ego_data, const route_handler::RouteHandler & route_handler)
124+
lanelet::ConstLanelets calculate_out_lanelets(
125+
const lanelet::LaneletLayer & lanelet_layer,
126+
const universe_utils::MultiPolygon2d & trajectory_footprints,
127+
const lanelet::ConstLanelets & trajectory_lanelets,
128+
const lanelet::ConstLanelets & ignored_lanelets)
120129
{
121-
const auto route_lanelets = calculate_trajectory_lanelets(ego_data, route_handler);
122-
const auto ignored_lanelets =
123-
out_of_lane::calculate_ignored_lanelets(route_lanelets, route_handler);
124-
for (const auto & ll : route_lanelets) {
125-
out_of_lane::Polygons tmp;
126-
boost::geometry::union_(ego_data.drivable_lane_polygons, ll.polygon2d().basicPolygon(), tmp);
127-
ego_data.drivable_lane_polygons = tmp;
128-
}
129-
for (const auto & ll : ignored_lanelets) {
130-
out_of_lane::Polygons tmp;
131-
boost::geometry::union_(ego_data.drivable_lane_polygons, ll.polygon2d().basicPolygon(), tmp);
132-
ego_data.drivable_lane_polygons = tmp;
130+
lanelet::ConstLanelets out_lanelets;
131+
const auto candidates = lanelet_layer.search(
132+
boost::geometry::return_envelope<lanelet::BoundingBox2d>(trajectory_footprints));
133+
for (const auto & lanelet : candidates) {
134+
const auto id = lanelet.id();
135+
if (
136+
contains_lanelet(trajectory_lanelets, id) || contains_lanelet(ignored_lanelets, id) ||
137+
!is_road_lanelet(lanelet)) {
138+
continue;
139+
}
140+
if (!boost::geometry::disjoint(trajectory_footprints, lanelet.polygon2d().basicPolygon())) {
141+
out_lanelets.push_back(lanelet);
142+
}
133143
}
144+
return out_lanelets;
134145
}
135146

136-
void calculate_overlapped_lanelets(
137-
OutOfLanePoint & out_of_lane_point, const route_handler::RouteHandler & route_handler)
147+
OutLaneletRtree calculate_out_lanelet_rtree(const lanelet::ConstLanelets & lanelets)
138148
{
139-
out_of_lane_point.overlapped_lanelets = lanelet::ConstLanelets();
140-
const auto candidates = route_handler.getLaneletMapPtr()->laneletLayer.search(
141-
lanelet::geometry::boundingBox2d(out_of_lane_point.outside_ring));
142-
for (const auto & ll : candidates) {
143-
if (
144-
is_road_lanelet(ll) && !contains_lanelet(out_of_lane_point.overlapped_lanelets, ll.id()) &&
145-
boost::geometry::within(out_of_lane_point.outside_ring, ll.polygon2d().basicPolygon())) {
146-
out_of_lane_point.overlapped_lanelets.push_back(ll);
147-
}
149+
std::vector<LaneletNode> nodes;
150+
nodes.reserve(lanelets.size());
151+
for (auto i = 0UL; i < lanelets.size(); ++i) {
152+
nodes.emplace_back(
153+
boost::geometry::return_envelope<universe_utils::Box2d>(
154+
lanelets[i].polygon2d().basicPolygon()),
155+
i);
148156
}
157+
return {nodes.begin(), nodes.end()};
149158
}
150159

151-
void calculate_overlapped_lanelets(
152-
OutOfLaneData & out_of_lane_data, const route_handler::RouteHandler & route_handler)
160+
void calculate_out_lanelet_rtree(
161+
EgoData & ego_data, const route_handler::RouteHandler & route_handler,
162+
const PlannerParam & params)
153163
{
154-
for (auto it = out_of_lane_data.outside_points.begin();
155-
it != out_of_lane_data.outside_points.end();) {
156-
calculate_overlapped_lanelets(*it, route_handler);
157-
if (it->overlapped_lanelets.empty()) {
158-
// do not keep out of lane points that do not overlap any lanelet
159-
out_of_lane_data.outside_points.erase(it);
160-
} else {
161-
++it;
162-
}
164+
universe_utils::LineString2d trajectory_ls;
165+
for (const auto & p : ego_data.trajectory_points) {
166+
trajectory_ls.emplace_back(p.pose.position.x, p.pose.position.y);
163167
}
168+
// add a point beyond the last trajectory point to account for the ego front offset
169+
const auto pose_beyond = universe_utils::calcOffsetPose(
170+
ego_data.trajectory_points.back().pose, params.front_offset, 0.0, 0.0, 0.0);
171+
trajectory_ls.emplace_back(pose_beyond.position.x, pose_beyond.position.y);
172+
const auto trajectory_lanelets = calculate_trajectory_lanelets(trajectory_ls, route_handler);
173+
const auto ignored_lanelets = calculate_ignored_lanelets(trajectory_lanelets, route_handler);
174+
175+
const auto max_ego_footprint_offset = std::max({
176+
params.front_offset + params.extra_front_offset,
177+
params.left_offset + params.extra_left_offset,
178+
params.right_offset + params.extra_right_offset,
179+
params.rear_offset + params.extra_rear_offset,
180+
});
181+
universe_utils::MultiPolygon2d trajectory_footprints;
182+
const boost::geometry::strategy::buffer::distance_symmetric<double> distance_strategy(
183+
max_ego_footprint_offset);
184+
const boost::geometry::strategy::buffer::join_miter join_strategy;
185+
const boost::geometry::strategy::buffer::end_flat end_strategy;
186+
const boost::geometry::strategy::buffer::point_square circle_strategy;
187+
const boost::geometry::strategy::buffer::side_straight side_strategy;
188+
boost::geometry::buffer(
189+
trajectory_ls, trajectory_footprints, distance_strategy, side_strategy, join_strategy,
190+
end_strategy, circle_strategy);
191+
192+
ego_data.out_lanelets = calculate_out_lanelets(
193+
route_handler.getLaneletMapPtr()->laneletLayer, trajectory_footprints, trajectory_lanelets,
194+
ignored_lanelets);
195+
ego_data.out_lanelets_rtree = calculate_out_lanelet_rtree(ego_data.out_lanelets);
164196
}
165197
} // namespace autoware::motion_velocity_planner::out_of_lane

0 commit comments

Comments
 (0)