Class BiquadFilter

java.lang.Object
org.wpilib.math.filter.BiquadFilter

public class BiquadFilter extends Object
This class implements a cascade of second-order IIR filter sections (biquads) in Direct Form II Transposed. It is intended for running higher-order filters (Butterworth, Chebyshev, etc.) produced by a filter designer without the numerical instability that direct-form implementations of a single high-order polynomial exhibit.

Each section implements:

  y[n]  = b₀ x[n] + s₁[n-1]
  s₁[n] = b₁ x[n] - a₁ y[n] + s₂[n-1]
  s₂[n] = b₂ x[n] - a₂ y[n]

Sections are normalized so that a₀ = 1 and are applied in series.

For 1st-order IIR filters or simple FIR filters (moving averages, finite differences), prefer LinearFilter and its factory methods — they cover those cases more ergonomically. Use BiquadFilter for high-order IIR cascades.

Note: calculate() should be called by the user on a known, regular period. Like any digital filter, the coefficients are a function of the sample rate they were designed for.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static enum 
    Frequency response shape for the classical IIR design factories.
    static final class 
    A single biquad (second-order) section.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates a biquad filter cascade from the given sections.
  • Method Summary

    Modifier and Type
    Method
    Description
    butterworth(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff)
    Designs a Butterworth IIR low-pass or high-pass filter (single cutoff).
    butterworth(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff)
    Designs a Butterworth IIR band-pass or band-stop filter as a cascade of biquad sections.
    double
    calculate(double input)
    Calculates the next value of the filter.
    chebyshevI(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff, double rippleDb)
    Designs a Chebyshev type-I IIR low-pass or high-pass filter (single cutoff).
    chebyshevI(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff, double rippleDb)
    Designs a Chebyshev type-I IIR band-pass or band-stop filter as a cascade of biquad sections.
    chebyshevII(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff, double stopAttenDb)
    Designs a Chebyshev type-II IIR low-pass or high-pass filter (single cutoff).
    chebyshevII(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff, double stopAttenDb)
    Designs a Chebyshev type-II (inverse Chebyshev) IIR band-pass or band-stop filter as a cascade of biquad sections.
    elliptic(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff, double rippleDb, double stopAttenDb)
    Designs an elliptic (Cauer) IIR low-pass or high-pass filter (single cutoff).
    elliptic(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff, double rippleDb, double stopAttenDb)
    Designs an elliptic (Cauer) IIR band-pass or band-stop filter as a cascade of biquad sections.
    double
    Returns the last value calculated by the BiquadFilter.
    movingAverage(int taps)
    Designs an N-tap moving-average filter as a cascade of FIR biquads.
    notch(double sampleRate, double centerFrequency, double qualityFactor)
    Designs a second-order IIR notch at the given center frequency with the given quality factor.
    int
    Returns the number of sections in the cascade.
    void
    Resets the filter state to zero.
    void
    reset(double value)
    Resets the filter state so that subsequent calls to calculate() with a constant input equal to value immediately return the filter's steady-state response to that input.
    Returns a copy of the cascade's sections, in application order.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • BiquadFilter

      public BiquadFilter(BiquadFilter.Section... sections)
      Creates a biquad filter cascade from the given sections.
      Parameters:
      sections - The biquad sections, applied in series.
      Throws:
      IllegalArgumentException - if sections is empty.
  • Method Details

    • calculate

      public double calculate(double input)
      Calculates the next value of the filter.
      Parameters:
      input - Current input value.
      Returns:
      The filtered value at this step.
    • reset

      public void reset()
      Resets the filter state to zero.
    • reset

      public void reset(double value)
      Resets the filter state so that subsequent calls to calculate() with a constant input equal to value immediately return the filter's steady-state response to that input.
      Parameters:
      value - The constant input value to seed with.
    • lastValue

      public double lastValue()
      Returns the last value calculated by the BiquadFilter.
      Returns:
      The last value.
    • numSections

      public int numSections()
      Returns the number of sections in the cascade.
      Returns:
      The number of sections.
    • sections

      public BiquadFilter.Section[] sections()
      Returns a copy of the cascade's sections, in application order. Useful for inspection, logging, or serialization of designed filters.
      Returns:
      A copy of the section array.
    • butterworth

      public static BiquadFilter butterworth(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff)
      Designs a Butterworth IIR band-pass or band-stop filter as a cascade of biquad sections.

      Coefficients match scipy.signal.butter(order, Wn, btype, fs, output='sos'). BandPass/BandStop outputs are numerically equivalent to scipy but may differ in section ordering / zero pairing; the product response matches.

      Parameters:
      kind - Must be BandPass or BandStop.
      order - Prototype order (>= 1). The cascade has 2*order poles.
      sampleRate - Sample rate (Hz). Must be positive.
      lowCutoff - Low edge of the band (Hz). Must satisfy 0 < lowCutoff < highCutoff < sampleRate/2.
      highCutoff - High edge of the band (Hz).
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is LowPass / HighPass.
    • butterworth

      public static BiquadFilter butterworth(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff)
      Designs a Butterworth IIR low-pass or high-pass filter (single cutoff).

      Coefficients match scipy.signal.butter(order, Wn, btype, fs, output='sos') to within ~1e-10.

      Parameters:
      kind - Must be LowPass or HighPass.
      order - Prototype order (>= 1).
      sampleRate - Sample rate (Hz). Must be positive.
      cutoff - Cutoff frequency (Hz). Must satisfy 0 < cutoff < sampleRate/2.
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is BandPass / BandStop.
    • chebyshevI

      public static BiquadFilter chebyshevI(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff, double rippleDb)
      Designs a Chebyshev type-I IIR band-pass or band-stop filter as a cascade of biquad sections. Equiripple in the passband, monotonic in the stopband. Coefficients match scipy.signal.cheby1(order, rp, Wn, btype, fs, output='sos').
      Parameters:
      kind - Must be BandPass or BandStop.
      order - Prototype order (>= 1). The cascade has 2*order poles.
      sampleRate - Sample rate (Hz). Must be positive.
      lowCutoff - Low edge of the band (Hz). Must satisfy 0 < lowCutoff < highCutoff < sampleRate/2.
      highCutoff - High edge of the band (Hz).
      rippleDb - Peak-to-peak passband ripple in dB. Must be > 0; values from ~0.1 to ~3 dB are typical.
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is LowPass / HighPass.
    • chebyshevI

      public static BiquadFilter chebyshevI(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff, double rippleDb)
      Designs a Chebyshev type-I IIR low-pass or high-pass filter (single cutoff). The cutoff is the frequency at which the response first drops to -rippleDb dB.
      Parameters:
      kind - Must be LowPass or HighPass.
      order - Prototype order (>= 1).
      sampleRate - Sample rate (Hz). Must be positive.
      cutoff - Cutoff frequency (Hz). Must satisfy 0 < cutoff < sampleRate/2.
      rippleDb - Peak-to-peak passband ripple in dB. Must be > 0.
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is BandPass / BandStop.
    • chebyshevII

      public static BiquadFilter chebyshevII(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff, double stopAttenDb)
      Designs a Chebyshev type-II (inverse Chebyshev) IIR band-pass or band-stop filter as a cascade of biquad sections. Monotonic in the passband, equiripple in the stopband. Coefficients match scipy.signal.cheby2(order, rs, Wn, btype, fs, output='sos').
      Parameters:
      kind - Must be BandPass or BandStop.
      order - Prototype order (>= 1). The cascade has 2*order poles.
      sampleRate - Sample rate (Hz). Must be positive.
      lowCutoff - Low edge of the stop band (Hz). Must satisfy 0 < lowCutoff < highCutoff < sampleRate/2.
      highCutoff - High edge of the stop band (Hz).
      stopAttenDb - Stopband attenuation in dB. Must be > 0; values from ~20 to ~80 dB are typical.
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is LowPass / HighPass.
    • chebyshevII

      public static BiquadFilter chebyshevII(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff, double stopAttenDb)
      Designs a Chebyshev type-II IIR low-pass or high-pass filter (single cutoff). The cutoff is the frequency at which the response first reaches stopAttenDb of attenuation.
      Parameters:
      kind - Must be LowPass or HighPass.
      order - Prototype order (>= 1).
      sampleRate - Sample rate (Hz). Must be positive.
      cutoff - Stopband-edge frequency (Hz). Must satisfy 0 < cutoff < sampleRate/2.
      stopAttenDb - Stopband attenuation in dB. Must be > 0.
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is BandPass / BandStop.
    • elliptic

      public static BiquadFilter elliptic(BiquadFilter.Kind kind, int order, double sampleRate, double lowCutoff, double highCutoff, double rippleDb, double stopAttenDb)
      Designs an elliptic (Cauer) IIR band-pass or band-stop filter as a cascade of biquad sections. Equiripple in both passband and stopband — the steepest transition for a given order, at the cost of ripple everywhere. Coefficients match scipy.signal.ellip(order, rp, rs, Wn, btype, fs, output='sos').
      Parameters:
      kind - Must be BandPass or BandStop.
      order - Filter order (>= 1).
      sampleRate - Sample rate (Hz). Must be positive.
      lowCutoff - Low edge of the band (Hz). Must satisfy 0 < lowCutoff < highCutoff < sampleRate/2.
      highCutoff - High edge of the band (Hz).
      rippleDb - Passband ripple in dB (> 0).
      stopAttenDb - Stopband attenuation in dB (must exceed rippleDb).
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is LowPass / HighPass.
    • elliptic

      public static BiquadFilter elliptic(BiquadFilter.Kind kind, int order, double sampleRate, double cutoff, double rippleDb, double stopAttenDb)
      Designs an elliptic (Cauer) IIR low-pass or high-pass filter (single cutoff). The cutoff is the frequency at which the response first drops to -rippleDb dB.
      Parameters:
      kind - Must be LowPass or HighPass.
      order - Filter order (>= 1).
      sampleRate - Sample rate (Hz). Must be positive.
      cutoff - Cutoff frequency (Hz). Must satisfy 0 < cutoff < sampleRate/2.
      rippleDb - Passband ripple in dB (> 0).
      stopAttenDb - Stopband attenuation in dB (must exceed rippleDb).
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if any argument is out of range or kind is BandPass / BandStop.
    • notch

      public static BiquadFilter notch(double sampleRate, double centerFrequency, double qualityFactor)
      Designs a second-order IIR notch at the given center frequency with the given quality factor. Matches scipy.signal.iirnotch.
      Parameters:
      sampleRate - Sample rate (Hz). Must be positive.
      centerFrequency - Notch center frequency (Hz). Must satisfy 0 < centerFrequency < sampleRate/2.
      qualityFactor - Quality factor (Q). Higher values give a narrower notch. Must be positive.
      Returns:
      The designed filter (single-section cascade).
      Throws:
      IllegalArgumentException - if any argument is out of range.
    • movingAverage

      public static BiquadFilter movingAverage(int taps)
      Designs an N-tap moving-average filter as a cascade of FIR biquads.

      Each section has a1 = a2 = 0 (all poles at the origin). The total gain 1/taps is folded into the first section's numerator so the DC gain of the cascade is 1.

      Parameters:
      taps - Length of the moving-average window. Must be >= 1.
      Returns:
      The designed filter.
      Throws:
      IllegalArgumentException - if taps < 1.