12#include <initializer_list>
18#include "units/time.h"
87 : m_inputs(ffGains.size()),
88 m_outputs(fbGains.size()),
89 m_inputGains(ffGains.begin(), ffGains.end()),
90 m_outputGains(fbGains.begin(), fbGains.end()) {
91 for (
size_t i = 0; i < ffGains.
size(); ++i) {
92 m_inputs.emplace_front(0.0);
94 for (
size_t i = 0; i < fbGains.
size(); ++i) {
95 m_outputs.emplace_front(0.0);
106 std::initializer_list<double> fbGains)
108 {fbGains.begin(), fbGains.end()}) {}
126 units::second_t period) {
127 double gain = std::exp(-period.value() / timeConstant);
146 double gain = std::exp(-period.value() / timeConstant);
162 throw std::runtime_error(
"Number of taps must be greater than zero.");
165 std::vector<double> gains(taps, 1.0 / taps);
186 template <
int Derivative,
int Samples>
188 const std::array<int, Samples> stencil, units::second_t period) {
205 static_assert(Derivative >= 1,
206 "Order of derivative must be greater than or equal to one.");
207 static_assert(Samples > 0,
"Number of samples must be greater than zero.");
208 static_assert(Derivative < Samples,
209 "Order of derivative must be less than number of samples.");
211 Eigen::Matrix<double, Samples, Samples> S;
212 for (
int row = 0; row < Samples; ++row) {
213 for (
int col = 0; col < Samples; ++col) {
214 S(row, col) = std::pow(stencil[col], row);
219 Eigen::Vector<double, Samples> d;
220 for (
int i = 0; i < Samples; ++i) {
221 d(i) = (i == Derivative) ? Factorial(Derivative) : 0.0;
224 Eigen::Vector<double, Samples> a =
225 S.householderQr().solve(d) / std::pow(period.value(), Derivative);
228 std::vector<double> ffGains;
229 for (
int i = Samples - 1; i >= 0; --i) {
230 ffGains.push_back(a(i));
253 template <
int Derivative,
int Samples>
256 std::array<int, Samples> stencil{};
257 for (
int i = 0; i < Samples; ++i) {
258 stencil[i] = -(Samples - 1) + i;
261 return FiniteDifference<Derivative, Samples>(stencil, period);
268 std::fill(m_inputs.begin(), m_inputs.end(), T{0.0});
269 std::fill(m_outputs.begin(), m_outputs.end(), T{0.0});
326 if (inputBuffer.
size() != m_inputGains.size() ||
327 outputBuffer.
size() != m_outputGains.size()) {
328 throw std::runtime_error(
329 "Incorrect length of inputBuffer or outputBuffer");
332 for (
size_t i = 0; i < inputBuffer.
size(); ++i) {
333 m_inputs.push_front(inputBuffer[i]);
335 for (
size_t i = 0; i < outputBuffer.
size(); ++i) {
336 m_outputs.push_front(outputBuffer[i]);
351 if (m_inputGains.size() > 0) {
352 m_inputs.push_front(input);
356 for (
size_t i = 0; i < m_inputGains.size(); ++i) {
357 retVal += m_inputs[i] * m_inputGains[i];
359 for (
size_t i = 0; i < m_outputGains.size(); ++i) {
360 retVal -= m_outputs[i] * m_outputGains[i];
364 if (m_outputGains.size() > 0) {
365 m_outputs.push_front(retVal);
381 std::vector<double> m_inputGains;
382 std::vector<double> m_outputGains;
389 static constexpr int Factorial(
int n) {
393 return n * Factorial(n - 1);
This class implements a linear, digital filter.
Definition LinearFilter.hpp:78
LinearFilter(std::initializer_list< double > ffGains, std::initializer_list< double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.hpp:105
static LinearFilter< T > BackwardFiniteDifference(units::second_t period)
Creates a backward finite difference filter that computes the nth derivative of the input given the s...
Definition LinearFilter.hpp:254
static LinearFilter< T > FiniteDifference(const std::array< int, Samples > stencil, units::second_t period)
Creates a finite difference filter that computes the nth derivative of the input given the specified ...
Definition LinearFilter.hpp:187
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:125
void Reset()
Reset the filter state.
Definition LinearFilter.hpp:267
T LastValue() const
Returns the last value calculated by the LinearFilter.
Definition LinearFilter.hpp:376
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:145
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:160
LinearFilter(span< const double > ffGains, span< const double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.hpp:86
T Calculate(T input)
Calculates the next value of the filter.
Definition LinearFilter.hpp:347
void Reset(span< const T > inputBuffer, span< const T > outputBuffer)
Resets the filter state, initializing internal buffers to the provided values.
Definition LinearFilter.hpp:322
This is a simple circular buffer so we don't need to "bucket brigade" copy old values.
Definition circular_buffer.hpp:24
constexpr size_type size() const noexcept
Definition span.hpp:305
Definition StatusCodes.h:18