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();
52 const auto& reference_line_towing_l =
54 for (
double curr_s = init_sl_state.first[0];
55 curr_s < std::fmin(init_sl_state.first[0] +
56 std::fmax(FLAGS_path_bounds_horizon,
58 FLAGS_trajectory_time_length),
59 reference_line.Length());
60 curr_s += FLAGS_path_bounds_decider_resolution) {
61 path_bound->emplace_back(curr_s, std::numeric_limits<double>::lowest(),
62 std::numeric_limits<double>::max());
63 if (index < reference_line_towing_l.size()) {
64 path_bound->back().towing_l = reference_line_towing_l.at(index);
70 if (path_bound->empty()) {
71 ADEBUG <<
"Empty path boundary in InitPathBoundary";
80 if (FLAGS_use_front_axe_center_in_path_planning) {
81 planning_start_point =
84 AINFO << std::fixed <<
"Plan at the starting point: x = "
86 <<
", y = " << planning_start_point.
path_point().
y()
91 *init_sl_state = reference_line.
ToFrenetFrame(planning_start_point);
96 double lane_left_width = 0.0;
97 double lane_right_width = 0.0;
98 if (!reference_line.
GetLaneWidth(adc_s, &lane_left_width,
100 constexpr double kDefaultLaneWidth = 5.0;
101 AWARN <<
"Failed to get lane width at planning start point.";
102 return kDefaultLaneWidth;
104 return lane_left_width + lane_right_width;
109 double left_bound,
double right_bound,
BoundType left_type,
110 BoundType right_type, std::string left_id, std::string right_id,
124 double left_bound,
BoundType left_type, std::string left_id,
126 double adc_half_width =
128 left_bound = left_bound - adc_half_width;
130 if (new_point.
l_upper.
l > left_bound) {
143 *bound_point = new_point;
148 double right_bound,
BoundType right_type, std::string right_id,
150 double adc_half_width =
152 right_bound = right_bound + adc_half_width;
154 if (new_point.
l_lower.
l < right_bound) {
162 ADEBUG <<
"Path is blocked at";
166 *bound_point = new_point;
171 const int path_blocked_idx,
PathBoundary*
const path_boundaries) {
172 if (path_blocked_idx != -1) {
173 if (path_blocked_idx == 0) {
174 AINFO <<
"Completely blocked. Cannot move at all.";
176 double front_edge_to_center =
179 path_boundaries->at(path_blocked_idx).s - front_edge_to_center;
180 AINFO <<
"Trimmed from " << path_boundaries->back().s <<
" to "
181 << path_boundaries->at(path_blocked_idx).s;
182 while (path_boundaries->size() > 1 &&
183 path_boundaries->back().s > trimmed_s) {
184 path_boundaries->pop_back();
191 std::vector<SLPolygon>* polygons,
const SLState& init_sl_state) {
195 for (
const auto* obstacle : obstacles.Items()) {
199 auto xy_poly = obstacle->PerceptionPolygon();
204 if (obstacle->PerceptionSLBoundary().end_s() < adc_back_edge_s) {
207 const auto obstacle_sl = obstacle->PerceptionSLBoundary();
208 polygons->emplace_back(obstacle_sl, obstacle->Id(),
209 obstacle->Perception().type());
211 sort(polygons->begin(), polygons->end(),
213 return a.MinS() < b.MinS();
219 std::vector<SLPolygon>*
const sl_polygon,
const SLState& init_sl_state,
220 PathBoundary*
const path_boundary, std::string*
const blocked_id,
221 double*
const narrowest_width) {
222 std::vector<double> center_l;
223 double max_nudge_check_distance;
225 path_boundary->
label().find(
"regular/left") != std::string::npos ||
226 path_boundary->
label().find(
"regular/right") != std::string::npos) {
228 (path_boundary->front().l_upper.l + path_boundary->front().l_lower.l) *
230 max_nudge_check_distance =
231 std::max(FLAGS_max_nudge_check_distance_in_lk,
234 center_l.push_back(0.0);
235 max_nudge_check_distance =
236 std::max(FLAGS_max_nudge_check_distance_in_lc,
241 path_boundary->front().l_upper.l - path_boundary->front().l_lower.l;
243 (path_boundary->front().l_upper.l + path_boundary->front().l_lower.l) / 2;
244 size_t nudge_check_count =
245 size_t(max_nudge_check_distance / FLAGS_path_bounds_decider_resolution);
246 double last_max_nudge_l = center_l.front();
252 for (
size_t i = 1; i < path_boundary->size(); ++i) {
253 double path_boundary_s = path_boundary->at(i).s;
254 auto& left_bound = path_boundary->at(i).l_upper;
255 auto& right_bound = path_boundary->at(i).l_lower;
256 double default_width = right_bound.l - left_bound.l;
258 center_l.end() - std::min(nudge_check_count, center_l.size());
259 last_max_nudge_l = *std::max_element(
260 begin_it, center_l.end(),
261 [](
double a,
double b) { return std::fabs(a) < std::fabs(b); });
262 AINFO <<
"last max nudge l: " << last_max_nudge_l;
263 bool is_left_width =
false;
265 reference_line_info, path_boundary_s, &is_left_width);
266 double left_half_width, right_half_width;
268 left_half_width = eq_width + FLAGS_obstacle_lat_buffer;
271 FLAGS_obstacle_lat_buffer;
275 FLAGS_obstacle_lat_buffer;
276 right_half_width = eq_width + FLAGS_obstacle_lat_buffer;
279 for (
size_t j = 0; j < sl_polygon->size(); j++) {
281 AINFO <<
"UpdatePathBoundaryBySLPolygon, ignore obs: "
282 << sl_polygon->at(j).id();
285 double min_s = sl_polygon->at(j).MinS();
287 sl_polygon->at(j).MaxS() + FLAGS_obstacle_lon_end_buffer_park;
288 if (max_s - min_s < FLAGS_path_bounds_decider_resolution) {
289 max_s += FLAGS_path_bounds_decider_resolution;
290 min_s -= FLAGS_path_bounds_decider_resolution;
292 if (max_s < path_boundary_s) {
295 if (min_s > path_boundary_s) {
299 sl_polygon->at(j).UpdatePassableInfo(left_bound.l, right_bound.l,
300 right_half_width, left_half_width,
303 double l_lower = sl_polygon->at(j).GetRightBoundaryByS(path_boundary_s);
304 double l_upper = sl_polygon->at(j).GetLeftBoundaryByS(path_boundary_s);
306 path_boundary_s, l_upper + right_half_width, left_bound.l);
307 obs_left_nudge_bound.
towing_l = path_boundary->at(i).towing_l;
308 PathBoundPoint obs_right_nudge_bound(path_boundary_s, right_bound.l,
309 l_lower - left_half_width);
310 obs_right_nudge_bound.
towing_l = path_boundary->at(i).towing_l;
316 AINFO <<
"last_max_nudge_l: " << last_max_nudge_l
317 <<
", obs id: " << sl_polygon->at(j).id()
318 <<
", obs l: " << l_lower <<
", " << l_upper;
319 double obs_l = (l_lower + l_upper) / 2;
320 if (sl_polygon->at(j).is_passable()[
RIGHT_INDEX]) {
321 if (sl_polygon->at(j).is_passable()[
LEFT_INDEX]) {
322 if (std::fabs(obs_l - mid_l) < 0.4 &&
323 std::fabs(path_boundary_s - init_sl_state.first[0]) < 5.0) {
324 if (init_sl_state.second[0] < obs_l) {
326 AINFO << sl_polygon->at(j).id()
327 <<
" right nudge with init_sl_state";
330 AINFO << sl_polygon->at(j).id()
331 <<
" left nudge width init_sl_state";
333 }
else if (path_boundary_s - adc_start_s > 0 &&
334 path_boundary_s - adc_end_s < 0) {
336 if (adc_end_l < obs_l) {
338 AINFO << sl_polygon->at(j).id()
339 <<
" right nudge with init_sl_state";
342 AINFO << sl_polygon->at(j).id()
343 <<
" left nudge width init_sl_state";
346 if (last_max_nudge_l < obs_l) {
348 AINFO << sl_polygon->at(j).id()
349 <<
" right nudge, according max_nudge_l";
352 AINFO << sl_polygon->at(j).id()
353 <<
" left nudge, according max_nudge_l";
358 AINFO << sl_polygon->at(j).id()
359 <<
" right nudge, left is not passable";
363 AINFO << sl_polygon->at(j).id()
364 <<
" left nudge, right is not passable";
367 AINFO <<
"last_max_nudge_l: " << last_max_nudge_l
368 <<
", obs id: " << sl_polygon->at(j).id()
369 <<
", obs l: " << l_lower <<
", " << l_upper
370 <<
", nudge info: " << sl_polygon->at(j).NudgeInfo();
374 if (obs_right_nudge_bound.
l_upper.
l < path_boundary->at(i).towing_l) {
375 sl_polygon->at(j).SetOverlapeWithReferCenter(
true);
376 sl_polygon->at(j).SetOverlapeSizeWithReference(
377 path_boundary->at(i).towing_l - obs_right_nudge_bound.
l_upper.
l);
379 if (!sl_polygon->at(j).is_passable()[
RIGHT_INDEX]) {
381 *blocked_id = sl_polygon->at(j).id();
382 AINFO <<
"blocked at " << *blocked_id <<
", s: " << path_boundary_s
383 <<
", left bound: " << left_bound.l
384 <<
", right bound: " << right_bound.l;
388 if (obs_right_nudge_bound.
l_upper.
l < left_bound.l) {
389 AINFO <<
"update left_bound: s " << path_boundary_s <<
", l "
390 << left_bound.l <<
" -> " << obs_right_nudge_bound.
l_upper.
l;
391 left_bound.l = obs_right_nudge_bound.
l_upper.
l;
393 left_bound.id = sl_polygon->at(j).id();
395 std::min(*narrowest_width, left_bound.l - right_bound.l);
399 if (obs_left_nudge_bound.
l_lower.
l > path_boundary->at(i).towing_l) {
400 sl_polygon->at(j).SetOverlapeWithReferCenter(
true);
401 sl_polygon->at(j).SetOverlapeSizeWithReference(
402 obs_left_nudge_bound.
l_lower.
l - path_boundary->at(i).towing_l);
404 if (!sl_polygon->at(j).is_passable()[
LEFT_INDEX]) {
406 *blocked_id = sl_polygon->at(j).id();
407 AINFO <<
"blocked at " << *blocked_id <<
", s: " << path_boundary_s
408 <<
", left bound: " << left_bound.l
409 <<
", right bound: " << right_bound.l;
413 if (obs_left_nudge_bound.
l_lower.
l > right_bound.l) {
414 AINFO <<
"update right_bound: s " << path_boundary_s <<
", l "
415 << right_bound.l <<
" -> " << obs_left_nudge_bound.
l_lower.
l;
416 right_bound.l = obs_left_nudge_bound.
l_lower.
l;
418 right_bound.id = sl_polygon->at(j).id();
420 std::min(*narrowest_width, left_bound.l - right_bound.l);
434 last_max_nudge_l = std::fabs((left_bound.l + right_bound.l) / 2.0 -
435 mid_l) > std::fabs(last_max_nudge_l - mid_l)
436 ? (left_bound.l + right_bound.l) / 2.0
440 if (!blocked_id->empty()) {
442 *narrowest_width = default_width;
449 center_l.push_back((left_bound.l + right_bound.l) / 2.0);
450 AINFO <<
"update s: " << path_boundary_s
451 <<
", center_l: " << center_l.back();
457 double s,
double l_lower,
double l_upper,
const PathBoundary& path_boundary,
459 size_t left_index = 0;
460 size_t right_index = 0;
461 double left_weight = 0.0;
462 double right_weight = 0.0;
464 &left_index, &right_index)) {
465 AERROR <<
"Fail to find extra path bound point in path boundary: " << s
466 <<
", path boundary start s: " << path_boundary.front().s
467 <<
", path boundary end s: " << path_boundary.back().s;
470 if (left_weight < 0.05 || right_weight < 0.05) {
474 ADEBUG <<
"corner" << s <<
"left_weight" << left_weight <<
"right_weight"
475 << right_weight <<
"left_index" << left_index <<
"right_index"
476 << right_index <<
"l_lower" << l_lower <<
"l_upper" << l_upper;
477 extra_constraints->emplace_back(left_weight, right_weight, l_lower, l_upper,
478 left_index, right_index, s);
486 size_t left_index = 0;
487 size_t right_index = 0;
488 double left_weight = 0.0;
489 double right_weight = 0.0;
491 sl_pt.
s(), &left_weight, &right_weight, &left_index, &right_index)) {
492 AERROR <<
"Fail to find extra path bound point in path boundary: "
494 <<
", path boundary start s: " << path_boundary.front().s
495 <<
", path boundary end s: " << path_boundary.back().s;
504 left_weight, right_weight, left_index, right_index);
506 left_weight, right_weight, left_index, right_index);
510 if ((is_left && corner_l < bound_l_upper) ||
511 (!is_left && corner_l > bound_l_lower)) {
513 bound_l_upper = corner_l;
515 bound_l_lower = corner_l;
517 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
518 bound_l_upper, left_index, right_index,
520 if (bound_l_upper < bound_l_lower) {
524 AINFO <<
"AddCornerPoint blocked id: " << obs_id <<
", index ["
525 << left_index <<
", " << right_index <<
"]";
530 if (FLAGS_enable_expand_obs_corner) {
531 double add_s = is_front_pt ? sl_pt.
s() - FLAGS_expand_obs_corner_lon_buffer
532 : sl_pt.
s() + FLAGS_expand_obs_corner_lon_buffer;
534 add_s, &left_weight, &right_weight, &left_index, &right_index)) {
539 left_weight, right_weight, left_index, right_index);
541 left_weight, right_weight, left_index, right_index);
543 if ((is_left && corner_l < bound_l_upper) ||
544 (!is_left && corner_l > bound_l_lower)) {
546 bound_l_upper = corner_l;
548 bound_l_lower = corner_l;
550 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
551 bound_l_upper, left_index, right_index,
553 if (bound_l_upper < bound_l_lower) {
557 AINFO <<
"AddCornerPoint blocked id: " << obs_id <<
", index ["
558 << left_index <<
", " << right_index <<
"]";
567 const std::vector<SLPolygon>& sl_polygons,
570 for (
const auto& obs_polygon : sl_polygons) {
571 if (obs_polygon.MinS() > path_boundary->back().s) {
572 ADEBUG <<
"obs_polygon.MinS()" << obs_polygon.MinS()
573 <<
"path_boundary->back().s" << path_boundary->back().s;
576 if (obs_polygon.MaxS() < path_boundary->front().s) {
580 for (
size_t i = 0; i < obs_polygon.LeftBoundary().size(); i++) {
581 auto pt = obs_polygon.LeftBoundary().at(i);
582 bool is_front_pt = i < (obs_polygon.LeftBoundary().size() * 0.5);
584 obs_polygon.id(), is_front_pt)) {
595 for (
size_t i = 0; i < obs_polygon.RightBoundary().size(); i++) {
596 auto pt = obs_polygon.RightBoundary().at(i);
597 bool is_front_pt = i > (obs_polygon.RightBoundary().size() * 0.5);
599 obs_polygon.id(), is_front_pt)) {
610 AINFO <<
"no nugde info, ignore obs: " << obs_polygon.id();
612 if (!extra_path_bound->blocked_id.empty()) {
629 for (
size_t i = 0; i < path_boundary->size(); i++) {
630 double rear_axle_s = path_boundary->at(i).s - front_edge_to_center;
631 if (rear_axle_s <= path_boundary->start_s()) {
634 size_t left_index = 0;
635 size_t right_index = 0;
636 double left_weight = 0.0;
637 double right_weight = 0.0;
639 &right_weight, &left_index,
641 AERROR <<
"Fail to find vertex path bound point in path boundary: "
642 << path_boundary->at(i).s
643 <<
"path boundary start s: " << path_boundary->front().s
644 <<
", path boundary end s: " << path_boundary->back().s;
647 adc_vertex_bound->emplace_back(
648 left_weight, right_weight, path_boundary->at(i).l_lower.l,
649 path_boundary->at(i).l_upper.l, left_index, right_index, rear_axle_s);
651 adc_vertex_bound->front_edge_to_center = front_edge_to_center;
656 std::vector<SLPolygon>*
const sl_polygons,
const SLState& init_sl_state,
657 PathBoundary*
const path_boundary, std::string*
const blocking_obstacle_id,
658 double*
const narrowest_width) {
660 path_boundary, blocking_obstacle_id,
663 blocking_obstacle_id);
668 double adc_half_width =
671 return (adc_half_width + FLAGS_obstacle_lat_buffer);
687 obstacle.
speed() > FLAGS_static_obstacle_speed_threshold) {
702 double front_to_rear_axe_distance =
705 ret.mutable_path_point()->set_x(
707 front_to_rear_axe_distance * std::cos(traj_point.
path_point().
theta()));
708 ret.mutable_path_point()->set_y(
710 front_to_rear_axe_distance * std::sin(traj_point.
path_point().
theta()));
718 CHECK_NOTNULL(path_bound);
719 ACHECK(!path_bound->empty());
721 double adc_lane_width =
725 double past_lane_left_width = adc_lane_width / 2.0;
726 double past_lane_right_width = adc_lane_width / 2.0;
727 int path_blocked_idx = -1;
728 for (
size_t i = 0; i < path_bound->size(); ++i) {
729 double curr_s = (*path_bound)[i].s;
731 double curr_lane_left_width = 0.0;
732 double curr_lane_right_width = 0.0;
733 double offset_to_lane_center = 0.0;
734 if (!reference_line.
GetLaneWidth(curr_s, &curr_lane_left_width,
735 &curr_lane_right_width)) {
736 AWARN <<
"Failed to get lane width at s = " << curr_s;
737 curr_lane_left_width = past_lane_left_width;
738 curr_lane_right_width = past_lane_right_width;
741 curr_lane_left_width += offset_to_lane_center;
742 curr_lane_right_width -= offset_to_lane_center;
743 past_lane_left_width = curr_lane_left_width;
744 past_lane_right_width = curr_lane_right_width;
749 double offset_to_map = 0.0;
752 double curr_left_bound = 0.0;
753 double curr_right_bound = 0.0;
754 curr_left_bound = curr_lane_left_width - offset_to_map;
755 curr_right_bound = -curr_lane_right_width - offset_to_map;
759 &path_bound->at(i))) {
760 path_blocked_idx =
static_cast<int>(i);
762 if (path_blocked_idx != -1) {
776 CHECK_NOTNULL(path_bound);
777 ACHECK(!path_bound->empty());
779 double adc_lane_width =
782 double past_road_left_width = adc_lane_width / 2.0;
783 double past_road_right_width = adc_lane_width / 2.0;
784 int path_blocked_idx = -1;
785 for (
size_t i = 0; i < path_bound->size(); ++i) {
787 double curr_s = (*path_bound)[i].s;
788 double curr_road_left_width = 0.0;
789 double curr_road_right_width = 0.0;
790 if (!reference_line.
GetRoadWidth(curr_s, &curr_road_left_width,
791 &curr_road_right_width)) {
792 AWARN <<
"Failed to get lane width at s = " << curr_s;
793 curr_road_left_width = past_road_left_width;
794 curr_road_right_width = past_road_right_width;
797 past_road_left_width = curr_road_left_width;
798 past_road_right_width = curr_road_right_width;
800 double curr_left_bound = curr_road_left_width;
801 double curr_right_bound = -curr_road_right_width;
802 ADEBUG <<
"At s = " << curr_s
803 <<
", left road bound = " << curr_road_left_width
804 <<
", right road bound = " << curr_road_right_width;
809 &path_bound->at(i))) {
810 path_blocked_idx =
static_cast<int>(i);
812 if (path_blocked_idx != -1) {
816 AINFO <<
"path_blocked_idx: " << path_blocked_idx;
823 const double extend_buffer,
PathBoundary*
const path_bound) {
824 double adc_l_to_lane_center = init_sl_state.second[0];
825 static constexpr double kMaxLateralAccelerations = 1.5;
827 double ADC_speed_buffer = (init_sl_state.second[1] > 0 ? 1.0 : -1.0) *
828 init_sl_state.second[1] * init_sl_state.second[1] /
829 kMaxLateralAccelerations / 2.0;
830 double adc_half_width =
832 double left_bound_adc =
833 std::fmax(adc_l_to_lane_center, adc_l_to_lane_center + ADC_speed_buffer) +
834 adc_half_width + extend_buffer;
835 double right_bound_adc =
836 std::fmin(adc_l_to_lane_center, adc_l_to_lane_center + ADC_speed_buffer) -
837 adc_half_width - extend_buffer;
839 static constexpr double kEpsilon = 0.05;
840 for (
size_t i = 0; i < path_bound->size(); ++i) {
841 double road_left_width = std::fabs(left_bound_adc) + kEpsilon;
842 double road_right_width = std::fabs(right_bound_adc) + kEpsilon;
844 (*path_bound)[i].s, &road_left_width, &road_right_width);
845 double left_bound_road = road_left_width - adc_half_width;
846 double right_bound_road = -road_right_width + adc_half_width;
848 if (left_bound_adc > (*path_bound)[i].l_upper.l) {
849 (*path_bound)[i].l_upper.l =
850 std::max(std::min(left_bound_adc, left_bound_road),
851 (*path_bound)[i].l_upper.l);
853 (*path_bound)[i].l_upper.id =
"adc";
855 if (right_bound_adc < (*path_bound)[i].l_lower.l) {
856 (*path_bound)[i].l_lower.l =
857 std::min(std::max(right_bound_adc, right_bound_road),
858 (*path_bound)[i].l_lower.l);
860 (*path_bound)[i].l_lower.id =
"adc";
870 for (
size_t i = 0; i < path_bound->size(); ++i) {
872 double curr_s = (*path_bound)[i].s;
873 double refline_offset_to_lane_center = 0.0;
874 reference_line.
GetOffsetToMap(curr_s, &refline_offset_to_lane_center);
875 (*path_bound)[i].l_lower.l -= refline_offset_to_lane_center;
876 (*path_bound)[i].l_upper.l -= refline_offset_to_lane_center;
882 const double y,
const PathBound& path_bound) {
885 if (point_sl.
s() > path_bound.back().s ||
887 path_bound.front().s - FLAGS_path_bounds_decider_resolution * 2) {
888 ADEBUG <<
"Longitudinally outside the boundary.";
892 while (idx_after <
static_cast<int>(path_bound.size()) &&
893 path_bound[idx_after].s < point_sl.
s()) {
896 ADEBUG <<
"The idx_after = " << idx_after;
897 ADEBUG <<
"The boundary is: "
898 <<
"[" << path_bound[idx_after].l_lower.l <<
", "
899 << path_bound[idx_after].l_upper.l <<
"].";
900 ADEBUG <<
"The point is at: " << point_sl.
l();
901 int idx_before = idx_after - 1;
902 if (path_bound[idx_before].l_lower.l <= point_sl.
l() &&
903 path_bound[idx_before].l_upper.l >= point_sl.
l() &&
904 path_bound[idx_after].l_lower.l <= point_sl.
l() &&
905 path_bound[idx_after].l_upper.l >= point_sl.
l()) {
908 ADEBUG <<
"Laterally outside the boundary.";
913 PathBoundPoint*
const path_bound_point,
bool is_left,
double init_l,
914 double heading,
double delta_s,
double init_frenet_kappa,
916 bool is_success =
false;
917 double protective_restrict = 0.0;
918 double relax_constraint = 0.0;
919 double radius = 1.0 / std::fabs(init_frenet_kappa);
920 double old_buffer = FLAGS_obstacle_lat_buffer;
921 double new_buffer = std::max(FLAGS_ego_front_slack_buffer,
922 FLAGS_nonstatic_obstacle_nudge_l_buffer);
924 if (init_frenet_kappa > 0 && heading < 0) {
926 delta_s, min_radius, heading, init_frenet_kappa,
927 &protective_restrict);
930 &protective_restrict);
934 std::max(path_bound_point->
l_upper.
l, init_l + protective_restrict);
935 AINFO <<
"init_pt_l: " << init_l
936 <<
", left_bound: " << path_bound_point->
l_upper.
l
937 <<
", diff s: " << delta_s <<
", radius: " << radius
938 <<
", protective_restrict: " << protective_restrict
939 <<
", left_obs_constraint: " << relax_constraint;
942 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
943 FLAGS_static_obstacle_nudge_l_buffer);
947 std::min(path_bound_point->
l_upper.
l + old_buffer - new_buffer,
949 AINFO <<
"left_obs_constraint: " << relax_constraint;
950 path_bound_point->
l_upper.
l = relax_constraint;
952 if (init_frenet_kappa < 0 && heading > 0) {
954 delta_s, min_radius, heading, init_frenet_kappa,
955 &protective_restrict);
958 &protective_restrict);
961 std::min(path_bound_point->
l_lower.
l, init_l + protective_restrict);
962 AINFO <<
"init_pt_l: " << init_l
963 <<
", right_bound: " << path_bound_point->
l_lower.
l
964 <<
", diff s: " << delta_s <<
", radius: " << radius
965 <<
", protective_restrict: " << protective_restrict
966 <<
", right_obs_constraint: " << relax_constraint;
969 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
970 FLAGS_static_obstacle_nudge_l_buffer);
974 std::max(path_bound_point->
l_lower.
l - old_buffer + new_buffer,
976 AINFO <<
"right_obs_constraint: " << relax_constraint;
977 path_bound_point->
l_lower.
l = relax_constraint;
984 if (path_boundary->size() < 2) {
985 AINFO <<
"path_boundary size = 0, return.";
988 const auto& veh_param =
991 std::max(veh_param.min_turn_radius(),
992 std::tan(veh_param.max_steer_angle() / veh_param.steer_ratio()) /
993 veh_param.wheel_base());
995 double init_frenet_kappa =
996 init_sl_state.second[2] /
997 std::pow(1 + std::pow(init_sl_state.second[1], 2), 1.5);
998 if (init_frenet_kappa < 0) {
999 init_frenet_kappa = std::min(
1000 -1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1002 init_frenet_kappa = std::max(
1003 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1006 const auto& init_pt = path_boundary->at(0);
1007 double init_frenet_heading =
1009 double init_pt_l = init_sl_state.second[0];
1010 bool left_calculate_success =
true;
1011 bool right_calculate_success =
true;
1012 for (
size_t i = 1; i < path_boundary->size(); ++i) {
1013 auto& left_bound = path_boundary->at(i).l_upper;
1014 auto& right_bound = path_boundary->at(i).l_lower;
1015 double delta_s = path_boundary->at(i).s - init_pt.s;
1016 if (delta_s > FLAGS_relax_path_s_threshold) {
1017 left_calculate_success =
false;
1018 right_calculate_success =
false;
1021 if (left_calculate_success &&
1023 path_boundary->at(i).is_nudge_bound[
LEFT_INDEX])) {
1025 &path_boundary->at(i),
true, init_pt_l, init_frenet_heading, delta_s,
1026 init_frenet_kappa, min_radius);
1028 if (right_calculate_success &&
1030 path_boundary->at(i).is_nudge_bound[
RIGHT_INDEX])) {
1032 &path_boundary->at(i),
false, init_pt_l, init_frenet_heading, delta_s,
1033 init_frenet_kappa, min_radius);
1035 if (!left_calculate_success && !right_calculate_success) {
1044 if (path_boundary->size() < 2) {
1045 AINFO <<
"path_boundary size = 0, return.";
1048 const auto& veh_param =
1051 std::max(veh_param.min_turn_radius(),
1052 std::tan(veh_param.max_steer_angle() / veh_param.steer_ratio()) /
1053 veh_param.wheel_base());
1055 double init_frenet_kappa =
1056 std::fabs(init_sl_state.second[2] /
1057 std::pow(1 + std::pow(init_sl_state.second[1], 2), 1.5));
1058 if (init_frenet_kappa < 0) {
1059 init_frenet_kappa = std::min(
1060 -1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1062 init_frenet_kappa = std::max(
1063 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1065 double kappa_radius = 1.0 / std::fabs(init_frenet_kappa);
1067 const auto& init_pt = path_boundary->at(0);
1068 double init_frenet_heading =
1070 double init_pt_l = init_sl_state.second[0];
1071 bool left_calculate_success =
true;
1072 bool right_calculate_success =
true;
1073 double new_buffer = std::max(FLAGS_ego_front_slack_buffer,
1074 FLAGS_nonstatic_obstacle_nudge_l_buffer);
1076 double delta_s = extra_path_bound.rear_axle_s - init_pt.s;
1077 if (delta_s > FLAGS_relax_path_s_threshold) {
1078 AINFO <<
"RelaxObsCornerBoundary delta_s: " << delta_s <<
" break";
1081 AINFO <<
"RelaxObsCornerBoundary check delta_s: " << delta_s;
1084 if (left_calculate_success) {
1085 double left_protective_restrict = 0.0;
1086 if (init_frenet_kappa > 0 && init_frenet_heading < 0) {
1087 left_calculate_success =
1089 delta_s, min_radius, init_frenet_heading, init_frenet_kappa,
1090 &left_protective_restrict);
1093 delta_s, kappa_radius, init_frenet_heading,
1094 &left_protective_restrict);
1097 double left_obs_constraint = std::max(
1098 extra_path_bound.upper_bound, init_pt_l + left_protective_restrict);
1099 AINFO <<
"extra_path_bound, init_pt_l: " << init_pt_l
1100 <<
", left_bound: " << extra_path_bound.upper_bound
1101 <<
", diff s: " << delta_s <<
", min_radius: " << min_radius
1102 <<
", init_frenet_heading: " << init_frenet_heading
1103 <<
", protective_restrict: " << left_protective_restrict
1104 <<
", left_obs_constraint: " << left_obs_constraint;
1105 left_obs_constraint = std::min(
1106 extra_path_bound.upper_bound + FLAGS_obstacle_lat_buffer - new_buffer,
1107 left_obs_constraint);
1108 AINFO <<
"extra_path_bound left_obs_constraint: " << left_obs_constraint;
1109 extra_path_bound.upper_bound = left_obs_constraint;
1112 if (right_calculate_success) {
1114 double right_protective_restrict = 0.0;
1115 if (init_frenet_kappa < 0 && init_frenet_heading > 0) {
1116 right_calculate_success =
1118 delta_s, min_radius, init_frenet_heading, init_frenet_kappa,
1119 &right_protective_restrict);
1122 delta_s, kappa_radius, init_frenet_heading,
1123 &right_protective_restrict);
1126 double right_obs_constraint = std::min(
1127 extra_path_bound.lower_bound, init_pt_l + right_protective_restrict);
1128 AINFO <<
"extra_path_bound, init_pt_l: " << init_pt_l
1129 <<
", right_bound: " << extra_path_bound.lower_bound
1130 <<
", diff s: " << delta_s <<
", min_radius: " << min_radius
1131 <<
", init_frenet_heading: " << init_frenet_heading
1132 <<
", protective_restrict: " << right_protective_restrict
1133 <<
", right_obs_constraint: " << right_obs_constraint;
1134 right_obs_constraint = std::max(
1135 extra_path_bound.lower_bound - FLAGS_obstacle_lat_buffer + new_buffer,
1136 right_obs_constraint);
1137 AINFO <<
"extra_path_bound, right_obs_constraint: "
1138 << right_obs_constraint;
1139 extra_path_bound.lower_bound = right_obs_constraint;
1142 if (!left_calculate_success && !right_calculate_success) {
1150 PathBoundary*
const path_boundary, std::string*
const blocked_id) {
1152 AINFO <<
"UpdateBlockInfoWithObsCornerBoundary, block id empty";
1159 *blocked_id = extra_path_bound->blocked_id;
1161 AINFO <<
"update block id: " << *blocked_id
1162 <<
", path_boundary size: " << path_boundary->size();
1164 if (path_boundary->size() < 1) {
1165 extra_path_bound->clear();
1166 AERROR <<
"UpdateBlockInfoWithObsCornerBoundary, new_path_index < 1";
1170 size_t new_path_index = path_boundary->size() - 1;
1171 while (extra_path_bound->size() > 0 &&
1172 (extra_path_bound->back().id == *blocked_id ||
1173 extra_path_bound->back().right_index > new_path_index)) {
1174 AINFO <<
"remove extra_path_bound: s "
1175 << extra_path_bound->back().rear_axle_s <<
", index ["
1176 << extra_path_bound->back().left_index <<
", "
1177 << extra_path_bound->back().right_index <<
"]";
1178 extra_path_bound->pop_back();
1184 const std::vector<SLPolygon>& sl_polygons,
1186 std::string*
const blocked_id) {
1188 if (FLAGS_enable_corner_constraint) {
1193 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)
double CalculateEquivalentEgoWidth(const ReferenceLineInfo &reference_line_info, double s, bool *is_left)
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