Skip to content

Commit 52b2fd6

Browse files
authoredMar 15, 2024··
feat(behavior_path_planner_common): add general method for calculating turn signal for bpp modules (#6625)
add general method for calculating turn signal for bpp modules Signed-off-by: Daniel Sanchez <danielsanchezaran@gmail.com>
1 parent 353a2ec commit 52b2fd6

File tree

4 files changed

+383
-32
lines changed

4 files changed

+383
-32
lines changed
 

‎planning/behavior_path_planner_common/docs/behavior_path_planner_turn_signal_design.md

+32-32
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Turn Signal decider determines necessary blinkers.
44

55
## Purpose / Role
66

7-
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.
7+
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.
88

99
### Assumptions
1010

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

1717
### Limitations
1818

19-
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.
19+
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.
2020

2121
## Parameters for turn signal decider
2222

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

6060
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.
6161

62-
- desired start point
63-
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.
62+
- desired start point
63+
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.
6464

65-
- desired end point
65+
- desired end point
6666
Terminal point of the intersection lanelet.
6767

68-
- required start point
68+
- required start point
6969
Initial point of the intersection lanelet.
7070

71-
- required end point
71+
- required end point
7272
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.
7373

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

8080
First section
8181

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

85-
- desired end point
85+
- desired end point
8686
Shift complete point where the path shift is completed.
8787

88-
- required start point
88+
- required start point
8989
Avoidance start point.
9090

91-
- required end point
91+
- required end point
9292
Shift complete point same as the desired end point.
9393

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

9696
Second section
9797

98-
- desired start point
98+
- desired start point
9999
Shift complete point.
100100

101-
- desired end point
101+
- desired end point
102102
Avoidance terminal point
103103

104-
- required start point
104+
- required start point
105105
Shift complete point.
106106

107-
- required end point
107+
- required end point
108108
Avoidance terminal point.
109109

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

112112
#### 3. Lane Change
113113

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

117-
- desired end point
117+
- desired end point
118118
Terminal point of the lane change path.
119119

120-
- required start point
120+
- required start point
121121
Initial point of the lane change path.
122122

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

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

128128
#### 4. Pull out
129129

130-
- desired start point
130+
- desired start point
131131
Start point of the path of pull out.
132132

133-
- desired end point
133+
- desired end point
134134
Terminal point of the path of pull out.
135135

136-
- required start point
136+
- required start point
137137
Start point of the path pull out.
138138

139-
- required end point
139+
- required end point
140140
Terminal point of the path of pull out.
141141

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

144144
#### 5. Goal Planner
145145

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

149-
- desired end point
149+
- desired end point
150150
Terminal point of the path of pull over.
151151

152-
- required start point
152+
- required start point
153153
Start point of the path of pull over.
154154

155-
- required end point
155+
- required end point
156156
Terminal point of the path of pull over.
157157

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

160160
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.
161161

162-
- pattern1
162+
- pattern1
163163
![pattern1](../images/turn_signal_decider/pattern1.drawio.svg)
164164

165-
- pattern2
165+
- pattern2
166166
![pattern2](../images/turn_signal_decider/pattern2.drawio.svg)
167167

168-
- pattern3
168+
- pattern3
169169
![pattern3](../images/turn_signal_decider/pattern3.drawio.svg)
170170

171-
- pattern4
171+
- pattern4
172172
![pattern4](../images/turn_signal_decider/pattern4.drawio.svg)
173173

174-
- pattern5
174+
- pattern5
175175
![pattern5](../images/turn_signal_decider/pattern5.drawio.svg)
176176

177177
Based on these five rules, turn signal decider can solve `blinker conflicts`. The following pictures show some examples of this kind of conflicts.

‎planning/behavior_path_planner_common/include/behavior_path_planner_common/data_manager.hpp

+57
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "motion_utils/trajectory/trajectory.hpp"
2222

2323
#include <lanelet2_extension/regulatory_elements/Forward.hpp>
24+
#include <lanelet2_extension/utility/utilities.hpp>
2425
#include <rclcpp/rclcpp/clock.hpp>
2526
#include <rclcpp/rclcpp/time.hpp>
2627
#include <route_handler/route_handler.hpp>
@@ -165,6 +166,62 @@ struct PlannerData
165166
mutable std::vector<double> drivable_area_expansion_prev_curvatures{};
166167
mutable TurnSignalDecider turn_signal_decider;
167168

169+
std::pair<TurnSignalInfo, bool> getBehaviorTurnSignalInfo(
170+
const PathWithLaneId & path, const size_t shift_start_idx, const size_t shift_end_idx,
171+
const lanelet::ConstLanelets & current_lanelets, const double current_shift_length,
172+
const bool is_driving_forward, const bool egos_lane_is_shifted,
173+
const bool override_ego_stopped_check = false, const bool is_pull_out = false) const
174+
{
175+
if (shift_start_idx + 1 > path.points.size()) {
176+
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
177+
return std::make_pair(TurnSignalInfo{}, true);
178+
}
179+
180+
if (shift_end_idx + 1 > path.points.size()) {
181+
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
182+
return std::make_pair(TurnSignalInfo{}, true);
183+
}
184+
185+
std::vector<double> lengths(path.points.size(), 0.0);
186+
ShiftedPath shifted_path{path, lengths};
187+
ShiftLine shift_line;
188+
189+
{
190+
const auto start_pose = path.points.at(shift_start_idx).point.pose;
191+
const auto start_shift_length =
192+
lanelet::utils::getArcCoordinates(current_lanelets, start_pose).distance;
193+
const auto end_pose = path.points.at(shift_end_idx).point.pose;
194+
const auto end_shift_length =
195+
lanelet::utils::getArcCoordinates(current_lanelets, end_pose).distance;
196+
shifted_path.shift_length.at(shift_start_idx) = start_shift_length;
197+
shifted_path.shift_length.at(shift_end_idx) = end_shift_length;
198+
199+
shift_line.start = start_pose;
200+
shift_line.end = end_pose;
201+
shift_line.start_shift_length = start_shift_length;
202+
shift_line.end_shift_length = end_shift_length;
203+
shift_line.start_idx = shift_start_idx;
204+
shift_line.end_idx = shift_end_idx;
205+
}
206+
207+
return turn_signal_decider.getBehaviorTurnSignalInfo(
208+
shifted_path, shift_line, current_lanelets, route_handler, parameters, self_odometry,
209+
current_shift_length, is_driving_forward, egos_lane_is_shifted, override_ego_stopped_check,
210+
is_pull_out);
211+
}
212+
213+
std::pair<TurnSignalInfo, bool> getBehaviorTurnSignalInfo(
214+
const ShiftedPath & path, const ShiftLine & shift_line,
215+
const lanelet::ConstLanelets & current_lanelets, const double current_shift_length,
216+
const bool is_driving_forward, const bool egos_lane_is_shifted,
217+
const bool override_ego_stopped_check = false, const bool is_pull_out = false) const
218+
{
219+
return turn_signal_decider.getBehaviorTurnSignalInfo(
220+
path, shift_line, current_lanelets, route_handler, parameters, self_odometry,
221+
current_shift_length, is_driving_forward, egos_lane_is_shifted, override_ego_stopped_check,
222+
is_pull_out);
223+
}
224+
168225
TurnIndicatorsCommand getTurnSignal(
169226
const PathWithLaneId & path, const TurnSignalInfo & turn_signal_info,
170227
TurnSignalDebugData & debug_data)

‎planning/behavior_path_planner_common/include/behavior_path_planner_common/turn_signal_decider.hpp

+146
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,24 @@
1515
#ifndef BEHAVIOR_PATH_PLANNER_COMMON__TURN_SIGNAL_DECIDER_HPP_
1616
#define BEHAVIOR_PATH_PLANNER_COMMON__TURN_SIGNAL_DECIDER_HPP_
1717

18+
#include "tier4_autoware_utils/geometry/boost_polygon_utils.hpp"
19+
1820
#include <behavior_path_planner_common/parameters.hpp>
21+
#include <behavior_path_planner_common/utils/path_shifter/path_shifter.hpp>
22+
#include <lanelet2_extension/utility/message_conversion.hpp>
1923
#include <route_handler/route_handler.hpp>
24+
#include <tier4_autoware_utils/geometry/boost_geometry.hpp>
25+
#include <tier4_autoware_utils/geometry/geometry.hpp>
2026

2127
#include <autoware_auto_planning_msgs/msg/path_with_lane_id.hpp>
2228
#include <autoware_auto_vehicle_msgs/msg/hazard_lights_command.hpp>
2329
#include <autoware_auto_vehicle_msgs/msg/turn_indicators_command.hpp>
30+
#include <nav_msgs/msg/odometry.hpp>
31+
32+
#include <boost/geometry/algorithms/intersects.hpp>
2433

2534
#include <lanelet2_core/Forward.h>
35+
#include <lanelet2_routing/RoutingGraphContainer.h>
2636

2737
#include <limits>
2838
#include <map>
@@ -37,6 +47,7 @@ using autoware_auto_vehicle_msgs::msg::HazardLightsCommand;
3747
using autoware_auto_vehicle_msgs::msg::TurnIndicatorsCommand;
3848
using geometry_msgs::msg::Point;
3949
using geometry_msgs::msg::Pose;
50+
using nav_msgs::msg::Odometry;
4051
using route_handler::RouteHandler;
4152

4253
const std::map<std::string, uint8_t> g_signal_map = {
@@ -100,6 +111,15 @@ class TurnSignalDecider
100111
std::pair<bool, bool> getIntersectionTurnSignalFlag();
101112
std::pair<Pose, double> getIntersectionPoseAndDistance();
102113

114+
std::pair<TurnSignalInfo, bool> getBehaviorTurnSignalInfo(
115+
const ShiftedPath & path, const ShiftLine & shift_line,
116+
const lanelet::ConstLanelets & current_lanelets,
117+
const std::shared_ptr<RouteHandler> route_handler,
118+
const BehaviorPathPlannerParameters & parameters, const Odometry::ConstSharedPtr self_odometry,
119+
const double current_shift_length, const bool is_driving_forward,
120+
const bool egos_lane_is_shifted, const bool override_ego_stopped_check = false,
121+
const bool is_pull_out = false) const;
122+
103123
private:
104124
std::optional<TurnSignalInfo> getIntersectionTurnSignalInfo(
105125
const PathWithLaneId & path, const Pose & current_pose, const double current_vel,
@@ -118,6 +138,132 @@ class TurnSignalDecider
118138
const double nearest_yaw_threshold);
119139
void initialize_intersection_info();
120140

141+
inline bool isAvoidShift(
142+
const double start_shift_length, const double end_shift_length, const double threshold) const
143+
{
144+
return std::abs(start_shift_length) < threshold && std::abs(end_shift_length) > threshold;
145+
};
146+
147+
inline bool isReturnShift(
148+
const double start_shift_length, const double end_shift_length, const double threshold) const
149+
{
150+
return std::abs(start_shift_length) > threshold && std::abs(end_shift_length) < threshold;
151+
};
152+
153+
inline bool isLeftMiddleShift(
154+
const double start_shift_length, const double end_shift_length, const double threshold) const
155+
{
156+
return start_shift_length > threshold && end_shift_length > threshold;
157+
};
158+
159+
inline bool isRightMiddleShift(
160+
const double start_shift_length, const double end_shift_length, const double threshold) const
161+
{
162+
return start_shift_length < threshold && end_shift_length < threshold;
163+
};
164+
165+
inline bool existShiftSideLane(
166+
const double start_shift_length, const double end_shift_length, const bool no_left_lanes,
167+
const bool no_right_lanes, const double threshold) const
168+
{
169+
const auto relative_shift_length = end_shift_length - start_shift_length;
170+
if (isAvoidShift(start_shift_length, end_shift_length, threshold)) {
171+
// Left avoid. But there is no adjacent lane. No need blinker.
172+
if (relative_shift_length > 0.0 && no_left_lanes) {
173+
return false;
174+
}
175+
176+
// Right avoid. But there is no adjacent lane. No need blinker.
177+
if (relative_shift_length < 0.0 && no_right_lanes) {
178+
return false;
179+
}
180+
}
181+
182+
if (isReturnShift(start_shift_length, end_shift_length, threshold)) {
183+
// Right return. But there is no adjacent lane. No need blinker.
184+
if (relative_shift_length > 0.0 && no_right_lanes) {
185+
return false;
186+
}
187+
188+
// Left return. But there is no adjacent lane. No need blinker.
189+
if (relative_shift_length < 0.0 && no_left_lanes) {
190+
return false;
191+
}
192+
}
193+
194+
if (isLeftMiddleShift(start_shift_length, end_shift_length, threshold)) {
195+
// Left avoid. But there is no adjacent lane. No need blinker.
196+
197+
if (relative_shift_length > 0.0 && no_left_lanes) {
198+
return false;
199+
}
200+
201+
// Left return. But there is no adjacent lane. No need blinker.
202+
if (relative_shift_length < 0.0 && no_left_lanes) {
203+
return false;
204+
}
205+
}
206+
207+
if (isRightMiddleShift(start_shift_length, end_shift_length, threshold)) {
208+
// Right avoid. But there is no adjacent lane. No need blinker.
209+
210+
if (relative_shift_length < 0.0 && no_right_lanes) {
211+
return false;
212+
}
213+
214+
// Left avoid. But there is no adjacent lane. No need blinker.
215+
if (relative_shift_length > 0.0 && no_right_lanes) {
216+
return false;
217+
}
218+
}
219+
return true;
220+
};
221+
222+
inline bool straddleRoadBound(
223+
const ShiftedPath & path, const ShiftLine & shift_line, const lanelet::ConstLanelets & lanes,
224+
const vehicle_info_util::VehicleInfo & vehicle_info) const
225+
{
226+
using boost::geometry::intersects;
227+
using tier4_autoware_utils::pose2transform;
228+
using tier4_autoware_utils::transformVector;
229+
230+
const auto footprint = vehicle_info.createFootprint();
231+
232+
for (const auto & lane : lanes) {
233+
for (size_t i = shift_line.start_idx; i < shift_line.end_idx; ++i) {
234+
const auto transform = pose2transform(path.path.points.at(i).point.pose);
235+
const auto shifted_vehicle_footprint = transformVector(footprint, transform);
236+
237+
if (intersects(lane.leftBound2d().basicLineString(), shifted_vehicle_footprint)) {
238+
return true;
239+
}
240+
241+
if (intersects(lane.rightBound2d().basicLineString(), shifted_vehicle_footprint)) {
242+
return true;
243+
}
244+
}
245+
}
246+
247+
return false;
248+
};
249+
250+
inline bool isNearEndOfShift(
251+
const double start_shift_length, const double end_shift_length, const Point & ego_pos,
252+
const lanelet::ConstLanelets & original_lanes, const double threshold) const
253+
{
254+
using boost::geometry::within;
255+
using lanelet::utils::to2D;
256+
using lanelet::utils::conversion::toLaneletPoint;
257+
258+
if (!isReturnShift(start_shift_length, end_shift_length, threshold)) {
259+
return false;
260+
}
261+
262+
return std::any_of(original_lanes.begin(), original_lanes.end(), [&ego_pos](const auto & lane) {
263+
return within(to2D(toLaneletPoint(ego_pos)), lane.polygon2d().basicPolygon());
264+
});
265+
};
266+
121267
geometry_msgs::msg::Quaternion calc_orientation(const Point & src_point, const Point & dst_point);
122268

123269
rclcpp::Logger logger_{

‎planning/behavior_path_planner_common/src/turn_signal_decider.cpp

+148
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
namespace behavior_path_planner
3535
{
36+
using motion_utils::calcSignedArcLength;
37+
3638
double calc_distance(
3739
const PathWithLaneId & path, const Pose & current_pose, const size_t current_seg_idx,
3840
const Pose & input_point, const double nearest_dist_threshold, const double nearest_yaw_threshold)
@@ -43,6 +45,11 @@ double calc_distance(
4345
path.points, current_pose.position, current_seg_idx, input_point.position, nearest_seg_idx);
4446
}
4547

48+
/***
49+
* @brief:
50+
* Gets the turn signal info after comparing the turn signal info output from the behavior path
51+
* module and comparing it to turn signal info obtained from intersections.
52+
*/
4653
TurnIndicatorsCommand TurnSignalDecider::getTurnSignal(
4754
const std::shared_ptr<RouteHandler> & route_handler, const PathWithLaneId & path,
4855
const TurnSignalInfo & turn_signal_info, const Pose & current_pose, const double current_vel,
@@ -606,4 +613,145 @@ geometry_msgs::msg::Quaternion TurnSignalDecider::calc_orientation(
606613
const double yaw = tier4_autoware_utils::calcAzimuthAngle(src_point, dst_point);
607614
return tier4_autoware_utils::createQuaternionFromRPY(0.0, pitch, yaw);
608615
}
616+
617+
std::pair<TurnSignalInfo, bool> TurnSignalDecider::getBehaviorTurnSignalInfo(
618+
const ShiftedPath & path, const ShiftLine & shift_line,
619+
const lanelet::ConstLanelets & current_lanelets,
620+
const std::shared_ptr<RouteHandler> route_handler,
621+
const BehaviorPathPlannerParameters & parameters, const Odometry::ConstSharedPtr self_odometry,
622+
const double current_shift_length, const bool is_driving_forward, const bool egos_lane_is_shifted,
623+
const bool override_ego_stopped_check, const bool is_pull_out) const
624+
{
625+
constexpr double THRESHOLD = 0.1;
626+
const auto & p = parameters;
627+
const auto & rh = route_handler;
628+
const auto & ego_pose = self_odometry->pose.pose;
629+
const auto & ego_speed = self_odometry->twist.twist.linear.x;
630+
631+
if (!is_driving_forward) {
632+
TurnSignalInfo turn_signal_info{};
633+
turn_signal_info.hazard_signal.command = HazardLightsCommand::ENABLE;
634+
const auto back_start_pose = rh->getOriginalStartPose();
635+
const Pose & start_pose = self_odometry->pose.pose;
636+
637+
turn_signal_info.desired_start_point = back_start_pose;
638+
turn_signal_info.required_start_point = back_start_pose;
639+
// pull_out start_pose is same to backward driving end_pose
640+
turn_signal_info.required_end_point = start_pose;
641+
turn_signal_info.desired_end_point = start_pose;
642+
return std::make_pair(turn_signal_info, false);
643+
}
644+
645+
if (shift_line.start_idx + 1 > path.shift_length.size()) {
646+
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
647+
return std::make_pair(TurnSignalInfo{}, true);
648+
}
649+
650+
if (shift_line.start_idx + 1 > path.path.points.size()) {
651+
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
652+
return std::make_pair(TurnSignalInfo{}, true);
653+
}
654+
655+
if (shift_line.end_idx + 1 > path.shift_length.size()) {
656+
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
657+
return std::make_pair(TurnSignalInfo{}, true);
658+
}
659+
660+
if (shift_line.end_idx + 1 > path.path.points.size()) {
661+
RCLCPP_WARN(rclcpp::get_logger(__func__), "index inconsistency.");
662+
return std::make_pair(TurnSignalInfo{}, true);
663+
}
664+
665+
const auto [start_shift_length, end_shift_length] =
666+
std::invoke([&path, &shift_line, &egos_lane_is_shifted]() -> std::pair<double, double> {
667+
const auto temp_start_shift_length = path.shift_length.at(shift_line.start_idx);
668+
const auto temp_end_shift_length = path.shift_length.at(shift_line.end_idx);
669+
// Shift is done using the target lane and not current ego's lane
670+
if (!egos_lane_is_shifted) {
671+
return std::make_pair(temp_end_shift_length, -temp_start_shift_length);
672+
}
673+
return std::make_pair(temp_start_shift_length, temp_end_shift_length);
674+
});
675+
676+
const auto relative_shift_length = end_shift_length - start_shift_length;
677+
678+
// If shift length is shorter than the threshold, it does not need to turn on blinkers
679+
if (std::fabs(relative_shift_length) < p.turn_signal_shift_length_threshold) {
680+
return std::make_pair(TurnSignalInfo{}, true);
681+
}
682+
683+
// If the vehicle does not shift anymore, we turn off the blinker
684+
if (std::fabs(end_shift_length - current_shift_length) < THRESHOLD) {
685+
return std::make_pair(TurnSignalInfo{}, true);
686+
}
687+
688+
const auto get_command = [](const auto & shift_length) {
689+
return shift_length > 0.0 ? TurnIndicatorsCommand::ENABLE_LEFT
690+
: TurnIndicatorsCommand::ENABLE_RIGHT;
691+
};
692+
693+
const auto signal_prepare_distance =
694+
std::max(ego_speed * p.turn_signal_search_time, p.turn_signal_minimum_search_distance);
695+
const auto ego_front_to_shift_start =
696+
calcSignedArcLength(path.path.points, ego_pose.position, shift_line.start_idx) -
697+
p.vehicle_info.max_longitudinal_offset_m;
698+
699+
if (signal_prepare_distance < ego_front_to_shift_start) {
700+
return std::make_pair(TurnSignalInfo{}, false);
701+
}
702+
703+
const auto blinker_start_pose = path.path.points.at(shift_line.start_idx).point.pose;
704+
const auto blinker_end_pose = path.path.points.at(shift_line.end_idx).point.pose;
705+
const auto get_start_pose = [&](const auto & ego_to_shift_start) {
706+
return ego_to_shift_start > 0.0 ? ego_pose : blinker_start_pose;
707+
};
708+
709+
TurnSignalInfo turn_signal_info{};
710+
turn_signal_info.desired_start_point = get_start_pose(ego_front_to_shift_start);
711+
turn_signal_info.desired_end_point = blinker_end_pose;
712+
turn_signal_info.required_start_point = blinker_start_pose;
713+
turn_signal_info.required_end_point = blinker_end_pose;
714+
turn_signal_info.turn_signal.command = get_command(relative_shift_length);
715+
716+
if (!p.turn_signal_on_swerving) {
717+
return std::make_pair(turn_signal_info, false);
718+
}
719+
720+
lanelet::ConstLanelet lanelet;
721+
const auto query_pose = (egos_lane_is_shifted) ? shift_line.end : shift_line.start;
722+
if (!rh->getClosestLaneletWithinRoute(query_pose, &lanelet)) {
723+
return std::make_pair(TurnSignalInfo{}, true);
724+
}
725+
726+
const auto left_same_direction_lane = rh->getLeftLanelet(lanelet, true, true);
727+
const auto left_opposite_lanes = rh->getLeftOppositeLanelets(lanelet);
728+
const auto right_same_direction_lane = rh->getRightLanelet(lanelet, true, true);
729+
const auto right_opposite_lanes = rh->getRightOppositeLanelets(lanelet);
730+
const auto has_left_lane = left_same_direction_lane.has_value() || !left_opposite_lanes.empty();
731+
const auto has_right_lane =
732+
right_same_direction_lane.has_value() || !right_opposite_lanes.empty();
733+
734+
if (
735+
!is_pull_out && !existShiftSideLane(
736+
start_shift_length, end_shift_length, !has_left_lane, !has_right_lane,
737+
p.turn_signal_shift_length_threshold)) {
738+
return std::make_pair(TurnSignalInfo{}, true);
739+
}
740+
741+
if (!straddleRoadBound(path, shift_line, current_lanelets, p.vehicle_info)) {
742+
return std::make_pair(TurnSignalInfo{}, true);
743+
}
744+
745+
constexpr double STOPPED_THRESHOLD = 0.1; // [m/s]
746+
if (ego_speed < STOPPED_THRESHOLD && !override_ego_stopped_check) {
747+
if (isNearEndOfShift(
748+
start_shift_length, end_shift_length, ego_pose.position, current_lanelets,
749+
p.turn_signal_shift_length_threshold)) {
750+
return std::make_pair(TurnSignalInfo{}, true);
751+
}
752+
}
753+
754+
return std::make_pair(turn_signal_info, false);
755+
}
756+
609757
} // namespace behavior_path_planner

0 commit comments

Comments
 (0)
Please sign in to comment.