TrajoptLib
Library for generating time-optimal trajectories for FRC robots.
Loading...
Searching...
No Matches
cubic_hermite_spline.hpp
1// Copyright (c) TrajoptLib contributors
2
3#pragma once
4
5#include <array>
6
7#include <Eigen/Core>
8
9#include "trajopt/spline/spline.hpp"
10#include "trajopt/util/symbol_exports.hpp"
11
12namespace trajopt {
13
15class TRAJOPT_DLLEXPORT CubicHermiteSpline : public Spline<3> {
16 public:
29 CubicHermiteSpline(std::array<double, 2> x_initial_control_vector,
30 std::array<double, 2> x_final_control_vector,
31 std::array<double, 2> y_initial_control_vector,
32 std::array<double, 2> y_final_control_vector)
33 : m_initial_control_vector{x_initial_control_vector,
34 y_initial_control_vector},
35 m_final_control_vector{x_final_control_vector, y_final_control_vector} {
36 // Calculate the basis matrix for cubic Hermite spline interpolation.
37 //
38 // Given P(i), P'(i), P(i+1), P'(i+1), the control vectors, we want to find
39 // the coefficients of the spline P(t) = a₃t³ + a₂t² + a₁t + a₀.
40 //
41 // P(i) = P(0) = a₀
42 // P'(i) = P'(0) = a₁
43 // P(i+1) = P(1) = a₃ + a₂ + a₁ + a₀
44 // P'(i+1) = P'(1) = 3a₃ + 2a₂ + a₁
45 //
46 // [P(i) ] = [0 0 0 1][a₃]
47 // [P'(i) ] = [0 0 1 0][a₂]
48 // [P(i+1) ] = [1 1 1 1][a₁]
49 // [P'(i+1)] = [3 2 1 0][a₀]
50 //
51 // To solve for the coefficients, we can invert the 4x4 matrix and move it
52 // to the other side of the equation.
53 //
54 // [a₃] = [ 2 1 -2 1][P(i) ]
55 // [a₂] = [-3 -2 3 -1][P'(i) ]
56 // [a₁] = [ 0 1 0 0][P(i+1) ]
57 // [a₀] = [ 1 0 0 0][P'(i+1)]
58 constexpr Eigen::Matrix4d basis{{+2.0, +1.0, -2.0, +1.0},
59 {-3.0, -2.0, +3.0, -1.0},
60 {+0.0, +1.0, +0.0, +0.0},
61 {+1.0, +0.0, +0.0, +0.0}};
62
63 Eigen::Vector4d x{m_initial_control_vector.x[0],
64 m_initial_control_vector.x[1],
65 m_final_control_vector.x[0], m_final_control_vector.x[1]};
66 Eigen::Vector4d y{m_initial_control_vector.y[0],
67 m_initial_control_vector.y[1],
68 m_final_control_vector.y[0], m_final_control_vector.y[1]};
69
70 // Populate rows 0 and 1 with coefficients
71 m_coefficients.template block<1, 4>(0, 0) = basis * x;
72 m_coefficients.template block<1, 4>(1, 0) = basis * y;
73
74 // Populate rows 2 and 3 with the derivatives of the equations above
75 for (int i = 0; i < 4; i++) {
76 // Here, we are multiplying by (3 - i) to manually take the derivative.
77 // The power of the term in index 0 is 3, index 1 is 2 and so on. To find
78 // the coefficient of the derivative, we can use the power rule and
79 // multiply the existing coefficient by its power.
80 m_coefficients.template block<2, 1>(2, i) =
81 m_coefficients.template block<2, 1>(0, i) * (3 - i);
82 }
83
84 // Populate rows 4 and 5 with the second derivatives
85 for (int i = 0; i < 3; i++) {
86 // Here, we are multiplying by (2 - i) to manually take the derivative.
87 // The power of the term in index 0 is 2, index 1 is 1 and so on. To find
88 // the coefficient of the derivative, we can use the power rule and
89 // multiply the existing coefficient by its power.
90 m_coefficients.template block<2, 1>(4, i) =
91 m_coefficients.template block<2, 1>(2, i) * (2 - i);
92 }
93 }
94
98 const Eigen::Matrix<double, 6, 3 + 1>& coefficients() const override {
99 return m_coefficients;
100 }
101
105 const ControlVector& get_initial_control_vector() const override {
106 return m_initial_control_vector;
107 }
108
112 const ControlVector& get_final_control_vector() const override {
113 return m_final_control_vector;
114 }
115
116 private:
117 Eigen::Matrix<double, 6, 4> m_coefficients;
118
119 ControlVector m_initial_control_vector;
120 ControlVector m_final_control_vector;
121};
122
123} // namespace trajopt
CubicHermiteSpline(std::array< double, 2 > x_initial_control_vector, std::array< double, 2 > x_final_control_vector, std::array< double, 2 > y_initial_control_vector, std::array< double, 2 > y_final_control_vector)
Definition cubic_hermite_spline.hpp:29
const Eigen::Matrix< double, 6, 3+1 > & coefficients() const override
Definition cubic_hermite_spline.hpp:98
const ControlVector & get_initial_control_vector() const override
Definition cubic_hermite_spline.hpp:105
const ControlVector & get_final_control_vector() const override
Definition cubic_hermite_spline.hpp:112
Definition spline.hpp:23