Filtering API
skelarm.filtering
From-scratch smoothing filters for noisy reference trajectories.
A hand-taught or coarsely sampled reference is often jagged; differentiating it for a velocity/acceleration reference then amplifies the noise. These low-pass filters smooth a uniformly sampled series before resampling/differentiation. They are implemented without SciPy:
lowpass_first_order— a one-pole RC/exponential filter.butterworth_lowpass— an order-nButterworth filter built from its analog prototype poles via the bilinear transform.
Both are applied zero-phase (forward then backward) so the smoothed signal is not
time-shifted, and both are seeded with steady-state initial conditions so a constant
(DC) signal passes through unchanged. A series may be 1-D (N,) or multi-column
(N, k) (filtered column-wise).
See docs/reference/09_trajectory_filtering.md for the theory.
FILTERS = ('none', 'lowpass', 'butterworth', 'moving_average', 'savgol')
module-attribute
The supported filter kinds for :func:smooth.
butterworth_lowpass(values, dt, *, cutoff_hz, order=2)
Zero-phase Butterworth low-pass filter of the given order.
Designs the digital filter from the analog Butterworth poles (bilinear transform
with frequency pre-warping) and applies it forward-and-backward (filtfilt-style)
with reflected edge padding and steady-state initial conditions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ArrayLike
|
Series of shape |
required |
dt
|
float
|
Sample period (s). |
required |
cutoff_hz
|
float
|
Cutoff frequency (Hz); must be below the Nyquist |
required |
order
|
int
|
Filter order ( |
2
|
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
The smoothed series, same shape as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/skelarm/filtering.py
lowpass_first_order(values, dt, *, cutoff_hz)
Zero-phase one-pole (RC) low-pass filter.
Applies the exponential recursion y[i] = y[i-1] + a (x[i] - y[i-1]) forward and
backward, with a = dt / (RC + dt) and RC = 1 / (2 pi cutoff_hz). Seeded at
the boundary sample so a constant input is preserved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ArrayLike
|
Series of shape |
required |
dt
|
float
|
Sample period (s). |
required |
cutoff_hz
|
float
|
Cutoff frequency (Hz). |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
The smoothed series, same shape as |
Source code in src/skelarm/filtering.py
moving_average(values, *, window)
Centered (zero-phase) moving-average filter over an odd window of samples.
Each output is the mean of the window samples centered on it; a symmetric window
introduces no phase shift and reproduces constants and linear trends in the interior.
The signal is reflected at the boundaries so the window stays full near the edges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ArrayLike
|
Series of shape |
required |
window
|
int
|
Window length in samples; must be odd and positive. |
required |
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
The smoothed series, same shape as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/skelarm/filtering.py
savitzky_golay(values, *, window, polyorder=2)
Zero-phase Savitzky-Golay filter: a least-squares polynomial fit over a sliding window.
Each output is the value at the center of a degree-polyorder polynomial fit to the
window samples around it. The symmetric kernel is phase-free and reproduces
polynomials up to polyorder exactly in the interior, so it smooths noise while
preserving peaks better than a plain average. The signal is reflected at the boundaries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ArrayLike
|
Series of shape |
required |
window
|
int
|
Window length in samples; must be odd and greater than |
required |
polyorder
|
int
|
Polynomial order fit in each window. |
2
|
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
The smoothed series, same shape as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in src/skelarm/filtering.py
smooth(values, dt, *, kind='none', cutoff_hz=None, order=2, window=None, polyorder=2)
Smooth a uniformly sampled series by the named filter kind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ArrayLike
|
The series, shape |
required |
dt
|
float
|
Sample period in seconds (the series must be uniformly sampled). |
required |
kind
|
str
|
One of :data: |
'none'
|
cutoff_hz
|
float | None
|
Cutoff frequency in Hz; required for |
None
|
order
|
int
|
Butterworth order (ignored otherwise); keep small ( |
2
|
window
|
int | None
|
Window length in samples (odd); required for |
None
|
polyorder
|
int
|
Savitzky-Golay polynomial order ( |
2
|
Returns:
| Type | Description |
|---|---|
NDArray[float64]
|
The smoothed series, same shape as |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |