Skip to content

Commit 33d6fc0

Browse files
authored
feat(out_of_lane): add option to use stop lines defined in the vector map (#9584)
Signed-off-by: Maxime CLEMENT <maxime.clement@tier4.jp>
1 parent eebb4a5 commit 33d6fc0

File tree

11 files changed

+267
-119
lines changed

11 files changed

+267
-119
lines changed

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ Whether it is decided to slow down or stop is determined by the distance between
9191
If this distance is bellow the `actions.slowdown.threshold`, a velocity of `actions.slowdown.velocity` will be used.
9292
If the distance is bellow the `actions.stop.threshold`, a velocity of `0`m/s will be used.
9393

94+
In addition, if parameter `action.use_map_stop_lines` is set to `true`,
95+
then the stop point may be moved to the earliest stop line preceding the stop point where ego can comfortably stop.
96+
Stop lines are defined in the vector map and must be attached to one of the lanelet followed by the ego trajectory.
97+
9498
![avoid_collision](./docs/ttcs_avoid.png)
9599

96100
### About stability of the stop/slowdown pose
@@ -126,6 +130,7 @@ Otherwise, the stop or slowdown pose will only be discarded after no out of lane
126130

127131
| Parameter /action | Type | Description |
128132
| ------------------------------ | ------ | --------------------------------------------------------------------- |
133+
| `use_map_stop_lines` | bool | [-] if true, try to stop at stop lines defined in the vector map |
129134
| `precision` | double | [m] precision when inserting a stop pose in the trajectory |
130135
| `longitudinal_distance_buffer` | double | [m] safety distance buffer to keep in front of the ego vehicle |
131136
| `lateral_distance_buffer` | double | [m] safety distance buffer to keep on the side of the ego vehicle |

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/config/out_of_lane.param.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ignore_behind_ego: false # if true, objects behind the ego vehicle are ignored
1919

2020
action: # action to insert in the trajectory if an object causes a conflict at an overlap
21+
use_map_stop_lines: true # if true, try to stop at stop lines defined in the vector map
2122
precision: 0.1 # [m] precision when inserting a stop pose in the trajectory
2223
longitudinal_distance_buffer: 1.5 # [m] safety distance buffer to keep in front of the ego vehicle
2324
lateral_distance_buffer: 1.0 # [m] safety distance buffer to keep on the side of the ego vehicle

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/calculate_slowdown_points.cpp

+47-24
Original file line numberDiff line numberDiff line change
@@ -84,48 +84,71 @@ std::optional<geometry_msgs::msg::Pose> calculate_pose_ahead_of_collision(
8484
return std::nullopt;
8585
}
8686

87-
std::optional<geometry_msgs::msg::Pose> calculate_slowdown_point(
88-
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data, PlannerParam params)
87+
std::optional<geometry_msgs::msg::Pose> calculate_last_in_lane_pose(
88+
const EgoData & ego_data, const OutOfLanePoint & point_to_avoid, PlannerParam params)
8989
{
90-
const auto point_to_avoid_it = std::find_if(
91-
out_of_lane_data.outside_points.cbegin(), out_of_lane_data.outside_points.cend(),
92-
[&](const auto & p) { return p.to_avoid; });
93-
if (point_to_avoid_it == out_of_lane_data.outside_points.cend()) {
94-
return std::nullopt;
95-
}
90+
std::optional<geometry_msgs::msg::Pose> last_in_lane_pose;
91+
92+
const auto outside_idx = point_to_avoid.trajectory_index;
93+
const auto outside_arc_length =
94+
motion_utils::calcSignedArcLength(ego_data.trajectory_points, 0UL, outside_idx);
95+
9696
const auto raw_footprint = make_base_footprint(params, true); // ignore extra footprint offsets
9797
const auto base_footprint = make_base_footprint(params);
9898
params.extra_front_offset += params.lon_dist_buffer;
9999
params.extra_right_offset += params.lat_dist_buffer;
100100
params.extra_left_offset += params.lat_dist_buffer;
101101
const auto expanded_footprint = make_base_footprint(params); // with added distance buffers
102102
lanelet::BasicPolygons2d polygons_to_avoid;
103-
for (const auto & ll : point_to_avoid_it->overlapped_lanelets) {
103+
for (const auto & ll : point_to_avoid.overlapped_lanelets) {
104104
polygons_to_avoid.push_back(ll.polygon2d().basicPolygon());
105105
}
106-
// points are ordered by trajectory index so the first one has the smallest index and arc length
107-
const auto first_outside_idx = out_of_lane_data.outside_points.front().trajectory_index;
108-
const auto first_outside_arc_length =
109-
motion_utils::calcSignedArcLength(ego_data.trajectory_points, 0UL, first_outside_idx);
110-
111-
std::optional<geometry_msgs::msg::Pose> slowdown_point;
112106
// search for the first slowdown decision for which a stop point can be inserted
113107
// we first try to use the expanded footprint (distance buffers + extra footprint offsets)
114-
for (const auto & footprint : {expanded_footprint, base_footprint, raw_footprint}) {
115-
slowdown_point = calculate_last_avoiding_pose(
116-
ego_data.trajectory_points, footprint, polygons_to_avoid, ego_data.min_stop_arc_length,
117-
first_outside_arc_length, params.precision);
118-
if (slowdown_point) {
108+
// then we use the base footprint (with distance buffers)
109+
// finally, we use the raw footprint
110+
for (const auto & ego_footprint : {expanded_footprint, base_footprint, raw_footprint}) {
111+
last_in_lane_pose = calculate_last_avoiding_pose(
112+
ego_data.trajectory_points, ego_footprint, polygons_to_avoid, ego_data.min_stop_arc_length,
113+
outside_arc_length, params.precision);
114+
if (last_in_lane_pose) {
119115
break;
120116
}
121117
}
122118
// fallback to simply stopping ahead of the collision to avoid (regardless of being out of lane or
123119
// not)
124-
if (!slowdown_point) {
125-
slowdown_point = calculate_pose_ahead_of_collision(
126-
ego_data, *point_to_avoid_it, expanded_footprint, params.precision);
120+
if (!last_in_lane_pose) {
121+
last_in_lane_pose = calculate_pose_ahead_of_collision(
122+
ego_data, point_to_avoid, expanded_footprint, params.precision);
123+
}
124+
return last_in_lane_pose;
125+
}
126+
127+
std::optional<geometry_msgs::msg::Pose> calculate_slowdown_pose(
128+
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data, const PlannerParam & params)
129+
{
130+
// points are ordered by trajectory index so the first one has the smallest index and arc length
131+
const auto point_to_avoid_it = std::find_if(
132+
out_of_lane_data.outside_points.cbegin(), out_of_lane_data.outside_points.cend(),
133+
[&](const auto & p) { return p.to_avoid; });
134+
if (point_to_avoid_it == out_of_lane_data.outside_points.cend()) {
135+
return std::nullopt;
136+
}
137+
auto slowdown_pose = calculate_last_in_lane_pose(ego_data, *point_to_avoid_it, params);
138+
if (slowdown_pose && params.use_map_stop_lines) {
139+
// try to use a map stop line ahead of the stop pose
140+
auto stop_arc_length =
141+
motion_utils::calcSignedArcLength(ego_data.trajectory_points, 0LU, slowdown_pose->position);
142+
for (const auto & stop_point : ego_data.map_stop_points) {
143+
if (
144+
stop_point.ego_trajectory_arc_length < stop_arc_length &&
145+
stop_point.ego_trajectory_arc_length >= ego_data.min_stop_arc_length) {
146+
slowdown_pose = stop_point.ego_stop_pose;
147+
stop_arc_length = stop_point.ego_trajectory_arc_length;
148+
}
149+
}
127150
}
128-
return slowdown_point;
151+
return slowdown_pose;
129152
}
130153

131154
void calculate_min_stop_and_slowdown_distances(

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/calculate_slowdown_points.hpp

+12-14
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,6 @@
2626

2727
namespace autoware::motion_velocity_planner::out_of_lane
2828
{
29-
/// @brief calculate the last pose along the trajectory where ego does not go out of lane
30-
/// @param [in] ego_data ego data
31-
/// @param [in] footprint the ego footprint
32-
/// @param [in] min_arc_length minimum arc length for the search
33-
/// @param [in] max_arc_length maximum arc length for the search
34-
/// @param [in] precision [m] search precision
35-
/// @return the last pose that is not out of lane (if found)
36-
std::optional<geometry_msgs::msg::Pose> calculate_last_in_lane_pose(
37-
const EgoData & ego_data, const autoware_utils::Polygon2d & footprint,
38-
const double min_arc_length, const double max_arc_length, const double precision);
39-
4029
/// @brief calculate the slowdown pose just ahead of a point to avoid
4130
/// @param ego_data ego data (trajectory, velocity, etc)
4231
/// @param point_to_avoid the point to avoid
@@ -47,13 +36,22 @@ std::optional<geometry_msgs::msg::Pose> calculate_pose_ahead_of_collision(
4736
const EgoData & ego_data, const OutOfLanePoint & point_to_avoid,
4837
const autoware_utils::Polygon2d & footprint, const double precision);
4938

39+
/// @brief calculate the last pose staying inside the lane and before the given point
40+
/// @details if no pose staying inside the lane can be found, return a pose before the given point
41+
/// @param [in] ego_data ego data (trajectory)
42+
/// @param [in] point_to_avoid the out of lane point to avoid
43+
/// @param [in] params parameters (ego footprint offsets, precision)
44+
/// @return optional slowdown pose
45+
std::optional<geometry_msgs::msg::Pose> calculate_last_in_lane_pose(
46+
const EgoData & ego_data, const OutOfLanePoint & point_to_avoid, PlannerParam params);
47+
5048
/// @brief calculate the slowdown point to insert in the trajectory
5149
/// @param ego_data ego data (trajectory, velocity, etc)
5250
/// @param out_of_lane_data data about out of lane areas
5351
/// @param params parameters
54-
/// @return optional slowdown point to insert in the trajectory
55-
std::optional<geometry_msgs::msg::Pose> calculate_slowdown_point(
56-
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data, PlannerParam params);
52+
/// @return optional slowdown pose to insert in the trajectory
53+
std::optional<geometry_msgs::msg::Pose> calculate_slowdown_pose(
54+
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data, const PlannerParam & params);
5755

5856
/// @brief calculate the minimum stop and slowdown distances of ego
5957
/// @param [inout] ego_data ego data where minimum stop and slowdown distances are set

planning/motion_velocity_planner/autoware_motion_velocity_out_of_lane_module/src/debug.cpp

+30-3
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ size_t add_stop_line_markers(
123123
{
124124
auto debug_marker = get_base_marker();
125125
debug_marker.type = visualization_msgs::msg::Marker::LINE_STRIP;
126-
debug_marker.ns = "stop_lines";
126+
debug_marker.ns = "object_stop_lines";
127127
const auto & add_lanelets_markers = [&](const auto & lanelets) {
128128
for (const auto & ll : lanelets) {
129129
debug_marker.points.clear();
@@ -155,6 +155,31 @@ size_t add_stop_line_markers(
155155
return max_id;
156156
}
157157

158+
void add_stop_line_markers(
159+
visualization_msgs::msg::MarkerArray & debug_marker_array,
160+
const std::vector<StopPoint> & map_stop_points, const double z)
161+
{
162+
auto debug_marker = get_base_marker();
163+
debug_marker.type = visualization_msgs::msg::Marker::LINE_LIST;
164+
debug_marker.ns = "ego_stop_lines";
165+
debug_marker.scale = autoware_utils::create_marker_scale(0.2, 0.2, 0.2);
166+
debug_marker.color = autoware_utils::create_marker_color(0.5, 0.0, 0.7, 1.0);
167+
geometry_msgs::msg::Point p1;
168+
geometry_msgs::msg::Point p2;
169+
p1.z = p2.z = z;
170+
for (const auto & stop_point : map_stop_points) {
171+
for (auto i = 0UL; i + 1 < stop_point.stop_line.size(); ++i) {
172+
p1.x = stop_point.stop_line[i].x();
173+
p1.y = stop_point.stop_line[i].y();
174+
p2.x = stop_point.stop_line[i + 1].x();
175+
p2.y = stop_point.stop_line[i + 1].y();
176+
debug_marker.points.push_back(p1);
177+
debug_marker.points.push_back(p2);
178+
}
179+
}
180+
debug_marker_array.markers.push_back(debug_marker);
181+
}
182+
158183
void add_out_lanelets(
159184
visualization_msgs::msg::MarkerArray & marker_array, visualization_msgs::msg::Marker base_marker,
160185
const lanelet::ConstLanelets & out_lanelets)
@@ -222,11 +247,11 @@ visualization_msgs::msg::MarkerArray create_debug_marker_array(
222247
const EgoData & ego_data, const OutOfLaneData & out_of_lane_data,
223248
const autoware_perception_msgs::msg::PredictedObjects & objects, DebugData & debug_data)
224249
{
225-
const auto z = ego_data.pose.position.z;
250+
const auto z = ego_data.pose.position.z + 0.5;
226251
visualization_msgs::msg::MarkerArray debug_marker_array;
227252

228253
auto base_marker = get_base_marker();
229-
base_marker.pose.position.z = z + 0.5;
254+
base_marker.pose.position.z = z;
230255
base_marker.ns = "footprints";
231256
base_marker.color = autoware_utils::create_marker_color(1.0, 1.0, 1.0, 1.0);
232257
// TODO(Maxime): move the debug marker publishing AFTER the trajectory generation
@@ -245,6 +270,8 @@ visualization_msgs::msg::MarkerArray create_debug_marker_array(
245270
debug_data.prev_stop_line = add_stop_line_markers(
246271
debug_marker_array, ego_data.stop_lines_rtree, z, debug_data.prev_stop_line);
247272

273+
add_stop_line_markers(debug_marker_array, ego_data.map_stop_points, z);
274+
248275
return debug_marker_array;
249276
}
250277

0 commit comments

Comments
 (0)