Maschinelle Übersetzung, nicht von einem Muttersprachler geprüft. Englisch ist die maßgebliche Fassung.

Empfängervertrauen und SeefahrtAuf GitHub bearbeitenQuelle: docs/MARITIME-TRUST.md

Maritimes Vertrauen: Kann die Brücke dieser Lösung vertrauen?

kshana receiver-trust kann für ein fahrendes Schiff für jede Positionslösung einen laufenden Vertrauenswert von 0-100 berechnen, aus dem, was jeder Empfänger ohnehin auf den Bus legt (zuerst NMEA 0183), und angeben, welche Prüfungen ihn gesenkt haben. Es ist eine Softwareschicht, die neben einem Empfänger sitzt. Es ist kein Empfänger, es ersetzt keinen, und es macht eine Lösung nicht genauer.

Beratende Software. Kshana ist keine typzugelassene Navigationsausrüstung (IEC 61108, IEC 61162) und wurde an keinem Leistungsstandard bewertet. Sein Wert und sein Gate sind Hilfen für das Urteil des Navigators. Der Betreiber bleibt für die sichere Navigation des Schiffes und für jede Entscheidung verantwortlich, sich auf eine Lösung zu verlassen oder sich nicht mehr auf sie zu verlassen.

Diese Seite sagt, worauf die Prüfungen schauen, was jede erfassen kann und was nicht, wie man sie live ausführt und was das Gate tut. Die Wertzuordnung und jeder Standardwert stehen in RECEIVER-TRUST.md.

Was gelesen wird#

Ein Schiff wird in der Sitzungsdatei deklariert, mit seinen vor dem Lauf angegebenen Grenzen:

[platform]
kind = "vessel"
max_speed_kn = 20.0        # includes any current you want to allow for: it limits speed over ground
max_accel_mps2 = 0.2
max_turn_rate_dps = 2.0
antenna_height_m = 18.0    # antenna above the waterline
heading_sensor = true      # the stream carries a gyro or compass heading
Satz Gelesen
GGA Position, Lösungsqualität (0 = keine Lösung), Höhe über dem mittleren Meeresspiegel, Geoidabstand, HDOP
RMC Status (A gültig, V nicht), Geschwindigkeit und Kurs über Grund, Datum, Modus
VTG Geschwindigkeit und Kurs über Grund, wo RMC keine hat
HDT, THS Steuerkurs (THS nur, wenn sein Modus nicht V ist)
VHW, VBW Fahrt durch das Wasser (VBW nur, wenn sein Status A ist)
ZDA Zeit
GSV Signalstärke je Satellit (dB-Hz), Elevation und Azimut (für die Geometrie)
GSA Dilution of Precision und verwendete Satelliten (für die Geometrie, wo GSV keinen Himmel liefert; und der angegebene HDOP, den die Schutzprüfung vergleicht)
$PKSOS,<A/F/N> ein von einem Empfänger gemeldeter OSNMA-Status, vom Adapter, der den Empfänger liest, in diesen Satz übersetzt: A authentifiziert, F fehlgeschlagen, N kein Ergebnis

Epochen, die der Empfänger selbst als keine Satellitenlösung bezeichnet (GGA-Qualität 0 oder 6 bis 8: geschätzt, manuell, Simulator; RMC-Status V oder Modus E, M, S, N), werden für die Positionsprüfungen nicht verwendet und tragen in keine Richtung Evidenz: Der Empfänger hat es bereits gesagt.

Die ersten calibration_s Sekunden bilden die Basislinie und werden nie bewertet. Jeder Monitor schaut nur auf die aktuelle und die früheren Epochen, sodass sich eine Entscheidung bei einer Epoche nicht ändert, wenn spätere Daten eintreffen, und ein Live-Strom denselben Wert liefert wie derselbe als Datei gelesene Text.

Was jede Prüfung erfasst und was nicht#

Richtungen zwischen Lösungen (die Spurpeilung, die die Drehraten-Prüfung verwendet, der Kurs, der sich aus zwei Positionen ergibt) sind die Richtung der Sehne zwischen ihnen, also das mittlere Azimut der Geodäte zwischen den Lösungen, nicht das Vorwärtsazimut an der ersten Lösung; die beiden unterscheiden sich um etwa die Hälfte der Meridiankonvergenz zwischen den Lösungen (0,001 Grad bei einer Basislinie von 260 m auf 59,5 Grad Breite).

Eine gefälschte Position muss mit der Physik eines Schiffes und mit den anderen Sensoren des Schiffes übereinstimmen. Jede Prüfung vergleicht die Lösung mit einem davon. Eine Prüfung ist nur so unabhängig wie ihre andere Quelle: Ein Steuerkurs von einem GNSS-Kompass oder eine "Fahrt durch das Wasser", die aus GNSS abgeleitet ist, ist vom geprüften Empfänger nicht unabhängig und trägt nichts bei.

