Maskinöversättning, inte granskad av en modersmålstalare. Engelska är referensen.

Mottagarförtroende och sjöfartRedigera på GitHubKälla: docs/MARINE-INTEGRATIONS.md

Marina integrationer: förtroendepoängen på bryggan

Kshanas maritima förtroendepoäng (MARITIME-TRUST.md) kan nås från programvara som båtägare redan kör: ett insticksprogram för servern Signal K och OpenCPN via NMEA i gate-läge över TCP. En referensbyggnad placerar den på en liten dator bredvid mottagaren.

Rådgivande programvara. Kshana är inte typgodkänd navigationsutrustning (IEC 61108, IEC 61162) och har inte bedömts mot någon prestandastandard. Allt på den här sidan är ett stöd för navigatörens omdöme. Operatören är fortsatt ansvarig för fartygets säkra navigering och för varje beslut att lita på, eller att sluta lita på, en positionsbestämning. Ingenting här sänder, och ingenting här gör en positionsbestämning mer exakt.

Del Var Status i 0,35
Signal K-plugin integrations/signalk/ levererad, enhetstestad på inspelade syntetiska utdata; inte publicerad på npm
OpenCPN via NMEA i gate-läge över TCP integrations/opencpn/ levererad och testad (uppspelning på konsumentsidan); själva OpenCPN:s användargränssnitt styrs inte av något test
Inbyggt insticksprogram för poängpanel i OpenCPN integrations/opencpn/plugin/ byggd, logiken enhetstestad och körd inuti OpenCPN 5.8.4 under en virtuell skärm (belägg i integrations/opencpn/evidence/); inte paketerad för insticksprogramhanteraren; levereras först efter granskning
Referensbyggnad deploy/reference-build/ delar, OS-steg, systemd-enheter (kontrollerade med dry-run), ett containeralternativ; inte testad på ett fartyg

Allt läser en enda sak: utdata från kshana receiver-trust live (JSON-rader, meningen $PKSHT, gaten). Trådformaten finns i MARITIME-TRUST.md. Signal K-insticksprogrammet samlar sin kunskap om dem i en enda fil, integrations/signalk/lib/adapter.js; en formatändring är en ändring i en fil.

Signal K-plugin#

Inga npm-beroenden. Själva insticksprogrammet körs på Node 18 eller nyare; aktuella versioner av signalk-server kräver Node 22 eller nyare, så i praktiken använder du 22. Kopiera eller länka integrations/signalk/ till serverns node_modules (till exempel ~/.signalk/node_modules/signalk-kshana-trust), starta om servern och aktivera Kshana GNSS trust under Server, Plugin Config.

Varifrån epokerna kommer (source)#

source Vad insticksprogrammet gör
spawn-signalk-nmea (standard) Kör kshana receiver-trust live <sessionFile> och skriver varje rå NMEA 0183-mening som servern tar emot (serverns nmea0183-händelse) till dess standardindata. Startar om det, med back-off, om det avslutas | Använd det bara på en server med en enda NMEA-källa: det matar in varje mening från varje leverantör, sammanflätade, så en andra GNSS-mottagare eller AIS ser ut som en mottagare vars position hoppar och kan poängsättas som spoofing. Med fler än en källa använder du spawn-args med den mottagarens egen ström --tcp, eller tcp-pksht från en gate.
spawn-args Kör kshana receiver-trust live <sessionFile> <inputArgs...>, till exempel ["--tcp","192.0.2.10:10110"] eller ["--udp","10110"]
tcp-json Ansluter till en ström av de JSON-rader som kshana skriver (till exempel från reläet i integrations/opencpn/)
tcp-pksht Ansluter till en NMEA-ström (till exempel gate-utdata från tjänsten eller containern i referensbyggnaden, port 10110) och läser bara dess $PKSHT-meningar

En ström som redan utsätts för spoofing när övervakaren först ansluter har ingen ren baslinje (de första calibration_s sekunderna poängsätts aldrig). Starta den före resan.

Publicerade sökvägar#

Varje epok uppdaterar (källa kshana-trust):

