← Blog

NEine Modellkonstellation24 Satelliten, 6 Bahnebenen bei 55°6 über der 10°-MaskeHohl: über dem Horizont,unter der MaskeLinien: die nächsten zwei StundenMitte: senkrecht nach obenRinge: 0°, 30°, 60° Höhenwinkel
Ein Himmelsplot über Innsbruck: wo die Satelliten einer GPS-Modellkonstellation stehen, nach Richtung und Höhe über dem Horizont, und wohin sie in den nächsten zwei Stunden wandern. Ein Modell, nicht die gesendeten Bahndaten eines echten Tages.
Unter der Haube

GNSS-Rohdaten auf Android: jeden Satelliten nutzen

Wie walker Androids GNSS-Rohdaten aus fünf Satellitensystemen und zwei Frequenzbändern auf dem Handy auswertet, und was das auf einer echten Radtour brachte.

· Malik · 21 Min. Lesezeit

Im Freien hat mein Handy 26 bis 36 Satelliten gleichzeitig gemessen, aus fünf Systemen und auf zwei Frequenzbändern. Die erste Bereinigung mit Satelliten, die ich geschrieben habe, nutzte davon etwa 12: GPS auf L1 und BeiDou auf B1I. Mehr als die Hälfte dessen, was das Handy maß, kam nie beim Solver an.

walker, die App für Spaziergänge, Wanderungen und Radtouren, die ich für Android entwickle, bereinigt jeden Track auf dem Handy. Eine Zeit lang hat sie dafür die fertigen GPS-Punkte des Chips verwendet. Inzwischen liest sie auch die Satelliten selbst: jedes System und jedes Band, das mein Handy misst und für das es gesendete Bahndaten gibt. Dieser Beitrag erzählt, was dafür nötig war und was es gebracht hat. Der Faktorgraph, der all das gewichtet, steht in GPS-Tracks glätten mit einem Faktorgraphen; die Reihe beginnt mit Eine ganze Android-App in Rust statt Kotlin.

Unter dem GPS-Punkt

Ein GPS-Punkt des Handys ist das Ergebnis eines Filters im GNSS-Chip, und meine zwei größten Probleme kamen aus diesem Filter, nicht vom Himmel. Das erste ist der Static Hold: Manche Chips halten den GPS-Punkt fest, während du weitergehst. Die Rohmessungen ändern sich währenddessen weiter, Satellit für Satellit, und eine Lösung aus ihnen friert nicht ein. Das zweite: Ein GPS-Punkt trägt nur eine Zahl für seine Qualität, eine einzige Genauigkeit. Die Rohmessungen dagegen liefern für jeden Satelliten die Signalstärke (C/N0), das Band und einen Mehrwegeindikator, ein Flag für Anzeichen, dass das Signal auch über Reflexionen angekommen ist.

Was Android dir gibt

Rohmessungen gibt es in android.location seit Android 7 (API-Level 24): Ein GnssMeasurementsEvent enthält eine GnssClock und ein GnssMeasurement pro Signal. Seit Android 10 sind sie Pflicht. Was du nicht bekommst, ist eine Pseudoentfernung, also die Entfernung, die aus der Laufzeit des Signals folgt. Die baust du aus zwei Zeiten selbst, so wie es Googles gps-measurement-tools und das White Paper der Europäischen GNSS-Agentur (GSA) tun.

Die erste Zeit ist der Moment, in dem der Empfänger gemessen hat, in GPS-Zeit, die ab dem 6. Januar 1980 zählt. Android liefert sie in Teilen. TimeNanos ist die Uhr des Empfängers. FullBiasNanos und BiasNanos sind die Schätzung des Chips, wie weit diese Uhr von der GPS-Zeit abweicht, in ganzen Nanosekunden und dem verbleibenden Bruchteil; sie werden abgezogen. TimeOffsetNanos ist der Versatz dieser einen Messung gegenüber der Uhr der Epoche. Android legt fest, dass er zu TimeNanos addiert wird, er gehört also zur Empfangszeit und nicht zur Zeit des Satelliten.

