// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*- /// @file AP_Buffer.h /// @brief fifo buffer template class #ifndef AP_BUFFER #define AP_BUFFER #include #include #include // ArduPilot Mega Vector/Matrix math Library /// @class AP_Buffer template class AP_Buffer { public: // Constructor AP_Buffer(); // clear - removes all points from the curve virtual void clear(); // add - adds an item to the buffer. returns TRUE if successfully added virtual bool add( T item ); // get - returns the next value in the buffer virtual T get(); // peek - check what the next value in the buffer is but don't pull it off virtual T peek(uint8_t position = 0); // num_values - returns number of values in the buffer virtual uint8_t num_items() { return _num_items; } // print_buffer - display the contents of the buffer on the serial port //virtual void print_buffer(); protected: uint8_t _num_items; // number of items in the buffer uint8_t _head; // first item in the buffer (will be returned with the next get call) uint8_t _tail; // last item added to the buffer (most recently added with the add method) T _buff[SIZE]; // x values of each point on the curve }; // Typedef for convenience typedef AP_Buffer AP_BufferUInt8_Size8; typedef AP_Buffer AP_BufferUnt8_Size16; typedef AP_Buffer AP_BufferUInt8_Size32; typedef AP_Buffer AP_BufferUInt8_Size64; typedef AP_Buffer AP_BufferUInt8_Size128; typedef AP_Buffer AP_BufferFloat_Size10; typedef AP_Buffer AP_BufferFloat_Size15; // Constructor template AP_Buffer::AP_Buffer() : _num_items(0) { // clear the buffer clear(); }; // clear - removes all points from the curve template void AP_Buffer::clear() { // clear the curve _num_items = 0; _head = 0; _tail = 0; } // add - adds an item to the buffer. returns TRUE if successfully added template bool AP_Buffer::add( T item ) { // add item at the tail _buff[_tail] = item; // move tail forward one position _tail++; // wrap around to front of buffer if required if( _tail >= SIZE ) _tail = 0; // if the tail bumps into the head, move the head forward (throw away the oldest item) if( _tail == _head ) { _head++; if( _head >= SIZE ) _head = 0; }else{ // increment number of items _num_items++; } // indicate success return true; /* Old method that fails when buffer fills up if( _num_items < SIZE ) { // add item at the tail _buff[_tail] = item; // move tail forward one position _tail++; // wrap around to front of buffer if required if( _tail >= SIZE ) _tail = 0; // increment number of items _num_items++; // indicate success return true; }else{ // we do not have room for the new item return false; } */ } // get - returns the next value in the buffer template T AP_Buffer::get() { T result; // return zero if buffer is empty if( _num_items == 0 ) { return 0; } // get next value in buffer result = _buff[_head]; // increment to next point _head++; if( _head >= SIZE ) _head = 0; // reduce number of items _num_items--; // return item return result; } // peek - check what the next value in the buffer is but don't pull it off template T AP_Buffer::peek(uint8_t position) { uint8_t j = _head+position; // return zero if position is out of range if( position >= _num_items ) return 0; // wrap around if necessary if( j >= SIZE ) j -= SIZE; // return desired value return _buff[j]; } // displays the contents of the curve (for debugging) /*template void AP_Buffer::print_buffer() { uint8_t i; Serial.print_P(PSTR("AP_Buffer: ")); for( i = 0; i<_num_items; i++ ){ if( i > 0 ) { Serial.print_P(PSTR(", ")); } Serial.print(peek(i)); } Serial.println(); }*/ /* // displays the contents of the curve (for debugging) template void AP_Buffer::print_buffer() { // we cannot print Vector3f types } */ #endif // AP_BUFFER