11#include <initializer_list>
16#include "units/time.h"
84 LinearFilter(std::span<const double> ffGains, std::span<const double> fbGains)
85 : m_inputs(ffGains.size()),
86 m_outputs(fbGains.size()),
87 m_inputGains(ffGains.begin(), ffGains.end()),
88 m_outputGains(fbGains.begin(), fbGains.end()) {
89 for (
size_t i = 0; i < ffGains.size(); ++i) {
90 m_inputs.emplace_front(0.0);
92 for (
size_t i = 0; i < fbGains.size(); ++i) {
93 m_outputs.emplace_front(0.0);
104 std::initializer_list<double> fbGains)
106 {fbGains.begin(), fbGains.end()}) {}
124 units::second_t period) {
125 double gain = std::exp(-period.value() / timeConstant);
144 double gain = std::exp(-period.value() / timeConstant);
160 throw std::runtime_error(
"Number of taps must be greater than zero.");
163 std::vector<double> gains(taps, 1.0 / taps);
171 std::fill(m_inputs.begin(), m_inputs.end(), T{0.0});
172 std::fill(m_outputs.begin(), m_outputs.end(), T{0.0});
225 void Reset(std::span<const T> inputBuffer, std::span<const T> outputBuffer) {
229 if (inputBuffer.size() != m_inputGains.size() ||
230 outputBuffer.size() != m_outputGains.size()) {
231 throw std::runtime_error(
232 "Incorrect length of inputBuffer or outputBuffer");
235 for (
size_t i = 0; i < inputBuffer.size(); ++i) {
236 m_inputs.push_front(inputBuffer[i]);
238 for (
size_t i = 0; i < outputBuffer.size(); ++i) {
239 m_outputs.push_front(outputBuffer[i]);
254 if (m_inputGains.size() > 0) {
255 m_inputs.push_front(input);
259 for (
size_t i = 0; i < m_inputGains.size(); ++i) {
260 retVal += m_inputs[i] * m_inputGains[i];
262 for (
size_t i = 0; i < m_outputGains.size(); ++i) {
263 retVal -= m_outputs[i] * m_outputGains[i];
267 if (m_outputGains.size() > 0) {
268 m_outputs.push_front(retVal);
284 std::vector<double> m_inputGains;
285 std::vector<double> m_outputGains;
292 static constexpr int Factorial(
int n) {
296 return n * Factorial(n - 1);
This class implements a linear, digital filter.
Definition LinearFilter.hpp:76
LinearFilter(std::initializer_list< double > ffGains, std::initializer_list< double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.hpp:103
static LinearFilter< T > SinglePoleIIR(double timeConstant, units::second_t period)
Creates a one-pole IIR low-pass filter of the form: y[n] = (1 - gain) x[n] + gain y[n-1] where gain...
Definition LinearFilter.hpp:123
void Reset(std::span< const T > inputBuffer, std::span< const T > outputBuffer)
Resets the filter state, initializing internal buffers to the provided values.
Definition LinearFilter.hpp:225
void Reset()
Reset the filter state.
Definition LinearFilter.hpp:170
T LastValue() const
Returns the last value calculated by the LinearFilter.
Definition LinearFilter.hpp:279
static LinearFilter< T > HighPass(double timeConstant, units::second_t period)
Creates a first-order high-pass filter of the form: y[n] = gain x[n] + (-gain) x[n-1] + gain y[n-1] ...
Definition LinearFilter.hpp:143
static LinearFilter< T > MovingAverage(int taps)
Creates a K-tap FIR moving average filter of the form: y[n] = 1/k (x[k] + x[k-1] + … + x[0])
Definition LinearFilter.hpp:158
LinearFilter(std::span< const double > ffGains, std::span< const double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.hpp:84
T Calculate(T input)
Calculates the next value of the filter.
Definition LinearFilter.hpp:250
This is a simple circular buffer so we don't need to "bucket brigade" copy old values.
Definition circular_buffer.hpp:24
Definition motor_constants.h:14