GLIM
Loading...
Searching...
No Matches
interpolation_helper.hpp
1#pragma once
2
3#include <deque>
4#include <algorithm>
5
6namespace glim {
7
9enum class InterpolationHelperResult {
10 SUCCESS,
11 FAILURE,
12 WAITING
13};
14
16enum class InterpolationHelperSearchMode {
17 LINEAR,
18 BINARY
19};
20
22template <typename Value>
24public:
25 using StampedValue = std::pair<double, Value>;
26
29 InterpolationHelper(InterpolationHelperSearchMode search_mode = InterpolationHelperSearchMode::LINEAR) : search_mode(search_mode) {}
31
33 bool empty() const { return values.empty(); }
34
36 int size() const { return values.size(); }
37
39 double leftmost_time() const { return values.empty() ? 0.0 : values.front().first; }
40
42 double rightmost_time() const { return values.empty() ? 0.0 : values.back().first; }
43
47 void add(double stamp, const Value& value) {
48 if (!values.empty() && values.back().first > stamp) {
49 std::cerr << "inserting non-ordered values!!" << std::endl;
50 return;
51 }
52 values.emplace_back(stamp, value);
53 }
54
56 void add(const std::pair<double, Value>& stamped_value) { //
57 values.emplace_back(stamped_value.first, stamped_value.second);
58 }
59
66 InterpolationHelperResult find(const double stamp, StampedValue* left_ptr, StampedValue* right_ptr, int* remove_cursor_ptr) const {
67 if (values.empty() || values.back().first < stamp) {
68 return InterpolationHelperResult::WAITING;
69 }
70
71 if (values.front().first > stamp) {
72 return InterpolationHelperResult::FAILURE;
73 }
74
75 int right = 1;
76 switch (search_mode) {
77 case InterpolationHelperSearchMode::LINEAR:
78 while (values[right].first < stamp) {
79 right++;
80 }
81 break;
82 case InterpolationHelperSearchMode::BINARY:
83 const auto found = std::lower_bound(values.begin(), values.end(), stamp, [](const auto& value, double stamp) { return value.first < stamp; });
84 right = std::distance(values.begin(), found);
85 break;
86 }
87
88 int left = right - 1;
89
90 if (values[left].first > stamp || values[right].first < stamp || right >= values.size()) {
91 std::cerr << "error: invalid condition!!" << std::endl;
92 abort();
93 }
94
95 if (left_ptr) {
96 *left_ptr = values[left];
97 }
98 if (right_ptr) {
99 *right_ptr = values[right];
100 }
101 if (remove_cursor_ptr) {
102 *remove_cursor_ptr = left - 1;
103 }
104
105 return InterpolationHelperResult::SUCCESS;
106 }
107
110 void erase(int remove_cursor) {
111 if (remove_cursor <= 0) {
112 return;
113 }
114 values.erase(values.begin(), values.begin() + remove_cursor);
115 }
116
117private:
118 InterpolationHelperSearchMode search_mode;
119 std::deque<StampedValue> values;
120};
121
122} // namespace glim
A helper class to find the values that cover a given timestamp from a data stream.
Definition interpolation_helper.hpp:23
void add(double stamp, const Value &value)
Add a new value.
Definition interpolation_helper.hpp:47
InterpolationHelperResult find(const double stamp, StampedValue *left_ptr, StampedValue *right_ptr, int *remove_cursor_ptr) const
Find the values that cover the target timestamp.
Definition interpolation_helper.hpp:66
int size() const
Number of queued values.
Definition interpolation_helper.hpp:36
double leftmost_time() const
Oldest timestamp in the queue.
Definition interpolation_helper.hpp:39
InterpolationHelper(InterpolationHelperSearchMode search_mode=InterpolationHelperSearchMode::LINEAR)
Constructor.
Definition interpolation_helper.hpp:29
void add(const std::pair< double, Value > &stamped_value)
Add a new value.
Definition interpolation_helper.hpp:56
bool empty() const
Check if it's emptry.
Definition interpolation_helper.hpp:33
void erase(int remove_cursor)
Erase values older than the given cursor.
Definition interpolation_helper.hpp:110
double rightmost_time() const
Newest timestamp in the queue.
Definition interpolation_helper.hpp:42