Write the aircraft down, and draw where they went
ADS-B was a live table and nothing else: an aircraft was overhead for four minutes and then gone, with nothing kept. Now everything heard goes into adsb_<time>.jsonl as it arrives -- one object per frame, the raw hex beside what was read out of it, flushed per line because a listening session ends with control-C -- with a readable report beside it. flights.py asks who the aircraft are: adsbdb for the airframe and the route, hexdb behind it, cached for a month. What needs no website is answered without one, because the ICAO address block says which country registered the aircraft and the first three letters of an airline callsign are its designator. Nothing but the address and the callsign heard on the air is ever sent. bandsaunter flights [LOG...] --out sky.gif reads a log back and draws the evening as a map with the clock running. Every frame is a moment: each aircraft is where it actually was then, interpolated between the position reports either side of it and dead-reckoned from its last speed and heading between them, and dropped rather than guessed at once it has not been heard for --stale seconds. The GIF is written here -- palette, LZW, frame differencing against a transparent index -- so nothing but numpy is needed; ffmpeg writes an MP4 where it happens to be installed, and .png draws the whole evening at once. The decoder needed 6.3 s to read a second of sky, so a live capture was losing six frames in seven. Reading the bits off a running total instead of summing each window takes that to 0.6 s, with identical output. --simulate flies six aircraft that are not there past a receiver that is not there, through the real encoder, the real checksum and the real decoder, so all of this can be tried without an aerial. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016PsWPTweCT6pwxKngvVxcg
This commit is contained in:
parent
a8a8548369
commit
eae60cb04d
15 changed files with 3857 additions and 177 deletions
|
|
@ -133,7 +133,13 @@ List attached receivers.
|
|||
List saved profiles.
|
||||
.TP
|
||||
.B adsb
|
||||
Listen to aircraft on 1090 MHz. See
|
||||
Listen to aircraft on 1090 MHz and write down everything they say. See
|
||||
.B AIRCRAFT
|
||||
below.
|
||||
.TP
|
||||
.B flights
|
||||
Read an ADS-B log back: the report, the map for Google Earth and the
|
||||
animation. See
|
||||
.B AIRCRAFT
|
||||
below.
|
||||
.TP
|
||||
|
|
@ -648,12 +654,69 @@ two frames \[em] the encoding sends a fraction of a zone, and one frame alone is
|
|||
ambiguous by hundreds of miles \[em] so an aircraft is placed once an even and an
|
||||
odd frame have both arrived, about a second apart.
|
||||
.PP
|
||||
.B \-\-kml
|
||||
writes what was heard as a map.
|
||||
An aircraft is overhead for four minutes and then gone, so everything heard is
|
||||
written down as it arrives: a JSON Lines log, one object per frame, in
|
||||
.I adsb_<time>.jsonl
|
||||
in the output directory, with the raw hexadecimal of every frame kept beside
|
||||
what was read out of it \[em] the frame is the evidence and the rest of the line
|
||||
is an opinion about it. The log is flushed as it is written, because a
|
||||
listening session ends with control-C. Beside it goes a readable report, one
|
||||
block per aircraft.
|
||||
.PP
|
||||
.B \-\-frames
|
||||
prints each frame as it arrives instead of a running count. An aerial cut for
|
||||
1090 MHz makes the difference between hearing the airport and hearing the
|
||||
county; the whip supplied with a dongle is a quarter of the length it wants.
|
||||
prints each frame as it arrives instead of a running count,
|
||||
.B \-\-no\-log
|
||||
listens without writing anything down,
|
||||
.B \-\-kml
|
||||
writes the flight paths for Google Earth and
|
||||
.B \-\-map
|
||||
draws the animation when the listening stops.
|
||||
.B \-\-simulate
|
||||
flies six imaginary aircraft past an imaginary receiver \[em] real frames, real
|
||||
checksums, the same decoder \[em] for trying all of this without an aerial;
|
||||
.BI \-\-near " LAT,LON"
|
||||
says where they are flying. An aerial cut for 1090 MHz makes the difference
|
||||
between hearing the airport and hearing the county; the whip supplied with a
|
||||
dongle is a quarter of the length it wants.
|
||||
.SS Who the aircraft is
|
||||
The frames say an address, not a registration. Two registers are asked \[em]
|
||||
adsbdb for the airframe and the route, then hexdb \[em] and the answers are
|
||||
cached for a month. Nothing is sent to either but the address or the callsign
|
||||
that was heard on the air.
|
||||
.PP
|
||||
What can be answered without asking anybody is answered without asking. The
|
||||
address block says which country registered the aircraft, fixed by treaty, and
|
||||
the first three letters of an airline callsign are its ICAO designator.
|
||||
.B \-\-no\-lookup
|
||||
stops at that.
|
||||
.SS The moving map
|
||||
.B bandsaunter flights
|
||||
reads a log back \[em] the newest one in the output directory unless told
|
||||
otherwise \[em] prints the report and draws the whole evening as a map with the
|
||||
clock running.
|
||||
.PP
|
||||
Every frame of the animation is a moment: each aircraft is drawn where it
|
||||
actually was then, interpolated between the position reports either side of it
|
||||
and dead-reckoned from its last known speed and heading where none arrived, so
|
||||
an aircraft crossing the picture in ten seconds took the twenty minutes the
|
||||
data says it took. An aircraft not heard from for
|
||||
.B \-\-stale
|
||||
seconds stops being drawn rather than being flown on by guesswork.
|
||||
.PP
|
||||
.BI \-\-speed " X"
|
||||
is seconds of flying per second of animation;
|
||||
.BI \-\-seconds " N"
|
||||
works that out from how long the animation should run instead.
|
||||
.B \-\-out
|
||||
takes a
|
||||
.IR .gif ,
|
||||
an
|
||||
.I .mp4
|
||||
where ffmpeg is installed, or a
|
||||
.I .png
|
||||
for the whole evening in one picture. Altitude is the colour, low warm to high
|
||||
cold. The GIF is written from first principles \[em] a palette, an LZW stream
|
||||
and frame differencing \[em] so nothing but numpy is needed to draw one.
|
||||
.SH METERS AND SENSORS
|
||||
Two things on the ISM bands are worth naming rather than reporting as
|
||||
hexadecimal.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue