27#include "modules/common_msgs/planning_msgs/sl_boundary.pb.h"
46 move_dest_lane_config_talbe_.clear();
47 max_speed_levels_.clear();
50 for (
const auto& item : move_dest_lane_config_talbe.lateral_shift()) {
51 double max_speed_level = item.max_speed();
52 double max_move_dest_lane_shift_y = item.max_move_dest_lane_shift_y();
53 if (move_dest_lane_config_talbe_.find(max_speed_level) ==
54 move_dest_lane_config_talbe_.end()) {
55 move_dest_lane_config_talbe_.emplace(
56 std::make_pair(max_speed_level, max_move_dest_lane_shift_y));
57 max_speed_levels_.push_back(max_speed_level);
60 AINFO <<
"Maximum speeds and move to dest lane config: ";
61 for (
const auto& data : move_dest_lane_config_talbe_) {
62 auto max_speed = data.first;
63 auto max_move_dest_lane_shift_y = data.second;
64 AINFO <<
"[max_speed : " << max_speed
65 <<
" ,max move dest lane shift y : " << max_move_dest_lane_shift_y
83 cur_reference_line_lane_id_ = reference_line_info->
Lanes().
Id();
88 RecordDebugInfo(reference_line_info->
path_data());
91 AERROR <<
"Reference Line " << reference_line_info->
Lanes().
Id()
92 <<
" is not drivable after " <<
Name();
100 const std::vector<const Obstacle*>& obstacles,
102 CHECK_NOTNULL(path_decision);
103 CHECK_NOTNULL(path_data);
104 start_plan_point_.set_x(vehicle_state_.
x());
105 start_plan_point_.set_y(vehicle_state_.
y());
106 start_plan_point_.set_theta(vehicle_state_.
heading());
109 if (start_plan_point_from_ == 1) {
111 start_plan_point_.set_x(init_point.
path_point().
x());
112 start_plan_point_.set_y(init_point.
path_point().
y());
114 start_plan_v_ = init_point.
v();
115 start_plan_a_ = init_point.
a();
119 std::vector<apollo::common::PathPoint> path_points;
120 if (!GetBasicPathData(reference_line, &path_points)) {
121 AERROR <<
"Get path points from reference line failed";
123 "NaviPathDecider GetBasicPathData");
129 double dest_ref_line_y = path_points[0].y();
131 ADEBUG <<
"in current plan cycle, adc to ref line distance : "
132 << dest_ref_line_y <<
"lane id : " << cur_reference_line_lane_id_;
133 MoveToDestLane(dest_ref_line_y, &path_points);
135 KeepLane(dest_ref_line_y, &path_points);
139 AERROR <<
"Set path data failed.";
141 "NaviPathDecider SetDiscretizedPath");
147void NaviPathDecider::MoveToDestLane(
148 const double dest_ref_line_y,
149 std::vector<common::PathPoint>*
const path_points) {
150 double dest_lateral_distance = std::fabs(dest_ref_line_y);
151 if (dest_lateral_distance < max_keep_lane_distance_) {
156 double max_shift_y = CalculateDistanceToDestLane();
158 double actual_start_point_y = std::copysign(max_shift_y, dest_ref_line_y);
160 double lateral_shift_value = -dest_ref_line_y + actual_start_point_y;
163 lateral_shift_value =
164 lateral_shift_value > 0.0
165 ? (lateral_shift_value - move_dest_lane_compensation_)
166 : lateral_shift_value;
167 ADEBUG <<
"in current plan cycle move to dest lane, adc shift to dest "
169 << lateral_shift_value;
170 std::transform(path_points->begin(), path_points->end(), path_points->begin(),
171 [lateral_shift_value](common::PathPoint& old_path_point) {
172 common::PathPoint new_path_point = old_path_point;
173 double new_path_point_y =
174 old_path_point.y() + lateral_shift_value;
175 new_path_point.set_y(new_path_point_y);
176 return new_path_point;
180void NaviPathDecider::KeepLane(
181 const double dest_ref_line_y,
182 std::vector<common::PathPoint>*
const path_points) {
183 double dest_lateral_distance = std::fabs(dest_ref_line_y);
184 if (dest_lateral_distance <= max_keep_lane_distance_) {
188 double actual_dest_point_y =
189 NudgeProcess(reference_line, *path_points, obstacles, *path_decision,
192 double actual_dest_lateral_distance = std::fabs(actual_dest_point_y);
193 double actual_shift_y = 0.0;
194 if (actual_dest_lateral_distance > min_keep_lane_offset_) {
195 double lateral_shift_value = 0.0;
196 lateral_shift_value =
197 (actual_dest_lateral_distance < max_keep_lane_shift_y_ +
198 min_keep_lane_offset_ -
199 keep_lane_shift_compensation_)
200 ? (actual_dest_lateral_distance - min_keep_lane_offset_ +
201 keep_lane_shift_compensation_)
202 : max_keep_lane_shift_y_;
203 actual_shift_y = std::copysign(lateral_shift_value, actual_dest_point_y);
206 ADEBUG <<
"in current plan cycle keep lane, actual dest : "
207 << actual_dest_point_y <<
" adc shift to dest : " << actual_shift_y;
209 path_points->begin(), path_points->end(), path_points->begin(),
210 [actual_shift_y](common::PathPoint& old_path_point) {
211 common::PathPoint new_path_point = old_path_point;
212 double new_path_point_y = old_path_point.y() + actual_shift_y;
213 new_path_point.set_y(new_path_point_y);
214 return new_path_point;
219void NaviPathDecider::RecordDebugInfo(
const PathData& path_data) {
220 const auto& path_points = path_data.discretized_path();
222 ->mutable_planning_data()
224 ptr_optimized_path->set_name(
Name());
225 ptr_optimized_path->mutable_path_point()->CopyFrom(
226 {path_points.begin(), path_points.end()});
229bool NaviPathDecider::GetBasicPathData(
230 const ReferenceLine& reference_line,
231 std::vector<common::PathPoint>*
const path_points) {
232 CHECK_NOTNULL(path_points);
239 path_len = std::max(path_len, min_path_len);
241 const double reference_line_len = reference_line.Length();
242 if (reference_line_len < path_len) {
243 AERROR <<
"Reference line is too short to generate path trajectory( s = "
244 << reference_line_len <<
").";
250 auto start_plan_point_project = reference_line.GetReferencePoint(
251 start_plan_point_.
x(), start_plan_point_.
y());
252 common::SLPoint sl_point;
253 if (!reference_line.XYToSL(start_plan_point_project.ToPathPoint(0.0),
255 AERROR <<
"Failed to get start plan point s from reference "
259 auto start_plan_point_project_s = sl_point.has_s() ? sl_point.s() : 0.0;
262 ADEBUG <<
"Basic path data len ; " << reference_line_len;
263 static constexpr double KDenseSampleUnit = 0.50;
264 static constexpr double KSparseSmapleUnit = 2.0;
265 for (
double s = start_plan_point_project_s; s < reference_line_len;
266 s += ((s < path_len) ? KDenseSampleUnit : KSparseSmapleUnit)) {
267 const auto& ref_point = reference_line.GetReferencePoint(s);
268 auto path_point = ref_point.ToPathPoint(s - start_plan_point_project_s);
269 path_points->emplace_back(path_point);
272 if (path_points->empty()) {
273 AERROR <<
"path poins is empty.";
280bool NaviPathDecider::IsSafeChangeLane(
const ReferenceLine& reference_line,
281 const PathDecision& path_decision) {
282 const auto& adc_param =
285 Vec2d adc_position(start_plan_point_.
x(), start_plan_point_.
y());
287 (adc_param.front_edge_to_center() - adc_param.back_edge_to_center()) /
289 (adc_param.left_edge_to_center() - adc_param.right_edge_to_center()) /
291 Vec2d adc_center(adc_position +
292 vec_to_center.rotate(start_plan_point_.
theta()));
293 Box2d adc_box(adc_center, start_plan_point_.
theta(), adc_param.length(),
295 SLBoundary adc_sl_boundary;
296 if (!reference_line.GetSLBoundary(adc_box, &adc_sl_boundary)) {
297 AERROR <<
"Failed to get ADC boundary from box: " << adc_box.DebugString();
301 for (
const auto* obstacle : path_decision.obstacles().Items()) {
302 const auto& sl_boundary = obstacle->PerceptionSLBoundary();
303 static constexpr double kLateralShift = 6.0;
304 if (sl_boundary.start_l() < -kLateralShift ||
305 sl_boundary.end_l() > kLateralShift) {
309 static constexpr double kSafeTime = 3.0;
310 static constexpr double kForwardMinSafeDistance = 6.0;
311 static constexpr double kBackwardMinSafeDistance = 8.0;
313 const double kForwardSafeDistance = std::max(
314 kForwardMinSafeDistance,
316 const double kBackwardSafeDistance = std::max(
317 kBackwardMinSafeDistance,
319 if (sl_boundary.end_s() >
320 adc_sl_boundary.start_s() - kBackwardSafeDistance &&
321 sl_boundary.start_s() <
322 adc_sl_boundary.end_s() + kForwardSafeDistance) {
330double NaviPathDecider::NudgeProcess(
331 const ReferenceLine& reference_line,
332 const std::vector<common::PathPoint>& path_data_points,
333 const std::vector<const Obstacle*>& obstacles,
334 const PathDecision& path_decision,
335 const common::VehicleState& vehicle_state) {
336 double nudge_position_y = 0.0;
339 int lane_obstacles_num = 0;
340 static constexpr double KNudgeEpsilon = 1e-6;
342 obstacles, reference_line, path_decision, path_data_points, vehicle_state,
343 &lane_obstacles_num);
345 if (std::fabs(nudge_distance) > KNudgeEpsilon) {
346 ADEBUG <<
"need latteral nudge distance : " << nudge_distance;
347 nudge_position_y = nudge_distance;
348 last_lane_id_to_nudge_flag_[cur_reference_line_lane_id_] =
true;
352 bool last_plan_has_nudge =
false;
353 if (last_lane_id_to_nudge_flag_.find(cur_reference_line_lane_id_) !=
354 last_lane_id_to_nudge_flag_.end()) {
355 last_plan_has_nudge =
356 last_lane_id_to_nudge_flag_[cur_reference_line_lane_id_];
359 if (last_plan_has_nudge && lane_obstacles_num != 0) {
360 ADEBUG <<
"Keepping last nudge path direction";
361 nudge_position_y = vehicle_state_.
y();
364 last_lane_id_to_nudge_flag_[cur_reference_line_lane_id_] =
false;
365 nudge_position_y = path_data_points[0].y();
369 return nudge_position_y;
372double NaviPathDecider::CalculateDistanceToDestLane() {
375 double move_distance = 0.0;
376 double max_adc_speed =
377 start_plan_v_ + start_plan_a_ * 1.0 / FLAGS_planning_loop_rate;
378 auto max_speed_level_itr = std::upper_bound(
379 max_speed_levels_.begin(), max_speed_levels_.end(), max_adc_speed);
380 if (max_speed_level_itr != max_speed_levels_.end()) {
381 auto max_speed_level = *max_speed_level_itr;
382 move_distance = move_dest_lane_config_talbe_[max_speed_level];
385 return move_distance;
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Rectangular (undirected) bounding box in 2-D.
Implements a class of 2-dimensional vectors.
const std::string & Id() const
Frame holds all data for one planning cycle.
const std::vector< const Obstacle * > obstacles() const
const common::VehicleState & vehicle_state() const
const common::TrajectoryPoint & PlanningStartPoint() const
bool Init(const PlannerNaviConfig &config) override
Initialization parameters
double GetNudgeDistance(const std::vector< const Obstacle * > &obstacles, const ReferenceLine &reference_line, const PathDecision &path_decision, const std::vector< common::PathPoint > &path_data_points, const common::VehicleState &vehicle_state, int *lane_obstacles_num)
get the actual nudgable distance according to the position of the obstacle
bool Init(const PlannerNaviConfig &config) override
apollo::common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info) override
Overrided implementation of the virtual function "Execute" in the base class "Task".
virtual const std::string & Name() const
virtual apollo::common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info)
ReferenceLineInfo * reference_line_info_
void SetReferenceLine(const ReferenceLine *reference_line)
bool SetDiscretizedPath(DiscretizedPath path)
PathDecision represents all obstacle decisions on one path.
ReferenceLineInfo holds all data for one reference line.
PathDecision * path_decision()
void SetDrivable(bool drivable)
Set if the vehicle can drive following this reference line A planner need to set this value to true i...
const hdmap::RouteSegments & Lanes() const
const ReferenceLine & reference_line() const
const PathData & path_data() const
planning_internal::Debug * mutable_debug()
PathData * mutable_path_data()
Planning module main class.
This file provides the declaration of the class "NaviPathDecider".
optional PathPoint path_point
optional VehicleParam vehicle_param
optional double linear_velocity
optional double linear_acceleration
optional double max_keep_lane_distance
optional double keep_lane_shift_compensation
optional uint32 min_look_forward_time
optional MoveDestLaneConfigTable move_dest_lane_config_talbe
optional double max_keep_lane_shift_y
optional uint32 start_plan_point_from
optional double min_keep_lane_offset
optional double move_dest_lane_compensation
optional double min_path_length
optional NaviPathDeciderConfig navi_path_decider_config