Apollo 11.0
自动驾驶开放平台
spline_seg_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
23
24#include <vector>
25
26namespace apollo {
27namespace planning {
28
29SplineSegKernel::SplineSegKernel() {
30 const int reserved_num_params = reserved_order_ + 1;
31 CalculateFx(reserved_num_params);
32 CalculateDerivative(reserved_num_params);
33 CalculateSecondOrderDerivative(reserved_num_params);
34 CalculateThirdOrderDerivative(reserved_num_params);
35}
36
37Eigen::MatrixXd SplineSegKernel::Kernel(const uint32_t num_params,
38 const double accumulated_x) {
39 if (num_params > reserved_order_ + 1) {
40 CalculateFx(num_params);
41 }
42 Eigen::MatrixXd term_matrix;
43 IntegratedTermMatrix(num_params, accumulated_x, "fx", &term_matrix);
44 return kernel_fx_.block(0, 0, num_params, num_params)
45 .cwiseProduct(term_matrix);
46}
47
49 const uint32_t n, const uint32_t num_params, const double accumulated_x) {
50 if (n == 1) {
51 return DerivativeKernel(num_params, accumulated_x);
52 } else if (n == 2) {
53 return SecondOrderDerivativeKernel(num_params, accumulated_x);
54 } else if (n == 3) {
55 return ThirdOrderDerivativeKernel(num_params, accumulated_x);
56 } else {
57 return Eigen::MatrixXd::Zero(num_params, num_params);
58 }
59}
60
61Eigen::MatrixXd SplineSegKernel::DerivativeKernel(const uint32_t num_params,
62 const double accumulated_x) {
63 if (num_params > reserved_order_ + 1) {
64 CalculateDerivative(num_params);
65 }
66 Eigen::MatrixXd term_matrix;
67 IntegratedTermMatrix(num_params, accumulated_x, "derivative", &term_matrix);
68 return kernel_derivative_.block(0, 0, num_params, num_params)
69 .cwiseProduct(term_matrix);
70}
71
72Eigen::MatrixXd SplineSegKernel::SecondOrderDerivativeKernel(
73 const uint32_t num_params, const double accumulated_x) {
74 if (num_params > reserved_order_ + 1) {
75 CalculateSecondOrderDerivative(num_params);
76 }
77 Eigen::MatrixXd term_matrix;
78 IntegratedTermMatrix(num_params, accumulated_x, "second_order", &term_matrix);
79 return kernel_second_order_derivative_.block(0, 0, num_params, num_params)
80 .cwiseProduct(term_matrix);
81}
82
83Eigen::MatrixXd SplineSegKernel::ThirdOrderDerivativeKernel(
84 const uint32_t num_params, const double accumulated_x) {
85 if (num_params > reserved_order_ + 1) {
86 CalculateThirdOrderDerivative(num_params);
87 }
88 Eigen::MatrixXd term_matrix;
89 IntegratedTermMatrix(num_params, accumulated_x, "third_order", &term_matrix);
90 return (kernel_third_order_derivative_.block(0, 0, num_params, num_params))
91 .cwiseProduct(term_matrix);
92}
93
94void SplineSegKernel::IntegratedTermMatrix(const uint32_t num_params,
95 const double x,
96 const std::string& type,
97 Eigen::MatrixXd* term_matrix) const {
98 if (term_matrix->rows() != term_matrix->cols() ||
99 term_matrix->rows() != static_cast<int>(num_params)) {
100 term_matrix->resize(num_params, num_params);
101 }
102
103 std::vector<double> x_pow(2 * num_params + 1, 1.0);
104 for (uint32_t i = 1; i < 2 * num_params + 1; ++i) {
105 x_pow[i] = x_pow[i - 1] * x;
106 }
107
108 if (type == "fx") {
109 for (uint32_t r = 0; r < num_params; ++r) {
110 for (uint32_t c = 0; c < num_params; ++c) {
111 (*term_matrix)(r, c) = x_pow[r + c + 1];
112 }
113 }
114
115 } else if (type == "derivative") {
116 for (uint32_t r = 1; r < num_params; ++r) {
117 for (uint32_t c = 1; c < num_params; ++c) {
118 (*term_matrix)(r, c) = x_pow[r + c - 1];
119 }
120 }
121 (*term_matrix).block(0, 0, num_params, 1) =
122 Eigen::MatrixXd::Zero(num_params, 1);
123 (*term_matrix).block(0, 0, 1, num_params) =
124 Eigen::MatrixXd::Zero(1, num_params);
125
126 } else if (type == "second_order") {
127 for (uint32_t r = 2; r < num_params; ++r) {
128 for (uint32_t c = 2; c < num_params; ++c) {
129 (*term_matrix)(r, c) = x_pow[r + c - 3];
130 }
131 }
132 (*term_matrix).block(0, 0, num_params, 2) =
133 Eigen::MatrixXd::Zero(num_params, 2);
134 (*term_matrix).block(0, 0, 2, num_params) =
135 Eigen::MatrixXd::Zero(2, num_params);
136
137 } else {
138 for (uint32_t r = 3; r < num_params; ++r) {
139 for (uint32_t c = 3; c < num_params; ++c) {
140 (*term_matrix)(r, c) = x_pow[r + c - 5];
141 }
142 }
143 (*term_matrix).block(0, 0, num_params, 3) =
144 Eigen::MatrixXd::Zero(num_params, 3);
145 (*term_matrix).block(0, 0, 3, num_params) =
146 Eigen::MatrixXd::Zero(3, num_params);
147 }
148}
149
150void SplineSegKernel::CalculateFx(const uint32_t num_params) {
151 kernel_fx_ = Eigen::MatrixXd::Zero(num_params, num_params);
152 for (int r = 0; r < kernel_fx_.rows(); ++r) {
153 for (int c = 0; c < kernel_fx_.cols(); ++c) {
154 kernel_fx_(r, c) = 1.0 / (r + c + 1.0);
155 }
156 }
157}
158
159void SplineSegKernel::CalculateDerivative(const uint32_t num_params) {
160 kernel_derivative_ = Eigen::MatrixXd::Zero(num_params, num_params);
161 for (int r = 1; r < kernel_derivative_.rows(); ++r) {
162 for (int c = 1; c < kernel_derivative_.cols(); ++c) {
163 kernel_derivative_(r, c) = r * c / (r + c - 1.0);
164 }
165 }
166}
167
168void SplineSegKernel::CalculateSecondOrderDerivative(
169 const uint32_t num_params) {
170 kernel_second_order_derivative_ =
171 Eigen::MatrixXd::Zero(num_params, num_params);
172 for (int r = 2; r < kernel_second_order_derivative_.rows(); ++r) {
173 for (int c = 2; c < kernel_second_order_derivative_.cols(); ++c) {
174 kernel_second_order_derivative_(r, c) =
175 (r * r - r) * (c * c - c) / (r + c - 3.0);
176 }
177 }
178}
179
180void SplineSegKernel::CalculateThirdOrderDerivative(const uint32_t num_params) {
181 kernel_third_order_derivative_ =
182 Eigen::MatrixXd::Zero(num_params, num_params);
183 for (int r = 3; r < kernel_third_order_derivative_.rows(); ++r) {
184 for (int c = 3; c < kernel_third_order_derivative_.cols(); ++c) {
185 kernel_third_order_derivative_(r, c) =
186 (r * r - r) * (r - 2) * (c * c - c) * (c - 2) / (r + c - 5.0);
187 }
188 }
189}
190
191} // namespace planning
192} // namespace apollo
Eigen::MatrixXd NthDerivativeKernel(const uint32_t n, const uint32_t num_params, const double accumulated_x)
Eigen::MatrixXd Kernel(const uint32_t num_params, const double accumulated_x)
Planning module main class.
class register implement
Definition arena_queue.h:37
: generating integrated kernels for smoothing spline