Prüfung Erfasst Nicht erfassbar
kinematic einen Positionssprung; eine Spur, deren Bewegung die gemeldete Geschwindigkeit und der gemeldete Kurs nicht erklären; eine abgeleitete Geschwindigkeit, Beschleunigung oder Drehrate über den angegebenen Schiffsgrenzen ein Wegziehen, dessen gemeldete Geschwindigkeit und gemeldeter Kurs der gefälschten Spur folgen und innerhalb der Grenzen bleiben (der Empfänger leitet sie aus seiner eigenen Lösung ab, sodass sie miteinander übereinstimmen); eine zu hoch angegebene Geschwindigkeitsgrenze
heading-course eine Spur, die um mehr als den angegebenen Vorhaltewinkel davon abweicht, wohin das Schiff zeigt ein Wegziehen entlang des Kurses (der Kurs ändert sich nicht); einen Steuerkurs vom selben Empfänger oder von einem GNSS-Kompass; einen Querversatz über der Toleranz (Fehlalarm); Geschwindigkeiten unter min_speed_kn
speed-log ein Wegziehen, das die Geschwindigkeit über Grund gegenüber der Fahrt durch das Wasser verändert ein Log, das aus GNSS abgeleitet ist; eine Strömung über dem Zulässigen (Fehlalarm); ein Wegziehen, das langsamer ist als das Zulässige
sea-level eine Höhe, die nicht dort liegt, wo die Meeresoberfläche und die angegebene Antennenhöhe sie hinlegen einen Spoofer, der die Höhe plausibel hält; die Toleranz ist weit, weil der vertikale Fehler im Alleinbetrieb groß ist; der Geoidabstand wird aufgezeichnet, aber nicht geprüft, weil die Engine kein Geoidmodell hat
cn0-spread, cn0-rise die Signatur eines einzelnen Senders: C/N0 über die Satelliten hinweg, das gemeinsam einbricht oder gemeinsam steigt, gegenüber der Kalibrierungs-Basislinie einen Spoofer, der die Leistung je Satellit formt; irgendetwas, solange die Basislinie selbst gespooft ist; eine GSV-Taktung, die zu langsam ist, um zu folgen
time-consistency die Zeit des Empfängers, die unregelmäßig springt oder rückwärts läuft; gegenüber der Uhr dieses Rechners die Zeit des Empfängers, die von ihr abdriftet (nur Echtzeitströme) eine gefälschte Zeit, die konsistent und stetig ist; eine Uhr, die von Anfang an falsch geht
osnma einen gemeldeten Fehlschlag der OSNMA-Authentifizierung der Status wird gelesen, nicht verifiziert; ein Spoofer, der die Meldung unterdrückt, wird nicht gesehen
cn0-drop, loss-of-lock, agc, jam-ind Leistungsverweigerung und Verlust von Satelliten, wie im statischen Fall sie sagen, dass die Umgebung feindlich ist, nicht dass die Lösung falsch ist

Was reine NMEA-Monitore nicht können. Ein Spoofer, der die gesamte Konstellation mit einer in sich stimmigen Position, Geschwindigkeit, einem mit dem Steuerkurs verträglichen Kurs, plausibler Leistung je Satellit und einer passenden Uhr reproduziert, ist für jede obige Prüfung unsichtbar: Nichts in den Sätzen unterscheidet seine Lösung von einer echten. Ebenso wenig ein Replay aufgezeichneter echter Signale. Authentifizierung (OSNMA oder ein Empfänger mit eigener Anti-Spoofing-Funktion) und unabhängige Navigationssensoren schließen diese Lücke; diese Schicht kann nur deren gemeldeten Status verwenden. Ein Strom, der bereits gespooft wird, während sich die Basislinie bildet, hat keine saubere Basislinie. Das Ausbleiben eines Alarms ist kein Beleg für eine gute Lösung.

Vertrauenswert#

Jede Epoche nach der Kalibrierung erhält einen Wert von 0 bis 100 und die Gründe, warum er nicht 100 ist: welche Prüfungen abgezogen haben, ihre Statistik gegenüber dem Schwellenwert und ihre Punkte. Bänder (Grenzen in der Sitzung angegeben): nominal ab 90, degraded ab 55, untrusted darunter. Die Zuordnung, jedes Gewicht und sein Grund stehen in RECEIVER-TRUST.md; sie ist deterministisch und vor der Bewertung eines Logs festgelegt, ohne Lernen und ohne etwas, das an Ereignisse angepasst wäre.

