10#include <units/time.h>
40 std::function<T(
const T&,
const T&,
double)> func)
41 : m_historySize(historySize), m_interpolatingFunc(func) {}
50 : m_historySize(historySize),
51 m_interpolatingFunc([](const T& start, const T& end, double t) {
52 return Lerp(start, end, t);
63 if (m_pastSnapshots.size() == 0 || time > m_pastSnapshots.back().first) {
64 m_pastSnapshots.emplace_back(time, sample);
66 auto first_after = std::upper_bound(
67 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
68 [](
auto t,
const auto& pair) { return t < pair.first; });
70 if (first_after == m_pastSnapshots.begin()) {
72 m_pastSnapshots.insert(first_after, std::pair{time, sample});
73 }
else if (
auto last_not_greater_than = first_after - 1;
74 last_not_greater_than == m_pastSnapshots.begin() ||
75 last_not_greater_than->first < time) {
78 m_pastSnapshots.insert(first_after, std::pair{time, sample});
81 last_not_greater_than->second = sample;
84 while (time - m_pastSnapshots[0].first > m_historySize) {
85 m_pastSnapshots.erase(m_pastSnapshots.begin());
90 void Clear() { m_pastSnapshots.clear(); }
98 std::optional<T>
Sample(units::second_t time)
const {
99 if (m_pastSnapshots.empty()) {
107 if (time <= m_pastSnapshots.front().first) {
108 return m_pastSnapshots.front().second;
110 if (time > m_pastSnapshots.back().first) {
111 return m_pastSnapshots.back().second;
113 if (m_pastSnapshots.size() < 2) {
114 return m_pastSnapshots[0].second;
118 auto upper_bound = std::lower_bound(
119 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
120 [](
const auto& pair,
auto t) { return t > pair.first; });
122 if (upper_bound == m_pastSnapshots.begin()) {
123 return upper_bound->second;
126 auto lower_bound = upper_bound - 1;
128 double t = ((time - lower_bound->first) /
129 (upper_bound->first - lower_bound->first));
131 return m_interpolatingFunc(lower_bound->second, upper_bound->second, t);
139 return m_pastSnapshots;
146 return m_pastSnapshots;
150 units::second_t m_historySize;
151 std::vector<std::pair<units::second_t, T>> m_pastSnapshots;
152 std::function<T(
const T&,
const T&,
double)> m_interpolatingFunc;
158 units::second_t historySize)
159 : m_historySize(historySize),
160 m_interpolatingFunc([](const Pose2d& start, const Pose2d& end, double t) {
166 Twist2d twist = start.Log(end);
167 Twist2d scaledTwist = twist * t;
168 return start.Exp(scaledTwist);
The TimeInterpolatableBuffer provides an easy way to estimate past measurements.
Definition TimeInterpolatableBuffer.hpp:31
void Clear()
Clear all old samples.
Definition TimeInterpolatableBuffer.hpp:90
std::optional< T > Sample(units::second_t time) const
Sample the buffer at the given time.
Definition TimeInterpolatableBuffer.hpp:98
TimeInterpolatableBuffer(units::second_t historySize)
Create a new TimeInterpolatableBuffer.
Definition TimeInterpolatableBuffer.hpp:49
std::vector< std::pair< units::second_t, T > > & GetInternalBuffer()
Grant access to the internal sample buffer.
Definition TimeInterpolatableBuffer.hpp:138
TimeInterpolatableBuffer(units::second_t historySize, std::function< T(const T &, const T &, double)> func)
Create a new TimeInterpolatableBuffer.
Definition TimeInterpolatableBuffer.hpp:39
void AddSample(units::second_t time, T sample)
Add a sample to the buffer.
Definition TimeInterpolatableBuffer.hpp:61
const std::vector< std::pair< units::second_t, T > > & GetInternalBuffer() const
Grant access to the internal sample buffer.
Definition TimeInterpolatableBuffer.hpp:145
Definition StatusCodes.h:18