Maritime integrasjoner: tillitsscoren på broen
Kshanas maritime tillitsscore (MARITIME-TRUST.md) er tilgjengelig fra programvare som båtfolk allerede bruker: en Signal K-serverplugin og OpenCPN gjennom NMEA i gate-modus over TCP. En referansebygging setter den på en liten datamaskin ved siden av mottakeren.
Veiledende programvare. Kshana er ikke typegodkjent navigasjonsutstyr (IEC 61108, IEC 61162) og er ikke vurdert mot noen ytelsesstandard. Alt på denne siden er et hjelpemiddel for navigatørens skjønn. Operatøren er fortsatt ansvarlig for fartøyets sikre navigasjon og for enhver beslutning om å stole på, eller slutte å stole på, en posisjonsbestemmelse. Ingenting her sender noe, og ingenting her gjør en posisjonsbestemmelse mer nøyaktig.
| Del | Hvor | Status i 0,35 |
|---|---|---|
| Signal K-plugin | integrations/signalk/ |
levert, enhetstestet på registrert syntetisk utdata; ikke publisert til npm |
| OpenCPN via NMEA i gate-modus over TCP | integrations/opencpn/ |
levert og testet (avspilling på forbrukersiden); selve OpenCPN-brukergrensesnittet styres ikke av noen test |
| OpenCPNs innebygde plugin med scorepanel | integrations/opencpn/plugin/ |
bygget, logikken enhetstestet, og kjørt inne i OpenCPN 5.8.4 under en virtuell skjerm (evidens i integrations/opencpn/evidence/); ikke pakket for plugin-behandleren; leveres først etter gjennomgang |
| Referansebygging | deploy/reference-build/ |
deler, OS-trinn, systemd-enheter (kontrollert med tørrkjøring), et containeralternativ; ikke testet på et fartøy |
Alt dette leser én ting: utdataene fra kshana receiver-trust live (JSON-linjer, setningen $PKSHT, gaten). Trådformatene står i MARITIME-TRUST.md. Signal K-pluginen holder kunnskapen om dem i én fil, integrations/signalk/lib/adapter.js; en formatendring er en endring i én fil.
Signal K-plugin#
Ingen npm-avhengigheter. Selve pluginen kjører på Node 18 eller nyere; gjeldende signalk-server-utgivelser krever Node 22 eller nyere, så bruk i praksis 22. Kopier eller lenk integrations/signalk/ inn i serverens node_modules (for eksempel ~/.signalk/node_modules/signalk-kshana-trust), start serveren på nytt og aktiver Kshana GNSS trust under Server, Plugin Config.
Hvor epokene kommer fra (source)#
source |
Hva pluginen gjør |
|---|---|
spawn-signalk-nmea (standard) |
Kjører kshana receiver-trust live <sessionFile> og skriver hver rå NMEA 0183-setning serveren mottar (serverens nmea0183-hendelse) til standard inn. Starter den på nytt, med tilbakeslag, hvis den avslutter | Bruk den bare på en server med én enkelt NMEA-kilde: den mater inn hver setning fra hver leverandør, sammenflettet, så en andre GNSS-mottaker eller AIS ser ut som én mottaker hvis posisjon hopper og kan bli scoret som spoofing. Med mer enn én kilde, bruk spawn-args med den mottakerens egen --tcp-strøm, eller tcp-pksht fra en gate. |
spawn-args |
Kjører kshana receiver-trust live <sessionFile> <inputArgs...>, for eksempel ["--tcp","192.0.2.10:10110"] eller ["--udp","10110"] |
tcp-json |
Kobler til en strøm av JSON-linjene kshana skriver (for eksempel fra reléet i integrations/opencpn/) |
tcp-pksht |
Kobler til en NMEA-strøm (for eksempel gate-utdataene fra tjenesten eller containeren i referansebyggingen, port 10110) og leser bare $PKSHT-setningene |
En strøm som allerede blir spoofet når monitoren først kobler til har ingen ren grunnlinje (de første calibration_s sekundene scores aldri). Start den før reisen.
Publiserte baner#
Hver epoke oppdaterer (kilde kshana-trust):
| Bane | Verdi |
|---|---|
navigation.gnss.kshana.band |
calibrating, nominal, degraded eller untrusted |
navigation.gnss.kshana.score |
0 til 100, eller null under kalibrering |
navigation.gnss.kshana.reasons |
[{monitor, points}], største først: hvilke kontroller som reduserte scoren |
navigation.gnss.kshana.alarms |
monitorene som for øyeblikket er over terskelen sin |
navigation.gnss.kshana.gate |
off, passed eller withheld (når en gate kjører et annet sted; null fra $PKSHT når den mangler) |
navigation.gnss.kshana.reportedPosition |
{latitude, longitude, altitude}: posisjonen mottakeren under test rapporterte i den epoken (JSON-skjema 1,1 eller nyere; ikke publisert når strømmen ikke har noen, for eksempel fra $PKSHT eller en eldre kshana). Bare tillitskontekst: pluginen skriver aldri navigation.position, så fartøyets egen posisjonsbane berøres ikke |
notifications.navigation.gnss.kshana.trust |
utløst når tilstanden endres: {state, method, message} |
Pluginen sender også Signal K-metadata for disse banene én gang ved start. score er Kshanas tillitsscore fra 0 til 100, en score og ikke et forhold eller en sannsynlighet, så den har ingen SI-enhet; metadataene gir området, en beskrivelse og soner som følger tersklene nedenfor. reasons[].points er scorepoeng trukket fra den scoren fra 0 til 100.
Varselet er normal, alert, warn eller alarm. Det fjernes ved å publisere tilstanden normal, ikke null: en forbruker som bare behandler null som fjernet bør behandle normal som fjernet også. Som standard gir båndet degraded warn og båndet untrusted gir alarm, med method: ["visual","sound"]. Det senkes etter clearAfterEpochs epoker med en bedre tilstand. Hvis ingen epoke kommer på staleAfterS sekunder, advarer det om at scoren ikke oppdateres. Kalibrering utløser aldri et varsel. Kilden $PKSHT har ingen alarms-liste (setningen har bare båndet, scoren og de to viktigste årsakene).
Konfigurasjon (hver terskel)#
| Nøkkel | Standard | Betydning |
|---|---|---|
source |
spawn-signalk-nmea |
se ovenfor |
command |
kshana |
den kjørbare filen (spawn-moduser). Den kjører en hvilken som helst kjørbar fil som serverens bruker: bare en administrator av Signal K-serveren bør kunne endre plugin-konfigurasjonen |
sessionFile |
/etc/kshana/session.toml |
fartøyets grenser, terskler og scorevekter (spawn-moduser) |
inputArgs |
[] |
argumenter lagt til kshana receiver-trust live <sessionFile> i begge spawn-modusene: inndata for spawn-args, ekstra flagg som --replay (en lagret logg matet raskere enn sanntid) for spawn-signalk-nmea. Pluginen avviser --gate, --listen, --json og --pksht (den leser kshanas JSON på standard ut), og for spawn-signalk-nmea også inndataflaggene (--stdin, --file, --tcp, --udp, --follow, --from-end) |
host, port |
127.0.0.1, 10111 |
TCP-moduser (gaten serverer på 10110: sett porten for tcp-pksht) |
thresholdMode |
band |
band: båndet Kshana rapporterer, med kantene i sesjonsfilen. score: de to scorene nedenfor |
warnBelowScore |
90 |
score-modus: under dette er tilstanden degradedState (Kshanas standardkant for nominal) |
alarmBelowScore |
55 |
score-modus: under dette er tilstanden alarm (Kshanas standardkant for degraded) |
degradedState |
warn |
tilstand for båndet degraded: normal, alert eller warn |
raiseAfterEpochs |
1 |
påfølgende epoker med en dårligere tilstand før varselet utløses |
clearAfterEpochs |
10 |
påfølgende epoker med en bedre tilstand før det senkes |
staleAfterS |
10 |
advar når ingen epoke kommer så lenge; 0 slår det av |
method |
["visual","sound"] |
varselmetoder |
Pluginen fungerer ikke som gate: den endrer aldri en posisjonsbestemmelse. Å markere en posisjonsbestemmelse som ugyldig for et kartsystem er gaten, nedenfor.
Tester#
cd integrations/signalk && npm test
node:test, ingen avhengigheter, ingen nettverk utover 127.0.0.1. Testene tolker og spiller av et utdrag på 66 epoker av JSON-linjene og $PKSHT-setningene som kshana receiver-trust live skrev for den syntetiske Østersjø-demoen (oppdiktede data, bare tekst), og kontrollerer samsvar mellom de to formatene, hold- og fjerningsoppførselen, scoremodus, foreldelse og de tre inndatabanene mot en lokal strøm og en erstatningsunderprosess. Disse testene starter ikke en ekte Signal K-server; en separat skriptet kjøring gjør det, se nedenfor.
Kjøring i en ekte Signal K-server#
integrations/signalk/evidence/ inneholder et skript som laster pluginen inn i den låste signalk-server 2.33.0-pakken (i et privat navnerom kun for loopback) og registrerer det serverens egne REST- og WebSocket-API-er viser. Tillitsbanene dukker opp, varselet går warn, alarm, normal (etter holdet) og warn igjen når dataene stopper, og med den ekte kshana matet av serverens egen NMEA-inngang publiserte den også reportedPosition, aldri navigation.position. Én serverversjon, én kjøring, intet reelt fartøy; begrensninger og gjengivelse står i evidens-README-en.
OpenCPN#
OpenCPN leser NMEA fra nettverket, og kshana receiver-trust live --gate kan selv servere den gatede strømmen på en TCP-port.
Anbefalt: den direkte tilkoblingen.
some-nmea-source | kshana receiver-trust live session.toml --gate --listen tcp:10110
(some-nmea-source er mottakerens serieport lest med stty og cat, en multiplekser, eller --tcp/--udp-inndataene til kshana selv; referansebyggingens kshana-gate.service gjør dette under systemd.) --listen tcp:<port> binder seg til loopback-adressen; et hvilket som helst antall skrivebeskyttede klienter kan koble til, og en som ikke henger med, kobles fra uten å forsinke de andre.
Alternativ: reléet. integrations/opencpn/nmea-tcp-relay.mjs er en avhengighetsfri Node-fan-out som gjør det samme for en kshana uten --listen, eller serverer en hvilken som helst annen linjestrøm (containeralternativet bruker den for JSON-epokene):
some-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl \
| node integrations/opencpn/nmea-tcp-relay.mjs --listen 10110
Den videresender byte uendret, bare hele linjer, og kobler fra en klient som ikke leser. Foretrekk den direkte tilkoblingen: én prosess mindre i kjeden.
I OpenCPN: Options, Connections, Add Connection, Network, protokoll TCP, adresse 127.0.0.1, port 10110, retning Input. Så lenge tilliten ikke er kollapset, er strømmen mottakerens egen, pluss en $PKSHT-setning per syklus. Mens den er kollapset, har den videresendte GGA kvalitet 0, RMC-status V, og modusindikatorene sier ingen posisjonsbestemmelse, med sjekksummer regnet ut på nytt: utstyret ser at selve mottakeren erklærer posisjonsbestemmelsen ugyldig og utløser sin egen alarm. $PKSHT-setningene er synlige i OpenCPNs NMEA-feilsøkingsvindu (Options, Connections, "NMEA debug window"). Posisjonsfeltene er uendret slik de ble mottatt.
Les «Gate mode» i MARITIME-TRUST.md før du stoler på dette: den er frivillig, legger til forsinkelse (en syklus holdes til epoken er scoret), er et enkelt punkt i kjeden, og kan holde tilbake en god posisjonsbestemmelse like godt som å slippe gjennom en forfalsket.
Tester#
cd integrations/opencpn && npm test
test/relay.test.mjs spiller av et registrert utdrag av den syntetiske gatede strømmen (186 setninger rundt tidspunktet tilliten kollapser, skrevet av kshana receiver-trust live --gate) gjennom reléet over en ekte TCP-socket og kontrollerer hva en forbruker mottar: strømmen byte for byte under vilkårlig oppdeling; gyldige sjekksummer på hver setning, også de omskrevne; GGA og RMC som stemmer overens, gyldige og deretter ugyldige uten flimmer; én $PKSHT per syklus med gate-feltet W nøyaktig der posisjonsbestemmelsen er ugyldig; to forbrukere identiske; en delvis linje videresendes aldri. Dette kontrollerer strømmen OpenCPN får, ikke OpenCPNs egen skjerm.
En ende-til-ende-kontroll med den ekte binærfilen, ikke en del av standardtestene (den trenger en bygget 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
Begge kjører den syntetiske demoen på én time og kontrollerer at posisjonsbestemmelsen blir gyldig, deretter ugyldig, med en $PKSHT per epoke.
Innebygd plugin#
integrations/opencpn/plugin/ er et scorepanel for OpenCPN (score, bånd, gate, viktigste årsaker, et varsel når tilliten blir untrusted) som leser $PKSHT fra OpenCPNs egen NMEA-strøm, så den trenger ingen tilkobling utover den ovenfor. Den bygges med CMake mot OpenCPNs plugin-API-header (medfølgende, med kildecommit) og wxWidgets; ctest kjører de wx-frie logikktestene og kontrollerer at biblioteket eksporterer inngangspunktene OpenCPN slår opp. Den er kjørt inne i OpenCPN 5.8.4 under en virtuell skjerm på den syntetiske gatede strømmen (OpenCPN ga $PKSHT til pluginen, panelet ble rødt, og OpenCPNs egen posisjon frøs da gaten grep inn; skjermbilder, logg og skript i integrations/opencpn/evidence/), men ikke på et reelt skrivebord, andre versjoner eller plattformer, og den er ikke pakket for OpenCPNs plugin-behandler. Se pluginens README.md. Den er lisensiert under GPL-3.0-or-later, i motsetning til resten av depotet (LICENSING.md).
Skjermbilder fra den kjøringen, i integrations/opencpn/evidence/ (én kjøring, OpenCPN 5.8.4 under en virtuell skjerm, syntetiske data; README.md oppgir begrensningene):
Disse viser rørleggerarbeidet og at den gatede posisjonsbestemmelsen når OpenCPN, ikke at noe varsel kommer til rett tid eller er riktig for et reelt fartøy. Veiledende programvare, ikke typegodkjent utstyr.
Referansebygging#
deploy/reference-build/: en generisk delliste, OS-oppsett, to systemd-enheter (den veiledende monitoren og den frivillige gaten), et containeralternativ og Signal K-koblingen. deploy/reference-build/check-units.sh kjører systemd-analyze verify på enhetene uten å starte noe.
Begrensninger#
- Scoren er bare så god som kontrollene bak den, som ser på et skips fysikk og dets andre sensorer; en selvkonsistent forfalskning med en matchende klokke ses ikke av monitorer som bare bruker NMEA (
MARITIME-TRUST.md). Fravær av alarm er ikke belegg for en god posisjonsbestemmelse. - Ingen tall på denne siden er en målt deteksjons- eller falsk alarm-rate. Testene ovenfor kontrollerer rørleggerarbeidet på syntetisk tekst; de sier ingenting om hvordan noen monitor klarer seg mot reell interferens.
- Ikke typegodkjent; operatøren er fortsatt ansvarlig.