Jede Schiffsausgabe trägt die Hinweisaussage: den Schlüssel advisory des Ergebnis-JSON und jeder Live-Zeile, eine erste Kommentarzeile # der CSV (Leser überspringen sie mit ihrer Kommentaroption), das <desc> und eine Fußzeile der SVG. Ausgaben eines Batch-Laufs: session.result.json (mit dem Wertmodell und den Abzügen jeder Epoche), session.trust.csv (mit den Spalten score und score_reasons) und session.trust.svg, das für ein Schiff die vom Empfänger gemeldete Spur ist, nach Vertrauensband gefärbt, über dem Wert über der Zeit.

Eine synthetische Demo#

examples/maritime-trust/ enthält ein erfundenes NMEA-Log einer Fähre auf einer Route von Tallinn nach Helsinki (ein Auszug von 50 Minuten, etwa 17 kn, 1 Hz: GGA, RMC, VTG, ein Gyro-Steuerkurs, ein Fahrtlog, GSV mit einem plausiblen Himmel), in dem ein Wegziehen der Position die gemeldete Position ab 1500 s von der echten des Schiffes entfernt. Der Empfänger meldet durchgehend eine gültige Lösung; es ist der Vertrauenswert, der fällt, durch das Band degraded in das Band untrusted. session.toml gibt vor dem Lauf jeden Schwellenwert, die Grenzen des Schiffes und jedes Wertgewicht an.

kshana receiver-trust examples/maritime-trust/session.toml
kshana receiver-trust live examples/maritime-trust/session.toml \
  --file examples/maritime-trust/tallinn-helsinki.nmea --gate --json trust.jsonl > gated.nmea

Das Log ist ein in eine Datei geschriebener Text von cargo run --example gen_maritime_trust_demo: Es modelliert kein Funksignal und sendet nichts. Es ist keine Messung, und die Route ist illustrativ, keine Seekarte. tests/receiver_trust_maritime_demo.rs legt das Log und die erwartete Ausgabe als Regressionswächter auf den synthetischen Daten fest; sie sagen nichts darüber aus, wie sich ein Monitor bei echter Störung schlägt.

Vertrauenswert über eine synthetische Passage, aus einem echten Lauf der Engine v0.40.0 auf examples/maritime-trust (ein erfundenes NMEA-Log einer Fähre auf einer Route von Tallinn nach Helsinki, 3001 Epochen bei 1 Hz). Drei Spuren teilen sich eine Zeitachse. Oben: der Abstand zwischen der vom Empfänger gemeldeten Position und der echten Position des Schiffes, der bis etwa 1576 s innerhalb weniger Meter bleibt, als das skriptgesteuerte Wegziehen der Position des Logs ihn vergrößert, während der Empfänger weiter eine gültige Lösung meldet. Mitte: der Vertrauenswert von 0 bis 100, während der ersten 300 s der Kalibrierung nicht berechnet, im Band nominal (mindestens 90) bis zum Wegziehen, dann durch das Band degraded (mindestens 55) in das Band untrusted fallend. Unten: das Band jeder Epoche als farbiges Band mit seinem Namen. Der Wert ist beratend. Beratende Software, keine typzugelassene Navigationsausrüstung (IEC 61108, IEC 61162): Der Betreiber bleibt für die Navigation des Schiffes verantwortlich. Das Log ist erfunden, um das Format und die Monitore zu zeigen; es ist keine Messung und sagt nichts darüber aus, wie sich irgendein Empfänger schlagen würde.Vertrauenswert über eine synthetische Passage, aus einem echten Lauf der Engine v0.40.0 auf examples/maritime-trust (ein erfundenes NMEA-Log einer Fähre auf einer Route von Tallinn nach Helsinki, 3001 Epochen bei 1 Hz). Drei Spuren teilen sich eine Zeitachse. Oben: der Abstand zwischen der vom Empfänger gemeldeten Position und der echten Position des Schiffes, der bis etwa 1576 s innerhalb weniger Meter bleibt, als das skriptgesteuerte Wegziehen der Position des Logs ihn vergrößert, während der Empfänger weiter eine gültige Lösung meldet. Mitte: der Vertrauenswert von 0 bis 100, während der ersten 300 s der Kalibrierung nicht berechnet, im Band nominal (mindestens 90) bis zum Wegziehen, dann durch das Band degraded (mindestens 55) in das Band untrusted fallend. Unten: das Band jeder Epoche als farbiges Band mit seinem Namen. Der Wert ist beratend. Beratende Software, keine typzugelassene Navigationsausrüstung (IEC 61108, IEC 61162): Der Betreiber bleibt für die Navigation des Schiffes verantwortlich. Das Log ist erfunden, um das Format und die Monitore zu zeigen; es ist keine Messung und sagt nichts darüber aus, wie sich irgendein Empfänger schlagen würde.

