Skip to main content
The EWMA (Exponentially Weighted Moving Average) filter automatically adjusts smoothing strength to minimize lag when moving and minimize noise when still. It’s an excellent general-purpose filter that requires minimal tuning.

How It Works

The EWMA filter uses delta filtering and noise variance detection to distinguish intentional movement from sensor noise:
  1. Delta filtering: Smooths the rate of change over the last 1/60 second (16ms)
  2. Noise estimation: Tracks average noise variance over the last 60 seconds
  3. Adaptive smoothing: Scales filtering from maxSmooth to minSmooth based on detected motion

Algorithm

The filter compares current delta to historical noise statistics:
As the delta increases from 0 to 3 standard deviations of the noise, the filtering scales down from maxSmooth to minSmooth at a rate controlled by smoothing_scale_curve.
The EWMA filter automatically adapts to your tracking environment over the first ~60 seconds. No manual calibration is required.

Parameters

The EWMA filter has only three parameters, making it easy to configure:
slider
default:"0.02"
Minimum smoothing during fast movement.
  • Lower values: Faster response, more visible jitter during motion
  • Higher values: More smoothing even during fast movements, increased lag
Default: 0.02 (2%)
slider
default:"0.7"
Maximum smoothing when stationary or moving slowly.
  • Lower values: Less jitter reduction when still, faster initial response
  • Higher values: Maximum jitter suppression, slower initial response
Default: 0.7 (70%)
The filter ensures max_smoothing >= min_smoothing automatically.
slider
default:"0.8"
Shape of the transition from max to min smoothing.
  • Lower values (< 1.0): Opens up earlier, more immediate feel
  • Higher values (> 1.0): Keeps heavy smoothing longer during motion
Default: 0.8This is the exponent applied to norm_noise in the smoothing calculation:

Tuning Guide

For Simulators and Precision Work

Maximize smoothness when stationary:
  • Very low min_smoothing (0.01) for minimal lag during intentional movement
  • High max_smoothing (0.9) for maximum jitter reduction when still
  • Curve > 1.0 keeps heavy smoothing applied longer during small motions

For Fast Action Games

Minimize lag while maintaining some smoothing:
  • Higher min_smoothing (0.05) ensures some smoothing even during fast turns
  • Lower max_smoothing (0.5) reduces lag when starting to move
  • Curve < 1.0 opens up quickly as soon as motion is detected

General Purpose (Default)

Balanced for most use cases:

How Noise Detection Works

The EWMA filter builds a statistical model of your tracking noise:
1

Measure instantaneous delta

Calculate the difference between input and last output for each axis.
2

Smooth delta over 1/60 sec

Apply fast exponential smoothing to the delta itself:
This removes very high-frequency noise components.
3

Track variance over 60 sec

Build a long-term estimate of noise variance:
This converges to the typical noise level of your tracker.
4

Normalize current noise

Compare instantaneous noise to historical variance:
  • 0.0 = noise within expected bounds (probably stationary)
  • 1.0 = noise 3+ standard deviations above normal (intentional movement)
5

Calculate adaptive alpha

Map normalized noise through the curve to determine smoothing:
The filter takes approximately 60 seconds to converge to accurate noise statistics after startup. During this period, noise_RC gradually increases from 0 to 60 seconds.

Implementation Details

Time Constants

The filter uses two time constants:
  • delta_RC: Fast response for instantaneous motion detection
  • noise_RC_max: Slow convergence for stable noise statistics

Angle Wrap-Around

Rotation angles (Yaw, Pitch, Roll) crossing ±180° are handled automatically:
This prevents discontinuities when your head rotates through North.

State Reset

When recentering, the filter resets its state:
On the next frame:
  • noise_RC resets to 0
  • Output jumps to current input
  • Delta and noise arrays clear
After recentering, the filter needs ~60 seconds to rebuild accurate noise statistics. You may experience suboptimal smoothing during this convergence period.

Comparison to Other Filters

Use EWMA if:
  • You want automatic adaptation without manual tuning
  • You have a consistent tracking environment
  • You prefer simplicity over maximum control
Use Alpha Spectrum if:
  • You need predictive filtering for extremely low latency
  • You want separate control over rotation vs translation
  • You’re willing to tune advanced parameters
  • You need real-time status monitoring

Troubleshooting

  • Decrease max_smoothing to 0.5 or lower
  • Decrease smoothing_scale_curve to open up faster
  • Consider switching to Accela filter for velocity-based response
  • Increase max_smoothing to 0.8 or 0.9
  • Wait for full convergence (~60 seconds)
  • Check tracker mounting and lighting conditions
  • Verify noise isn’t from external vibration (fans, desk movement)
This is normal behavior. The filter needs ~60 seconds to rebuild noise statistics after recentering.If this is problematic, consider using Hamilton or Alpha Spectrum which don’t require convergence time.
The EWMA filter applies the same parameters to all 6 axes (X, Y, Z, Yaw, Pitch, Roll).If you need independent control, use Alpha Spectrum which has separate rotation and translation parameters.

Code Reference

Relevant source files:
  • Implementation: filter-ewma2/ftnoir_filter_ewma2.cpp
  • Header/settings: filter-ewma2/ftnoir_filter_ewma2.h
  • Dialog: filter-ewma2/ftnoir_filter_ewma2_dialog.cpp

Key Implementation Lines

Noise normalization (ftnoir_filter_ewma2.cpp:74):
Smoothing calculation (ftnoir_filter_ewma2.cpp:76-77):
Dynamic alpha (ftnoir_filter_ewma2.cpp:79):

Next Steps

Filter Overview

Compare all available filters

Alpha Spectrum

Advanced filter with predictive heads

Hamilton Filter

Quaternion-based smooth rotations

Accela Filter

Velocity-dependent acceleration filtering