Kalman 1D Filter
A Kalman filter keeps a running estimate of a noisy signal. Each tick it does two things: predict what it expects next, then correct using the actual measurement. The gap between prediction and measurement is called the innovation — when it is small, the filter’s model is working; when it is large, something unexpected happened.
Smoothing and Outlier Detection
The signal below is a noisy sensor reading with a few sudden spikes and a step change partway through. The filter smooths the noise while the innovation gate flags samples that are too far from what it predicted.
Parameters — drag the sliders and watch the chart respond:
processVariance— how much the signal can change between ticks beyond what the model predicts. Low = smooth estimate, high = responsive.sensorVariance— how noisy the sensor is. High = trust the prediction more than the measurement.chi2Threshold— how large the prediction error must be before flagging an outlier. 3.84 = 95% confidence, 6.63 = 99%.followMode— Exclude ignores the outlier and continues from the prediction. Follow resets to the measurement — use this for real step changes, not sensor faults.
Try this:
- Set
chi2Thresholdlow (~3) and watch false alarms multiply. - Switch
followModeto Follow and see the filter track the step change at sample 200 instantly instead of slowly converging. - Drag
processVarianceto 0.5 — the filter follows every wiggle. Then drag it to 0.001 — it barely moves.
Adding a Known Input
The demo above treats the filter as a smoother — it has no idea why the signal changes, only that it does. But when you can tell the filter about a known influence on the signal, it becomes something more powerful: a diagnostic tool that reveals hidden faults.
The setup
A forklift battery on a factory floor. Two sensors feed data to Composer every minute:
- A current sensor on the main bus reports discharge amps.
- The BMS reports State of Charge (%) from voltage measurements.
| Assumption | Value | Why |
|---|---|---|
| Battery capacity | 100 Ah | Standard forklift traction battery |
| Sampling interval | 60 s | BMS reports once per minute |
| Normal discharge | 8 A | Light duty — driving between stations |
| BMS noise | σ ≈ 0.1% SoC | Voltage-based estimate with averaging |
The filter uses the current reading to predict how much SoC should change each tick — simple coulomb counting. Then it corrects using the BMS measurement. For a healthy battery, prediction and measurement agree — innovation hovers near zero.
Composer parameters for this scenario
| Parameter | Value | What it means here |
|---|---|---|
controlModel | 0.0167 | Amps → SoC%/tick: 60 / (100 × 3600) × 100. At 8A, the filter predicts 0.133% SoC drop per tick. |
processVariance | 0.05 | How much SoC can change per tick beyond what coulomb counting predicts. A tuning knob: low = smooth, high = responsive. |
sensorVariance | 0.01 | BMS noise variance (σ² = 0.1²). Fixed in the demo — Composer defines processVariance as a ratio relative to sensorVariance, so changing one without the other has no effect on the filter. |
The fault — parasitic drain
A hydraulic valve controller has a wiring fault and draws 5A continuously, but this load sits downstream of the current sensor — the sensor cannot see it. Every tick, the filter predicts based on the 8A it can see. But the BMS, measuring voltage, reflects the actual charge level, which is dropping as if 13A were flowing.
The innovation drifts negative: the BMS consistently reads lower than what the current alone would predict. That persistent bias is the diagnostic signal.
Drag controlModel to zero and watch the filter lose its ability
to separate the drain from normal operation.
What you’re seeing
The first 200 ticks are normal — the current sensor sees all the discharge, prediction matches reality, innovation fluctuates around zero. At tick 200 a hidden load appears. The current sensor still reads the same, but the BMS sees the extra drain. Innovation develops a persistent negative bias — the filter keeps predicting higher than reality.
Drag controlModel to zero and innovation becomes noisy in both
halves. You can no longer tell where the fault starts. The control
input is what makes the diagnostic possible.
What else the innovation reveals
Different faults produce different innovation signatures:
-
Capacity fade — the battery ages and its usable capacity drops, but the model still assumes the original rating. The filter underestimates each tick’s SoC change. Innovation drifts negative, and the bias grows with load — worse during heavy discharge, smaller during light use.
-
Current sensor drift — the sensor develops a constant offset and reads high. Now the filter overestimates the drain each tick. Innovation flips positive — the BMS consistently reads higher than predicted. That opposite sign points toward a calibration problem, not a battery problem.
kalman1d Quick Reference
All parameters with their defaults. The demos above expose the highlighted ones as sliders.
| Parameter | Default | What it controls |
|---|---|---|
sensorVariance | 1 | Measurement noise variance. Match to your sensor’s σ². |
processVariance | 0.01 | Ratio of process noise to sensor noise. Higher = more responsive, lower = smoother. |
chi2Threshold | 6.63 | Innovation gate threshold. 3.84 = 95%, 6.63 = 99%, 10.84 = 99.9% confidence. |
followMode | false | false = reject outliers (exclude). true = track step changes (follow). |
controlModel | 0 | Scales the control input. Zero = no control input. |
control | — | Name of the message field carrying the control signal (e.g. 'current'). |
stateTransition | 1 | How the state evolves between ticks. 1 = constant (random walk). |
measurement | 1 | How the state maps to the sensor reading. 1 = direct observation. |
varianceLimit | 100 | Caps uncertainty growth during gaps. Maximum variance = varianceLimit × sensorVariance. |
References
- R. E. Kalman, “A New Approach to Linear Filtering and Prediction Problems,” Journal of Basic Engineering, 82(1), pp. 35—45, 1960. doi:10.1115/1.3662552
Next Steps
- Detecting Sudden Shifts —
a complete recipe that uses
kalman1dwithsanitizeandmedian3for step-change detection. - Under the Hood — how messages flow through a Composer pipeline at runtime.