Die Abbildung wird von tools/gen_readme_assets.py aus einem echten Lauf dieser Demo gezeichnet (kshana receiver-trust examples/maritime-trust/session.toml); der Wert ist beratend, und das Log ist erfunden.

Spezifikation der Studio-Ansicht#

Für alle, die die Studio-Ansicht eines Schiffslaufs bauen. Nichts in diesem Abschnitt ist im Studio bereits implementiert; die Engine-Seite (die Daten unten) ist es.

Eingaben. Eine von beiden:

  • das Ergebnis-JSON eines Batch-Laufs (kshana receiver-trust <session.toml> oder dasselbe über receiver_trust(toml) im WebAssembly-Paket mit dem Log inline): score_model (Bandgrenzen, Rampe, Evidenz-Haltezeit, jedes Gewicht), monitors_run, states und epochs[], jeweils mit t_s, state, alarms, score.{score,band,deductions[]}, marine.{position:[lat,lon], stats, ratios} und ab 0,36 geometry und der class jedes Abzugs, mit geometry_model und geometry_summary auf oberster Ebene; oder
  • die Live-JSON-Zeilen (Schema oben), ein Objekt je Epoche, angehängt, während der Strom läuft. Jede Zeile trägt die vom Empfänger gemeldete position (Schema 1,1).

Der Demo-Satz ist examples/maritime-trust/: session.toml, tallinn-helsinki.nmea (das Log) und tallinn-helsinki.truth.csv (t_s,true_lat_deg,true_lon_deg: wo das Schiff wirklich war, was kein echtes Log hat). Eine Ansicht sollte die Sitzung ausführen und die Wahrheitsdatei daneben lesen.

Was zu zeichnen ist.

  1. Spur, Norden oben, ein Maßstab auf beiden Achsen: die vom Empfänger gemeldeten Positionen als Linie, gefärbt nach dem Band der Epoche (grau calibrating, grün nominal, bernstein degraded, rot untrusted), Anfang und Ende markiert, ein Maßstabsbalken. Für die Demo die wahre Spur als dünne neutrale Linie darunter, sodass sich das Wegziehen als Auseinanderlaufen der beiden zeigt; ein Schalter für die wahre Spur und eine Anzeige des Versatzes in Metern zur Zeit des Cursors.
  2. Wertverlauf: der Wert von 0 bis 100 über der Zeit, die Bandgrenzen (nominal_min, degraded_min aus score_model) als gestrichelte Linien, das Band als Streifen darunter und der Beginn jedes angegebenen Ereignisses als Markierung. Die Zeitachse wird mit der Spur geteilt.
  3. Gründe: für die Epoche unter dem Cursor die Abzüge (Monitor, Verhältnis zum Schwellenwert, Punkte) als waagerechte Balken, größte zuerst, mit dem Gewicht, das jeder Monitor aus score_model.weights trägt; Monitore, die liefen und nichts kosteten, blass dargestellt, Monitore, die nicht liefen (nicht in monitors_run), als "not run" aufgeführt, nie als bestanden. Der Monitor geometry hat keinen Eintrag in score_model.weights: Seine Obergrenze ist geometry_model.cap_in_force.
  4. Monitorstreifen: ein dünner Streifen je Monitor in monitors_run, der sein Verhältnis über der Zeit zeigt (Alarm bei 1), sodass ein Leser sieht, welche Prüfung sich zuerst bewegte.
  5. Gate-Zustand: in einer Live-Ansicht das gate jeder Epoche (off, passed, withheld) als Streifen unter dem Bandstreifen und das jeweils letzte $PKSHT. In einer Batch-Ansicht sind die Epochen, die ein Gate zurückgehalten hätte, jene, deren Band untrusted ist, mit angewandter Freigabe-Haltezeit.
  6. Geometriespur (0,36): ein Streifen unter dem Bandstreifen, gefärbt nach geometry.status (grün gut, bernstein degraded, grau schraffiert unbekannt), in einer Farbfamilie, die sich von den Spuren für Inkonsistenz und Umgebung unterscheidet, mit der Legende "geometry: the sky, not the signal". Abzüge, gefärbt nach class (geometry, environment, inconsistency) im Gründe-Panel und in den Monitorstreifen, und die Epochenzahlen je Klasse aus geometry_summary neben den Bandzählungen. Für die Epoche unter dem Cursor: geometry.note, n_used, HDOP, PDOP, VDOP, source, age_s und eine Markierung, wenn reported_derived_mismatch gesetzt ist (der Geometrie-Abzug ist dann eine Inkonsistenz). unknown wird als "geometry unknown: no GSV or GSA in the log" gezeigt, nie als gut. Die Schwellenwerte [geometry] und ihre Herkunft aus geometry_model stehen neben den Wert-Einstellungen. Der beratende Hinweis bleibt.
  7. Vom Empfänger gemeldete Lösung: Der Empfänger der Demo meldet durchgehend eine gültige Lösung (GGA-Qualität 1, RMC-Status A); sagen Sie das in der Legende, denn das ist der Sinn der Ansicht.

