Apollo 11.0
自动驾驶开放平台
lane_change_path_generic.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 <limits>
21#include <memory>
22#include <string>
23#include <utility>
24#include <vector>
25
26#include "cyber/time/clock.h"
33
34namespace apollo {
35namespace planning {
36
44
45constexpr double kIntersectionClearanceDist = 20.0;
46constexpr double kJunctionClearanceDist = 15.0;
47
49 const std::string& config_dir,
50 const std::string& name,
51 const std::shared_ptr<DependencyInjector>& injector) {
52 if (!Task::Init(config_dir, name, injector)) {
53 return false;
54 }
55 // Load the config this task.
56 return Task::LoadConfig<LaneChangePathGenericConfig>(&config_);
57}
58
59apollo::common::Status LaneChangePathGeneric::Process(Frame* frame, ReferenceLineInfo* reference_line_info) {
60 UpdateLaneChangeStatus();
61 const auto& status = injector_->planning_context()->mutable_planning_status()->mutable_change_lane()->status();
62 if (!reference_line_info->IsChangeLanePath() || reference_line_info->path_reusable()) {
63 ADEBUG << "Skip this time" << reference_line_info->IsChangeLanePath() << "path reusable"
64 << reference_line_info->path_reusable();
65 return Status::OK();
66 }
68 ADEBUG << injector_->planning_context()->mutable_planning_status()->mutable_change_lane()->DebugString();
69 return Status(ErrorCode::PLANNING_ERROR, "Not satisfy lane change conditions");
70 }
71 std::vector<PathBoundary> candidate_path_boundaries;
72 std::vector<PathData> candidate_path_data;
73
75 if (!DecidePathBounds(&candidate_path_boundaries)) {
76 return Status(ErrorCode::PLANNING_ERROR, "lane change path bounds failed");
77 }
78 if (!OptimizePath(candidate_path_boundaries, &candidate_path_data)) {
79 return Status(ErrorCode::PLANNING_ERROR, "lane change path optimize failed");
80 }
81 if (!AssessPath(&candidate_path_data, reference_line_info->mutable_path_data())) {
82 return Status(ErrorCode::PLANNING_ERROR, "No valid lane change path");
83 }
84
85 return Status::OK();
86}
87
88bool LaneChangePathGeneric::DecidePathBounds(std::vector<PathBoundary>* boundary) {
89 boundary->emplace_back();
90 auto& path_bound = boundary->back();
91 double path_narrowest_width = 0;
92 // 1. Initialize the path boundaries to be an indefinitely large area.
94 const std::string msg = "Failed to initialize path boundaries.";
95 AERROR << msg;
96 return false;
97 }
98 // 2. Decide a rough boundary based on lane info and ADC's position
100 AERROR << "Failed to decide a rough boundary based on self lane.";
101 return false;
102 }
103 path_bound.DebugString("from_self_lane_l");
105 *reference_line_info_, init_sl_state_, config_.extend_adc_buffer(), &path_bound)) {
106 AERROR << "Failed to decide a rough boundary based on adc.";
107 return false;
108 }
109 path_bound.DebugString("extend_boundary_by_ADC_l");
110
111 path_bound.set_label("regular/lane_change");
112
113 PathBound temp_path_bound = path_bound;
114 std::string blocking_obstacle_id;
115 obs_sl_polygons_.clear();
116 GetSLPolygons(&obs_sl_polygons_);
121 &path_bound,
122 &blocking_obstacle_id,
123 &path_narrowest_width);
124 path_bound.DebugString("from_static_obstacles_l");
125
126 // 3. Remove the S-length of target lane out of the path-bound.
127 if (config_.enable_forbidden_zone()) {
128 GetBoundaryFromLaneChangeForbiddenZone(&path_bound);
129 path_bound.DebugString("forbidden_zone_l");
130 }
131
132 GetBoundaryFromNudgeDecision(&path_bound);
133 path_bound.DebugString("from_nudge_decision_l");
134
135 // 3.3 Update boundary width Extra Path Bound
137
138 // Append some extra path bound points to avoid zero-length path data.
139 int counter = 0;
140 while (!blocking_obstacle_id.empty() && path_bound.size() < temp_path_bound.size()
141 && counter < FLAGS_num_extra_tail_bound_point) {
142 path_bound.push_back(temp_path_bound[path_bound.size()]);
143 counter++;
144 }
145
146 path_bound.set_blocking_obstacle_id(blocking_obstacle_id);
147 RecordDebugInfo(path_bound, path_bound.label(), reference_line_info_);
148 return true;
149}
150bool LaneChangePathGeneric::OptimizePath(
151 const std::vector<PathBoundary>& path_boundaries,
152 std::vector<PathData>* candidate_path_data) {
153 const auto& config = config_.path_optimizer_config();
154 const ReferenceLine& reference_line = reference_line_info_->reference_line();
155 std::array<double, 3> end_state = {0.0, 0.0, 0.0};
156 for (const auto& path_boundary : path_boundaries) {
157 size_t path_boundary_size = path_boundary.boundary().size();
158 if (path_boundary_size <= 1U) {
159 AERROR << "Get invalid path boundary with size: " << path_boundary_size;
160 return false;
161 }
162 std::vector<double> opt_l, opt_dl, opt_ddl;
163 std::vector<std::pair<double, double>> ddl_bounds;
164 PathOptimizerUtil::CalculateAccBound(path_boundary, reference_line, &ddl_bounds);
165 const double jerk_bound = PathOptimizerUtil::EstimateJerkBoundary(std::fmax(init_sl_state_.first[1], 1e-12));
166 std::vector<double> ref_l(path_boundary_size, 0);
167 std::vector<double> weight_ref_l(path_boundary_size, 0);
169 path_boundary, config.path_reference_l_weight(), &ref_l, &weight_ref_l);
170
171 bool res_opt = PathOptimizerUtil::OptimizePath(
173 end_state,
174 ref_l,
175 weight_ref_l,
176 path_boundary,
177 ddl_bounds,
178 jerk_bound,
179 config,
180 &opt_l,
181 &opt_dl,
182 &opt_ddl);
183 if (res_opt) {
184 auto frenet_frame_path = PathOptimizerUtil::ToPiecewiseJerkPath(
185 opt_l, opt_dl, opt_ddl, path_boundary.delta_s(), path_boundary.start_s());
186 PathData path_data;
187 path_data.SetReferenceLine(&reference_line);
188 path_data.SetFrenetPath(std::move(frenet_frame_path));
189 if (FLAGS_use_front_axe_center_in_path_planning) {
190 auto discretized_path
192 path_data.SetDiscretizedPath(discretized_path);
193 }
194 path_data.set_path_label(path_boundary.label());
195 path_data.set_blocking_obstacle_id(path_boundary.blocking_obstacle_id());
196 candidate_path_data->push_back(std::move(path_data));
197 }
198 }
199 if (candidate_path_data->empty()) {
200 return false;
201 }
202 return true;
203}
204
205bool LaneChangePathGeneric::AssessPath(std::vector<PathData>* candidate_path_data, PathData* final_path) {
206 std::vector<PathData> valid_path_data;
207 for (auto& curr_path_data : *candidate_path_data) {
209 SetPathInfo(&curr_path_data);
210 if (reference_line_info_->SDistanceToDestination() < FLAGS_path_trim_destination_threshold) {
212 }
213 if (curr_path_data.Empty()) {
214 AINFO << "lane change path is empty after trimed";
215 continue;
216 }
217 valid_path_data.push_back(curr_path_data);
218 }
219 }
220 if (valid_path_data.empty()) {
221 AINFO << "All lane change path are not valid";
222 return false;
223 }
224
225 *final_path = valid_path_data[0];
227 RecordDebugInfo(*final_path, final_path->path_label(), reference_line_info_);
228 return true;
229}
230
231void LaneChangePathGeneric::UpdateLaneChangeStatus() {
232 std::string change_lane_id;
233 auto* prev_status = injector_->planning_context()->mutable_planning_status()->mutable_change_lane();
234 double now = Clock::NowInSeconds();
235 // Init lane change status
236 if (!prev_status->has_status()) {
237 UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED, "");
238 return;
239 }
240 bool has_change_lane = frame_->reference_line_info().size() > 1;
241 if (!has_change_lane) {
242 if (prev_status->status() == ChangeLaneStatus::IN_CHANGE_LANE) {
243 UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED, prev_status->path_id());
244 }
245 return;
246 }
247 // has change lane
249 const auto* history_frame = injector_->frame_history()->Latest();
250 if (!CheckLastFrameSucceed(history_frame)) {
251 UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FAILED, change_lane_id);
252 is_exist_lane_change_start_position_ = false;
253 return;
254 }
255 is_clear_to_change_lane_ = IsClearToChangeLane(reference_line_info_);
256 change_lane_id = reference_line_info_->Lanes().Id();
257 ADEBUG << "change_lane_id" << change_lane_id;
258 if (prev_status->status() == ChangeLaneStatus::CHANGE_LANE_FAILED) {
259 if (now - prev_status->timestamp() > config_.change_lane_fail_freeze_time()) {
260 UpdateStatus(now, ChangeLaneStatus::IN_CHANGE_LANE, change_lane_id);
261 ADEBUG << "change lane again after failed";
262 }
263 return;
264 } else if (prev_status->status() == ChangeLaneStatus::CHANGE_LANE_FINISHED) {
265 if (now - prev_status->timestamp() > config_.change_lane_success_freeze_time()) {
266 UpdateStatus(now, ChangeLaneStatus::IN_CHANGE_LANE, change_lane_id);
267 AINFO << "change lane again after success";
268 }
269 } else if (prev_status->status() == ChangeLaneStatus::IN_CHANGE_LANE) {
270 if (prev_status->path_id() != change_lane_id) {
271 AINFO << "change_lane_id" << change_lane_id << "prev" << prev_status->path_id();
272 UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED, prev_status->path_id());
273 }
274 }
275 }
276}
277
278bool LaneChangePathGeneric::IsClearToChangeLane(ReferenceLineInfo* reference_line_info) {
279 double ego_start_s = reference_line_info->AdcSlBoundary().start_s();
280 double ego_end_s = reference_line_info->AdcSlBoundary().end_s();
281 double ego_v = std::abs(reference_line_info->vehicle_state().linear_velocity());
282
283 for (const auto* obstacle : reference_line_info->path_decision()->obstacles().Items()) {
284 if (obstacle->IsVirtual() || obstacle->IsStatic()) {
285 ADEBUG << "skip one virtual or static obstacle";
286 continue;
287 }
288
289 double start_s = std::numeric_limits<double>::max();
290 double end_s = -std::numeric_limits<double>::max();
291 double start_l = std::numeric_limits<double>::max();
292 double end_l = -std::numeric_limits<double>::max();
293
294 for (const auto& p : obstacle->PerceptionPolygon().points()) {
296 reference_line_info->reference_line().XYToSL(p, &sl_point);
297 start_s = std::fmin(start_s, sl_point.s());
298 end_s = std::fmax(end_s, sl_point.s());
299
300 start_l = std::fmin(start_l, sl_point.l());
301 end_l = std::fmax(end_l, sl_point.l());
302 }
303
304 if (reference_line_info->IsChangeLanePath()) {
305 double left_width(0), right_width(0);
306 reference_line_info->mutable_reference_line()->GetLaneWidth(
307 (start_s + end_s) * 0.5, &left_width, &right_width);
308 if (end_l < -right_width || start_l > left_width) {
309 continue;
310 }
311 }
312
313 // Raw estimation on whether same direction with ADC or not based on
314 // prediction trajectory
315 bool same_direction = true;
316 if (obstacle->HasTrajectory()) {
317 double obstacle_moving_direction = obstacle->Trajectory().trajectory_point(0).path_point().theta();
318 const auto& vehicle_state = reference_line_info->vehicle_state();
319 double vehicle_moving_direction = vehicle_state.heading();
320 if (vehicle_state.gear() == canbus::Chassis::GEAR_REVERSE) {
321 vehicle_moving_direction = common::math::NormalizeAngle(vehicle_moving_direction + M_PI);
322 }
323 double heading_difference
324 = std::abs(common::math::NormalizeAngle(obstacle_moving_direction - vehicle_moving_direction));
325 same_direction = heading_difference < (M_PI / 2.0);
326 }
327
328 // TODO(All) move to confs
329 static constexpr double kSafeTimeOnSameDirection = 3.0;
330 static constexpr double kSafeTimeOnOppositeDirection = 5.0;
331 static constexpr double kForwardMinSafeDistanceOnSameDirection = 10.0;
332 static constexpr double kBackwardMinSafeDistanceOnSameDirection = 10.0;
333 static constexpr double kForwardMinSafeDistanceOnOppositeDirection = 50.0;
334 static constexpr double kBackwardMinSafeDistanceOnOppositeDirection = 1.0;
335 static constexpr double kDistanceBuffer = 0.5;
336
337 double kForwardSafeDistance = 0.0;
338 double kBackwardSafeDistance = 0.0;
339 if (same_direction) {
340 kForwardSafeDistance = std::fmax(
341 kForwardMinSafeDistanceOnSameDirection, (ego_v - obstacle->speed()) * kSafeTimeOnSameDirection);
342 kBackwardSafeDistance = std::fmax(
343 kBackwardMinSafeDistanceOnSameDirection, (obstacle->speed() - ego_v) * kSafeTimeOnSameDirection);
344 } else {
345 kForwardSafeDistance = std::fmax(
346 kForwardMinSafeDistanceOnOppositeDirection,
347 (ego_v + obstacle->speed()) * kSafeTimeOnOppositeDirection);
348 kBackwardSafeDistance = kBackwardMinSafeDistanceOnOppositeDirection;
349 }
350
351 if (HysteresisFilter(
352 ego_start_s - end_s, kBackwardSafeDistance, kDistanceBuffer, obstacle->IsLaneChangeBlocking())
353 && HysteresisFilter(
354 start_s - ego_end_s, kForwardSafeDistance, kDistanceBuffer, obstacle->IsLaneChangeBlocking())) {
355 reference_line_info->path_decision()->Find(obstacle->Id())->SetLaneChangeBlocking(true);
356 ADEBUG << "Lane Change is blocked by obstacle" << obstacle->Id();
357 return false;
358 } else {
359 reference_line_info->path_decision()->Find(obstacle->Id())->SetLaneChangeBlocking(false);
360 }
361 }
362 return true;
363}
364
365void LaneChangePathGeneric::GetLaneChangeStartPoint(
366 const ReferenceLine& reference_line,
367 double adc_frenet_s,
368 common::math::Vec2d* start_xy) {
369 double lane_change_start_s = config_.lane_change_prepare_length() + adc_frenet_s;
370 common::SLPoint lane_change_start_sl;
371 lane_change_start_sl.set_s(lane_change_start_s);
372 lane_change_start_sl.set_l(0.0);
373 reference_line.SLToXY(lane_change_start_sl, start_xy);
374}
375
376void LaneChangePathGeneric::GetBoundaryFromLaneChangeForbiddenZone(PathBoundary* const path_bound) {
377 // Sanity checks.
378 CHECK_NOTNULL(path_bound);
379
380 if (is_clear_to_change_lane_) {
381 is_exist_lane_change_start_position_ = false;
382 return;
383 }
384 double lane_change_start_s = 0.0;
385 const ReferenceLine& reference_line = reference_line_info_->reference_line();
386 // If there is a pre-determined lane-change starting position, then use it;
387 // otherwise, decide one.
388 if (is_exist_lane_change_start_position_) {
389 common::SLPoint point_sl;
390 reference_line.XYToSL(lane_change_start_xy_, &point_sl);
391 lane_change_start_s = point_sl.s();
392 } else {
393 // TODO(jiacheng): train ML model to learn this.
394 lane_change_start_s = config_.lane_change_prepare_length() + init_sl_state_.first[0];
395
396 // Update the lane_change_start_xy_ decided by lane_change_start_s
397 GetLaneChangeStartPoint(reference_line, init_sl_state_.first[0], &lane_change_start_xy_);
398 }
399
400 // Remove the target lane out of the path-boundary, up to the decided S.
401 if (lane_change_start_s < init_sl_state_.first[0]) {
402 // If already passed the decided S, then return.
403 return;
404 }
405 double adc_half_width = VehicleConfigHelper::GetConfig().vehicle_param().width() / 2.0;
406 for (size_t i = 0; i < path_bound->size(); ++i) {
407 double curr_s = (*path_bound)[i].s;
408 if (curr_s > lane_change_start_s) {
409 break;
410 }
411 double curr_lane_left_width = 0.0;
412 double curr_lane_right_width = 0.0;
413 double offset_to_map = 0.0;
414 reference_line.GetOffsetToMap(curr_s, &offset_to_map);
415 if (reference_line.GetLaneWidth(curr_s, &curr_lane_left_width, &curr_lane_right_width)) {
416 double offset_to_lane_center = 0.0;
417 reference_line.GetOffsetToMap(curr_s, &offset_to_lane_center);
418 curr_lane_left_width += offset_to_lane_center;
419 curr_lane_right_width -= offset_to_lane_center;
420 }
421 curr_lane_left_width -= offset_to_map;
422 curr_lane_right_width += offset_to_map;
423
424 (*path_bound)[i].l_lower.l = init_sl_state_.second[0] > curr_lane_left_width
425 ? curr_lane_left_width + adc_half_width
426 : (*path_bound)[i].l_lower.l;
427 (*path_bound)[i].l_lower.l = std::fmin((*path_bound)[i].l_lower.l, init_sl_state_.second[0] - 0.1);
428 (*path_bound)[i].l_upper.l = init_sl_state_.second[0] < -curr_lane_right_width
429 ? -curr_lane_right_width - adc_half_width
430 : (*path_bound)[i].l_upper.l;
431 (*path_bound)[i].l_upper.l = std::fmax((*path_bound)[i].l_upper.l, init_sl_state_.second[0] + 0.1);
432 }
433}
434
435bool LaneChangePathGeneric::GetBoundaryFromNudgeDecision(PathBoundary* const path_bound) {
437
438 const auto& nudge_info = ParkDataCenter::Instance()->current_nudge_info(reference_line_info_->key());
439 bool is_use_nudge_key_points = FLAGS_enable_nudge_decider && nudge_info.is_enable()
440 && nudge_info.extra_nudge_key_points().size() > 1 && nudge_info.extra_nudge_key_points().at(0).size() > 1;
441 if (!is_use_nudge_key_points) {
442 AINFO << "GetBoundaryFromNudgeDecision, not use nudge key points";
443 return true;
444 }
445
446 double start_pt_s, end_pt_s;
447 int key_points_index = is_right_change_lane ? 0 : 1;
448 start_pt_s = nudge_info.extra_nudge_key_points().at(key_points_index).front().s();
449 end_pt_s = nudge_info.extra_nudge_key_points().at(key_points_index).back().s();
450
451 if (is_right_change_lane) {
452 for (size_t i = 1; i < path_bound->size(); ++i) {
453 auto& left_bound = path_bound->at(i).l_upper;
454 auto& right_bound = path_bound->at(i).l_lower;
455 double check_s = path_bound->at(i).s;
456 if (check_s < start_pt_s) {
457 continue;
458 } else if (check_s < end_pt_s) {
459 double nudge_l = 0;
460 if (nudge_info.GetInterpolatedNudgeL(true, check_s, &nudge_l)) {
461 right_bound.l = std::max(std::min(nudge_l, left_bound.l), right_bound.l);
462 }
463 } else {
464 break;
465 }
466 }
467 } else {
468 for (size_t i = 1; i < path_bound->size(); ++i) {
469 auto& left_bound = path_bound->at(i).l_upper;
470 auto& right_bound = path_bound->at(i).l_lower;
471 double check_s = path_bound->at(i).s;
472 if (check_s < start_pt_s) {
473 continue;
474 } else if (check_s < end_pt_s) {
475 double nudge_l = 0;
476 if (nudge_info.GetInterpolatedNudgeL(false, check_s, &nudge_l)) {
477 left_bound.l = std::min(std::max(nudge_l, right_bound.l), left_bound.l);
478 }
479 } else {
480 break;
481 }
482 }
483 }
484 return true;
485}
486
487void LaneChangePathGeneric::UpdateStatus(
488 double timestamp,
489 ChangeLaneStatus::Status status_code,
490 const std::string& path_id) {
491 auto* lane_change_status = injector_->planning_context()->mutable_planning_status()->mutable_change_lane();
492 AINFO << "lane change update from " << lane_change_status->DebugString() << "to";
493 lane_change_status->set_timestamp(timestamp);
494 lane_change_status->set_path_id(path_id);
495 lane_change_status->set_status(status_code);
496 AINFO << lane_change_status->DebugString();
497}
498
499bool LaneChangePathGeneric::HysteresisFilter(
500 const double obstacle_distance,
501 const double safe_distance,
502 const double distance_buffer,
503 const bool is_obstacle_blocking) {
504 if (is_obstacle_blocking) {
505 return obstacle_distance < safe_distance + distance_buffer;
506 } else {
507 return obstacle_distance < safe_distance - distance_buffer;
508 }
509}
510
511void LaneChangePathGeneric::SetPathInfo(PathData* const path_data) {
512 std::vector<PathPointDecision> path_decision;
514 // Go through every path_point, and add in-lane/out-of-lane info.
515 const auto& discrete_path = path_data->discretized_path();
516 SLBoundary ego_sl_boundary;
517 for (size_t i = 0; i < discrete_path.size(); ++i) {
518 if (!GetSLBoundary(*path_data, i, reference_line_info_, &ego_sl_boundary)) {
519 ADEBUG << "Unable to get SL-boundary of ego-vehicle.";
520 continue;
521 }
522 double lane_left_width = 0.0;
523 double lane_right_width = 0.0;
524 double middle_s = (ego_sl_boundary.start_s() + ego_sl_boundary.end_s()) / 2.0;
525 if (reference_line_info_->reference_line().GetLaneWidth(middle_s, &lane_left_width, &lane_right_width)) {
526 // Rough sl boundary estimate using single point lane width
527 double back_to_inlane_extra_buffer = 0.2;
528 // For lane-change path, only transitioning part is labeled as
529 // out-of-lane.
530 if (ego_sl_boundary.start_l() > lane_left_width || ego_sl_boundary.end_l() < -lane_right_width) {
531 // This means that ADC hasn't started lane-change yet.
532 std::get<1>((path_decision)[i]) = PathData::PathPointType::IN_LANE;
533 } else if (
534 ego_sl_boundary.start_l() > -lane_right_width + back_to_inlane_extra_buffer
535 && ego_sl_boundary.end_l() < lane_left_width - back_to_inlane_extra_buffer) {
536 // This means that ADC has safely completed lane-change with margin.
537 std::get<1>((path_decision)[i]) = PathData::PathPointType::IN_LANE;
538 } else {
539 // ADC is right across two lanes.
540 std::get<1>((path_decision)[i]) = PathData::PathPointType::OUT_ON_FORWARD_LANE;
541 }
542 } else {
543 AERROR << "reference line not ready when setting path point guide";
544 return;
545 }
546 }
547 path_data->SetPathPointDecisionGuide(std::move(path_decision));
548}
549
550bool LaneChangePathGeneric::CheckLastFrameSucceed(const apollo::planning::Frame* const last_frame) {
551 if (last_frame) {
552 for (const auto& reference_line_info : last_frame->reference_line_info()) {
553 if (!reference_line_info.IsChangeLanePath()) {
554 continue;
555 }
556 const auto history_trajectory_type = reference_line_info.trajectory_type();
557 if (history_trajectory_type == ADCTrajectory::SPEED_FALLBACK) {
558 return false;
559 }
560 }
561 }
562 return true;
563}
564
565void LaneChangePathGeneric::GetSLPolygons(std::vector<SLPolygon>* polygons) {
566 polygons->clear();
567 auto obstacles = reference_line_info_->path_decision()->obstacles();
568 const auto& nudge_info = ParkDataCenter::Instance()->current_nudge_info(reference_line_info_->key());
569 const double adc_back_edge_s = reference_line_info_->AdcSlBoundary().start_s();
570 for (const auto* obstacle : obstacles.Items()) {
572 continue;
573 }
574 double check_dis = std::max(reference_line_info_->vehicle_state().linear_velocity() * 3.0, 10.0);
575
576 if (nudge_info.IsObsIgnoreNudgeDecision(
577 obstacle->Id(), obstacle->PerceptionSLBoundary().start_s(), check_dis)) {
578 continue;
579 }
580 auto xy_poly = obstacle->PerceptionPolygon();
581
582 // if (obstacle->PerceptionSLBoundary().end_s() < init_sl_state.first[0]) {
583 // continue;
584 // }
585 if (obstacle->PerceptionSLBoundary().end_s() < adc_back_edge_s) {
586 continue;
587 }
588 const auto obstacle_sl = obstacle->PerceptionSLBoundary();
589 polygons->emplace_back(obstacle_sl, obstacle->Id(), obstacle->Perception().type());
590 }
591 sort(polygons->begin(), polygons->end(), [](const SLPolygon& a, const SLPolygon& b) {
592 return a.MinS() < b.MinS();
593 });
594}
595
596} // namespace planning
597} // 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.
Rectangular (undirected) bounding box in 2-D.
Definition box2d.h:52
The class of polygon in 2-D.
Definition polygon2d.h:42
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
a singleton clock that can be used to get the current timestamp.
Definition clock.h:39
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
const std::string & Id() const
routing::ChangeLaneType PreviousAction() const
Get the previous change lane action need to take by the vehicle to reach current segment,...
Frame holds all data for one planning cycle.
Definition frame.h:62
const std::list< ReferenceLineInfo > & reference_line_info() const
Definition frame.cc:123
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
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 void TrimTailingOutLanePoints(PathData *const path_data)
Trim the points at tail of path which away from lane
static bool IsValidRegularPath(const ReferenceLineInfo &reference_line_info, const PathData &path_data)
Check if the generated path is valid
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 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 AddExtraPathBound(const std::vector< SLPolygon > &sl_polygons, PathBoundary *const path_boundary, const SLState &init_sl_state, std::string *const blocked_id)
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...
const IndexedList< std::string, Obstacle > & obstacles() const
void RecordDebugInfo(const PathBound &path_boundaries, const std::string &debug_name, ReferenceLineInfo *const reference_line_info)
add path_boundary debug info for PnC monitor
bool GetSLBoundary(const PathData &path_data, int point_index, const ReferenceLineInfo *reference_line_info, SLBoundary *const sl_boundary)
get sl boundary of the point on PathData
std::vector< SLPolygon > obs_sl_polygons_
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.
static void UpdatePathRefWithBound(const PathBoundary &path_boundary, double weight, std::vector< double > *ref_l, std::vector< double > *weight_ref_l)
If ref_l is below or above path boundary, will update its values and weights
ReferenceLineInfo holds all data for one reference line.
const common::VehicleState & vehicle_state() const
std::vector< SLPolygon > * mutable_obs_sl_polygons()
const hdmap::RouteSegments & Lanes() 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 ...
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
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 ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
constexpr double kJunctionClearanceDist
constexpr double kIntersectionClearanceDist
std::vector< PathBoundPoint > PathBound
class register implement
Definition arena_queue.h:37
optional VehicleParam vehicle_param