Sökväg Värde
navigation.gnss.kshana.band calibrating, nominal, degraded eller untrusted
navigation.gnss.kshana.score 0 till 100, eller null under kalibrering
navigation.gnss.kshana.reasons [{monitor, points}], största först: vilka kontroller som sänkte poängen
navigation.gnss.kshana.alarms de övervakare som för närvarande ligger över sin tröskel
navigation.gnss.kshana.gate off, passed eller withheld (när en gate körs någon annanstans; null från $PKSHT när den saknas)
navigation.gnss.kshana.reportedPosition {latitude, longitude, altitude}: den position som mottagaren under test rapporterade vid epoken (JSON-schema 1,1 eller senare; publiceras inte när strömmen inte bär någon, till exempel från $PKSHT eller en äldre kshana). Endast som förtroendekontext: insticksprogrammet skriver aldrig navigation.position, så fartygets egen positionssökväg lämnas orörd
notifications.navigation.gnss.kshana.trust utlöses när tillståndet ändras: {state, method, message}

Insticksprogrammet skickar också Signal K-metadata för de här sökvägarna en gång vid start. score är Kshanas förtroendepoäng från 0 till 100, en poäng och inte en kvot eller en sannolikhet, så den har ingen SI-enhet; dess metadata anger intervallet, en beskrivning och zoner som följer tröskelvärdena nedan. reasons[].points är poängenheter som dras av från den poängen på 0 till 100.

Notifieringen är normal, alert, warn eller alarm. Den rensas genom att tillståndet normal publiceras, inte null: en konsument som bara behandlar null som rensad bör behandla normal som rensad också. Som standard ger bandet degraded warn och bandet untrusted ger alarm, med method: ["visual","sound"]. Den sänks efter clearAfterEpochs epoker i ett bättre tillstånd. Om ingen epok anländer på staleAfterS sekunder varnar den för att poängen inte uppdateras. Kalibrering utlöser aldrig en notifiering. Källan $PKSHT har ingen lista alarms (meningen har bara bandet, poängen och de två främsta orsakerna).

Konfiguration (varje tröskel)#

Nyckel Standardvärde Betydelse
source spawn-signalk-nmea se ovan
command kshana den körbara filen (spawn-lägen). Den kör vilken körbar fil som helst som serverns användare: bara en administratör för Signal K-servern bör kunna ändra insticksprogrammets konfiguration
sessionFile /etc/kshana/session.toml fartygets gränser, trösklar och poängvikter (spawn-lägen)
inputArgs [] argument som läggs till i kshana receiver-trust live <sessionFile> i båda spawn-lägena: indata för spawn-args, extra flaggor som --replay (en lagrad logg som matas snabbare än realtid) för spawn-signalk-nmea. Insticksprogrammet vägrar --gate, --listen, --json och --pksht (det läser kshanas JSON på standardutdata), och för spawn-signalk-nmea också indataflaggorna (--stdin, --file, --tcp, --udp, --follow, --from-end)
host, port 127.0.0.1, 10111 TCP-lägen (gaten serverar på 10110: ange porten för tcp-pksht)
thresholdMode band band: det band som Kshana rapporterar, med gränserna i sessionsfilen. score: de två poängen nedan
warnBelowScore 90 Läget score: under detta är tillståndet degradedState (Kshanas standardgräns för nominal)
alarmBelowScore 55 Läget score: under detta är tillståndet alarm (Kshanas standardgräns för degraded)
degradedState warn tillstånd för bandet degraded: normal, alert eller warn
raiseAfterEpochs 1 på varandra följande epoker i ett sämre tillstånd innan notifieringen utlöses
clearAfterEpochs 10 på varandra följande epoker i ett bättre tillstånd innan den sänks
staleAfterS 10 varna när ingen epok anländer på så här lång tid; 0 stänger av det
method ["visual","sound"] notifieringsmetoder

Insticksprogrammet gatar inte: det ändrar aldrig en positionsbestämning. Att markera en positionsbestämning som ogiltig för ett kartsystem är gaten, nedan.

Tester#

cd integrations/signalk && npm test