Interaktionen. Ein Zeitcursor, den jedes Panel teilt (Ziehen, Pfeiltasten und eine Abspieltaste, die mit 1x bis 60x wiedergibt); das Überfahren der Spur oder eines Streifens bewegt ihn. Ein Klick auf einen Abzug hebt die Epochen hervor, in denen dieser Monitor über seinem Einsatzpunkt lag. Ein Bandfilter (nur Epochen mit degraded und untrusted zeigen) und ein Sprung zum ersten Abzug und zur ersten Epoche mit untrusted. Hover-Text an jedem Monitornamen mit der einzeiligen Beschreibung von dieser Seite. Die Schwellenwerte und Gewichte der Sitzung werden nur lesend neben dem Diagramm gezeigt, sodass auf dem Bildschirm steht, was der Wert verwendet hat.

Wortlaut, der zu bewahren ist. Die Seite muss sagen, dass sie beratende Software und keine typzugelassene Navigationsausrüstung ist, dass die Demo synthetischer Text mit einem erfundenen Wegziehen ist und dass eine Lösung ohne Alarm dadurch keine gute Lösung ist (siehe die Grenzen oben). Keine Zahl auf der Seite sollte als Maß dafür gelesen werden, wie sich die Prüfungen bei echter Störung schlagen.

Aus dem Code#

Für Aufrufer, die die Sitzung und die Bytes im Speicher halten (keine Dateien, keine Uhr, keine Sockets; sicher für WebAssembly), hat kshana::receiver_trust::assess:

  • assess_vessel_log(session_toml, log_bytes) -> Result<ReceiverTrustResult, String>: ein ganzes Log, als Batch-Lauf bewertet; dasselbe Ergebnis wie kshana receiver-trust <session.toml>, das zum Ergebnis-JSON serialisiert (score_model, monitors_run, epochs[] mit Werten und Abzügen).
  • assess_stream_excerpt(session_toml, excerpt_bytes) -> Result<ExcerptAssessment, String>: ein begrenzter Teil eines Stroms (höchstens 2 MiB und 20.000 Epochen, und lang genug, um das Kalibrierungsfenster zu fassen), so bewertet, wie der Live-Modus bewertet, und im Live-JSON-Zeilen-Schema zurückgegeben (epochs[], das letzte $PKSHT, eine Zusammenfassung der Bandzählungen, niedrigster und letzter Wert, erste Zeit mit untrusted). Die Zeit des Empfängers wird nicht mit einer Host-Uhr verglichen. Der lang laufende Live-Modus (Sockets, eine Datei, an die angehängt wird, das Gate) gehört der Binärdatei.

Beide brauchen eine Sitzung mit [platform] kind = "vessel"; ihre Tabelle [log] ist optional.

Live ausführen#

# stdin: a serial port read by another tool, or a multiplexer's output
some-nmea-source | kshana receiver-trust live session.toml

# a log file that is being appended to (it starts at the beginning; --from-end skips what is there)
kshana receiver-trust live session.toml --file /var/log/nmea.log --follow

# a TCP server (a multiplexer or a terminal server) or UDP datagrams (a bridge network)
kshana receiver-trust live session.toml --tcp 192.0.2.10:10110
kshana receiver-trust live session.toml --udp 10110

Die Sitzung ist dieselbe session.toml wie bei einem Batch-Lauf, mit einer Tabelle [platform], die kind = "vessel" deklariert; ihre Tabelle [log] wird nicht gebraucht. Serielle Ports werden noch nicht direkt geöffnet: Lesen Sie den Port mit dem Werkzeug, das Sie bereits verwenden (stty und cat, ein Terminalserver, ein Multiplexer), und leiten Sie ihn per Pipe oder Weiterleitung weiter. Direkte serielle Eingabe kann später kommen.

Jede abgeschlossene Epoche schreibt eine JSON-Zeile auf stdout:

{"seq":941,"t_s":940.0,"time":"2025-06-14T08:15:40.000Z","state":"degraded","score":60.0,
 "deductions":[{"monitor":"heading-course","ratio":1.5,"points":40.0}],
 "alarms":["heading-course"],"gate":"off","note":null,
 "position":{"lat_deg":59.8123456,"lon_deg":24.9012345,"height_m":39.4}}

state ist calibrating, nominal, degraded oder untrusted (das Band des Werts, mit den Grenzen in der Tabelle [score] der Sitzung); score fehlt während der Kalibrierung; deductions listet auf, welche Prüfungen Punkte abgezogen haben und wie viele, größte zuerst.

JSON-Lines-Schema (Version 1,1)#

Ein JSON-Objekt je abgeschlossener Epoche, Schlüssel in dieser Reihenfolge:

Schlüssel Typ Bedeutung
seq Ganzzahl Anzahl der gemeldeten Epochen, ab 1
t_s Zahl Sekunden seit der ersten Epoche des Stroms
time Zeichenfolge oder null die Zeit der Epoche, wie der Strom sie angibt (ISO-8601 UTC mit einem Datum, sobald ein RMC gesehen wurde, sonst hh:mm:ss.mmm UTC (date not in log))
state Zeichenfolge calibrating, nominal, degraded oder untrusted
score Zahl oder null 0 bis 100, eine Dezimalstelle; null während der Kalibrierung oder wenn note sagt, warum keiner erzeugt werden konnte
deductions Array {"monitor": string, "ratio": number, "points": number, "class": string}, größte Punkte zuerst; ratio ist die Statistik über dem Schwellenwert (Alarm ab 1); nur Monitore, die Punkte gekostet haben, werden aufgeführt; class (hinzugefügt in 1,3) ist geometry, environment oder inconsistency
alarms Array von Strings Monitore auf oder über ihrem Schwellenwert
gate Zeichenfolge off, passed oder withheld
note Zeichenfolge oder null warum kein Wert erzeugt wurde (zum Beispiel ein deklarierter Steuerkurssensor, der fehlt)
position Objekt oder null (hinzugefügt in 1,1) die Position, die der Empfänger in dieser Epoche gemeldet hat, {"lat_deg", "lon_deg", "height_m"} (Höhe ellipsoidisch, wo der Satz den Geoidabstand angibt, sonst über dem mittleren Meeresspiegel); null, wenn der Empfänger keine geliefert hat, einschließlich Kalibrierungsepochen ohne Lösung
advisory Zeichenfolge (hinzugefügt in 1,2) was diese Software ist und was nicht: beratend, keine typzugelassene Navigationsausrüstung, der Betreiber bleibt verantwortlich
geometry Objekt (hinzugefügt in 1,3) die Satellitengeometrie: status (good, degraded, unknown, wenn der Strom keine GSV-Elevationen und -Azimute und kein GSA hat), reasons (few-satellites, high-pdop, high-hdop, sky-blocked), source (derived, reported, none), n_used, hdop, pdop, vdop, open_fraction, max_azimuth_gap_deg, age_s, reported_hdop, reported_derived_mismatch, note, in_view, signal_loss (Satelliten in Sicht, aber nicht verfolgt, während das DOP in Sicht gut ist: Der Geometrie-Abzug ist dann environment), label (good, fair, poor, unknown: immer gemeldet, nie bewertet; der Wert zieht nur für poor ab) (siehe RECEIVER-TRUST.md)

Monitornamen (Kebab-Case; 17): cn0-drop, agc, jam-ind, loss-of-lock, position-jump, raim, clock, solve-failure, kinematic, heading-course, speed-log, sea-level, cn0-spread, cn0-rise, time-consistency, osnma und ab 1,3 geometry. In späteren Versionen können neue Namen hinzukommen; Verbraucher sollten einen unbekannten Monitornamen als Monitor behandeln. Das unten stehende Layout $PKSHT trägt in seinem ersten Feld eine Formatversion; dieses JSON-Schema hat die Version 1,3: 1,1 fügte position hinzu, 1,2 advisory, 1,3 geometry am Ende und class in jedem Abzug, und es ändert sich nur durch Hinzufügen von Schlüsseln am Ende.

Authentifizierungseingabe#

Der Monitor osnma nimmt den Authentifizierungsstatus je Satellit von einer Authentifizierungsquelle über MarineObs::sat_auth (eine Liste von (satellite, status), Status Authenticated, Failed oder Unavailable), neben dem Gesamtwert MarineObs::osnma. Auf der NMEA-Seite wird dasselbe durch $PKSOS,<A|F|N>[,<sat>:<A|F|N>...] getragen, zum Beispiel $PKSOS,A,E11:A,E19:F. Jeder Fehlschlag, insgesamt oder bei einem Satelliten, löst den Alarm des Monitors aus und kostet sein ganzes Gewicht (er erhält das Verhältnis 1,5); ein Erfolg ist kein Beleg. Kshana verifiziert hier nichts: Die Quelle, die es tut, ist für den Status verantwortlich, den sie meldet.

