Skip to content

Commit d8f135f

Browse files
Merge pull request #1092 from tier4/hotfix/v0.20.0/start_planner
feat(start_planner): cherry pick
2 parents 2ea2390 + 60a9691 commit d8f135f

File tree

9 files changed

+443
-84
lines changed

9 files changed

+443
-84
lines changed

planning/behavior_path_planner_common/include/behavior_path_planner_common/utils/parking_departure/common_module_data.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ struct StartGoalPlannerData
4141

4242
Pose refined_start_pose;
4343
std::vector<Pose> start_pose_candidates;
44+
size_t selected_start_pose_candidate_index;
45+
double margin_for_start_pose_candidate;
4446
};
4547

4648
} // namespace behavior_path_planner

planning/behavior_path_start_planner_module/README.md

+72-19
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@
22

33
## Purpose / Role
44

5-
The Start Planner module is designed to generate a path from the current ego position to the driving lane, avoiding static obstacles and implementing safety checks against dynamic obstacles. (Note: The feature of safety checks against dynamic obstacles is currently a work in progress.)
6-
This module is activated when a new route is received.
5+
The Start Planner module is designed to generate a path from the current ego position to the driving lane, avoiding static obstacles and stopping in response to dynamic obstacles when a collision is detected.
76

8-
Use cases are as follows
7+
Use cases include:
98

10-
- start smoothly from the current ego position to centerline.
11-
![case1](./images/start_from_road_lane.drawio.svg)
129
- pull out from the side of the road lane to centerline.
13-
![case2](./images/start_from_road_side.drawio.svg)
10+
11+
<figure markdown>
12+
![case1](images/start_from_road_side.drawio.svg){width=1000}
13+
<figcaption>pull out from side of the road lane</figcaption>
14+
</figure>
15+
1416
- pull out from the shoulder lane to the road lane centerline.
15-
![case3](./images/start_from_road_shoulder.drawio.svg)
17+
18+
<figure markdown>
19+
![case2](images/start_from_start_from_road_shoulder.drawio.svg){width=1000}
20+
<figcaption>pull out from the shoulder lane</figcaption>
21+
</figure>
1622

1723
## Design
1824

@@ -59,18 +65,19 @@ PullOutPath --o PullOutPlannerBase
5965

6066
## General parameters for start_planner
6167

62-
| Name | Unit | Type | Description | Default value |
63-
| :---------------------------------------------------------- | :---- | :----- | :-------------------------------------------------------------------------- | :------------ |
64-
| th_arrived_distance_m | [m] | double | distance threshold for arrival of path termination | 1.0 |
65-
| th_distance_to_middle_of_the_road | [m] | double | distance threshold to determine if the vehicle is on the middle of the road | 0.1 |
66-
| th_stopped_velocity_mps | [m/s] | double | velocity threshold for arrival of path termination | 0.01 |
67-
| th_stopped_time_sec | [s] | double | time threshold for arrival of path termination | 1.0 |
68-
| th_turn_signal_on_lateral_offset | [m] | double | lateral distance threshold for turning on blinker | 1.0 |
69-
| intersection_search_length | [m] | double | check if intersections exist within this length | 30.0 |
70-
| length_ratio_for_turn_signal_deactivation_near_intersection | [m] | double | deactivate turn signal of this module near intersection | 0.5 |
71-
| collision_check_margin | [m] | double | Obstacle collision check margin | 1.0 |
72-
| collision_check_distance_from_end | [m] | double | collision check distance from end point. currently only for pull out | 15.0 |
73-
| center_line_path_interval | [m] | double | reference center line path point interval | 1.0 |
68+
| Name | Unit | Type | Description | Default value |
69+
| :---------------------------------------------------------- | :---- | :------- | :-------------------------------------------------------------------------- | :-------------- |
70+
| th_arrived_distance_m | [m] | double | distance threshold for arrival of path termination | 1.0 |
71+
| th_distance_to_middle_of_the_road | [m] | double | distance threshold to determine if the vehicle is on the middle of the road | 0.1 |
72+
| th_stopped_velocity_mps | [m/s] | double | velocity threshold for arrival of path termination | 0.01 |
73+
| th_stopped_time_sec | [s] | double | time threshold for arrival of path termination | 1.0 |
74+
| th_turn_signal_on_lateral_offset | [m] | double | lateral distance threshold for turning on blinker | 1.0 |
75+
| intersection_search_length | [m] | double | check if intersections exist within this length | 30.0 |
76+
| length_ratio_for_turn_signal_deactivation_near_intersection | [m] | double | deactivate turn signal of this module near intersection | 0.5 |
77+
| collision_check_margins | [m] | [double] | Obstacle collision check margins list | [2.0, 1.5, 1.0] |
78+
| collision_check_distance_from_end | [m] | double | collision check distance from end shift end pose | 1.0 |
79+
| collision_check_margin_from_front_object | [m] | double | collision check margin from front object | 5.0 |
80+
| center_line_path_interval | [m] | double | reference center line path point interval | 1.0 |
7481