node:test, inga beroenden, inget nätverk utöver 127.0.0.1. Testerna tolkar och spelar upp ett utdrag på 66 epoker av de JSON-rader och $PKSHT-meningar som kshana receiver-trust live skrev för den syntetiska Östersjödemon (påhittade data, endast text), och kontrollerar överensstämmelsen mellan de två formaten, håll- och rensningsbeteendet, poängläget, inaktualitet och de tre indatavägarna mot ett lokalt flöde och en stand-in-barnprocess. Testerna startar ingen verklig Signal K-server; en separat skriptad körning gör det, se nedan.

Körning i en verklig Signal K-server#

integrations/signalk/evidence/ innehåller ett skript som läser in insticksprogrammet i det fästa paketet signalk-server 2.33.0 (i ett privat nätverksnamnrymd med endast loopback) och registrerar vad serverns egna REST- och WebSocket-API:er visar. Förtroendesökvägarna visas, notifieringen går warn, alarm, normal (efter hållet) och warn igen när data upphör, och med verkliga kshana matad av serverns egen NMEA-indata publicerade den också reportedPosition, aldrig navigation.position. En serverversion, en körning, inget verkligt fartyg; begränsningar och reproduktion finns i belägg-README.

OpenCPN#

OpenCPN läser NMEA från nätverket, och kshana receiver-trust live --gate kan själv servera den gatade strömmen på en TCP-port.

Rekommenderas: den direkta anslutningen.

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

(some-nmea-source är mottagarens serieport läst med stty och cat, en multiplexer, eller indata --tcp/--udp i kshana självt; referensbyggnadens kshana-gate.service gör detta under systemd.) --listen tcp:<port> binder loopback-adressen; valfritt antal skrivskyddade klienter kan ansluta, och en som inte hinner med kopplas bort utan att fördröja de andra.

Alternativ: reläet. integrations/opencpn/nmea-tcp-relay.mjs är en beroendefri Node-fan-out som gör detsamma för en kshana utan --listen, eller serverar vilken annan radström som helst (containeralternativet använder den för JSON-epokerna):

some-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl \
  | node integrations/opencpn/nmea-tcp-relay.mjs --listen 10110

Den vidarebefordrar byte oförändrade, bara hela rader, och kopplar bort en klient som inte läser. Föredra den direkta anslutningen: en process mindre i kedjan.

I OpenCPN: Options, Connections, Add Connection, Network, protokoll TCP, adress 127.0.0.1, port 10110, riktning Input. Så länge förtroendet inte har kollapsat är strömmen mottagarens egen, plus en $PKSHT-mening per cykel. När det har kollapsat har den vidarebefordrade GGA kvalitet 0, RMC status V, och lägesindikatorerna anger ingen positionsbestämning, med omräknade kontrollsummor: utrustningen ser att mottagaren själv förklarar positionsbestämningen ogiltig och utlöser sitt eget larm. Meningarna $PKSHT syns i OpenCPN:s NMEA-felsökningsfönster (Options, Connections, "NMEA debug window"). Positionsfälten lämnas som de togs emot.

Läs "Gate mode" i MARITIME-TRUST.md innan du förlitar dig på detta: det är ett tillval, ger fördröjning (en cykel hålls tills dess epok har poängsatts), är en enskild punkt i kedjan och kan hålla tillbaka en bra positionsbestämning lika väl som släppa igenom en förfalskad.

Tester#

cd integrations/opencpn && npm test

test/relay.test.mjs spelar upp ett inspelat utdrag av den syntetiska gatade strömmen (186 meningar kring det ögonblick då förtroendet kollapsar, skrivna av kshana receiver-trust live --gate) genom reläet över en verklig TCP-socket och kontrollerar vad en konsument tar emot: strömmen byte för byte under godtycklig styckning; giltiga kontrollsummor på varje mening, även omskrivna; GGA och RMC som är överens, giltiga och sedan ogiltiga utan flimmer; en $PKSHT per cykel med sitt gate-fält W exakt där positionsbestämningen är ogiltig; två identiska konsumenter; en ofullständig rad vidarebefordras aldrig. Detta kontrollerar den ström OpenCPN får, inte OpenCPN:s egen skärm.

En kontroll från början till slut med den verkliga binären, inte en del av standardtesterna (den kräver en byggd kshana):

