Apollo 11.0
自动驾驶开放平台
smooth_stop_trajectory_fallback.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
22
23#include <algorithm>
24
29
30namespace apollo {
31namespace planning {
32
33using common::math::Vec2d;
34
35SpeedData SmoothStopTrajectoryFallback::GenerateFallbackSpeed(const EgoInfo* ego_info, const double stop_distance) {
36 const double v0 = ego_info->start_point().v();
37 const double a0 = ego_info->start_point().a();
38 // Use the max value of jerk bound as max jerk value for fallback speed
39 // planning for convenience.
40 const double max_deceleration = FLAGS_slowdown_profile_deceleration;
41 // Get the lower bound to check collision.
42 std::vector<std::vector<Vec2d>> lower_bounds;
43 GetLowerSTBound(lower_bounds);
44 // Check the initial motion state to make sure the vehicle not move backward.
45 if (a0 <= 0.0) {
46 SpeedData speed_data;
47 if (v0 <= 0.0) {
48 // Make vehicle stop directly to get status: (v0 = 0, a0 = 0)
49 speed_data.AppendSpeedPoint(0.0, 0.0, 0.0, 0.0, 0.0);
50 AINFO << "Fallback speed: current speed is already 0! a0: " << a0 << " v0: " << v0;
52 return speed_data;
53 } else {
54 double square_a0 = a0 * a0;
55 double min_jerk_required = square_a0 / (2.0 * v0);
56 if (FLAGS_longitudinal_jerk_upper_bound < min_jerk_required) {
57 double slow_down_time = -a0 / min_jerk_required;
58 // Make vehicle stop directly to get status: (v0 = 0, a0 = 0)
59 double s = 0.0;
60 double v = 0.0;
61 double a = 0.0;
62 double square_t = 0.0;
63 for (double t = 0.0; t < slow_down_time; t += FLAGS_fallback_time_unit) {
64 square_t = t * t;
65 a = a0 + t * min_jerk_required;
66 v = v0 + a0 * t + 0.5 * min_jerk_required * square_t;
67 s = v0 * t + 0.5 * a0 * square_t + min_jerk_required * square_t * t / 6.0;
68 speed_data.AppendSpeedPoint(s, t, v, a, min_jerk_required);
69 }
70 if (!IsCollisionWithSpeedBoundaries(speed_data)) {
71 AINFO << "Fallback speed: Make vehicle just stop to zero speed. a0: " << a0 << " v0: " << v0
72 << " new_jerk: " << min_jerk_required;
74 return speed_data;
75 }
76 // Fast stop because of collision.
77 SpeedData fast_stop_speed_data;
78 SpeedPlanner::FastStop(v0, a0, max_deceleration, &fast_stop_speed_data);
80 AINFO << "Fallback speed: Fast stop because of collision. a0: " << a0 << " v0: " << v0
81 << " dec: " << max_deceleration;
82 return fast_stop_speed_data;
83 }
84 }
85 }
86 // 1. Stop with max deceleration and check collision.
87 SpeedData fast_stop_speed_data;
88 SpeedPlanner::FastStop(v0, a0, max_deceleration, &fast_stop_speed_data);
89 if (IsCollisionWithSpeedBoundaries(fast_stop_speed_data)) {
91 AINFO << "Fallback speed: Fast stop the vehicle. a0: " << a0 << " v0: " << v0 << " dec: " << max_deceleration;
92 return fast_stop_speed_data;
93 }
94
95 // 2. Stop smoothly and check collision.
96 SpeedData smooth_stop_speed_data;
98 v0,
99 a0,
100 max_deceleration,
101 FLAGS_longitudinal_jerk_upper_bound,
102 FLAGS_longitudinal_jerk_lower_bound,
103 &smooth_stop_speed_data);
104 if (IsCollisionWithSpeedBoundaries(smooth_stop_speed_data)) {
105 // Need stop more quickly. Try to enlarge max jerk.
106 double max_jerk = fabs(max_deceleration / FLAGS_fallback_time_unit);
107 smooth_stop_speed_data.clear();
108 SpeedPlanner::SmoothStop(v0, a0, max_deceleration, max_jerk, max_jerk, &smooth_stop_speed_data);
109 if (IsCollisionWithSpeedBoundaries(smooth_stop_speed_data)) {
110 AINFO << "Fallback speed: Hard to stop smoothly and use still fast stop. "
111 "a0: "
112 << a0 << " v0: " << v0 << " dec: " << max_deceleration;
114 return fast_stop_speed_data;
115 }
116 SpeedData last_no_collision_speed_data = smooth_stop_speed_data;
117 // Find the proper max_jerk with binary search.
118 double lower_jerk
119 = std::min(fabs(FLAGS_longitudinal_jerk_upper_bound), fabs(FLAGS_longitudinal_jerk_lower_bound));
120 double upper_jerk = max_jerk;
121 double mid_jerk = 0.0;
122 const double jerk_error = 1.0;
123 while (mid_jerk - lower_jerk > jerk_error) {
124 mid_jerk = (lower_jerk + upper_jerk) * 0.5;
125 SpeedPlanner::SmoothStop(v0, a0, max_deceleration, mid_jerk, mid_jerk, &smooth_stop_speed_data);
126 if (IsCollisionWithSpeedBoundaries(smooth_stop_speed_data)) {
127 lower_jerk = mid_jerk;
128 } else {
129 upper_jerk = mid_jerk;
130 last_no_collision_speed_data = smooth_stop_speed_data;
131 }
132 }
133 SpeedProfileGenerator::FillEnoughSpeedPoints(&last_no_collision_speed_data);
134 AINFO << "Fallback speed: Find new jerk to stop the vehilce. a0: " << a0 << " v0: " << v0
135 << " new jerk: " << mid_jerk;
136 return last_no_collision_speed_data;
137 }
138 AINFO << "Fallback speed: stop smoothly the vehilce. a0: " << a0 << " v0: " << v0 << " dec: " << max_deceleration;
139 SpeedProfileGenerator::FillEnoughSpeedPoints(&smooth_stop_speed_data);
140 return smooth_stop_speed_data;
141}
142
143bool SmoothStopTrajectoryFallback::IsCollisionWithSpeedBoundaries(
144 const SpeedData& speed_data) const {
145 if (speed_data.empty()) {
146 return false;
147 }
148 const std::vector<const STBoundary*>& st_boundaries = reference_line_info_->st_graph_data().st_boundaries();
149 for (const auto& boundary : st_boundaries) {
150 for (int i = 0; i < speed_data.size() - 1; i++) {
151 Vec2d point1(speed_data[i].s(), speed_data[i].t());
152 Vec2d point2(speed_data[i + 1].s(), speed_data[i + 1].t());
153 if (boundary->HasOverlap({point1, point2})) {
154 return true;
155 }
156 }
157 }
158 return false;
159}
160
161bool CompareVec2d(const Vec2d& v1, const Vec2d& v2) {
162 return (v1.x() < v2.x());
163}
164
165void SmoothStopTrajectoryFallback::GetLowerSTBound(std::vector<std::vector<Vec2d>>& lower_bounds) {
166 lower_bounds.clear();
167 const std::vector<const STBoundary*>& st_boundaries = reference_line_info_->st_graph_data().st_boundaries();
168 const double min_time_distance = 0.0001;
169 for (const STBoundary* boundary : st_boundaries) {
170 std::vector<Vec2d> lower_bound_points;
171 const auto& points = boundary->points();
172 for (const auto& p : points) {
173 bool is_exist = false;
174 for (size_t i = 0; i < lower_bound_points.size(); ++i) {
175 if (fabs(lower_bound_points[i].x() - p.x()) < min_time_distance) {
176 if (lower_bound_points[i].y() > p.y()) {
177 lower_bound_points[i].set_y(p.y());
178 }
179 is_exist = true;
180 break;
181 }
182 }
183 if (!is_exist) {
184 lower_bound_points.emplace_back(p);
185 }
186 }
187 std::sort(lower_bound_points.begin(), lower_bound_points.end(), CompareVec2d);
188 lower_bounds.emplace_back(lower_bound_points);
189 }
190}
191
192} // namespace planning
193} // namespace apollo
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
double x() const
Getter for x component
Definition vec2d.h:54
common::TrajectoryPoint start_point() const
Definition ego_info.h:51
SpeedData GenerateFallbackSpeed(const EgoInfo *ego_info, const double stop_distance=0.0) override
void AppendSpeedPoint(const double s, const double time, const double v, const double a, const double da)
Definition speed_data.cc:48
static void SmoothStop(double v0, double a0, double max_deceleration, double max_pos_jerk, double max_neg_jerk, SpeedData *speed_data)
static void FastStop(double v0, double a0, double max_deceleration, SpeedData *speed_data)
static void FillEnoughSpeedPoints(SpeedData *const speed_data)
const std::vector< const STBoundary * > & st_boundaries() const
ReferenceLineInfo * reference_line_info_
Definition task.h:58
Planning module main class.
#define AINFO
Definition log.h:42
bool CompareVec2d(const Vec2d &v1, const Vec2d &v2)
class register implement
Definition arena_queue.h:37