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
mc_trajectory::SequenceInterpolator::prevIndex_
size_t prevIndex_
Cache the previous index to optimize lookup when used sequentially.
Definition: SequenceInterpolator.h:169
mc_trajectory::SequenceInterpolator::SequenceInterpolator
SequenceInterpolator() noexcept
Creates an empty interpolator.
Definition: SequenceInterpolator.h:63
mc_trajectory::SequenceInterpolator
Interpolate values in a timed sequence.
Definition: SequenceInterpolator.h:53
mc_trajectory::SequenceInterpolator< Eigen::Vector6d, mc_trajectory::LinearInterpolation< Eigen::Vector6d > >::TimedValue
typename std::pair< double, Eigen::Vector6d > TimedValue
Definition: SequenceInterpolator.h:55
mc_trajectory::SequenceInterpolator::compute
Value compute(double currTime)
Definition: SequenceInterpolator.h:124
mc_trajectory::SequenceInterpolator::nextIndex_
size_t nextIndex_
Cache the next index.
Definition: SequenceInterpolator.h:170
mc_trajectory::SequenceInterpolator::intervalDuration_
double intervalDuration_
Cache the duration of the current interval.
Definition: SequenceInterpolator.h:171
mc_trajectory
Definition: BSpline.h:14
mc_trajectory::SequenceInterpolator::interpolator_
InterpolationFunction interpolator_
Functor for computing the interpolated values.
Definition: SequenceInterpolator.h:167
mc_rtc::log::error_and_throw
void error_and_throw(Args &&... args)
Definition: logging.h:47
mc_trajectory::SequenceInterpolator::values
const TimedValueVector & values() const noexcept
Definition: SequenceInterpolator.h:100
mc_trajectory::SequenceInterpolator::values
void values(const TimedValueVector &values)
Set interpolator values.
Definition: SequenceInterpolator.h:82
mc_trajectory::SequenceInterpolator< Eigen::Vector6d, mc_trajectory::LinearInterpolation< Eigen::Vector6d > >::TimedValueVector
std::vector< TimedValue > TimedValueVector
Definition: SequenceInterpolator.h:56
mc_trajectory::SequenceInterpolator::values_
TimedValueVector values_
Interpolation values.
Definition: SequenceInterpolator.h:168
LinearInterpolation.h
mc_trajectory::SequenceInterpolator::clear
void clear()
Definition: SequenceInterpolator.h:109
logging.h
mc_trajectory::SequenceInterpolator::SequenceInterpolator
SequenceInterpolator(const TimedValueVector &values)
Creates an interpolator with values.
Definition: SequenceInterpolator.h:72
mc_trajectory::SequenceInterpolator::hasValues
bool hasValues() const noexcept
Definition: SequenceInterpolator.h:106