Skip to content

Commit 26315fd

Browse files
authored
Merge pull request #1197 from tier4/cherry-pick/pr6599
fix(blind_spot): find collision point using sibling straight lanelet boundary (autowarefoundation#6599)
2 parents 74df650 + 218e457 commit 26315fd

File tree

2 files changed

+52
-68
lines changed

2 files changed

+52
-68
lines changed

planning/behavior_velocity_blind_spot_module/src/scene.cpp

+49-60
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ BlindSpotModule::BlindSpotModule(
6868
const rclcpp::Clock::SharedPtr clock)
6969
: SceneModuleInterface(module_id, logger, clock),
7070
lane_id_(lane_id),
71+
planner_param_{planner_param},
7172
turn_direction_(TurnDirection::INVALID),
7273
is_over_pass_judge_line_(false)
7374
{
7475
velocity_factor_.init(PlanningBehavior::REAR_CHECK);
75-
planner_param_ = planner_param;
7676

7777
const auto & assigned_lanelet =
7878
planner_data->route_handler_->getLaneletMapPtr()->laneletLayer.get(lane_id);
@@ -91,7 +91,7 @@ bool BlindSpotModule::modifyPathVelocity(PathWithLaneId * path, StopReason * sto
9191

9292
const auto input_path = *path;
9393

94-
StateMachine::State current_state = state_machine_.getState();
94+
const auto current_state = state_machine_.getState();
9595
RCLCPP_DEBUG(
9696
logger_, "lane_id = %ld, state = %s", lane_id_, StateMachine::toString(current_state).c_str());
9797

@@ -110,12 +110,8 @@ bool BlindSpotModule::modifyPathVelocity(PathWithLaneId * path, StopReason * sto
110110
}
111111
const auto & interpolated_path_info = interpolated_path_info_opt.value();
112112

113-
if (!first_conflicting_lanelet_) {
114-
first_conflicting_lanelet_ = getFirstConflictingLanelet(interpolated_path_info);
115-
}
116-
if (!first_conflicting_lanelet_) {
117-
RCLCPP_DEBUG(logger_, "[BlindSpotModule::run] failed to find first conflicting lanelet");
118-
return false;
113+
if (!sibling_straight_lanelet_) {
114+
sibling_straight_lanelet_ = getSiblingStraightLanelet();
119115
}
120116

121117
const auto stoplines_idx_opt = generateStopLine(interpolated_path_info, path);
@@ -263,70 +259,37 @@ std::optional<InterpolatedPathInfo> BlindSpotModule::generateInterpolatedPathInf
263259
return interpolated_path_info;
264260
}
265261

266-
std::optional<lanelet::ConstLanelet> BlindSpotModule::getFirstConflictingLanelet(
267-
const InterpolatedPathInfo & interpolated_path_info) const
262+
std::optional<lanelet::ConstLanelet> BlindSpotModule::getSiblingStraightLanelet() const
268263
{
269-
if (!interpolated_path_info.lane_id_interval) {
270-
return std::nullopt;
271-
}
272-
273264
const auto lanelet_map_ptr = planner_data_->route_handler_->getLaneletMapPtr();
274265
const auto routing_graph_ptr = planner_data_->route_handler_->getRoutingGraphPtr();
275266

276267
const auto assigned_lane = lanelet_map_ptr->laneletLayer.get(lane_id_);
277-
const auto conflicting_lanes =
278-
lanelet::utils::getConflictingLanelets(routing_graph_ptr, assigned_lane);
279-
lanelet::ConstLanelets conflicting_ex_sibling_lanes{};
280-
lanelet::ConstLanelets sibling_lanes{};
281268
for (const auto & prev : routing_graph_ptr->previous(assigned_lane)) {
282269
for (const auto & following : routing_graph_ptr->following(prev)) {
283-
if (!lanelet::utils::contains(sibling_lanes, following)) {
284-
sibling_lanes.push_back(following);
285-
}
286-
}
287-
}
288-
for (const auto & conflicting : conflicting_lanes) {
289-
if (!lanelet::utils::contains(sibling_lanes, conflicting)) {
290-
conflicting_ex_sibling_lanes.push_back(conflicting);
291-
}
292-
}
293-
294-
const auto [lane_start, lane_end] = interpolated_path_info.lane_id_interval.value();
295-
const size_t vehicle_length_idx = static_cast<size_t>(
296-
planner_data_->vehicle_info_.max_longitudinal_offset_m / interpolated_path_info.ds);
297-
const size_t start =
298-
static_cast<size_t>(std::max<int>(0, static_cast<int>(lane_start) - vehicle_length_idx));
299-
const auto local_footprint = planner_data_->vehicle_info_.createFootprint(0.0, 0.0);
300-
for (size_t i = start; i <= lane_end; ++i) {
301-
const auto & pose = interpolated_path_info.path.points.at(i).point.pose;
302-
const auto path_footprint = tier4_autoware_utils::transformVector(
303-
local_footprint, tier4_autoware_utils::pose2transform(pose));
304-
for (const auto & conflicting : conflicting_ex_sibling_lanes) {
305-
const auto area2d = conflicting.polygon2d().basicPolygon();
306-
const bool is_in_polygon = bg::intersects(area2d, path_footprint);
307-
if (is_in_polygon) {
308-
return std::make_optional<lanelet::ConstLanelet>(conflicting);
270+
if (std::string(following.attributeOr("turn_direction", "else")) == "straight") {
271+
return following;
309272
}
310273
}
311274
}
312275
return std::nullopt;
313276
}
314277

315-
static std::optional<size_t> getFirstPointInsidePolygonByFootprint(
316-
const lanelet::CompoundPolygon2d & polygon, const InterpolatedPathInfo & interpolated_path_info,
278+
static std::optional<size_t> getFirstPointIntersectsLineByFootprint(
279+
const lanelet::ConstLineString2d & line, const InterpolatedPathInfo & interpolated_path_info,
317280
const tier4_autoware_utils::LinearRing2d & footprint, const double vehicle_length)
318281
{
319282
const auto & path_ip = interpolated_path_info.path;
320283
const auto [lane_start, lane_end] = interpolated_path_info.lane_id_interval.value();
321284
const size_t vehicle_length_idx = static_cast<size_t>(vehicle_length / interpolated_path_info.ds);
322285
const size_t start =
323286
static_cast<size_t>(std::max<int>(0, static_cast<int>(lane_start) - vehicle_length_idx));
324-
const auto area_2d = polygon.basicPolygon();
287+
const auto line2d = line.basicLineString();
325288
for (auto i = start; i <= lane_end; ++i) {
326289
const auto & base_pose = path_ip.points.at(i).point.pose;
327290
const auto path_footprint = tier4_autoware_utils::transformVector(
328291
footprint, tier4_autoware_utils::pose2transform(base_pose));
329-
if (bg::intersects(path_footprint, area_2d)) {
292+
if (bg::intersects(path_footprint, line2d)) {
330293
return std::make_optional<size_t>(i);
331294
}
332295
}
@@ -389,21 +352,47 @@ std::optional<std::pair<size_t, size_t>> BlindSpotModule::generateStopLine(
389352
const int margin_idx_dist =
390353
std::ceil(planner_param_.stop_line_margin / interpolated_path_info.ds);
391354

392-
const auto first_conflict_idx_ip_opt = getFirstPointInsidePolygonByFootprint(
393-
first_conflicting_lanelet_.value().polygon2d(), interpolated_path_info,
394-
planner_data_->vehicle_info_.createFootprint(0.0, 0.0),
395-
planner_data_->vehicle_info_.max_longitudinal_offset_m);
396-
if (!first_conflict_idx_ip_opt) {
397-
return std::nullopt;
398-
}
399-
const int first_conflict_idx_ip = static_cast<int>(first_conflict_idx_ip_opt.value());
355+
const auto & path_ip = interpolated_path_info.path;
400356

401-
const size_t stop_idx_default_ip =
402-
static_cast<size_t>(std::max(first_conflict_idx_ip - margin_idx_dist, 0));
403-
const size_t stop_idx_critical_ip = static_cast<size_t>(first_conflict_idx_ip);
357+
size_t stop_idx_default_ip = 0;
358+
size_t stop_idx_critical_ip = 0;
359+
if (sibling_straight_lanelet_) {
360+
const auto sibling_straight_lanelet = sibling_straight_lanelet_.value();
361+
const auto turn_boundary_line = turn_direction_ == TurnDirection::LEFT
362+
? sibling_straight_lanelet.leftBound()
363+
: sibling_straight_lanelet.rightBound();
364+
const auto first_conflict_idx_ip_opt = getFirstPointIntersectsLineByFootprint(
365+
lanelet::utils::to2D(turn_boundary_line), interpolated_path_info,
366+
planner_data_->vehicle_info_.createFootprint(0.0, 0.0),
367+
planner_data_->vehicle_info_.max_longitudinal_offset_m);
368+
if (!first_conflict_idx_ip_opt) {
369+
return std::nullopt;
370+
}
371+
const int first_conflict_idx_ip = static_cast<int>(first_conflict_idx_ip_opt.value());
372+
373+
stop_idx_default_ip = static_cast<size_t>(std::max(first_conflict_idx_ip - margin_idx_dist, 0));
374+
stop_idx_critical_ip = static_cast<size_t>(first_conflict_idx_ip);
375+
} else {
376+
// the entry point of the assigned lane
377+
const auto & assigned_lanelet =
378+
planner_data_->route_handler_->getLaneletMapPtr()->laneletLayer.get(lane_id_);
379+
const auto left_pt = assigned_lanelet.leftBound().front().basicPoint();
380+
const auto right_pt = assigned_lanelet.rightBound().front().basicPoint();
381+
const auto mid_pt = (left_pt + right_pt) / 2.0;
382+
const geometry_msgs::msg::Point mid_point =
383+
geometry_msgs::build<geometry_msgs::msg::Point>().x(mid_pt.x()).y(mid_pt.y()).z(mid_pt.z());
384+
stop_idx_default_ip = stop_idx_critical_ip =
385+
motion_utils::findNearestSegmentIndex(path_ip.points, mid_point);
386+
/*
387+
// NOTE: it is not ambiguous when the curve starts on the left/right lanelet, so this module
388+
inserts stopline at the beginning of the lanelet for baselink
389+
stop_idx_default_ip = stop_idx_critical_ip = static_cast<size_t>(std::max<int>(0,
390+
static_cast<int>(motion_utils::findNearestSegmentIndex(path_ip.points, mid_point)) -
391+
baselink2front_dist));
392+
*/
393+
}
404394

405395
/* insert stop_point to use interpolated path*/
406-
const auto & path_ip = interpolated_path_info.path;
407396
const auto stopline_idx_default_opt = insertPointIndex(
408397
path_ip.points.at(stop_idx_default_ip).point.pose, path,
409398
planner_data_->ego_nearest_dist_threshold, planner_data_->ego_nearest_yaw_threshold);

planning/behavior_velocity_blind_spot_module/src/scene.hpp

+3-8
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,17 @@ class BlindSpotModule : public SceneModuleInterface
106106

107107
private:
108108
const int64_t lane_id_;
109+
const PlannerParam planner_param_;
109110
TurnDirection turn_direction_{TurnDirection::INVALID};
110111
bool is_over_pass_judge_line_{false};
111-
std::optional<lanelet::ConstLanelet> first_conflicting_lanelet_{std::nullopt};
112+
std::optional<lanelet::ConstLanelet> sibling_straight_lanelet_{std::nullopt};
112113

113114
// Parameter
114-
PlannerParam planner_param_;
115115

116116
std::optional<InterpolatedPathInfo> generateInterpolatedPathInfo(
117117
const autoware_auto_planning_msgs::msg::PathWithLaneId & input_path) const;
118118

119-
std::optional<lanelet::ConstLanelet> getFirstConflictingLanelet(
120-
const InterpolatedPathInfo & interpolated_path_info) const;
121-
122-
std::optional<int> getFirstPointConflictingLanelets(
123-
const InterpolatedPathInfo & interpolated_path_info,
124-
const lanelet::ConstLanelets & lanelets) const;
119+
std::optional<lanelet::ConstLanelet> getSiblingStraightLanelet() const;
125120

126121
/**
127122
* @brief Generate a stop line and insert it into the path.

0 commit comments

Comments
 (0)