Die zweite Zeit, ttxt_{tx}, ist der Moment, in dem der Satellit das Signal gesendet hat, nach der Uhr des Satelliten: ReceivedSvTimeNanos. Sie zählt ab dem Beginn der Woche des Systems, bei GLONASS ab dem Beginn des Tages, und in der Zeit des jeweiligen Systems. Galileo und QZSS laufen auf GPS-Zeit. Die BeiDou-Zeit liegt 14 s dahinter: Sie begann 2006, als seit dem Start der GPS-Zeit 14 Schaltsekunden vergangen waren, und hat seitdem keine weitere übernommen. GLONASS zählt den Moskauer Tag, der UTC mitsamt den Schaltsekunden folgt. Die Empfangszeit wird deshalb zuerst in die Systemzeit des Satelliten umgerechnet, trxsyst_{rx}^{sys}.

Beide Zeiten zählen innerhalb einer Spanne, die sich wiederholt, einer Woche oder einem Tag. Ihre Differenz muss deshalb auch innerhalb dieser Spanne gebildet werden. Laufzeit und Pseudoentfernung sind dann

Δt=[(trxsys mod W)−ttx] mod W,ρ=c Δt\Delta t = \left[\left(t_{rx}^{sys} \bmod W\right) - t_{tx}\right] \bmod W, \qquad \rho = c\,\Delta t
(1)

wobei WW die Spanne ist, in der der Satellit zählt (eine Woche oder bei GLONASS ein Tag), cc die Lichtgeschwindigkeit und ρ\rho die Pseudoentfernung in Metern.

Die Fallen stecken alle an den Rändern.

Die Rate musst du nicht selbst bauen: PseudorangeRateMetersPerSecond ist der Doppler in Metern pro Sekunde. Während der Aufzeichnung fordert walker außerdem volles Tracking an. Ohne das arbeitet der Chip im Duty-Cycling, schaltet seinen Empfänger also zwischen zwei GPS-Punkten ab, um Strom zu sparen, und die Messungen verlieren ihre Kontinuität.

Was mein Handy tatsächlich misst

Mein Handy ist ein OnePlus 7 Pro. Der erste Test, drei Sekunden im Stehen bei schwachem Signal, sah nur GPS L1 und BeiDou B1I, 8–9 Satelliten. Laut seiner Liste der Fähigkeiten liefert das Handy weder Messungen noch Navigationsnachrichten. Messungen kommen trotzdem an, der Liste ist also nicht zu trauen.

Im Freien sah es ganz anders aus. Drei GnssLogger-Logs und eine Radtour an einem Tag zeigten 26–36 Satelliten pro Epoche (einem Messzeitpunkt):

System Satelliten pro Epoche Bänder Median des Doppler-σ
GPS 11–15 L1, L5 0,05–0,67 m/s
Galileo 10–13 E1, E5a 0,59–0,86 m/s
GLONASS 4–6 G1 0,26–1,01 m/s
BeiDou 1–2 B1I 0,67–0,81 m/s
QZSS 0–0,4 L1 0,85–4,36 m/s
Tabelle 1

Bei 84–85 % dieser Messungen war die Zeit in der Woche decodiert, bei 0 % gab es eine gültige Trägerphase. Alles Weitere beruht also nur auf Code und Doppler. Von diesen 26–36 kam die erste Bereinigung mit GPS L1 und BeiDou B1I auf etwa 12 Satelliten pro Epoche. Das ist die Hälfte, die nie beim Solver ankam.

Bahndaten, ohne zu verraten, wo du warst

Eine Pseudoentfernung nützt nichts ohne die Position des Satelliten, und Android gibt die Ephemeriden des Chips, seine Kopie der Bahndaten, nicht heraus. walker hat zwei Quellen.

Die erste sind die Navigationsnachrichten, die Daten, die jeder Satellit über seine Bahn sendet. walker decodiert GPS LNAV, die ältere Nachricht auf L1, und BeiDous D1 und D2. Android sagt nicht, ob die GPS-Daten noch invertiert oder die BeiDou-Wörter noch verschachtelt sind. Jeder Unterrahmen wird deshalb auf jede Art gelesen und dort behalten, wo die Parität jedes Wortes stimmt. In der Praxis hat mein Handy in vier Aufzeichnungen keine einzige geliefert.

Die zweite ist die Tagesdatei der gesendeten Bahndaten vom BKG, eine zusammengeführte Navigationsdatei in RINEX 3, dem empfängerunabhängigen Austauschformat, mit GPS, GLONASS, Galileo, BeiDou und QZSS, alle 15 Minuten aktualisiert. walker lädt sie nur herunter, wenn du es in Settings unter Download satellite orbits (Satellitenbahnen herunterladen) erlaubst: Always (immer), Ask (fragen, die Voreinstellung) oder Never (nie). Die App speichert den Tag zwischen, und eine Tour behält die paar hundert Byte Bahndaten je Satellit, die sie braucht. Einen weiteren Download braucht sie danach nie.

Der Download hat walkers Regel, das Netz nur auf deinen Wunsch zu nutzen, erweitert. Deshalb lohnt es sich, genau zu sein. Die Datei ist an einem Tag für alle gleich. Der Server erfährt deine IP-Adresse und nach welchem Tag du gefragt hast. Eine Position oder eine Route erfährt er nie.

Für jede Messung wählt walker den zeitlich nächsten gesunden Datensatz des Satelliten, innerhalb der Zeit, für die die Datensätze seines Systems gelten.

Von Bahnelementen zur Entfernung

GPS, Galileo, QZSS und BeiDou senden Keplersche Bahnelemente: eine Ellipse und wie sie sich verschiebt. walker macht daraus eine Position, wie es IS-GPS-200 beschreibt, mit den Konstanten des jeweiligen Systems. Im Kern steht die Kepler-Gleichung. Die mittlere Anomalie MM ist ein Uhrzeiger, der sich gleichmäßig dreht, und der tatsächliche Winkel des Satelliten muss daraus berechnet werden:

E−esin⁡E=ME - e \sin E = M
(2)

Dabei ist ee die Exzentrizität der Bahn und EE die exzentrische Anomalie. Eine geschlossene Lösung gibt es nicht. walker löst die Gleichung mit dem Newton-Verfahren ab E0=ME_0 = M, und jeder Schritt korrigiert die Schätzung um das, was ihr fehlt:

Ej+1=Ej−Ej−esin⁡Ej−M1−ecos⁡EjE_{j+1} = E_j - \frac{E_j - e \sin E_j - M}{1 - e \cos E_j}
(3)

Dabei zählt jj die Schritte. Die Bahnen sind fast kreisrund, also reichen wenige Schritte. Die gesendeten Korrekturen, die Drift des Knotens (wo die Bahn den Äquator kreuzt) und die Drehung in erdfeste Koordinaten folgen so, wie das ICD sie beschreibt.

MEνe = 0,6, überzeichnetSatellitErde im BrennpunktNewton, E aus M = 50°:Schritt 0: 50,0000°Schritt 1: 92,8675°Schritt 2: 84,5831°Schritt 3: 84,2024°Schritt 4: 84,2016°ν = 122,1°GPS, e ≈ 0,01: 3 Schritte
Abbildung 1. Die Kepler-Gleichung als Bild, mit einer Exzentrizität von 0,6: Echte Navigationsbahnen sind viel runder. MM dreht sich gleichmäßig; EE ist der Winkel im Mittelpunkt zu dem Punkt auf dem Kreis, der senkrecht über dem Satelliten liegt; ν\nu ist der tatsächliche Winkel des Satelliten, gesehen von der Erde im Brennpunkt der Ellipse. Die Schritte sind das Newton-Verfahren ab E0=ME_0 = M, für diese Zeichnung berechnet.

Die geostationäre Ausnahme

Die geostationären Satelliten von BeiDou sind die Ausnahme. Eine wirklich äquatoriale Bahn hat keinen sauber definierten Knoten. Ihre Elemente sind deshalb in einem gekippten System angegeben, und die Position muss zurückgedreht werden. walkers Test setzt einen solchen Satelliten auf seinen geostationären Radius und prüft, dass er eine Stunde lang auf einen Meter genau über demselben Ort bleibt.

Die Uhr des Satelliten

Die Uhr des Satelliten weicht nach einem gesendeten Polynom von der Zeit ihres Systems ab. Dazu kommen ein Term für die Relativität und einer für die Verzögerung des Signals im Satelliten selbst, die je nach Band verschieden ist. Bei GPS L5 weicht walker vom ICD ab. IS-GPS-705 korrigiert L5 mit einer Inter-Signal-Korrektur aus CNAV, der neueren Nachricht auf L5. Die Bahndatendatei, die walker liest, hat für diese Verzögerung aber nur den älteren LNAV-Wert, skaliert nach der Frequenz. Der Unterschied, einige Dezimeter je Satellit, landet im L5-Bias des Empfängers weiter unten.

