Apollo 11.0
自动驾驶开放平台
path_bounds_decider_util.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <algorithm>
20#include <functional>
21#include <limits>
22#include <set>
23#include <string>
24#include <tuple>
25#include <unordered_map>
26#include <vector>
27
34
35namespace apollo {
36namespace planning {
37
39
41 const ReferenceLineInfo& reference_line_info,
42 PathBoundary* const path_bound, SLState init_sl_state) {
43 // Sanity checks.
44 CHECK_NOTNULL(path_bound);
45 path_bound->clear();
46 const auto& reference_line = reference_line_info.reference_line();
47 path_bound->set_delta_s(FLAGS_path_bounds_decider_resolution);
48
49 const auto& vehicle_config =
50 common::VehicleConfigHelper::Instance()->GetConfig();
51 double index = 0;
52 const auto& reference_line_towing_l =
53 reference_line_info.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,
57 reference_line_info.GetCruiseSpeed() *
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);
65 }
66 index++;
67 }
68
69 // Return.
70 if (path_bound->empty()) {
71 ADEBUG << "Empty path boundary in InitPathBoundary";
72 return false;
73 }
74 return true;
75}
76
78 common::TrajectoryPoint planning_start_point,
79 const ReferenceLine& reference_line, SLState* init_sl_state) {
80 if (FLAGS_use_front_axe_center_in_path_planning) {
81 planning_start_point =
82 InferFrontAxeCenterFromRearAxeCenter(planning_start_point);
83 }
84 AINFO << std::fixed << "Plan at the starting point: x = "
85 << planning_start_point.path_point().x()
86 << ", y = " << planning_start_point.path_point().y()
87 << ", and angle = " << planning_start_point.path_point().theta();
88
89 // Initialize some private variables.
90 // ADC s/l info.
91 *init_sl_state = reference_line.ToFrenetFrame(planning_start_point);
92}
93
95 const ReferenceLine& reference_line, const double adc_s) {
96 double lane_left_width = 0.0;
97 double lane_right_width = 0.0;
98 if (!reference_line.GetLaneWidth(adc_s, &lane_left_width,
99 &lane_right_width)) {
100 constexpr double kDefaultLaneWidth = 5.0;
101 AWARN << "Failed to get lane width at planning start point.";
102 return kDefaultLaneWidth;
103 } else {
104 return lane_left_width + lane_right_width;
105 }
106}
107
109 double left_bound, double right_bound, BoundType left_type,
110 BoundType right_type, std::string left_id, std::string right_id,
111 PathBoundPoint* const bound_point) {
112 if (!UpdateLeftPathBoundaryWithBuffer(left_bound, left_type, left_id,
113 bound_point)) {
114 return false;
115 }
116 if (!UpdateRightPathBoundaryWithBuffer(right_bound, right_type, right_id,
117 bound_point)) {
118 return false;
119 }
120 return true;
121}
122
124 double left_bound, BoundType left_type, std::string left_id,
125 PathBoundPoint* const bound_point) {
126 double adc_half_width =
128 left_bound = left_bound - adc_half_width;
129 PathBoundPoint new_point = *bound_point;
130 if (new_point.l_upper.l > left_bound) {
131 new_point.l_upper.l = left_bound;
132 new_point.l_upper.type = left_type;
133 new_point.l_upper.id = left_id;
134 }
135 // Check if ADC is blocked.
136 // If blocked, don't update anything, return false.
137 if (new_point.l_lower.l > new_point.l_upper.l) {
138 ADEBUG << "Path is blocked at" << new_point.l_lower.l << " "
139 << new_point.l_upper.l;
140 return false;
141 }
142 // Otherwise, update path_boundaries and center_line; then return true.
143 *bound_point = new_point;
144 return true;
145}
146
148 double right_bound, BoundType right_type, std::string right_id,
149 PathBoundPoint* const bound_point) {
150 double adc_half_width =
152 right_bound = right_bound + adc_half_width;
153 PathBoundPoint new_point = *bound_point;
154 if (new_point.l_lower.l < right_bound) {
155 new_point.l_lower.l = right_bound;
156 new_point.l_lower.type = right_type;
157 new_point.l_lower.id = right_id;
158 }
159 // Check if ADC is blocked.
160 // If blocked, don't update anything, return false.
161 if (new_point.l_lower.l > new_point.l_upper.l) {
162 ADEBUG << "Path is blocked at";
163 return false;
164 }
165 // Otherwise, update path_boundaries and center_line; then return true.
166 *bound_point = new_point;
167 return true;
168}
169
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.";
175 }
176 double front_edge_to_center =
178 double trimmed_s =
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();
185 }
186 }
187}
188
190 const ReferenceLineInfo& reference_line_info,
191 std::vector<SLPolygon>* polygons, const SLState& init_sl_state) {
192 polygons->clear();
193 auto obstacles = reference_line_info.path_decision().obstacles();
194 const double adc_back_edge_s = reference_line_info.AdcSlBoundary().start_s();
195 for (const auto* obstacle : obstacles.Items()) {
196 if (!IsWithinPathDeciderScopeObstacle(*obstacle)) {
197 continue;
198 }
199 auto xy_poly = obstacle->PerceptionPolygon();
200
201 // if (obstacle->PerceptionSLBoundary().end_s() < init_sl_state.first[0]) {
202 // continue;
203 // }
204 if (obstacle->PerceptionSLBoundary().end_s() < adc_back_edge_s) {
205 continue;
206 }
207 const auto obstacle_sl = obstacle->PerceptionSLBoundary();
208 polygons->emplace_back(obstacle_sl, obstacle->Id(),
209 obstacle->Perception().type());
210 }
211 sort(polygons->begin(), polygons->end(),
212 [](const SLPolygon& a, const SLPolygon& b) {
213 return a.MinS() < b.MinS();
214 });
215}
216
218 const ReferenceLineInfo& reference_line_info,
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;
224 if (reference_line_info.IsChangeLanePath() ||
225 path_boundary->label().find("regular/left") != std::string::npos ||
226 path_boundary->label().find("regular/right") != std::string::npos) {
227 center_l.push_back(
228 (path_boundary->front().l_upper.l + path_boundary->front().l_lower.l) *
229 0.5);
230 max_nudge_check_distance =
231 std::max(FLAGS_max_nudge_check_distance_in_lk,
232 2 * VehicleConfigHelper::GetConfig().vehicle_param().length());
233 } else {
234 center_l.push_back(0.0);
235 max_nudge_check_distance =
236 std::max(FLAGS_max_nudge_check_distance_in_lc,
237 2 * VehicleConfigHelper::GetConfig().vehicle_param().length());
238 }
239
240 *narrowest_width =
241 path_boundary->front().l_upper.l - path_boundary->front().l_lower.l;
242 double mid_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();
247 // bool obs_overlap_with_refer_center = false;
248 const double adc_end_s = reference_line_info.AdcSlBoundary().end_s() + 1.0;
249 const double adc_start_s = reference_line_info.AdcSlBoundary().start_s();
250 const double adc_end_l = reference_line_info.AdcSlBoundary().end_l();
251
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;
257 auto begin_it =
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;
264 double eq_width = util::CalculateEquivalentEgoWidth(
265 reference_line_info, path_boundary_s, &is_left_width);
266 double left_half_width, right_half_width;
267 if (is_left_width) {
268 left_half_width = eq_width + FLAGS_obstacle_lat_buffer;
269 right_half_width =
271 FLAGS_obstacle_lat_buffer;
272 } else {
273 left_half_width =
275 FLAGS_obstacle_lat_buffer;
276 right_half_width = eq_width + FLAGS_obstacle_lat_buffer;
277 }
278
279 for (size_t j = 0; j < sl_polygon->size(); j++) {
280 if (sl_polygon->at(j).NudgeInfo() == SLPolygon::IGNORE) {
281 AINFO << "UpdatePathBoundaryBySLPolygon, ignore obs: "
282 << sl_polygon->at(j).id();
283 continue;
284 }
285 double min_s = sl_polygon->at(j).MinS();
286 double max_s =
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;
291 }
292 if (max_s < path_boundary_s) {
293 continue;
294 }
295 if (min_s > path_boundary_s) {
296 break;
297 }
298 // double adc_obs_edge_buffer = GetBufferBetweenADCCenterAndEdge();
299 sl_polygon->at(j).UpdatePassableInfo(left_bound.l, right_bound.l,
300 right_half_width, left_half_width,
301 path_boundary_s);
302
303 double l_lower = sl_polygon->at(j).GetRightBoundaryByS(path_boundary_s);
304 double l_upper = sl_polygon->at(j).GetLeftBoundaryByS(path_boundary_s);
305 PathBoundPoint obs_left_nudge_bound(
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;
311 // obs_overlap_with_refer_center =
312 // left_bound.l < path_boundary->at(i).towing_l ||
313 // right_bound.l > path_boundary->at(i).towing_l;
314
315 if (sl_polygon->at(j).NudgeInfo() == SLPolygon::UNDEFINED) {
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) {
325 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
326 AINFO << sl_polygon->at(j).id()
327 << " right nudge with init_sl_state";
328 } else {
329 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
330 AINFO << sl_polygon->at(j).id()
331 << " left nudge width init_sl_state";
332 }
333 } else if (path_boundary_s - adc_start_s > 0 &&
334 path_boundary_s - adc_end_s < 0) {
335 // check obs in side of ego
336 if (adc_end_l < obs_l) {
337 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
338 AINFO << sl_polygon->at(j).id()
339 << " right nudge with init_sl_state";
340 } else {
341 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
342 AINFO << sl_polygon->at(j).id()
343 << " left nudge width init_sl_state";
344 }
345 } else {
346 if (last_max_nudge_l < obs_l) {
347 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
348 AINFO << sl_polygon->at(j).id()
349 << " right nudge, according max_nudge_l";
350 } else {
351 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
352 AINFO << sl_polygon->at(j).id()
353 << " left nudge, according max_nudge_l";
354 }
355 }
356 } else {
357 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
358 AINFO << sl_polygon->at(j).id()
359 << " right nudge, left is not passable";
360 }
361 } else {
362 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
363 AINFO << sl_polygon->at(j).id()
364 << " left nudge, right is not passable";
365 }
366 } else {
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();
371 }
372 if (sl_polygon->at(j).NudgeInfo() == SLPolygon::RIGHT_NUDGE) {
373 // right nudge
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);
378 }
379 if (!sl_polygon->at(j).is_passable()[RIGHT_INDEX]) {
380 // boundary is blocked
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;
385 sl_polygon->at(j).SetNudgeInfo(SLPolygon::BLOCKED);
386 break;
387 }
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;
392 left_bound.type = BoundType::OBSTACLE;
393 left_bound.id = sl_polygon->at(j).id();
394 *narrowest_width =
395 std::min(*narrowest_width, left_bound.l - right_bound.l);
396 }
397 } else if (sl_polygon->at(j).NudgeInfo() == SLPolygon::LEFT_NUDGE) {
398 // left nudge
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);
403 }
404 if (!sl_polygon->at(j).is_passable()[LEFT_INDEX]) {
405 // boundary is blocked
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;
410 sl_polygon->at(j).SetNudgeInfo(SLPolygon::BLOCKED);
411 break;
412 }
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;
417 right_bound.type = BoundType::OBSTACLE;
418 right_bound.id = sl_polygon->at(j).id();
419 *narrowest_width =
420 std::min(*narrowest_width, left_bound.l - right_bound.l);
421 }
422 }
423 // obs_overlap_with_refer_center =
424 // left_bound.l < path_boundary->at(i).towing_l ||
425 // right_bound.l > path_boundary->at(i).towing_l;
426
427 // double current_center_l = obs_overlap_with_refer_center
428 // ? (left_bound.l + right_bound.l) / 2.0
429 // : path_boundary->at(i).towing_l;
430 // last_max_nudge_l = std::fabs(current_center_l - mid_l) >
431 // std::fabs(last_max_nudge_l - mid_l)
432 // ? current_center_l
433 // : last_max_nudge_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
437 : last_max_nudge_l;
438 }
439 // if blocked, trim path
440 if (!blocked_id->empty()) {
441 TrimPathBounds(i, path_boundary);
442 *narrowest_width = default_width;
443 return false;
444 }
445 // double current_center_l = obs_overlap_with_refer_center
446 // ? (left_bound.l + right_bound.l) / 2.0
447 // : path_boundary->at(i).towing_l;
448 // center_l.push_back(current_center_l);
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();
452 }
453 return true;
454}
455
457 double s, double l_lower, double l_upper, const PathBoundary& path_boundary,
458 ObsCornerConstraints* extra_constraints) {
459 size_t left_index = 0;
460 size_t right_index = 0;
461 double left_weight = 0.0;
462 double right_weight = 0.0;
463 if (!path_boundary.get_interpolated_s_weight(s, &left_weight, &right_weight,
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;
468 return false;
469 }
470 if (left_weight < 0.05 || right_weight < 0.05) {
471 // filter contraint that near evaulated point
472 return false;
473 }
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);
479 return true;
480}
481
483 SLPoint sl_pt, const PathBoundary& path_boundary,
484 ObsCornerConstraints* extra_constraints, bool is_left, std::string obs_id,
485 bool is_front_pt) {
486 size_t left_index = 0;
487 size_t right_index = 0;
488 double left_weight = 0.0;
489 double right_weight = 0.0;
490 if (!path_boundary.get_interpolated_s_weight(
491 sl_pt.s(), &left_weight, &right_weight, &left_index, &right_index)) {
492 AERROR << "Fail to find extra path bound point in path boundary: "
493 << sl_pt.s()
494 << ", path boundary start s: " << path_boundary.front().s
495 << ", path boundary end s: " << path_boundary.back().s;
496 return true;
497 }
498 // if (left_weight < 0.05 || right_weight < 0.05) {
499 // // filter contraint that near evaulated point
500 // return true;
501 // }
502
503 double bound_l_upper = path_boundary.get_upper_bound_by_interpolated_index(
504 left_weight, right_weight, left_index, right_index);
505 double bound_l_lower = path_boundary.get_lower_bound_by_interpolated_index(
506 left_weight, right_weight, left_index, right_index);
507
508 double corner_l = is_left ? sl_pt.l() - GetBufferBetweenADCCenterAndEdge()
510 if ((is_left && corner_l < bound_l_upper) ||
511 (!is_left && corner_l > bound_l_lower)) {
512 if (is_left) {
513 bound_l_upper = corner_l;
514 } else {
515 bound_l_lower = corner_l;
516 }
517 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
518 bound_l_upper, left_index, right_index,
519 sl_pt.s(), obs_id);
520 if (bound_l_upper < bound_l_lower) {
521 extra_constraints->blocked_id = obs_id;
522 extra_constraints->block_left_index = left_index;
523 extra_constraints->block_right_index = right_index;
524 AINFO << "AddCornerPoint blocked id: " << obs_id << ", index ["
525 << left_index << ", " << right_index << "]";
526 return false;
527 }
528 }
529
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;
533 if (!path_boundary.get_interpolated_s_weight(
534 add_s, &left_weight, &right_weight, &left_index, &right_index)) {
535 return true;
536 }
537
538 bound_l_upper = path_boundary.get_upper_bound_by_interpolated_index(
539 left_weight, right_weight, left_index, right_index);
540 bound_l_lower = path_boundary.get_lower_bound_by_interpolated_index(
541 left_weight, right_weight, left_index, right_index);
542
543 if ((is_left && corner_l < bound_l_upper) ||
544 (!is_left && corner_l > bound_l_lower)) {
545 if (is_left) {
546 bound_l_upper = corner_l;
547 } else {
548 bound_l_lower = corner_l;
549 }
550 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
551 bound_l_upper, left_index, right_index,
552 add_s, obs_id);
553 if (bound_l_upper < bound_l_lower) {
554 extra_constraints->blocked_id = obs_id;
555 extra_constraints->block_left_index = left_index;
556 extra_constraints->block_right_index = right_index;
557 AINFO << "AddCornerPoint blocked id: " << obs_id << ", index ["
558 << left_index << ", " << right_index << "]";
559 return false;
560 }
561 }
562 }
563 return true;
564}
565
567 const std::vector<SLPolygon>& sl_polygons,
568 PathBoundary* const path_boundary) {
569 auto* extra_path_bound = path_boundary->mutable_extra_path_bound();
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;
574 break;
575 }
576 if (obs_polygon.MaxS() < path_boundary->front().s) {
577 continue;
578 }
579 if (obs_polygon.NudgeInfo() == SLPolygon::LEFT_NUDGE) {
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);
583 if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, false,
584 obs_polygon.id(), is_front_pt)) {
585 break;
586 }
587 }
588 // for (auto pt : obs_polygon.LeftBoundary()) {
589 // if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, false,
590 // obs_polygon.id())) {
591 // break;
592 // }
593 // }
594 } else if (obs_polygon.NudgeInfo() == SLPolygon::RIGHT_NUDGE) {
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);
598 if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, true,
599 obs_polygon.id(), is_front_pt)) {
600 break;
601 }
602 }
603 // for (auto pt : obs_polygon.RightBoundary()) {
604 // if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, true,
605 // obs_polygon.id())) {
606 // break;
607 // }
608 // }
609 } else {
610 AINFO << "no nugde info, ignore obs: " << obs_polygon.id();
611 }
612 if (!extra_path_bound->blocked_id.empty()) {
613 break;
614 }
615 }
616 // sort(extra_path_bound->begin(), extra_path_bound->end(),
617 // [](const InterPolatedPoint& a, const InterPolatedPoint& b) {
618 // return a.rear_axle_s < b.rear_axle_s;
619 // });
620}
621
623 PathBoundary* const path_boundary) {
624 auto* adc_vertex_bound = path_boundary->mutable_adc_vertex_bound();
625 // front_edge_to_center in Apollo is the front edge to rear center
626 double front_edge_to_center = apollo::common::VehicleConfigHelper::GetConfig()
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()) {
632 continue;
633 }
634 size_t left_index = 0;
635 size_t right_index = 0;
636 double left_weight = 0.0;
637 double right_weight = 0.0;
638 if (!path_boundary->get_interpolated_s_weight(rear_axle_s, &left_weight,
639 &right_weight, &left_index,
640 &right_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;
645 continue;
646 }
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);
650 }
651 adc_vertex_bound->front_edge_to_center = front_edge_to_center;
652}
653
655 const ReferenceLineInfo& reference_line_info,
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) {
659 UpdatePathBoundaryBySLPolygon(reference_line_info, sl_polygons, init_sl_state,
660 path_boundary, blocking_obstacle_id,
661 narrowest_width);
662 AddExtraPathBound(*sl_polygons, path_boundary, init_sl_state,
663 blocking_obstacle_id);
664 return true;
665}
666
668 double adc_half_width =
670
671 return (adc_half_width + FLAGS_obstacle_lat_buffer);
672}
673
675 const Obstacle& obstacle) {
676 // Obstacle should be non-virtual.
677 if (obstacle.IsVirtual()) {
678 return false;
679 }
680 // Obstacle should not have ignore decision.
681 if (obstacle.HasLongitudinalDecision() && obstacle.HasLateralDecision() &&
682 obstacle.IsIgnore()) {
683 return false;
684 }
685 // Obstacle should not be moving obstacle.
686 if (!obstacle.IsStatic() ||
687 obstacle.speed() > FLAGS_static_obstacle_speed_threshold) {
688 return false;
689 }
690 // TODO(jiacheng):
691 // Some obstacles are not moving, but only because they are waiting for
692 // red light (traffic rule) or because they are blocked by others (social).
693 // These obstacles will almost certainly move in the near future and we
694 // should not side-pass such obstacles.
695
696 return true;
697}
698
701 const common::TrajectoryPoint& traj_point) {
702 double front_to_rear_axe_distance =
704 common::TrajectoryPoint ret = traj_point;
705 ret.mutable_path_point()->set_x(
706 traj_point.path_point().x() +
707 front_to_rear_axe_distance * std::cos(traj_point.path_point().theta()));
708 ret.mutable_path_point()->set_y(
709 traj_point.path_point().y() +
710 front_to_rear_axe_distance * std::sin(traj_point.path_point().theta()));
711 return ret;
712}
713
715 const ReferenceLineInfo& reference_line_info, const SLState& init_sl_state,
716 PathBoundary* const path_bound) {
717 // Sanity checks.
718 CHECK_NOTNULL(path_bound);
719 ACHECK(!path_bound->empty());
720 const ReferenceLine& reference_line = reference_line_info.reference_line();
721 double adc_lane_width =
722 GetADCLaneWidth(reference_line, init_sl_state.first[0]);
723 // Go through every point, update the boundary based on lane info and
724 // ADC's position.
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;
730 // 1. Get the current lane width at current point.
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;
739 } else {
740 reference_line.GetOffsetToMap(curr_s, &offset_to_lane_center);
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;
745 }
746
747 // 3. Calculate the proper boundary based on lane-width, ADC's position,
748 // and ADC's velocity.
749 double offset_to_map = 0.0;
750 reference_line.GetOffsetToMap(curr_s, &offset_to_map);
751
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;
756 // 4. Update the boundary.
757 if (!UpdatePathBoundaryWithBuffer(curr_left_bound, curr_right_bound,
759 &path_bound->at(i))) {
760 path_blocked_idx = static_cast<int>(i);
761 }
762 if (path_blocked_idx != -1) {
763 break;
764 }
765 }
766
767 PathBoundsDeciderUtil::TrimPathBounds(path_blocked_idx, path_bound);
768
769 return true;
770}
771
773 const ReferenceLineInfo& reference_line_info, const SLState& init_sl_state,
774 PathBoundary* const path_bound) {
775 // Sanity checks.
776 CHECK_NOTNULL(path_bound);
777 ACHECK(!path_bound->empty());
778 const ReferenceLine& reference_line = reference_line_info.reference_line();
779 double adc_lane_width =
780 GetADCLaneWidth(reference_line, init_sl_state.first[0]);
781 // Go through every point, update the boudnary based on the road boundary.
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) {
786 // 1. Get road boundary.
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;
795 }
796
797 past_road_left_width = curr_road_left_width;
798 past_road_right_width = curr_road_right_width;
799
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;
805
806 // 2. Update into path_bound.
807 if (!UpdatePathBoundaryWithBuffer(curr_left_bound, curr_right_bound,
809 &path_bound->at(i))) {
810 path_blocked_idx = static_cast<int>(i);
811 }
812 if (path_blocked_idx != -1) {
813 break;
814 }
815 }
816 AINFO << "path_blocked_idx: " << path_blocked_idx;
817 TrimPathBounds(path_blocked_idx, path_bound);
818 return true;
819}
820
822 const ReferenceLineInfo& reference_line_info, const SLState& init_sl_state,
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;
826
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;
838
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;
843 reference_line_info.reference_line().GetRoadWidth(
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;
847
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);
852 (*path_bound)[i].l_upper.type = BoundType::ADC;
853 (*path_bound)[i].l_upper.id = "adc";
854 }
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);
859 (*path_bound)[i].l_lower.type = BoundType::ADC;
860 (*path_bound)[i].l_lower.id = "adc";
861 }
862 }
863 return true;
864}
865
867 const ReferenceLineInfo& reference_line_info,
868 PathBoundary* const path_bound) {
869 const ReferenceLine& reference_line = reference_line_info.reference_line();
870 for (size_t i = 0; i < path_bound->size(); ++i) {
871 // 1. Get road boundary.
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;
877 }
878}
879
881 const ReferenceLineInfo& reference_line_info, const double x,
882 const double y, const PathBound& path_bound) {
883 common::SLPoint point_sl;
884 reference_line_info.reference_line().XYToSL({x, y}, &point_sl);
885 if (point_sl.s() > path_bound.back().s ||
886 point_sl.s() <
887 path_bound.front().s - FLAGS_path_bounds_decider_resolution * 2) {
888 ADEBUG << "Longitudinally outside the boundary.";
889 return -1;
890 }
891 int idx_after = 0;
892 while (idx_after < static_cast<int>(path_bound.size()) &&
893 path_bound[idx_after].s < point_sl.s()) {
894 ++idx_after;
895 }
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()) {
906 return idx_after;
907 }
908 ADEBUG << "Laterally outside the boundary.";
909 return -1;
910}
911
913 PathBoundPoint* const path_bound_point, bool is_left, double init_l,
914 double heading, double delta_s, double init_frenet_kappa,
915 double min_radius) {
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);
923 if (is_left) {
924 if (init_frenet_kappa > 0 && heading < 0) {
926 delta_s, min_radius, heading, init_frenet_kappa,
927 &protective_restrict);
928 } else {
929 is_success = util::left_arc_bound_with_heading(delta_s, radius, heading,
930 &protective_restrict);
931 }
932
933 relax_constraint =
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;
940
941 if (path_bound_point->is_nudge_bound[LEFT_INDEX]) {
942 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
943 FLAGS_static_obstacle_nudge_l_buffer);
944 }
945
946 relax_constraint =
947 std::min(path_bound_point->l_upper.l + old_buffer - new_buffer,
948 relax_constraint);
949 AINFO << "left_obs_constraint: " << relax_constraint;
950 path_bound_point->l_upper.l = relax_constraint;
951 } else {
952 if (init_frenet_kappa < 0 && heading > 0) {
954 delta_s, min_radius, heading, init_frenet_kappa,
955 &protective_restrict);
956 } else {
957 is_success = util::right_arc_bound_with_heading(delta_s, radius, heading,
958 &protective_restrict);
959 }
960 relax_constraint =
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;
967
968 if (path_bound_point->is_nudge_bound[RIGHT_INDEX]) {
969 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
970 FLAGS_static_obstacle_nudge_l_buffer);
971 }
972
973 relax_constraint =
974 std::max(path_bound_point->l_lower.l - old_buffer + new_buffer,
975 relax_constraint);
976 AINFO << "right_obs_constraint: " << relax_constraint;
977 path_bound_point->l_lower.l = relax_constraint;
978 }
979 return is_success;
980}
981
983 PathBoundary* const path_boundary, const SLState& init_sl_state) {
984 if (path_boundary->size() < 2) {
985 AINFO << "path_boundary size = 0, return.";
986 return false;
987 }
988 const auto& veh_param =
990 double min_radius =
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());
994
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);
1001 } else {
1002 init_frenet_kappa = std::max(
1003 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1004 }
1005
1006 const auto& init_pt = path_boundary->at(0);
1007 double init_frenet_heading =
1008 common::math::Vec2d(1.0, init_sl_state.second[1]).Angle();
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;
1019 break;
1020 }
1021 if (left_calculate_success &&
1022 (left_bound.type == BoundType::OBSTACLE ||
1023 path_boundary->at(i).is_nudge_bound[LEFT_INDEX])) {
1024 left_calculate_success = RelaxBoundaryPoint(
1025 &path_boundary->at(i), true, init_pt_l, init_frenet_heading, delta_s,
1026 init_frenet_kappa, min_radius);
1027 }
1028 if (right_calculate_success &&
1029 (right_bound.type == BoundType::OBSTACLE ||
1030 path_boundary->at(i).is_nudge_bound[RIGHT_INDEX])) {
1031 right_calculate_success = RelaxBoundaryPoint(
1032 &path_boundary->at(i), false, init_pt_l, init_frenet_heading, delta_s,
1033 init_frenet_kappa, min_radius);
1034 }
1035 if (!left_calculate_success && !right_calculate_success) {
1036 break;
1037 }
1038 }
1039 return true;
1040}
1041
1043 PathBoundary* const path_boundary, const SLState& init_sl_state) {
1044 if (path_boundary->size() < 2) {
1045 AINFO << "path_boundary size = 0, return.";
1046 return false;
1047 }
1048 const auto& veh_param =
1050 double min_radius =
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());
1054
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);
1061 } else {
1062 init_frenet_kappa = std::max(
1063 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1064 }
1065 double kappa_radius = 1.0 / std::fabs(init_frenet_kappa);
1066
1067 const auto& init_pt = path_boundary->at(0);
1068 double init_frenet_heading =
1069 common::math::Vec2d(1.0, init_sl_state.second[1]).Angle();
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);
1075 for (auto& extra_path_bound : *(path_boundary->mutable_extra_path_bound())) {
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";
1079 break;
1080 }
1081 AINFO << "RelaxObsCornerBoundary check delta_s: " << delta_s;
1082
1083 // calculate the left side
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);
1091 } else {
1092 left_calculate_success = util::left_arc_bound_with_heading(
1093 delta_s, kappa_radius, init_frenet_heading,
1094 &left_protective_restrict);
1095 }
1096
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;
1110 }
1111
1112 if (right_calculate_success) {
1113 // calculate the right side
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);
1120 } else {
1121 right_calculate_success = util::right_arc_bound_with_heading(
1122 delta_s, kappa_radius, init_frenet_heading,
1123 &right_protective_restrict);
1124 }
1125
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;
1140 }
1141
1142 if (!left_calculate_success && !right_calculate_success) {
1143 break;
1144 }
1145 }
1146 return true;
1147}
1148
1150 PathBoundary* const path_boundary, std::string* const blocked_id) {
1151 if (path_boundary->extra_path_bound().blocked_id.empty()) {
1152 AINFO << "UpdateBlockInfoWithObsCornerBoundary, block id empty";
1153 return true;
1154 }
1155 auto* extra_path_bound = path_boundary->mutable_extra_path_bound();
1156 size_t path_boundary_block_index = extra_path_bound->block_right_index;
1157
1158 // trim path boundary width corner constraints block obstacle id
1159 *blocked_id = extra_path_bound->blocked_id;
1160 TrimPathBounds(path_boundary_block_index, path_boundary);
1161 AINFO << "update block id: " << *blocked_id
1162 << ", path_boundary size: " << path_boundary->size();
1163
1164 if (path_boundary->size() < 1) {
1165 extra_path_bound->clear();
1166 AERROR << "UpdateBlockInfoWithObsCornerBoundary, new_path_index < 1";
1167 return false;
1168 }
1169
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();
1179 }
1180 return false;
1181}
1182
1184 const std::vector<SLPolygon>& sl_polygons,
1185 PathBoundary* const path_boundary, const SLState& init_sl_state,
1186 std::string* const blocked_id) {
1187 RelaxEgoPathBoundary(path_boundary, init_sl_state);
1188 if (FLAGS_enable_corner_constraint) {
1189 AddCornerBounds(sl_polygons, path_boundary);
1190 RelaxObsCornerBoundary(path_boundary, init_sl_state);
1191 UpdateBlockInfoWithObsCornerBoundary(path_boundary, blocked_id);
1192 }
1193 if (FLAGS_enable_adc_vertex_constraint) {
1194 AddAdcVertexBounds(path_boundary);
1195 }
1196 return true;
1197}
1198
1199} // namespace planning
1200} // namespace apollo
@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.
Definition vec2d.h:42
double Angle() const
Gets the angle between the vector and the positive x semi-axis
Definition vec2d.cc:37
This is the class that associates an Obstacle with its path properties.
Definition obstacle.h:62
bool HasLongitudinalDecision() const
Definition obstacle.cc:636
bool HasLateralDecision() const
Definition obstacle.cc:631
double speed() const
Definition obstacle.h:78
bool IsIgnore() const
Check if this object can be safely ignored.
Definition obstacle.cc:585
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()
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.
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.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
Some util functions.
bool left_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
Definition util.cc:243
bool right_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
Definition util.cc:258
double CalculateEquivalentEgoWidth(const ReferenceLineInfo &reference_line_info, double s, bool *is_left)
Definition util.cc:160
bool left_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
Definition util.cc:272
bool right_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
Definition util.cc:294
std::pair< std::array< double, 3 >, std::array< double, 3 > > SLState
std::vector< PathBoundPoint > PathBound
class register implement
Definition arena_queue.h:37
#define LEFT_INDEX
#define RIGHT_INDEX
optional VehicleParam vehicle_param