Apollo 11.0
自动驾驶开放平台
discrete_points_reference_line_smoother.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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
21#include "cyber/common/file.h"
22#include "cyber/common/log.h"
28
29namespace apollo {
30namespace planning {
31
35
37 const ReferenceLine& raw_reference_line,
38 ReferenceLine* const smoothed_reference_line) {
39 std::vector<std::pair<double, double>> raw_point2d;
40 std::vector<double> anchorpoints_lateralbound;
41
42 for (const auto& anchor_point : anchor_points_) {
43 raw_point2d.emplace_back(anchor_point.path_point.x(),
44 anchor_point.path_point.y());
45 anchorpoints_lateralbound.emplace_back(anchor_point.lateral_bound);
46 }
47
48 // fix front and back points to avoid end states deviate from the center of
49 // road
50 anchorpoints_lateralbound.front() = 0.0;
51 anchorpoints_lateralbound.back() = 0.0;
52
53 NormalizePoints(&raw_point2d);
54
55 bool status = false;
56
57 const auto& smoothing_method = config_.discrete_points().smoothing_method();
58 std::vector<std::pair<double, double>> smoothed_point2d;
59 switch (smoothing_method) {
61 status = CosThetaSmooth(raw_point2d, anchorpoints_lateralbound,
62 &smoothed_point2d);
63 break;
65 status = FemPosSmooth(raw_point2d, anchorpoints_lateralbound,
66 &smoothed_point2d);
67 break;
68 default:
69 AERROR << "Smoother type not defined";
70 return false;
71 }
72
73 if (!status) {
74 AERROR << "discrete_points reference line smoother fails";
75 return false;
76 }
77
78 DeNormalizePoints(&smoothed_point2d);
79
80 std::vector<ReferencePoint> ref_points;
81 GenerateRefPointProfile(raw_reference_line, smoothed_point2d, &ref_points);
82
84
85 if (ref_points.size() < 2) {
86 AERROR << "Fail to generate smoothed reference line.";
87 return false;
88 }
89
90 *smoothed_reference_line = ReferenceLine(ref_points);
91 return true;
92}
93
94bool DiscretePointsReferenceLineSmoother::CosThetaSmooth(
95 const std::vector<std::pair<double, double>>& raw_point2d,
96 const std::vector<double>& bounds,
97 std::vector<std::pair<double, double>>* ptr_smoothed_point2d) {
98 const auto& cos_theta_config =
99 config_.discrete_points().cos_theta_smoothing();
100
101 CosThetaSmoother smoother(cos_theta_config);
102
103 // box contraints on pos are used in cos theta smoother, thus shrink the
104 // bounds by 1.0 / sqrt(2.0)
105 std::vector<double> box_bounds = bounds;
106 const double box_ratio = 1.0 / std::sqrt(2.0);
107 for (auto& bound : box_bounds) {
108 bound *= box_ratio;
109 }
110
111 std::vector<double> opt_x;
112 std::vector<double> opt_y;
113 bool status = smoother.Solve(raw_point2d, box_bounds, &opt_x, &opt_y);
114
115 if (!status) {
116 AERROR << "Costheta reference line smoothing failed";
117 return false;
118 }
119
120 if (opt_x.size() < 2 || opt_y.size() < 2) {
121 AERROR << "Return by Costheta smoother is wrong. Size smaller than 2 ";
122 return false;
123 }
124
125 CHECK_EQ(opt_x.size(), opt_y.size()) << "x and y result size not equal";
126
127 size_t point_size = opt_x.size();
128 for (size_t i = 0; i < point_size; ++i) {
129 ptr_smoothed_point2d->emplace_back(opt_x[i], opt_y[i]);
130 }
131
132 return true;
133}
134
135bool DiscretePointsReferenceLineSmoother::FemPosSmooth(
136 const std::vector<std::pair<double, double>>& raw_point2d,
137 const std::vector<double>& bounds,
138 std::vector<std::pair<double, double>>* ptr_smoothed_point2d) {
139 const auto& fem_pos_config =
140 config_.discrete_points().fem_pos_deviation_smoothing();
141
142 FemPosDeviationSmoother smoother(fem_pos_config);
143
144 // box contraints on pos are used in fem pos smoother, thus shrink the
145 // bounds by 1.0 / sqrt(2.0)
146 std::vector<double> box_bounds = bounds;
147 const double box_ratio = 1.0 / std::sqrt(2.0);
148 for (auto& bound : box_bounds) {
149 bound *= box_ratio;
150 }
151
152 std::vector<double> opt_x;
153 std::vector<double> opt_y;
154 bool status = smoother.Solve(raw_point2d, box_bounds, &opt_x, &opt_y);
155
156 if (!status) {
157 AERROR << "Fem Pos reference line smoothing failed";
158 return false;
159 }
160
161 if (opt_x.size() < 2 || opt_y.size() < 2) {
162 AERROR << "Return by fem pos smoother is wrong. Size smaller than 2 ";
163 return false;
164 }
165
166 CHECK_EQ(opt_x.size(), opt_y.size()) << "x and y result size not equal";
167
168 size_t point_size = opt_x.size();
169 for (size_t i = 0; i < point_size; ++i) {
170 ptr_smoothed_point2d->emplace_back(opt_x[i], opt_y[i]);
171 }
172
173 return true;
174}
175
177 const std::vector<AnchorPoint>& anchor_points) {
178 CHECK_GT(anchor_points.size(), 1U);
179 anchor_points_ = anchor_points;
180}
181
182void DiscretePointsReferenceLineSmoother::NormalizePoints(
183 std::vector<std::pair<double, double>>* xy_points) {
184 zero_x_ = xy_points->front().first;
185 zero_y_ = xy_points->front().second;
186 std::for_each(xy_points->begin(), xy_points->end(),
187 [this](std::pair<double, double>& point) {
188 auto curr_x = point.first;
189 auto curr_y = point.second;
190 std::pair<double, double> xy(curr_x - zero_x_,
191 curr_y - zero_y_);
192 point = std::move(xy);
193 });
194}
195
196void DiscretePointsReferenceLineSmoother::DeNormalizePoints(
197 std::vector<std::pair<double, double>>* xy_points) {
198 std::for_each(xy_points->begin(), xy_points->end(),
199 [this](std::pair<double, double>& point) {
200 auto curr_x = point.first;
201 auto curr_y = point.second;
202 std::pair<double, double> xy(curr_x + zero_x_,
203 curr_y + zero_y_);
204 point = std::move(xy);
205 });
206}
207
208bool DiscretePointsReferenceLineSmoother::GenerateRefPointProfile(
209 const ReferenceLine& raw_reference_line,
210 const std::vector<std::pair<double, double>>& xy_points,
211 std::vector<ReferencePoint>* reference_points) {
212 // Compute path profile
213 std::vector<double> headings;
214 std::vector<double> kappas;
215 std::vector<double> dkappas;
216 std::vector<double> accumulated_s;
218 xy_points, &headings, &accumulated_s, &kappas, &dkappas)) {
219 return false;
220 }
221
222 // Load into ReferencePoints
223 size_t points_size = xy_points.size();
224 for (size_t i = 0; i < points_size; ++i) {
225 common::SLPoint ref_sl_point;
226 if (!raw_reference_line.XYToSL({xy_points[i].first, xy_points[i].second},
227 &ref_sl_point)) {
228 return false;
229 }
230 const double kEpsilon = 1e-6;
231 if (ref_sl_point.s() < -kEpsilon ||
232 ref_sl_point.s() > raw_reference_line.Length()) {
233 continue;
234 }
235 ref_sl_point.set_s(std::max(ref_sl_point.s(), 0.0));
236 ReferencePoint rlp = raw_reference_line.GetReferencePoint(ref_sl_point.s());
237 auto new_lane_waypoints = rlp.lane_waypoints();
238 for (auto& lane_waypoint : new_lane_waypoints) {
239 lane_waypoint.l = ref_sl_point.l();
240 }
241 reference_points->emplace_back(ReferencePoint(
242 hdmap::MapPathPoint(
243 common::math::Vec2d(xy_points[i].first, xy_points[i].second),
244 headings[i], new_lane_waypoints),
245 kappas[i], dkappas[i]));
246 }
247 return true;
248}
249
250} // namespace planning
251} // namespace apollo
static bool ComputePathProfile(const std::vector< std::pair< double, double > > &xy_points, std::vector< double > *headings, std::vector< double > *accumulated_s, std::vector< double > *kappas, std::vector< double > *dkappas)
bool Smooth(const ReferenceLine &raw_reference_line, ReferenceLine *const smoothed_reference_line) override
Smooth a given reference line
void SetAnchorPoints(const std::vector< AnchorPoint > &) override
Smoothing constraints
static void RemoveDuplicates(std::vector< ReferencePoint > *points)
Planning module main class.
#define AERROR
Definition log.h:44
Some util functions.
T bound(const T &x, const T &min, const T &max)
Get bound of value x
Definition misc.h:98
class register implement
Definition arena_queue.h:37