Skip to content

Commit 2cba3d4

Browse files
committed
feat(intersection): distinguish 1st/2nd attention lanelet (autowarefoundation#6042)
1 parent f974193 commit 2cba3d4

File tree

3 files changed

+159
-38
lines changed

3 files changed

+159
-38
lines changed

planning/behavior_velocity_intersection_module/src/debug.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,22 @@ visualization_msgs::msg::MarkerArray IntersectionModule::createDebugMarkerArray(
188188
&debug_marker_array);
189189
}
190190

191+
if (debug_data_.first_attention_area) {
192+
appendMarkerArray(
193+
createLaneletPolygonsMarkerArray(
194+
{debug_data_.first_attention_area.value()}, "first_attention_area", lane_id_, 1, 0.647,
195+
0.0),
196+
&debug_marker_array, now);
197+
}
198+
199+
if (debug_data_.second_attention_area) {
200+
appendMarkerArray(
201+
createLaneletPolygonsMarkerArray(
202+
{debug_data_.second_attention_area.value()}, "second_attention_area", lane_id_, 1, 0.647,
203+
0.0),
204+
&debug_marker_array, now);
205+
}
206+
191207
if (debug_data_.stuck_vehicle_detect_area) {
192208
appendMarkerArray(
193209
debug::createPolygonMarkerArray(

planning/behavior_velocity_intersection_module/src/scene_intersection.cpp

+105-32
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,8 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
10081008
getTrafficPrioritizedLevel(assigned_lanelet, planner_data_->traffic_light_id_map);
10091009
const bool is_prioritized =
10101010
traffic_prioritized_level == TrafficPrioritizedLevel::FULLY_PRIORITIZED;
1011-
intersection_lanelets.update(is_prioritized, interpolated_path_info, footprint, baselink2front);
1011+
intersection_lanelets.update(
1012+
is_prioritized, interpolated_path_info, footprint, baselink2front, routing_graph_ptr);
10121013

10131014
// this is abnormal
10141015
const auto & conflicting_lanelets = intersection_lanelets.conflicting();
@@ -1019,6 +1020,7 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
10191020
}
10201021
const auto & first_conflicting_lane = first_conflicting_lane_opt.value();
10211022
const auto & first_conflicting_area = first_conflicting_area_opt.value();
1023+
const auto & second_attention_area_opt = intersection_lanelets.second_attention_area();
10221024

10231025
// generate all stop line candidates
10241026
// see the doc for struct IntersectionStopLines
@@ -1029,16 +1031,20 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
10291031
: first_conflicting_lane;
10301032

10311033
const auto intersection_stoplines_opt = generateIntersectionStopLines(
1032-
assigned_lanelet, first_conflicting_area, dummy_first_attention_lane, interpolated_path_info,
1033-
path);
1034+
assigned_lanelet, first_conflicting_area, dummy_first_attention_lane, second_attention_area_opt,
1035+
interpolated_path_info, path);
10341036
if (!intersection_stoplines_opt) {
10351037
return IntersectionModule::Indecisive{"failed to generate intersection_stoplines"};
10361038
}
10371039
const auto & intersection_stoplines = intersection_stoplines_opt.value();
1038-
const auto
1039-
[closest_idx, stuck_stopline_idx_opt, default_stopline_idx_opt,
1040-
first_attention_stopline_idx_opt, occlusion_peeking_stopline_idx_opt,
1041-
default_pass_judge_line_idx, occlusion_wo_tl_pass_judge_line_idx] = intersection_stoplines;
1040+
const auto closest_idx = intersection_stoplines.closest_idx;
1041+
const auto stuck_stopline_idx_opt = intersection_stoplines.stuck_stopline;
1042+
const auto default_stopline_idx_opt = intersection_stoplines.default_stopline;
1043+
const auto first_attention_stopline_idx_opt = intersection_stoplines.first_attention_stopline;
1044+
const auto occlusion_peeking_stopline_idx_opt = intersection_stoplines.occlusion_peeking_stopline;
1045+
const auto default_pass_judge_line_idx = intersection_stoplines.first_pass_judge_line;
1046+
const auto occlusion_wo_tl_pass_judge_line_idx =
1047+
intersection_stoplines.occlusion_wo_tl_pass_judge_line;
10421048

10431049
// see the doc for struct PathLanelets
10441050
const auto & first_attention_area_opt = intersection_lanelets.first_attention_area();
@@ -1147,6 +1153,8 @@ IntersectionModule::DecisionResult IntersectionModule::modifyPathVelocityDetail(
11471153
debug_data_.attention_area = intersection_lanelets.attention_area();
11481154
debug_data_.occlusion_attention_area = occlusion_attention_area;
11491155
debug_data_.adjacent_area = intersection_lanelets.adjacent_area();
1156+
debug_data_.first_attention_area = intersection_lanelets.first_attention_area();
1157+
debug_data_.second_attention_area = intersection_lanelets.second_attention_area();
11501158

11511159
// check occlusion on detection lane
11521160
if (!occlusion_attention_divisions_) {
@@ -1662,6 +1670,7 @@ IntersectionLanelets IntersectionModule::getObjectiveLanelets(
16621670
std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionStopLines(
16631671
lanelet::ConstLanelet assigned_lanelet, const lanelet::CompoundPolygon3d & first_conflicting_area,
16641672
const lanelet::ConstLanelet & first_attention_lane,
1673+
const std::optional<lanelet::CompoundPolygon3d> & second_attention_area_opt,
16651674
const util::InterpolatedPathInfo & interpolated_path_info,
16661675
autoware_auto_planning_msgs::msg::PathWithLaneId * original_path)
16671676
{
@@ -1683,15 +1692,16 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
16831692
const int base2front_idx_dist =
16841693
std::ceil(planner_data_->vehicle_info_.max_longitudinal_offset_m / ds);
16851694

1686-
// find the index of the first point whose vehicle footprint on it intersects with detection_area
1695+
// find the index of the first point whose vehicle footprint on it intersects with attention_area
16871696
const auto local_footprint = planner_data_->vehicle_info_.createFootprint(0.0, 0.0);
1688-
std::optional<size_t> first_footprint_inside_detection_ip_opt =
1697+
const std::optional<size_t> first_footprint_inside_1st_attention_ip_opt =
16891698
getFirstPointInsidePolygonByFootprint(
16901699
first_attention_area, interpolated_path_info, local_footprint, baselink2front);
1691-
if (!first_footprint_inside_detection_ip_opt) {
1700+
if (!first_footprint_inside_1st_attention_ip_opt) {
16921701
return std::nullopt;
16931702
}
1694-
const auto first_footprint_inside_detection_ip = first_footprint_inside_detection_ip_opt.value();
1703+
const auto first_footprint_inside_1st_attention_ip =
1704+
first_footprint_inside_1st_attention_ip_opt.value();
16951705

16961706
std::optional<size_t> first_footprint_attention_centerline_ip_opt = std::nullopt;
16971707
for (auto i = std::get<0>(lane_interval_ip); i < std::get<1>(lane_interval_ip); ++i) {
@@ -1719,7 +1729,7 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
17191729
stop_idx_ip_int = static_cast<int>(map_stop_idx_ip.value()) - base2front_idx_dist;
17201730
}
17211731
if (stop_idx_ip_int < 0) {
1722-
stop_idx_ip_int = first_footprint_inside_detection_ip - stopline_margin_idx_dist;
1732+
stop_idx_ip_int = first_footprint_inside_1st_attention_ip - stopline_margin_idx_dist;
17231733
}
17241734
if (stop_idx_ip_int < 0) {
17251735
default_stopline_valid = false;
@@ -1735,7 +1745,7 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
17351745
// (3) occlusion peeking stop line position on interpolated path
17361746
int occlusion_peeking_line_ip_int = static_cast<int>(default_stopline_ip);
17371747
bool occlusion_peeking_line_valid = true;
1738-
// NOTE: if footprints[0] is already inside the detection area, invalid
1748+
// NOTE: if footprints[0] is already inside the attention area, invalid
17391749
{
17401750
const auto & base_pose0 = path_ip.points.at(default_stopline_ip).point.pose;
17411751
const auto path_footprint0 = tier4_autoware_utils::transformVector(
@@ -1747,32 +1757,32 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
17471757
}
17481758
if (occlusion_peeking_line_valid) {
17491759
occlusion_peeking_line_ip_int =
1750-
first_footprint_inside_detection_ip + std::ceil(peeking_offset / ds);
1760+
first_footprint_inside_1st_attention_ip + std::ceil(peeking_offset / ds);
17511761
}
1752-
17531762
const auto occlusion_peeking_line_ip = static_cast<size_t>(
17541763
std::clamp<int>(occlusion_peeking_line_ip_int, 0, static_cast<int>(path_ip.points.size()) - 1));
1755-
const auto first_attention_stopline_ip = first_footprint_inside_detection_ip;
1764+
1765+
// (4) first attention stopline position on interpolated path
1766+
const auto first_attention_stopline_ip = first_footprint_inside_1st_attention_ip;
17561767
const bool first_attention_stopline_valid = true;
17571768

1758-
// (4) pass judge line position on interpolated path
1769+
// (5) 1st pass judge line position on interpolated path
17591770
const double velocity = planner_data_->current_velocity->twist.linear.x;
17601771
const double acceleration = planner_data_->current_acceleration->accel.accel.linear.x;
17611772
const double braking_dist = planning_utils::calcJudgeLineDistWithJerkLimit(
17621773
velocity, acceleration, max_accel, max_jerk, delay_response_time);
1763-
int pass_judge_ip_int =
1764-
static_cast<int>(first_footprint_inside_detection_ip) - std::ceil(braking_dist / ds);
1765-
const auto pass_judge_line_ip = static_cast<size_t>(
1766-
std::clamp<int>(pass_judge_ip_int, 0, static_cast<int>(path_ip.points.size()) - 1));
1767-
// TODO(Mamoru Sobue): maybe braking dist should be considered
1768-
const auto occlusion_wo_tl_pass_judge_line_ip =
1769-
static_cast<size_t>(first_footprint_attention_centerline_ip);
1770-
1771-
// (5) stuck vehicle stop line
1774+
int first_pass_judge_ip_int =
1775+
static_cast<int>(first_footprint_inside_1st_attention_ip) - std::ceil(braking_dist / ds);
1776+
const auto first_pass_judge_line_ip = static_cast<size_t>(
1777+
std::clamp<int>(first_pass_judge_ip_int, 0, static_cast<int>(path_ip.points.size()) - 1));
1778+
const auto occlusion_wo_tl_pass_judge_line_ip = static_cast<size_t>(std::max<int>(
1779+
0, static_cast<int>(first_footprint_attention_centerline_ip) - std::ceil(braking_dist / ds)));
1780+
1781+
// (6) stuck vehicle stopline position on interpolated path
17721782
int stuck_stopline_ip_int = 0;
17731783
bool stuck_stopline_valid = true;
17741784
if (use_stuck_stopline) {
1775-
// NOTE: when ego vehicle is approaching detection area and already passed
1785+
// NOTE: when ego vehicle is approaching attention area and already passed
17761786
// first_conflicting_area, this could be null.
17771787
const auto stuck_stopline_idx_ip_opt = getFirstPointInsidePolygonByFootprint(
17781788
first_conflicting_area, interpolated_path_info, local_footprint, baselink2front);
@@ -1791,14 +1801,37 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
17911801
}
17921802
const auto stuck_stopline_ip = static_cast<size_t>(std::max(0, stuck_stopline_ip_int));
17931803

1804+
// (7) second attention stopline position on interpolated path
1805+
int second_attention_stopline_ip_int = -1;
1806+
bool second_attention_stopline_valid = false;
1807+
if (second_attention_area_opt) {
1808+
const auto & second_attention_area = second_attention_area_opt.value();
1809+
std::optional<size_t> first_footprint_inside_2nd_attention_ip_opt =
1810+
getFirstPointInsidePolygonByFootprint(
1811+
second_attention_area, interpolated_path_info, local_footprint, baselink2front);
1812+
if (first_footprint_inside_2nd_attention_ip_opt) {
1813+
second_attention_stopline_ip_int = first_footprint_inside_2nd_attention_ip_opt.value();
1814+
}
1815+
}
1816+
const auto second_attention_stopline_ip =
1817+
second_attention_stopline_ip_int >= 0 ? static_cast<size_t>(second_attention_stopline_ip_int)
1818+
: 0;
1819+
1820+
// (8) second pass judge lie position on interpolated path
1821+
int second_pass_judge_ip_int = second_attention_stopline_ip_int - std::ceil(braking_dist / ds);
1822+
const auto second_pass_judge_line_ip =
1823+
static_cast<size_t>(std::max<int>(second_pass_judge_ip_int, 0));
1824+
17941825
struct IntersectionStopLinesTemp
17951826
{
17961827
size_t closest_idx{0};
17971828
size_t stuck_stopline{0};
17981829
size_t default_stopline{0};
17991830
size_t first_attention_stopline{0};
1831+
size_t second_attention_stopline{0};
18001832
size_t occlusion_peeking_stopline{0};
1801-
size_t pass_judge_line{0};
1833+
size_t first_pass_judge_line{0};
1834+
size_t second_pass_judge_line{0};
18021835
size_t occlusion_wo_tl_pass_judge_line{0};
18031836
};
18041837

@@ -1808,8 +1841,10 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
18081841
{&stuck_stopline_ip, &intersection_stoplines_temp.stuck_stopline},
18091842
{&default_stopline_ip, &intersection_stoplines_temp.default_stopline},
18101843
{&first_attention_stopline_ip, &intersection_stoplines_temp.first_attention_stopline},
1844+
{&second_attention_stopline_ip, &intersection_stoplines_temp.second_attention_stopline},
18111845
{&occlusion_peeking_line_ip, &intersection_stoplines_temp.occlusion_peeking_stopline},
1812-
{&pass_judge_line_ip, &intersection_stoplines_temp.pass_judge_line},
1846+
{&first_pass_judge_line_ip, &intersection_stoplines_temp.first_pass_judge_line},
1847+
{&second_pass_judge_line_ip, &intersection_stoplines_temp.second_pass_judge_line},
18131848
{&occlusion_wo_tl_pass_judge_line_ip,
18141849
&intersection_stoplines_temp.occlusion_wo_tl_pass_judge_line}};
18151850
stoplines.sort(
@@ -1843,11 +1878,17 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
18431878
intersection_stoplines.first_attention_stopline =
18441879
intersection_stoplines_temp.first_attention_stopline;
18451880
}
1881+
if (second_attention_stopline_valid) {
1882+
intersection_stoplines.second_attention_stopline =
1883+
intersection_stoplines_temp.second_attention_stopline;
1884+
}
18461885
if (occlusion_peeking_line_valid) {
18471886
intersection_stoplines.occlusion_peeking_stopline =
18481887
intersection_stoplines_temp.occlusion_peeking_stopline;
18491888
}
1850-
intersection_stoplines.pass_judge_line = intersection_stoplines_temp.pass_judge_line;
1889+
intersection_stoplines.first_pass_judge_line = intersection_stoplines_temp.first_pass_judge_line;
1890+
intersection_stoplines.second_pass_judge_line =
1891+
intersection_stoplines_temp.second_pass_judge_line;
18511892
intersection_stoplines.occlusion_wo_tl_pass_judge_line =
18521893
intersection_stoplines_temp.occlusion_wo_tl_pass_judge_line;
18531894
return intersection_stoplines;
@@ -3252,7 +3293,8 @@ getFirstPointInsidePolygonsByFootprint(
32523293

32533294
void IntersectionLanelets::update(
32543295
const bool is_prioritized, const util::InterpolatedPathInfo & interpolated_path_info,
3255-
const tier4_autoware_utils::LinearRing2d & footprint, const double vehicle_length)
3296+
const tier4_autoware_utils::LinearRing2d & footprint, const double vehicle_length,
3297+
lanelet::routing::RoutingGraphPtr routing_graph_ptr)
32563298
{
32573299
is_prioritized_ = is_prioritized;
32583300
// find the first conflicting/detection area polygon intersecting the path
@@ -3265,13 +3307,44 @@ void IntersectionLanelets::update(
32653307
}
32663308
}
32673309
if (!first_attention_area_) {
3268-
auto first = getFirstPointInsidePolygonsByFootprint(
3310+
const auto first = getFirstPointInsidePolygonsByFootprint(
32693311
attention_non_preceding_area_, interpolated_path_info, footprint, vehicle_length);
32703312
if (first) {
32713313
first_attention_lane_ = attention_non_preceding_.at(first.value().second);
32723314
first_attention_area_ = attention_non_preceding_area_.at(first.value().second);
32733315
}
32743316
}
3317+
if (first_attention_lane_ && !second_attention_lane_ && !second_attention_lane_empty_) {
3318+
const auto first_attention_lane = first_attention_lane_.value();
3319+
// remove first_attention_area_ and non-straight lanelets from attention_non_preceding
3320+
lanelet::ConstLanelets attention_non_preceding_ex_first;
3321+
lanelet::ConstLanelets sibling_first_attention_lanelets;
3322+
for (const auto & previous : routing_graph_ptr->previous(first_attention_lane)) {
3323+
for (const auto & following : routing_graph_ptr->following(previous)) {
3324+
sibling_first_attention_lanelets.push_back(following);
3325+
}
3326+
}
3327+
for (const auto & ll : attention_non_preceding_) {
3328+
// the sibling lanelets of first_attention_lanelet are ruled out
3329+
if (lanelet::utils::contains(sibling_first_attention_lanelets, ll)) {
3330+
continue;
3331+
}
3332+
if (std::string(ll.attributeOr("turn_direction", "else")).compare("straight") == 0) {
3333+
attention_non_preceding_ex_first.push_back(ll);
3334+
}
3335+
}
3336+
if (attention_non_preceding_ex_first.empty()) {
3337+
second_attention_lane_empty_ = true;
3338+
}
3339+
const auto attention_non_preceding_ex_first_area =
3340+
getPolygon3dFromLanelets(attention_non_preceding_ex_first);
3341+
const auto second = getFirstPointInsidePolygonsByFootprint(
3342+
attention_non_preceding_ex_first_area, interpolated_path_info, footprint, vehicle_length);
3343+
if (second) {
3344+
second_attention_lane_ = attention_non_preceding_ex_first.at(second.value().second);
3345+
second_attention_area_ = second_attention_lane_.value().polygon3d();
3346+
}
3347+
}
32753348
}
32763349

32773350
void TargetObject::calc_dist_to_stopline()

0 commit comments

Comments
 (0)