Line data Source code
1 : #pragma once 2 : 3 : #include <AH/Containers/Array.hpp> 4 : #include <AH/Math/Divide.hpp> 5 : #include <AH/STL/algorithm> 6 : #include <AH/STL/cstdint> 7 : #include <AH/STL/type_traits> 8 : 9 : /// @addtogroup Filters 10 : /// @{ 11 : 12 : /** 13 : * @brief Simple Moving Average filter. 14 : * 15 : * Returns the average of the N most recent input values. 16 : * 17 : * @f[ 18 : * y[n] = \frac{1}{N} \sum_{i=0}^{N-1}x[n-i] 19 : * @f] 20 : * 21 : * @see https://tttapa.github.io/Pages/Mathematics/Systems-and-Control-Theory/Digital-filters/Simple%20Moving%20Average/Simple-Moving-Average.html 22 : * 23 : * @tparam N 24 : * The number of samples to average. 25 : * @tparam input_t 26 : * The type of the input (and output) of the filter. 27 : * @tparam sum_t 28 : * The type to use for the accumulator, must be large enough to fit 29 : * N times the maximum input value. 30 : */ 31 : template <uint8_t N, class input_t = uint16_t, class sum_t = uint32_t> 32 : class SMA { 33 : public: 34 : /** 35 : * @brief Default constructor (initial state is initialized to all zeros). 36 : */ 37 : SMA() = default; 38 : 39 : /** 40 : * @brief Constructor (initial state is initialized to given value). 41 : * 42 : * @param initialValue 43 : * Determines the initial state of the filter: 44 : * @f$ x[-N] =\ \ldots\ = x[-2] = x[-1] = \text{initialValue} @f$ 45 : */ 46 2 : SMA(input_t initialValue) : sum(N * (sum_t)initialValue) { 47 2 : std::fill(std::begin(previousInputs), std::end(previousInputs), 48 : initialValue); 49 2 : } 50 : 51 : /** 52 : * @brief Update the internal state with the new input @f$ x[n] @f$ and 53 : * return the new output @f$ y[n] @f$. 54 : * 55 : * @param input 56 : * The new input @f$ x[n] @f$. 57 : * @return The new output @f$ y[n] @f$. 58 : */ 59 30 : input_t operator()(input_t input) { 60 30 : sum -= previousInputs[index]; 61 30 : sum += input; 62 30 : previousInputs[index] = input; 63 30 : if (++index == N) 64 3 : index = 0; 65 30 : return AH::round_div<N>(sum); 66 : } 67 : 68 : private: 69 : uint8_t index = 0; 70 : input_t previousInputs[N] = {}; 71 : sum_t sum = 0; 72 : }; 73 : 74 : /// @}