SequenceInterpolator.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015-2020 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 
7 #include <mc_rtc/logging.h>
9 
10 #include <algorithm>
11 
12 namespace mc_trajectory
13 {
14 
52 template<typename Value, typename InterpolationFunction = LinearInterpolation<Value>>
54 {
55  using TimedValue = typename std::pair<double, Value>;
56  using TimedValueVector = std::vector<TimedValue>;
57 
63  SequenceInterpolator() noexcept {}
64 
72  SequenceInterpolator(const TimedValueVector & values) { this->values(values); }
73 
83  {
84  if(values.empty()) return;
85  if(!std::is_sorted(values.begin(), values.end(),
86  [](const TimedValue & a, const TimedValue & b) { return a.first < b.first; }))
87  {
88  mc_rtc::log::error_and_throw("SequenceInterpolator values must be ordered by strictly ascending time");
89  }
90  values_ = values;
91  prevIndex_ = 0;
92  if(values_.size() > 1)
93  {
94  nextIndex_ = 1;
96  }
97  }
98 
100  inline const TimedValueVector & values() const noexcept { return values_; }
101 
106  inline bool hasValues() const noexcept { return values_.size(); }
107 
109  void clear() { values_.clear(); }
110 
124  Value compute(double currTime)
125  {
126  if(values_.empty()) { mc_rtc::log::error_and_throw("SequenceInterpolator requires at least one value"); }
127 
128  // Check for out-of-bound access
129  if(currTime >= values_.back().first) { return values_.back().second; }
130  else if(currTime <= values_.front().first) { return values_.front().second; }
131 
132  /*
133  * Efficiently update interval index and associated cached values:
134  * 1/ Check whether currTime is in the current interval
135  * 2/ Check whether currTime is in the next interval
136  * 3/ Perform a binary search
137  * Note that we don't need to check indices bounds here as they are valid by
138  * construction.
139  */
140  auto updateIndex = [this, currTime]()
141  {
142  if(values_[prevIndex_].first < currTime && values_[nextIndex_].first >= currTime) { return; }
143  else if(values_[nextIndex_].first < currTime && values_[nextIndex_ + 1].first >= currTime)
144  {
145  ++prevIndex_;
146  ++nextIndex_;
148  }
149  else
150  {
151  // first element in values_ with time greater or equal to currTime
152  auto nextIt = std::lower_bound(std::begin(values_), std::end(values_), currTime,
153  [](const TimedValue & lhs, const double & rhs) { return lhs.first < rhs; });
154  nextIndex_ = static_cast<size_t>(nextIt - values_.begin());
155  prevIndex_ = nextIndex_ - 1;
157  }
158  };
159 
160  updateIndex();
161  const auto & prevTime = values_[prevIndex_].first;
162  return interpolator_(values_[prevIndex_].second, values_[nextIndex_].second,
163  (currTime - prevTime) / intervalDuration_);
164  }
165 
166 protected:
167  InterpolationFunction interpolator_;
169  size_t prevIndex_ = 0;
170  size_t nextIndex_ = 0;
171  double intervalDuration_ = 0;
172 };
173 
174 } // namespace mc_trajectory
void error_and_throw(Args &&... args)
Definition: logging.h:47
Definition: BSpline.h:15
Interpolate values in a timed sequence.
Definition: SequenceInterpolator.h:54
bool hasValues() const noexcept
Definition: SequenceInterpolator.h:106
size_t prevIndex_
Cache the previous index to optimize lookup when used sequentially.
Definition: SequenceInterpolator.h:169
SequenceInterpolator() noexcept
Creates an empty interpolator.
Definition: SequenceInterpolator.h:63
std::vector< TimedValue > TimedValueVector
Definition: SequenceInterpolator.h:56
size_t nextIndex_
Cache the next index.
Definition: SequenceInterpolator.h:170
Value compute(double currTime)
Definition: SequenceInterpolator.h:124
double intervalDuration_
Cache the duration of the current interval.
Definition: SequenceInterpolator.h:171
InterpolationFunction interpolator_
Functor for computing the interpolated values.
Definition: SequenceInterpolator.h:167
SequenceInterpolator(const TimedValueVector &values)
Creates an interpolator with values.
Definition: SequenceInterpolator.h:72
void values(const TimedValueVector &values)
Set interpolator values.
Definition: SequenceInterpolator.h:82
typename std::pair< double, Value > TimedValue
Definition: SequenceInterpolator.h:55
void clear()
Definition: SequenceInterpolator.h:109
const TimedValueVector & values() const noexcept
Definition: SequenceInterpolator.h:100
TimedValueVector values_
Interpolation values.
Definition: SequenceInterpolator.h:168