Apollo 10.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 const double ego_front_to_center =
52 vehicle_config.vehicle_param().front_edge_to_center();
53 double index = 0;
54 const auto& reference_line_towing_l =
55 reference_line_info.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,
59 reference_line_info.GetCruiseSpeed() *
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);
67 }
68 index++;
69 }
70
71 // Return.
72 if (path_bound->empty()) {
73 ADEBUG << "Empty path boundary in InitPathBoundary";
74 return false;
75 }
76 return true;
77}
78
80 common::TrajectoryPoint planning_start_point,
81 const ReferenceLine& reference_line, SLState* init_sl_state) {
82 if (FLAGS_use_front_axe_center_in_path_planning) {
83 planning_start_point =
84 InferFrontAxeCenterFromRearAxeCenter(planning_start_point);
85 }
86 AINFO << std::fixed << "Plan at the starting point: x = "
87 << planning_start_point.path_point().x()
88 << ", y = " << planning_start_point.path_point().y()
89 << ", and angle = " << planning_start_point.path_point().theta();
90
91 // Initialize some private variables.
92 // ADC s/l info.
93 *init_sl_state = reference_line.ToFrenetFrame(planning_start_point);
94}
95
97 const ReferenceLine& reference_line, const double adc_s) {
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;
105 } else {
106 return lane_left_width + lane_right_width;
107 }
108}
109
111 double left_bound, double right_bound, BoundType left_type,
112 BoundType right_type, std::string left_id, std::string right_id,
113 PathBoundPoint* const bound_point) {
114 if (!UpdateLeftPathBoundaryWithBuffer(left_bound, left_type, left_id,
115 bound_point)) {
116 return false;
117 }
118 if (!UpdateRightPathBoundaryWithBuffer(right_bound, right_type, right_id,
119 bound_point)) {
120 return false;
121 }
122 return true;
123}
124
126 double left_bound, BoundType left_type, std::string left_id,
127 PathBoundPoint* const bound_point) {
128 double adc_half_width =
130 left_bound = left_bound - adc_half_width;
131 PathBoundPoint new_point = *bound_point;
132 if (new_point.l_upper.l > left_bound) {
133 new_point.l_upper.l = left_bound;
134 new_point.l_upper.type = left_type;
135 new_point.l_upper.id = left_id;
136 }
137 // Check if ADC is blocked.
138 // If blocked, don't update anything, return false.
139 if (new_point.l_lower.l > new_point.l_upper.l) {
140 ADEBUG << "Path is blocked at" << new_point.l_lower.l << " "
141 << new_point.l_upper.l;
142 return false;
143 }
144 // Otherwise, update path_boundaries and center_line; then return true.
145 *bound_point = new_point;
146 return true;
147}
148
150 double right_bound, BoundType right_type, std::string right_id,
151 PathBoundPoint* const bound_point) {
152 double adc_half_width =
154 right_bound = right_bound + adc_half_width;
155 PathBoundPoint new_point = *bound_point;
156 if (new_point.l_lower.l < right_bound) {
157 new_point.l_lower.l = right_bound;
158 new_point.l_lower.type = right_type;
159 new_point.l_lower.id = right_id;
160 }
161 // Check if ADC is blocked.
162 // If blocked, don't update anything, return false.
163 if (new_point.l_lower.l > new_point.l_upper.l) {
164 ADEBUG << "Path is blocked at";
165 return false;
166 }
167 // Otherwise, update path_boundaries and center_line; then return true.
168 *bound_point = new_point;
169 return true;
170}
171
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.";
177 }
178 double front_edge_to_center =
180 double trimmed_s =
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();
187 }
188 }
189}
190
192 const ReferenceLineInfo& reference_line_info,
193 std::vector<SLPolygon>* polygons, const SLState& init_sl_state) {
194 polygons->clear();
195 auto obstacles = reference_line_info.path_decision().obstacles();
196 const double adc_back_edge_s = reference_line_info.AdcSlBoundary().start_s();
197 for (const auto* obstacle : obstacles.Items()) {
198 if (!IsWithinPathDeciderScopeObstacle(*obstacle)) {
199 continue;
200 }
201 auto xy_poly = obstacle->PerceptionPolygon();
202
203 // if (obstacle->PerceptionSLBoundary().end_s() < init_sl_state.first[0]) {
204 // continue;
205 // }
206 if (obstacle->PerceptionSLBoundary().end_s() < adc_back_edge_s) {
207 continue;
208 }
209 const auto obstacle_sl = obstacle->PerceptionSLBoundary();
210 polygons->emplace_back(obstacle_sl, obstacle->Id(),
211 obstacle->Perception().type());
212 }
213 sort(polygons->begin(), polygons->end(),
214 [](const SLPolygon& a, const SLPolygon& b) {
215 return a.MinS() < b.MinS();
216 });
217}
218
220 const ReferenceLineInfo& reference_line_info,
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;
226 if (reference_line_info.IsChangeLanePath() ||
227 path_boundary->label().find("regular/left") != std::string::npos ||
228 path_boundary->label().find("regular/right") != std::string::npos) {
229 center_l.push_back(
230 (path_boundary->front().l_upper.l + path_boundary->front().l_lower.l) *
231 0.5);
232 max_nudge_check_distance = FLAGS_max_nudge_check_distance_in_lk;
233 } else {
234 center_l.push_back(0.0);
235 max_nudge_check_distance = FLAGS_max_nudge_check_distance_in_lc;
236 }
237
238 *narrowest_width =
239 path_boundary->front().l_upper.l - path_boundary->front().l_lower.l;
240 double mid_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();
245 // bool obs_overlap_with_refer_center = false;
246
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;
252 auto begin_it =
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++) {
259 if (sl_polygon->at(j).NudgeInfo() == SLPolygon::IGNORE) {
260 AINFO << "UpdatePathBoundaryBySLPolygon, ignore obs: "
261 << sl_polygon->at(j).id();
262 continue;
263 }
264 double min_s = sl_polygon->at(j).MinS();
265 double max_s =
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;
270 }
271 if (max_s < path_boundary_s) {
272 continue;
273 }
274 if (min_s > path_boundary_s) {
275 break;
276 }
277 double adc_obs_edge_buffer = GetBufferBetweenADCCenterAndEdge();
278 sl_polygon->at(j).UpdatePassableInfo(left_bound.l, right_bound.l,
279 adc_obs_edge_buffer);
280
281 double l_lower = sl_polygon->at(j).GetRightBoundaryByS(path_boundary_s);
282 double l_upper = sl_polygon->at(j).GetLeftBoundaryByS(path_boundary_s);
283 PathBoundPoint obs_left_nudge_bound(
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;
289 // obs_overlap_with_refer_center =
290 // left_bound.l < path_boundary->at(i).towing_l ||
291 // right_bound.l > path_boundary->at(i).towing_l;
292
293 if (sl_polygon->at(j).NudgeInfo() == SLPolygon::UNDEFINED) {
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) {
303 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
304 AINFO << sl_polygon->at(j).id()
305 << " right nudge with init_sl_state";
306 } else {
307 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
308 AINFO << sl_polygon->at(j).id()
309 << " left nudge width init_sl_state";
310 }
311 } else {
312 if (last_max_nudge_l < obs_l) {
313 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
314 AINFO << sl_polygon->at(j).id()
315 << " right nudge, according max_nudge_l";
316 } else {
317 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
318 AINFO << sl_polygon->at(j).id()
319 << " left nudge, according max_nudge_l";
320 }
321 }
322 } else {
323 sl_polygon->at(j).SetNudgeInfo(SLPolygon::RIGHT_NUDGE);
324 AINFO << sl_polygon->at(j).id()
325 << " right nudge, left is not passable";
326 }
327 } else {
328 sl_polygon->at(j).SetNudgeInfo(SLPolygon::LEFT_NUDGE);
329 AINFO << sl_polygon->at(j).id()
330 << " left nudge, right is not passable";
331 }
332 } else {
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();
337 }
338 if (sl_polygon->at(j).NudgeInfo() == SLPolygon::RIGHT_NUDGE) {
339 // right nudge
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);
344 }
345 if (!sl_polygon->at(j).is_passable()[RIGHT_INDEX]) {
346 // boundary is blocked
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;
351 sl_polygon->at(j).SetNudgeInfo(SLPolygon::BLOCKED);
352 break;
353 }
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;
358 left_bound.type = BoundType::OBSTACLE;
359 left_bound.id = sl_polygon->at(j).id();
360 *narrowest_width =
361 std::min(*narrowest_width, left_bound.l - right_bound.l);
362 }
363 } else if (sl_polygon->at(j).NudgeInfo() == SLPolygon::LEFT_NUDGE) {
364 // left nudge
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);
369 }
370 if (!sl_polygon->at(j).is_passable()[LEFT_INDEX]) {
371 // boundary is blocked
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;
376 sl_polygon->at(j).SetNudgeInfo(SLPolygon::BLOCKED);
377 break;
378 }
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;
383 right_bound.type = BoundType::OBSTACLE;
384 right_bound.id = sl_polygon->at(j).id();
385 *narrowest_width =
386 std::min(*narrowest_width, left_bound.l - right_bound.l);
387 }
388 }
389 // obs_overlap_with_refer_center =
390 // left_bound.l < path_boundary->at(i).towing_l ||
391 // right_bound.l > path_boundary->at(i).towing_l;
392
393 // double current_center_l = obs_overlap_with_refer_center
394 // ? (left_bound.l + right_bound.l) / 2.0
395 // : path_boundary->at(i).towing_l;
396 // last_max_nudge_l = std::fabs(current_center_l - mid_l) >
397 // std::fabs(last_max_nudge_l - mid_l)
398 // ? current_center_l
399 // : last_max_nudge_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
403 : last_max_nudge_l;
404 }
405 // if blocked, trim path
406 if (!blocked_id->empty()) {
407 TrimPathBounds(i, path_boundary);
408 *narrowest_width = default_width;
409 return false;
410 }
411 // double current_center_l = obs_overlap_with_refer_center
412 // ? (left_bound.l + right_bound.l) / 2.0
413 // : path_boundary->at(i).towing_l;
414 // center_l.push_back(current_center_l);
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();
418 }
419 return true;
420}
421
423 double s, double l_lower, double l_upper, const PathBoundary& path_boundary,
424 ObsCornerConstraints* extra_constraints) {
425 size_t left_index = 0;
426 size_t right_index = 0;
427 double left_weight = 0.0;
428 double right_weight = 0.0;
429 if (!path_boundary.get_interpolated_s_weight(s, &left_weight, &right_weight,
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;
434 return false;
435 }
436 if (left_weight < 0.05 || right_weight < 0.05) {
437 // filter contraint that near evaulated point
438 return false;
439 }
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);
445 return true;
446}
447
449 SLPoint sl_pt, const PathBoundary& path_boundary,
450 ObsCornerConstraints* extra_constraints, bool is_left, std::string obs_id,
451 bool is_front_pt) {
452 size_t left_index = 0;
453 size_t right_index = 0;
454 double left_weight = 0.0;
455 double right_weight = 0.0;
456 if (!path_boundary.get_interpolated_s_weight(
457 sl_pt.s(), &left_weight, &right_weight, &left_index, &right_index)) {
458 AERROR << "Fail to find extra path bound point in path boundary: "
459 << sl_pt.s()
460 << ", path boundary start s: " << path_boundary.front().s
461 << ", path boundary end s: " << path_boundary.back().s;
462 return true;
463 }
464 // if (left_weight < 0.05 || right_weight < 0.05) {
465 // // filter contraint that near evaulated point
466 // return true;
467 // }
468
469 double bound_l_upper = path_boundary.get_upper_bound_by_interpolated_index(
470 left_weight, right_weight, left_index, right_index);
471 double bound_l_lower = path_boundary.get_lower_bound_by_interpolated_index(
472 left_weight, right_weight, left_index, right_index);
473
474 double corner_l = is_left ? sl_pt.l() - GetBufferBetweenADCCenterAndEdge()
476 if ((is_left && corner_l < bound_l_upper) ||
477 (!is_left && corner_l > bound_l_lower)) {
478 if (is_left) {
479 bound_l_upper = corner_l;
480 } else {
481 bound_l_lower = corner_l;
482 }
483 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
484 bound_l_upper, left_index, right_index,
485 sl_pt.s(), obs_id);
486 if (bound_l_upper < bound_l_lower) {
487 extra_constraints->blocked_id = obs_id;
488 extra_constraints->block_left_index = left_index;
489 extra_constraints->block_right_index = right_index;
490 AINFO << "AddCornerPoint blocked id: " << obs_id << ", index ["
491 << left_index << ", " << right_index << "]";
492 return false;
493 }
494 }
495
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;
499 if (!path_boundary.get_interpolated_s_weight(
500 add_s, &left_weight, &right_weight, &left_index, &right_index)) {
501 return true;
502 }
503
504 bound_l_upper = path_boundary.get_upper_bound_by_interpolated_index(
505 left_weight, right_weight, left_index, right_index);
506 bound_l_lower = path_boundary.get_lower_bound_by_interpolated_index(
507 left_weight, right_weight, left_index, right_index);
508
509 if ((is_left && corner_l < bound_l_upper) ||
510 (!is_left && corner_l > bound_l_lower)) {
511 if (is_left) {
512 bound_l_upper = corner_l;
513 } else {
514 bound_l_lower = corner_l;
515 }
516 extra_constraints->emplace_back(left_weight, right_weight, bound_l_lower,
517 bound_l_upper, left_index, right_index,
518 add_s, obs_id);
519 if (bound_l_upper < bound_l_lower) {
520 extra_constraints->blocked_id = obs_id;
521 extra_constraints->block_left_index = left_index;
522 extra_constraints->block_right_index = right_index;
523 AINFO << "AddCornerPoint blocked id: " << obs_id << ", index ["
524 << left_index << ", " << right_index << "]";
525 return false;
526 }
527 }
528 }
529 return true;
530}
531
533 const std::vector<SLPolygon>& sl_polygons,
534 PathBoundary* const path_boundary) {
535 auto* extra_path_bound = path_boundary->mutable_extra_path_bound();
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;
540 break;
541 }
542 if (obs_polygon.MaxS() < path_boundary->front().s) {
543 continue;
544 }
545 if (obs_polygon.NudgeInfo() == SLPolygon::LEFT_NUDGE) {
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);
549 if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, false,
550 obs_polygon.id(), is_front_pt)) {
551 break;
552 }
553 }
554 // for (auto pt : obs_polygon.LeftBoundary()) {
555 // if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, false,
556 // obs_polygon.id())) {
557 // break;
558 // }
559 // }
560 } else if (obs_polygon.NudgeInfo() == SLPolygon::RIGHT_NUDGE) {
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);
564 if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, true,
565 obs_polygon.id(), is_front_pt)) {
566 break;
567 }
568 }
569 // for (auto pt : obs_polygon.RightBoundary()) {
570 // if (!AddCornerPoint(pt, *path_boundary, extra_path_bound, true,
571 // obs_polygon.id())) {
572 // break;
573 // }
574 // }
575 } else {
576 AINFO << "no nugde info, ignore obs: " << obs_polygon.id();
577 }
578 if (!extra_path_bound->blocked_id.empty()) {
579 break;
580 }
581 }
582 // sort(extra_path_bound->begin(), extra_path_bound->end(),
583 // [](const InterPolatedPoint& a, const InterPolatedPoint& b) {
584 // return a.rear_axle_s < b.rear_axle_s;
585 // });
586}
587
589 PathBoundary* const path_boundary) {
590 auto* adc_vertex_bound = path_boundary->mutable_adc_vertex_bound();
591 // front_edge_to_center in Apollo is the front edge to rear center
592 double front_edge_to_center = apollo::common::VehicleConfigHelper::GetConfig()
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()) {
598 continue;
599 }
600 size_t left_index = 0;
601 size_t right_index = 0;
602 double left_weight = 0.0;
603 double right_weight = 0.0;
604 if (!path_boundary->get_interpolated_s_weight(rear_axle_s, &left_weight,
605 &right_weight, &left_index,
606 &right_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;
611 continue;
612 }
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);
616 }
617 adc_vertex_bound->front_edge_to_center = front_edge_to_center;
618}
619
621 const ReferenceLineInfo& reference_line_info,
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) {
625 UpdatePathBoundaryBySLPolygon(reference_line_info, sl_polygons, init_sl_state,
626 path_boundary, blocking_obstacle_id,
627 narrowest_width);
628 AddExtraPathBound(*sl_polygons, path_boundary, init_sl_state,
629 blocking_obstacle_id);
630 return true;
631}
632
634 double adc_half_width =
636
637 return (adc_half_width + FLAGS_obstacle_lat_buffer);
638}
639
641 const Obstacle& obstacle) {
642 // Obstacle should be non-virtual.
643 if (obstacle.IsVirtual()) {
644 return false;
645 }
646 // Obstacle should not have ignore decision.
647 if (obstacle.HasLongitudinalDecision() && obstacle.HasLateralDecision() &&
648 obstacle.IsIgnore()) {
649 return false;
650 }
651 // Obstacle should not be moving obstacle.
652 if (!obstacle.IsStatic() ||
653 obstacle.speed() > FLAGS_static_obstacle_speed_threshold) {
654 return false;
655 }
656 // TODO(jiacheng):
657 // Some obstacles are not moving, but only because they are waiting for
658 // red light (traffic rule) or because they are blocked by others (social).
659 // These obstacles will almost certainly move in the near future and we
660 // should not side-pass such obstacles.
661
662 return true;
663}
664
667 const common::TrajectoryPoint& traj_point) {
668 double front_to_rear_axe_distance =
670 common::TrajectoryPoint ret = traj_point;
671 ret.mutable_path_point()->set_x(
672 traj_point.path_point().x() +
673 front_to_rear_axe_distance * std::cos(traj_point.path_point().theta()));
674 ret.mutable_path_point()->set_y(
675 traj_point.path_point().y() +
676 front_to_rear_axe_distance * std::sin(traj_point.path_point().theta()));
677 return ret;
678}
679
681 const ReferenceLineInfo& reference_line_info, const SLState& init_sl_state,
682 PathBoundary* const path_bound) {
683 // Sanity checks.
684 CHECK_NOTNULL(path_bound);
685 ACHECK(!path_bound->empty());
686 const ReferenceLine& reference_line = reference_line_info.reference_line();
687 double adc_lane_width =
688 GetADCLaneWidth(reference_line, init_sl_state.first[0]);
689 // Go through every point, update the boundary based on lane info and
690 // ADC's position.
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;
696 // 1. Get the current lane width at current point.
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;
705 } else {
706 reference_line.GetOffsetToMap(curr_s, &offset_to_lane_center);
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;
711 }
712
713 // 3. Calculate the proper boundary based on lane-width, ADC's position,
714 // and ADC's velocity.
715 double offset_to_map = 0.0;
716 reference_line.GetOffsetToMap(curr_s, &offset_to_map);
717
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;
722 // 4. Update the boundary.
723 if (!UpdatePathBoundaryWithBuffer(curr_left_bound, curr_right_bound,
725 &path_bound->at(i))) {
726 path_blocked_idx = static_cast<int>(i);
727 }
728 if (path_blocked_idx != -1) {
729 break;
730 }
731 }
732
733 PathBoundsDeciderUtil::TrimPathBounds(path_blocked_idx, path_bound);
734
735 return true;
736}
737
739 const ReferenceLineInfo& reference_line_info, const SLState& init_sl_state,
740 PathBoundary* const path_bound) {
741 // Sanity checks.
742 CHECK_NOTNULL(path_bound);
743 ACHECK(!path_bound->empty());
744 const ReferenceLine& reference_line = reference_line_info.reference_line();
745 double adc_lane_width =
746 GetADCLaneWidth(reference_line, init_sl_state.first[0]);
747 // Go through every point, update the boudnary based on the road boundary.
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) {
752 // 1. Get road boundary.
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;
761 }
762
763 past_road_left_width = curr_road_left_width;
764 past_road_right_width = curr_road_right_width;
765
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;
771
772 // 2. Update into path_bound.
773 if (!UpdatePathBoundaryWithBuffer(curr_left_bound, curr_right_bound,
775 &path_bound->at(i))) {
776 path_blocked_idx = static_cast<int>(i);
777 }
778 if (path_blocked_idx != -1) {
779 break;
780 }
781 }
782 AINFO << "path_blocked_idx: " << path_blocked_idx;
783 TrimPathBounds(path_blocked_idx, path_bound);
784 return true;
785}
786
788 const ReferenceLineInfo& reference_line_info, const SLState& init_sl_state,
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;
792
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;
804
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;
809 reference_line_info.reference_line().GetRoadWidth(
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;
813
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);
818 (*path_bound)[i].l_upper.type = BoundType::ADC;
819 (*path_bound)[i].l_upper.id = "adc";
820 }
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);
825 (*path_bound)[i].l_lower.type = BoundType::ADC;
826 (*path_bound)[i].l_lower.id = "adc";
827 }
828 }
829 return true;
830}
831
833 const ReferenceLineInfo& reference_line_info,
834 PathBoundary* const path_bound) {
835 const ReferenceLine& reference_line = reference_line_info.reference_line();
836 for (size_t i = 0; i < path_bound->size(); ++i) {
837 // 1. Get road boundary.
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;
843 }
844}
845
847 const ReferenceLineInfo& reference_line_info, const double x,
848 const double y, const PathBound& path_bound) {
849 common::SLPoint point_sl;
850 reference_line_info.reference_line().XYToSL({x, y}, &point_sl);
851 if (point_sl.s() > path_bound.back().s ||
852 point_sl.s() <
853 path_bound.front().s - FLAGS_path_bounds_decider_resolution * 2) {
854 ADEBUG << "Longitudinally outside the boundary.";
855 return -1;
856 }
857 int idx_after = 0;
858 while (idx_after < static_cast<int>(path_bound.size()) &&
859 path_bound[idx_after].s < point_sl.s()) {
860 ++idx_after;
861 }
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()) {
872 return idx_after;
873 }
874 ADEBUG << "Laterally outside the boundary.";
875 return -1;
876}
877
879 PathBoundPoint* const path_bound_point, bool is_left, double init_l,
880 double heading, double delta_s, double init_frenet_kappa,
881 double min_radius) {
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);
889 if (is_left) {
890 if (init_frenet_kappa > 0 && heading < 0) {
892 delta_s, min_radius, heading, init_frenet_kappa,
893 &protective_restrict);
894 } else {
895 is_success = util::left_arc_bound_with_heading(delta_s, radius, heading,
896 &protective_restrict);
897 }
898
899 relax_constraint =
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;
906
907 if (path_bound_point->is_nudge_bound[LEFT_INDEX]) {
908 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
909 FLAGS_static_obstacle_nudge_l_buffer);
910 }
911
912 relax_constraint =
913 std::min(path_bound_point->l_upper.l + old_buffer - new_buffer,
914 relax_constraint);
915 AINFO << "left_obs_constraint: " << relax_constraint;
916 path_bound_point->l_upper.l = relax_constraint;
917 } else {
918 if (init_frenet_kappa < 0 && heading > 0) {
920 delta_s, min_radius, heading, init_frenet_kappa,
921 &protective_restrict);
922 } else {
923 is_success = util::right_arc_bound_with_heading(delta_s, radius, heading,
924 &protective_restrict);
925 }
926 relax_constraint =
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;
933
934 if (path_bound_point->is_nudge_bound[RIGHT_INDEX]) {
935 old_buffer = std::max(FLAGS_obstacle_lat_buffer,
936 FLAGS_static_obstacle_nudge_l_buffer);
937 }
938
939 relax_constraint =
940 std::max(path_bound_point->l_lower.l - old_buffer + new_buffer,
941 relax_constraint);
942 AINFO << "right_obs_constraint: " << relax_constraint;
943 path_bound_point->l_lower.l = relax_constraint;
944 }
945 return is_success;
946}
947
949 PathBoundary* const path_boundary, const SLState& init_sl_state) {
950 if (path_boundary->size() < 2) {
951 AINFO << "path_boundary size = 0, return.";
952 return false;
953 }
954 const auto& veh_param =
956 double min_radius =
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());
960
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);
967 } else {
968 init_frenet_kappa = std::max(
969 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
970 }
971
972 const auto& init_pt = path_boundary->at(0);
973 double init_frenet_heading =
974 common::math::Vec2d(1.0, init_sl_state.second[1]).Angle();
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;
985 break;
986 }
987 if (left_calculate_success &&
988 (left_bound.type == BoundType::OBSTACLE ||
989 path_boundary->at(i).is_nudge_bound[LEFT_INDEX])) {
990 left_calculate_success = RelaxBoundaryPoint(
991 &path_boundary->at(i), true, init_pt_l, init_frenet_heading, delta_s,
992 init_frenet_kappa, min_radius);
993 }
994 if (right_calculate_success &&
995 (right_bound.type == BoundType::OBSTACLE ||
996 path_boundary->at(i).is_nudge_bound[RIGHT_INDEX])) {
997 right_calculate_success = RelaxBoundaryPoint(
998 &path_boundary->at(i), false, init_pt_l, init_frenet_heading, delta_s,
999 init_frenet_kappa, min_radius);
1000 }
1001 if (!left_calculate_success && !right_calculate_success) {
1002 break;
1003 }
1004 }
1005 return true;
1006}
1007
1009 PathBoundary* const path_boundary, const SLState& init_sl_state) {
1010 if (path_boundary->size() < 2) {
1011 AINFO << "path_boundary size = 0, return.";
1012 return false;
1013 }
1014 const auto& veh_param =
1016 double min_radius =
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());
1020
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);
1027 } else {
1028 init_frenet_kappa = std::max(
1029 1.0 / (min_radius + FLAGS_relax_ego_radius_buffer), init_frenet_kappa);
1030 }
1031 double kappa_radius = 1.0 / std::fabs(init_frenet_kappa);
1032
1033 const auto& init_pt = path_boundary->at(0);
1034 double init_frenet_heading =
1035 common::math::Vec2d(1.0, init_sl_state.second[1]).Angle();
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);
1041 for (auto& extra_path_bound : *(path_boundary->mutable_extra_path_bound())) {
1042 double delta_s = extra_path_bound.rear_axle_s - init_pt.s;
1043 if (delta_s > FLAGS_relax_path_s_threshold) {
1044 break;
1045 }
1046
1047 // calculate the left side
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);
1055 } else {
1056 left_calculate_success = util::left_arc_bound_with_heading(
1057 delta_s, kappa_radius, init_frenet_heading,
1058 &left_protective_restrict);
1059 }
1060
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;
1074 }
1075
1076 if (right_calculate_success) {
1077 // calculate the right side
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);
1084 } else {
1085 right_calculate_success = util::right_arc_bound_with_heading(
1086 delta_s, kappa_radius, init_frenet_heading,
1087 &right_protective_restrict);
1088 }
1089
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;
1104 }
1105
1106 if (!left_calculate_success && !right_calculate_success) {
1107 break;
1108 }
1109 }
1110 return true;
1111}
1112
1114 PathBoundary* const path_boundary, std::string* const blocked_id) {
1115 if (path_boundary->extra_path_bound().blocked_id.empty()) {
1116 AINFO << "UpdateBlockInfoWithObsCornerBoundary, block id empty";
1117 return true;
1118 }
1119 auto* extra_path_bound = path_boundary->mutable_extra_path_bound();
1120 size_t path_boundary_block_index = extra_path_bound->block_right_index;
1121
1122 // trim path boundary width corner constraints block obstacle id
1123 *blocked_id = extra_path_bound->blocked_id;
1124 TrimPathBounds(path_boundary_block_index, path_boundary);
1125 AINFO << "update block id: " << *blocked_id
1126 << ", path_boundary size: " << path_boundary->size();
1127
1128 if (path_boundary->size() < 1) {
1129 extra_path_bound->clear();
1130 AERROR << "UpdateBlockInfoWithObsCornerBoundary, new_path_index < 1";
1131 return false;
1132 }
1133
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();
1143 }
1144 return false;
1145}
1146
1148 const std::vector<SLPolygon>& sl_polygons,
1149 PathBoundary* const path_boundary, const SLState& init_sl_state,
1150 std::string* const blocked_id) {
1151 RelaxEgoPathBoundary(path_boundary, init_sl_state);
1152 if (FLAGS_enable_corner_constraint) {
1153 AddCornerBounds(sl_polygons, path_boundary);
1154 RelaxObsCornerBoundary(path_boundary, init_sl_state);
1155 UpdateBlockInfoWithObsCornerBoundary(path_boundary, blocked_id);
1156 }
1157 if (FLAGS_enable_adc_vertex_constraint) {
1158 AddAdcVertexBounds(path_boundary);
1159 }
1160 return true;
1161}
1162
1163} // namespace planning
1164} // 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:242
bool right_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
Definition util.cc:257
bool left_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
Definition util.cc:271
bool right_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
Definition util.cc:293
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