8#include <initializer_list>
20#include "units/time.h"
85 std::span<const double> fbGains)
86 : m_inputs(ffGains.size()),
87 m_outputs(fbGains.size()),
88 m_inputGains(ffGains.begin(), ffGains.end()),
89 m_outputGains(fbGains.begin(), fbGains.end()) {
90 for (
size_t i = 0; i < ffGains.size(); ++i) {
91 m_inputs.emplace_front(0.0);
93 for (
size_t i = 0; i < fbGains.size(); ++i) {
94 m_outputs.emplace_front(0.0);
97 if (!std::is_constant_evaluated()) {
111 std::initializer_list<double> fbGains)
113 {fbGains.begin(), fbGains.end()}) {}
131 units::second_t period) {
132 double gain =
gcem::exp(-period.value() / timeConstant);
151 units::second_t period) {
152 double gain =
gcem::exp(-period.value() / timeConstant);
168 throw std::runtime_error(
"Number of taps must be greater than zero.");
171 std::vector<double> gains(taps, 1.0 / taps);
192 template <
int Derivative,
int Samples>
211 static_assert(Derivative >= 1,
212 "Order of derivative must be greater than or equal to one.");
213 static_assert(Samples > 0,
"Number of samples must be greater than zero.");
214 static_assert(Derivative < Samples,
215 "Order of derivative must be less than number of samples.");
218 for (
int row = 0; row < Samples; ++row) {
219 for (
int col = 0; col < Samples; ++col) {
226 for (
int i = 0; i < Samples; ++i) {
227 d(i) = (i == Derivative) ? Factorial(Derivative) : 0.0;
231 S.householderQr().solve(d) /
gcem::pow(period.value(), Derivative);
234 std::vector<double> ffGains;
235 for (
int i = Samples - 1; i >= 0; --i) {
236 ffGains.push_back(a(i));
259 template <
int Derivative,
int Samples>
263 for (
int i = 0; i < Samples; ++i) {
264 stencil[i] = -(Samples - 1) + i;
274 std::fill(m_inputs.begin(), m_inputs.end(), T{0.0});
275 std::fill(m_outputs.begin(), m_outputs.end(), T{0.0});
328 constexpr void Reset(std::span<const T> inputBuffer,
329 std::span<const T> outputBuffer) {
333 if (inputBuffer.size() != m_inputGains.size() ||
334 outputBuffer.size() != m_outputGains.size()) {
335 throw std::runtime_error(
336 "Incorrect length of inputBuffer or outputBuffer");
339 for (
size_t i = 0; i < inputBuffer.size(); ++i) {
340 m_inputs.push_front(inputBuffer[i]);
342 for (
size_t i = 0; i < outputBuffer.size(); ++i) {
343 m_outputs.push_front(outputBuffer[i]);
358 if (m_inputGains.size() > 0) {
359 m_inputs.push_front(input);
363 for (
size_t i = 0; i < m_inputGains.size(); ++i) {
364 retVal += m_inputs[i] * m_inputGains[i];
366 for (
size_t i = 0; i < m_outputGains.size(); ++i) {
367 retVal -= m_outputs[i] * m_outputGains[i];
371 if (m_outputGains.size() > 0) {
372 m_outputs.push_front(retVal);
375 m_lastOutput = retVal;
389 std::vector<double> m_inputGains;
390 std::vector<double> m_outputGains;
394 inline static int instances = 0;
401 static constexpr int Factorial(
int n) {
405 return n * Factorial(n - 1);
This class implements a linear, digital filter.
Definition LinearFilter.h:76
constexpr LinearFilter(std::span< const double > ffGains, std::span< const double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.h:84
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.h:260
static LinearFilter< T > FiniteDifference(const wpi::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.h:193
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.h:166
constexpr 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.h:328
static constexpr 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.h:150
constexpr void Reset()
Reset the filter state.
Definition LinearFilter.h:273
constexpr T Calculate(T input)
Calculates the next value of the filter.
Definition LinearFilter.h:354
constexpr LinearFilter(std::initializer_list< double > ffGains, std::initializer_list< double > fbGains)
Create a linear FIR or IIR filter.
Definition LinearFilter.h:110
static constexpr 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.h:130
constexpr T LastValue() const
Returns the last value calculated by the LinearFilter.
Definition LinearFilter.h:384
This class is a wrapper around std::array that does compile time size checking.
Definition array.h:26
This is a simple circular buffer so we don't need to "bucket brigade" copy old values.
Definition circular_buffer.h:20
static void ReportUsage(MathUsageId id, int count)
Definition MathShared.h:80
Eigen::Matrix< double, Rows, Cols, Options, MaxRows, MaxCols > Matrixd
Definition EigenCore.h:21
Eigen::Vector< double, Size > Vectord
Definition EigenCore.h:12
constexpr return_t< T > exp(const T x) noexcept
Compile-time exponential function.
Definition exp.hpp:130
constexpr common_t< T1, T2 > pow(const T1 base, const T2 exp_term) noexcept
Compile-time power function.
Definition pow.hpp:82
constexpr empty_array_t empty_array
Definition array.h:16
#define S(label, offset, message)
Definition Errors.h:113