-
Notifications
You must be signed in to change notification settings - Fork 0
/
imu_sync.hpp
74 lines (66 loc) · 2.6 KB
/
imu_sync.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ifndef IMU_SYNC_H
#define IMU_SYNC_H
#include <functional>
#include <deque>
#include <iostream>
// _Not_ thread safe imu sample synchronization
class ImuSync {
public:
std::function<void(double time, double leaderX, double leaderY, double leaderZ, double followerX, double followerY, double followerZ)> onSyncedLeader;
struct Sample {
double time;
double x;
double y;
double z;
};
void process() {
if (leaderSamples.empty() || followerSamples.size() < 2) return;
while(!leaderSamples.empty() && leaderSamples.back().time < followerSamples.back().time) {
// If we don't have a follower sample before leader samples timestamp, drop them
leaderSamples.pop_back();
}
auto prevFollower = followerSamples.rbegin();
auto nextFollower = followerSamples.rbegin() + 1;
while (
!leaderSamples.empty()
&& leaderSamples.back().time <= followerSamples.front().time) {
while (leaderSamples.back().time > nextFollower->time) {
prevFollower++;
nextFollower++;
followerSamples.pop_back();
}
Sample current = leaderSamples.back();
leaderSamples.pop_back();
double t0 = (nextFollower->time - current.time) / (nextFollower->time - prevFollower->time);
double t1 = 1. - t0;
if (onSyncedLeader)
onSyncedLeader(
current.time,
current.x,
current.y,
current.z,
prevFollower->x * t0 + nextFollower->x * t1,
prevFollower->y * t0 + nextFollower->y * t1,
prevFollower->z * t0 + nextFollower->z * t1
);
}
}
void addLeader(double time, double x, double y, double z) {
// Not strictly necessary in scope of this class, but leads to more nicely behaved data
if (!this->leaderSamples.empty() && time <= this->leaderSamples.front().time)
return;
this->leaderSamples.emplace_front(Sample {time, x, y, z});
process();
}
void addFollower(double time, double x, double y, double z) {
// Follower samples timestamps must be increasing to avoid divided by zero
if (!this->followerSamples.empty() && time <= this->followerSamples.front().time)
return;
this->followerSamples.emplace_front(Sample {time, x, y, z});
process();
}
private:
std::deque<Sample> leaderSamples;
std::deque<Sample> followerSamples;
};
#endif // IMU_SYNC_H