7582
## Safety check with static obstacles
7683

@@ -243,6 +250,52 @@ If a safe path cannot be generated from the current position, search backwards f
243250

244251
[pull out after backward driving video](https://user-images.githubusercontent.com/39142679/181025149-8fb9fb51-9b8f-45c4-af75-27572f4fba78.mp4)
245252

253+
### **search priority**
254+
255+
If a safe path with sufficient clearance for static obstacles cannot be generated forward, a backward search from the vehicle's current position is conducted to locate a suitable start point for a pull out path generation.
256+
257+
During this backward search, different policies can be applied based on `search_priority` parameters:
258+
259+
Selecting `efficient_path` focuses on creating a shift pull out path, regardless of how far back the vehicle needs to move.
260+
Opting for `short_back_distance` aims to find a location with the least possible backward movement.
261+
262+
![priority_order](./images/priority_order.drawio.svg)
263+
264+
`PriorityOrder` is defined as a vector of pairs, where each element consists of a `size_t` index representing a start pose candidate index, and the planner type. The PriorityOrder vector is processed sequentially from the beginning, meaning that the pairs listed at the top of the vector are given priority in the selection process for pull out path generation.
265+
266+
#### `efficient_path`
267+
268+
When `search_priority` is set to `efficient_path` and the preference is for prioritizing `shift_pull_out`, the `PriorityOrder` array is populated in such a way that `shift_pull_out` is grouped together for all start pose candidates before moving on to the next planner type. This prioritization is reflected in the order of the array, with `shift_pull_out` being listed before geometric_pull_out.
269+
270+
| Index | Planner Type |
271+
| ----- | ------------------ |
272+
| 0 | shift_pull_out |
273+
| 1 | shift_pull_out |
274+
| ... | ... |
275+
| N | shift_pull_out |
276+
| 0 | geometric_pull_out |
277+
| 1 | geometric_pull_out |
278+
| ... | ... |
279+
| N | geometric_pull_out |
280+
281+
This approach prioritizes trying all candidates with `shift_pull_out` before proceeding to `geometric_pull_out`, which may be efficient in situations where `shift_pull_out` is likely to be appropriate.
282+
283+
#### `short_back_distance`
284+
285+
For `search_priority` set to `short_back_distance`, the array alternates between planner types for each start pose candidate, which can minimize the distance the vehicle needs to move backward if the earlier candidates are successful.
286+
287+
| Index | Planner Type |
288+
| ----- | ------------------ |
289+
| 0 | shift_pull_out |
290+
| 0 | geometric_pull_out |
291+
| 1 | shift_pull_out |
292+
| 1 | geometric_pull_out |
293+
| ... | ... |
294+
| N | shift_pull_out |
295+
| N | geometric_pull_out |
296+
297+
This ordering is beneficial when the priority is to minimize the backward distance traveled, giving an equal chance for each planner to succeed at the closest possible starting position.
298+
246299
### **parameters for backward pull out start point search**
247300

248301
| Name | Unit | Type | Description | Default value |

planning/behavior_path_start_planner_module/config/start_planner.param.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
th_arrived_distance: 1.0
66
th_stopped_velocity: 0.01
77
th_stopped_time: 1.0
8-
collision_check_margin: 1.0
8+
collision_check_margins: [2.0, 1.5, 1.0]
99
collision_check_distance_from_end: 1.0
10+
collision_check_margin_from_front_object: 5.0
1011
th_moving_object_velocity: 1.0
1112
th_distance_to_middle_of_the_road: 0.5
1213
center_line_path_interval: 1.0

planning/behavior_path_start_planner_module/images/priority_order.drawio.svg

+319
Loading

planning/behavior_path_start_planner_module/images/start_from_road_lane.drawio.svg

-34
This file was deleted.

planning/behavior_path_start_planner_module/include/behavior_path_start_planner_module/start_planner_module.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,9 @@ class StartPlannerModule : public SceneModuleInterface
172172
const std::string & search_priority, const size_t start_pose_candidates_num);
173173
bool findPullOutPath(
174174
const Pose & start_pose_candidate, const std::shared_ptr<PullOutPlannerBase> & planner,
175-
const Pose & refined_start_pose, const Pose & goal_pose);
175+
const Pose & refined_start_pose, const Pose & goal_pose, const double collision_check_margin);
176176

