Skip to content

Commit c734d1a

Browse files
yield at intersection by making the check conservative
Signed-off-by: Zulfaqar Azmi <zulfaqar.azmi@tier4.jp>
1 parent ed926b3 commit c734d1a

File tree

8 files changed

+149
-0
lines changed

8 files changed

+149
-0
lines changed

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/scene.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class NormalLaneChange : public LaneChangeBase
9898

9999
bool isStoppedAtRedTrafficLight() const override;
100100

101+
bool is_safe_to_try_change_lanes_at_intersection() const final;
102+
101103
protected:
102104
lanelet::ConstLanelets getCurrentLanes() const override;
103105

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/utils/base_class.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class LaneChangeBase
8484

8585
virtual bool isAbortState() const = 0;
8686

87+
virtual bool is_safe_to_try_change_lanes_at_intersection() const = 0;
88+
8789
virtual bool isAbleToReturnCurrentLane() const = 0;
8890

8991
virtual LaneChangePath getLaneChangePath() const = 0;

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/utils/data_structs.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ struct LaneChangeParameters
9393
// lane change parameters
9494
double backward_length_buffer_for_end_of_lane;
9595
double backward_length_buffer_for_blocking_object;
96+
double backward_length_from_intersection{5.0};
9697
double lane_changing_lateral_jerk{0.5};
9798
double minimum_lane_changing_velocity{5.6};
9899
double lane_change_prepare_duration{4.0};

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/utils/path.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <autoware_auto_planning_msgs/msg/path_with_lane_id.hpp>
2323

24+
#include <limits>
2425
#include <vector>
2526

2627
namespace behavior_path_planner
@@ -39,14 +40,19 @@ using LaneChangePaths = std::vector<LaneChangePath>;
3940
struct LaneChangeStatus
4041
{
4142
PathWithLaneId lane_follow_path{};
43+
PathWithLaneId path_after_intersection{};
4244
LaneChangePath lane_change_path{};
4345
lanelet::ConstLanelets current_lanes{};
4446
lanelet::ConstLanelets target_lanes{};
47+
lanelet::ConstLanelet current_lane_{};
4548
std::vector<lanelet::Id> lane_follow_lane_ids{};
4649
std::vector<lanelet::Id> lane_change_lane_ids{};
4750
bool is_safe{false};
4851
bool is_valid_path{true};
52+
bool is_ego_in_turn_direction_lane{false};
53+
bool is_ego_in_intersection{false};
4954
double start_distance{0.0};
55+
double distance_from_prev_intersection{std::numeric_limits<double>::max()};
5056
};
5157

5258
} // namespace behavior_path_planner

planning/behavior_path_lane_change_module/include/behavior_path_lane_change_module/utils/utils.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ using autoware_auto_perception_msgs::msg::PredictedObjects;
4343
using autoware_auto_perception_msgs::msg::PredictedPath;
4444
using autoware_auto_planning_msgs::msg::PathWithLaneId;
4545
using behavior_path_planner::utils::path_safety_checker::ExtendedPredictedObject;
46+
using behavior_path_planner::utils::path_safety_checker::ExtendedPredictedObjects;
4647
using behavior_path_planner::utils::path_safety_checker::PoseWithVelocityAndPolygonStamped;
4748
using behavior_path_planner::utils::path_safety_checker::PoseWithVelocityStamped;
4849
using behavior_path_planner::utils::path_safety_checker::PredictedPathWithPolygon;
@@ -338,5 +339,11 @@ bool has_blocking_target_object(
338339
const lanelet::ConstLanelets & target_lanes, const LaneChangeTargetObjects & filtered_objects,
339340
const LaneChangeParameters & lc_param, const double stop_arc_length, const Pose & ego_pose,
340341
const PathWithLaneId & path);
342+
343+
std::vector<LineString2d> get_line_string_paths(const ExtendedPredictedObject & object);
344+
345+
bool has_overtaking_turn_lane_object(
346+
const lanelet::ConstLanelets & target_lanes, const lanelet::ConstLanelet & ego_current_lane,
347+
const ExtendedPredictedObjects & trailing_objects);
341348
} // namespace behavior_path_planner::utils::lane_change
342349
#endif // BEHAVIOR_PATH_LANE_CHANGE_MODULE__UTILS__UTILS_HPP_

