trajectory_collection
BangBangInterpolator.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include <TrajColl/Func.h>
6 
7 namespace TrajColl
8 {
15 template<class T, class U = T>
16 class BangBangInterpolator : public Interpolator<T, U>
17 {
18 public:
23  BangBangInterpolator(const std::map<double, T> & points = {}, const std::vector<double> & accelDurationList = {})
24  : Interpolator<T, U>(points), accelDurationList_(accelDurationList)
25  {
26  func_ = std::make_shared<PiecewiseFunc<double>>();
27 
28  if(accelDurationList_.size() > 0 && (this->points_.size() != accelDurationList_.size() + 1))
29  {
30  throw std::invalid_argument(
31  "[BangBangInterpolator] The size of the accelDurationList must be one less than the size of the points: "
32  + std::to_string(accelDurationList_.size()) + " != " + std::to_string(this->points_.size()) + " + 1");
33  }
34 
35  if(this->points_.size() >= 2)
36  {
37  calcCoeff();
38  }
39  }
40 
43  {
45  func_ = std::make_shared<PiecewiseFunc<double>>(*inst.func_);
46  }
47 
49  virtual std::shared_ptr<Interpolator<T, U>> clone() const override
50  {
51  return std::shared_ptr<Interpolator<T, U>>(new BangBangInterpolator(*this));
52  }
53 
55  virtual void clearPoints() override
56  {
58  accelDurationList_.clear();
59  }
60 
66  virtual void appendPoint(const std::pair<double, T> & point) override
67  {
68  appendPoint(point, 0.0);
69  }
70 
77  void appendPoint(const std::pair<double, T> & point, double accelDuration)
78  {
79  if(!this->points_.empty() && point.first <= this->points_.rbegin()->first)
80  {
81  throw std::invalid_argument("[BangBangInterpolator] Only adding a trailing point is allowed: "
82  + std::to_string(point.first)
83  + " <= " + std::to_string(this->points_.rbegin()->first));
84  }
85 
86  this->points_.insert(point);
87 
88  // Set accelDurationList_
89  if(this->points_.size() >= 2)
90  {
91  double interpDuration = this->points_.rbegin()->first - std::next(this->points_.rbegin())->first;
92 
93  if(accelDuration <= 0.0)
94  {
95  constexpr double accelDurationRatio = 0.2;
96  accelDuration = accelDurationRatio * interpDuration;
97  }
98 
99  if(accelDuration >= 0.5 * interpDuration)
100  {
101  std::cerr << "[BangBangInterpolator] Overwrite accelDuration because accelDuration must be less than half of "
102  "interpDuration: "
103  << std::to_string(accelDuration) << " >= " << std::to_string(0.5 * interpDuration) << std::endl;
104  constexpr double eps = 1e-10;
105  accelDuration = 0.5 * interpDuration - eps;
106  }
107 
108  accelDurationList_.push_back(accelDuration);
109  }
110  }
111 
113  virtual void calcCoeff() override
114  {
115  if(this->points_.size() < 2)
116  {
117  throw std::out_of_range("[BangBangInterpolator] Number of points should be 2 or more: "
118  + std::to_string(this->points_.size()));
119  }
120 
121  func_->clearFuncs();
122 
123  auto pointIt = this->points_.begin();
124  for(int i = 0; i < static_cast<int>(this->points_.size()) - 1; i++, pointIt++)
125  {
126  double segStartTime = pointIt->first;
127  double segEndTime = std::next(pointIt)->first;
128  double segAccelDuration = accelDurationList_[i];
129  double segVel = 1.0 / (segEndTime - segStartTime - segAccelDuration);
130  double segAccel = segVel / segAccelDuration;
131 
132  // Set segFunc
133  std::shared_ptr<PiecewiseFunc<double>> segFunc = std::make_shared<PiecewiseFunc<double>>();
134  segFunc->setDomainLowerLimit(segStartTime);
135  segFunc->appendFunc(segStartTime + segAccelDuration,
136  std::make_shared<QuadraticPolynomial<double>>(
137  std::array<double, 3>{static_cast<double>(i), 0.0, 0.5 * segAccel}, segStartTime));
138  segFunc->appendFunc(
139  segEndTime - segAccelDuration,
140  std::make_shared<LinearPolynomial<double>>(std::array<double, 2>{static_cast<double>(i) + 0.5, segVel},
141  0.5 * (segStartTime + segEndTime)));
142  segFunc->appendFunc(segEndTime,
143  std::make_shared<QuadraticPolynomial<double>>(
144  std::array<double, 3>{static_cast<double>(i + 1), 0.0, -0.5 * segAccel}, segEndTime));
145 
146  func_->appendFunc(segEndTime, segFunc);
147  }
148 
149  func_->setDomainLowerLimit(this->points_.begin()->first);
150  }
151 
155  virtual T operator()(double t) const override
156  {
157  size_t idx = func_->index(t);
158  double ratio = (*func_)(t) - static_cast<double>(idx);
159  return interpolate<T>(std::next(this->points_.begin(), idx)->second,
160  std::next(this->points_.begin(), idx + 1)->second, std::clamp(ratio, 0.0, 1.0));
161  }
162 
169  virtual U derivative(double t, int order = 1) const override
170  {
171  size_t idx = func_->index(t);
172  double ratio = (*func_)(t) - static_cast<double>(idx);
173  return func_->derivative(t, order)
174  * interpolateDerivative<T, U>(std::next(this->points_.begin(), idx)->second,
175  std::next(this->points_.begin(), idx + 1)->second, std::clamp(ratio, 0.0, 1.0),
176  1);
177  }
178 
179 protected:
181  std::vector<double> accelDurationList_;
182 
184  std::shared_ptr<PiecewiseFunc<double>> func_;
185 };
186 } // namespace TrajColl
TrajColl::BangBangInterpolator
Interpolator with bang-bang control.
Definition: BangBangInterpolator.h:16
TrajColl::BangBangInterpolator::accelDurationList_
std::vector< double > accelDurationList_
List of acceleration/deceleration duration.
Definition: BangBangInterpolator.h:181
ElementInterpolation.h
TrajColl::BangBangInterpolator::operator()
virtual T operator()(double t) const override
Calculate interpolated value.
Definition: BangBangInterpolator.h:155
TrajColl::BangBangInterpolator::func_
std::shared_ptr< PiecewiseFunc< double > > func_
Function to calculate the ratio of interpolation points.
Definition: BangBangInterpolator.h:184
Func.h
TrajColl::BangBangInterpolator::appendPoint
virtual void appendPoint(const std::pair< double, T > &point) override
Add point.
Definition: BangBangInterpolator.h:66
Interpolator.h
TrajColl::BangBangInterpolator::calcCoeff
virtual void calcCoeff() override
Calculate coefficients.
Definition: BangBangInterpolator.h:113
TrajColl::BangBangInterpolator::appendPoint
void appendPoint(const std::pair< double, T > &point, double accelDuration)
Add point.
Definition: BangBangInterpolator.h:77
TrajColl::BangBangInterpolator::derivative
virtual U derivative(double t, int order=1) const override
Calculate the derivative of interpolated value.
Definition: BangBangInterpolator.h:169
TrajColl::Interpolator::clearPoints
virtual void clearPoints()
Clear points.
Definition: Interpolator.h:33
TrajColl::Interpolator< T, T >::points_
std::map< double, T > points_
Times and values to be interpolated.
Definition: Interpolator.h:81
TrajColl
Definition: BangBangInterpolator.h:7
TrajColl::BangBangInterpolator::BangBangInterpolator
BangBangInterpolator(const std::map< double, T > &points={}, const std::vector< double > &accelDurationList={})
Constructor.
Definition: BangBangInterpolator.h:23
TrajColl::BangBangInterpolator::clearPoints
virtual void clearPoints() override
Clear points.
Definition: BangBangInterpolator.h:55
TrajColl::Polynomial
Polynomial function.
Definition: Func.h:154
TrajColl::BangBangInterpolator::clone
virtual std::shared_ptr< Interpolator< T, U > > clone() const override
Clone this instance and get shared pointer.
Definition: BangBangInterpolator.h:49
TrajColl::Interpolator
Interpolator of a sequence of waypoints.
Definition: Interpolator.h:14
TrajColl::BangBangInterpolator::BangBangInterpolator
BangBangInterpolator(const BangBangInterpolator &inst)
Copy constructor.
Definition: BangBangInterpolator.h:42
TrajColl::Interpolator< T, T >::points
const std::map< double, T > & points() const
Get points.
Definition: Interpolator.h:74