45 std::function<T(
const T&,
const T&,
double)> func)
46 : m_historySize(historySize), m_interpolatingFunc(func) {}
55 : m_historySize(historySize),
56 m_interpolatingFunc([](const T& start, const T& end, double t) {
68 if (m_pastSnapshots.size() == 0 || time > m_pastSnapshots.back().first) {
69 m_pastSnapshots.emplace_back(time, sample);
71 auto first_after = std::upper_bound(
72 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
73 [](
auto t,
const auto& pair) { return t < pair.first; });
75 if (first_after == m_pastSnapshots.begin()) {
77 m_pastSnapshots.insert(first_after, std::pair{time, sample});
78 }
else if (
auto last_not_greater_than = first_after - 1;
79 last_not_greater_than == m_pastSnapshots.begin() ||
80 last_not_greater_than->first < time) {
83 m_pastSnapshots.insert(first_after, std::pair{time, sample});
86 last_not_greater_than->second = sample;
89 while (time - m_pastSnapshots[0].
first > m_historySize) {
90 m_pastSnapshots.erase(m_pastSnapshots.begin());
95 void Clear() { m_pastSnapshots.clear(); }
103 std::optional<T>
Sample(units::second_t time) {
104 if (m_pastSnapshots.empty()) {
112 if (time <= m_pastSnapshots.front().first) {
113 return m_pastSnapshots.front().second;
115 if (time > m_pastSnapshots.back().first) {
116 return m_pastSnapshots.back().second;
118 if (m_pastSnapshots.size() < 2) {
119 return m_pastSnapshots[0].second;
123 auto upper_bound = std::lower_bound(
124 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
125 [](
const auto& pair,
auto t) { return t > pair.first; });
127 if (upper_bound == m_pastSnapshots.begin()) {
128 return upper_bound->second;
131 auto lower_bound = upper_bound - 1;
133 double t = ((time - lower_bound->first) /
134 (upper_bound->first - lower_bound->first));
136 return m_interpolatingFunc(lower_bound->second, upper_bound->second, t);
144 return m_pastSnapshots;
148 units::second_t m_historySize;
149 std::vector<std::pair<units::second_t, T>> m_pastSnapshots;
150 std::function<T(
const T&,
const T&,
double)> m_interpolatingFunc;
156 units::second_t historySize);
#define WPILIB_DLLEXPORT
Definition: SymbolExports.h:36
The TimeInterpolatableBuffer provides an easy way to estimate past measurements.
Definition: TimeInterpolatableBuffer.h:36
void Clear()
Clear all old samples.
Definition: TimeInterpolatableBuffer.h:95
TimeInterpolatableBuffer(units::second_t historySize, std::function< T(const T &, const T &, double)> func)
Create a new TimeInterpolatableBuffer.
Definition: TimeInterpolatableBuffer.h:44
TimeInterpolatableBuffer(units::second_t historySize)
Create a new TimeInterpolatableBuffer.
Definition: TimeInterpolatableBuffer.h:54
std::vector< std::pair< units::second_t, T > > & GetInternalBuffer()
Grant access to the internal sample buffer.
Definition: TimeInterpolatableBuffer.h:143
std::optional< T > Sample(units::second_t time)
Sample the buffer at the given time.
Definition: TimeInterpolatableBuffer.h:103
void AddSample(units::second_t time, T sample)
Add a sample to the buffer.
Definition: TimeInterpolatableBuffer.h:66
const T & first(const T &value, const Tail &...)
Definition: compile.h:60
Definition: AprilTagPoseEstimator.h:15
constexpr T Lerp(const T &startValue, const T &endValue, double t)
Linearly interpolates between two values.
Definition: MathExtras.h:638