Apollo 11.0
自动驾驶开放平台
pull_over_path.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 <memory>
21#include <string>
22#include <utility>
23#include <vector>
24
32
33namespace apollo {
34namespace planning {
35
40
41bool PullOverPath::Init(const std::string& config_dir, const std::string& name,
42 const std::shared_ptr<DependencyInjector>& injector) {
43 if (!Task::Init(config_dir, name, injector)) {
44 return false;
45 }
46 // Load the config this task.
47 return Task::LoadConfig<PullOverPathConfig>(&config_);
48}
49
50apollo::common::Status PullOverPath::Process(
51 Frame* frame, ReferenceLineInfo* reference_line_info) {
52 if (!reference_line_info->path_data().Empty() ||
53 reference_line_info->IsChangeLanePath()) {
54 return Status::OK();
55 }
56 std::vector<PathBoundary> candidate_path_boundaries;
57 std::vector<PathData> candidate_path_data;
58
60
61 if (!DecidePathBounds(&candidate_path_boundaries)) {
62 return Status::OK();
63 }
64 if (!OptimizePath(candidate_path_boundaries, &candidate_path_data)) {
65 return Status::OK();
66 }
67 if (AssessPath(&candidate_path_data,
68 reference_line_info->mutable_path_data())) {
69 ADEBUG << "pull-over path success";
70 }
71
72 return Status::OK();
73}
74
75bool PullOverPath::DecidePathBounds(std::vector<PathBoundary>* boundary) {
76 auto* pull_over_status = injector_->planning_context()
77 ->mutable_planning_status()
78 ->mutable_pull_over();
79 const bool plan_pull_over_path = pull_over_status->plan_pull_over_path();
80 if (!plan_pull_over_path) {
81 return false;
82 }
83 boundary->emplace_back();
84 auto& path_bound = boundary->back();
85 double path_narrowest_width = 0;
86 // 1. Initialize the path boundaries to be an indefinitely large area.
88 &path_bound, init_sl_state_)) {
89 AERROR << "Failed to initialize path boundaries.";
90 return false;
91 }
92 if (!GetBoundaryFromRoads(*reference_line_info_, &path_bound)) {
93 AERROR << "Failed to decide a rough boundary based on road boundary.";
94 return false;
95 }
96 RecordDebugInfo(path_bound, "pull_over_road", reference_line_info_);
98 *reference_line_info_, &path_bound);
99
100 if (init_sl_state_.second[0] < path_bound.front().l_lower.l ||
101 init_sl_state_.second[0] > path_bound.front().l_upper.l) {
102 AERROR << "ADC is outside road boundary already. Cannot generate pull-over "
103 "path";
104 return false;
105 }
106 bool is_pull_over_right = true;
108 double adc_to_left_bound =
109 path_bound.front().l_upper.l - init_sl_state_.second[0];
110 double adc_to_right_bound =
111 init_sl_state_.second[0] - path_bound.front().l_upper.l;
112 is_pull_over_right = adc_to_left_bound > adc_to_right_bound;
113 } else if (config_.pull_over_direction() == PullOverPathConfig::LEFT_SIDE) {
114 is_pull_over_right = false;
115 } else {
116 is_pull_over_right = true;
117 }
118 // 2. Update boundary by lane boundary for pull_over
119 UpdatePullOverBoundaryByLaneBoundary(is_pull_over_right, &path_bound);
120 RecordDebugInfo(path_bound, "pull_over_lane", reference_line_info_);
121
122 std::string blocking_obstacle_id = "";
123 PathBound temp_path_bound = path_bound;
124 std::vector<SLPolygon> obs_sl_polygons;
128 *reference_line_info_, &obs_sl_polygons, init_sl_state_, &path_bound,
129 &blocking_obstacle_id, &path_narrowest_width)) {
130 AERROR << "Failed to decide fine tune the boundaries after "
131 "taking into consideration all static obstacles.";
132 return false;
133 }
134 // If already found a pull-over position, simply check if it's valid.
135 int curr_idx = -1;
136 if (pull_over_status->has_position()) {
138 *reference_line_info_, pull_over_status->position().x(),
139 pull_over_status->position().y(), path_bound);
140 }
141 // If haven't found a pull-over position, search for one.
142 if (curr_idx < 0) {
143 pull_over_status->Clear();
144 pull_over_status->set_plan_pull_over_path(true);
145 std::tuple<double, double, double, int> pull_over_configuration;
146 if (!SearchPullOverPosition(path_bound, &pull_over_configuration)) {
147 AERROR << "Failed to find a proper pull-over position.";
148 return false;
149 }
150 const auto& vehicle_param =
152 curr_idx = std::get<3>(pull_over_configuration);
153 // If have found a pull-over position, update planning-context
154 pull_over_status->mutable_position()->set_x(
155 std::get<0>(pull_over_configuration));
156 pull_over_status->mutable_position()->set_y(
157 std::get<1>(pull_over_configuration));
158 pull_over_status->mutable_position()->set_z(0.0);
159 pull_over_status->set_theta(std::get<2>(pull_over_configuration));
160 pull_over_status->set_length_front(vehicle_param.front_edge_to_center());
161 pull_over_status->set_length_back(vehicle_param.back_edge_to_center());
162 pull_over_status->set_width_left(vehicle_param.width() / 2.0);
163 pull_over_status->set_width_right(vehicle_param.width() / 2.0);
164
165 AINFO << "Pull Over: x[" << std::fixed << pull_over_status->position().x()
166 << "] y[" << pull_over_status->position().y() << "] theta["
167 << pull_over_status->theta() << "]";
168 }
169 // Trim path-bound properly
170 while (static_cast<int>(path_bound.size()) - 1 >
171 curr_idx + FLAGS_num_extra_tail_bound_point) {
172 path_bound.pop_back();
173 }
174 for (size_t idx = curr_idx + 1; idx < path_bound.size(); ++idx) {
175 path_bound[idx].l_lower.l = path_bound[curr_idx].l_lower.l;
176 path_bound[idx].l_upper.l = path_bound[curr_idx].l_upper.l;
177 }
178 return true;
179}
180
181bool PullOverPath::OptimizePath(
182 const std::vector<PathBoundary>& path_boundaries,
183 std::vector<PathData>* candidate_path_data) {
184 auto path_config = config_.path_optimizer_config();
185 const ReferenceLine& reference_line = reference_line_info_->reference_line();
186 std::array<double, 3> end_state = {0.0, 0.0, 0.0};
187
188 for (const auto& path_boundary : path_boundaries) {
189 size_t path_boundary_size = path_boundary.boundary().size();
190 if (path_boundary_size <= 1U) {
191 AERROR << "Get invalid path boundary with size: " << path_boundary_size;
192 return false;
193 }
194 std::vector<double> opt_l, opt_dl, opt_ddl;
195 std::vector<std::pair<double, double>> ddl_bounds;
196 PathOptimizerUtil::CalculateAccBound(path_boundary, reference_line,
197 &ddl_bounds);
198 const auto& pull_over_status =
199 injector_->planning_context()->planning_status().pull_over();
200 std::vector<double> weight_ref_l(path_boundary_size,
201 path_config.path_reference_l_weight());
202 std::vector<double> ref_l(path_boundary_size, 0);
203 if (pull_over_status.has_position() &&
204 pull_over_status.position().has_x() &&
205 pull_over_status.position().has_y()) {
206 common::SLPoint pull_over_sl;
207 reference_line.XYToSL(pull_over_status.position(), &pull_over_sl);
208 end_state[0] = pull_over_sl.l();
209 ref_l.assign(path_boundary_size, end_state[0]);
210 weight_ref_l.assign(path_boundary_size, config_.pull_over_weight());
211 }
212
213 const double jerk_bound = PathOptimizerUtil::EstimateJerkBoundary(
214 std::fmax(init_sl_state_.first[1], 1e-12));
215
216 bool res_opt = PathOptimizerUtil::OptimizePath(
217 init_sl_state_, end_state, ref_l, weight_ref_l, path_boundary,
218 ddl_bounds, jerk_bound, path_config, &opt_l, &opt_dl, &opt_ddl);
219 if (res_opt) {
220 auto frenet_frame_path = PathOptimizerUtil::ToPiecewiseJerkPath(
221 opt_l, opt_dl, opt_ddl, path_boundary.delta_s(),
222 path_boundary.start_s());
223 PathData path_data;
224 path_data.SetReferenceLine(&reference_line);
225 path_data.SetFrenetPath(std::move(frenet_frame_path));
226 if (FLAGS_use_front_axe_center_in_path_planning) {
227 auto discretized_path = DiscretizedPath(
229 path_data));
230 path_data.SetDiscretizedPath(discretized_path);
231 }
232 path_data.set_path_label(path_boundary.label());
233 path_data.set_blocking_obstacle_id(path_boundary.blocking_obstacle_id());
234 candidate_path_data->push_back(std::move(path_data));
235 }
236 }
237 if (candidate_path_data->empty()) {
238 return false;
239 }
240 return true;
241}
242
243bool PullOverPath::AssessPath(std::vector<PathData>* candidate_path_data,
244 PathData* final_path) {
245 PathData& curr_path_data = candidate_path_data->back();
246 RecordDebugInfo(curr_path_data, curr_path_data.path_label(),
249 curr_path_data)) {
250 AINFO << "Lane follow path is invalid";
251 return false;
252 }
253
254 std::vector<PathPointDecision> path_decision;
256 curr_path_data, PathData::PathPointType::IN_LANE, &path_decision);
257 curr_path_data.SetPathPointDecisionGuide(std::move(path_decision));
258
259 if (curr_path_data.Empty()) {
260 AINFO << "Lane follow path is empty after trimed";
261 return false;
262 }
263 *final_path = curr_path_data;
265 curr_path_data.blocking_obstacle_id());
266 auto* pull_over_debug = reference_line_info_->mutable_debug()
267 ->mutable_planning_data()
268 ->mutable_pull_over();
269 const auto& pull_over_status =
270 injector_->planning_context()->planning_status().pull_over();
271 pull_over_debug->mutable_position()->CopyFrom(pull_over_status.position());
272 pull_over_debug->set_theta(pull_over_status.theta());
273 pull_over_debug->set_length_front(pull_over_status.length_front());
274 pull_over_debug->set_length_back(pull_over_status.length_back());
275 pull_over_debug->set_width_left(pull_over_status.width_left());
276 pull_over_debug->set_width_right(pull_over_status.width_right());
277 return true;
278}
279
280bool PullOverPath::GetBoundaryFromRoads(
281 const ReferenceLineInfo& reference_line_info,
282 PathBoundary* const path_bound) {
283 // Sanity checks.
284 CHECK_NOTNULL(path_bound);
285 ACHECK(!path_bound->empty());
286 const ReferenceLine& reference_line = reference_line_info.reference_line();
287 double adc_lane_width = PathBoundsDeciderUtil::GetADCLaneWidth(
288 reference_line, init_sl_state_.first[0]);
289 // Go through every point, update the boudnary based on the road boundary.
290 double past_road_left_width = adc_lane_width / 2.0;
291 double past_road_right_width = adc_lane_width / 2.0;
292 int path_blocked_idx = -1;
293 for (size_t i = 0; i < path_bound->size(); ++i) {
294 // 1. Get road boundary.
295 double curr_s = (*path_bound)[i].s;
296 double curr_road_left_width = 0.0;
297 double curr_road_right_width = 0.0;
298 double refline_offset_to_lane_center = 0.0;
299 reference_line.GetOffsetToMap(curr_s, &refline_offset_to_lane_center);
300 if (!reference_line.GetRoadWidth(curr_s, &curr_road_left_width,
301 &curr_road_right_width)) {
302 AWARN << "Failed to get lane width at s = " << curr_s;
303 curr_road_left_width = past_road_left_width;
304 curr_road_right_width = past_road_right_width;
305 } else {
306 curr_road_left_width += refline_offset_to_lane_center;
307 curr_road_right_width -= refline_offset_to_lane_center;
308 past_road_left_width = curr_road_left_width;
309 past_road_right_width = curr_road_right_width;
310 }
311 double curr_left_bound = curr_road_left_width;
312 double curr_right_bound = -curr_road_right_width;
313 ADEBUG << "At s = " << curr_s
314 << ", left road bound = " << curr_road_left_width
315 << ", right road bound = " << curr_road_right_width
316 << ", offset from refline to lane-center = "
317 << refline_offset_to_lane_center;
318
319 // 2. Update into path_bound.
321 curr_left_bound, curr_right_bound, BoundType::ROAD, BoundType::ROAD,
322 "", "", &path_bound->at(i))) {
323 path_blocked_idx = static_cast<int>(i);
324 }
325 if (path_blocked_idx != -1) {
326 break;
327 }
328 }
329
330 PathBoundsDeciderUtil::TrimPathBounds(path_blocked_idx, path_bound);
331 return true;
332}
333
334void PullOverPath::UpdatePullOverBoundaryByLaneBoundary(
335 bool is_pull_over_right, PathBoundary* const path_bound) {
336 const ReferenceLine& reference_line = reference_line_info_->reference_line();
337 for (size_t i = 0; i < path_bound->size(); ++i) {
338 const double curr_s = (*path_bound)[i].s;
339 double left_bound = 3.0;
340 double right_bound = 3.0;
341 double curr_lane_left_width = 0.0;
342 double curr_lane_right_width = 0.0;
343 if (reference_line.GetLaneWidth(curr_s, &curr_lane_left_width,
344 &curr_lane_right_width)) {
345 double offset_to_lane_center = 0.0;
346 reference_line.GetOffsetToMap(curr_s, &offset_to_lane_center);
347 left_bound = curr_lane_left_width + offset_to_lane_center;
348 right_bound = curr_lane_right_width + offset_to_lane_center;
349 }
350 ADEBUG << "left_bound[" << left_bound << "] right_bound[" << right_bound
351 << "]";
352 if (is_pull_over_right) {
353 (*path_bound)[i].l_upper.l = left_bound;
354 } else {
355 (*path_bound)[i].l_lower.l = right_bound;
356 }
357 }
358}
359
360bool PullOverPath::SearchPullOverPosition(
361 const PathBound& path_bound,
362 std::tuple<double, double, double, int>* const pull_over_configuration) {
363 // search direction
364 bool search_backward = false; // search FORWARD by default
365
366 double pull_over_s = 0.0;
368 if (!FindNearestPullOverS(&pull_over_s)) {
369 AERROR << "Failed to find emergency_pull_over s";
370 return false;
371 }
372 search_backward = false; // search FORWARD from target position
373 } else if (config_.pull_over_position() == PullOverPathConfig::DESTINATION) {
374 if (!FindDestinationPullOverS(path_bound, &pull_over_s)) {
375 AERROR << "Failed to find pull_over s upon destination arrival";
376 return false;
377 }
378 search_backward = true; // search BACKWARD from target position
379 } else {
380 return false;
381 }
382
383 int idx = 0;
384 if (search_backward) {
385 // 1. Locate the first point before destination.
386 idx = static_cast<int>(path_bound.size()) - 1;
387 while (idx >= 0 && path_bound[idx].s > pull_over_s) {
388 --idx;
389 }
390 } else {
391 // 1. Locate the first point after emergency_pull_over s.
392 while (idx < static_cast<int>(path_bound.size()) &&
393 path_bound[idx].s < pull_over_s) {
394 ++idx;
395 }
396 }
397 if (idx < 0 || idx >= static_cast<int>(path_bound.size())) {
398 AERROR << "Failed to find path_bound index for pull over s";
399 return false;
400 }
401 constexpr double kPulloverLonSearchCoeff = 1.5;
402 constexpr double kPulloverLatSearchCoeff = 1.25;
403 // Search for a feasible location for pull-over.
404 const double pull_over_space_length =
405 kPulloverLonSearchCoeff *
407 FLAGS_obstacle_lon_start_buffer - FLAGS_obstacle_lon_end_buffer;
408 const double pull_over_space_width =
409 (kPulloverLatSearchCoeff - 1.0) *
411 const double adc_half_width =
413
414 // 2. Find a window that is close to road-edge.
415 // (not in any intersection)
416 bool has_a_feasible_window = false;
417 while ((search_backward && idx >= 0 &&
418 path_bound[idx].s - path_bound.front().s > pull_over_space_length) ||
419 (!search_backward && idx < static_cast<int>(path_bound.size()) &&
420 path_bound.back().s - path_bound[idx].s > pull_over_space_length)) {
421 int j = idx;
422 bool is_feasible_window = true;
423
424 // Check if the point of idx is within intersection.
425 double pt_ref_line_s = path_bound[idx].s;
426 double pt_ref_line_l = 0.0;
427 common::SLPoint pt_sl;
428 pt_sl.set_s(pt_ref_line_s);
429 pt_sl.set_l(pt_ref_line_l);
430 common::math::Vec2d pt_xy;
432 common::PointENU hdmap_point;
433 hdmap_point.set_x(pt_xy.x());
434 hdmap_point.set_y(pt_xy.y());
435 ADEBUG << "Pull-over position might be around (" << pt_xy.x() << ", "
436 << pt_xy.y() << ")";
437 std::vector<std::shared_ptr<const JunctionInfo>> junctions;
438 HDMapUtil::BaseMap().GetJunctions(hdmap_point, 1.0, &junctions);
439 if (!junctions.empty()) {
440 AWARN << "Point is in PNC-junction.";
441 idx = search_backward ? idx - 1 : idx + 1;
442 continue;
443 }
444
445 while ((search_backward && j >= 0 &&
446 path_bound[idx].s - path_bound[j].s < pull_over_space_length) ||
447 (!search_backward && j < static_cast<int>(path_bound.size()) &&
448 path_bound[j].s - path_bound[idx].s < pull_over_space_length)) {
449 double curr_s = path_bound[j].s;
450 double curr_right_bound = std::fabs(path_bound[j].l_lower.l);
451 double curr_road_left_width = 0;
452 double curr_road_right_width = 0;
454 curr_s, &curr_road_left_width, &curr_road_right_width);
455 ADEBUG << "s[" << curr_s << "] curr_road_left_width["
456 << curr_road_left_width << "] curr_road_right_width["
457 << curr_road_right_width << "]";
458 if (curr_road_right_width - (curr_right_bound + adc_half_width) >
459 config_.pull_over_road_edge_buffer()) {
460 AERROR << "Not close enough to road-edge. Not feasible for pull-over.";
461 is_feasible_window = false;
462 break;
463 }
464 const double right_bound = path_bound[j].l_lower.l;
465 const double left_bound = path_bound[j].l_upper.l;
466 ADEBUG << "left_bound[" << left_bound << "] right_bound[" << right_bound
467 << "]";
468 if (left_bound - right_bound < pull_over_space_width) {
469 AERROR << "Not wide enough to fit ADC. Not feasible for pull-over.";
470 is_feasible_window = false;
471 break;
472 }
473
474 j = search_backward ? j - 1 : j + 1;
475 }
476 if (j < 0) {
477 return false;
478 }
479 if (is_feasible_window) {
480 has_a_feasible_window = true;
481 const auto& reference_line = reference_line_info_->reference_line();
482 // estimate pull over point to have the vehicle keep same safety
483 // distance to front and back
484 const auto& vehicle_param =
486 const double back_clear_to_total_length_ratio =
487 (0.5 * (kPulloverLonSearchCoeff - 1.0) * vehicle_param.length() +
488 vehicle_param.back_edge_to_center()) /
489 vehicle_param.length() / kPulloverLonSearchCoeff;
490
491 int start_idx = j;
492 int end_idx = idx;
493 if (!search_backward) {
494 start_idx = idx;
495 end_idx = j;
496 }
497 auto pull_over_idx = static_cast<size_t>(
498 back_clear_to_total_length_ratio * static_cast<double>(end_idx) +
499 (1.0 - back_clear_to_total_length_ratio) *
500 static_cast<double>(start_idx));
501
502 const auto& pull_over_point = path_bound[pull_over_idx];
503 const double pull_over_s = pull_over_point.s;
504 const double pull_over_l =
505 pull_over_point.l_lower.l + pull_over_space_width / 2.0;
506 common::SLPoint pull_over_sl_point;
507 pull_over_sl_point.set_s(pull_over_s);
508 pull_over_sl_point.set_l(pull_over_l);
509
510 common::math::Vec2d pull_over_xy_point;
511 reference_line.SLToXY(pull_over_sl_point, &pull_over_xy_point);
512 const double pull_over_x = pull_over_xy_point.x();
513 const double pull_over_y = pull_over_xy_point.y();
514
515 // set the pull over theta to be the nearest lane theta rather than
516 // reference line theta in case of reference line theta not aligned with
517 // the lane
518 const auto& reference_point =
519 reference_line.GetReferencePoint(pull_over_s);
520 double pull_over_theta = reference_point.heading();
522 double s = 0.0;
523 double l = 0.0;
524 auto point =
525 common::util::PointFactory::ToPointENU(pull_over_x, pull_over_y);
526 if (HDMapUtil::BaseMap().GetNearestLaneWithHeading(
527 point, 5.0, pull_over_theta, M_PI_2, &lane, &s, &l) == 0) {
528 pull_over_theta = lane->Heading(s);
529 }
530 *pull_over_configuration =
531 std::make_tuple(pull_over_x, pull_over_y, pull_over_theta,
532 static_cast<int>(pull_over_idx));
533 break;
534 }
535
536 idx = search_backward ? idx - 1 : idx + 1;
537 }
538
539 return has_a_feasible_window;
540}
541
542bool PullOverPath::FindNearestPullOverS(double* pull_over_s) {
543 const double adc_end_s = reference_line_info_->AdcSlBoundary().end_s();
544 const double min_turn_radius = common::VehicleConfigHelper::Instance()
545 ->GetConfig()
546 .vehicle_param()
547 .min_turn_radius();
548 const double adjust_factor =
550 const double pull_over_distance = min_turn_radius * 2 * adjust_factor;
551 *pull_over_s = adc_end_s + pull_over_distance;
552 return true;
553}
554
555bool PullOverPath::FindDestinationPullOverS(const PathBound& path_bound,
556 double* pull_over_s) {
557 // destination_s based on routing_end
558 const auto& reference_line = reference_line_info_->reference_line();
559 common::SLPoint destination_sl;
560 const auto& routing_end = *(frame_->local_view().end_lane_way_point);
561 reference_line.XYToSL(routing_end.pose(), &destination_sl);
562 const double destination_s = destination_sl.s();
563 const double adc_end_s = reference_line_info_->AdcSlBoundary().end_s();
564
565 // Check if destination is some distance away from ADC.
566 ADEBUG << "Destination s[" << destination_s << "] adc_end_s[" << adc_end_s
567 << "]";
568 if (destination_s - adc_end_s <
570 AERROR << "Destination is too close to ADC. distance["
571 << destination_s - adc_end_s << "]";
572 return false;
573 }
574
575 // Check if destination is within path-bounds searching scope.
576 const double destination_to_pathend_buffer =
578 if (destination_s + destination_to_pathend_buffer >= path_bound.back().s) {
579 AERROR << "Destination is not within path_bounds search scope";
580 return false;
581 }
582
583 *pull_over_s = destination_s;
584 return true;
585}
586
587} // namespace planning
588} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
static Status OK()
generate a success status.
Definition status.h:60
@Brief This is a helper class that can load vehicle configurations.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
static PointENU ToPointENU(const double x, const double y, const double z=0)
static const HDMap & BaseMap()
int GetJunctions(const apollo::common::PointENU &point, double distance, std::vector< JunctionInfoConstPtr > *junctions) const
get all junctions in certain range
Definition hdmap.cc:95
Frame holds all data for one planning cycle.
Definition frame.h:62
const LocalView & local_view() const
Definition frame.h:163
static void InitPathPointDecision(const PathData &path_data, const PathData::PathPointType type, std::vector< PathPointDecision > *const path_point_decision)
Init path_point_decision as type
static bool IsValidRegularPath(const ReferenceLineInfo &reference_line_info, const PathData &path_data)
Check if the generated path is valid
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 void TrimPathBounds(const int path_blocked_idx, PathBoundary *const path_boundaries)
static bool UpdatePathBoundaryWithBuffer(double left_bound, double right_bound, BoundType left_type, BoundType right_type, std::string left_id, std::string right_id, PathBoundPoint *const bound_point)
Update the path_boundary at "idx" It also checks if ADC is blocked (lmax < lmin).
static 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 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...
void RecordDebugInfo(const PathBound &path_boundaries, const std::string &debug_name, ReferenceLineInfo *const reference_line_info)
add path_boundary debug info for PnC monitor
void GetStartPointSLState()
calculate init sl state by planning start point, result will store in init_sl_state_
static std::vector< common::PathPoint > ConvertPathPointRefFromFrontAxeToRearAxe(const PathData &path_data)
static void CalculateAccBound(const PathBoundary &path_boundary, const ReferenceLine &reference_line, std::vector< std::pair< double, double > > *ddl_bounds)
calculate ddl bound by referenceline kappa and adc lat accleration
static FrenetFramePath ToPiecewiseJerkPath(const std::vector< double > &x, const std::vector< double > &dx, const std::vector< double > &ddx, const double delta_s, const double start_s)
Data format tramform from raw data to FrenetFramePath
static double EstimateJerkBoundary(const double vehicle_speed)
Calculation of jerk boundary based on vehicle kinematics model.
static bool OptimizePath(const SLState &init_state, const std::array< double, 3 > &end_state, std::vector< double > l_ref, std::vector< double > l_ref_weight, const PathBoundary &path_boundary, const std::vector< std::pair< double, double > > &ddl_bounds, double dddl_bound, const PiecewiseJerkPathConfig &config, std::vector< double > *x, std::vector< double > *dx, std::vector< double > *ddx)
Piecewise jerk path optimizer.
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
ReferenceLineInfo holds all data for one reference line.
void SetBlockingObstacle(const std::string &blocking_obstacle_id)
const ReferenceLine & reference_line() const
planning_internal::Debug * mutable_debug()
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 ...
bool GetRoadWidth(const double s, double *const road_left_width, double *const road_right_width) const
bool SLToXY(const common::SLPoint &sl_point, common::math::Vec2d *const xy_point) 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 GetOffsetToMap(const double s, double *l_offset) const
std::shared_ptr< DependencyInjector > injector_
Definition task.h:59
ReferenceLineInfo * reference_line_info_
Definition task.h:58
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Definition task.cc:40
Planning module main class.
#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
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
std::vector< PathBoundPoint > PathBound
class register implement
Definition arena_queue.h:37
optional VehicleParam vehicle_param
std::shared_ptr< routing::LaneWaypoint > end_lane_way_point
Definition local_view.h:49
optional PullOverPosition pull_over_position
optional double pull_over_approach_lon_distance_adjust_factor
optional PullOverDirection pull_over_direction
optional PiecewiseJerkPathConfig path_optimizer_config