Die Erde dreht sich, während das Signal fliegt

Die Bahn liefert den Satelliten im erdfesten System des Moments, in dem er gesendet hat. In den rund 70 ms des Flugs dreht sich die Erde unter ihm weiter. Das ist der Sagnac-Effekt. walker dreht den Satelliten in das System des Empfangsmoments. Das verschiebt einen GPS-Satelliten um bis zu etwa 150 m und eine Entfernung um bis zu einige Dutzend Meter.

θbeim SendengedrehtEmpfängerNEchte Werte:Höhenwinkel 49°Laufzeit τ = 71,4 msθ = 5,21 µradauf der Bahn: 138 mStrecke: +21,8 mGezeichnet:θ etwa 40.000×zu groß; Bahn undErde maßstäblich
Abbildung 2. Die Erde dreht sich um θ=ωeτ\theta = \omega_e \tau, während das Signal τ\tau lang fliegt; ωe\omega_e ist die Drehrate der Erde. Im System des Empfangs dreht sich die Position des Satelliten beim Senden um θ\theta zurück. Ein Modell: ein Empfänger am Äquator und ein Satellit auf dem Radius der GPS-Bahn in derselben Ebene. Die Abstände sind maßstäblich, der Winkel ist um ein Vielfaches zu groß gezeichnet, und seine echte Größe steht rechts daneben.

Das Messmodell

Der Graph braucht jede Entfernung als Funktion der Größen, nach denen er löst. Ist der Uhrenfehler des Satelliten herausgerechnet, gewichtet walkers Graph für jedes Signal, in groben Zügen,

ρ+c δts=∥rs−rr∥+br+T+bsig+ϵ\rho + c\,\delta t^s = \left\lVert \mathbf{r}^s - \mathbf{r}_r \right\rVert + b_r + T + b_{sig} + \epsilon
(4)

δts\delta t^s ist der Uhrenfehler des Satelliten, rs\mathbf{r}^s die Position des Satelliten und rr\mathbf{r}_r die des Empfängers, brb_r der Uhrenfehler des Empfängers in Metern, TT die Verzögerung in der Troposphäre, bsigb_{sig} der Bias des Empfängers für dieses Signal gegenüber GPS L1 (mehr dazu unten) und ϵ\epsilon das Rauschen. Für die Troposphäre reicht ein einfaches Modell auf Meereshöhe nach dem Höhenwinkel: etwa 2,4 m senkrecht nach oben und etwa 9 m bei 15°. Die Ionosphäre fehlt mit Absicht; sie bekommt weiter unten einen eigenen Abschnitt. Auch die Doppler-Raten bekommen ein Modell, aus den Geschwindigkeiten von Satellit und Empfänger entlang der Linie zwischen ihnen.

Der Uhrenfehler des Empfängers brb_r ist der Grund, warum eine Pseudoentfernung „pseudo“ ist: Er verlängert jede Entfernung einer Epoche um denselben Betrag und wird deshalb zusammen mit der Position gelöst (Abbildung 3).

gemessenminus Uhrenfehlergelöste PositionSatellitUhrenfehler: 30 mgelöst: 31,3 mPositionum 1,3 m danebenRauschen σ = 1,5 m
Abbildung 3. Warum der Uhrenfehler mit der Position gelöst wird, an einem erfundenen, ebenen Beispiel: drei Satelliten und Entfernungen, die durch die Uhr des Empfängers jeweils 30 m zu lang sind, dazu etwas Rauschen. Die gemessenen Bögen (gestrichelt) treffen sich nicht. Eine Anpassung nach kleinsten Quadraten an die Position und einen gemeinsamen Uhrenfehler verkürzt sie alle um denselben Betrag, und sie treffen sich. Ein Handy löst dasselbe Problem in drei Dimensionen und der Zeit.

Wo es gehakt hat

GLONASS ist nicht Keplersch

GLONASS sendet alle 30 Minuten eine Position, eine Geschwindigkeit und die Anziehung von Sonne und Mond (die lunisolare Beschleunigung), gültig für etwa 15 Minuten davor und danach. Integrieren musst du selbst: die Schwerkraft, die Abplattung der Erde (J2J_2), diese Anziehung und die Zentrifugal- und Coriolis-Terme eines sich drehenden erdfesten Systems, schrittweise nach dem Runge-Kutta-Verfahren vierter Ordnung, wie es das ICD vorgibt.

