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; });
76 auto last_not_greater_than = first_after - 1;
78 if (first_after == m_pastSnapshots.begin() ||
79 last_not_greater_than == m_pastSnapshots.begin() ||
80 last_not_greater_than->first < time) {
85 m_pastSnapshots.insert(first_after, std::pair(time, sample));
89 last_not_greater_than->second = sample;
92 while (time - m_pastSnapshots[0].
first > m_historySize) {
93 m_pastSnapshots.erase(m_pastSnapshots.begin());
98 void Clear() { m_pastSnapshots.clear(); }
106 std::optional<T>
Sample(units::second_t time) {
107 if (m_pastSnapshots.empty()) {
115 if (time <= m_pastSnapshots.front().first) {
116 return m_pastSnapshots.front().second;
118 if (time > m_pastSnapshots.back().first) {
119 return m_pastSnapshots.back().second;
121 if (m_pastSnapshots.size() < 2) {
122 return m_pastSnapshots[0].second;
126 auto upper_bound = std::lower_bound(
127 m_pastSnapshots.begin(), m_pastSnapshots.end(), time,
128 [](
const auto& pair,
auto t) { return t > pair.first; });
130 if (upper_bound == m_pastSnapshots.begin()) {
131 return upper_bound->second;
134 auto lower_bound = upper_bound - 1;
136 double t = ((time - lower_bound->first) /
137 (upper_bound->first - lower_bound->first));
139 return m_interpolatingFunc(lower_bound->second, upper_bound->second, t);
147 return m_pastSnapshots;
151 units::second_t m_historySize;
152 std::vector<std::pair<units::second_t, T>> m_pastSnapshots;
153 std::function<T(
const T&,
const T&,
double)> m_interpolatingFunc;
159 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:98
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:146
std::optional< T > Sample(units::second_t time)
Sample the buffer at the given time.
Definition: TimeInterpolatableBuffer.h:106
void AddSample(units::second_t time, T sample)
Add a sample to the buffer.
Definition: TimeInterpolatableBuffer.h:66
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
Definition: IndexedViewHelper.h:81
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: AprilTagFieldLayout.h:22
constexpr T Lerp(const T &startValue, const T &endValue, double t)
Linearly interpolates between two values.
Definition: MathExtras.h:950