25#include <unordered_map>
44 CHECK_NOTNULL(path_bound);
47 path_bound->
set_delta_s(FLAGS_path_bounds_decider_resolution);
49 const auto& vehicle_config =
50 common::VehicleConfigHelper::Instance()->GetConfig();
51 const double ego_front_to_center =
52 vehicle_config.vehicle_param().front_edge_to_center();
54 const auto& reference_line_towing_l =
56 for (
double curr_s = init_sl_state.first[0];
57 curr_s < std::fmin(init_sl_state.first[0] +
58 std::fmax(FLAGS_path_bounds_horizon,
60 FLAGS_trajectory_time_length),
61 reference_line.Length() - ego_front_to_center);
62 curr_s += FLAGS_path_bounds_decider_resolution) {
63 path_bound->emplace_back(curr_s, std::numeric_limits<double>::lowest(),
64 std::numeric_limits<double>::max());
65 if (index < reference_line_towing_l.size()) {
66 path_bound->back().towing_l = reference_line_towing_l.at(index);
72 if (path_bound->empty()) {
73 ADEBUG <<
"Empty path boundary in InitPathBoundary";
82 if (FLAGS_use_front_axe_center_in_path_planning) {
83 planning_start_point =
86 AINFO << std::fixed <<
"Plan at the starting point: x = "
88 <<
", y = " << planning_start_point.
path_point().
y()
93 *init_sl_state = reference_line.
ToFrenetFrame(planning_start_point);
98 double lane_left_width = 0.0;
99 double lane_right_width = 0.0;
100 if (!reference_line.
GetLaneWidth(adc_s, &lane_left_width,
101 &lane_right_width)) {
102 constexpr double kDefaultLaneWidth = 5.0;
103 AWARN <<
"Failed to get lane width at planning start point.";
104 return kDefaultLaneWidth;
106 return lane_left_width + lane_right_width;
111 double left_bound,
double right_bound,
BoundType left_type,
112 BoundType right_type, std::string left_id, std::string right_id,
126 double left_bound,
BoundType left_type, std::string left_id,
128 double adc_half_width =
130 left_bound = left_bound - adc_half_width;
132 if (new_point.
l_upper.
l > left_bound) {
145 *bound_point = new_point;
150 double right_bound,
BoundType right_type, std::string right_id,
152 double adc_half_width =
154 right_bound = right_bound + adc_half_width;
156 if (new_point.
l_lower.
l < right_bound) {
164 ADEBUG <<
"Path is blocked at";
168 *bound_point = new_point;
173 const int path_blocked_idx,
PathBoundary*
const path_boundaries) {
174 if (path_blocked_idx != -1) {
175 if (path_blocked_idx == 0) {
176 AINFO <<
"Completely blocked. Cannot move at all.";
178 double front_edge_to_center =
181 path_boundaries->at(path_blocked_idx).s - front_edge_to_center;
182 AINFO <<
"Trimmed from " << path_boundaries->back().s <<
" to "
183 << path_boundaries->at(path_blocked_idx).s;
184 while (path_boundaries->size() > 1 &&
185 path_boundaries->back().s > trimmed_s) {
186 path_boundaries->pop_back();
193 std::vector<SLPolygon>* polygons,
const SLState& init_sl_state) {
197 for (
const auto* obstacle : obstacles.Items()) {
201 auto xy_poly = obstacle->PerceptionPolygon();
206 if (obstacle->PerceptionSLBoundary().end_s() < adc_back_edge_s) {
209 const auto obstacle_sl = obstacle->PerceptionSLBoundary();
210 polygons->emplace_back(obstacle_sl, obstacle->Id(),
211 obstacle->Perception().type());
213 sort(polygons->begin(), polygons->end(),
215 return a.MinS() < b.MinS();
221 std::vector<SLPolygon>*
const sl_polygon,
const SLState& init_sl_state,
222 PathBoundary*
const path_boundary, std::string*
const blocked_id,
223 double*
const narrowest_width) {
224 std::vector<double> center_l;
225 double max_nudge_check_distance;
227 path_boundary->
label().find(
"regular/left") != std::string::npos ||
228 path_boundary->
label().find(
"regular/right") != std::string::npos) {
230 (path_boundary->front().l_upper.l + path_boundary->front().l_lower.l) *
232 max_nudge_check_distance = FLAGS_max_nudge_check_distance_in_lk;
234 center_l.push_back(0.0);
235 max_nudge_check_distance = FLAGS_max_nudge_check_distance_in_lc;
239 path_boundary->front().l_upper.l - path_boundary->front().l_lower.l;
241 (path_boundary->front().l_upper.l + path_boundary->front().l_lower.l) / 2;
242 size_t nudge_check_count =
243 size_t(max_nudge_check_distance / FLAGS_path_bounds_decider_resolution);
244 double last_max_nudge_l = center_l.front();
247 for (
size_t i = 1; i < path_boundary->size(); ++i) {
248 double path_boundary_s = path_boundary->at(i).s;
249 auto& left_bound = path_boundary->at(i).l_upper;
250 auto& right_bound = path_boundary->at(i).l_lower;
251 double default_width = right_bound.l - left_bound.l;
253 center_l.end() - std::min(nudge_check_count, center_l.size());
254 last_max_nudge_l = *std::max_element(
255 begin_it, center_l.end(),
256 [](
double a,
double b) { return std::fabs(a) < std::fabs(b); });
257 AINFO <<
"last max nudge l: " << last_max_nudge_l;
258 for (
size_t j = 0; j < sl_polygon->size(); j++) {
260 AINFO <<
"UpdatePathBoundaryBySLPolygon, ignore obs: "
261 << sl_polygon->at(j).id();
264 double min_s = sl_polygon->at(j).MinS();
266 sl_polygon->at(j).MaxS() + FLAGS_obstacle_lon_end_buffer_park;
267 if (max_s - min_s < FLAGS_path_bounds_decider_resolution) {
268 max_s += FLAGS_path_bounds_decider_resolution;
269 min_s -= FLAGS_path_bounds_decider_resolution;
271 if (max_s < path_boundary_s) {
274 if (min_s > path_boundary_s) {
278 sl_polygon->at(j).UpdatePassableInfo(left_bound.l, right_bound.l,
279 adc_obs_edge_buffer);
281 double l_lower = sl_polygon->at(j).GetRightBoundaryByS(path_boundary_s);
282 double l_upper = sl_polygon->at(j).GetLeftBoundaryByS(path_boundary_s);
284 path_boundary_s, l_upper + adc_obs_edge_buffer, left_bound.l);
285 obs_left_nudge_bound.
towing_l = path_boundary->at(i).towing_l;
286 PathBoundPoint obs_right_nudge_bound(path_boundary_s, right_bound.l,
287 l_lower - adc_obs_edge_buffer);
288 obs_right_nudge_bound.
towing_l = path_boundary->at(i).towing_l;
294 AINFO <<
"last_max_nudge_l: " << last_max_nudge_l
295 <<
", obs id: " << sl_polygon->at(j).id()
296 <<
", obs l: " << l_lower <<
", " << l_upper;
297 double obs_l = (l_lower + l_upper) / 2;
298 if (sl_polygon->at(j).is_passable()[
RIGHT_INDEX]) {
299 if (sl_polygon->at(j).is_passable()[
LEFT_INDEX]) {
300 if (std::fabs(obs_l - mid_l) < 0.4 &&
301 std::fabs(path_boundary_s - init_sl_state.first[0]) < 5.0) {
302 if (init_sl_state.second[0] < obs_l) {
304 AINFO << sl_polygon->at(j).id()
305 <<
" right nudge with init_sl_state";
308 AINFO << sl_polygon->at(j).id()
309 <<
" left nudge width init_sl_state";
312 if (last_max_nudge_l < obs_l) {
314 AINFO << sl_polygon->at(j).id()
315 <<
" right nudge, according max_nudge_l";
318 AINFO << sl_polygon->at(j).id()
319 <<
" left nudge, according max_nudge_l";
324 AINFO << sl_polygon->at(j).id()
325 <<
" right nudge, left is not passable";
329 AINFO << sl_polygon->at(j).id()
330 <<
" left nudge, right is not passable";
333 AINFO <<
"last_max_nudge_l: " << last_max_nudge_l
334 <<
", obs id: " << sl_polygon->at(j).id()
335 <<
", obs l: " << l_lower <<
", " << l_upper
336 <<
", nudge info: " << sl_polygon->at(j).NudgeInfo();
340 if (obs_right_nudge_bound.
l_upper.
l < path_boundary->at(i).towing_l) {
341 sl_polygon->at(j).SetOverlapeWithReferCenter(
true);
342 sl_polygon->at(j).SetOverlapeSizeWithReference(
343 path_boundary->at(i).towing_l - obs_right_nudge_bound.
l_upper.
l);
345 if (!sl_polygon->at(j).is_passable()[
RIGHT_INDEX]) {
347 *blocked_id = sl_polygon->at(j).id();
348 AINFO <<
"blocked at " << *blocked_id <<
", s: " << path_boundary_s
349 <<
", left bound: " << left_bound.l
350 <<
", right bound: " << right_bound.l;
354 if (obs_right_nudge_bound.
l_upper.
l < left_bound.l) {
355 AINFO <<
"update left_bound: s " << path_boundary_s <<
", l "
356 << left_bound.l <<
" -> " << obs_right_nudge_bound.
l_upper.
l;
357 left_bound.l = obs_right_nudge_bound.
l_upper.
l;
359 left_bound.id = sl_polygon->at(j).id();
361 std::min(*narrowest_width, left_bound.l - right_bound.l);
365 if (obs_left_nudge_bound.
l_lower.
l > path_boundary->at(i).towing_l) {
366 sl_polygon->at(j).SetOverlapeWithReferCenter(
true);
367 sl_polygon->at(j).SetOverlapeSizeWithReference(
368 obs_left_nudge_bound.
l_lower.
l - path_boundary->at(i).towing_l);
370 if (!sl_polygon->at(j).is_passable()[
LEFT_INDEX]) {
372 *blocked_id = sl_polygon->at(j).id();
373 AINFO <<
"blocked at " << *blocked_id <<
", s: " << path_boundary_s
374 <<
", left bound: " << left_bound.l
375 <<
", right bound: " << right_bound.l;
379 if (obs_left_nudge_bound.
l_lower.
l > right_bound.l) {
380 AINFO <<
"update right_bound: s " << path_boundary_s <<
", l "
381 << right_bound.l <<
" -> " << obs_left_nudge_bound.
l_lower.
l;
382 right_bound.l = obs_left_nudge_bound.
l_lower.
l;
384 right_bound.id = sl_polygon->at(j).id();
386 std::min(*narrowest_width, left_bound.l - right_bound.l);
400 last_max_nudge_l = std::fabs((left_bound.l + right_bound.l) / 2.0 -
401 mid_l) > std::fabs(last_max_nudge_l - mid_l)
402 ? (left_bound.l + right_bound.l) / 2.0
406 if (!blocked_id->empty()) {
408 *narrowest_width = default_width;
415 center_l.push_back((left_bound.l + right_bound.l) / 2.0);
416 AINFO <<
"update s: " << path_boundary_s
417 <<
", center_l: " << center_l.back();
423 double s,
double l_lower,
double l_upper,
const PathBoundary& path_boundary,
425 size_t left_index = 0;
426 size_t right_index = 0;
427 double left_weight = 0.0;
428 double right_weight = 0.0;
430 &left_index, &right_index)) {
431 AERROR <<
"Fail to find extra path bound point in path boundary: " << s
432 <<
", path boundary start s: " << path_boundary.front().s
433 <<
", path boundary end s: " << path_boundary.back().s;
436 if (left_weight < 0.05 || right_weight < 0.05) {
440 ADEBUG <<
"corner" << s <<
"left_weight" << left_weight <<
"right_weight"
441 << right_weight <<
"left_index" << left_index <<
"right_index"
442 << right_index <<
"l_lower" << l_lower <<
"l_upper" << l_upper;
443 extra_constraints->emplace_back(left_weight, right_weight, l_lower, l_upper,
444 left_index, right_index, s);
452 size_t left_index = 0;
453 size_t right_index = 0;
454 double left_weight = 0.0;
455 double right_weight = 0.0;
457 sl_pt.
s(), &left_weight, &right_weight, &left_index, &right_index)) {
458 AERROR <<
"Fail to find extra path bound point in path boundary: "
460 <<
", path boundary start s: " << path_boundary.front().s
461 <<
", path boundary end s: " << path_boundary.back().s;
470 left_weight, right_weight, left_index, right_index);
472 left_weight, right_weight, left_index, right_index);
476 if ((is_left && corner_l < bound_l_upper) ||
477 (!is_left && corner_l > bound_l_lower)) {
479 bound_l_upper = corner_l;
481 bound_l_lower = corner_l;
483 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
484 bound_l_upper, left_index, right_index,
486 if (bound_l_upper < bound_l_lower) {
490 AINFO <<
"AddCornerPoint blocked id: " << obs_id <<
", index ["
491 << left_index <<
", " << right_index <<
"]";
496 if (FLAGS_enable_expand_obs_corner) {
497 double add_s = is_front_pt ? sl_pt.
s() - FLAGS_expand_obs_corner_lon_buffer
498 : sl_pt.
s() + FLAGS_expand_obs_corner_lon_buffer;
500 add_s, &left_weight, &right_weight, &left_index, &right_index)) {
505 left_weight, right_weight, left_index, right_index);
507 left_weight, right_weight, left_index, right_index);
509 if ((is_left && corner_l < bound_l_upper) ||
510 (!is_left && corner_l > bound_l_lower)) {
512 bound_l_upper = corner_l;
514 bound_l_lower = corner_l;
516 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
517 bound_l_upper, left_index, right_index,
519 if (bound_l_upper < bound_l_lower) {
523 AINFO <<
"AddCornerPoint blocked id: " << obs_id <<
", index ["
524 << left_index <<
", " << right_index <<
"]";
533 const std::vector<SLPolygon>& sl_polygons,
536 for (
const auto& obs_polygon : sl_polygons) {
537 if (obs_polygon.MinS() > path_boundary->back().s) {
538 ADEBUG <<
"obs_polygon.MinS()" << obs_polygon.MinS()
539 <<
"path_boundary->back().s" << path_boundary->back().s;
542 if (obs_polygon.MaxS() < path_boundary->front().s) {
546 for (
size_t i = 0; i < obs_polygon.LeftBoundary().size(); i++) {
547 auto pt = obs_polygon.LeftBoundary().at(i);
548 bool is_front_pt = i < (obs_polygon.LeftBoundary().size() * 0.5);
550 obs_polygon.id(), is_front_pt)) {
561 for (
size_t i = 0; i < obs_polygon.RightBoundary().size(); i++) {
562 auto pt = obs_polygon.RightBoundary().at(i);
563 bool is_front_pt = i > (obs_polygon.RightBoundary().size() * 0.5);
565 obs_polygon.id(), is_front_pt)) {
576 AINFO <<
"no nugde info, ignore obs: " << obs_polygon.id();
578 if (!extra_path_bound->blocked_id.empty()) {
595 for (
size_t i = 0; i < path_boundary->size(); i++) {
596 double rear_axle_s = path_boundary->at(i).s - front_edge_to_center;
597 if (rear_axle_s <= path_boundary->start_s()) {
600 size_t left_index = 0;
601 size_t right_index = 0;
602 double left_weight = 0.0;
603 double right_weight = 0.0;
605 &right_weight, &left_index,
607 AERROR <<
"Fail to find vertex path bound point in path boundary: "
608 << path_boundary->at(i).s
609 <<
"path boundary start s: " << path_boundary->front().s
610 <<
", path boundary end s: " << path_boundary->back().s;
613 adc_vertex_bound->emplace_back(
614 left_weight, right_weight, path_boundary->at(i).l_lower.l,
615 path_boundary->at(i).l_upper.l, left_index, right_index, rear_axle_s);
617 adc_vertex_bound->front_edge_to_center = front_edge_to_center;
622 std::vector<SLPolygon>*
const sl_polygons,
const SLState& init_sl_state,
623 PathBoundary*
const path_boundary, std::string*
const blocking_obstacle_id,
624 double*
const narrowest_width) {
626 path_boundary, blocking_obstacle_id,
629 blocking_obstacle_id);
634 double adc_half_width =
637 return (adc_half_width + FLAGS_obstacle_lat_buffer);
653 obstacle.
speed() > FLAGS_static_obstacle_speed_threshold) {
668 double front_to_rear_axe_distance =
671 ret.mutable_path_point()->set_x(
673 front_to_rear_axe_distance * std::cos(traj_point.
path_point().
theta()));
674 ret.mutable_path_point()->set_y(
676 front_to_rear_axe_distance * std::sin(traj_point.
path_point().
theta()));
684 CHECK_NOTNULL(path_bound);
685 ACHECK(!path_bound->empty());
687 double adc_lane_width =
691 double past_lane_left_width = adc_lane_width / 2.0;
692 double past_lane_right_width = adc_lane_width / 2.0;
693 int path_blocked_idx = -1;
694 for (
size_t i = 0; i < path_bound->size(); ++i) {
695 double curr_s = (*path_bound)[i].s;
697 double curr_lane_left_width = 0.0;
698 double curr_lane_right_width = 0.0;
699 double offset_to_lane_center = 0.0;
700 if (!reference_line.
GetLaneWidth(curr_s, &curr_lane_left_width,
701 &curr_lane_right_width)) {
702 AWARN <<
"Failed to get lane width at s = " << curr_s;
703 curr_lane_left_width = past_lane_left_width;
704 curr_lane_right_width = past_lane_right_width;
707 curr_lane_left_width += offset_to_lane_center;
708 curr_lane_right_width -= offset_to_lane_center;
709 past_lane_left_width = curr_lane_left_width;
710 past_lane_right_width = curr_lane_right_width;
715 double offset_to_map = 0.0;
718 double curr_left_bound = 0.0;
719 double curr_right_bound = 0.0;
720 curr_left_bound = curr_lane_left_width - offset_to_map;
721 curr_right_bound = -curr_lane_right_width - offset_to_map;
725 &path_bound->at(i))) {
726 path_blocked_idx =
static_cast<int>(i);
728 if (path_blocked_idx != -1) {
742 CHECK_NOTNULL(path_bound);
743 ACHECK(!path_bound->empty());
745 double adc_lane_width =
748 double past_road_left_width = adc_lane_width / 2.0;
749 double past_road_right_width = adc_lane_width / 2.0;
750 int path_blocked_idx = -1;
751 for (
size_t i = 0; i < path_bound->size(); ++i) {
753 double curr_s = (*path_bound)[i].s;
754 double curr_road_left_width = 0.0;
755 double curr_road_right_width = 0.0;
756 if (!reference_line.
GetRoadWidth(curr_s, &curr_road_left_width,
757 &curr_road_right_width)) {
758 AWARN <<
"Failed to get lane width at s = " << curr_s;
759 curr_road_left_width = past_road_left_width;
760 curr_road_right_width = past_road_right_width;
763 past_road_left_width = curr_road_left_width;
764 past_road_right_width = curr_road_right_width;
766 double curr_left_bound = curr_road_left_width;
767 double curr_right_bound = -curr_road_right_width;
768 ADEBUG <<
"At s = " << curr_s
769 <<
", left road bound = " << curr_road_left_width
770 <<
", right road bound = " << curr_road_right_width;
775 &path_bound->at(i))) {
776 path_blocked_idx =
static_cast<int>(i);
778 if (path_blocked_idx != -1) {
782 AINFO <<
"path_blocked_idx: " << path_blocked_idx;
789 const double extend_buffer,
PathBoundary*
const path_bound) {
790 double adc_l_to_lane_center = init_sl_state.second[0];
791 static constexpr double kMaxLateralAccelerations = 1.5;
793 double ADC_speed_buffer = (init_sl_state.second[1] > 0 ? 1.0 : -1.0) *
794 init_sl_state.second[1] * init_sl_state.second[1] /
795 kMaxLateralAccelerations / 2.0;
796 double adc_half_width =
798 double left_bound_adc =
799 std::fmax(adc_l_to_lane_center, adc_l_to_lane_center + ADC_speed_buffer) +
800 adc_half_width + extend_buffer;
801 double right_bound_adc =
802 std::fmin(adc_l_to_lane_center, adc_l_to_lane_center + ADC_speed_buffer) -
803 adc_half_width - extend_buffer;
805 static constexpr double kEpsilon = 0.05;
806 for (
size_t i = 0; i < path_bound->size(); ++i) {
807 double road_left_width = std::fabs(left_bound_adc) + kEpsilon;
808 double road_right_width = std::fabs(right_bound_adc) + kEpsilon;
810 (*path_bound)[i].s, &road_left_width, &road_right_width);
811 double left_bound_road = road_left_width - adc_half_width;
812 double right_bound_road = -road_right_width + adc_half_width;
814 if (left_bound_adc > (*path_bound)[i].l_upper.l) {
815 (*path_bound)[i].l_upper.l =
816 std::max(std::min(left_bound_adc, left_bound_road),
817 (*path_bound)[i].l_upper.l);
819 (*path_bound)[i].l_upper.id =
"adc";
821 if (right_bound_adc < (*path_bound)[i].l_lower.l) {
822 (*path_bound)[i].l_lower.l =
823 std::min(std::max(right_bound_adc, right_bound_road),
824 (*path_bound)[i].l_lower.l);
826 (*path_bound)[i].l_lower.id =
"adc";
836 for (
size_t i = 0; i < path_bound->size(); ++i) {
838 double curr_s = (*path_bound)[i].s;
839 double refline_offset_to_lane_center = 0.0;
840 reference_line.
GetOffsetToMap(curr_s, &refline_offset_to_lane_center);
841 (*path_bound)[i].l_lower.l -= refline_offset_to_lane_center;
842 (*path_bound)[i].l_upper.l -= refline_offset_to_lane_center;
848 const double y,
const PathBound& path_bound) {
851 if (point_sl.
s() > path_bound.back().s ||
853 path_bound.front().s - FLAGS_path_bounds_decider_resolution * 2) {
854 ADEBUG <<
"Longitudinally outside the boundary.";
858 while (idx_after <
static_cast<int>(path_bound.size()) &&
859 path_bound[idx_after].s < point_sl.
s()) {
862 ADEBUG <<
"The idx_after = " << idx_after;
863 ADEBUG <<
"The boundary is: "
864 <<
"[" << path_bound[idx_after].l_lower.l <<
", "
865 << path_bound[idx_after].l_upper.l <<
"].";
866 ADEBUG <<
"The point is at: " << point_sl.
l();
867 int idx_before = idx_after - 1;
868 if (path_bound[idx_before].l_lower.l <= point_sl.
l() &&
869 path_bound[idx_before].l_upper.l >= point_sl.
l() &&
870 path_bound[idx_after].l_lower.l <= point_sl.
l() &&
871 path_bound[idx_after].l_upper.l >= point_sl.
l()) {
874 ADEBUG <<
"Laterally outside the boundary.";
879 PathBoundPoint*
const path_bound_point,
bool is_left,
double init_l,
880 double heading,
double delta_s,
double init_frenet_kappa,
882 bool is_success =
false;
883 double protective_restrict = 0.0;
884 double relax_constraint = 0.0;
885 double radius = 1.0 / std::fabs(init_frenet_kappa);
886 double old_buffer = FLAGS_obstacle_lat_buffer;
887 double new_buffer = std::max(FLAGS_ego_front_slack_buffer,
888 FLAGS_nonstatic_obstacle_nudge_l_buffer);
890 if (init_frenet_kappa > 0 && heading < 0) {
892 delta_s, min_radius, heading, init_frenet_kappa,
893 &protective_restrict);
896 &protective_restrict);
900 std::max(path_bound_point->
l_upper.
l, init_l + protective_restrict);
901 AINFO <<
"init_pt_l: " << init_l
902 <<
", left_bound: " << path_bound_point->
l_upper.
l
903 <<
", diff s: " << delta_s <<
", radius: " << radius
904 <<
", protective_restrict: " << protective_restrict
905 <<
", left_obs_constraint: " << relax_constraint;
908 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
909 FLAGS_static_obstacle_nudge_l_buffer);
913 std::min(path_bound_point->
l_upper.
l + old_buffer - new_buffer,
915 AINFO <<
"left_obs_constraint: " << relax_constraint;
916 path_bound_point->
l_upper.
l = relax_constraint;
918 if (init_frenet_kappa < 0 && heading > 0) {
920 delta_s, min_radius, heading, init_frenet_kappa,
921 &protective_restrict);
924 &protective_restrict);
927 std::min(path_bound_point->
l_lower.
l, init_l + protective_restrict);
928 AINFO <<
"init_pt_l: " << init_l
929 <<
", right_bound: " << path_bound_point->
l_lower.
l
930 <<
", diff s: " << delta_s <<
", radius: " << radius
931 <<
", protective_restrict: " << protective_restrict
932 <<
", right_obs_constraint: " << relax_constraint;
935 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
936 FLAGS_static_obstacle_nudge_l_buffer);
940 std::max(path_bound_point->
l_lower.
l - old_buffer + new_buffer,
942 AINFO <<
"right_obs_constraint: " << relax_constraint;
943 path_bound_point->
l_lower.
l = relax_constraint;
950 if (path_boundary->size() < 2) {
951 AINFO <<
"path_boundary size = 0, return.";
954 const auto& veh_param =
957 std::max(veh_param.min_turn_radius(),
958 std::tan(veh_param.max_steer_angle() / veh_param.steer_ratio()) /
959 veh_param.wheel_base());
961 double init_frenet_kappa =
962 init_sl_state.second[2] /
963 std::pow(1 + std::pow(init_sl_state.second[1], 2), 1.5);
964 if (init_frenet_kappa < 0) {
965 init_frenet_kappa = std::min(
966 -1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
968 init_frenet_kappa = std::max(
969 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
972 const auto& init_pt = path_boundary->at(0);
973 double init_frenet_heading =
975 double init_pt_l = init_sl_state.second[0];
976 bool left_calculate_success =
true;
977 bool right_calculate_success =
true;
978 for (
size_t i = 1; i < path_boundary->size(); ++i) {
979 auto& left_bound = path_boundary->at(i).l_upper;
980 auto& right_bound = path_boundary->at(i).l_lower;
981 double delta_s = path_boundary->at(i).s - init_pt.s;
982 if (delta_s > FLAGS_relax_path_s_threshold) {
983 left_calculate_success =
false;
984 right_calculate_success =
false;
987 if (left_calculate_success &&
989 path_boundary->at(i).is_nudge_bound[
LEFT_INDEX])) {
991 &path_boundary->at(i),
true, init_pt_l, init_frenet_heading, delta_s,
992 init_frenet_kappa, min_radius);
994 if (right_calculate_success &&
996 path_boundary->at(i).is_nudge_bound[
RIGHT_INDEX])) {
998 &path_boundary->at(i),
false, init_pt_l, init_frenet_heading, delta_s,
999 init_frenet_kappa, min_radius);
1001 if (!left_calculate_success && !right_calculate_success) {
1010 if (path_boundary->size() < 2) {
1011 AINFO <<
"path_boundary size = 0, return.";
1014 const auto& veh_param =
1017 std::max(veh_param.min_turn_radius(),
1018 std::tan(veh_param.max_steer_angle() / veh_param.steer_ratio()) /
1019 veh_param.wheel_base());
1021 double init_frenet_kappa =
1022 std::fabs(init_sl_state.second[2] /
1023 std::pow(1 + std::pow(init_sl_state.second[1], 2), 1.5));
1024 if (init_frenet_kappa < 0) {
1025 init_frenet_kappa = std::min(
1026 -1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1028 init_frenet_kappa = std::max(
1029 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1031 double kappa_radius = 1.0 / std::fabs(init_frenet_kappa);
1033 const auto& init_pt = path_boundary->at(0);
1034 double init_frenet_heading =
1036 double init_pt_l = init_sl_state.second[0];
1037 bool left_calculate_success =
true;
1038 bool right_calculate_success =
true;
1039 double new_buffer = std::max(FLAGS_ego_front_slack_buffer,
1040 FLAGS_nonstatic_obstacle_nudge_l_buffer);
1042 double delta_s = extra_path_bound.rear_axle_s - init_pt.s;
1043 if (delta_s > FLAGS_relax_path_s_threshold) {
1048 if (left_calculate_success) {
1049 double left_protective_restrict = 0.0;
1050 if (init_frenet_kappa > 0 && init_frenet_heading < 0) {
1051 left_calculate_success =
1053 delta_s, min_radius, init_frenet_heading, init_frenet_kappa,
1054 &left_protective_restrict);
1057 delta_s, kappa_radius, init_frenet_heading,
1058 &left_protective_restrict);
1061 double left_obs_constraint = std::max(
1062 extra_path_bound.upper_bound, init_pt_l + left_protective_restrict);
1063 AINFO <<
"extra_path_bound, init_pt_l: " << init_pt_l
1064 <<
", left_bound: " << extra_path_bound.upper_bound
1065 <<
", diff s: " << delta_s <<
", min_radius: " << min_radius
1066 <<
", init_frenet_heading: " << init_frenet_heading
1067 <<
", protective_restrict: " << left_protective_restrict
1068 <<
", left_obs_constraint: " << left_obs_constraint;
1069 left_obs_constraint = std::min(
1070 extra_path_bound.upper_bound + FLAGS_obstacle_lat_buffer - new_buffer,
1071 left_obs_constraint);
1072 AINFO <<
"extra_path_bound left_obs_constraint: " << left_obs_constraint;
1073 extra_path_bound.upper_bound = left_obs_constraint;
1076 if (right_calculate_success) {
1078 double right_protective_restrict = 0.0;
1079 if (init_frenet_kappa < 0 && init_frenet_heading > 0) {
1080 right_calculate_success =
1082 delta_s, min_radius, init_frenet_heading, init_frenet_kappa,
1083 &right_protective_restrict);
1086 delta_s, kappa_radius, init_frenet_heading,
1087 &right_protective_restrict);
1090 double right_obs_constraint = std::min(
1091 extra_path_bound.lower_bound, init_pt_l + right_protective_restrict);
1092 AINFO <<
"extra_path_bound, init_pt_l: " << init_pt_l
1093 <<
", right_bound: " << extra_path_bound.lower_bound
1094 <<
", diff s: " << delta_s <<
", min_radius: " << min_radius
1095 <<
", init_frenet_heading: " << init_frenet_heading
1096 <<
", protective_restrict: " << right_protective_restrict
1097 <<
", right_obs_constraint: " << right_obs_constraint;
1098 right_obs_constraint = std::max(
1099 extra_path_bound.lower_bound - FLAGS_obstacle_lat_buffer + new_buffer,
1100 right_obs_constraint);
1101 AINFO <<
"extra_path_bound, right_obs_constraint: "
1102 << right_obs_constraint;
1103 extra_path_bound.lower_bound = right_obs_constraint;
1106 if (!left_calculate_success && !right_calculate_success) {
1114 PathBoundary*
const path_boundary, std::string*
const blocked_id) {
1116 AINFO <<
"UpdateBlockInfoWithObsCornerBoundary, block id empty";
1123 *blocked_id = extra_path_bound->blocked_id;
1125 AINFO <<
"update block id: " << *blocked_id
1126 <<
", path_boundary size: " << path_boundary->size();
1128 if (path_boundary->size() < 1) {
1129 extra_path_bound->clear();
1130 AERROR <<
"UpdateBlockInfoWithObsCornerBoundary, new_path_index < 1";
1134 size_t new_path_index = path_boundary->size() - 1;
1135 while (extra_path_bound->size() > 0 &&
1136 (extra_path_bound->back().id == *blocked_id ||
1137 extra_path_bound->back().right_index > new_path_index)) {
1138 AINFO <<
"remove extra_path_bound: s "
1139 << extra_path_bound->back().rear_axle_s <<
", index ["
1140 << extra_path_bound->back().left_index <<
", "
1141 << extra_path_bound->back().right_index <<
"]";
1142 extra_path_bound->pop_back();
1148 const std::vector<SLPolygon>& sl_polygons,
1150 std::string*
const blocked_id) {
1152 if (FLAGS_enable_corner_constraint) {
1157 if (FLAGS_enable_adc_vertex_constraint) {
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Implements a class of 2-dimensional vectors.
double Angle() const
Gets the angle between the vector and the positive x semi-axis
This is the class that associates an Obstacle with its path properties.
bool HasLongitudinalDecision() const
bool HasLateralDecision() const
bool IsIgnore() const
Check if this object can be safely ignored.
double get_upper_bound_by_interpolated_index(double left_weight, double right_weight, size_t left_index, size_t right_index) const
bool get_interpolated_s_weight(const double s, double *left_weight, double *right_weight, size_t *left_index, size_t *right_index) const
ADCVertexConstraints * mutable_adc_vertex_bound()
const ObsCornerConstraints & extra_path_bound() const
ObsCornerConstraints * mutable_extra_path_bound()
void set_delta_s(double s)
const std::string & label() const
double get_lower_bound_by_interpolated_index(double left_weight, double right_weight, size_t left_index, size_t right_index) const
static bool GetBoundaryFromSelfLane(const ReferenceLineInfo &reference_line_info, const SLState &init_sl_state, PathBoundary *const path_bound)
generate path bound by self lane and adc position
static bool RelaxObsCornerBoundary(PathBoundary *const path_boundary, const SLState &init_sl_state)
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 UpdateLeftPathBoundaryWithBuffer(double left_bound, BoundType left_type, std::string left_id, PathBoundPoint *const bound_point)
static bool RelaxEgoPathBoundary(PathBoundary *const path_boundary, const SLState &init_sl_state)
static void AddCornerBounds(const std::vector< SLPolygon > &sl_polygons, PathBoundary *const path_boundary)
static bool AddExtraPathBound(const std::vector< SLPolygon > &sl_polygons, PathBoundary *const path_boundary, const SLState &init_sl_state, std::string *const blocked_id)
static bool AddCornerPoint(double s, double l_lower, double l_upper, const PathBoundary &path_boundary, ObsCornerConstraints *extra_constraints)
static void ConvertBoundarySAxisFromLaneCenterToRefLine(const ReferenceLineInfo &reference_line_info, PathBoundary *const path_bound)
static bool GetBoundaryFromStaticObstacles(const ReferenceLineInfo &reference_line_info, std::vector< SLPolygon > *const sl_polygons, const SLState &init_sl_state, PathBoundary *const path_boundaries, std::string *const blocking_obstacle_id, double *const narrowest_width)
Refine the boundary based on static obstacles.
static int IsPointWithinPathBound(const ReferenceLineInfo &reference_line_info, const double x, const double y, const PathBound &path_bound)
static bool GetBoundaryFromRoad(const ReferenceLineInfo &reference_line_info, const SLState &init_sl_state, PathBoundary *const path_bound)
static void AddAdcVertexBounds(PathBoundary *const path_boundary)
static bool UpdateBlockInfoWithObsCornerBoundary(PathBoundary *const path_boundary, std::string *const blocked_id)
static common::TrajectoryPoint InferFrontAxeCenterFromRearAxeCenter(const common::TrajectoryPoint &traj_point)
static void GetStartPoint(common::TrajectoryPoint planning_start_point, const ReferenceLine &reference_line, SLState *init_sl_state)
Starting from ADC's current position, increment until the horizon, and and set lateral bounds to be i...
static void TrimPathBounds(const int path_blocked_idx, PathBoundary *const path_boundaries)
static bool RelaxBoundaryPoint(PathBoundPoint *const path_bound_point, bool is_left, double init_l, double heading, double delta_s, double init_frenet_kappa, double min_radius)
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 GetBufferBetweenADCCenterAndEdge()
Get the distance between ADC's center and its edge.
static void GetSLPolygons(const ReferenceLineInfo &reference_line_info, std::vector< SLPolygon > *polygons, const SLState &init_sl_state)
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...
static bool UpdateRightPathBoundaryWithBuffer(double right_bound, BoundType right_type, std::string right_id, PathBoundPoint *const bound_point)
Trim the path bounds starting at the idx where path is blocked.
const IndexedList< std::string, Obstacle > & obstacles() const
ReferenceLineInfo holds all data for one reference line.
PathDecision * path_decision()
double GetCruiseSpeed() const
const std::vector< double > & reference_line_towing_l() const
const ReferenceLine & reference_line() const
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 ...
std::pair< std::array< double, 3 >, std::array< double, 3 > > ToFrenetFrame(const common::TrajectoryPoint &traj_point) const
bool GetRoadWidth(const double s, double *const road_left_width, double *const road_right_width) const
bool XYToSL(const common::math::Vec2d &xy_point, common::SLPoint *const sl_point, double warm_start_s=-1.0) const
Transvert Cartesian coordinates to Frenet.
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
bool GetOffsetToMap(const double s, double *l_offset) const
Planning module main class.
Linear interpolation functions.
bool left_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
bool right_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
bool left_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
bool right_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
std::pair< std::array< double, 3 >, std::array< double, 3 > > SLState
std::vector< PathBoundPoint > PathBound
optional PathPoint path_point
optional VehicleParam vehicle_param
optional double front_edge_to_center
optional double wheel_base