Apollo 11.0
自动驾驶开放平台
spline_1d_kernel.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
24
25#include <algorithm>
26
27#include "cyber/common/log.h"
29
30namespace apollo {
31namespace planning {
32
34 : Spline1dKernel(spline1d.x_knots(), spline1d.spline_order()) {}
35
36Spline1dKernel::Spline1dKernel(const std::vector<double>& x_knots,
37 const uint32_t spline_order)
38 : x_knots_(x_knots), spline_order_(spline_order) {
39 total_params_ =
40 (static_cast<uint32_t>(x_knots.size()) > 1
41 ? (static_cast<uint32_t>(x_knots.size()) - 1) * (1 + spline_order_)
42 : 0);
43 kernel_matrix_ = Eigen::MatrixXd::Zero(total_params_, total_params_);
44 offset_ = Eigen::MatrixXd::Zero(total_params_, 1);
45}
46
47void Spline1dKernel::AddRegularization(const double regularized_param) {
48 Eigen::MatrixXd id_matrix =
49 Eigen::MatrixXd::Identity(kernel_matrix_.rows(), kernel_matrix_.cols());
50 kernel_matrix_ += 2.0 * id_matrix * regularized_param;
51}
52
53bool Spline1dKernel::AddKernel(const Eigen::MatrixXd& kernel,
54 const Eigen::MatrixXd& offset,
55 const double weight) {
56 if (kernel.rows() != kernel.cols() ||
57 kernel.rows() != kernel_matrix_.rows() || offset.cols() != 1 ||
58 offset.rows() != offset_.rows()) {
59 return false;
60 }
61 kernel_matrix_ += kernel * weight;
62 offset_ += offset * weight;
63 return true;
64}
65
66bool Spline1dKernel::AddKernel(const Eigen::MatrixXd& kernel,
67 const double weight) {
68 Eigen::MatrixXd offset = Eigen::MatrixXd::Zero(kernel.rows(), 1);
69 return AddKernel(kernel, offset, weight);
70}
71
73 return &kernel_matrix_;
74}
75
76Eigen::MatrixXd* Spline1dKernel::mutable_offset() { return &offset_; }
77
78const Eigen::MatrixXd& Spline1dKernel::kernel_matrix() const {
79 return kernel_matrix_;
80}
81
82const Eigen::MatrixXd& Spline1dKernel::offset() const { return offset_; }
83
84// build-in kernel methods
85void Spline1dKernel::AddNthDerivativekernelMatrix(const uint32_t n,
86 const double weight) {
87 const uint32_t num_params = spline_order_ + 1;
88 for (uint32_t i = 0; i + 1 < x_knots_.size(); ++i) {
89 Eigen::MatrixXd cur_kernel =
90 2 *
91 SplineSegKernel::Instance()->NthDerivativeKernel(
92 n, num_params, x_knots_[i + 1] - x_knots_[i]) *
93 weight;
94 kernel_matrix_.block(i * num_params, i * num_params, num_params,
95 num_params) += cur_kernel;
96 }
97}
98
100 AddNthDerivativekernelMatrix(1, weight);
101}
102
104 AddNthDerivativekernelMatrix(2, weight);
105}
106
108 AddNthDerivativekernelMatrix(3, weight);
109}
110
111void Spline1dKernel::AddNthDerivativekernelMatrixForSplineK(
112 const uint32_t n, const uint32_t k, const double weight) {
113 if (k + 1 >= x_knots_.size()) {
114 AERROR << "Cannot add NthDerivativeKernel for spline K because k is out of "
115 "range. k = "
116 << k;
117 return;
118 }
119 const uint32_t num_params = spline_order_ + 1;
120 Eigen::MatrixXd cur_kernel =
121 2 *
122 SplineSegKernel::Instance()->NthDerivativeKernel(
123 n, num_params, x_knots_[k + 1] - x_knots_[k]) *
124 weight;
125 kernel_matrix_.block(k * num_params, k * num_params, num_params,
126 num_params) += cur_kernel;
127}
128
130 const double weight) {
131 AddNthDerivativekernelMatrixForSplineK(1, k, weight);
132}
133
135 const uint32_t k, const double weight) {
136 AddNthDerivativekernelMatrixForSplineK(2, k, weight);
137}
138
140 const uint32_t k, const double weight) {
141 AddNthDerivativekernelMatrixForSplineK(3, k, weight);
142}
143
145 const std::vector<double>& x_coord, const std::vector<double>& ref_x,
146 const double weight) {
147 if (ref_x.size() != x_coord.size()) {
148 return false;
149 }
150
151 const uint32_t num_params = spline_order_ + 1;
152 for (size_t i = 0; i < x_coord.size(); ++i) {
153 auto cur_index = FindIndex(x_coord[i]);
154 double cur_rel_x = x_coord[i] - x_knots_[cur_index];
155 // update offset
156 double offset_coef = -2.0 * ref_x[i] * weight;
157 for (size_t j = 0; j < num_params; ++j) {
158 offset_(j + cur_index * num_params, 0) += offset_coef;
159 offset_coef *= cur_rel_x;
160 }
161 // update kernel matrix
162 Eigen::MatrixXd ref_kernel(num_params, num_params);
163
164 double cur_x = 1.0;
165 std::vector<double> power_x;
166 for (uint32_t n = 0; n + 1 < 2 * num_params; ++n) {
167 power_x.emplace_back(cur_x);
168 cur_x *= cur_rel_x;
169 }
170
171 for (uint32_t r = 0; r < num_params; ++r) {
172 for (uint32_t c = 0; c < num_params; ++c) {
173 ref_kernel(r, c) = 2.0 * power_x[r + c];
174 }
175 }
176
177 kernel_matrix_.block(cur_index * num_params, cur_index * num_params,
178 num_params, num_params) += weight * ref_kernel;
179 }
180 return true;
181}
182
183uint32_t Spline1dKernel::FindIndex(const double x) const {
184 auto upper_bound = std::upper_bound(x_knots_.begin() + 1, x_knots_.end(), x);
185 return std::min(static_cast<uint32_t>(x_knots_.size() - 1),
186 static_cast<uint32_t>(upper_bound - x_knots_.begin())) -
187 1;
188}
189
190void Spline1dKernel::AddDistanceOffset(const double weight) {
191 for (uint32_t i = 1; i < x_knots_.size(); ++i) {
192 const double cur_x = x_knots_[i] - x_knots_[i - 1];
193 double pw_x = 2.0 * weight;
194 for (uint32_t j = 0; j < spline_order_ + 1; ++j) {
195 offset_((i - 1) * (spline_order_ + 1) + j, 0) -= pw_x;
196 pw_x *= cur_x;
197 }
198 }
199}
200} // namespace planning
201} // namespace apollo
Spline1dKernel(const Spline1d &spline1d)
void AddSecondOrderDerivativeMatrix(const double weight)
void AddDerivativeKernelMatrixForSplineK(const uint32_t k, const double weight)
void AddDistanceOffset(const double weight)
void AddRegularization(const double regularized_param)
const Eigen::MatrixXd & kernel_matrix() const
const Eigen::MatrixXd & offset() const
void AddThirdOrderDerivativeMatrix(const double weight)
void AddThirdOrderDerivativeMatrixForSplineK(const uint32_t k, const double weight)
Eigen::MatrixXd * mutable_kernel_matrix()
void AddDerivativeKernelMatrix(const double weight)
void AddSecondOrderDerivativeMatrixForSplineK(const uint32_t k, const double weight)
bool AddKernel(const Eigen::MatrixXd &kernel, const Eigen::MatrixXd &offset, const double weight)
bool AddReferenceLineKernelMatrix(const std::vector< double > &x_coord, const std::vector< double > &ref_fx, const double weight)
Planning module main class.
#define AERROR
Definition log.h:44
class register implement
Definition arena_queue.h:37
: wrap up solver constraint interface with direct methods and preset methods
: generating integrated kernels for smoothing spline