Skip to content

Motion Smoothing

Ravi Singh edited this page May 7, 2026 · 1 revision

Motion Smoothing

The motion smoother sits between raw radar frames and the LED render, turning a noisy stream of distance readings into a smooth-feeling tracked target.

Why it matters

Raw LD2450 output is noisy:

  • Distance jumps ±5–10 cm even for a stationary target due to micro-motion (breathing, hand gestures).
  • Occasional outlier frames at 0 cm or near the max range when the radar momentarily loses lock.
  • Multiple targets get reported in parallel, and which one is "primary" can switch frame-to-frame.

Without smoothing, the LED cluster stutters, jumps to wrong positions, and feels broken.

Two smoothers

v6.x ships two algorithms. Pick from Motion tab → Mode.

Kalman (recommended)

A 1-D Kalman filter that tracks both position and velocity. Three intuitive knobs:

Knob Range What it does
Response 0–100 How fast the smoother adapts to a new measurement. Higher = faster but noisier.
Look-ahead (ms) 0–500 Predict the position N ms from now using the velocity estimate. Compensates for the ~50 ms render latency.
Outlier rejection 0–100 How aggressively to reject single-frame jumps as noise. Higher = more rejections.

The Kalman filter internally maintains:

  • pos — estimated position (cm)
  • vel — estimated velocity (cm/s)
  • cov — uncertainty matrix

On each new measurement:

  1. Predict — advance pos by vel × dt; inflate uncertainty.
  2. Innovation — measure the new reading vs predicted reading.
  3. Outlier check — if innovation > N × √cov, reject the measurement.
  4. Update — if accepted, blend prediction with measurement weighted by uncertainty.
  5. Outputpos + look_ahead × vel is what gets published to the LED render.

PI smoother (legacy v5)

A simpler position+velocity EMA pair with PI feedback. Carried forward from v5 for users who'd already tuned it. Five knobs:

Knob What it does
Position smoothing × 1/1000 EMA alpha for position
Velocity smoothing × 1/1000 EMA alpha for velocity
Prediction factor × 1/1000 How much velocity contributes to predicted output
P gain × 1/1000 Proportional response to position error
I gain × 1/1000 Integral correction for drift

In Kalman mode the Response knob replaces the P/I gains; in PI mode it's not used.

Tuning recipes

"The lights feel laggy / behind me"

You're feeling the system's render latency. Two fixes:

  • Raise Look-ahead to 150–200 ms.
  • Raise Response by 10–15 points.

If both are maxed and it's still laggy, you're at the limit of what the LD2450's frame rate (~10 Hz) supports. v6.x is pushing this about as hard as it goes on a single-sensor setup.

"The lights are jittery / flicker between positions"

Too much noise getting through. Three fixes:

  • Lower Response by 10–15 points.
  • Raise Outlier rejection to 75–85.
  • Check the Hardware → Radar diagnostic — if the byte count is steady but frames-parsed is flat, something's wrong with the radar wiring (check baud, TX/RX cross).

"The lights jump to the far end of the strip occasionally"

Outliers slipping through. Fixes:

  • Raise Outlier rejection to 85+.
  • If you're on PI smoother mode, swap to Kalman.
  • Check the radar mounting — strong reflections from a metal surface in the room can cause LD2450 to occasionally report wildly wrong distances.

"The lights don't move at all when I do"

System is over-smoothed:

  • Raise Response to 70+.
  • Lower Outlier rejection to 50.
  • Confirm raw radar is updating (Hardware → Radar diagnostic → frames parsed should climb).

Live raw vs smoothed chart

The Motion tab includes a two-line chart:

  • Grey line: raw radar reading (median-filtered for visibility but un-smoothed).
  • Orange line: what the smoother is publishing to the LED engine.

What good tuning looks like:

  • Orange follows grey closely with a brief lag (~50 ms).
  • Outliers in grey (sudden jumps) don't appear in orange.
  • When you stop moving, both lines converge to a flat horizontal value.

If orange is much smoother than grey but the smoothed value is consistently behind your actual position by a visible amount, raise Look-ahead.

If orange is identical to grey, smoothing is effectively off — raise Response towards 50+.

If orange is a flat line that occasionally jumps, you've over-smoothed and outlier rejection is masking real motion as noise.

Defaults

The shipped defaults are tuned for typical hallway / stair installs:

Knob Default
Mode Kalman
Response 60
Look-ahead 100 ms
Outlier rejection 70

Most users never touch these. If you do, write down the values you settle on — Motion tab settings are saved to NVS but a factory reset wipes them.

Beyond the UI

Motion smoother values live in NVS namespace motion. You can set them via the API:

curl -X POST http://ambisense-XXXX.local/api/settings \
  -H "Content-Type: application/json" \
  -d '{"response": 65, "look_ahead_ms": 150, "outlier_strength": 80}'

Source code: firmware/components/motion/motion_kalman.c for Kalman, motion.c for PI.

Clone this wiki locally