Seed the world with live ADS-B traffic from adsb.retina.fm - #14
Merged
Merged
Conversation
Real aircraft over the fleet's metro now join the simulated world and are
echoed by the synthetic nodes: a new LiveAdsbClient polls an adsb.lol-shaped
feed (/v2/point/{lat}/{lon}/{radius_nm}; adsb.retina.fm serves it), and
SimulationWorld.ingest_live_aircraft turns each row into a `live-<hex>`
aircraft flying its real position, altitude, ground speed, track and
vertical rate, extrapolated from the fix's capture time and dead-reckoned
between polls. The feed owns these aircraft: no waypoints, no separation
slowing, no lifetime — they leave when the feed stops reporting them.
Two independent knobs:
- frac_live_dark casts a share of the LIVE aircraft as dark — mirrored
without their transponder (has_adsb off, adsb_hex None), so the node
frames carry no tag for them, the ADS-B push omits them, and the ground
truth keys them by object id, exactly like a synthetic dark spawn. The
cast is a stable per-hex hash, so moving the knob re-partitions the
aircraft already in the air (raising it only adds dark aircraft) instead
of re-rolling them, and set_frac_live_dark applies it at the next config
poll rather than the next fleet turnover.
- min/max_aircraft and frac_dark keep governing the SYNTHETIC spawns
layered on top: spawning counts synthetic aircraft only, so the feed's
population never starves synthetic spawns or vice versa.
Orchestrator: --live-adsb-url / --live-adsb-interval start _seed_live_adsb
over the --metro/--metros areas; the backend's frac_live_dark and
live_adsb_enabled ride the existing /api/simulation/config poll (pausing
clears the live aircraft). Ground-truth payloads carry source=live|sim;
the ADS-B push now carries the callsign. --real-adsb is ignored while
seeding runs — both would push the same hexes into one cache under two
world tags.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
retina_simulation/live_adsb.py:LiveAdsbClientpolls an adsb.lol-shaped feed (/v2/point/{lat}/{lon}/{radius_nm}— what adsb.retina.fm serves) and normalises tar1090 rows (ground/positionless rows dropped,seen_posresolved to an absolute capture time, last-good cache across a failed fetch).SimulationWorld.ingest_live_aircraftturns feed rows intolive-<hex>world aircraft flying their real position/altitude/ground speed/track/vertical rate, extrapolated from the fix's capture time and dead-reckoned between polls. They are echoed by the synthetic nodes like any other aircraft, but the feed owns them: no waypoints, no separation slowing, no lifetime — they expire only when the feed stops reporting them (live_stale_s, 60 s).frac_live_darkcasts a share of the live aircraft as dark: mirrored without their transponder (has_adsboff,adsb_hexNone → no tag in node frames, omitted from the ADS-B push, ground truth keyed by object id — the shape of a synthetic dark spawn with a real trajectory underneath). The cast is a stable per-hex hash, so moving the knob re-partitions the aircraft already in the air (raising it only ever adds dark aircraft) andset_frac_live_darkapplies it at the next config poll.min/max_aircraft+frac_darkkeep governing the synthetic traffic layered on top, whatever the feed reports.--live-adsb-url/--live-adsb-intervalstart_seed_live_adsbover the--metro/--metrosareas;frac_live_darkandlive_adsb_enabledride the existing/api/simulation/configpoll (disabling clears the live aircraft). Ground-truth payloads carrysource: live|sim; the ADS-B push carries the callsign.--real-adsbis ignored while seeding runs (both would push the same hexes into one server cache under two world tags).Server side (fleet entrypoint env, Physics Settings slider, config keys, counts): offworldlabs/retina-server PR to follow, pinning this branch.
Test plan
pytest— 200 passed (26 new intests/test_live_adsb.py: parsing, client URL + last-good fallback, ingest/extrapolation/update/expiry, synthetic independence, dark cast stability/monotonicity, frame/push/GT shapes for both roles)pre-commit run --all-filesgreen (ruff, ruff-format, vulture, ruff-config)🤖 Generated with Claude Code