Eine Epoche ist abgeschlossen, wenn der nächste zeitgestempelte Satz eintrifft; Sätze langsamerer oder unsynchronisierter Instrumente (ein Gyroskop, das einige Zehntelsekunden hinter dem Empfänger liegt), die vorher eintreffen, gehören zu ihr. Stockt der Strom für [live] idle_flush_s (Standard 1,5 s, setzen Sie es über die längste Lücke zwischen den zeitgestempelten Sätzen Ihres Empfängers), wird die Epoche so abgeschlossen, wie sie ist. Die ersten calibration_s Sekunden des Stroms bilden die Basislinie und werden nie bewertet, daher hat ein Strom, der bereits gespooft wird, wenn er zum ersten Mal verbunden wird, keine saubere Basislinie: Starten Sie die Schicht vor der Fahrt oder solange die Lösung bekanntermaßen gut ist. Das Kalibrierungsfenster schließt sich einmal, nach Eintreffen: Eine Epoche, deren Zeit früher ist als eine bereits gesehene Zeit (ein Zurückspulen, ein Replay des Stromanfangs), ist nie Kalibrierung, was auch immer ihre Zeit sagt; sie wird mit einem vollen Abzug time-consistency bewertet, der untrusted ist. Die Live-Engine bewertet jede Epoche über die Kalibrierungsepochen und die letzte Minute oder so des Stroms, sodass ihr Aufwand je Epoche mit calibration_s mal der Epochenrate wächst; halten Sie das Fenster bei einem schnellen Empfänger kurz. Ihre Puffer sind begrenzt (eine Flut von Zeilen ohne zeitgestempelten Satz wird alle 5.000 Zeilen abgeschlossen, Kalibrierung und Verlauf sind auf 20.000 Epochen begrenzt).

Die Zeit des Empfängers wird auch mit der monotonen Uhr dieses Rechners verglichen, was nur für einen in Echtzeit eintreffenden Strom etwas bedeutet. Ein gespeichertes Log, das mit voller Geschwindigkeit über stdin, TCP oder UDP eingespeist wird, löst diese Prüfung konstruktionsbedingt aus: Übergeben Sie --replay. (--file ohne --follow impliziert es bereits.) Ein --file ... --follow wird als Replay gelesen, bis es bis zu seinem Ende gelesen wurde, und die Host-Uhr wird von da an einbezogen, sodass ein Rückstau nicht als Uhrfehler gelesen wird; die Prüfung braucht dann, dass das Kalibrierungsfenster noch offen ist (sonst hat sie keine Basislinie und läuft nicht).

Stromenden und Fehler: stdin und eine bis zu ihrem Ende gelesene Datei enden normal (Exit 0). Eine vom Peer geschlossene TCP-Verbindung ist für einen Strom, der weitergehen sollte, kein normales Ende: Die Schicht endet nach dem Bewerten und Schreiben alles Empfangenen ungleich null und verbindet sich nicht neu, führen Sie sie also unter einem Supervisor aus, der sie neu startet. UDP-Datagramme, die einen Satz teilen, werden zusammengefügt; die Leser von stdin, einer Datei und TCP werden von einer begrenzten Warteschlange gestützt, die auf den Sender zurückdrückt (nichts geht verloren), während UDP, das nicht zurückdrücken kann, Datagramme verwirft, die die Engine nicht annehmen kann, und dies auf stderr meldet. --udp <port> bindet an die Loopback-Adresse; geben Sie --udp <addr>:<port> an, um anderswo zu lauschen (eine Warnung wird ausgegeben).

$PKSHT: der proprietäre Satz#

Jede Epoche erzeugt außerdem einen NMEA-0183-Satz mit gültiger Prüfsumme, den --pksht <path|-> in eine Datei oder auf stdout schreibt und den das Gate in den weitergeleiteten Strom einfügt:

$PKSHT,1,080140.25,30.0,U,W,heading-course:40.0/cn0-spread:30.0*2F
Feld Bedeutung
1 1: die Formatversion
2 UTC-Zeit der Epoche, hhmmss.ss; leer, wenn der Strom keine geliefert hat
3 Vertrauenswert 0 bis 100, eine Dezimalstelle; leer während der Kalibrierung oder wenn keiner erzeugt werden konnte
4 Band: C calibrating, N nominal, D degraded, U untrusted
5 Gate: - off, P passed, W withheld (die Lösung wurde im weitergeleiteten Zyklus als ungültig markiert)
6 bis zu zwei Gründe, monitor:points, verbunden durch /; leer, wenn nichts abgezogen wurde

Die Adresse ist P + das Herstellerkürzel KSH + T. Ausrüstung, die einen proprietären Satz nicht kennt, ignoriert ihn. Kshana ignoriert sein eigenes $PKSHT bei der Eingabe.

Gate-Modus#

