Apollo 11.0
自动驾驶开放平台
spline_2d_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
22
23#include <algorithm>
24
26
27namespace apollo {
28namespace planning {
29
31
32Spline2dKernel::Spline2dKernel(const std::vector<double>& t_knots,
33 const uint32_t spline_order)
34 : t_knots_(t_knots), spline_order_(spline_order) {
35 total_params_ =
36 (t_knots_.size() > 1 ? 2 * (t_knots_.size() - 1) * (1 + spline_order_)
37 : 0);
38 kernel_matrix_ = Eigen::MatrixXd::Zero(total_params_, total_params_);
39 offset_ = Eigen::MatrixXd::Zero(total_params_, 1);
40}
41
42// customized input output
43void Spline2dKernel::AddRegularization(const double regularization_param) {
44 Eigen::MatrixXd id_matrix =
45 Eigen::MatrixXd::Identity(kernel_matrix_.rows(), kernel_matrix_.cols());
46 kernel_matrix_ += id_matrix * regularization_param;
47}
48
49bool Spline2dKernel::AddKernel(const Eigen::MatrixXd& kernel,
50 const Eigen::MatrixXd& offset,
51 const double weight) {
52 if (kernel.rows() != kernel.cols() ||
53 kernel.rows() != kernel_matrix_.rows() || offset.cols() != 1 ||
54 offset.rows() != offset_.rows()) {
55 return false;
56 }
57 kernel_matrix_ += kernel * weight;
58 offset_ += offset * weight;
59 return true;
60}
61
62bool Spline2dKernel::AddKernel(const Eigen::MatrixXd& kernel,
63 const double weight) {
64 Eigen::MatrixXd offset = Eigen::MatrixXd::Zero(kernel.rows(), 1);
65 return AddKernel(kernel, offset, weight);
66}
67
69 return &kernel_matrix_;
70}
71
72Eigen::MatrixXd* Spline2dKernel::mutable_offset() { return &offset_; }
73
74Eigen::MatrixXd Spline2dKernel::kernel_matrix() const {
75 return kernel_matrix_ * 2.0;
76}
77
78const Eigen::MatrixXd Spline2dKernel::offset() const { return offset_; }
79
80// build-in kernel methods
81
82void Spline2dKernel::AddNthDerivativeKernelMatrix(const uint32_t n,
83 const double weight) {
84 for (uint32_t i = 0; i + 1 < t_knots_.size(); ++i) {
85 const uint32_t num_params = spline_order_ + 1;
86 Eigen::MatrixXd cur_kernel =
87 SplineSegKernel::Instance()->NthDerivativeKernel(
88 n, num_params, t_knots_[i + 1] - t_knots_[i]) *
89 weight;
90 kernel_matrix_.block(2 * i * num_params, 2 * i * num_params, num_params,
91 num_params) += cur_kernel;
92 kernel_matrix_.block((2 * i + 1) * num_params, (2 * i + 1) * num_params,
93 num_params, num_params) += cur_kernel;
94 }
95}
96
98 AddNthDerivativeKernelMatrix(1, weight);
99}
100
102 AddNthDerivativeKernelMatrix(2, weight);
103}
104
106 AddNthDerivativeKernelMatrix(3, weight);
107}
108
109// reference line kernel, t_coord in strictly increasing order (for path
110// optimizer)
112 const std::vector<double>& t_coord, const std::vector<Vec2d>& ref_points,
113 const double weight) {
114 if (ref_points.size() != t_coord.size()) {
115 return false;
116 }
117
118 for (uint32_t i = 0; i < t_coord.size(); ++i) {
119 auto cur_index = find_index(t_coord[i]);
120 double cur_rel_t = t_coord[i] - t_knots_[cur_index];
121 // update offset
122 double offset_coef_x = -ref_points[i].x() * weight;
123 double offset_coef_y = -ref_points[i].y() * weight;
124 const uint32_t num_params = spline_order_ + 1;
125 for (uint32_t j = 0; j < num_params; ++j) {
126 offset_(j + (2 * cur_index) * num_params, 0) = offset_coef_x;
127 offset_(j + (2 * cur_index + 1) * num_params, 0) = offset_coef_y;
128 offset_coef_x *= cur_rel_t;
129 offset_coef_y *= cur_rel_t;
130 }
131
132 // update kernel matrix
133 Eigen::MatrixXd ref_kernel(num_params, num_params);
134
135 double cur_t = 1.0;
136 std::vector<double> power_t;
137 for (uint32_t n = 0; n + 1 < 2 * num_params; ++n) {
138 power_t.emplace_back(cur_t);
139 cur_t *= cur_rel_t;
140 }
141
142 for (uint32_t r = 0; r < num_params; ++r) {
143 for (uint32_t c = 0; c < num_params; ++c) {
144 ref_kernel(r, c) = power_t[r + c];
145 }
146 }
147 kernel_matrix_.block((2 * cur_index) * num_params,
148 (2 * cur_index) * num_params, num_params,
149 num_params) += weight * ref_kernel;
150 kernel_matrix_.block((2 * cur_index + 1) * num_params,
151 (2 * cur_index + 1) * num_params, num_params,
152 num_params) += weight * ref_kernel;
153 }
154 return true;
155}
156
157uint32_t Spline2dKernel::find_index(const double t) const {
158 auto upper_bound = std::upper_bound(t_knots_.begin() + 1, t_knots_.end(), t);
159 return std::min(static_cast<uint32_t>(t_knots_.size() - 1),
160 static_cast<uint32_t>(upper_bound - t_knots_.begin())) -
161 1;
162}
163
164} // namespace planning
165} // namespace apollo
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
Spline2dKernel(const std::vector< double > &t_knots, const uint32_t spline_order)
Eigen::MatrixXd kernel_matrix() const
bool AddReferenceLineKernelMatrix(const std::vector< double > &t_coord, const std::vector< common::math::Vec2d > &ref_points, const double weight)
Eigen::MatrixXd * mutable_kernel_matrix()
bool AddKernel(const Eigen::MatrixXd &kernel, const Eigen::MatrixXd &offset, const double weight)
void AddRegularization(const double regularization_param)
void AddDerivativeKernelMatrix(const double weight)
void AddSecondOrderDerivativeMatrix(const double weight)
void AddThirdOrderDerivativeMatrix(const double weight)
const Eigen::MatrixXd offset() const
Planning module main class.
class register implement
Definition arena_queue.h:37
: generating integrated kernels for smoothing spline