39 std::vector<std::pair<double, double>> raw_point2d;
40 std::vector<double> anchorpoints_lateralbound;
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);
50 anchorpoints_lateralbound.front() = 0.0;
51 anchorpoints_lateralbound.back() = 0.0;
53 NormalizePoints(&raw_point2d);
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,
65 status = FemPosSmooth(raw_point2d, anchorpoints_lateralbound,
69 AERROR <<
"Smoother type not defined";
74 AERROR <<
"discrete_points reference line smoother fails";
78 DeNormalizePoints(&smoothed_point2d);
80 std::vector<ReferencePoint> ref_points;
81 GenerateRefPointProfile(raw_reference_line, smoothed_point2d, &ref_points);
85 if (ref_points.size() < 2) {
86 AERROR <<
"Fail to generate smoothed reference line.";
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();
105 std::vector<double> box_bounds = bounds;
106 const double box_ratio = 1.0 / std::sqrt(2.0);
107 for (
auto& bound : box_bounds) {
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);
116 AERROR <<
"Costheta reference line smoothing failed";
120 if (opt_x.size() < 2 || opt_y.size() < 2) {
121 AERROR <<
"Return by Costheta smoother is wrong. Size smaller than 2 ";
125 CHECK_EQ(opt_x.size(), opt_y.size()) <<
"x and y result size not equal";
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]);
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();
142 FemPosDeviationSmoother smoother(fem_pos_config);
146 std::vector<double> box_bounds = bounds;
147 const double box_ratio = 1.0 / std::sqrt(2.0);
148 for (
auto& bound : box_bounds) {
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);
157 AERROR <<
"Fem Pos reference line smoothing failed";
161 if (opt_x.size() < 2 || opt_y.size() < 2) {
162 AERROR <<
"Return by fem pos smoother is wrong. Size smaller than 2 ";
166 CHECK_EQ(opt_x.size(), opt_y.size()) <<
"x and y result size not equal";
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]);
177 const std::vector<AnchorPoint>& anchor_points) {
178 CHECK_GT(anchor_points.size(), 1U);
179 anchor_points_ = anchor_points;
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_,
192 point = std::move(xy);
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_,
204 point = std::move(xy);
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) {
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)) {
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},
230 const double kEpsilon = 1e-6;
231 if (ref_sl_point.s() < -kEpsilon ||
232 ref_sl_point.s() > raw_reference_line.Length()) {
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();
241 reference_points->emplace_back(ReferencePoint(
243 common::math::Vec2d(xy_points[i].first, xy_points[i].second),
244 headings[i], new_lane_waypoints),
245 kappas[i], dkappas[i]));
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
DiscretePointsReferenceLineSmoother(const ReferenceLineSmootherConfig &config)
void SetAnchorPoints(const std::vector< AnchorPoint > &) override
Smoothing constraints
ReferenceLineSmootherConfig config_
static void RemoveDuplicates(std::vector< ReferencePoint > *points)
Planning module main class.
T bound(const T &x, const T &min, const T &max)
Get bound of value x
@ FEM_POS_DEVIATION_SMOOTHING