--gate stellt Kshana zwischen den Empfänger und die Ausrüstung, die seine Lösung verwendet (ein Kartensystem, ein Kursregelsystem). Der NMEA-Strom geht hinein, kommt auf stdout heraus und wird:

  • unverändert durchgereicht, solange die Epoche nicht untrusted ist (und während der Kalibrierung), mit einem $PKSHT nach jedem Satzzyklus; und
  • als ungültig markiert, solange sie untrusted ist: GGA-Qualität 0; RMC-Status V (und sein Modusindikator N und der Navigationsstatus V, wo vorhanden); GNS-Modus N in jeder Position; GLL-Status V und Modus N; VTG-Modus N, wo es einen hat. Die Positionsfelder bleiben, wie sie waren: Der Sinn ist, dass die Ausrüstung sieht, dass der Empfänger selbst die Lösung für ungültig erklärt, und ihren eigenen Alarm auslöst. Bei jedem umgeschriebenen Satz wird die Prüfsumme neu berechnet.

Einmal zurückgehalten, wird die Lösung erst freigegeben, nachdem die Epochen für [live] gate_release_s (Standard 30 s) außerhalb des Bands untrusted waren, sodass ein Wert an der Bandgrenze die Lösung nicht flackern lassen kann. Die JSON-Zeilen gehen nur dorthin, wohin --json <path> es angibt (standardmäßig nirgendwohin, weil der Strom stdout hat).

receiver-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl | downstream-equipment

Damit sich ein Kartenplotter direkt verbinden kann, stellen Sie den gesperrten Strom statt auf stdout über TCP bereit:

receiver-nmea-source | kshana receiver-trust live session.toml --gate --listen tcp:10110

--listen tcp:<port> lauscht an der Loopback-Adresse; tcp:<addr>:<port> lauscht anderswo (eine Warnung wird ausgegeben, weil jeder, der die Adresse erreichen kann, den Strom lesen kann). Beliebig viele Clients können sich verbinden; jeder erhält denselben Strom ab dem Moment, in dem er sich verbindet, und Clients lesen nur. Jeder Client hat seine eigene begrenzte Warteschlange und seinen eigenen Writer, sodass einer, der nicht mithalten kann, fallen gelassen wird (seine Verbindung wird geschlossen, eine Zeile auf stderr) und nie die anderen oder die Eingabe verzögert. --listen braucht --gate; stdout trägt dann nichts vom Strom, daher ist --json - frei.

Was das Gate nicht tut und was Sie vor der Verwendung wissen sollten:

  • Es ist ein Opt-in. Nichts markiert eine Lösung als ungültig, es sei denn, --gate wird angegeben.
  • Es fügt Latenz hinzu: Ein Zyklus wird zurückgehalten, bis seine Epoche bewertet ist, also bis zum nächsten zeitgestempelten Satz (etwa ein Zyklus: eine Sekunde bei einem 1-Hz-Empfänger), oder idle_flush_s nach dem letzten, wenn der Strom stockt. Ausrüstung, die einen Satz innerhalb einiger zehn Millisekunden nach der Ausgabe des Empfängers braucht, darf nicht dahinter sitzen.
  • Es ist ein einzelner Punkt in der Kette: Wenn es stoppt, stoppt der Strom. Führen Sie es beaufsichtigt aus und legen Sie im Voraus fest, was die nachgeschaltete Ausrüstung ohne Strom tut.
  • Es schlägt bei eigenen Fehlern geschlossen fehl: Wenn die Monitore nach der Kalibrierung keinen Wert erzeugen können (ein deklarierter Steuerkurssensor, der nichts sendet, zu wenige Kalibrierungsepochen), ist die Epoche untrusted, trägt ein note und wird zurückgehalten; die Freigabe-Haltezeit wird auf der Uhr dieses Rechners gemessen, nicht auf der Zeit des Empfängers, die ein Spoofer kontrolliert (bei einem Replay gibt es nur die Zeit des Empfängers).
  • Es kann eine gute Lösung zurückhalten (ein Fehlalarm) ebenso wie eine gespoofte durchlassen (ein Verpasser). Die Monitore prüfen eine Lösung gegen die Physik eines Schiffes und seine anderen Sensoren; eine Fälschung, die mit allen davon konsistent ist, wird nicht gesehen (siehe die Grenzen unten).
  • Es erwartet einen reinen NMEA-0183-Textstrom. In den Strom gemischte Binärrahmen werden unverändert weitergeleitet, aber ein $PKSHT kann dann zwischen den Bytes eines Rahmens landen.
  • Es ist nicht typzugelassen, und nichts darin wurde gegen IEC 61108 oder IEC 61162 bewertet. Der Betreiber bleibt für die Navigation des Schiffes verantwortlich.