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