Apollo  6.0
Open source self driving car software
curve_fitting.h
Go to the documentation of this file.
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 
29 namespace apollo {
30 namespace common {
31 namespace math {
32 
33 // The coef is in ascending order,
34 // i.e., f(x) = coef[0] + coef[1] * x + coef[2] * x^2 ...
35 template <std::size_t N>
36 double 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.
46 template <std::size_t N, std::size_t M>
47 std::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
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
Eigen::Vector2d Vector2d
Definition: base_map_fwd.h:36
double EvaluatePolynomial(const std::array< double, N+1 > &coef, const double p)
Definition: curve_fitting.h:36
Defines some useful matrix operations.
std::array< double, N+1 > FitPolynomial(const std::array< Eigen::Vector2d, M > &points, double *ptr_error_square=nullptr)
Definition: curve_fitting.h:47