Wer diese Gleichungen in der Ausgabe des ICD von 2008 nachschlägt, findet zwei Terme, die wie Druckfehler aussehen. In der erdfesten Form hat der Coriolis-Term in der xx- und der yy-Zeile dasselbe Vorzeichen, obwohl er in jedem drehenden System zwischen ihnen das Vorzeichen wechselt. Und der Abplattungsterm in der zz-Zeile weicht von der inertialen Form derselben Gleichungen ein paar Seiten vorher ab. walker folgt der Physik. Der Test nimmt einen echten Zustand und führt ihn 15 Minuten weiter bis zur nächsten Sendung. Er landet auf 5 m genau. Mit dem Coriolis-Vorzeichen wie gedruckt verfehlt er sie um 31 km, ohne J2J_2 um 14 m. Echte Datensätze, gegeneinander geprüft, haben die Referenzwerte ersetzt, die ich aus RTKLIB übernehmen wollte.

Die Uhr von GLONASS ist einfacher als die der anderen, mit eingebauter Relativität. Die Bahndatendatei gibt ihre Bezugszeiten in UTC an. walker rechnet sie mit den Schaltsekunden in GPS-Zeit um, und so laufen die GLONASS-Bahnen auf derselben Uhr wie alle anderen.

Galileo sendet jeden Satelliten doppelt

Galileos offener Dienst hat zwei Navigationsnachrichten, I/NAV und F/NAV. Sie teilen sich die Bahn, aber nicht die Gruppenlaufzeit, weil die Uhr jeder Nachricht für ein anderes Frequenzpaar gilt. E1 nimmt den I/NAV-Datensatz, E5a den F/NAV-Datensatz; welcher welcher ist, sagen die Datenquellen-Bits in RINEX.

Ein Bias pro Signal

Die Biases des Empfängers stellten sich als Eigenschaft des Signals heraus, nicht des Systems. Gegenüber GPS L1 verzögerte der Empfänger Galileo E1 um −219 m, GPS L5 um −2.350 m, Galileo E5a um −2.348 m, GLONASS um +1.141 m und BeiDou um −459 m, in jedem Log auf wenige Meter gleich. Galileos E5a liegt bei GPS L5, nicht bei Galileos E1. Ein Versatz pro System und ein gemeinsames L5 − L1 ließen Residuen von 45 m übrig. Der Graph hat deshalb einen Bias pro Signal: bsigb_{sig} von oben ist eine von fünf Zahlen, für B1I, E1, E5a, L5 und G1.

Die GLONASS-Kanäle driften auseinander

GLONASS trennt seine Satelliten nach Frequenz. Jeder sendet G1 auf einem Kanal kk von −7 bis +6, und der Kanal legt die Trägerfrequenz fest:

fk=1602+0,5625 k MHzf_k = 1602 + 0{,}5625\,k\ \text{MHz}
(5)

Dabei ist fkf_k die Trägerfrequenz von Kanal kk. Die Verzögerung eines Empfängers hängt von der Frequenz ab, und die Residuen reichten von etwa −4 m bei k=−7k = -7 bis +3–5 m bei k=+6k = +6, bis der Bias neben einem Versatz auch eine Steigung in kk bekam. Die Steigung lag in allen drei Logs bei +0,7 bis +0,8 m pro kk. Das gilt für diesen Chip; ein anderer ist in kk vielleicht nicht linear.

Eine Höhenwinkelmaske

Tief stehende Satelliten haben die stärksten Mehrwegefehler, und bei 25 oder mehr Satelliten bleiben ohne sie genug übrig. Signale von knapp über dem Horizont fallen deshalb weg.

15°Luft1×3,9×Empfänger510150°30°60°90°2,4 m9,3 m bei 15°Verzögerung, mHöhenwinkel
Abbildung 4. Das Signal eines tief stehenden Satelliten durchquert mehr Luft und streift auf seinem Weg mehr Boden und Gebäude. Links: der Weg durch eine Luftschicht bei 15° Höhenwinkel gegenüber senkrecht von oben. Rechts: die Verzögerung nach dem Höhenwinkel, ausgehend von 2,4 m senkrecht nach oben, mit einer allgemeinen Abbildungsfunktion 1/sin⁡ε1/\sin\varepsilon für den Höhenwinkel ε\varepsilon, einer Lehrbuchnäherung, die nahe am Horizont versagt.