177-
PathWithLaneId extractCollisionCheckPath(const PullOutPath & path);
177+
PathWithLaneId extractCollisionCheckSection(const PullOutPath & path);
178178
void updateStatusWithCurrentPath(
179179
const behavior_path_planner::PullOutPath & path, const Pose & start_pose,
180180
const behavior_path_planner::PlannerType & planner_type);

planning/behavior_path_start_planner_module/include/behavior_path_start_planner_module/start_planner_parameters.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ struct StartPlannerParameters
4242
double th_distance_to_middle_of_the_road{0.0};
4343
double intersection_search_length{0.0};
4444
double length_ratio_for_turn_signal_deactivation_near_intersection{0.0};
45-
double collision_check_margin{0.0};
45+
std::vector<double> collision_check_margins{};
4646
double collision_check_distance_from_end{0.0};
47+
double collision_check_margin_from_front_object{0.0};
4748
double th_moving_object_velocity{0.0};
4849
double center_line_path_interval{0.0};
4950

planning/behavior_path_start_planner_module/src/manager.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,12 @@ void StartPlannerModuleManager::init(rclcpp::Node * node)
4343
p.intersection_search_length = node->declare_parameter<double>(ns + "intersection_search_length");
4444
p.length_ratio_for_turn_signal_deactivation_near_intersection = node->declare_parameter<double>(
4545
ns + "length_ratio_for_turn_signal_deactivation_near_intersection");
46-
p.collision_check_margin = node->declare_parameter<double>(ns + "collision_check_margin");
46+
p.collision_check_margins =
47+
node->declare_parameter<std::vector<double>>(ns + "collision_check_margins");
4748
p.collision_check_distance_from_end =
4849
node->declare_parameter<double>(ns + "collision_check_distance_from_end");
50+
p.collision_check_margin_from_front_object =
51+
node->declare_parameter<double>(ns + "collision_check_margin_from_front_object");
4952
p.th_moving_object_velocity = node->declare_parameter<double>(ns + "th_moving_object_velocity");
5053
p.center_line_path_interval = node->declare_parameter<double>(ns + "center_line_path_interval");
5154
// shift pull out

planning/behavior_path_start_planner_module/src/start_planner_module.cpp

