Apollo 10.0
自动驾驶开放平台
curve_fitting.h
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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#pragma once
22
23#include <array>
24
25#include "Eigen/Dense"
26
28
29namespace apollo {
30namespace common {
31namespace math {
32
33// The coef is in ascending order,
34// i.e., f(x) = coef[0] + coef[1] * x + coef[2] * x^2 ...
35template <std::size_t N>
36double EvaluatePolynomial(const std::array<double, N + 1>& coef,
37 const double p) {
38 double r = 0.0;
39 for (int i = N; i >= 0; --i) {
40 r = r * p + coef[i];
41 }
42 return r;
43}
44
45// Fit a Nth order polynomial using M 2d points.
46template <std::size_t N, std::size_t M>
47std::array<double, N + 1> FitPolynomial(
48 const std::array<Eigen::Vector2d, M>& points,
49 double* ptr_error_square = nullptr) {
50 Eigen::Matrix<double, M, N + 1> X;
51 Eigen::Matrix<double, M, 1> Y;
52 for (std::size_t i = 0; i < M; ++i) {
53 double x = points[i].x();
54 double y = points[i].y();
55
56 X(i, 0) = 1.0;
57 for (std::size_t j = 1; j < N + 1; ++j) {
58 X(i, j) = X(i, j - 1) * x;
59 }
60
61 Y(i, 0) = y;
62 }
63
64 Eigen::Matrix<double, N + 1, 1> t =
65 PseudoInverse<double, N + 1, N + 1>(X.transpose() * X) * X.transpose() *
66 Y;
67
68 std::array<double, N + 1> coefs;
69 for (std::size_t i = 0; i < N + 1; ++i) {
70 coefs[i] = t(i, 0);
71 }
72
73 if (ptr_error_square != nullptr) {
74 *ptr_error_square = 0.0;
75 for (const Eigen::Vector2d& point : points) {
76 double error = EvaluatePolynomial(coefs, point.x()) - point.y();
77 *ptr_error_square += error * error;
78 }
79 }
80 return coefs;
81}
82
83} // namespace math
84} // namespace common
85} // namespace apollo
Defines some useful matrix operations.
std::array< double, N+1 > FitPolynomial(const std::array< Eigen::Vector2d, M > &points, double *ptr_error_square=nullptr)
double EvaluatePolynomial(const std::array< double, N+1 > &coef, const double p)
class register implement
Definition arena_queue.h:37