25#include "modules/common_msgs/basic_msgs/pnc_point.pb.h"
44void QpSplineReferenceLineSmoother::Clear() { t_knots_.clear(); }
50 const double kEpsilon = 1e-6;
52 AERROR <<
"Fail to sample reference line smoother points!";
56 spline_solver_->Reset(t_knots_,
config_.qp_spline().spline_order());
58 if (!AddConstraint()) {
59 AERROR <<
"Add constraint for spline smoother failed";
64 AERROR <<
"Add kernel for spline smoother failed.";
69 AERROR <<
"Solve spline smoother problem failed";
73 const double start_t = t_knots_.front();
74 const double end_t = t_knots_.back();
76 const double resolution =
79 std::vector<ReferencePoint> ref_points;
80 const auto& spline = spline_solver_->spline();
82 ++i, t += resolution) {
83 const double heading =
84 std::atan2(spline.DerivativeY(t), spline.DerivativeX(t));
86 spline.DerivativeX(t), spline.SecondDerivativeX(t),
87 spline.DerivativeY(t), spline.SecondDerivativeY(t));
89 spline.DerivativeX(t), spline.SecondDerivativeX(t),
90 spline.ThirdDerivativeX(t), spline.DerivativeY(t),
91 spline.SecondDerivativeY(t), spline.ThirdDerivativeY(t));
93 std::pair<double, double> xy = spline(t);
97 if (!raw_reference_line.
XYToSL({xy.first, xy.second}, &ref_sl_point)) {
100 if (ref_sl_point.
s() < -kEpsilon ||
101 ref_sl_point.
s() > raw_reference_line.
Length()) {
104 ref_sl_point.set_s(std::max(ref_sl_point.
s(), 0.0));
107 for (
auto& lane_waypoint : new_lane_waypoints) {
108 lane_waypoint.l = ref_sl_point.
l();
117 if (ref_points.size() < 2) {
118 AERROR <<
"Fail to generate smoothed reference line.";
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);
135 ref_x_ = anchor_points_.front().path_point.x();
136 ref_y_ = anchor_points_.front().path_point.y();
140bool QpSplineReferenceLineSmoother::AddConstraint() {
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_);
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);
161 auto* spline_constraint = spline_solver_->mutable_constraint();
164 if (!spline_constraint->Add2dBoundary(evaluated_t, headings, xy_points,
165 longitudinal_bound, lateral_bound)) {
166 AERROR <<
"Add 2d boundary constraint failed.";
172 if (FLAGS_enable_reference_line_stitching &&
173 !spline_constraint->AddPointAngleConstraint(evaluated_t.front(),
175 AERROR <<
"Add 2d point angle constraint failed.";
180 if (!spline_constraint->AddSecondDerivativeSmoothConstraint()) {
181 AERROR <<
"Add jointness constraint failed.";
188bool QpSplineReferenceLineSmoother::AddKernel() {
189 Spline2dKernel* kernel = spline_solver_->mutable_kernel();
192 if (
config_.qp_spline().second_derivative_weight() > 0.0) {
193 kernel->AddSecondOrderDerivativeMatrix(
194 config_.qp_spline().second_derivative_weight());
196 if (
config_.qp_spline().third_derivative_weight() > 0.0) {
197 kernel->AddThirdOrderDerivativeMatrix(
198 config_.qp_spline().third_derivative_weight());
201 kernel->AddRegularization(
config_.qp_spline().regularization_weight());
205bool QpSplineReferenceLineSmoother::Solve() {
return spline_solver_->Solve(); }
208 const std::vector<AnchorPoint>& anchor_points) {
209 CHECK_GE(anchor_points.size(), 2U);
210 anchor_points_ = anchor_points;
Implements a class of 2-dimensional vectors.
const std::vector< LaneWaypoint > & lane_waypoints() const
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.
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.
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
ReferenceLineSmootherConfig config_
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.
optional uint32 num_of_total_points