Skip to content

20260907 - Default the Doppler span to +/-300 Hz and let it reach deployed nodes - #36

Merged
Purple10101 merged 1 commit into
mainfrom
20260907-doppler-span-300
Sep 7, 2026
Merged

Purple10101 merged 1 commit into
mainfrom
20260907-doppler-span-300

Conversation

@Purple10101

Copy link
Copy Markdown
Collaborator

Ticket: https://app.clickup.com/t/123zgec0m7t

Why

owl was widened to +/-1000 Hz on 2026-08-11 to catch a 402 m/s target that sat at -674 Hz when the node ran at fc 503 MHz. At 213 MHz that same target appears at 286 Hz, so the window that justified +/-1000 now costs 265 ms/CPI to cover speeds nothing flies at. +/-300 Hz reaches ~+/-422 m/s for +42 ms/CPI span-attributable, measured over 74 CPIs on owl.

Doppler span costs no resolution: bin spacing is pinned at 1/CPI and the span sets bin count, paid out of nCorr = fs/dopplerSpan. At +/-300 against +/-200 the real costs are ~0.4 dB more far-range integration loss at delay bin 400 (nCorr falls 4975 -> 3322, deepening the linear-correlation taper) and 1.5x the raw CFAR false alarms, before centroiding and the minDoppler gate.

The part that is not just a config edit

Changing default.yml alone would have reached nothing. The merger seeds user.yml with a whole copy of default.yml on first boot, so every node that has ever booted holds the shipped span in its own overlay, which wins over defaults.

migrate_doppler_span drops the pair from the overlay when it is exactly the +/-200 that used to ship, so the default shows through. It follows migrate_gain_reduction in kind and differs in three ways:

  • It tests both bounds together. -200/1000 or -200/400 is somebody's decision and is kept whole. owl's -1000/1000 survives untouched.
  • It deletes rather than rewrites, so the value lives in default.yml alone and the next span change needs no merger edit.
  • It runs before the user merge rather than after the forced one, so forced.yml keeps the last word.

A node that deliberately chose +/-200 cannot be told apart from a first-boot copy, so it moves too and has to be set again.

user.yml on disk is left alone, which makes this function load-bearing rather than one-shot: remove it and those nodes fall back to the +/-200 their overlay still holds. test_doppler_span_migration_does_not_rewrite_user_yml pins that. It also means rollback is clean: redeploy the previous merger image and a migrated node returns to +/-200 by itself.

Verification

30/30 merger tests pass, 7 new covering the guard table above.

Deployed to owl and verified live on 2026-09-07, running against the node's real files inside the released retina-config-merger:v0.4.5.0 image with this script mounted in:

  • Guard, against owl's actual +/-1000 overlay: passes through untouched.
  • Migration, against that file with +/-200 in it: Dropping first-boot Doppler span (-200/200 Hz), output +/-300, overlay on disk unchanged.
  • Full flattened diff of the merged config against owl's running config: exactly two keys move. tar1090.env and retina-tracker.yaml regenerate identical.
  • Running radar: 301 Doppler bins, axis -300.02 to +300.02 Hz. The off-round extent confirms the arithmetic, since nCorr 3322 gives a true CPI of 0.499961 s and 2.000156 Hz spacing.
  • Timing over 10 live samples tracks the bench figures: ambiguity 141.5 vs 154.6, detector 29.1 vs 29.6, output 35.0 vs 35.1.
  • 150 CPIs sampled: 77 of 230 detections fell outside +/-200 Hz, max 297.8 Hz. Treat that as evidence the window is doing work, not as 77 aircraft: the outside-band share matches the band's share of the axis, and owl's ADS-B overlay is wrong-region so no truth association was possible.

Found while deploying, and it shapes the rollout: restarting blah2 was followed ~70 s later by the whole stack restarting, which re-ran the released merger and overwrote a hand-generated config.yml seconds before blah2 read it. This has to ship as an image; a hand-run merger is not a deployment.

🤖 Generated with Claude Code

…loyed nodes

owl was widened to +/-1000 Hz on 2026-08-11 to catch a 402 m/s target that sat
at -674 Hz when the node ran at fc 503 MHz. At 213 MHz (lambda 1.407 m) that
same target appears at 286 Hz, so the window that justified +/-1000 now costs
265 ms/CPI to cover speeds nothing flies at. +/-300 Hz reaches ~+/-422 m/s for
+42 ms/CPI span-attributable, measured over 74 CPIs on owl on 2026-09-07.

Doppler span costs no resolution: bin spacing is pinned at 1/CPI and the span
sets bin count, paid for out of nCorr = fs/dopplerSpan. What it does cost, at
+/-300 against +/-200, is ~0.4 dB more far-range integration loss at delay bin
400 (the linear-correlation taper deepens as nCorr falls from 4975 to 3322) and
1.5x the raw CFAR false alarms, before centroiding and the minDoppler gate.

Changing default.yml alone would have reached nothing. The merger seeds user.yml
with a whole copy of default.yml on first boot, so every node that has ever
booted holds the shipped span in its own overlay, which wins over defaults.
owl's overlay carries all six top-level sections for exactly this reason.

migrate_doppler_span drops the pair from the overlay when it is exactly the
+/-200 that used to ship, so the default shows through. It follows
migrate_gain_reduction in kind, and differs in three ways:

- It tests both bounds together. -200/1000 or -200/400 is somebody's decision
  and is kept whole. owl's -1000/1000 survives untouched.
- It deletes rather than rewrites, so the value lives in default.yml alone and
  the next span change needs no merger edit.
- It runs before the user merge rather than after the forced one, so forced.yml
  keeps the last word.

A node that deliberately chose +/-200 cannot be told apart from a first-boot
copy, so it moves too and has to be set again. That is the cost of the overlay
never recording who wrote a value.

user.yml on disk is left alone, which makes this function load-bearing rather
than one-shot: remove it and those nodes fall back to the +/-200 their overlay
still holds. test_doppler_span_migration_does_not_rewrite_user_yml pins that so
it is not deleted as spent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Purple10101
Purple10101 merged commit d8749cd into main Sep 7, 2026
1 check passed
@Purple10101
Purple10101 deleted the 20260907-doppler-span-300 branch September 10, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant