43 std::function<T(
const T&,
const T&,
double)> func)
44 : m_historySize(historySize), m_interpolatingFunc(func) {}
53 : m_historySize(historySize),
54 m_interpolatingFunc([](const T& start, const T& end, double t) {
66 if (m_pastSnapshots.size() == 0 || time > m_pastSnapshots.back().first) {
67 m_pastSnapshots.emplace_back(time, sample);
69 auto first_after = std::upper_bound(
70 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
71 [](
auto t,
const auto& pair) { return t < pair.first; });
73 if (first_after == m_pastSnapshots.begin()) {
75 m_pastSnapshots.insert(first_after, std::pair{time, sample});
76 }
else if (
auto last_not_greater_than = first_after - 1;
77 last_not_greater_than == m_pastSnapshots.begin() ||
78 last_not_greater_than->first < time) {
81 m_pastSnapshots.insert(first_after, std::pair{time, sample});
84 last_not_greater_than->second = sample;
87 while (time - m_pastSnapshots[0].first > m_historySize) {
88 m_pastSnapshots.erase(m_pastSnapshots.begin());
93 void Clear() { m_pastSnapshots.clear(); }
101 std::optional<T>
Sample(units::second_t time)
const {
102 if (m_pastSnapshots.empty()) {
110 if (time <= m_pastSnapshots.front().first) {
111 return m_pastSnapshots.front().second;
113 if (time > m_pastSnapshots.back().first) {
114 return m_pastSnapshots.back().second;
116 if (m_pastSnapshots.size() < 2) {
117 return m_pastSnapshots[0].second;
121 auto upper_bound = std::lower_bound(
122 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
123 [](
const auto& pair,
auto t) { return t > pair.first; });
125 if (upper_bound == m_pastSnapshots.begin()) {
126 return upper_bound->second;
129 auto lower_bound = upper_bound - 1;
131 double t = ((time - lower_bound->first) /
132 (upper_bound->first - lower_bound->first));
134 return m_interpolatingFunc(lower_bound->second, upper_bound->second, t);
142 return m_pastSnapshots;
149 return m_pastSnapshots;
153 units::second_t m_historySize;
154 std::vector<std::pair<units::second_t, T>> m_pastSnapshots;
155 std::function<T(
const T&,
const T&,
double)> m_interpolatingFunc;
161 units::second_t historySize)
162 : m_historySize(historySize),
163 m_interpolatingFunc([](const
Pose2d& start, const
Pose2d& end, double t) {
169 Twist2d twist = start.Log(end);
170 Twist2d scaledTwist = twist * t;
171 return start.Exp(scaledTwist);
Represents a 2D pose containing translational and rotational elements.
Definition Pose2d.h:28
The TimeInterpolatableBuffer provides an easy way to estimate past measurements.
Definition TimeInterpolatableBuffer.h:34
void Clear()
Clear all old samples.
Definition TimeInterpolatableBuffer.h:93
TimeInterpolatableBuffer(units::second_t historySize, std::function< T(const T &, const T &, double)> func)
Create a new TimeInterpolatableBuffer.
Definition TimeInterpolatableBuffer.h:42
TimeInterpolatableBuffer(units::second_t historySize)
Create a new TimeInterpolatableBuffer.
Definition TimeInterpolatableBuffer.h:52
std::vector< std::pair< units::second_t, T > > & GetInternalBuffer()
Grant access to the internal sample buffer.
Definition TimeInterpolatableBuffer.h:141
const std::vector< std::pair< units::second_t, T > > & GetInternalBuffer() const
Grant access to the internal sample buffer.
Definition TimeInterpolatableBuffer.h:148
std::optional< T > Sample(units::second_t time) const
Sample the buffer at the given time.
Definition TimeInterpolatableBuffer.h:101
void AddSample(units::second_t time, T sample)
Add a sample to the buffer.
Definition TimeInterpolatableBuffer.h:64
constexpr T Lerp(const T &startValue, const T &endValue, double t)
Linearly interpolates between two values.
Definition MathExtras.h:772
A change in distance along a 2D arc since the last pose update.
Definition Twist2d.h:22