WPILibC++ 2024.3.2
Spline.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <utility>
8#include <vector>
9
10#include <wpi/array.h>
11
12#include "frc/EigenCore.h"
13#include "frc/geometry/Pose2d.h"
14#include "units/curvature.h"
15#include "units/length.h"
16
17namespace frc {
18/**
19 * Represents a two-dimensional parametric spline that interpolates between two
20 * points.
21 *
22 * @tparam Degree The degree of the spline.
23 */
24template <int Degree>
25class Spline {
26 public:
27 using PoseWithCurvature = std::pair<Pose2d, units::curvature_t>;
28
29 Spline() = default;
30
31 Spline(const Spline&) = default;
32 Spline& operator=(const Spline&) = default;
33
34 Spline(Spline&&) = default;
35 Spline& operator=(Spline&&) = default;
36
37 virtual ~Spline() = default;
38
39 /**
40 * Represents a control vector for a spline.
41 *
42 * Each element in each array represents the value of the derivative at the
43 * index. For example, the value of x[2] is the second derivative in the x
44 * dimension.
45 */
47 /// The x components of the control vector.
48 wpi::array<double, (Degree + 1) / 2> x;
49
50 /// The y components of the control vector.
51 wpi::array<double, (Degree + 1) / 2> y;
52 };
53
54 /**
55 * Gets the pose and curvature at some point t on the spline.
56 *
57 * @param t The point t
58 * @return The pose and curvature at that point.
59 */
60 PoseWithCurvature GetPoint(double t) const {
61 Vectord<Degree + 1> polynomialBases;
62
63 // Populate the polynomial bases
64 for (int i = 0; i <= Degree; i++) {
65 polynomialBases(i) = std::pow(t, Degree - i);
66 }
67
68 // This simply multiplies by the coefficients. We need to divide out t some
69 // n number of times where n is the derivative we want to take.
70 Vectord<6> combined = Coefficients() * polynomialBases;
71
72 double dx, dy, ddx, ddy;
73
74 // If t = 0, all other terms in the equation cancel out to zero. We can use
75 // the last x^0 term in the equation.
76 if (t == 0.0) {
77 dx = Coefficients()(2, Degree - 1);
78 dy = Coefficients()(3, Degree - 1);
79 ddx = Coefficients()(4, Degree - 2);
80 ddy = Coefficients()(5, Degree - 2);
81 } else {
82 // Divide out t for first derivative.
83 dx = combined(2) / t;
84 dy = combined(3) / t;
85
86 // Divide out t for second derivative.
87 ddx = combined(4) / t / t;
88 ddy = combined(5) / t / t;
89 }
90
91 // Find the curvature.
92 const auto curvature =
93 (dx * ddy - ddx * dy) / ((dx * dx + dy * dy) * std::hypot(dx, dy));
94
95 return {
96 {FromVector(combined.template block<2, 1>(0, 0)), Rotation2d{dx, dy}},
97 units::curvature_t{curvature}};
98 }
99
100 /**
101 * Returns the coefficients of the spline.
102 *
103 * @return The coefficients of the spline.
104 */
106
107 /**
108 * Returns the initial control vector that created this spline.
109 *
110 * @return The initial control vector that created this spline.
111 */
112 virtual const ControlVector& GetInitialControlVector() const = 0;
113
114 /**
115 * Returns the final control vector that created this spline.
116 *
117 * @return The final control vector that created this spline.
118 */
119 virtual const ControlVector& GetFinalControlVector() const = 0;
120
121 protected:
122 /**
123 * Converts a Translation2d into a vector that is compatible with Eigen.
124 *
125 * @param translation The Translation2d to convert.
126 * @return The vector.
127 */
128 static Eigen::Vector2d ToVector(const Translation2d& translation) {
129 return Eigen::Vector2d{translation.X().value(), translation.Y().value()};
130 }
131
132 /**
133 * Converts an Eigen vector into a Translation2d.
134 *
135 * @param vector The vector to convert.
136 * @return The Translation2d.
137 */
138 static Translation2d FromVector(const Eigen::Vector2d& vector) {
139 return Translation2d{units::meter_t{vector(0)}, units::meter_t{vector(1)}};
140 }
141};
142} // namespace frc
A rotation in a 2D coordinate frame represented by a point on the unit circle (cosine and sine).
Definition: Rotation2d.h:23
Represents a two-dimensional parametric spline that interpolates between two points.
Definition: Spline.h:25
virtual ~Spline()=default
virtual Matrixd< 6, Degree+1 > Coefficients() const =0
Returns the coefficients of the spline.
static Translation2d FromVector(const Eigen::Vector2d &vector)
Converts an Eigen vector into a Translation2d.
Definition: Spline.h:138
Spline()=default
PoseWithCurvature GetPoint(double t) const
Gets the pose and curvature at some point t on the spline.
Definition: Spline.h:60
Spline & operator=(const Spline &)=default
static Eigen::Vector2d ToVector(const Translation2d &translation)
Converts a Translation2d into a vector that is compatible with Eigen.
Definition: Spline.h:128
Spline(const Spline &)=default
std::pair< Pose2d, units::curvature_t > PoseWithCurvature
Definition: Spline.h:27
virtual const ControlVector & GetFinalControlVector() const =0
Returns the final control vector that created this spline.
Spline(Spline &&)=default
Spline & operator=(Spline &&)=default
virtual const ControlVector & GetInitialControlVector() const =0
Returns the initial control vector that created this spline.
Represents a translation in 2D space.
Definition: Translation2d.h:27
constexpr units::meter_t X() const
Returns the X component of the translation.
Definition: Translation2d.h:76
constexpr units::meter_t Y() const
Returns the Y component of the translation.
Definition: Translation2d.h:83
This class is a wrapper around std::array that does compile time size checking.
Definition: array.h:26
UnitTypeLhs hypot(const UnitTypeLhs &x, const UnitTypeRhs &y)
Computes the square root of the sum-of-squares of x and y.
Definition: math.h:505
Definition: AprilTagPoseEstimator.h:15
Eigen::Matrix< double, Rows, Cols, Options, MaxRows, MaxCols > Matrixd
Definition: EigenCore.h:21
Eigen::Vector< double, Size > Vectord
Definition: EigenCore.h:12
auto pow(const UnitType &value) noexcept -> unit_t< typename units::detail::power_of_unit< power, typename units::traits::unit_t_traits< UnitType >::unit_type >::type, typename units::traits::unit_t_traits< UnitType >::underlying_type, linear_scale >
computes the value of value raised to the power
Definition: base.h:2806
Represents a control vector for a spline.
Definition: Spline.h:46
wpi::array< double,(Degree+1)/2 > x
The x components of the control vector.
Definition: Spline.h:48
wpi::array< double,(Degree+1)/2 > y
The y components of the control vector.
Definition: Spline.h:51