Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(behavior_path_planner_common): add general method for calculating turn signal for bpp modules #6625

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Turn Signal decider determines necessary blinkers.

## Purpose / Role

This module is responsible for activating a necessary blinker during driving. It uses rule-based algorithm to determine blinkers, and the details of this algorithm are described in the following sections. Note that this algorithm is strictly based on the Japanese Road Traffic Raw.
This module is responsible for activating a necessary blinker during driving. It uses rule-based algorithm to determine blinkers, and the details of this algorithm are described in the following sections. Note that this algorithm is strictly based on the Japanese Road Traffic Law.

### Assumptions

Expand All @@ -16,7 +16,7 @@ Autoware has following order of priorities for turn signals.

### Limitations

Currently, this algorithm can sometimes give unnatural (not wrong) blinkers in a complicated situations. This is because it tries to follow the road traffic raw and cannot solve `blinker conflicts` clearly in that environment.
Currently, this algorithm can sometimes give unnatural (not wrong) blinkers in complicated situations. This is because it tries to follow the road traffic law and cannot solve `blinker conflicts` clearly in that environment.

## Parameters for turn signal decider

Expand Down Expand Up @@ -59,16 +59,16 @@ For left turn, right turn, avoidance, lane change, goal planner and pull out, we

Turn signal decider checks each lanelet on the map if it has `turn_direction` information. If a lanelet has this information, it activates necessary blinker based on this information.

- desired start point
The `search_distance` for blinkers at intersections is `v * turn_signal_search_time + turn_signal_intersection_search_distance`. Then the start point becomes `search_distance` meters before the start point of the intersection lanelet(depicted in gree in the following picture), where `v` is the velocity of the ego vehicle. However, if we set `turn_signal_distance` in the lanelet, we use that length as search distance.
- desired start point
The `search_distance` for blinkers at intersections is `v * turn_signal_search_time + turn_signal_intersection_search_distance`. Then the start point becomes `search_distance` meters before the start point of the intersection lanelet(depicted in green in the following picture), where `v` is the velocity of the ego vehicle. However, if we set `turn_signal_distance` in the lanelet, we use that length as search distance.

- desired end point
- desired end point
Terminal point of the intersection lanelet.

- required start point
- required start point
Initial point of the intersection lanelet.

- required end point
- required end point
The earliest point that satisfies the following condition. $\theta - \theta_{\textrm{end}} < \delta$, where $\theta_{\textrm{end}}$ is yaw angle of the terminal point of the lanelet, $\theta$ is the angle of a required end point and $\delta$ is the threshold defined by the user.

![section_turn_signal](../images/turn_signal_decider/left_right_turn.drawio.svg)
Expand All @@ -79,99 +79,99 @@ Avoidance can be separated into two sections, first section and second section.

First section

- desired start point
- desired start point
`v * turn_signal_search_time` meters before the start point of the avoidance shift path.

- desired end point
- desired end point
Shift complete point where the path shift is completed.

- required start point
- required start point
Avoidance start point.

- required end point
- required end point
Shift complete point same as the desired end point.

![section_first_avoidance](../images/turn_signal_decider/avoidance_first_section.drawio.svg)

Second section

- desired start point
- desired start point
Shift complete point.

- desired end point
- desired end point
Avoidance terminal point

- required start point
- required start point
Shift complete point.

- required end point
- required end point
Avoidance terminal point.

![section_second_avoidance](../images/turn_signal_decider/avoidance_second_section.drawio.svg)

#### 3. Lane Change

- desired start point
- desired start point
`v * turn_signal_search_time` meters before the start point of the lane change path.

- desired end point
- desired end point
Terminal point of the lane change path.

- required start point
- required start point
Initial point of the lane change path.

- required end point
- required end point
Cross point with lane change path and boundary line of the adjacent lane.

![section_lane_change](../images/turn_signal_decider/lane_change.drawio.svg)

#### 4. Pull out

- desired start point
- desired start point
Start point of the path of pull out.

- desired end point
- desired end point
Terminal point of the path of pull out.

- required start point
- required start point
Start point of the path pull out.

- required end point
- required end point
Terminal point of the path of pull out.

![section_pull_out](../images/turn_signal_decider/pull_out.drawio.svg)

#### 5. Goal Planner

- desired start point
- desired start point
`v * turn_signal_search_time` meters before the start point of the pull over path.

