Demo — Bearings-Only Tracker#
One aircraft, one radar-warning receiver, and a pop-up emitter nobody put on the laydown. Every few seconds the RWR reports a bearing — a direction, never a distance — and an extended Kalman filter (EKF) folds it into its estimate of where the emitter is. This demo runs that filter over a five-minute leg and shows you what the bearings can and cannot tell it: the error ellipse collapses when the geometry lets it, and stays a long sliver along the line of sight when it does not.
The model#
The own-ship flies East at 250 m/s from the origin for 300 s, either on a straight leg or on a dogleg that turns by a chosen angle at a chosen time. The emitter is either stationary or moving at a constant 15 m/s, and starts either off the route (40 km North, 55 km East) or dead ahead on the own-ship’s track (120 km East). Intel’s planning prior puts it 8 km short of its true position along the first line of sight and 4 km to the right, with \(\sigma = 8\) km on each axis (and \(0 \pm 0.05\) km/s on each velocity component for the moving emitter).
Each bearing is the true direction plus Gaussian noise of standard deviation \(\sigma_\theta\):
The filter predicts with \(F = I\) for a stationary emitter and a constant-velocity \(F\) for a moving one (\(Q = 0\) in both, because the emitter really does behave that way), then updates with L33’s bearing row evaluated at its own estimate:
The whole run is computed first, from the scenario and the random seed. Run, Step and the scrubber only reveal it — so the six tiles, which report the end of the run, never change while it animates. A notional 40 km threat ring around the emitter shows what each maneuver costs: the red stretch of the track, and the red band on the chart, are the time spent inside it.
Interactive demo#
Walkthrough#
The four preset chips tell the lesson’s story in order. The numbers below are for the defaults — \(\sigma_\theta = 1^\circ\), one bearing every 5 s (60 bearings), seed 1; Re-roll noise changes them a little, never the story.
Stationary. Press Run. The intel prior starts as an 8 km circle (\(\sqrt{\operatorname{tr} P} = 11.3\) km). The first bearings squash it across the line of sight; then, as the own-ship flies past and the bearing swings, it shrinks along the line of sight too. By the end \(\sqrt{\operatorname{tr} P} = 0.28\) km, and the estimate is 0.15 km from the truth. Turn on Zoom ×5 to see an ellipse that small. No maneuver was needed: the leg itself was the baseline.
Dead ahead. Now the emitter sits on the own-ship’s track, and the bearing never changes. The ellipse becomes a needle along the track — 7.89 × 0.14 km, its long axis 0° off the line of sight — and the estimate is still 7.6 km out in range, exactly where the prior left it. Every line of position is the same line.
Moving. Back off the route, but the emitter now moves at constant velocity while the own-ship flies straight and steady. The ellipse stays long along the line of sight (4.48 × 0.27 km) and the \(\sqrt{\operatorname{tr} P}\) curve on the chart flattens instead of diving. Slide the update rate to 1 Hz: five times the bearings bring the thin axis down to 0.13 km and leave the long one where it was. A scaled “ghost” of the emitter’s track fits every bearing just as well, so better or faster bearings cannot find range.
Moving + dogleg. The own-ship turns 90° left at 90 s. Watch the chart: the \(\sqrt{\operatorname{tr} P}\) curve leaves the straight-leg plateau right after the turn line and ends at 0.63 km. Now read the Exposure tile: 143 s inside the 40 km ring, starting at 157 s — the red band on the chart. That is the price of the fix.
Turn the other way. Drag Turn angle to 90° right. The exposure drops to zero and \(\sqrt{\operatorname{tr} P}\) climbs to 12.8 km: turning away from the emitter opens the range and barely changes the bearing rate, so it buys almost nothing. Try the angles in between, and a later or earlier turn, and watch the two tiles trade against each other.
The turn you did not need. Pick Stationary and switch to Dogleg. The ellipse ends at 0.26 km — no better than the straight leg’s 0.28 — and the aircraft spent 143 s in the ring to get it. For an emitter that was already observable, the maneuver was pure cost.
Two failure modes are worth seeing once. With the moving emitter on a straight leg, drive \(\sigma_\theta\) down to 0.2° and the rate to 1 Hz: the Error tile turns red because the actual error (6.4 km) has run well past three times the filter’s claimed \(\sqrt{\operatorname{tr} P}\) (2.1 km). Linearizing at a wrong estimate has let the EKF invent range information the geometry never supplied — on the chart, the error curve rides above the \(\sqrt{\operatorname{tr} P}\) curve. And a turn that points the own-ship straight down the line of sight (for the stationary emitter, 45° left at 60 s) flies over the emitter; when the estimate comes within 1 km of the own-ship the filter skips those updates, and the map says so.
Key observations#
A bearing measures direction. Each update shrinks the ellipse across the line of sight only; range has to come from a change in geometry.
A stationary emitter off the route is observable from a straight leg — the leg is the baseline. Dead ahead, it is not.
A moving emitter seen from a straight, steady own-ship has unobservable range, however accurate or frequent the bearings. A maneuver breaks the ambiguity.
Seeing costs exposure. The turns that collapse the ellipse fastest swing the line of sight and close the range — and those are the turns that spend time inside the threat’s ring.
Check the filter against the truth. A small \(\sqrt{\operatorname{tr} P}\) on a geometry that should not have produced one is the EKF fooling itself.
Source#
MATLAB bundle · L35_BearingsOnlyEKF.m↓
The companion script runs the same scenario and the same filter, line for line, in three cases — a stationary emitter from a straight leg, the moving emitter from a straight leg, and the moving emitter with the 90° dogleg at 90 s — and plots \(\sqrt{\operatorname{tr} P}\) against time for all three. It draws its own noise with rng(35), so its numbers differ slightly from the demo’s seed 1 (0.28, 4.26 and 0.62 km), and it ends by printing the exposure each leg costs inside the 40 km ring: 0 s straight, 143 s with the dogleg.