+40-26
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,16 @@ void StartPlannerModule::planWithPriority(
585585
const PriorityOrder order_priority =
586586
determinePriorityOrder(search_priority, start_pose_candidates.size());
587587

588-
for (const auto & [index, planner] : order_priority) {
589-
if (findPullOutPath(start_pose_candidates[index], planner, refined_start_pose, goal_pose))
590-
return;
588+
for (const auto & collision_check_margin : parameters_->collision_check_margins) {
589+
for (const auto & [index, planner] : order_priority) {
590+
if (findPullOutPath(
591+
start_pose_candidates[index], planner, refined_start_pose, goal_pose,
592+
collision_check_margin)) {
593+
start_planner_data_.selected_start_pose_candidate_index = index;
594+
start_planner_data_.margin_for_start_pose_candidate = collision_check_margin;
595+
return;
596+
}
597+
}
591598
}
592599

593600
updateStatusIfNoSafePathFound();
@@ -618,7 +625,7 @@ PriorityOrder StartPlannerModule::determinePriorityOrder(
618625

619626
bool StartPlannerModule::findPullOutPath(
620627
const Pose & start_pose_candidate, const std::shared_ptr<PullOutPlannerBase> & planner,
621-
const Pose & refined_start_pose, const Pose & goal_pose)
628+
const Pose & refined_start_pose, const Pose & goal_pose, const double collision_check_margin)
622629
{
623630
const auto & dynamic_objects = planner_data_->dynamic_object;
624631
const auto pull_out_lanes = start_planner_utils::getPullOutLanes(
@@ -645,8 +652,8 @@ bool StartPlannerModule::findPullOutPath(
645652

646653
// check collision
647654
if (utils::checkCollisionBetweenPathFootprintsAndObjects(
648-
vehicle_footprint, extractCollisionCheckPath(*pull_out_path), pull_out_lane_stop_objects,
649-
parameters_->collision_check_margin)) {
655+
vehicle_footprint, extractCollisionCheckSection(*pull_out_path), pull_out_lane_stop_objects,
656+
collision_check_margin)) {
650657
return false;
651658
}
652659

@@ -660,30 +667,28 @@ bool StartPlannerModule::findPullOutPath(
660667
return true;
661668
}
662669

663-
PathWithLaneId StartPlannerModule::extractCollisionCheckPath(const PullOutPath & path)
670+
PathWithLaneId StartPlannerModule::extractCollisionCheckSection(const PullOutPath & path)
664671
{
665672
PathWithLaneId combined_path;
666673
for (const auto & partial_path : path.partial_paths) {
667674
combined_path.points.insert(
668675
combined_path.points.end(), partial_path.points.begin(), partial_path.points.end());
669676
}
670-
671677
// calculate collision check end idx
672-
size_t collision_check_end_idx = 0;
673-
const auto collision_check_end_pose = motion_utils::calcLongitudinalOffsetPose(
674-
combined_path.points, path.end_pose.position, parameters_->collision_check_distance_from_end);
675-
676-
if (collision_check_end_pose) {
677-
collision_check_end_idx =
678-
motion_utils::findNearestIndex(combined_path.points, collision_check_end_pose->position);
679-
}
678+
const size_t collision_check_end_idx = std::invoke([&]() {
679+
const auto collision_check_end_pose = motion_utils::calcLongitudinalOffsetPose(
680+
combined_path.points, path.end_pose.position, parameters_->collision_check_distance_from_end);
680681

682+
if (collision_check_end_pose) {
683+
return motion_utils::findNearestIndex(
684+
combined_path.points, collision_check_end_pose->position);
685+
} else {
686+
return combined_path.points.size() - 1;
687+
}
688+
});
681689
// remove the point behind of collision check end pose
682-
if (collision_check_end_idx + 1 < combined_path.points.size()) {
683-
combined_path.points.erase(
684-
combined_path.points.begin() + collision_check_end_idx + 1, combined_path.points.end());
685-
}
686-
690+
combined_path.points.erase(
691+
combined_path.points.begin() + collision_check_end_idx + 1, combined_path.points.end());
687692
return combined_path;
688693
}
689694

@@ -839,8 +844,10 @@ void StartPlannerModule::updatePullOutStatus()
839844
return {*refined_start_pose};
840845
});
841846

842-
planWithPriority(
843-
start_pose_candidates, *refined_start_pose, goal_pose, parameters_->search_priority);
847+
if (!status_.backward_driving_complete) {
848+
planWithPriority(
849+
start_pose_candidates, *refined_start_pose, goal_pose, parameters_->search_priority);
850+
}
844851

845852
start_planner_data_.refined_start_pose = *refined_start_pose;
846853
start_planner_data_.start_pose_candidates = start_pose_candidates;
@@ -910,6 +917,10 @@ std::vector<Pose> StartPlannerModule::searchPullOutStartPoseCandidates(
910917
pull_out_lanes, start_pose.position, parameters_->th_moving_object_velocity,
911918
backward_path_length, std::numeric_limits<double>::max());
912919

920+
const auto front_stop_objects_in_pull_out_lanes = filterStopObjectsInPullOutLanes(
921+
pull_out_lanes, start_pose.position, parameters_->th_moving_object_velocity, 0,
922+
std::numeric_limits<double>::max());
923+
913924
// Set the maximum backward distance less than the distance from the vehicle's base_link to the
914925
// lane's rearmost point to prevent lane departure.
915926
const double current_arc_length =
@@ -922,9 +933,12 @@ std::vector<Pose> StartPlannerModule::searchPullOutStartPoseCandidates(
922933
back_distance += parameters_->backward_search_resolution) {
923934
const auto backed_pose = calcLongitudinalOffsetPose(
924935
back_path_from_start_pose.points, start_pose.position, -back_distance);
925-
if (!backed_pose) {
936+
if (!backed_pose) continue;
937+
938+
if (utils::checkCollisionBetweenFootprintAndObjects(
939+
local_vehicle_footprint, *backed_pose, front_stop_objects_in_pull_out_lanes,
940+
parameters_->collision_check_margin_from_front_object))
926941
continue;
927-
}
928942

929943
const double backed_pose_arc_length =
930944
lanelet::utils::getArcCoordinates(pull_out_lanes, *backed_pose).length;
@@ -941,7 +955,7 @@ std::vector<Pose> StartPlannerModule::searchPullOutStartPoseCandidates(
941955

942956
if (utils::checkCollisionBetweenFootprintAndObjects(
943957
local_vehicle_footprint, *backed_pose, stop_objects_in_pull_out_lanes,
944-
parameters_->collision_check_margin)) {
958+
parameters_->collision_check_margins.back())) {
945959
break; // poses behind this has a collision, so break.
946960
}
947961

0 commit comments

Comments
 (0)