trajectory_collection
CubicSpline.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <Eigen/Core>
4 
5 #include <TrajColl/Func.h>
6 
7 namespace TrajColl
8 {
11 {
13  Velocity = 0,
14 
17 };
18 
22 template<class T>
24 {
27 
29  T value;
30 
35  BoundaryConstraint(const BoundaryConstraintType & _type, const T & _value) : type(_type), value(_value) {}
36 };
37 
41 template<class T>
42 class CubicSpline : public PiecewiseFunc<T>
43 {
44 public:
51  CubicSpline(int dim,
52  const BoundaryConstraint<T> & bcStart,
53  const BoundaryConstraint<T> & bcEnd,
54  const std::map<double, T> & points = {})
55  : dim_(dim), bcStart_(bcStart), bcEnd_(bcEnd), points_(points)
56  {
57  }
58 
60  const std::map<double, T> & points() const noexcept
61  {
62  return points_;
63  }
64 
66  void clearPoints()
67  {
68  points_.clear();
69  }
70 
74  void appendPoint(const std::pair<double, T> & point)
75  {
76  points_.insert(point);
77  }
78 
83  void calcCoeff()
84  {
85  this->funcs_.clear();
86 
87  size_t n = points_.size();
88  if(n < 2)
89  {
90  throw std::runtime_error("[CubicSpline] Invalid points size: " + std::to_string(n));
91  }
92 
93  std::array<Eigen::MatrixXd, 4> coeffMatAll;
94  for(auto & coeffMat : coeffMatAll)
95  {
96  coeffMat.resize(dim_, n);
97  }
98 
99  // Calculate coefficients for each dimension
100  for(int dimIdx = 0; dimIdx < dim_; dimIdx++)
101  {
102  // tridiagonalSystem represents the coefficients (A and b) of linear
103  // system A x = b where A is tridiagonal matrix. In each row, first three
104  // elements are the tridiagonal elements of A and the last element is the
105  // element of b.
106  Eigen::MatrixXd tridiagonalSystem(n, 4);
107  Eigen::VectorXd y(n);
108  Eigen::VectorXd yd(n);
109  Eigen::VectorXd deltaT(n - 1);
110  Eigen::VectorXd deltaY(n - 1);
111  Eigen::VectorXd h(n - 1);
112  Eigen::VectorXd r(n - 1);
113 
114  // Set y, deltaT, deltaY, h, r
115  {
116  auto pointIt = points_.begin();
117  for(size_t k = 0; k < n; k++, pointIt++)
118  {
119  y(k) = pointIt->second(dimIdx);
120  if(k != n - 1)
121  {
122  deltaT(k) = std::next(pointIt)->first - pointIt->first;
123  deltaY(k) = std::next(pointIt)->second(dimIdx) - pointIt->second(dimIdx);
124  h(k) = deltaT(k);
125  r(k) = deltaY(k) / deltaT(k);
126  }
127  }
128  }
129 
130  // Set tridiagonalSystem
131  for(size_t k = 0; k < n - 2; k++)
132  {
133  // First and last rows are set later
134  tridiagonalSystem.row(k + 1) << h(k + 1), 2 * (h(k) + h(k + 1)), h(k), 3 * (r(k) * h(k + 1) + r(k + 1) * h(k));
135  }
136 
137  // Set tridiagonalSystem of boundary
139  {
140  tridiagonalSystem.row(0) << 0, 1, 0, bcStart_.value(dimIdx);
141  }
143  {
144  tridiagonalSystem.row(0) << 0, 1, 0.5,
145  (3 * deltaY(0)) / (2 * deltaT(0)) - bcStart_.value(dimIdx) / (4 * deltaT(0));
146  }
147  else
148  {
149  throw std::runtime_error("[CubicSpline] Unsupported type of boundary constraint: "
150  + std::to_string(static_cast<int>(bcStart_.type)));
151  }
153  {
154  tridiagonalSystem.row(n - 1) << 0, 1, 0, bcEnd_.value(dimIdx);
155  }
157  {
158  tridiagonalSystem.row(n - 1) << 2, 4, 0,
159  (6 * deltaY(n - 2)) / deltaT(n - 2) + bcEnd_.value(dimIdx) * deltaT(n - 2);
160  }
161  else
162  {
163  throw std::runtime_error("[CubicSpline] Unsupported type of boundary constraint: "
164  + std::to_string(static_cast<int>(bcEnd_.type)));
165  }
166 
167  // Calculate yd by solving tridiagonalSystem
168  // See https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm#Method
169  for(size_t i = 1; i < n; i++)
170  {
171  double w = tridiagonalSystem(i, 0) / tridiagonalSystem(i - 1, 1);
172  tridiagonalSystem(i, 1) -= w * tridiagonalSystem(i - 1, 2);
173  tridiagonalSystem(i, 3) -= w * tridiagonalSystem(i - 1, 3);
174  }
175  yd(n - 1) = tridiagonalSystem(n - 1, 3) / tridiagonalSystem(n - 1, 1);
176  for(int i = static_cast<int>(n - 2); i >= 0; i--)
177  {
178  yd(i) = (tridiagonalSystem(i, 3) - tridiagonalSystem(i, 2) * yd(i + 1)) / tridiagonalSystem(i, 1);
179  }
180 
181  // Set coeffMatAll
182  for(size_t k = 0; k < n - 1; k++)
183  {
184  coeffMatAll[0](dimIdx, k) = y(k);
185  coeffMatAll[1](dimIdx, k) = yd(k);
186  coeffMatAll[2](dimIdx, k) = (3 * deltaY(k) / deltaT(k) - 2 * yd(k) - yd(k + 1)) / deltaT(k);
187  coeffMatAll[3](dimIdx, k) = (-2 * deltaY(k) / deltaT(k) + yd(k) + yd(k + 1)) / (deltaT(k) * deltaT(k));
188  }
189  }
190 
191  // Set piecewise CubicPolynomial
192  {
193  auto pointIt = points_.begin();
194  for(size_t k = 0; k < n - 1; k++, pointIt++)
195  {
196  double t0 = pointIt->first;
197  std::array<T, 4> coeff;
198  for(size_t i = 0; i < coeffMatAll.size(); i++)
199  {
200  coeff[i] = coeffMatAll[i].col(k);
201  }
202  std::shared_ptr<CubicPolynomial<T>> cubicFunc = std::make_shared<CubicPolynomial<T>>(coeff, t0);
203  this->funcs_.emplace(std::next(pointIt)->first, cubicFunc);
204  }
205  }
206 
207  // Set tLowerLimit_
208  this->tLowerLimit_ = points_.begin()->first;
209  }
210 
211 protected:
213  int dim_;
214 
217 
220 
222  std::map<double, T> points_;
223 };
224 } // namespace TrajColl
TrajColl::BoundaryConstraint
Boundary constraint.
Definition: CubicSpline.h:23
TrajColl::CubicSpline::CubicSpline
CubicSpline(int dim, const BoundaryConstraint< T > &bcStart, const BoundaryConstraint< T > &bcEnd, const std::map< double, T > &points={})
Constructor.
Definition: CubicSpline.h:51
TrajColl::CubicSpline::appendPoint
void appendPoint(const std::pair< double, T > &point)
Add point.
Definition: CubicSpline.h:74
TrajColl::BoundaryConstraint::type
BoundaryConstraintType type
Type of boundary constraint.
Definition: CubicSpline.h:26
TrajColl::CubicSpline::bcEnd_
BoundaryConstraint< T > bcEnd_
Boundary constraint of end point.
Definition: CubicSpline.h:219
Func.h
TrajColl::CubicSpline::points
const std::map< double, T > & points() const noexcept
Access points.
Definition: CubicSpline.h:60
TrajColl::CubicSpline
Cubic spline.
Definition: CubicSpline.h:42
TrajColl::PiecewiseFunc
Piecewise function.
Definition: Func.h:51
TrajColl::BoundaryConstraintType
BoundaryConstraintType
Type of boundary constraint.
Definition: CubicSpline.h:10
TrajColl
Definition: BangBangInterpolator.h:7
TrajColl::BoundaryConstraint::value
T value
Value of boundary constraint.
Definition: CubicSpline.h:29
TrajColl::PiecewiseFunc::tLowerLimit_
double tLowerLimit_
Lower limit of domain of this function.
Definition: Func.h:146
TrajColl::BoundaryConstraint::BoundaryConstraint
BoundaryConstraint(const BoundaryConstraintType &_type, const T &_value)
Constructor.
Definition: CubicSpline.h:35
TrajColl::CubicSpline::points_
std::map< double, T > points_
Way points.
Definition: CubicSpline.h:222
TrajColl::BoundaryConstraintType::Velocity
@ Velocity
Velocity constraint.
TrajColl::CubicSpline::calcCoeff
void calcCoeff()
Calculate coefficients.
Definition: CubicSpline.h:83
TrajColl::CubicSpline::bcStart_
BoundaryConstraint< T > bcStart_
Boundary constraint of start point.
Definition: CubicSpline.h:216
TrajColl::CubicSpline::clearPoints
void clearPoints()
Clear points.
Definition: CubicSpline.h:66
TrajColl::BoundaryConstraintType::Acceleration
@ Acceleration
Acceleration constraint.
TrajColl::CubicSpline::dim_
int dim_
Dimension of value.
Definition: CubicSpline.h:213
TrajColl::PiecewiseFunc::funcs_
std::map< double, std::shared_ptr< Func< T > > > funcs_
Map of upper bound of domain and function.
Definition: Func.h:143