Apollo 11.0
自动驾驶开放平台
qp_spline_reference_line_smoother.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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
21
22#include <algorithm>
23#include <utility>
24
25#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
26
27#include "cyber/common/log.h"
33
34namespace apollo {
35namespace planning {
36
38 const ReferenceLineSmootherConfig& config)
39 : ReferenceLineSmoother(config) {
40 spline_solver_.reset(
41 new OsqpSpline2dSolver(t_knots_, config.qp_spline().spline_order()));
42}
43
44void QpSplineReferenceLineSmoother::Clear() { t_knots_.clear(); }
45
47 const ReferenceLine& raw_reference_line,
48 ReferenceLine* const smoothed_reference_line) {
49 Clear();
50 const double kEpsilon = 1e-6;
51 if (!Sampling()) {
52 AERROR << "Fail to sample reference line smoother points!";
53 return false;
54 }
55
56 spline_solver_->Reset(t_knots_, config_.qp_spline().spline_order());
57
58 if (!AddConstraint()) {
59 AERROR << "Add constraint for spline smoother failed";
60 return false;
61 }
62
63 if (!AddKernel()) {
64 AERROR << "Add kernel for spline smoother failed.";
65 return false;
66 }
67
68 if (!Solve()) {
69 AERROR << "Solve spline smoother problem failed";
70 }
71
72 // mapping spline to reference line point
73 const double start_t = t_knots_.front();
74 const double end_t = t_knots_.back();
75
76 const double resolution =
77 (end_t - start_t) / (config_.num_of_total_points() - 1);
78 double t = start_t;
79 std::vector<ReferencePoint> ref_points;
80 const auto& spline = spline_solver_->spline();
81 for (std::uint32_t i = 0; i < config_.num_of_total_points() && t < end_t;
82 ++i, t += resolution) {
83 const double heading =
84 std::atan2(spline.DerivativeY(t), spline.DerivativeX(t));
85 const double kappa = CurveMath::ComputeCurvature(
86 spline.DerivativeX(t), spline.SecondDerivativeX(t),
87 spline.DerivativeY(t), spline.SecondDerivativeY(t));
88 const double dkappa = CurveMath::ComputeCurvatureDerivative(
89 spline.DerivativeX(t), spline.SecondDerivativeX(t),
90 spline.ThirdDerivativeX(t), spline.DerivativeY(t),
91 spline.SecondDerivativeY(t), spline.ThirdDerivativeY(t));
92
93 std::pair<double, double> xy = spline(t);
94 xy.first += ref_x_;
95 xy.second += ref_y_;
96 common::SLPoint ref_sl_point;
97 if (!raw_reference_line.XYToSL({xy.first, xy.second}, &ref_sl_point)) {
98 return false;
99 }
100 if (ref_sl_point.s() < -kEpsilon ||
101 ref_sl_point.s() > raw_reference_line.Length()) {
102 continue;
103 }
104 ref_sl_point.set_s(std::max(ref_sl_point.s(), 0.0));
105 ReferencePoint rlp = raw_reference_line.GetReferencePoint(ref_sl_point.s());
106 auto new_lane_waypoints = rlp.lane_waypoints();
107 for (auto& lane_waypoint : new_lane_waypoints) {
108 lane_waypoint.l = ref_sl_point.l();
109 }
110 ref_points.emplace_back(ReferencePoint(
111 hdmap::MapPathPoint(common::math::Vec2d(xy.first, xy.second), heading,
112 new_lane_waypoints),
113 kappa, dkappa));
114 }
115
117 if (ref_points.size() < 2) {
118 AERROR << "Fail to generate smoothed reference line.";
119 return false;
120 }
121 *smoothed_reference_line = ReferenceLine(ref_points);
122 return true;
123}
124
125bool QpSplineReferenceLineSmoother::Sampling() {
126 const double length = anchor_points_.back().path_point.s() -
127 anchor_points_.front().path_point.s();
128 uint32_t num_spline =
129 std::max(1u, static_cast<uint32_t>(
130 length / config_.qp_spline().max_spline_length() + 0.5));
131 for (std::uint32_t i = 0; i <= num_spline; ++i) {
132 t_knots_.push_back(i * 1.0);
133 }
134 // normalize point xy
135 ref_x_ = anchor_points_.front().path_point.x();
136 ref_y_ = anchor_points_.front().path_point.y();
137 return true;
138}
139
140bool QpSplineReferenceLineSmoother::AddConstraint() {
141 // Add x, y boundary constraint
142 std::vector<double> headings;
143 std::vector<double> longitudinal_bound;
144 std::vector<double> lateral_bound;
145 std::vector<common::math::Vec2d> xy_points;
146 for (const auto& point : anchor_points_) {
147 const auto& path_point = point.path_point;
148 headings.push_back(path_point.theta());
149 longitudinal_bound.push_back(point.longitudinal_bound);
150 lateral_bound.push_back(point.lateral_bound);
151 xy_points.emplace_back(path_point.x() - ref_x_, path_point.y() - ref_y_);
152 }
153 const double scale = (anchor_points_.back().path_point.s() -
154 anchor_points_.front().path_point.s()) /
155 (t_knots_.back() - t_knots_.front());
156 std::vector<double> evaluated_t;
157 for (const auto& point : anchor_points_) {
158 evaluated_t.emplace_back(point.path_point.s() / scale);
159 }
160
161 auto* spline_constraint = spline_solver_->mutable_constraint();
162
163 // all points (x, y) should not deviate anchor points by a bounding box
164 if (!spline_constraint->Add2dBoundary(evaluated_t, headings, xy_points,
165 longitudinal_bound, lateral_bound)) {
166 AERROR << "Add 2d boundary constraint failed.";
167 return false;
168 }
169
170 // the heading of the first point should be identical to the anchor point.
171
172 if (FLAGS_enable_reference_line_stitching &&
173 !spline_constraint->AddPointAngleConstraint(evaluated_t.front(),
174 headings.front())) {
175 AERROR << "Add 2d point angle constraint failed.";
176 return false;
177 }
178
179 // all spline should be connected smoothly to the second order derivative.
180 if (!spline_constraint->AddSecondDerivativeSmoothConstraint()) {
181 AERROR << "Add jointness constraint failed.";
182 return false;
183 }
184
185 return true;
186}
187
188bool QpSplineReferenceLineSmoother::AddKernel() {
189 Spline2dKernel* kernel = spline_solver_->mutable_kernel();
190
191 // add spline kernel
192 if (config_.qp_spline().second_derivative_weight() > 0.0) {
193 kernel->AddSecondOrderDerivativeMatrix(
194 config_.qp_spline().second_derivative_weight());
195 }
196 if (config_.qp_spline().third_derivative_weight() > 0.0) {
197 kernel->AddThirdOrderDerivativeMatrix(
198 config_.qp_spline().third_derivative_weight());
199 }
200
201 kernel->AddRegularization(config_.qp_spline().regularization_weight());
202 return true;
203}
204
205bool QpSplineReferenceLineSmoother::Solve() { return spline_solver_->Solve(); }
206
208 const std::vector<AnchorPoint>& anchor_points) {
209 CHECK_GE(anchor_points.size(), 2U);
210 anchor_points_ = anchor_points;
211}
212
213} // namespace planning
214} // namespace apollo
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
const std::vector< LaneWaypoint > & lane_waypoints() const
Definition path.h:121
static double ComputeCurvatureDerivative(const double dx, const double d2x, const double d3x, const double dy, const double d2y, const double d3y)
Compute the curvature change rate w.r.t.
Definition curve_math.cc:38
static double ComputeCurvature(const double dx, const double d2x, const double dy, const double d2y)
Compute the curvature (kappa) given curve X = (x(t), y(t)) which t is an arbitrary parameter.
Definition curve_math.cc:29
QpSplineReferenceLineSmoother(const ReferenceLineSmootherConfig &config)
bool Smooth(const ReferenceLine &raw_reference_line, ReferenceLine *const smoothed_reference_line) override
Smooth a given reference line
void SetAnchorPoints(const std::vector< AnchorPoint > &anchor_points) override
Smoothing constraints
ReferencePoint GetReferencePoint(const double s) const
bool XYToSL(const common::math::Vec2d &xy_point, common::SLPoint *const sl_point, double warm_start_s=-1.0) const
Transvert Cartesian coordinates to Frenet.
static void RemoveDuplicates(std::vector< ReferencePoint > *points)
Planning module main class.
#define AERROR
Definition log.h:44
Some util functions.
class register implement
Definition arena_queue.h:37
Defines the Vec2d class.