42constexpr double kTsGraphSStep = 0.4;
43constexpr size_t kFallbackSpeedPointNum = 4;
44constexpr double kSpeedPointSLimit = 200.0;
45constexpr double kSpeedPointTimeLimit = 50.0;
46constexpr double kZeroSpeedEpsilon = 1.0e-3;
47constexpr double kZeroAccelEpsilon = 1.0e-3;
48constexpr double kDecelCompensationLimit = 2.0;
49constexpr double kKappaAdjustRatio = 20.0;
55 CHECK_GT(FLAGS_planning_upper_speed_limit, 0.0);
56 ACHECK(config.has_navi_speed_decider_config());
77 max_speed_ = FLAGS_planning_upper_speed_limit;
86 preferred_accel_ = std::min(max_accel_, preferred_accel_);
87 preferred_decel_ = std::min(max_decel_, preferred_accel_);
93 safe_distance_ratio_ =
95 following_accel_ratio_ =
97 soft_centric_accel_limit_ =
99 hard_centric_accel_limit_ =
101 soft_centric_accel_limit_ =
102 std::min(hard_centric_accel_limit_, soft_centric_accel_limit_);
108 enable_planning_start_point_ =
110 enable_accel_auto_compensation_ =
115 return obstacle_decider_.
Init(config);
124 preferred_speed_ = planning_target.has_cruise_speed()
125 ? std::abs(planning_target.cruise_speed())
127 preferred_speed_ = std::min(max_speed_, preferred_speed_);
132 planning_start_point.has_v() ? planning_start_point.
v() : 0.0;
134 planning_start_point.has_a() ? planning_start_point.a() : 0.0;
138 auto current_v = vehicle_state.has_linear_velocity()
141 auto current_a = vehicle_state.has_linear_acceleration()
142 ? vehicle_state.linear_acceleration()
150 if (enable_planning_start_point_) {
151 start_v = std::max(0.0, expected_v);
152 start_a = expected_a;
155 start_v = std::max(0.0, current_v);
161 if (enable_accel_auto_compensation_) {
162 if (prev_v_ > 0.0 && current_v > 0.0 && prev_v_ > expected_v) {
163 auto raw_ratio = (prev_v_ - expected_v) / (prev_v_ - current_v);
164 raw_ratio = Clamp(raw_ratio, 0.0, kDecelCompensationLimit);
165 decel_compensation_ratio_ = (decel_compensation_ratio_ + raw_ratio) / 2.0;
166 decel_compensation_ratio_ =
167 Clamp(decel_compensation_ratio_, 1.0, kDecelCompensationLimit);
168 ADEBUG <<
"change decel_compensation_ratio: " << decel_compensation_ratio_
169 <<
" raw: " << raw_ratio;
177 auto ret = MakeSpeedDecision(
179 [&](
const std::string&
id) { return frame_->Find(id); },
181 RecordDebugInfo(reference_line_info->
speed_data());
184 AERROR <<
"Reference Line " << reference_line_info->
Lanes().
Id()
185 <<
" is not drivable after " <<
Name();
191Status NaviSpeedDecider::MakeSpeedDecision(
192 double start_v,
double start_a,
double start_da,
193 const std::vector<PathPoint>& path_points,
194 const std::vector<const Obstacle*>& obstacles,
195 const std::function<
const Obstacle*(
const std::string&)>& find_obstacle,
197 CHECK_NOTNULL(speed_data);
198 CHECK_GE(path_points.size(), 2U);
200 auto start_s = path_points.front().has_s() ? path_points.front().s() : 0.0;
201 auto end_s = path_points.back().has_s() ? path_points.back().s() : start_s;
202 auto planning_length = end_s - start_s;
204 ADEBUG <<
"start to make speed decision, start_v: " << start_v
205 <<
" start_a: " << start_a <<
" start_da: " << start_da
206 <<
" start_s: " << start_s <<
" planning_length: " << planning_length;
208 if (start_v > max_speed_) {
209 const std::string msg =
"exceeding maximum allowable speed.";
211 return Status(ErrorCode::PLANNING_ERROR, msg);
213 start_v = std::max(0.0, start_v);
215 auto s_step = planning_length > kTsGraphSStep
217 : planning_length / kFallbackSpeedPointNum;
220 ts_graph_.
Reset(s_step, planning_length, start_v, start_a, start_da);
223 auto ret = AddPerceptionRangeConstraints();
225 AERROR <<
"Add t-s constraints base on range of perception failed";
229 ret = AddObstaclesConstraints(start_v, planning_length, path_points,
230 obstacles, find_obstacle);
232 AERROR <<
"Add t-s constraints base on obstacles failed";
236 ret = AddCentricAccelerationConstraints(path_points);
238 AERROR <<
"Add t-s constraints base on centric acceleration failed";
242 ret = AddConfiguredConstraints();
244 AERROR <<
"Add t-s constraints base on configs failed";
249 std::vector<NaviSpeedTsPoint> ts_points;
251 AERROR <<
"Solve speed points failed";
259 for (
auto& ts_point : ts_points) {
260 if (ts_point.s > kSpeedPointSLimit || ts_point.t > kSpeedPointTimeLimit)
263 if (ts_point.v > hard_speed_limit_) {
264 AERROR <<
"The v: " << ts_point.v <<
" of point with s: " << ts_point.s
265 <<
" and t: " << ts_point.t <<
"is greater than hard_speed_limit "
266 << hard_speed_limit_;
267 ts_point.v = hard_speed_limit_;
270 if (std::abs(ts_point.v) < kZeroSpeedEpsilon) {
273 if (ts_point.a > hard_accel_limit_) {
274 AERROR <<
"The a: " << ts_point.a <<
" of point with s: " << ts_point.s
275 <<
" and t: " << ts_point.t <<
"is greater than hard_accel_limit "
276 << hard_accel_limit_;
277 ts_point.a = hard_accel_limit_;
280 if (std::abs(ts_point.a) < kZeroAccelEpsilon) {
284 if (enable_accel_auto_compensation_) {
286 ts_point.a *= accel_compensation_ratio_;
288 ts_point.a *= decel_compensation_ratio_;
292 ts_point.a, ts_point.da);
295 if (speed_data->size() == 1) {
296 const auto& prev = speed_data->back();
303Status NaviSpeedDecider::AddPerceptionRangeConstraints() {
308Status NaviSpeedDecider::AddObstaclesConstraints(
309 double vehicle_speed,
double path_length,
310 const std::vector<PathPoint>& path_points,
311 const std::vector<const Obstacle*>& obstacles,
312 const std::function<
const Obstacle*(
const std::string&)>& find_obstacle) {
313 const auto& vehicle_config = VehicleConfigHelper::Instance()->GetConfig();
314 auto front_edge_to_center =
315 vehicle_config.vehicle_param().front_edge_to_center();
316 auto get_obstacle_distance = [&](
double d) ->
double {
317 return std::max(0.0, d - front_edge_to_center - obstacle_buffer_);
319 auto get_safe_distance = [&](
double v) ->
double {
320 return safe_distance_ratio_ * v + safe_distance_base_ +
321 front_edge_to_center + obstacle_buffer_;
326 for (
const auto& info : obstacle_decider_.UnsafeObstacles()) {
327 const auto&
id = std::get<0>(info);
328 const auto* obstacle = find_obstacle(
id);
329 if (obstacle !=
nullptr) {
330 auto s = std::get<1>(info);
331 auto obstacle_distance = get_obstacle_distance(s);
332 auto obstacle_speed = std::max(std::get<2>(info), 0.0);
333 auto safe_distance = get_safe_distance(obstacle_speed);
334 AINFO <<
"obstacle with id: " <<
id <<
" s: " << s
335 <<
" distance: " << obstacle_distance
336 <<
" speed: " << obstacle_speed
337 <<
" safe_distance: " << safe_distance;
340 following_accel_ratio_,
341 obstacle_speed, preferred_speed_);
346 if (enable_safe_path_) {
347 auto obstacle_distance = get_obstacle_distance(path_length);
348 auto safe_distance = get_safe_distance(0.0);
350 following_accel_ratio_, 0.0,
362Status NaviSpeedDecider::AddCentricAccelerationConstraints(
363 const std::vector<PathPoint>& path_points) {
364 if (path_points.size() < 2) {
365 const std::string msg =
"Too few path points";
367 return Status(ErrorCode::PLANNING_ERROR, msg);
370 double max_kappa = 0.0;
371 double max_kappa_v = std::numeric_limits<double>::max();
372 double preffered_kappa_v = std::numeric_limits<double>::max();
373 double max_kappa_s = 0.0;
374 const auto bs = path_points[0].has_s() ? path_points[0].s() : 0.0;
381 std::vector<CLimit> c_limits;
382 c_limits.resize(path_points.size() - 1);
384 for (
size_t i = 1; i < path_points.size(); i++) {
385 const auto& prev = path_points[i - 1];
386 const auto& cur = path_points[i];
387 auto start_s = prev.has_s() ? prev.s() - bs : 0.0;
388 start_s = std::max(0.0, start_s);
389 auto end_s = cur.has_s() ? cur.s() - bs : 0.0;
390 end_s = std::max(0.0, end_s);
391 auto start_k = prev.has_kappa() ? prev.kappa() : 0.0;
392 auto end_k = cur.has_kappa() ? cur.kappa() : 0.0;
393 auto kappa = std::abs((start_k + end_k) / 2.0);
394 if (std::abs(kappa) < kappa_threshold_) {
395 kappa /= kKappaAdjustRatio;
397 auto v_preffered = std::min(std::sqrt(soft_centric_accel_limit_ / kappa),
398 std::numeric_limits<double>::max());
399 auto v_max = std::min(std::sqrt(hard_centric_accel_limit_ / kappa),
400 std::numeric_limits<double>::max());
402 c_limits[i - 1].s = end_s;
403 c_limits[i - 1].v_max = v_max;
404 c_limits[i - 1].v_preffered = v_preffered;
406 if (kappa > max_kappa) {
409 preffered_kappa_v = v_preffered;
410 max_kappa_s = start_s;
415 for (
size_t i = 0; i < c_limits.size(); i++) {
416 for (
size_t j = i; j - i < (size_t)(kappa_preview_ / kTsGraphSStep) &&
419 c_limits[i].v_preffered =
420 std::min(c_limits[j].v_preffered, c_limits[i].v_preffered);
423 double start_s = 0.0;
424 for (
size_t i = 0; i < c_limits.size(); i++) {
425 auto end_s = c_limits[i].s;
426 auto v_max = c_limits[i].v_max;
427 auto v_preffered = c_limits[i].v_preffered;
429 NaviSpeedTsConstraints constraints;
430 constraints.v_max = v_max;
431 constraints.v_preffered = v_preffered;
437 AINFO <<
"add speed limit for centric acceleration with kappa: " << max_kappa
438 <<
" v_max: " << max_kappa_v <<
" v_preffered: " << preffered_kappa_v
439 <<
" s: " << max_kappa_s;
444Status NaviSpeedDecider::AddConfiguredConstraints() {
445 NaviSpeedTsConstraints constraints;
446 constraints.v_max = max_speed_;
447 constraints.v_preffered = preferred_speed_;
448 constraints.a_max = max_accel_;
449 constraints.a_preffered = preferred_accel_;
450 constraints.b_max = max_decel_;
451 constraints.b_preffered = preferred_decel_;
452 constraints.da_preffered = preferred_jerk_;
458void NaviSpeedDecider::RecordDebugInfo(
const SpeedData& speed_data) {
460 auto ptr_speed_plan = debug->mutable_planning_data()->add_speed_plan();
461 ptr_speed_plan->set_name(
Name());
462 ptr_speed_plan->mutable_speed_point()->CopyFrom(
463 {speed_data.begin(), speed_data.end()});
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
@Brief This is a helper class that can load vehicle configurations.
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
void GetUnsafeObstaclesInfo(const std::vector< common::PathPoint > &path_data_points, const std::vector< const Obstacle * > &obstacles)
get the unsafe obstacles between trajectory and reference line.
apollo::common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info) override
Overrided implementation of the virtual function "Execute" in the base class "Task".
bool Init(const PlannerNaviConfig &config) override
void UpdateObstacleConstraints(double distance, double safe_distance, double following_accel_ratio, double v, double cruise_speed)
Assign constraints for an obstacle.
void Reset(double s_step, double s_max, double start_v, double start_a, double start_da)
Reset points's num and time step etc.
void UpdateRangeConstraints(double start_s, double end_s, const NaviSpeedTsConstraints &constraints)
Assign constraints to a range.
void UpdateConstraints(const NaviSpeedTsConstraints &constraints)
Assign constraints to all points.
apollo::common::Status Solve(std::vector< NaviSpeedTsPoint > *points)
Solving the t-s curve.
virtual const std::string & Name() const
virtual apollo::common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info)
ReferenceLineInfo * reference_line_info_
This is the class that associates an Obstacle with its path properties.
const DiscretizedPath & discretized_path() const
ReferenceLineInfo holds all data for one reference line.
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 SpeedData & speed_data() const
SpeedData * mutable_speed_data()
const PlanningTarget & planning_target() const
const hdmap::RouteSegments & Lanes() const
const PathData & path_data() const
planning_internal::Debug * mutable_debug()
void AppendSpeedPoint(const double s, const double time, const double v, const double a, const double da)
Planning module main class.
Math-related util functions.
T Clamp(const T value, T bound1, T bound2)
Clamp a value between two bounds.
Status AddTrafficDecisionConstraints()
This file provides the declaration of the class "NaviSpeedDecider".
optional double linear_velocity
optional double kappa_threshold
optional double obstacle_buffer
optional double preferred_accel
optional double safe_distance_base
optional bool enable_planning_start_point
optional double kappa_preview
optional double hard_centric_accel_limit
optional double max_decel
optional bool enable_safe_path
optional double preferred_decel
optional bool enable_accel_auto_compensation
optional double hard_speed_limit
optional double safe_distance_ratio
optional double preferred_jerk
optional double max_accel
optional double hard_accel_limit
optional double following_accel_ratio
optional double soft_centric_accel_limit
optional NaviSpeedDeciderConfig navi_speed_decider_config