Die Entfernungen gewichten

Die erste Radtour mit Satelliten kam 13 % länger heraus als ohne sie. Das Gewicht jeder Entfernung berücksichtigt inzwischen ihre Signalstärke und Fehler, die länger anhalten. Die Entfernungen einer Epoche zählen zusammen wie einige wenige unabhängige, weil die Umgebung sie alle zugleich verbiegt. Die ganze Geschichte steht im Beitrag über den Faktorgraphen.

Die Bänder haben mich überrascht. L5 und E5a passen in jeder Epoche doppelt so gut wie L1 und E1: Median-Residuen von 1,7–2,6 m gegenüber 3,2–5,4 m. Trotzdem gab ihnen die Abstimmung eine höhere Untergrenze für ihr σ als L1, keine niedrigere, weil ihre Fehler länger anhalten. GLONASS bekommt ebenfalls eine höhere, für den Kanal-Bias, den das Modell übrig lässt.

Die Ionosphäre, die ich weggelassen habe

Die Ionosphäre verzögert jedes Signal um einen Betrag, der von seiner Frequenz abhängt. Genau das erlaubt es, sie mit zwei Bändern zu messen:

If=40,3 TECf2I_f = \frac{40{,}3\ \text{TEC}}{f^2}
(6)

in Metern. TEC ist der Gesamtelektronengehalt entlang des Wegs in Elektronen pro Quadratmeter und ff die Trägerfrequenz in Hertz. Das gesendete Klobuchar-Modell kommt aus den GPS-Navigationsnachrichten, die mein Handy nie liefert. Die Datei des BKG hatte keine Kopfzeilen zur Ionosphäre. Auf diesem Handy gab es überhaupt kein Modell.

Satelliten mit zwei Frequenzen können sie messen. Die klassische Antwort ist die ionosphärenfreie Linearkombination der Pseudoentfernungen P1P_1 auf L1 und P5P_5 auf L5, wobei PP eine Pseudoentfernung auf einem Band ist, das ρ\rho von oben. Weil die Verzögerung mit dem Quadrat der Frequenz fällt, hebt eine gewichtete Differenz der beiden sie auf:

PIF=f12P1−f52P5f12−f52=γ1P1−γ5P5,γ1=f12f12−f52≈2,26,γ5=f52f12−f52≈1,26P_{IF} = \frac{f_1^2 P_1 - f_5^2 P_5}{f_1^2 - f_5^2} = \gamma_1 P_1 - \gamma_5 P_5, \qquad \gamma_1 = \frac{f_1^2}{f_1^2 - f_5^2} \approx 2{,}26, \quad \gamma_5 = \frac{f_5^2}{f_1^2 - f_5^2} \approx 1{,}26
(7)

mit f1=1575,42f_1 = 1575{,}42 MHz und f5=1176,45f_5 = 1176{,}45 MHz. Die 1/f21/f^2-Verzögerungen heben sich genau auf. Das Rauschen nicht: Bei gleichem, unabhängigem Rauschen σ auf beiden Entfernungen trägt die Kombination

σIF=γ12+γ52 σ≈2,59 σ\sigma_{IF} = \sqrt{\gamma_1^2 + \gamma_5^2}\ \sigma \approx 2{,}59\,\sigma
(8)

Beim Code eines Handys, dessen Rauschen und Mehrwegefehler bei einigen Metern liegen, ist das ein schlechter Tausch für eine Verzögerung von ein paar Metern. walker berechnet sie nie.

Ich habe es deshalb sanfter versucht: eine einzige glatte Ionosphäre, eine dünne Schale mit Gradienten, angepasst an alle L1-L5-Paare eines ganzen Logs auf einmal, zusammen mit dem L5 − L1-Bias des Empfängers, damit sich das Coderauschen herausmitteln kann. Über drei Logs ergab das senkrechte Verzögerungen von −0,5, 1,6 und 2,7 m, bei einem σ der Paare von 5–6,5 m. Angepasst an jeweils fünf Minuten schwankte sie zwischen −2,3 und 9,3 m: Das Rauschen der Paare ist viel größer als die Verzögerung. Sie herauszurechnen verschob die Lösung je Epoche um höchstens 0,7 m, in die eine wie die andere Richtung, und änderte die bereinigte Distanz der Radtour um nur 2 m. Sie bleibt im Diagnosewerkzeug und kommt nicht in die App. Die Biases pro Signal tragen die Entfernungen auf zwei Bändern.

