15 #ifndef VISIONTRANSFER_SENSORRINGBUFFER_H
16 #define VISIONTRANSFER_SENSORRINGBUFFER_H
25 #include <visiontransfer/sensordata.h>
27 using namespace visiontransfer;
29 namespace visiontransfer {
41 template<
typename RecordType,
int RINGBUFFER_SIZE>
44 int read_horizon, write_position, read_next;
45 unsigned long lostSamples;
46 std::array<RecordType, RINGBUFFER_SIZE> buffer;
47 std::recursive_mutex mutex;
49 constexpr
unsigned int ringbufferSize()
const {
return RINGBUFFER_SIZE; }
51 constexpr
int capacity()
const {
return ringbufferSize() - 1; }
52 int size()
const {
return (ringbufferSize() + (write_position - read_next)) % ringbufferSize(); }
53 int samplesLost()
const {
return lostSamples; }
54 bool isFull()
const {
return size()==capacity(); }
55 bool isEmpty()
const {
return write_position==read_next; }
57 bool advanceWritePosition() {
58 write_position = (write_position + 1) % ringbufferSize();
59 if (write_position==read_next) {
61 read_next = (write_position + 1) % ringbufferSize();
64 return lostSamples==0;
67 bool pushData(
const std::vector<RecordType>& data) {
69 std::unique_lock<std::recursive_mutex> lock(mutex);
70 for (
auto const& d: data) {
73 return lostSamples==0;
76 bool pushData(
const RecordType& data) {
77 std::unique_lock<std::recursive_mutex> lock(mutex);
78 buffer[write_position] = data;
79 return advanceWritePosition();
82 bool pushData(RecordType&& data) {
83 std::unique_lock<std::recursive_mutex> lock(mutex);
84 buffer[write_position] = std::move(data);
85 return advanceWritePosition();
89 std::vector<RecordType> popAllData() {
90 std::unique_lock<std::recursive_mutex> lock(mutex);
92 if (write_position < read_next) {
94 std::vector<RecordType> v(buffer.begin()+read_next, buffer.end());
95 v.reserve(v.size() + write_position);
96 std::copy(buffer.begin(), buffer.begin() + write_position, std::back_inserter(v));
97 read_next = (write_position) % ringbufferSize();
100 std::vector<RecordType> v(buffer.begin()+read_next, buffer.begin()+write_position);
101 read_next = (write_position) % ringbufferSize();
107 std::vector<RecordType>
popBetweenTimes(
int fromSec = 0,
int fromUSec = 0,
int untilSec = 0x7fffFFFFl,
int untilUSec = 0x7fffFFFFl) {
108 std::unique_lock<std::recursive_mutex> lock(mutex);
111 if (write_position == read_next)
return std::vector<RecordType>();
113 buffer[read_next].getTimestamp(tsSec, tsUSec);
114 while ((tsSec < fromSec) || ((tsSec == fromSec) && (tsUSec < fromUSec))) {
115 read_next = (read_next + 1) % ringbufferSize();
116 if (write_position == read_next)
return std::vector<RecordType>();
119 int lastidx = read_next;
121 buffer[lastidx].getTimestamp(tsSec, tsUSec);
122 while ((tsSec < untilSec) || ((tsSec == untilSec) && (tsUSec <= untilUSec))) {
123 li = (lastidx + 1) % ringbufferSize();
125 if (li == write_position)
break;
127 if (lastidx < read_next) {
129 std::vector<RecordType> v(buffer.begin()+read_next, buffer.end());
130 v.reserve(v.size() + lastidx);
131 std::copy(buffer.begin(), buffer.begin() + lastidx, std::back_inserter(v));
135 std::vector<RecordType> v(buffer.begin()+read_next, buffer.begin()+lastidx);
136 read_next = (lastidx) % ringbufferSize();