- desired end point
- desired end point
Terminal point of the path of pull over.

- required start point
- required start point
Start point of the path of pull over.

- required end point
- required end point
Terminal point of the path of pull over.

![section_pull_over](../images/turn_signal_decider/pull_over.drawio.svg)

When it comes to handle several blinkers, it gives priority to the first blinker that comes first. However, this rule sometimes activate unnatural blinkers, so turn signal decider uses the following five rules to decide the necessary turn signal.

- pattern1
- pattern1
![pattern1](../images/turn_signal_decider/pattern1.drawio.svg)

- pattern2
- pattern2
![pattern2](../images/turn_signal_decider/pattern2.drawio.svg)

- pattern3
- pattern3
![pattern3](../images/turn_signal_decider/pattern3.drawio.svg)

- pattern4
- pattern4
![pattern4](../images/turn_signal_decider/pattern4.drawio.svg)

- pattern5
- pattern5
![pattern5](../images/turn_signal_decider/pattern5.drawio.svg)

Based on these five rules, turn signal decider can solve `blinker conflicts`. The following pictures show some examples of this kind of conflicts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "motion_utils/trajectory/trajectory.hpp"

#include <lanelet2_extension/regulatory_elements/Forward.hpp>
#include <lanelet2_extension/utility/utilities.hpp>
#include <rclcpp/rclcpp/clock.hpp>
#include <rclcpp/rclcpp/time.hpp>
#include <route_handler/route_handler.hpp>
Expand Down Expand Up @@ -165,6 +166,62 @@ struct PlannerData
mutable std::vector<double> drivable_area_expansion_prev_curvatures{};
mutable TurnSignalDecider turn_signal_decider;

std::pair<TurnSignalInfo, bool> getBehaviorTurnSignalInfo(
const PathWithLaneId & path, const size_t shift_start_idx, const size_t shift_end_idx,
const lanelet::ConstLanelets & current_lanelets, const double current_shift_length,
const bool is_driving_forward, const bool egos_lane_is_shifted,
const bool override_ego_stopped_check = false, const bool is_pull_out = false) const
{
if (shift_start_idx + 1 > path.points.size()) {
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
return std::make_pair(TurnSignalInfo{}, true);
}

if (shift_end_idx + 1 > path.points.size()) {
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
return std::make_pair(TurnSignalInfo{}, true);
}

std::vector<double> lengths(path.points.size(), 0.0);
ShiftedPath shifted_path{path, lengths};
ShiftLine shift_line;

{
const auto start_pose = path.points.at(shift_start_idx).point.pose;
const auto start_shift_length =
lanelet::utils::getArcCoordinates(current_lanelets, start_pose).distance;
const auto end_pose = path.points.at(shift_end_idx).point.pose;
const auto end_shift_length =
lanelet::utils::getArcCoordinates(current_lanelets, end_pose).distance;
shifted_path.shift_length.at(shift_start_idx) = start_shift_length;
shifted_path.shift_length.at(shift_end_idx) = end_shift_length;

shift_line.start = start_pose;
shift_line.end = end_pose;
shift_line.start_shift_length = start_shift_length;
shift_line.end_shift_length = end_shift_length;
shift_line.start_idx = shift_start_idx;
shift_line.end_idx = shift_end_idx;
}

return turn_signal_decider.getBehaviorTurnSignalInfo(
shifted_path, shift_line, current_lanelets, route_handler, parameters, self_odometry,
current_shift_length, is_driving_forward, egos_lane_is_shifted, override_ego_stopped_check,
is_pull_out);
}

std::pair<TurnSignalInfo, bool> getBehaviorTurnSignalInfo(
const ShiftedPath & path, const ShiftLine & shift_line,
const lanelet::ConstLanelets & current_lanelets, const double current_shift_length,
const bool is_driving_forward, const bool egos_lane_is_shifted,
const bool override_ego_stopped_check = false, const bool is_pull_out = false) const
{
return turn_signal_decider.getBehaviorTurnSignalInfo(
path, shift_line, current_lanelets, route_handler, parameters, self_odometry,
current_shift_length, is_driving_forward, egos_lane_is_shifted, override_ego_stopped_check,
is_pull_out);
}

TurnIndicatorsCommand getTurnSignal(
const PathWithLaneId & path, const TurnSignalInfo & turn_signal_info,
TurnSignalDebugData & debug_data)
Expand Down
Loading
Loading