In diesem Beitrag beschreibe ich, wie ich ein robustes real-time failover für GNSS auf Basis von Raspberry Pi und mehreren USB‑GNSS‑Empfängern aufgebaut habe. Ziel war, GPS‑Ausfälle bei wechselnden Sichtbedingungen (z. B. Bewuchs, Hallen, Maschinenaufbauten) abzufangen, ohne dass Verbraucher (Drohnensteuerung, Präzisionslenksysteme, Telemetrie) ins Leere laufen. Ich erkläre Komponenten, Architektur, Software‑Konzept und praktische Implementation mit Hinweisen zu Tests und Tuning.
Warum ein RT‑Failover nötig ist
In der Praxis reicht oft ein einzelnes GNSS‑Patch nicht aus: Multipath, Abschattung durch Anbauten oder kurzzeitige Störungen (z. B. NLOS, Solarstörungen) führen zu schlechten Fixes oder ganzem Verlust. Mein Ziel war, Ausfallzeiten zu minimieren und eine nahtlose Umschaltung auf ein anderes Gerät zu ermöglichen, sobald dessen Messqualität besser ist — und das alles in Realtime, also ohne manuelle Eingriffe.
Grundprinzip der Lösung
Die Grundidee ist simpel: mehrere unabhängige GNSS‑Empfänger (USB) an einem Raspberry Pi betreiben, die Positionsdaten kontinuierlich überwachen und anhand klarer Qualitätskriterien in Echtzeit den besten Datenstream an die Verbraucher weiterreichen. Wichtige Punkte:
Mehrere Empfänger statt Kombigerät — hardwareseitige Diversität reduziert gemeinsame Ausfallursachen.Qualitätsmetriken wie Anzahl Satelliten, SNR (Signal‑to‑Noise‑Ratio), Fix‑Type (3D/RTK/none), PDOP und Solution Age entscheiden.Hysterese und Mindesthaltezeit verhindern Flapping bei schwankenden Bedingungen.Virtualisierung des Outputs (Pseudo‑TTY / NMEA TCP) erlaubt transparente Nutzung durch existierende Software.Benötigte Hardware
| Komponente | Beispiele | Kommentar |
| Raspberry Pi | Raspberry Pi 4 (2GB/4GB) | Ausreichend CPU; empfehle eMMC oder schnelle SSD |
| GNSS‑Empfänger (USB) | u-blox ZED‑F9P, u-blox NEO‑M8T, u-blox M10 | Mind. 2–3 verschiedene Module, F9P für RTK/Multiband |
| USB‑Hubs | passiv/aktiv, mit guter Erdung | Schutz vor Spannungsabfall; powered hub falls viele Geräte |
| PPS‑Verkabelung | falls verfügbar | für Zeitreferenz (optional) |
| GPS‑Antenne(n) | magnetisch/Flach, Multiband empfohlen | unterschiedliche Antennenstandorte erhöhen Diversity |
Softwarestack
Für meine Lösung verwende ich eine Kombination aus bewährten Open‑Source‑Tools und einem kleinen Python‑Daemon, der das Failover steuert:
gpsd als Daemon, der mehrere GPS‑Devices liest und JSON‑Output bereitstellt.chrony oder systemd‑timesyncd für Zeitreferenz, zusammen mit PPS falls vorhanden.Ein selbstgeschriebener Failover‑Daemon (Python), der per gpsd‑JSON die Qualität der Geräte überwacht, das beste auswählt und NMEA an eine virtuelle Schnittstelle (PTY) weiterleitet. Alternativ kann socat verwendet werden.Optionale Integration: RTKLIB für RTK/PPP, NTRIP‑Client falls Korrekturdaten benötigt werden.Warum nicht nur gpsd‑Fusing?
gpsd kann mehrere Geräte gleichzeitig bedienen und liefert ein fused view, das manchmal ausreichend ist. Problem: gpsd macht intern Entscheidungen, die nicht immer optimal auf Präzisions‑ oder Ausfallszenarien abgestimmt sind (z. B. subtile Wechsel bei SNR). Ich wollte volle Kontrolle über Switch‑Logik, Hysterese und Extrapolation — daher der externe Daemon.
Implementations‑Skizze (Praxis)
So habe ich das bei mir umgesetzt:
Alle USB‑Empfänger werden erkannt (/dev/ttyUSB0, /dev/ttyUSB1, …). gpsd ist so konfiguriert, dass es alle liest: /etc/default/gpsd — DEVICES="/dev/ttyUSB0 /dev/ttyUSB1".Ein Python‑Daemon verbindet sich mit gpsd (JSON‑Stream über TCP 2947) und sammelt für jedes Gerät periodisch Metriken: satelliten_count, snr_avg, mode (1/2/3), eph_age, climb/ground speed plausibility.Anhand von Gewichtungsfaktoren berechnet der Daemon einen Score pro Gerät. Beispiel‑Gewichtung: FixType (3D/RTK)=+50, Satelliten>8 = +20, SNR Mittelwert>30dB = +20, PDOP<2 = +10, Age<1s = +10.Das Gerät mit höchstem Score wird als Primary gesetzt — nur wenn es einen signifikanten Vorsprung hat (z. B. +15 Punkte) wird sofort geswitcht; sonst bleibt der aktuelle Primary solange gehalten (Hysterese 5–10s).Der Daemon öffnet für Verbraucher eine virtuelle Pseudo‑TTY (z. B. /dev/pts/10) und schreibt dort entweder NMEA (durch Weiterleiten der Originalbytes) oder ein berechnetes/fused NMEA‑Sentence.Optional: Während kurzer Ausfälle kann ein einfacher Dead‑Reckoning‑Modus ("Holdover") eingesetzt werden: letze Pos + Geschwindigkeitsvektor linear extrapoliert für bis zu X Sekunden, bevor ein Fallback‑Alarm ausgelöst wird.Beispiel: Monitoring‑Logik (vereinfacht)
Die Logik ist bewusst pragmatisch:
Erfasse Daten alle 0.5–1s.Filtere Geräte mit mode==1 (no fix) sofort von primärer Auswahl aus.Berechne Score = a*fix + b*sat + c*snr + d*(1/pdop) + e*(1/age).Wenn current_primary.Score < best.Score − threshold => switch.Bei Switch: flush Pseudo‑TTY Buffer, beginne Umschaltung mit einer kleinen Überlappungsphase (500–1000ms), um abruptes Verhalten der Verbraucher zu vermeiden.Praktische Implementationshinweise
Setze verschiedene Antennenstandorte wenn möglich, auch kleinere Versätze (z. B. Dach vs. Front) geben Diversity.Nutze unterschiedliche Chipsets (u‑blox + andere) — gleiche Störung ist dann weniger wahrscheinlich.Logge alle Switches und Scores ausführlich; beim Testen war das der wichtigste Debug‑Hebel.Testfälle: simulierte Abschattung (Hand über Antenne), Multipath durch Metallplatten, temporärer USB‑Pull, GPS‑Jamming/Simulationstest (vorsichtig!).Lege fest, welche Verbraucher wie reagieren sollen: Manche Software kann NMEA‑Fehler nicht gut verarbeiten — in dem Fall lieber stabile Holdover‑Sätze senden statt abrupt disconnects.Beispielhafte Kommandos & Tools
Einige nützliche Kommandos, die ich verwendet habe:
gpsd starten: sudo systemctl enable --now gpsd.socketgpsmon/gpspipe zum Debug: gpspipe -r -n 10 oder cgps -sPTY erstellen/written per Python: modul pty + os.openpty(); alternativ socat: socat -d -d /dev/ttyUSB0 PTY,link=/dev/virtualGPS0,raw,echo=0Testen und Bewertungsmetriken
Für eine belastbare Lösung habe ich folgende Metriken erfasst und ausgewertet:
Mean Time To Failure (MTTF) eines einzelnen Empfängers unter verschiedenen Bedingungen.Anzahl und Dauer der Switches pro Stunde (zu häufig = schlecht).Mean Position Error (gegen Ground Truth) in Szenarien mit Abschattung.Maximale Zeit, die Holdover tolerierbar ist, bis Verbraucher signifikante Fehler melden.Weiterführende Optionen
Wer mehr Präzision braucht, kombiniert das System mit RTKLIB und NTRIP‑Korrekturen. Für mobile Fahrzeuge ist die Integration von IMU/Wheel‑Encoder sinnvoll, um lange Ausfälle per Dead‑Reckoning zu überbrücken. Für industrielle Umgebungen lohnt sich zudem ein Watchdog‑Mechanismus, um den Pi oder den Daemon bei Hänger neu zu starten.
Wenn du möchtest, kann ich dir den Python‑Daemon als Vorlage zusammenstellen (mit Score‑Berechnung, gpsd‑Client und PTY‑Output) oder eine Liste empfehlenswerter USB‑GNSS‑Kombinationen für deinen Einsatzzweck erstellen. Sag mir kurz, welche Verbraucher (Software/Hardware) die Daten bekommen sollen und welche Umgebungsbedingungen typisch sind — dann passe ich die Empfehlung an.