Die Daten speichern

walker speichert die Rohmessungen und keine daraus abgeleitete Geschwindigkeit. So macht ein besserer Solver später auch alte Touren besser. Das kostet Platz. Die 1 h 16 min aufgezeichneter GPS-Punkte der Radtour kamen gepackt auf 8,5 MB, bei 64 Byte pro Messung: vier- bis fünfmal so viel, wie ich geschätzt hatte.

Verfahren Byte
walkers eigenes Format 8.541.131
LZ4, schnell (lz4_flex) 3.201.331
LZ4 HC Stufe 9 2.397.753
Deflate Stufe 6 2.300.428
Tabelle 2

Deflate ist am kleinsten, aber lz4_flex war über die Datenbank ohnehin im Build und brachte kein neues Crate mit. Die Roh-GNSS-Daten jeder Aufzeichnung liegen jetzt als LZ4-Datei neben der Datenbank, zuerst unter anderem Namen geschrieben und dann umbenannt, und mit SHA-256 geprüft. Die Datei der Radtour kam auf 3,2 MB, geschrieben in 38 ms und gelesen in 26 ms auf meinem Desktop-Rechner. Nach Spalten gepackt ließe sie sich noch viel stärker komprimieren; die Dateien tragen eine Version, das kann also später kommen.

Backups schreiben jede Datei in versiegelten Blöcken, sodass ein Jahr Touren nie auf einmal im Speicher liegt. Wie sie funktionieren, steht in Eine App ohne Server.

Was es gebracht hat

Pro Epoche, auf drei Logs, alle Signale gegenüber dem alten Satz aus GPS und BeiDou:

Log Signale pro Epoche Median-Abstand zum GPS-Punkt des Chips
9 min 9,6 → 27,6 14,6 → 7,3 m
4 min 8,4 → 25,1 17,7 → 12,0 m
28 min 11,2 → 30,7 7,8 → 4,9 m
Tabelle 3

Der Abstand zum GPS-Punkt des Chips halbiert sich im ersten Log und sinkt in den beiden anderen um etwa ein Drittel. Das ist Übereinstimmung mit dem Chip, keine Genauigkeit: Für diese Logs habe ich keinen wahren Weg.

Für die bereinigte Radtour gelten die zwei Maße aus dem Beitrag über den Faktorgraphen: wie weit die GPS-Punkte von den kartierten Wegen liegen (Median und 90. Perzentil) und wie gut zurückgehaltene Satelliten dazu passen:

Radtour, bereinigt Abstand zu den Wegen σ der zurückgehaltenen Entfernungen
ohne Satelliten 2,37 / 5,98 m 7,61 m
nur GPS L1 und BeiDou 2,29 / 5,28 m 7,57 m
alle Signale 2,24 / 5,34 m 7,51 m
Tabelle 4

Alle Signale schlagen den alten Satz beim Median und bei den zurückgehaltenen Satelliten, nicht aber beim 90. Perzentil. Ehrlich gesagt ist das wenig: Der Gewinn liegt vor allem bei den schlechtesten GPS-Punkten, und ein guter GPS-Punkt des Chips lag schon vorher nah am Weg. Außerdem kostet es Zeit: Eine Stunde mit 29 Signalen pro Epoche war in 3,5 s bereinigt, gegenüber 2,4 s mit 10, in einem Debug-Build auf meinem Desktop-Rechner.

Als Nächstes hätte ich gern eine echte Referenz: Punkte, zu denen ich gehe und die ich auf der Karte markiere, und eine Autofahrt, die auf die Mitte ihrer Fahrspur abgeglichen wird. Damit ließen sich die Gewichte an der Wirklichkeit abstimmen statt an einer Karte. Bis dahin sind die Zahlen oben die, für die ich einstehe.

walker Zeichnet Spaziergänge, Wanderungen und Radtouren mit Offline-Karten auf. Nichts verlässt dein Handy. Bald bei Google Play.