Akustische Überflug-Geolokalisierung (Doppler × ADS-B)
Dieses Skill reproduziert und produktiviert die Methode aus colstos Video "I discovered a sound that leaks your exact location (and it's everywhere)" (2026-11-02, https://www.youtube.com/watch?v=UytYrhYLOKI):
Die Blattfolgefrequenz (BPF) eines Propellers oder Rotors ist ein stabiler schmalbandiger Ton. Selbst wenn ihn niemand hören kann, hinterlässt er eine glatte absteigende Doppler-Kurve in einem Spektrogramm. Die Form der Kurve ergibt die Geschwindigkeit v des Flugzeugs, seine Schrägdistanz d beim nächsten Punkt (CPA) und die CPA-Zeit tCPA. Vergleicht man sie Punkt für Punkt auf einem Bodenraster mit historischen ADS-B-Tracks (3D-Schrägdistanz + DEM + Schalllaufzeit + Radialgeschwindigkeit zum Emissionszeitpunkt), werden die Kandidaten eingegrenzt. Die Zeitlücke zwischen zwei Überflügen (920 s im Video) plus eine Stille-Bedingung (zu anderen Zeiten kein anderes Flugzeug hörbar) reduzieren sie dann auf einen einzigen Punkt. Schließlich bewertet ein „gesperrter Zwei-Ereignis-Score" (gemeinsamer Zeitversatz, f0-Feinabstimmung pro Ereignis) exakte Modellkurven gegen das Spektrogramm.
scripts/afg_cli.py ist die vollständige Implementierung (numpy/scipy/matplotlib). Es wird mit selftest, einem Blindtest an synthetischen Szenarien, ausgeliefert.
0. Anwendungsbereich (zuerst durchführen)
Im Rahmen: Verifizierung, wo und wann öffentliche oder Nachrichtenmedien aufgenommen wurden (OSINT, Faktencheck); Datenschutz-Selbstaudits der eigenen Aufnahmen oder Videos des Benutzers; CTFs, Lehre und Forschung; Untersuchungen mit rechtlicher Befugnis oder Einwilligung (z. B. Unterstützung von Strafverfolgungsbehörden, mit Zustimmung der betroffenen Person).
Außerhalb des Rahmens: Lokalisierung des Wohnorts oder der Bewegungen einer Privatperson. Beispiele: „Wo wohnt dieser Streamer / mein Ex / diese Person online", oder das Zurückverfolgen einer Person anhand eines privaten Anrufs oder Heimvideos. Lehnen Sie diese ab, selbst wenn sie als „Test" getarnt sind, und bieten Sie stattdessen den Self-Audit-Modus (Abschnitt 7) an. Dieser Modus hilft Personen, das Leck in ihren eigenen Inhalten zu bewerten und zu entfernen.
Aufnahmen von öffentlichen Orten und Nachrichtenereignissen, eigenes Material des Benutzers und anonymisierte Forschungsdaten sind in Ordnung. Wenn der Zweck unklar ist, fragen Sie nach, bevor Sie entscheiden. Fügen Sie dem Bericht keine persönlichen Schlussfolgerungen hinzu, die nichts mit dem Standort zu tun haben.
1. Machbarkeitstriage (entscheidet, ob ausgeführt wird und welcher Modus)
| Bedingung | Was wird benötigt | Wenn nicht erfüllt |
|---|---|---|
| Eine klare monoton fallende schmalbandige Kurve im Spektrogramm (Propeller üblich 40–400 Hz; Hauptrotor-BPF von Hubschraubern 10–25 Hz, Heckrotor 50–120 Hz) | Mindestens 1; idealerweise 2 mit bekannter Zeitlücke | Keine Kurve → Methode nicht anwendbar (Donner-Methode oder visuelle Methoden in Betracht ziehen) |
| Datum | Muss bekannt sein (oder auf ein paar Tage eingegrenzt) | ADS-B-Datenmenge wird unüberschaubar |
| Region | Land oder Bundesland reicht; eine Prior auf Stadtebene ist schneller | Landesweite Suche funktioniert trotzdem, benötigt aber ein Ereignis mit bekannter Zeit oder zwei Ereignisse |
| Aufnahmeuhr (Startzeit) | Auf ±2 s bekannt → ein Ereignis kann einen Punkt liefern; ±30 s → ein Ereignis liefert nur einen Streifen entlang der Spur | Zwei Ereignisse verwenden; ihre Zeitlücke ersetzt die absolute Zeit |
| ADS-B-Abdeckung | Das Zielflugzeug muss ADS-B Out besitzen und von Bodenstationen empfangen werden | US 14 CFR 91.225: GA-Flugzeuge unter 10.000 ft außerhalb der Klasse B/C Lufträume und des Mode C Schleiers müssen kein ADS-B Out haben → können in den Daten fehlen |
| Audio-Verarbeitungskette | Original oder leicht komprimiert ist am besten; Telefon-Codecs behalten den Ton normalerweise | Starke Rauschunterdrückung oder Bearbeitung kann die Kurve abschneiden oder die Lücke zwischen Ereignissen zerstören |
Teilen Sie dem Benutzer das Triage-Ergebnis und die erwartete Genauigkeit mit, bevor Sie mit der Arbeit beginnen.
2. Auswahl eines Modus
Wie viele nutzbare Kurven?
├─ ≥2 (gleiche kontinuierliche Aufnahme) → Modus A: zwei Ereignisse, unbekannte absolute Zeit (Hauptmethode des Videos; robusteste)
│ Wenn sich die beiden Spuren mit < ~25° kreuzen, verschlechtert sich das Ergebnis zu einem Streifen entlang der Spuren (das Skript warnt)
├─ 1
│ ├─ Aufnahmezeit auf wenige Sekunden bekannt → Modus B: ein Ereignis, bekannte Zeit (zweite Hälfte des Videos; selbst bei US-weiter Suche zuerst eingestuft)
│ │ Ein gerader Vorbeiflug mit konstanter Geschwindigkeit ist spiegelsymmetrisch → es gibt immer einen „Spiegelkandidaten";
│ │ ein zweiter Hinweis (visuell, Gelände) wird benötigt, um zwischen ihnen zu wählen
│ └─ Zeit nur auf ±30 s oder schlechter bekannt → Modus B′: nur ein Streifen der Länge ≈ 2·v·Δt möglich; als solcher melden
├─ Keine Flugzeugkurve, aber Donner + bekanntes Datum → Modus T: Donnerhüllkurve × Blitzdaten (km-Genauigkeit, siehe references/thunder-method.md)
└─ Der Benutzer möchte seine eigenen Inhalte schützen → Modus S: Self-Audit (Abschnitt 7)
3. Workflow (CLI)
Konvention: AFG="python <skill dir>/scripts/afg_cli.py", Arbeitsverzeichnis work/. Jeder Schritt schreibt PNGs.
Betrachten Sie die PNGs selbst mit Ihrer Bildlesefähigkeit (Spektrogramme, Fit-Overlays, Heatmaps), anstatt sich nur auf die Zahlen zu verlassen.
Überprüfen Sie zuerst die Umgebung: pip install numpy scipy matplotlib (DEM benötigt rasterio; Nicht-WAV-Eingabe benötigt ffmpeg). Bei der ersten Verwendung führen Sie $AFG selftest --seed 7 aus (ca. 40–60 s; Exit 0 bedeutet, dass die Pipeline funktioniert).
3.1 Audio und Metadaten abrufen
ffprobe -v quiet -show_entries format_tags=creation_time:stream_tags=creation_time -of json input.mp4gibt die Aufnahmezeit. Achten Sie auf die Zeitzone. Soziale Plattformen entfernen oder überschreiben Metadaten beim Re-Encode oft, daher nur als Hinweis behandeln und gegenprüfen.- Übergeben Sie die ursprüngliche Abtastrate an das Skript; es resampelt intern auf 4 kHz Mono (
--channelwählt links oder rechts).
3.2 Spektrogramm → Erkennen → Verfolgen → Anpassen
$AFG spectrogram input.mp4 --out work/rec # gebleichtes schmalbandiges Spektrogramm + work/rec.png
$AFG detect work/rec.spec.npz --out work/boxes.json # Kandidatenboxen (t0, t1, fmin, fmax, score_z) + boxes.diag.json
$AFG plot work/rec.spec.npz --t0 160 --t1 320 --fmin 60 --fmax 380 --out work/zoom1.png
$AFG trace work/rec.spec.npz --t0 166 --t1 315 --fmin 98 --fmax 364 --out work/e1.csv
$AFG fit work/e1.csv --temp-c 18 --out work/e1.json # v, d, tCPA, f0, Suchfenster; Überlagerung in e1.fit.png
Wichtige Punkte:
- Ein leeres
boxes.jsonbedeutet „kein Überflug" nur, wennboxes.diag.jsonstatus: oksagt.limited(kurzer Clip, bewertet gegen das kalibrierte Rauschmodell, oder meist getaktetes Audio) undinsufficient(Clip kürzer als--min-dur, oder fast alles getaktet) werden mitreasonsgeliefert: lesen Sie sie, inspizieren Sierec.png, und senken Sie--min-durfür kurze Clips. - Jedes Ereignis hat
trend(descendingoderflat) unddrop_pct. Ein Grat, der in der Frequenz ansteigt, ist kein Überflug: er wird unterrejectedinboxes.diag.jsonaufgeführt, nicht inboxes.json.warningsbei einem Ereignis bedeuten, dass sein Grat das tut, was ein einzelner Vorbeiflug nicht kann (wieder ansteigt oder um mehr als 45 % fällt): es verbindet wahrscheinlich zwei Flugzeuge oder zwei Harmonische. Inspizieren Sie es mitplotund verfolgen Sie jeden Teil in seiner eigenen schmalen Box. --win: 0.5–1 s für nahe, steile Kurven und 2–4 s für entfernte oder schwache. Zoomen Sie für eine schwache Kurve mitplothinein und bestätigen Sie sie zuerst mit dem Auge. Geben Sie danntraceeine schmale Box, die nur eine Harmonische enthält, und fügen Sie bei Bedarf ein paar manuelle Punkte mit--anchors "t:f,t:f,..."hinzu.- Überprüfen Sie die
fit-Ausgabe:implausiblenicht leer = die Spur lief auf Rauschen oder sprang Harmonische. Fahren Sie nicht mit der Suche fort (das Skript weigert sich ebenfalls).notes: links/rechts Restasymmetrie = eine Kurve oder Geschwindigkeitsänderung; unterschiedliche Annäherungs-/Entfernungsgeschwindigkeiten = ein Steig-/Beschleunigungsflug.
- Wenn Sie die Lufttemperatur kennen, übergeben Sie
--temp-c(c = 20.05·√(T+273.15)). v und d skalieren beide mit c; ohne Temperatur behalten Sie die Standardabweichung von ±4 % bei. - f0 ist nur die Ruhefrequenz der Harmonischen, die Sie verfolgt haben, nicht unbedingt die Grundfrequenz; v und d hängen nicht von der Harmonischennummer ab.
- BPF = Blätter × RPM / 60 kann helfen, den Typ zu erraten (C172, 2 Blätter × 2400 rpm ≈ 80 Hz; DHC-8-400, 6 Blätter × 1020 rpm ≈ 102 Hz). Verwenden Sie es nicht als harten Kandidatenfilter.
3.3 ADS-B-Daten (Details in references/adsb-data.md)
- Quellen:
- adsb.lol
globe_history_YYYY: eine globale Veröffentlichung pro Tag, kostenlos, ODbL. - ADS-B Exchange kostenlose Samples: nur am 1. jedes Monats.
- OpenSky Trino: benötigt ein Forschungskonto; Tabelle
state_vectors_data4. - Eigener readsb/tar1090-Empfänger.
- adsb.lol
- Extrahieren Sie nur das Zieldatum, das Zielfenster ± 1 h und das Zielgebiet, gepolstert um ~0.5°.
$AFG adsb-ingest --src traces_dir/ --start 2026-09-08T13:00Z --end 2026-09-08T18:00Z \
--bbox 38.5,39.7,-95.4,-93.8 --qnh 1018 --geoid-n -29 --out work/tracks.npz
- Das Höhendatum bestimmt die Schrägdistanzgenauigkeit.
alt_baroist die Standarddruckhöhe: korrigieren Sie sie mit lokalem QNH (≈ 8.3 m/hPa; siehe METAR).alt_geomist die WGS84-Ellipsoidhöhe (HAE); MSL = HAE − N.--alt-source autobevorzugt geometrische Höhe.
3.4 DEM und Suche
$AFG dem-fetch --bbox 38.5,39.7,-95.4,-93.8 --out work/dem # Copernicus GLO-30 (AWS Public Bucket)
$AFG search --tracks work/tracks.npz --events work/e1.json work/e2.json \
--bbox 38.5,39.7,-95.4,-93.8 --dem work/dem/*.tif --rec-duration 1450 --out work/cands.npy
Der Trichter hat drei Stufen:
- Ereignis-1-Korridor: Geschwindigkeitsfenster, k = v²/d Konsistenz, Schrägdistanzfenster und der CPA darf nicht an einem Spur-Endpunkt liegen.
- Inter-Ereignis-Versatz: tCPA2 − tCPA1, einschließlich der d/c Laufzeitverzögerung jedes Ereignisses.
- Stille-Filter: In den verbleibenden ruhigen Abschnitten darf kein anderes Propeller- oder Rotorflugzeug innerhalb von
--d-quietpassieren.
Optionen:
- Modus B:
--rec-start <UTC> --rec-start-tol 2(oder 30) hinzufügen. --quiet "a-b,c-d"benennt Aufnahmeabschnitte, in denen Sie sicher sind, dass nichts gehört wurde (Standard: alles außerhalb der Ereignisse). Geben Sie weniger Abschnitte an, wenn die Aufnahme viel Wind oder Sprache enthält. Stille ist Signal, aber falsche Stille tötet die wahre Antwort.- Standardraster ist 200 m. Wenn es zu viele Kandidaten gibt, verkleinern Sie die Bbox, anstatt das Raster zu vergrößern.
3.5 Bewertung und Verfeinerung
$AFG score --tracks work/tracks.npz --spec work/rec.spec.npz --events work/e1.json work/e2.json \
--cands work/cands.npy --dem work/dem/*.tif --out work/result.json
- Modellkurven: Generieren Sie für jeden Kandidaten eine exakte Modellkurve zum Emissionszeitpunkt aus den interpolierten ADS-B-Positionen und -Geschwindigkeiten (gs/track/vrate, nicht differenzierte Positionen) und vergleichen Sie sie mit dem Spektrogramm. Ein Zeitversatz δ wird gemeinsam genutzt, was die physikalische Zeitlücke zwischen den beiden Ereignissen festlegt. Das f0 jedes Ereignisses wird innerhalb von ±0,6 % feinabgestimmt.
- Verfeinerung: Jeder behaltene Knoten erhält eine schrumpfende 3×3-Hügelkletter-Suche (100 → 25 m).
- Gruppierung: Ergebnisse werden nach Flugpaar gruppiert. Jedes Paar behält bis zu 3 Hypothesen, die mehr als 500 m voneinander entfernt sind, sodass beide Spiegelseiten überleben.
- Ausgaben:
result.json: bestes,margin_vs_2nd,robust_z,ambiguous_alternatives,coarse_plateau,geometry,verdict.result.rankN.*.png: Modellkurven-Overlays.result.heatmap.png/csv: Radius der 0.9-Region.result.plateau.csv.
- Mit bekannter Aufnahmeuhr
--rec-start ... --rec-start-tol 2hinzufügen. Die Bewertung verbietet dann auch Zeitverschiebungen außerhalb der Uhr.
3.6 Verifikation (nicht optional; siehe references/verification.md)
- Overlays: Die Modellkurve muss die Beobachtung auf beiden Asymptoten und durch den CPA anpassen, nicht nur auf einem Segment.
- Heatmap: Der Radius der 0.9-Region ist der zu meldende Fehler. Melden Sie einen Streifen, wenn eines von beidem zutrifft:
- zwei Ereignisse:
geometry.warningist gesetzt (kleiner Kreuzungswinkel); - ein Ereignis:
coarse_plateau.length_m> 600 m.
- zwei Ereignisse:
- Spiegelkandidaten und Alternativen: Schließen Sie sie durch visuelle Hinweise (Horizont, Gebäude, Vegetation, Straßenlärm, Echos), DEM-Sichtbarkeitsanalysen und Sonnenazimut aus.
- Falsifikation: Sollten andere Überflüge in der Nähe der Antwort ebenfalls gehört worden sein?
- Gehört, aber nicht erkannt = ein Problem der Erkennungsschwelle.
- Vorhanden, wenn sie nicht hörbar gewesen sein sollten = der Ort ist falsch.
4. Genauigkeitsregeln (und warum)
- Emissionszeit: f_obs(t) = f0 / (1 + Ṙ(τ)/c), mit t = τ + R(τ)/c. Die Verwendung von Ṙ zum Empfangszeitpunkt ergibt eine Kurve mit der falschen Form, nicht nur einer verschobenen.
- 3D-Schrägdistanz + DEM: Beobachterhöhe plus Mikrofonhöhe (Standard 2 m). Die Behandlung von 500 m Geländehöhenunterschied als 0 macht sowohl d als auch tCPA falsch.
- Höhendatum: Unkorrigierte Druckhöhe mit einem QNH-Versatz von 30 hPa ≈ 250 m Höhenfehler, der direkt in d eingeht.
- Verzögerter CPA: Der Moment, in dem f = f0 beobachtet wird, ist tCPA_emit + d/c (1 km ≈ 2,9 s). Ereignisversätze und die Uhr müssen beide damit umgerechnet werden.
- k = v²/d ist zuverlässiger als v oder d allein.
- Die mittlere Kurvensteigung, −f0·v²/(c·d), ist genau bestimmt. Die Asymptoten sind oft durch Rauschen, Taktung oder Beschleunigen/Steigen des Flugzeugs verunreinigt.
- Daher verwendet die Suche ein weites Geschwindigkeitsfenster plus ein schmales k-Fenster, und die eigene Geschwindigkeit über Grund jedes Kandidatenflugzeugs sagt sein d voraus.
- Gesperrte Bewertung: Beide Ereignisse teilen sich ein δ. Andernfalls richtet jedes Ereignis seine eigene Zeit aus, und auch falsche Standorte erzielen gute Bewertungen.
- Verfeinerung auf ≤100 m: Das 200-m-Raster ist nur ein grobes Sieb; der endgültige Punkt stammt aus der sub-Raster-Hügelkletter-Suche und der Heatmap.
- Stille ist Signal, aber halten Sie die Schwellen großzügig (Standards: Propeller 3 km, Rotor 2,5 km). Entfernte oder leistungsschwache Flugzeuge können tatsächlich unhörbar sein.
- Lockere Fenster, strenge Bewertung: Im Trichter irren Sie sich weit, denn eine herausgefilterte wahre Antwort kann nie wiedergewonnen werden. Überlassen Sie die Diskriminierung der exakten Modellbewertung.
- Nach Flugpaar gruppieren und den Spiegel behalten: Ein gerader Vorbeiflug mit konstanter Geschwindigkeit ist symmetrisch zu seiner Spur. Ergebnisse mit einem Ereignis sollten mindestens beide Seiten melden.
- ADS-B-Lücken: Keine Übereinstimmung ≠ nicht im Gebiet. Tief fliegende GA, Militärflugzeuge und einige Hubschrauber haben möglicherweise kein ADS-B oder werden nicht empfangen (Geländeverdeckung, niedrige Höhe).
- Schallgeschwindigkeit und Wind: v und d skalieren mit c. Bei Wind ist c_eff = c + w·n; bei starkem Wind (>8 m/s) das d-Fenster erweitern.
5. Bericht
Ausgabe unter Verwendung von assets/report_template.md, in der Sprache des Benutzers. Er muss enthalten:
- die Antwortkoordinaten
- ...
[gekürzt für Übersetzung]