filters
Index
Robotics / filter and estimator
IIR low past filter
first-order IIR low-pass filter, also called an exponential moving average
It keeps mostly the slow trend (low frequencies) and suppresses fast changes (high frequencies).
\[y[n] = (1 - \alpha) \cdot x[n] + \alpha \cdot y[n-1]\]
x[n] → new input sample
y[n] → filtered output
y[n−1] is the previous output
α → smoothing factor (0–1)
alfa
smoothing factor between (0–1)
If α is small (e.g. 0.1), the filter reacts quickly to new changes (less smoothing).
If α is large (e.g. 0.9), the filter reacts slowly, producing a smoother result.
Demo
import numpy as np
import matplotlib.pyplot as plt
# Simulated noisy signal
t = np . linspace ( 0 , 2 * np . pi , 200 )
x = np . sin ( t ) + 0.5 * np . random . randn ( len ( t ))
# Exponential Moving Average (IIR LPF)
alpha = 0.9
y = np . zeros_like ( x )
for i in range ( 1 , len ( x )):
y [ i ] = ( 1 - alpha ) * x [ i ] + alpha * y [ i - 1 ]
plt . figure ( figsize = ( 10 , 5 ))
plt . plot ( t , x , label = "Noisy Signal" )
plt . plot ( t , y , label = f "IIR Low-pass (alpha= { alpha } )" , linewidth = 2 )
plt . legend ()
plt . show ()
Simple moving average
It smooths a signal by taking the average of the last N samples:
\[y[n] = \frac{1}{N} \sum_{k=0}^{N-1} x[n-k]\]
SMA is great for smoothing sensor readings like distance sensors or temperature, but not ideal for real-time fast response (since it introduces delay).
Demo
import numpy as np
import matplotlib.pyplot as plt
from collections import deque
class MovingAverage :
def __init__ ( self , window_size ):
self . window_size = window_size
self . buffer = deque ( maxlen = window_size )
self . sum = 0.0
def update ( self , new_value ):
if len ( self . buffer ) == self . window_size :
self . sum -= self . buffer [ 0 ]
self . buffer . append ( new_value )
self . sum += new_value
return self . sum / len ( self . buffer )
# Generate noisy signal (simulate stream)
t = np . linspace ( 0 , 4 * np . pi , 200 )
signal = np . sin ( t ) + 0.5 * np . random . randn ( len ( t ))
# Apply streaming moving average
ma = MovingAverage ( window_size = 5 )
ma_15 = MovingAverage ( window_size = 15 )
filtered = []
filtered2 = []
for x in signal :
y = ma . update ( x )
filtered . append ( y )
y2 = ma_15 . update ( x )
filtered2 . append ( y2 )
# Plot results
plt . figure ( figsize = ( 10 , 5 ))
plt . plot ( t , signal , label = "Noisy Signal" , alpha = 0.6 )
plt . plot ( t , filtered , label = "Streaming SMA (window=5)" , linewidth = 2 )
plt . plot ( t , filtered2 , label = "Streaming SMA (window=15)" , linewidth = 2 )
plt . legend ()
plt . show ()
The code implementation return the average event if the window buffer not full
Resource