11#include <initializer_list>
16#include <wpi/units/time.hpp>
83 LinearFilter(std::span<const double> ffGains, std::span<const double> fbGains)
84 : m_inputs(ffGains.size()),
85 m_outputs(fbGains.size()),
86 m_inputGains(ffGains.begin(), ffGains.end()),
87 m_outputGains(fbGains.begin(), fbGains.end()) {
88 for (
size_t i = 0; i < ffGains.size(); ++i) {
89 m_inputs.emplace_front(0.0);
91 for (
size_t i = 0; i < fbGains.size(); ++i) {
92 m_outputs.emplace_front(0.0);
103 std::initializer_list<double> fbGains)
105 {fbGains.begin(), fbGains.end()}) {}
123 wpi::units::second_t period) {
124 double gain = std::exp(-period.value() / timeConstant);
143 double gain = std::exp(-period.value() / timeConstant);
159 throw std::runtime_error(
"Number of taps must be greater than zero.");
162 std::vector<double> gains(taps, 1.0 / taps);
170 std::fill(m_inputs.begin(), m_inputs.end(), T{0.0});
171 std::fill(m_outputs.begin(), m_outputs.end(), T{0.0});
224 void Reset(std::span<const T> inputBuffer, std::span<const T> outputBuffer) {
228 if (inputBuffer.size() != m_inputGains.size() ||
229 outputBuffer.size() != m_outputGains.size()) {
230 throw std::runtime_error(
231 "Incorrect length of inputBuffer or outputBuffer");
234 for (
size_t i = 0; i < inputBuffer.size(); ++i) {
235 m_inputs.push_front(inputBuffer[i]);
237 for (
size_t i = 0; i < outputBuffer.size(); ++i) {
238 m_outputs.push_front(outputBuffer[i]);
253 if (m_inputGains.size() > 0) {
254 m_inputs.push_front(input);
258 for (
size_t i = 0; i < m_inputGains.size(); ++i) {
259 retVal += m_inputs[i] * m_inputGains[i];
261 for (
size_t i = 0; i < m_outputGains.size(); ++i) {
262 retVal -= m_outputs[i] * m_outputGains[i];
266 if (m_outputGains.size() > 0) {
267 m_outputs.push_front(retVal);
283 std::vector<double> m_inputGains;
284 std::vector<double> m_outputGains;
291 static constexpr int Factorial(
int n) {
295 return n * Factorial(n - 1);
LinearFilter(std::initializer_list< double > ffGains, std::initializer_list< double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.hpp:102
static LinearFilter< T > HighPass(double timeConstant, wpi::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:142
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:224
void Reset()
Reset the filter state.
Definition LinearFilter.hpp:169
T LastValue() const
Returns the last value calculated by the LinearFilter.
Definition LinearFilter.hpp:278
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:157
static LinearFilter< T > SinglePoleIIR(double timeConstant, wpi::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:122
LinearFilter(std::span< const double > ffGains, std::span< const double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.hpp:83
T Calculate(T input)
Calculates the next value of the filter.
Definition LinearFilter.hpp:249
This is a simple circular buffer so we don't need to "bucket brigade" copy old values.
Definition circular_buffer.hpp:24
Definition SwerveModule.hpp:28
Definition ExternalFeedbackConfigs.hpp:16
Definition motor_constants.h:14