Apollo 11.0
自动驾驶开放平台
lane_change_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 <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
48bool LaneChangePath::Init(const std::string& config_dir,
49 const std::string& name,
50 const std::shared_ptr<DependencyInjector>& injector) {
51 if (!Task::Init(config_dir, name, injector)) {
52 return false;
53 }
54 // Load the config this task.
55 return Task::LoadConfig<LaneChangePathConfig>(&config_);
56}
57
58apollo::common::Status LaneChangePath::Process(
59 Frame* frame, ReferenceLineInfo* reference_line_info) {
60 UpdateLaneChangeStatus();
61 const auto& status = injector_->planning_context()
62 ->mutable_planning_status()
63 ->mutable_change_lane()
64 ->status();
65 if (!reference_line_info->IsChangeLanePath() ||
66 reference_line_info->path_reusable()) {
67 ADEBUG << "Skip this time" << reference_line_info->IsChangeLanePath()
68 << "path reusable" << reference_line_info->path_reusable();
69 return Status::OK();
70 }
72 ADEBUG << injector_->planning_context()
73 ->mutable_planning_status()
74 ->mutable_change_lane()
75 ->DebugString();
76 return Status(ErrorCode::PLANNING_ERROR,
77 "Not satisfy lane change conditions");
78 }
79 std::vector<PathBoundary> candidate_path_boundaries;
80 std::vector<PathData> candidate_path_data;
81
83 if (!DecidePathBounds(&candidate_path_boundaries)) {
84 return Status(ErrorCode::PLANNING_ERROR, "lane change path bounds failed");
85 }
86 if (!OptimizePath(candidate_path_boundaries, &candidate_path_data)) {
87 return Status(ErrorCode::PLANNING_ERROR,
88 "lane change path optimize failed");
89 }
90 if (!AssessPath(&candidate_path_data,
91 reference_line_info->mutable_path_data())) {
92 return Status(ErrorCode::PLANNING_ERROR, "No valid lane change path");
93 }
94
95 return Status::OK();
96}
97
98bool LaneChangePath::DecidePathBounds(std::vector<PathBoundary>* boundary) {
99 boundary->emplace_back();
100 auto& path_bound = boundary->back();
101 double path_narrowest_width = 0;
102 // 1. Initialize the path boundaries to be an indefinitely large area.
104 &path_bound, init_sl_state_)) {
105 const std::string msg = "Failed to initialize path boundaries.";
106 AERROR << msg;
107 return false;
108 }
109 // 2. Decide a rough boundary based on lane info and ADC's position
111 *reference_line_info_, init_sl_state_, &path_bound)) {
112 AERROR << "Failed to decide a rough boundary based on self lane.";
113 return false;
114 }
117 &path_bound)) {
118 AERROR << "Failed to decide a rough boundary based on adc.";
119 return false;
120 }
121
122 // 3. Remove the S-length of target lane out of the path-bound.
123 GetBoundaryFromLaneChangeForbiddenZone(&path_bound);
124
125 path_bound.set_label("regular/lane_change");
126
127 PathBound temp_path_bound = path_bound;
128 std::string blocking_obstacle_id;
129 obs_sl_polygons_.clear();
134 &blocking_obstacle_id, &path_narrowest_width)) {
135 AERROR << "Failed to decide fine tune the boundaries after "
136 "taking into consideration all static obstacles.";
137 return false;
138 }
139
140 // Append some extra path bound points to avoid zero-length path data.
141 int counter = 0;
142 while (!blocking_obstacle_id.empty() &&
143 path_bound.size() < temp_path_bound.size() &&
144 counter < FLAGS_num_extra_tail_bound_point) {
145 path_bound.push_back(temp_path_bound[path_bound.size()]);
146 counter++;
147 }
148
149 path_bound.set_blocking_obstacle_id(blocking_obstacle_id);
150 RecordDebugInfo(path_bound, path_bound.label(), reference_line_info_);
151 return true;
152}
153bool LaneChangePath::OptimizePath(
154 const std::vector<PathBoundary>& path_boundaries,
155 std::vector<PathData>* candidate_path_data) {
156 const auto& config = config_.path_optimizer_config();
157 const ReferenceLine& reference_line = reference_line_info_->reference_line();
158 std::array<double, 3> end_state = {0.0, 0.0, 0.0};
159 for (const auto& path_boundary : path_boundaries) {
160 size_t path_boundary_size = path_boundary.boundary().size();
161 if (path_boundary_size <= 1U) {
162 AERROR << "Get invalid path boundary with size: " << path_boundary_size;
163 return false;
164 }
165 std::vector<double> opt_l, opt_dl, opt_ddl;
166 std::vector<std::pair<double, double>> ddl_bounds;
167 PathOptimizerUtil::CalculateAccBound(path_boundary, reference_line,
168 &ddl_bounds);
169 const double jerk_bound = PathOptimizerUtil::EstimateJerkBoundary(
170 std::fmax(init_sl_state_.first[1], 1e-12));
171 std::vector<double> ref_l(path_boundary_size, 0);
172 std::vector<double> weight_ref_l(path_boundary_size, 0);
173
174 bool res_opt = PathOptimizerUtil::OptimizePath(
175 init_sl_state_, end_state, ref_l, weight_ref_l, path_boundary,
176 ddl_bounds, jerk_bound, config, &opt_l, &opt_dl, &opt_ddl);
177 if (res_opt) {
178 auto frenet_frame_path = PathOptimizerUtil::ToPiecewiseJerkPath(
179 opt_l, opt_dl, opt_ddl, path_boundary.delta_s(),
180 path_boundary.start_s());
181 PathData path_data;
182 path_data.SetReferenceLine(&reference_line);
183 path_data.SetFrenetPath(std::move(frenet_frame_path));
184 if (FLAGS_use_front_axe_center_in_path_planning) {
185 auto discretized_path = DiscretizedPath(
187 path_data));
188 path_data.SetDiscretizedPath(discretized_path);
189 }
190 path_data.set_path_label(path_boundary.label());
191 path_data.set_blocking_obstacle_id(path_boundary.blocking_obstacle_id());
192 candidate_path_data->push_back(std::move(path_data));
193 }
194 }
195 if (candidate_path_data->empty()) {
196 return false;
197 }
198 return true;
199}
200
201bool LaneChangePath::AssessPath(std::vector<PathData>* candidate_path_data,
202 PathData* final_path) {
203 std::vector<PathData> valid_path_data;
204 for (auto& curr_path_data : *candidate_path_data) {
206 curr_path_data)) {
207 SetPathInfo(&curr_path_data);
209 FLAGS_path_trim_destination_threshold) {
211 }
212 if (curr_path_data.Empty()) {
213 AINFO << "lane change path is empty after trimed";
214 continue;
215 }
216 valid_path_data.push_back(curr_path_data);
217 }
218 }
219 if (valid_path_data.empty()) {
220 AINFO << "All lane change path are not valid";
221 return false;
222 }
223
224 *final_path = valid_path_data[0];
225 // move obs_sl_polygon to reference_line_info, it will be empty, do not use it
227 RecordDebugInfo(*final_path, final_path->path_label(), reference_line_info_);
228 return true;
229}
230
231void LaneChangePath::UpdateLaneChangeStatus() {
232 std::string change_lane_id;
233 auto* prev_status = injector_->planning_context()
234 ->mutable_planning_status()
235 ->mutable_change_lane();
236 double now = Clock::NowInSeconds();
237 // Init lane change status
238 if (!prev_status->has_status()) {
239 UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FINISHED, "");
240 return;
241 }
242 bool has_change_lane = frame_->reference_line_info().size() > 1;
243 if (!has_change_lane) {
244 if (prev_status->status() == ChangeLaneStatus::IN_CHANGE_LANE) {
246 prev_status->path_id());
247 }
248 return;
249 }
250 // has change lane
252 const auto* history_frame = injector_->frame_history()->Latest();
253 if (!CheckLastFrameSucceed(history_frame)) {
254 UpdateStatus(now, ChangeLaneStatus::CHANGE_LANE_FAILED, change_lane_id);
255 is_exist_lane_change_start_position_ = false;
256 return;
257 }
258 is_clear_to_change_lane_ = IsClearToChangeLane(reference_line_info_);
259 change_lane_id = reference_line_info_->Lanes().Id();
260 ADEBUG << "change_lane_id" << change_lane_id;
261 if (prev_status->status() == ChangeLaneStatus::CHANGE_LANE_FAILED) {
262 if (now - prev_status->timestamp() >
264 UpdateStatus(now, ChangeLaneStatus::IN_CHANGE_LANE, change_lane_id);
265 ADEBUG << "change lane again after failed";
266 }
267 return;
268 } else if (prev_status->status() ==
270 if (now - prev_status->timestamp() >
272 UpdateStatus(now, ChangeLaneStatus::IN_CHANGE_LANE, change_lane_id);
273 AINFO << "change lane again after success";
274 }
275 } else if (prev_status->status() == ChangeLaneStatus::IN_CHANGE_LANE) {
276 if (prev_status->path_id() != change_lane_id) {
277 AINFO << "change_lane_id" << change_lane_id << "prev"
278 << prev_status->path_id();
280 prev_status->path_id());
281 }
282 }
283 }
284}
285
286bool LaneChangePath::IsClearToChangeLane(
287 ReferenceLineInfo* reference_line_info) {
288 double ego_start_s = reference_line_info->AdcSlBoundary().start_s();
289 double ego_end_s = reference_line_info->AdcSlBoundary().end_s();
290 double ego_v =
291 std::abs(reference_line_info->vehicle_state().linear_velocity());
292
293 for (const auto* obstacle :
294 reference_line_info->path_decision()->obstacles().Items()) {
295 if (obstacle->IsVirtual() || obstacle->IsStatic()) {
296 ADEBUG << "skip one virtual or static obstacle";
297 continue;
298 }
299
300 double start_s = std::numeric_limits<double>::max();
301 double end_s = -std::numeric_limits<double>::max();
302 double start_l = std::numeric_limits<double>::max();
303 double end_l = -std::numeric_limits<double>::max();
304
305 for (const auto& p : obstacle->PerceptionPolygon().points()) {
307 reference_line_info->reference_line().XYToSL(p, &sl_point);
308 start_s = std::fmin(start_s, sl_point.s());
309 end_s = std::fmax(end_s, sl_point.s());
310
311 start_l = std::fmin(start_l, sl_point.l());
312 end_l = std::fmax(end_l, sl_point.l());
313 }
314
315 if (reference_line_info->IsChangeLanePath()) {
316 double left_width(0), right_width(0);
317 reference_line_info->mutable_reference_line()->GetLaneWidth(
318 (start_s + end_s) * 0.5, &left_width, &right_width);
319 if (end_l < -right_width || start_l > left_width) {
320 continue;
321 }
322 }
323
324 // Raw estimation on whether same direction with ADC or not based on
325 // prediction trajectory
326 bool same_direction = true;
327 if (obstacle->HasTrajectory()) {
328 double obstacle_moving_direction =
329 obstacle->Trajectory().trajectory_point(0).path_point().theta();
330 const auto& vehicle_state = reference_line_info->vehicle_state();
331 double vehicle_moving_direction = vehicle_state.heading();
332 if (vehicle_state.gear() == canbus::Chassis::GEAR_REVERSE) {
333 vehicle_moving_direction =
334 common::math::NormalizeAngle(vehicle_moving_direction + M_PI);
335 }
336 double heading_difference = std::abs(common::math::NormalizeAngle(
337 obstacle_moving_direction - vehicle_moving_direction));
338 same_direction = heading_difference < (M_PI / 2.0);
339 }
340
341 // TODO(All) move to confs
342 static constexpr double kSafeTimeOnSameDirection = 3.0;
343 static constexpr double kSafeTimeOnOppositeDirection = 5.0;
344 static constexpr double kForwardMinSafeDistanceOnSameDirection = 10.0;
345 static constexpr double kBackwardMinSafeDistanceOnSameDirection = 10.0;
346 static constexpr double kForwardMinSafeDistanceOnOppositeDirection = 50.0;
347 static constexpr double kBackwardMinSafeDistanceOnOppositeDirection = 1.0;
348 static constexpr double kDistanceBuffer = 0.5;
349
350 double kForwardSafeDistance = 0.0;
351 double kBackwardSafeDistance = 0.0;
352 if (same_direction) {
353 kForwardSafeDistance =
354 std::fmax(kForwardMinSafeDistanceOnSameDirection,
355 (ego_v - obstacle->speed()) * kSafeTimeOnSameDirection);
356 kBackwardSafeDistance =
357 std::fmax(kBackwardMinSafeDistanceOnSameDirection,
358 (obstacle->speed() - ego_v) * kSafeTimeOnSameDirection);
359 } else {
360 kForwardSafeDistance =
361 std::fmax(kForwardMinSafeDistanceOnOppositeDirection,
362 (ego_v + obstacle->speed()) * kSafeTimeOnOppositeDirection);
363 kBackwardSafeDistance = kBackwardMinSafeDistanceOnOppositeDirection;
364 }
365
366 if (HysteresisFilter(ego_start_s - end_s, kBackwardSafeDistance,
367 kDistanceBuffer, obstacle->IsLaneChangeBlocking()) &&
368 HysteresisFilter(start_s - ego_end_s, kForwardSafeDistance,
369 kDistanceBuffer, obstacle->IsLaneChangeBlocking())) {
370 reference_line_info->path_decision()
371 ->Find(obstacle->Id())
372 ->SetLaneChangeBlocking(true);
373 ADEBUG << "Lane Change is blocked by obstacle" << obstacle->Id();
374 return false;
375 } else {
376 reference_line_info->path_decision()
377 ->Find(obstacle->Id())
378 ->SetLaneChangeBlocking(false);
379 }
380 }
381 return true;
382}
383
384void LaneChangePath::GetLaneChangeStartPoint(
385 const ReferenceLine& reference_line, double adc_frenet_s,
386 common::math::Vec2d* start_xy) {
387 double lane_change_start_s =
388 config_.lane_change_prepare_length() + adc_frenet_s;
389 common::SLPoint lane_change_start_sl;
390 lane_change_start_sl.set_s(lane_change_start_s);
391 lane_change_start_sl.set_l(0.0);
392 reference_line.SLToXY(lane_change_start_sl, start_xy);
393}
394
395void LaneChangePath::GetBoundaryFromLaneChangeForbiddenZone(
396 PathBoundary* const path_bound) {
397 // Sanity checks.
398 CHECK_NOTNULL(path_bound);
399
400 if (is_clear_to_change_lane_) {
401 is_exist_lane_change_start_position_ = false;
402 return;
403 }
404 double lane_change_start_s = 0.0;
405 const ReferenceLine& reference_line = reference_line_info_->reference_line();
406 // If there is a pre-determined lane-change starting position, then use it;
407 // otherwise, decide one.
408 if (is_exist_lane_change_start_position_) {
409 common::SLPoint point_sl;
410 reference_line.XYToSL(lane_change_start_xy_, &point_sl);
411 lane_change_start_s = point_sl.s();
412 } else {
413 // TODO(jiacheng): train ML model to learn this.
414 lane_change_start_s =
415 config_.lane_change_prepare_length() + init_sl_state_.first[0];
416
417 // Update the lane_change_start_xy_ decided by lane_change_start_s
418 GetLaneChangeStartPoint(reference_line, init_sl_state_.first[0],
419 &lane_change_start_xy_);
420 }
421
422 // Remove the target lane out of the path-boundary, up to the decided S.
423 if (lane_change_start_s < init_sl_state_.first[0]) {
424 // If already passed the decided S, then return.
425 return;
426 }
427 double adc_half_width =
429 for (size_t i = 0; i < path_bound->size(); ++i) {
430 double curr_s = (*path_bound)[i].s;
431 if (curr_s > lane_change_start_s) {
432 break;
433 }
434 double curr_lane_left_width = 0.0;
435 double curr_lane_right_width = 0.0;
436 double offset_to_map = 0.0;
437 reference_line.GetOffsetToMap(curr_s, &offset_to_map);
438 if (reference_line.GetLaneWidth(curr_s, &curr_lane_left_width,
439 &curr_lane_right_width)) {
440 double offset_to_lane_center = 0.0;
441 reference_line.GetOffsetToMap(curr_s, &offset_to_lane_center);
442 curr_lane_left_width += offset_to_lane_center;
443 curr_lane_right_width -= offset_to_lane_center;
444 }
445 curr_lane_left_width -= offset_to_map;
446 curr_lane_right_width += offset_to_map;
447
448 (*path_bound)[i].l_lower.l = init_sl_state_.second[0] > curr_lane_left_width
449 ? curr_lane_left_width + adc_half_width
450 : (*path_bound)[i].l_lower.l;
451 (*path_bound)[i].l_lower.l =
452 std::fmin((*path_bound)[i].l_lower.l, init_sl_state_.second[0] - 0.1);
453 (*path_bound)[i].l_upper.l =
454 init_sl_state_.second[0] < -curr_lane_right_width
455 ? -curr_lane_right_width - adc_half_width
456 : (*path_bound)[i].l_upper.l;
457 (*path_bound)[i].l_upper.l =
458 std::fmax((*path_bound)[i].l_upper.l, init_sl_state_.second[0] + 0.1);
459 }
460}
461
462void LaneChangePath::UpdateStatus(double timestamp,
463 ChangeLaneStatus::Status status_code,
464 const std::string& path_id) {
465 auto* lane_change_status = injector_->planning_context()
466 ->mutable_planning_status()
467 ->mutable_change_lane();
468 AINFO << "lane change update from" << lane_change_status->DebugString()
469 << "to";
470 lane_change_status->set_timestamp(timestamp);
471 lane_change_status->set_path_id(path_id);
472 lane_change_status->set_status(status_code);
473 AINFO << lane_change_status->DebugString();
474}
475
476bool LaneChangePath::HysteresisFilter(const double obstacle_distance,
477 const double safe_distance,
478 const double distance_buffer,
479 const bool is_obstacle_blocking) {
480 if (is_obstacle_blocking) {
481 return obstacle_distance < safe_distance + distance_buffer;
482 } else {
483 return obstacle_distance < safe_distance - distance_buffer;
484 }
485}
486
487void LaneChangePath::SetPathInfo(PathData* const path_data) {
488 std::vector<PathPointDecision> path_decision;
490 *path_data, PathData::PathPointType::IN_LANE, &path_decision);
491 // Go through every path_point, and add in-lane/out-of-lane info.
492 const auto& discrete_path = path_data->discretized_path();
493 SLBoundary ego_sl_boundary;
494 for (size_t i = 0; i < discrete_path.size(); ++i) {
495 if (!GetSLBoundary(*path_data, i, reference_line_info_, &ego_sl_boundary)) {
496 ADEBUG << "Unable to get SL-boundary of ego-vehicle.";
497 continue;
498 }
499 double lane_left_width = 0.0;
500 double lane_right_width = 0.0;
501 double middle_s =
502 (ego_sl_boundary.start_s() + ego_sl_boundary.end_s()) / 2.0;
504 middle_s, &lane_left_width, &lane_right_width)) {
505 // Rough sl boundary estimate using single point lane width
506 double back_to_inlane_extra_buffer = 0.2;
507 // For lane-change path, only transitioning part is labeled as
508 // out-of-lane.
509 if (ego_sl_boundary.start_l() > lane_left_width ||
510 ego_sl_boundary.end_l() < -lane_right_width) {
511 // This means that ADC hasn't started lane-change yet.
512 std::get<1>((path_decision)[i]) = PathData::PathPointType::IN_LANE;
513 } else if (ego_sl_boundary.start_l() >
514 -lane_right_width + back_to_inlane_extra_buffer &&
515 ego_sl_boundary.end_l() <
516 lane_left_width - back_to_inlane_extra_buffer) {
517 // This means that ADC has safely completed lane-change with margin.
518 std::get<1>((path_decision)[i]) = PathData::PathPointType::IN_LANE;
519 } else {
520 // ADC is right across two lanes.
521 std::get<1>((path_decision)[i]) =
523 }
524 } else {
525 AERROR << "reference line not ready when setting path point guide";
526 return;
527 }
528 }
529 path_data->SetPathPointDecisionGuide(std::move(path_decision));
530}
531
532bool LaneChangePath::CheckLastFrameSucceed(
533 const apollo::planning::Frame* const last_frame) {
534 if (last_frame) {
535 for (const auto& reference_line_info : last_frame->reference_line_info()) {
536 if (!reference_line_info.IsChangeLanePath()) {
537 continue;
538 }
539 const auto history_trajectory_type =
540 reference_line_info.trajectory_type();
541 if (history_trajectory_type == ADCTrajectory::SPEED_FALLBACK) {
542 return false;
543 }
544 }
545 }
546 return true;
547}
548
549} // namespace planning
550} // 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
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 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 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 void GetSLPolygons(const ReferenceLineInfo &reference_line_info, std::vector< SLPolygon > *polygons, const SLState &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
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.
ReferenceLineInfo holds all data for one reference line.
std::vector< SLPolygon > * mutable_obs_sl_polygons()
const hdmap::RouteSegments & Lanes() const
const ReferenceLine & reference_line() 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
optional PiecewiseJerkPathConfig path_optimizer_config