Brian Silverman | 5b3e51e | 2013-03-29 22:53:44 -0700 | [diff] [blame] | 1 | #ifndef VISION_RINGBUFFER_H_ |
| 2 | #define VISION_RINGBUFFER_H_ |
| 3 | |
Brian Silverman | 6ae77dd | 2013-03-29 22:28:08 -0700 | [diff] [blame] | 4 | #include <stdio.h> |
| 5 | #include <stdlib.h> |
Brian Silverman | 5b3e51e | 2013-03-29 22:53:44 -0700 | [diff] [blame] | 6 | |
| 7 | namespace frc971 { |
| 8 | namespace vision { |
Brian Silverman | 6ae77dd | 2013-03-29 22:28:08 -0700 | [diff] [blame] | 9 | |
| 10 | template<class T,class V> |
| 11 | class 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 Silverman | 5b3e51e | 2013-03-29 22:53:44 -0700 | [diff] [blame] | 62 | ((time - time_at(min)).ToSeconds()/(time_at(max) - time_at(min)).ToSeconds()); |
Brian Silverman | 6ae77dd | 2013-03-29 22:28:08 -0700 | [diff] [blame] | 63 | } |
| 64 | }; |
| 65 | }; // vision |
| 66 | }; // frc971 |
Brian Silverman | 5b3e51e | 2013-03-29 22:53:44 -0700 | [diff] [blame] | 67 | #endif // VISION_RINGBUFFER_H_ |