@@ -352,6 +352,48 @@ std::optional<size_t> IntersectionModule::getStopLineIndexFromMap(
352352 planner_data_->ego_nearest_yaw_threshold );
353353}
354354
355+ std::optional<size_t > IntersectionModule::getFirstAttentionLineFromMap (
356+ const InterpolatedPathInfo & interpolated_path_info,
357+ const lanelet::ConstLanelet & assigned_lanelet, const double ds,
358+ const autoware_utils::LinearRing2d & local_footprint, const double vehicle_length) const
359+ {
360+ const auto & path = interpolated_path_info.path ;
361+ const auto & lane_interval = interpolated_path_info.lane_id_interval .value ();
362+
363+ const auto road_markings =
364+ assigned_lanelet.regulatoryElementsAs <lanelet::autoware::RoadMarking>();
365+ lanelet::ConstLineStrings3d attention_stopline_3d;
366+ for (const auto & road_marking : road_markings) {
367+ const auto & line = road_marking->roadMarking ();
368+ const std::string type = line.attributeOr (lanelet::AttributeName::Type, " none" );
369+ if (type == " custom_intersection_pass_judge_line" ) {
370+ attention_stopline_3d.push_back (line);
371+ break ; // only one stopline exists.
372+ }
373+ }
374+ if (attention_stopline_3d.empty ()) {
375+ return std::nullopt ;
376+ }
377+
378+ const auto p_start = attention_stopline_3d.front ().front ();
379+ const auto p_end = attention_stopline_3d.front ().back ();
380+ const LineString2d stopline = {{p_start.x (), p_start.y ()}, {p_end.x (), p_end.y ()}};
381+ const size_t vehicle_length_idx = static_cast <size_t >(vehicle_length / ds);
382+ const size_t start = static_cast <size_t >(
383+ std::max<int >(0 , static_cast <int >(lane_interval.first ) - vehicle_length_idx));
384+
385+ for (size_t i = start; i <= lane_interval.second && i < path.points .size (); ++i) {
386+ const auto & base_pose = path.points .at (i).point .pose ;
387+ const auto path_footprint =
388+ autoware_utils::transform_vector (local_footprint, autoware_utils::pose2transform (base_pose));
389+ if (bg::intersects (path_footprint, stopline)) {
390+ return static_cast <size_t >(std::max<int >(0 , static_cast <int >(i - 1 )));
391+ }
392+ }
393+
394+ return std::nullopt ;
395+ }
396+
355397std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionStopLines (
356398 lanelet::ConstLanelet assigned_lanelet, const lanelet::CompoundPolygon3d & first_conflicting_area,
357399 const lanelet::ConstLanelet & first_attention_lane,
@@ -373,24 +415,34 @@ std::optional<IntersectionStopLines> IntersectionModule::generateIntersectionSto
373415 const int base2front_idx_dist = std::ceil (baselink2front / ds);
374416
375417 // (1) find the index of the first point whose vehicle footprint on it intersects with
376- // attention_area for the first time
418+ // attention_area for the first time, or use map-defined attention_stop_line if available
377419 const auto local_footprint = planner_data_->vehicle_info_ .createFootprint (0.0 , 0.0 );
420+ const std::optional<size_t > map_first_attention_stopline_ip_opt = getFirstAttentionLineFromMap (
421+ interpolated_path_info, assigned_lanelet, ds, local_footprint, baselink2front);
378422 const std::optional<size_t > first_footprint_inside_1st_attention_ip_opt =
379423 util::getFirstPointInsidePolygonByFootprint (
380424 first_attention_area, interpolated_path_info, local_footprint, baselink2front);
381- if (!first_footprint_inside_1st_attention_ip_opt) {
425+ if (!first_footprint_inside_1st_attention_ip_opt && !map_first_attention_stopline_ip_opt ) {
382426 return std::nullopt ;
383427 }
384- const auto first_attention_stopline_ip = first_footprint_inside_1st_attention_ip_opt.value ();
428+ const auto first_attention_stopline_ip = [&]() -> size_t {
429+ if (map_first_attention_stopline_ip_opt) {
430+ return map_first_attention_stopline_ip_opt.value ();
431+ } else {
432+ return first_footprint_inside_1st_attention_ip_opt.value ();
433+ }
434+ }();
385435
386436 // (2) pass judge line position on interpolated path
387437 const double braking_dist = planning_utils::calcJudgeLineDistWithJerkLimit (
388438 planner_data_->current_velocity ->twist .linear .x ,
389439 planner_data_->current_acceleration ->accel .accel .linear .x , planner_param_.common .max_accel ,
390440 planner_param_.common .max_jerk , 0.0 );
391- int first_pass_judge_ip_int =
392- static_cast <int >(first_attention_stopline_ip) - static_cast <int >(std::ceil (braking_dist / ds)) -
393- static_cast <int >(std::ceil (planner_param_.common .pass_judge_line_margin / ds));
441+ const double pass_judge_line_margin =
442+ map_first_attention_stopline_ip_opt ? 0.0 : planner_param_.common .pass_judge_line_margin ;
443+ int first_pass_judge_ip_int = static_cast <int >(first_attention_stopline_ip) -
444+ static_cast <int >(std::ceil (braking_dist / ds)) -
445+ static_cast <int >(std::ceil (pass_judge_line_margin / ds));
394446 const auto first_pass_judge_line_ip = static_cast <size_t >(
395447 std::clamp<int >(first_pass_judge_ip_int, 0 , static_cast <int >(path_ip.points .size ()) - 1 ));
396448
0 commit comments