blob: f333f2996490040c1f697dc51bd3ea22f7e59668 [file] [log] [blame]
Brian Silverman5b3e51e2013-03-29 22:53:44 -07001#ifndef VISION_RINGBUFFER_H_
2#define VISION_RINGBUFFER_H_
3
Brian Silverman6ae77dd2013-03-29 22:28:08 -07004#include <stdio.h>
5#include <stdlib.h>
Brian Silverman5b3e51e2013-03-29 22:53:44 -07006
7namespace frc971 {
8namespace vision {
Brian Silverman6ae77dd2013-03-29 22:28:08 -07009
10template<class T,class V>
11class RingBuffer{
12 //record class to hold sampes
13 class Samples{
14 public:
15 T time;
16 V value;
17 };
18 Samples *samples;
19 int current_;
20 int wraps_;
21 V value_at(int index){
22 return samples[index & 255].value;
23 }
24 T time_at(int index){
25 return samples[index & 255].time;
26 }
27 public:
28 RingBuffer(){
29 current_ = 0;
30 wraps_ = 0;
31 samples = (Samples *)malloc(sizeof(Samples) * 256);
32 }
33 // Adds samples into the ringbuffer.
34 void Sample(T time,V val){
35 current_ += 1;
36 wraps_ += current_ / 256;
37 current_ = current_ % 256;
38 samples[current_].time = time;
39 samples[current_].value = val;
40 }
41 // Binary Search to find and interpolate the values.
42 V ValueAt(T time){
43 int start = current_ - 255;
44 int end = current_;
45 if(start < 0 && !wraps_){
46 start = 0;
47 }
48 int max = end;
49 int min = start;
50 while(end - start > 1){
51 int mid = (start + end) / 2;
52 Samples check = samples[mid & 255];
53 if(check.time < time){
54 start = mid;
55 min = mid;
56 }else{
57 max = mid;
58 end = mid;
59 }
60 }
61 return value_at(min) + (value_at(max) - value_at(min)) *
Brian Silverman5b3e51e2013-03-29 22:53:44 -070062 ((time - time_at(min)).ToSeconds()/(time_at(max) - time_at(min)).ToSeconds());
Brian Silverman6ae77dd2013-03-29 22:28:08 -070063 }
64};
65}; // vision
66}; // frc971
Brian Silverman5b3e51e2013-03-29 22:53:44 -070067#endif // VISION_RINGBUFFER_H_