45 const std::string& config_dir,
46 const std::string& name,
47 const std::shared_ptr<DependencyInjector>& injector) {
52 return Task::LoadConfig<LaneBorrowPathGenericConfig>(&config_);
60 if (!IsNecessaryToBorrowLane()) {
61 decided_side_pass_direction_.clear();
62 auto* mutable_path_decider_status
63 =
injector_->planning_context()->mutable_planning_status()->mutable_path_decider();
64 mutable_path_decider_status->set_left_borrow(
false);
65 mutable_path_decider_status->set_right_borrow(
false);
66 AINFO <<
"No need to borrow lane";
69 std::vector<PathBoundary> candidate_path_boundaries;
70 std::vector<PathData> candidate_path_data;
75 if (!DecidePathBounds(&candidate_path_boundaries)) {
76 AERROR <<
"Failed to decide path boundaries.";
79 if (!OptimizePath(candidate_path_boundaries, &candidate_path_data)) {
80 AERROR <<
"Failed to optimize path.";
83 if (!AssessPath(&candidate_path_data, reference_line_info->
mutable_path_data())) {
84 AERROR <<
"Path assessment failed";
90bool LaneBorrowPathGeneric::DecidePathBounds(std::vector<PathBoundary>* boundary) {
91 AINFO <<
"side pass direction size:" << decided_side_pass_direction_.size();
92 narrowest_width_.clear();
93 for (
size_t i = 0; i < decided_side_pass_direction_.size(); i++) {
94 boundary->emplace_back();
95 auto& path_bound = boundary->back();
96 std::string blocking_obstacle_id =
"";
97 std::string borrow_lane_type =
"";
98 double path_narrowest_width = 0;
101 const std::string msg =
"Failed to initialize path boundaries.";
103 boundary->pop_back();
107 if (!GetBoundaryFromNeighborLane(decided_side_pass_direction_[i], &path_bound, &borrow_lane_type)) {
108 AERROR <<
"Failed to decide a rough boundary based on lane and adc.";
109 boundary->pop_back();
115 AERROR <<
"Failed to decide a rough boundary based on adc.";
116 boundary->pop_back();
122 if (decided_side_pass_direction_[i] == SidePassDirection::LEFT_BORROW) {
123 label =
"regular/left" + borrow_lane_type;
125 label =
"regular/right" + borrow_lane_type;
127 path_bound.set_label(label);
131 AINFO <<
"LaneBorrowPathGeneric, decided_side_pass_direction: " << decided_side_pass_direction_[i]
132 <<
", boundary size: " << path_bound.size() <<
", path_bound start end s: [ " << path_bound.front().s
133 <<
", " << path_bound.back().s <<
"]";
136 LaneBorrowInfo lane_borrow_direction = decided_side_pass_direction_[i] == SidePassDirection::LEFT_BORROW
146 &blocking_obstacle_id,
147 &path_narrowest_width);
151 GetBoundaryFromNudgeDecision(decided_side_pass_direction_[i], &path_bound);
159 while (!blocking_obstacle_id.empty() && path_bound.size() < temp_path_bound.size()
160 && counter < FLAGS_num_extra_tail_bound_point) {
161 path_bound.push_back(temp_path_bound[path_bound.size()]);
166 auto* lane_borrow_status =
injector_->planning_context()->mutable_planning_status()->mutable_lane_borrow();
167 if (!blocking_obstacle_id.empty()) {
169 lane_borrow_status->set_block_obstacle_id(blocking_obstacle_id);
170 if (lane_borrow_status->lane_borrow_block()) {
171 lane_borrow_status->set_block_duration(
172 lane_borrow_status->block_duration() + current_time
173 - lane_borrow_status->last_block_timestamp());
175 lane_borrow_status->set_block_duration(0);
176 lane_borrow_status->set_lane_borrow_block(
true);
178 lane_borrow_status->set_last_block_timestamp(current_time);
180 if (lane_borrow_status->lane_borrow_block()) {
181 lane_borrow_status->set_block_duration(0);
182 lane_borrow_status->set_lane_borrow_block(
false);
183 lane_borrow_status->set_last_block_timestamp(0);
187 ADEBUG <<
"Completed generating path boundaries.";
189 path_bound.set_blocking_obstacle_id(blocking_obstacle_id);
191 narrowest_width_.emplace(label, path_narrowest_width);
193 return !boundary->empty();
196bool LaneBorrowPathGeneric::OptimizePath(
197 const std::vector<PathBoundary>& path_boundaries,
198 std::vector<PathData>* candidate_path_data) {
201 std::array<double, 3> end_state = {0.0, 0.0, 0.0};
203 for (
const auto& path_boundary : path_boundaries) {
204 std::vector<double> opt_l, opt_dl, opt_ddl;
205 std::vector<std::pair<double, double>> ddl_bounds;
208 std::vector<double> ref_l;
209 std::vector<double> weight_ref_l;
210 bool is_left_side_pass = path_boundary.label().find(
"left") != std::string::npos;
212 path_boundary, config.path_reference_l_weight(), &ref_l, &weight_ref_l, is_left_side_pass);
228 opt_l, opt_dl, opt_ddl, path_boundary.delta_s(), path_boundary.start_s());
230 path_data.SetReferenceLine(&reference_line);
231 path_data.SetFrenetPath(std::move(frenet_frame_path));
232 if (FLAGS_use_front_axe_center_in_path_planning) {
233 auto discretized_path
235 path_data.SetDiscretizedPath(discretized_path);
237 path_data.set_path_label(path_boundary.label());
238 path_data.set_blocking_obstacle_id(path_boundary.blocking_obstacle_id());
239 candidate_path_data->push_back(std::move(path_data));
240 AINFO <<
"Lane borrow: path labels [ " << path_boundary.label() <<
" ]";
241 AINFO <<
"dalta s: " << path_boundary.delta_s() <<
", boundary size: " << path_boundary.size()
242 <<
", frenet path size: " << candidate_path_data->back().frenet_frame_path().size();
245 if (candidate_path_data->empty()) {
251bool LaneBorrowPathGeneric::AssessPath(std::vector<PathData>* candidate_path_data, PathData* final_path) {
252 std::vector<PathData> valid_path_data;
253 for (
auto& curr_path_data : *candidate_path_data) {
255 SetPathInfo(&curr_path_data);
259 if (curr_path_data.Empty()) {
260 AINFO <<
"lane borrow path is empty after trimed";
263 valid_path_data.push_back(curr_path_data);
266 if (valid_path_data.empty()) {
267 AINFO <<
"All lane borrow path are not valid";
270 auto* mutable_path_decider_status
271 =
injector_->planning_context()->mutable_planning_status()->mutable_path_decider();
273 if (valid_path_data.size() > 1) {
280 *final_path = valid_path_data[0];
282 *final_path = valid_path_data[1];
285 *final_path = valid_path_data[0];
293bool LaneBorrowPathGeneric::GetBoundaryFromNeighborLane(
295 PathBoundary*
const path_bound,
296 std::string* borrow_lane_type) {
298 CHECK_NOTNULL(path_bound);
299 ACHECK(!path_bound->empty());
302 double offset_to_map = 0;
303 bool borrowing_reverse_lane =
false;
304 reference_line.GetOffsetToMap(
init_sl_state_.first[0], &offset_to_map);
307 double past_lane_left_width = adc_lane_width / 2.0;
308 double past_lane_right_width = adc_lane_width / 2.0;
309 int path_blocked_idx = -1;
310 for (
size_t i = 0; i < path_bound->size(); ++i) {
311 double curr_s = (*path_bound)[i].s;
313 double curr_lane_left_width = 0.0;
314 double curr_lane_right_width = 0.0;
315 double offset_to_lane_center = 0.0;
316 if (!reference_line.GetLaneWidth(curr_s, &curr_lane_left_width, &curr_lane_right_width)) {
317 AWARN <<
"Failed to get lane width at s = " << curr_s;
318 curr_lane_left_width = past_lane_left_width;
319 curr_lane_right_width = past_lane_right_width;
321 reference_line.GetOffsetToMap(curr_s, &offset_to_lane_center);
322 curr_lane_left_width += offset_to_lane_center;
323 curr_lane_right_width -= offset_to_lane_center;
324 past_lane_left_width = curr_lane_left_width;
325 past_lane_right_width = curr_lane_right_width;
328 double curr_neighbor_lane_width = 0.0;
330 hdmap::Id neighbor_lane_id;
331 if (pass_direction == SidePassDirection::LEFT_BORROW) {
337 &curr_neighbor_lane_width)) {
338 ADEBUG <<
"Borrow left forward neighbor lane." << neighbor_lane_id.id();
343 &curr_neighbor_lane_width)) {
344 borrowing_reverse_lane =
true;
345 ADEBUG <<
"Borrow left reverse neighbor lane." << neighbor_lane_id.id();
347 }
else if (pass_direction == SidePassDirection::RIGHT_BORROW) {
353 &curr_neighbor_lane_width)) {
354 ADEBUG <<
"Borrow right forward neighbor lane." << neighbor_lane_id.id();
359 &curr_neighbor_lane_width)) {
360 borrowing_reverse_lane =
true;
361 ADEBUG <<
"Borrow right reverse neighbor lane." << neighbor_lane_id.id();
363 AINFO <<
"There is no right neighbor lane.";
369 double offset_to_map = 0.0;
370 reference_line.GetOffsetToMap(curr_s, &offset_to_map);
372 double curr_left_bound_lane = curr_lane_left_width
373 + (pass_direction == SidePassDirection::LEFT_BORROW ? curr_neighbor_lane_width : 0.0);
375 double curr_right_bound_lane = -curr_lane_right_width
376 - (pass_direction == SidePassDirection::RIGHT_BORROW ? curr_neighbor_lane_width : 0.0);
377 double curr_left_bound = 0.0;
378 double curr_right_bound = 0.0;
379 curr_left_bound = curr_left_bound_lane - offset_to_map;
380 curr_right_bound = curr_right_bound_lane - offset_to_map;
385 path_blocked_idx =
static_cast<int>(i);
387 if (path_blocked_idx != -1) {
392 *borrow_lane_type = borrowing_reverse_lane ?
"reverse" :
"forward";
396bool LaneBorrowPathGeneric::GetBoundaryFromNudgeDecision(
398 PathBoundary*
const path_bound) {
400 bool is_use_nudge_key_points = FLAGS_enable_nudge_decider && nudge_info.is_enable()
401 && nudge_info.extra_nudge_key_points().size() > 1 && nudge_info.extra_nudge_key_points().at(0).size() > 1;
402 if (!is_use_nudge_key_points) {
403 AINFO <<
"GetBoundaryFromNudgeDecision, not use nudge key points";
407 double start_pt_s, end_pt_s;
408 int key_points_index = pass_direction == SidePassDirection::LEFT_BORROW ? 0 : 1;
409 start_pt_s = nudge_info.extra_nudge_key_points().at(key_points_index).front().s();
410 end_pt_s = nudge_info.extra_nudge_key_points().at(key_points_index).back().s();
412 if (pass_direction == SidePassDirection::LEFT_BORROW) {
413 for (
size_t i = 1; i < path_bound->size(); ++i) {
414 auto& left_bound = path_bound->at(i).l_upper;
415 auto& right_bound = path_bound->at(i).l_lower;
416 double check_s = path_bound->at(i).s;
417 if (check_s < start_pt_s) {
419 }
else if (check_s < end_pt_s) {
421 if (nudge_info.GetInterpolatedNudgeL(
true, check_s, &nudge_l)) {
422 right_bound.l = std::max(std::min(nudge_l, left_bound.l), right_bound.l);
423 path_bound->at(i).is_nudge_bound[
RIGHT_INDEX] =
true;
430 for (
size_t i = 1; i < path_bound->size(); ++i) {
431 auto& left_bound = path_bound->at(i).l_upper;
432 auto& right_bound = path_bound->at(i).l_lower;
433 double check_s = path_bound->at(i).s;
434 if (check_s < start_pt_s) {
436 }
else if (check_s < end_pt_s) {
438 if (nudge_info.GetInterpolatedNudgeL(
false, check_s, &nudge_l)) {
439 left_bound.l = std::min(std::max(nudge_l, right_bound.l), left_bound.l);
440 path_bound->at(i).is_nudge_bound[
LEFT_INDEX] =
true;
450void LaneBorrowPathGeneric::UpdateSelfPathInfo() {
452 if (!cur_path.Empty() && cur_path.path_label().find(
"self") != std::string::npos
453 && cur_path.blocking_obstacle_id().empty() && IsNudgeFinish()) {
454 use_self_lane_ = std::max(use_self_lane_ + 1, 0);
455 use_self_lane_ = std::min(use_self_lane_, 10);
457 use_self_lane_ = std::min(use_self_lane_ - 1, 0);
458 use_self_lane_ = std::max(use_self_lane_, -10);
460 blocking_obstacle_id_ = cur_path.blocking_obstacle_id();
463bool LaneBorrowPathGeneric::IsNudgeFinish() {
465 return !nudge_info.is_enable() || nudge_info.extra_nudge_key_points().size() < 2;
468bool LaneBorrowPathGeneric::IsNecessaryToBorrowLane() {
469 auto* mutable_path_decider_status
470 =
injector_->planning_context()->mutable_planning_status()->mutable_path_decider();
471 UpdateSelfPathInfo();
472 is_in_path_lane_borrow_scenario_ = mutable_path_decider_status->is_in_path_lane_borrow_scenario();
473 decided_side_pass_direction_.clear();
474 if (mutable_path_decider_status->left_borrow()) {
475 decided_side_pass_direction_.push_back(SidePassDirection::LEFT_BORROW);
477 if (mutable_path_decider_status->right_borrow()) {
478 decided_side_pass_direction_.push_back(SidePassDirection::RIGHT_BORROW);
480 AINFO <<
"is_in_path_lane_borrow_scenario_: " << is_in_path_lane_borrow_scenario_
481 <<
", use_self_lane_: " << use_self_lane_;
482 if (is_in_path_lane_borrow_scenario_) {
485 bool last_frame_not_in_lane_borrow =
nullptr != last_frame &&
nullptr != last_frame->DriveReferenceLineInfo()
486 && (last_frame->DriveReferenceLineInfo()->path_data().path_label().find(
"lane_change")
487 != std::string::npos);
488 if (use_self_lane_ >= 6 || last_frame_not_in_lane_borrow
492 is_in_path_lane_borrow_scenario_ =
false;
493 decided_side_pass_direction_.clear();
494 AINFO <<
"Switch from LANE-BORROW path to SELF-LANE path.";
498 AINFO <<
"Blocking obstacle ID[" << blocking_obstacle_id_ <<
"]";
505 AINFO <<
"Current referenceline is lane change.";
508 if (!IsWithinSidePassingSpeedADC(*
frame_)) {
509 AINFO <<
"Not IsWithinSidePassingSpeedADC.";
515 AINFO <<
"Not IsBlockingObstacleFarFromIntersection.";
524 AINFO <<
"Not IsBlockingObstacleWithinDestination.";
532 AINFO <<
"Not nudge, no blocking_obstacle_id and not active trigger";
537 AINFO <<
"Not nudge, details in ObstacleNudgeDecider";
542 if (decided_side_pass_direction_.empty()) {
544 bool left_borrowable;
545 bool right_borrowable;
547 if (!left_borrowable && !right_borrowable) {
548 is_in_path_lane_borrow_scenario_ =
false;
549 AINFO <<
"LEFT AND RIGHT LANE CAN NOT BORROW";
552 is_in_path_lane_borrow_scenario_ =
true;
553 if (left_borrowable) {
554 decided_side_pass_direction_.push_back(SidePassDirection::LEFT_BORROW);
555 mutable_path_decider_status->set_left_borrow(
true);
557 if (right_borrowable) {
558 decided_side_pass_direction_.push_back(SidePassDirection::RIGHT_BORROW);
559 mutable_path_decider_status->set_right_borrow(
true);
564 for (
auto& lane_borrow_dir : decided_side_pass_direction_) {
565 AINFO <<
"lane_borrow_dir: " << lane_borrow_dir;
567 AINFO <<
"Switch from SELF-LANE path to LANE-BORROW path.";
569 mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(is_in_path_lane_borrow_scenario_);
570 return is_in_path_lane_borrow_scenario_;
573bool LaneBorrowPathGeneric::HasSingleReferenceLine(
const Frame& frame) {
574 return frame.reference_line_info().size() == 1;
577bool LaneBorrowPathGeneric::IsWithinSidePassingSpeedADC(
const Frame& frame) {
581bool LaneBorrowPathGeneric::IsLongTermBlockingObstacle() {
583 ADEBUG <<
"The blocking obstacle is long-term existing.";
586 ADEBUG <<
"The blocking obstacle is not long-term existing.";
591bool LaneBorrowPathGeneric::IsSidePassableObstacle(
const ReferenceLineInfo& reference_line_info) {
592 const auto& path_decider_status =
injector_->planning_context()->planning_status().path_decider();
593 if (blocking_obstacle_id_.empty()) {
594 AINFO <<
"There is no blocking obstacle.";
597 const Obstacle* blocking_obstacle = reference_line_info.path_decision().obstacles().Find(blocking_obstacle_id_);
598 if (blocking_obstacle ==
nullptr) {
599 AINFO <<
"Blocking obstacle is no longer there.";
606bool LaneBorrowPathGeneric::IsEnableNudge(
const ReferenceLineInfo& reference_line_info) {
607 if (!FLAGS_enable_nudge_decider) {
616 const auto& nudge_info = ParkDataCenter::Instance()->current_nudge_info(reference_line_info.key());
617 if (nudge_info.is_enable() && nudge_info.extra_nudge_key_points().size() > 1) {
618 AINFO <<
"LaneBorrowPathGeneric::IsEnableNudge, Lane Nudge is enable";
624void LaneBorrowPathGeneric::CheckLaneBorrow(
625 const ReferenceLineInfo& reference_line_info,
626 bool* left_neighbor_lane_borrowable,
627 bool* right_neighbor_lane_borrowable) {
628 const ReferenceLine& reference_line = reference_line_info.reference_line();
630 *left_neighbor_lane_borrowable =
true;
631 *right_neighbor_lane_borrowable =
true;
633 static constexpr double kLookforwardDistance = 20.0;
634 double check_s = reference_line_info.AdcSlBoundary().end_s();
635 double lookforward_distance = std::min(check_s + kLookforwardDistance, reference_line.Length());
638 const auto& nudge_info = ParkDataCenter::Instance()->current_nudge_info(reference_line_info.key());
639 if (FLAGS_enable_nudge_decider && nudge_info.is_enable() && nudge_info.extra_nudge_key_points().size() > 1
640 && nudge_info.extra_nudge_key_points().at(0).size() > 1) {
641 double nudge_length = nudge_info.extra_nudge_key_points().at(0).back().s();
642 lookforward_distance = std::max(std::min(lookforward_distance, nudge_length), check_s + 10.0);
645 while (check_s < lookforward_distance) {
646 auto ref_point = reference_line.GetNearestReferencePoint(check_s);
647 if (ref_point.lane_waypoints().empty()) {
648 *left_neighbor_lane_borrowable =
false;
649 *right_neighbor_lane_borrowable =
false;
652 auto ptr_lane_info = reference_line_info.LocateLaneInfo(check_s);
653 if (ptr_lane_info->lane().left_neighbor_forward_lane_id().empty()
654 && ptr_lane_info->lane().left_neighbor_reverse_lane_id().empty()) {
655 *left_neighbor_lane_borrowable =
false;
657 if (ptr_lane_info->lane().right_neighbor_forward_lane_id().empty()
658 && ptr_lane_info->lane().right_neighbor_reverse_lane_id().empty()) {
659 *right_neighbor_lane_borrowable =
false;
663 const auto waypoint = ref_point.lane_waypoints().front();
666 if (*left_neighbor_lane_borrowable) {
671 *left_neighbor_lane_borrowable =
false;
673 AINFO <<
"s[" << check_s <<
"] left_lane_boundary_type["
674 << LaneBoundaryType_Type_Name(lane_boundary_type) <<
"]";
676 if (*right_neighbor_lane_borrowable) {
680 *right_neighbor_lane_borrowable =
false;
682 AINFO <<
"s[" << check_s <<
"] right_neighbor_lane_borrowable["
683 << LaneBoundaryType_Type_Name(lane_boundary_type) <<
"]";
690bool LaneBorrowPathGeneric::CheckLaneBoundaryType(
691 const ReferenceLineInfo& reference_line_info,
692 const double check_s,
694 const ReferenceLine& reference_line = reference_line_info.reference_line();
695 auto ref_point = reference_line.GetNearestReferencePoint(check_s);
696 if (ref_point.lane_waypoints().empty()) {
700 const auto waypoint = ref_point.lane_waypoints().front();
702 if (lane_borrow_info == SidePassDirection::LEFT_BORROW) {
704 }
else if (lane_borrow_info == SidePassDirection::RIGHT_BORROW) {
715void LaneBorrowPathGeneric::SetPathInfo(PathData*
const path_data) {
716 std::vector<PathPointDecision> path_decision;
719 const auto& discrete_path = path_data->discretized_path();
720 bool is_prev_point_out_lane =
false;
721 SLBoundary ego_sl_boundary;
722 for (
size_t i = 0; i < discrete_path.size(); ++i) {
724 ADEBUG <<
"Unable to get SL-boundary of ego-vehicle.";
727 double lane_left_width = 0.0;
728 double lane_right_width = 0.0;
729 double middle_s = (ego_sl_boundary.start_s() + ego_sl_boundary.end_s()) / 2.0;
732 double back_to_inlane_extra_buffer = 0.2;
733 double in_and_out_lane_hysteresis_buffer = is_prev_point_out_lane ? back_to_inlane_extra_buffer : 0.0;
737 if (ego_sl_boundary.end_l() > lane_left_width + in_and_out_lane_hysteresis_buffer
738 || ego_sl_boundary.start_l() < -lane_right_width - in_and_out_lane_hysteresis_buffer) {
739 if (path_data->path_label().find(
"reverse") != std::string::npos) {
741 }
else if (path_data->path_label().find(
"forward") != std::string::npos) {
746 if (!is_prev_point_out_lane) {
747 if (ego_sl_boundary.end_l() > lane_left_width + back_to_inlane_extra_buffer
748 || ego_sl_boundary.start_l() < -lane_right_width - back_to_inlane_extra_buffer) {
749 is_prev_point_out_lane =
true;
755 if (is_prev_point_out_lane) {
756 is_prev_point_out_lane =
false;
761 AERROR <<
"reference line not ready when setting path point guide, middle_s" << middle_s <<
",index" << i
762 <<
"path point" << discrete_path[i].DebugString();
766 path_data->SetPathPointDecisionGuide(std::move(path_decision));
769void LaneBorrowPathGeneric::GetSLPolygons(std::vector<SLPolygon>* polygons,
LaneBorrowInfo lane_borrow_info) {
774 for (
const auto* obstacle : obstacles.Items()) {
784 if (obstacle->PerceptionSLBoundary().end_s() < adc_back_edge_s) {
787 const auto obstacle_sl = obstacle->PerceptionSLBoundary();
789 polygons->emplace_back(obstacle_sl, obstacle->Id(), obstacle->Perception().type());
790 if (nudge_info.NeedCheckObsCollision(obstacle->Id())) {
793 AINFO <<
"Set Obs " << obstacle->Id() <<
", LEFT_NUDGE";
796 AINFO <<
"Set Obs " << obstacle->Id() <<
", RIGHT_NUDGE";
800 sort(polygons->begin(), polygons->end(), [](
const SLPolygon& a,
const SLPolygon& b) {
801 return a.MinS() < b.MinS();
810 const std::unordered_map<std::string, double>& narrowest_width) {
812 static constexpr double kNeighborPathLengthComparisonTolerance = 25.0;
817 if (std::fabs(lhs_path_length - rhs_path_length) > kNeighborPathLengthComparisonTolerance) {
818 return lhs_path_length > rhs_path_length;
825 if (std::abs(lhs_on_reverse - rhs_on_reverse) > 6) {
826 AINFO <<
"ComparePathData, on_reverse: [left, right] : [ " << lhs_on_reverse <<
", " << rhs_on_reverse <<
" ]";
827 return lhs_on_reverse < rhs_on_reverse;
831 if (blocking_obstacle) {
836 ADEBUG <<
"ComparePathData, obstacle " << blocking_obstacle->
Id() <<
", l: " << obstacle_l;
838 ParkDataCenter::Instance()
839 ->current_nudge_info(reference_line_info.
key())
840 .GetFirstBlockSLPolygon(blocking_obstacle->
Id(), &blocking_obstacle_sl_polygon);
841 if (!blocking_obstacle_sl_polygon.
id().empty()) {
842 obstacle_l = (blocking_obstacle_sl_polygon.
MaxL() + blocking_obstacle_sl_polygon.
MinL()) / 2;
843 AINFO <<
"ComparePathData, obstacle in nudge_info " << blocking_obstacle_sl_polygon.
id()
844 <<
", l: " << obstacle_l;
845 if (obstacle_l > 0.3) {
846 return lhs.
path_label().find(
"right") != std::string::npos;
847 }
else if (obstacle_l < -0.3) {
848 return lhs.
path_label().find(
"left") != std::string::npos;
854 AINFO <<
"ComparePathData, adc_l: " << adc_l;
856 AINFO <<
"adc_l < -1.0";
857 return lhs.
path_label().find(
"right") != std::string::npos;
858 }
else if (adc_l > 1.0) {
859 AINFO <<
"adc_l > 1.0";
860 return lhs.
path_label().find(
"left") != std::string::npos;
865 static constexpr double kBackToSelfLaneComparisonTolerance = 20.0;
870 if (std::fabs(lhs_back_s - rhs_back_s) > kBackToSelfLaneComparisonTolerance) {
871 AINFO <<
"ComparePathData, back_idx [ " << lhs_back_idx <<
", " << rhs_back_idx <<
" ], bask_s [ " << lhs_back_s
872 <<
", " << rhs_back_s <<
" ]";
873 return lhs_back_idx < rhs_back_idx;
876 if (narrowest_width.find(lhs.
path_label()) != narrowest_width.end()
877 && narrowest_width.find(rhs.
path_label()) != narrowest_width.end()) {
878 double lhs_w = narrowest_width.at(lhs.
path_label());
879 double rhs_w = narrowest_width.at(rhs.
path_label());
880 if ((lhs_w < 2.0 || rhs_w < 2.0) && std::fabs(lhs_w - rhs_w) > 1.5) {
881 AINFO <<
"ComparePathData, lhs_w: " << lhs_w <<
", rhs_w: " << rhs_w <<
", chose left: " << (lhs_w > rhs_w);
882 return lhs_w > rhs_w;
887 bool lhs_on_leftlane = lhs.
path_label().find(
"left") != std::string::npos;
888 AINFO <<
"ComparePathData, lhs_on_leftlane: " << lhs_on_leftlane;
889 return lhs_on_leftlane;
894 for (
const auto& curr_decision : path_point_decision) {
907 for (
int i =
static_cast<int>(path_point_decision.size()) - 1; i >= 0; --i) {
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
@Brief This is a helper class that can load vehicle configurations.
Rectangular (undirected) bounding box in 2-D.
The class of polygon in 2-D.
Implements a class of 2-dimensional vectors.
static double NowInSeconds()
gets the current time in second.
Frame holds all data for one planning cycle.
const std::list< ReferenceLineInfo > & reference_line_info() const
T * Find(const I id)
Find object by id in the container
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
This is the class that associates an Obstacle with its path properties.
const std::string & Id() const
const SLBoundary & PerceptionSLBoundary() const
static void InitPathPointDecision(const PathData &path_data, const PathData::PathPointType type, std::vector< PathPointDecision > *const path_point_decision)
Init path_point_decision as type
static void TrimTailingOutLanePoints(PathData *const path_data)
Trim the points at tail of path which away from lane
static bool IsValidRegularPath(const ReferenceLineInfo &reference_line_info, const PathData &path_data)
Check if the generated path is valid
static bool UpdatePathBoundaryBySLPolygon(const ReferenceLineInfo &reference_line_info, std::vector< SLPolygon > *const sl_polygon, const SLState &init_sl_state, PathBoundary *const path_boundary, std::string *const blocked_id, double *const narrowest_width)
static bool ExtendBoundaryByADC(const ReferenceLineInfo &reference_line_info, const SLState &init_sl_state, const double extend_buffer, PathBoundary *const path_bound)
extend boundary to include adc
static bool AddExtraPathBound(const std::vector< SLPolygon > &sl_polygons, PathBoundary *const path_boundary, const SLState &init_sl_state, std::string *const blocked_id)
static void TrimPathBounds(const int path_blocked_idx, PathBoundary *const path_boundaries)
static bool UpdatePathBoundaryWithBuffer(double left_bound, double right_bound, BoundType left_type, BoundType right_type, std::string left_id, std::string right_id, PathBoundPoint *const bound_point)
Update the path_boundary at "idx" It also checks if ADC is blocked (lmax < lmin).
static double GetADCLaneWidth(const ReferenceLine &reference_line, const double adc_frenet_s)
Get lane width in init_sl_state.
static bool IsWithinPathDeciderScopeObstacle(const Obstacle &obstacle)
Is obstacle should be considered in path decision
static bool InitPathBoundary(const ReferenceLineInfo &reference_line_info, PathBoundary *const path_bound, SLState init_sl_state)
Starting from ADC's current position, increment until the path length, and set lateral bounds to be i...
const std::string & path_label() const
const FrenetFramePath & frenet_frame_path() const
const std::vector< std::tuple< double, PathPointType, double > > & path_point_decision_guide() const
const IndexedList< std::string, Obstacle > & obstacles() const
void RecordDebugInfo(const PathBound &path_boundaries, const std::string &debug_name, ReferenceLineInfo *const reference_line_info)
add path_boundary debug info for PnC monitor
bool GetSLBoundary(const PathData &path_data, int point_index, const ReferenceLineInfo *reference_line_info, SLBoundary *const sl_boundary)
get sl boundary of the point on PathData
std::vector< SLPolygon > obs_sl_polygons_
void GetStartPointSLState()
calculate init sl state by planning start point, result will store in init_sl_state_
static void UpdatePathRefWithBoundInSidePassDirection(const PathBoundary &path_boundary, double weight, std::vector< double > *ref_l, std::vector< double > *weight_ref_l, bool is_left_side_pass)
static std::vector< common::PathPoint > ConvertPathPointRefFromFrontAxeToRearAxe(const PathData &path_data)
static void CalculateAccBound(const PathBoundary &path_boundary, const ReferenceLine &reference_line, std::vector< std::pair< double, double > > *ddl_bounds)
calculate ddl bound by referenceline kappa and adc lat accleration
static FrenetFramePath ToPiecewiseJerkPath(const std::vector< double > &x, const std::vector< double > &dx, const std::vector< double > &ddx, const double delta_s, const double start_s)
Data format tramform from raw data to FrenetFramePath
static double EstimateJerkBoundary(const double vehicle_speed)
Calculation of jerk boundary based on vehicle kinematics model.
static bool OptimizePath(const SLState &init_state, const std::array< double, 3 > &end_state, std::vector< double > l_ref, std::vector< double > l_ref_weight, const PathBoundary &path_boundary, const std::vector< std::pair< double, double > > &ddl_bounds, double dddl_bound, const PiecewiseJerkPathConfig &config, std::vector< double > *x, std::vector< double > *dx, std::vector< double > *ddx)
Piecewise jerk path optimizer.
ReferenceLineInfo holds all data for one reference line.
bool path_reusable() const
PathDecision * path_decision()
bool GetNeighborLaneInfo(const ReferenceLineInfo::LaneType lane_type, const double s, hdmap::Id *ptr_lane_id, double *ptr_lane_width) const
std::vector< SLPolygon > * mutable_obs_sl_polygons()
const ReferenceLine & reference_line() const
const PathData & path_data() const
double SDistanceToDestination() const
std::vector< PathData > * MutableCandidatePathData()
const SLBoundary & AdcSlBoundary() const
bool IsChangeLanePath() const
Check if the current reference line is a change lane reference line, i.e., ADC's current position is ...
PathData * mutable_path_data()
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
std::shared_ptr< DependencyInjector > injector_
ReferenceLineInfo * reference_line_info_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Planning module main class.
LaneBoundaryType::Type LeftBoundaryType(const LaneWaypoint &waypoint)
get left boundary type at a waypoint.
LaneBoundaryType::Type RightBoundaryType(const LaneWaypoint &waypoint)
get left boundary type at a waypoint.
int GetBackToInLaneIndex(const std::vector< PathPointDecision > &path_point_decision)
bool IsBlockingObstacleWithinDestination(const ReferenceLineInfo &reference_line_info, const std::string &blocking_obstacle_id, const double threshold)
int ContainsOutOnReverseLane(const std::vector< PathPointDecision > &path_point_decision)
std::vector< PathBoundPoint > PathBound
bool IsNonmovableObstacle(const ReferenceLineInfo &reference_line_info, const Obstacle &obstacle)
bool ComparePathData(const PathData &lhs, const PathData &rhs, const Obstacle *blocking_obstacle)
bool IsBlockingObstacleFarFromIntersection(const ReferenceLineInfo &reference_line_info, const std::string &blocking_obstacle_id)
optional int64 long_term_blocking_obstacle_cycle_threshold
optional bool is_allow_lane_borrowing
optional bool enable_active_trigger
optional double enable_nudge_destination_threshold
optional PiecewiseJerkPathConfig path_optimizer_config
optional bool enable_extend_boundary_by_adc
optional double lane_borrow_max_speed
optional bool enable_ignore_boundary_type