Software · Controls

Signal Filter Lab

Real sensors are noisy. A filter cleans up the reading, but every filter makes your code find out about real changes a little later. Turn filters on, change their settings, and measure what you gain and what you pay.

Distance sensor

What each filter costs

In robot code

Updates with your settings

      

Make the filter once (a field), then call calculate() exactly once every loop. These filters assume they are called every 20 ms. Call it twice a loop, or skip loops, and the timing is wrong.

Things to try

  1. Average vs. median. On Distance, turn spikes up to 2 per second. The moving average turns each spike into a bump. The median filter throws most spikes away and still keeps the step sharp.
  2. Lag grows with smoothing. Drag moving-average taps from 5 to 50. "Time to 90%" goes from about 80 ms to about 880 ms. A robot that waits almost a second to notice a change will feel slow.
  3. Our current filter. On Current, set the IIR time constant to 0.10 s. That is the exact LinearFilter.singlePoleIIR(0.1, 0.02) MW-Lib uses on motor current. Raise the noise and watch the raw threshold flicker while the IIR stays steady.
  4. Rising vs. falling. On Beam break, switch the Debouncer between Rising, Falling and Both. Look at the "Delay on / off" column: Rising only delays turning on, Falling only delays turning off.
  5. Miss a fast piece. Set "Piece blocks the beam for" to 0.20 s and the Debouncer to Rising 0.30 s. The code never sees the piece. Debounce time must be shorter than the shortest real signal.
  6. Slew rate is not a smoother. On Joystick, turn noise up. The slew rate limiter still passes small jitter straight through. It only limits how fast the value can change, so it is for driver inputs and setpoints, not for noise.

Where our code uses these

  • MW-Lib mechanisms (arm, elevator, roller, flywheel) smooth motor current with LinearFilter.singlePoleIIR(0.1, 0.02).
  • The 2026 shooter smooths flywheel speed with singlePoleIIR(0.15, 0.02).
  • "Shooter ready" uses new Debouncer(0.1, DebounceType.kRising): flywheel, hood and heading must all be on target for 0.1 s.
  • "Is shooting" uses new Debouncer(0.65, DebounceType.kFalling): it stays true for 0.65 s after the flywheel speed dip ends.
  • Motor, gyro and battery "connected" flags use new Debouncer(0.5) (Rising is the default), so one bad packet does not raise an alert.
  • The launch calculator averages hood angle over 0.1 s and heading over 0.8 s with LinearFilter.movingAverage(...).
  • Swerve teleop limits speed changes with MW-Lib's DynamicSlewRateLimiter (a SlewRateLimiter whose limit can change), 40 m/s² by default.

The Signal Filtering page also covers the Kalman filter, which mixes several sensors into one estimate. That is what WPILib's pose estimator does. Try it in the Pose Estimator Lab.