planning/behavior_path_lane_change_module/src/interface.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,15 @@ ModuleStatus LaneChangeInterface::updateState()
120120
module_type_->evaluateApprovedPathWithUnsafeHysteresis(module_type_->isApprovedPathSafe());
121121

122122
setObjectDebugVisualization();
123+
124+
if (
125+
!module_type_->is_safe_to_try_change_lanes_at_intersection() &&
126+
module_type_->isAbleToReturnCurrentLane()) {
127+
RCLCPP_DEBUG(
128+
logger_, "unsafe to try lane change at intersection but able to return to current lane");
129+
return ModuleStatus::SUCCESS;
130+
}
131+
123132
if (is_safe) {
124133
log_warn_throttled("Lane change path is safe.");
125134
module_type_->toNormalState();

planning/behavior_path_lane_change_module/src/scene.cpp

+75
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,51 @@ NormalLaneChange::NormalLaneChange(
5454
void NormalLaneChange::updateLaneChangeStatus()
5555
{
5656
updateStopTime();
57+
status_.current_lanes = getCurrentLanes();
58+
if (status_.current_lanes.empty()) {
59+
return;
60+
}
61+
62+
lanelet::ConstLanelet current_lane;
63+
if (!getRouteHandler()->getClosestLaneletWithinRoute(getEgoPose(), &current_lane)) {
64+
RCLCPP_DEBUG(logger_, "ego's current lane not in route");
65+
return;
66+
}
67+
status_.current_lane_ = current_lane;
68+
69+
const auto ego_footprint =
70+
utils::lane_change::getEgoCurrentFootprint(getEgoPose(), getCommonParam().vehicle_info);
71+
status_.is_ego_in_turn_direction_lane =
72+
utils::lane_change::isWithinTurnDirectionLanes(current_lane, ego_footprint);
73+
status_.is_ego_in_intersection =
74+
utils::lane_change::isWithinIntersection(getRouteHandler(), current_lane, ego_footprint);
75+
76+
if (
77+
status_.is_ego_in_intersection && status_.is_ego_in_turn_direction_lane &&
78+
status_.path_after_intersection.points.empty()) {
79+
const auto target_neighbor =
80+
utils::lane_change::getTargetNeighborLanes(*getRouteHandler(), status_.current_lanes, type_);
81+
status_.path_after_intersection = getRouteHandler()->getCenterLinePath(
82+
target_neighbor, 0.0, std::numeric_limits<double>::max());
83+
status_.distance_from_prev_intersection = 0.0;
84+
}
85+
86+
if (
87+
!status_.is_ego_in_intersection && !status_.is_ego_in_turn_direction_lane &&
88+
!status_.path_after_intersection.points.empty()) {
89+
status_.distance_from_prev_intersection = calcSignedArcLength(
90+
status_.path_after_intersection.points,
91+
status_.path_after_intersection.points.front().point.pose.position, getEgoPosition());
92+
}
93+
94+
if (
95+
!status_.is_ego_in_intersection && !status_.is_ego_in_turn_direction_lane &&
96+
status_.distance_from_prev_intersection >
97+
lane_change_parameters_->backward_length_from_intersection &&
98+
!status_.path_after_intersection.points.empty()) {
99+
status_.path_after_intersection = PathWithLaneId();
100+
status_.distance_from_prev_intersection = std::numeric_limits<double>::max();
101+
}
57102
const auto [found_valid_path, found_safe_path] = getSafePath(status_.lane_change_path);
58103

59104
// Update status
@@ -135,6 +180,24 @@ bool NormalLaneChange::isStoppedAtRedTrafficLight() const
135180
status_.lane_change_path.info.length.sum());
136181
}
137182

183+
bool NormalLaneChange::is_safe_to_try_change_lanes_at_intersection() const
184+
{
185+
if (debug_filtered_objects_.target_lane.empty() || status_.target_lanes.empty()) {
186+
return true;
187+
}
188+
189+
const auto has_overtaking_turn_direction_object =
190+
utils::lane_change::has_overtaking_turn_lane_object(
191+
status_.target_lanes, status_.current_lane_, debug_filtered_objects_.target_lane);
192+
193+
if (!has_overtaking_turn_direction_object) {
194+
return true;
195+
}
196+
197+
return status_.distance_from_prev_intersection >
198+
lane_change_parameters_->backward_length_from_intersection;
199+
}
200+
138201
LaneChangePath NormalLaneChange::getLaneChangePath() const
139202
{
140203
return status_.lane_change_path;
@@ -1372,6 +1435,18 @@ bool NormalLaneChange::getLaneChangePaths(
13721435
}
13731436
candidate_paths->push_back(*candidate_path);
13741437

1438+
if (status_.is_ego_in_intersection && status_.is_ego_in_turn_direction_lane) {
1439+
return false;
1440+
}
1441+
if (
1442+
status_.distance_from_prev_intersection <
1443+
lane_change_parameters_->backward_length_from_intersection &&
1444+
utils::lane_change::has_overtaking_turn_lane_object(
1445+
status_.target_lanes, status_.current_lane_, target_objects.target_lane)) {
1446+
RCLCPP_DEBUG(logger_, "has overtaking object while ego leaves intersection");
1447+
return false;
1448+
}
1449+
13751450
std::vector<ExtendedPredictedObject> filtered_objects =
13761451
filterObjectsInTargetLane(target_objects, target_lanes);
13771452
if (

planning/behavior_path_lane_change_module/src/utils/utils.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -1305,4 +1305,51 @@ bool has_blocking_target_object(
13051305
return (arc_length_to_target_lane_obj - width_margin) >= stop_arc_length;
13061306
});
13071307
}
1308+
1309+
std::vector<LineString2d> get_line_string_paths(const ExtendedPredictedObject & object)
1310+
{
1311+
const auto transform = [](const auto & predicted_path) -> LineString2d {
1312+
LineString2d line_string;
1313+
const auto & path = predicted_path.path;
1314+
line_string.reserve(path.size());
1315+
for (const auto & path_point : path) {
1316+
const auto point = tier4_autoware_utils::fromMsg(path_point.pose.position).to_2d();
1317+
line_string.push_back(point);
1318+
}
1319+
1320+
return line_string;
1321+
};
1322+
1323+
const auto paths = object.predicted_paths;
1324+
std::vector<LineString2d> line_strings;
1325+
std::transform(paths.begin(), paths.end(), std::back_inserter(line_strings), transform);
1326+
1327+
return line_strings;
1328+
}
1329+
1330+
bool has_overtaking_turn_lane_object(
1331+
const lanelet::ConstLanelets & target_lanes, const lanelet::ConstLanelet & ego_current_lane,
1332+
const ExtendedPredictedObjects & trailing_objects)
1333+
{
1334+
const auto target_lane_poly =
1335+
lanelet::utils::combineLaneletsShape(target_lanes).polygon2d().basicPolygon();
1336+
const auto is_overlap_with_target = [&](const LineString2d & path) {
1337+
return !boost::geometry::disjoint(path, target_lane_poly);
1338+
};
1339+
1340+
return std::any_of(
1341+
trailing_objects.begin(), trailing_objects.end(), [&](const ExtendedPredictedObject & object) {
1342+
lanelet::ConstLanelet obj_lane;
1343+
const auto obj_poly =
1344+
tier4_autoware_utils::toPolygon2d(object.initial_pose.pose, object.shape);
1345+
if (!boost::geometry::disjoint(
1346+
obj_poly, utils::toPolygon2d(
1347+
lanelet::utils::to2D(ego_current_lane.polygon2d().basicPolygon())))) {
1348+
return true;
1349+
}
1350+
1351+
const auto paths = get_line_string_paths(object);
1352+
return std::any_of(paths.begin(), paths.end(), is_overlap_with_target);
1353+
});
1354+
}
13081355
} // namespace behavior_path_planner::utils::lane_change

0 commit comments

Comments
 (0)