KSHANA_BIN=target/release/kshana npm run e2e            # kshana --gate --listen | TCP consumer; the consumer's bytes must equal the gate's stdout
KSHANA_BIN=target/release/kshana npm run e2e -- relay   # kshana --gate | relay | TCP consumer

Båda kör den syntetiska demon på en timme och kontrollerar att positionsbestämningen blir giltig, sedan ogiltig, med en $PKSHT per epok.

Inbyggt insticksprogram#

integrations/opencpn/plugin/ är en poängpanel för OpenCPN (poäng, band, gate, främsta orsaker, en varning när förtroendet blir untrusted) som läser $PKSHT från OpenCPN:s egen NMEA-ström, så den behöver ingen annan anslutning än den ovan. Den byggs med CMake mot OpenCPN:s API-header för insticksprogram (medföljer, med sin källcommit) och wxWidgets; ctest kör de wx-fria logiktesterna och kontrollerar att biblioteket exporterar de ingångspunkter som OpenCPN slår upp. Den har körts inuti OpenCPN 5.8.4 under en virtuell skärm på den syntetiska gatade strömmen (OpenCPN gav $PKSHT till insticksprogrammet, panelen blev röd och OpenCPN:s egen position frös när gaten slog till; skärmbilder, logg och skript i integrations/opencpn/evidence/), men inte på ett verkligt skrivbord, andra versioner eller plattformar, och den är inte paketerad för OpenCPN:s insticksprogramhanterare. Se insticksprogrammets README.md. Den är licensierad under GPL-3.0-or-later, till skillnad från resten av förrådet (LICENSING.md).

Skärmbilder från den körningen, i integrations/opencpn/evidence/ (en körning, OpenCPN 5.8.4 under en virtuell skärm, syntetiska data; README.md anger begränsningarna):

OpenCPN:s kartfönster som kör insticksprogrammet Kshana score panel på den syntetiska gatade strömmen, före förtroendekollapsen: ingen panel är öppen (den öppnar sig själv vid larm), fartygets position i statusfältet lyder 54 32,4659 N 018 46,1670 E med hastighet 16,48 kn och kurs 088, och positionsindikatorn uppe till höger visar tre staplar. Samma OpenCPN-fönster efter kollapsen: panelen Kshana är öppen i rött med poängen 47 och ordet UNTRUSTED, raderna gate: fix marked invalid, cn0-spread -30.0, speed-log -21.0 och age 2 s, och uttalandet att detta är rådgivande programvara, inte typgodkänd navigationsutrustning och att operatören är fortsatt ansvarig. Statusfältet lyder fortfarande 54 32,4672 N 018 46,2227 E, och positionsindikatorn har sjunkit till två staplar. OpenCPN matat direkt av kshana receiver-trust live --gate --listen: panelen Kshana är öppen i rött med poängen 44 och UNTRUSTED, raderna gate: fix marked invalid, cn0-spread -30.0, speed-log -18.8 och age 1 s, samt det rådgivande uttalandet. Den här körningen stöder inte observationen att positionen fryser: OpenCPN höll fortfarande på att arbeta av den inledande skuren av epoker.

Dessa visar ledningsdragningen och att den gatade positionsbestämningen når OpenCPN, inte att något larm är i rätt tid eller korrekt för ett verkligt fartyg. Rådgivande programvara, inte typgodkänd utrustning.

Referensbyggnad#

deploy/reference-build/: en generisk dellista, OS-installation, två systemd-enheter (den rådgivande övervakaren och den valfria gaten), ett containeralternativ och Signal K-kopplingen. deploy/reference-build/check-units.sh kör systemd-analyze verify på enheterna utan att starta något.

Begränsningar#

  • Poängen är bara så bra som kontrollerna bakom den, som tittar på ett fartygs fysik och dess andra sensorer; en självkonsistent förfalskning med en matchande klocka ses inte av övervakare som bara använder NMEA (MARITIME-TRUST.md). Frånvaro av larm är inget belägg för en bra positionsbestämning.
  • Ingen siffra på den här sidan är en uppmätt detektions- eller falsklarmsfrekvens. Testerna ovan kontrollerar ledningsdragningen på syntetisk text; de säger ingenting om hur någon övervakare klarar sig mot verklig störning.
  • Inte typgodkänd; operatören är fortsatt ansvarig.