Apollo 11.0
自动驾驶开放平台
sl_polygon.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 <limits>
24#include <string>
25#include <utility>
26
29
32
33namespace apollo {
34namespace planning {
35
37
38
40
42 const std::vector<SLPoint>& boundary, const double s) {
43 ACHECK(!boundary.empty());
44 if (s <= boundary.front().s()) {
45 return boundary.front().l();
46 } else if (s >= boundary.back().s()) {
47 return boundary.back().l();
48 }
49 SLPoint sl_point;
50 sl_point.set_s(s);
51 sl_point.set_l(0.0);
52 auto cmp = [](const SLPoint& sl_point, const double s) {
53 return sl_point.s() < s;
54 };
55 auto iter = std::lower_bound(boundary.begin(), boundary.end(), s, cmp);
56 auto last_iter = *(iter - 1);
57 return last_iter.l() + (s - last_iter.s()) * (iter->l() - last_iter.l()) /
58 (iter->s() - last_iter.s());
59}
60void SLPolygon::PrintToLog(std::string prefix) const {
61 PrintCurves print_curve;
62 std::string key = id_ + prefix + "_sl_boundary";
63 for (int i = 0; i < sl_boundary_.boundary_point_size(); i++) {
64 print_curve.AddPoint(key, sl_boundary_.boundary_point(i).s(),
65 sl_boundary_.boundary_point(i).l());
66 }
67 print_curve.PrintToLog();
68}
69
71 PrintCurves print_curve;
72 std::string key = id_ + "_BlockSLPolygons";
73 for (int i = 0; i < sl_boundary_.boundary_point_size(); i++) {
74 print_curve.AddPoint(key, sl_boundary_.boundary_point(i).s(),
75 sl_boundary_.boundary_point(i).l());
76 }
77 print_curve.PrintToLog();
78}
79
80SLPolygon::SLPolygon(SLBoundary sl_boundary, std::string id,
81 PerceptionObstacle::Type type, bool print_log)
82 : sl_boundary_(sl_boundary), id_(id), obstacle_type_(type) {
83 int min_s_index = -1;
84 int max_s_index = -1;
85 int min_l_index = -1;
86 int max_l_index = -1;
87 double min_s = std::numeric_limits<double>::max();
88 double min_l = std::numeric_limits<double>::max();
89 double max_s = std::numeric_limits<double>::lowest();
90 double max_l = std::numeric_limits<double>::lowest();
91 for (int i = 0; i < sl_boundary.boundary_point_size(); i++) {
92 const auto& sl_point = sl_boundary.boundary_point(i);
93 if (sl_point.s() < min_s) {
94 min_s = sl_point.s();
95 min_s_index = i;
96 }
97 if (sl_point.s() > max_s) {
98 max_s = sl_point.s();
99 max_s_index = i;
100 }
101 if (sl_point.l() < min_l) {
102 min_l = sl_point.l();
103 min_l_index = i;
104 }
105 if (sl_point.l() > max_l) {
106 max_l = sl_point.l();
107 max_l_index = i;
108 }
109 }
110 min_s_point_ = sl_boundary.boundary_point(min_s_index);
111 min_l_point_ = sl_boundary.boundary_point(min_l_index);
112 max_s_point_ = sl_boundary.boundary_point(max_s_index);
113 max_l_point_ = sl_boundary.boundary_point(max_l_index);
114 // AINFO << "min_s_point_" << min_s_point_.s() << "," << min_s_point_.l();
115 // AINFO << "min_l_point_" << min_l_point_.s() << "," << min_l_point_.l();
116 // AINFO << "max_s_point_" << max_s_point_.s() << "," << max_s_point_.l();
117 // AINFO << "max_l_point_" << max_l_point_.s() << "," << max_l_point_.l();
118 int t = min_s_index;
119 SLPoint sl_point;
120 while (t != max_s_index) {
121 sl_point.set_s(sl_boundary.boundary_point(t).s());
122 sl_point.set_l(sl_boundary.boundary_point(t).l());
123 right_boundary_.push_back(sl_point);
124 t = (t + 1) % sl_boundary.boundary_point_size();
125 }
126 sl_point.set_s(sl_boundary.boundary_point(t).s());
127 sl_point.set_l(sl_boundary.boundary_point(t).l());
128 right_boundary_.push_back(sl_point);
129 if (right_boundary_.front().s() > right_boundary_.back().s()) {
130 std::reverse(right_boundary_.begin(), right_boundary_.end());
131 }
132
133 t = max_s_index;
134 while (t != min_s_index) {
135 sl_point.set_s(sl_boundary.boundary_point(t).s());
136 sl_point.set_l(sl_boundary.boundary_point(t).l());
137 left_boundary_.push_back(sl_point);
138 t = (t + 1) % sl_boundary.boundary_point_size();
139 }
140 sl_point.set_s(sl_boundary.boundary_point(t).s());
141 sl_point.set_l(sl_boundary.boundary_point(t).l());
142 left_boundary_.push_back(sl_point);
143 if (left_boundary_.front().s() > left_boundary_.back().s()) {
144 std::reverse(left_boundary_.begin(), left_boundary_.end());
145 }
146 double mid_s = (sl_boundary.boundary_point(min_s_index).s() +
147 sl_boundary.boundary_point(max_s_index).s()) /
148 2.0;
149
150 if (GetInterpolatedLFromBoundary(left_boundary_, mid_s) <
151 GetInterpolatedLFromBoundary(right_boundary_, mid_s)) {
152 std::swap(left_boundary_, right_boundary_);
153 }
154
155 if (print_log) {
156 PrintCurves print_curve;
157 for (auto pt : right_boundary_) {
158 print_curve.AddPoint("right_boundary", pt.s(), pt.l());
159 }
160 for (auto pt : left_boundary_) {
161 print_curve.AddPoint("left_boundary", pt.s(), pt.l());
162 }
163 print_curve.PrintToLog();
164 }
165}
166
168 const std::vector<SLPoint>& boundary, double s) {
169 if (s <= boundary.front().s()) {
170 return boundary.front().l();
171 }
172 if (s >= boundary.back().s()) {
173 return boundary.back().l();
174 }
175 auto iter = std::lower_bound(
176 boundary.begin(), boundary.end(), s,
177 [](const SLPoint& sl_point, const double s) { return sl_point.s() < s; });
178 auto last_iter = std::prev(iter);
179 double ret = last_iter->l() + (s - last_iter->s()) *
180 (iter->l() - last_iter->l()) /
181 (iter->s() - last_iter->s());
182 return ret;
183}
184
185void SLPolygon::UpdatePassableInfo(double left_bound, double right_bound,
186 double left_buffer, double right_buffer,
187 double check_s) {
188 if (!is_passable_[0] && !is_passable_[1]) {
189 return;
190 }
191 double l_lower = GetRightBoundaryByS(check_s);
192 double l_upper = GetLeftBoundaryByS(check_s);
193 is_passable_[0] = left_bound > l_upper + left_buffer;
194 is_passable_[1] = right_bound < l_lower - right_buffer;
195}
196
197double SLPolygon::MinRadiusStopDistance(double adc_min_l, double adc_max_l,
198 double ego_half_width) {
199 if (min_radius_stop_distance_ > 0) {
200 return min_radius_stop_distance_;
201 }
202 static constexpr double stop_distance_buffer = 0.4;
203 double min_turn_radius = VehicleConfigHelper::MinSafeTurnRadius();
204 AINFO << "min_turn_radius: " << min_turn_radius;
205
206 const auto& adc_param =
207 VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
208 double lateral_diff = 0.0;
209 double expand_adc_half_width =
210 ego_half_width + FLAGS_nonstatic_obstacle_nudge_l_buffer;
211 min_turn_radius += expand_adc_half_width;
212 AINFO << "expand min_turn_radius: " << min_turn_radius;
213 if (nudge_type_ == NudgeType::LEFT_NUDGE) {
214 lateral_diff =
215 max_l_point_.l() - adc_min_l + FLAGS_nonstatic_obstacle_nudge_l_buffer;
216 } else if (nudge_type_ == NudgeType::RIGHT_NUDGE) {
217 lateral_diff =
218 adc_max_l + FLAGS_nonstatic_obstacle_nudge_l_buffer - min_l_point_.l();
219 }
220 lateral_diff = std::max(0.0, lateral_diff);
221 const double kEpison = 1e-5;
222 lateral_diff = std::min(lateral_diff, min_turn_radius - kEpison);
223 AINFO << "obs: " << id_ << ", lateral_diff: " << lateral_diff;
224 double min_radius_stop_distance_ =
225 std::sqrt(std::fabs(min_turn_radius * min_turn_radius -
226 (min_turn_radius - lateral_diff) *
227 (min_turn_radius - lateral_diff))) +
228 stop_distance_buffer;
229 double turn_heading =
230 std::atan2(min_radius_stop_distance_, min_turn_radius - lateral_diff);
231
232 min_radius_stop_distance_ +=
233 adc_param.front_edge_to_center() * std::cos(turn_heading);
234 min_radius_stop_distance_ =
235 std::min(min_radius_stop_distance_, FLAGS_max_stop_distance_obstacle);
236 min_radius_stop_distance_ =
237 std::max(min_radius_stop_distance_, FLAGS_min_stop_distance_obstacle +
238 adc_param.front_edge_to_center());
239 AINFO << "obs: " << id_
240 << ", min_radius_stop_distance: " << min_radius_stop_distance_;
241 return min_radius_stop_distance_;
242}
243
244} // namespace planning
245} // namespace apollo
@Brief This is a helper class that can load vehicle configurations.
static double MinSafeTurnRadius()
Get the safe turning radius when the vehicle is turning with maximum steering angle.
void AddPoint(std::string key, double x, double y)
add point to curve key
double MinRadiusStopDistance(double adc_min_l, double adc_max_l, double ego_half_width)
const double GetLeftBoundaryByS(const double s) const
Definition sl_polygon.h:60
void UpdatePassableInfo(double left_bound, double right_bound, double left_buffer, double right_buffer, double check_s)
void PrintToLog(std::string prefix="") const
Definition sl_polygon.cc:60
static double GetInterpolatedLFromBoundary(const std::vector< SLPoint > &boundary, const double s)
Definition sl_polygon.cc:41
static double GetInterpolatedSFromBoundary(const std::vector< SLPoint > &boundary, double s)
const double GetRightBoundaryByS(const double s) const
Definition sl_polygon.h:66
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define AINFO
Definition log.h:42
class register implement
Definition arena_queue.h:37
repeated apollo::common::SLPoint boundary_point