#pragma once // This is a simple alpha-beta filter. It follows the example from Wikipedia // closely: http://en.wikipedia.org/wiki/Alpha_beta_filter // // Given an initial position and velocity, learning parameters alpha and beta, // and a series of input observations of the distance travelled, the filter // predicts the real position and velocity. // // This is essentially just a C++ version of xwax's pitch.h, // which is Copyright (C) 2010 Mark Hills class AlphaBetaFilter { public: AlphaBetaFilter() : m_initialized(false), m_dt(0.0), m_x(0.0), m_v(0.0), m_alpha(0.0), m_beta(0.0) { } // Prepare the filter for observations every dt seconds. Default filter // values were concluded experimentally for time code vinyl. void init(double dt, double v, double alpha = 1.0/512, double beta = (1.0/512)/1024) { m_initialized = true; m_dt = dt; m_x = 0.0; m_v = v; m_alpha = alpha; m_beta = beta; } // Input an observation to the filter; in the last dt seconds the position // has moved by dx. // // Because the values come from a digital controller, the values for dx are // discrete rather than smooth. void observation(double dx) { if (!m_initialized) { return; } double predicted_x = m_x + m_v * m_dt; double predicted_v = m_v; double residual_x = dx - predicted_x; m_x = predicted_x + residual_x * m_alpha; m_v = predicted_v + residual_x * m_beta / m_dt; // relative to previous m_x -= dx; } // Get the velocity after filtering. double predictedVelocity() const { return m_v; } // Get the position after filtering. double predictedPosition() const { return m_x; } private: // Whether init() has been called. bool m_initialized; // State of the rate calculation filter double m_dt, m_x, m_v, m_alpha, m_beta; };