Maritime integrationer: tillidsscoren på broen
Kshanas maritime tillidsscore (MARITIME-TRUST.md) kan nås fra software, som fritidssejlere allerede kører: et Signal K-serverplugin og OpenCPN gennem NMEA i gate-tilstand over TCP. En referencebygning sætter den på en lille computer ved siden af modtageren.
Vejledende software. Kshana er ikke typegodkendt navigationsudstyr (IEC 61108, IEC 61162) og er ikke vurderet i forhold til nogen ydeevnestandard. Alt på denne side er en hjælp til navigatørens skøn. Operatøren er fortsat ansvarlig for fartøjets sikre navigation og for enhver beslutning om at stole på en positionsbestemmelse eller holde op med at stole på den. Intet her sender, og intet her gør en positionsbestemmelse mere nøjagtig.
| Del | Hvor | Status i 0,35 |
|---|---|---|
| Signal K-plugin | integrations/signalk/ |
leveret, enhedstestet på optaget syntetisk output; ikke udgivet på npm |
| OpenCPN gennem NMEA i gate-tilstand over TCP | integrations/opencpn/ |
leveret og testet (afspilning på forbrugersiden); selve OpenCPN's brugerflade køres ikke af nogen test |
| Native scorepanel-plugin til OpenCPN | integrations/opencpn/plugin/ |
bygget, logikken enhedstestet og kørt i OpenCPN 5.8.4 under en virtuel skærm (evidens i integrations/opencpn/evidence/); ikke pakket til plugin-manageren; leveres først efter gennemgang |
| Referencebygning | deploy/reference-build/ |
dele, OS-trin, systemd-enheder (kontrolleret med dry-run), en containermulighed; ikke afprøvet på et fartøj |
Det hele læser én ting: output fra kshana receiver-trust live (JSON-linjer, sætningen $PKSHT, gaten). Trådformaterne er beskrevet i MARITIME-TRUST.md. Signal K-pluginet samler sin viden om dem i én fil, integrations/signalk/lib/adapter.js; en formatændring er en ændring i én fil.
Signal K-plugin#
Ingen npm-afhængigheder. Selve pluginet kører på Node 18 eller nyere; aktuelle udgaver af signalk-server kræver Node 22 eller nyere, så i praksis skal du bruge 22. Kopiér eller link integrations/signalk/ ind i serverens node_modules (for eksempel ~/.signalk/node_modules/signalk-kshana-trust), genstart serveren og aktivér Kshana GNSS trust under Server, Plugin Config.
Hvor epokerne kommer fra (source)#
source |
Hvad pluginet gør |
|---|---|
spawn-signalk-nmea (standard) |
Kører kshana receiver-trust live <sessionFile> og skriver hver rå NMEA 0183-sætning, serveren modtager (serverens hændelse nmea0183), til dens standardinput. Genstarter den med back-off, hvis den afsluttes | Brug den kun på en server med én enkelt NMEA-kilde: den fodrer med hver sætning fra hver udbyder, sammenflettet, så en anden GNSS-modtager eller AIS ligner én modtager, hvis position hopper, og kan blive scoret som spoofing. Ved mere end én kilde skal du bruge spawn-args med den pågældende modtagers egen --tcp-strøm eller tcp-pksht fra en gate. |
spawn-args |
Kører kshana receiver-trust live <sessionFile> <inputArgs...>, for eksempel ["--tcp","192.0.2.10:10110"] eller ["--udp","10110"] |
tcp-json |
Forbinder til en strøm af de JSON-linjer, kshana skriver (for eksempel fra relayet i integrations/opencpn/) |
tcp-pksht |
Forbinder til en NMEA-strøm (for eksempel gate-outputtet fra tjenesten eller containeren i referencebygningen, port 10110) og læser kun dens $PKSHT-sætninger |
En strøm, der allerede bliver spoofet, når monitoren første gang forbinder, har ingen ren baseline (de første calibration_s sekunder scores aldrig). Start den før rejsen.
Udgivne stier#
Hver epoke opdaterer (kilde kshana-trust):
| Sti | Værdi |
|---|---|
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}], den største først: hvilke kontroller der sænkede scoren |
navigation.gnss.kshana.alarms |
de monitorer, der aktuelt er over deres tærskel |
navigation.gnss.kshana.gate |
off, passed eller withheld (når en gate kører et andet sted; null fra $PKSHT, når den mangler) |
navigation.gnss.kshana.reportedPosition |
{latitude, longitude, altitude}: den position, som modtageren under test rapporterede ved den epoke (JSON-skema 1,1 eller senere; udgives ikke, når strømmen ikke har nogen, for eksempel fra $PKSHT eller en ældre kshana). Kun tillidskontekst: pluginet skriver aldrig navigation.position, så fartøjets egen positionssti berøres ikke |
notifications.navigation.gnss.kshana.trust |
udløses, når tilstanden skifter: {state, method, message} |
Pluginet sender også Signal K-metadata for disse stier én gang ved start. score er Kshanas tillidsscore fra 0 til 100, en score og ikke et forhold eller en sandsynlighed, så den har ingen SI-enhed; dens metadata angiver intervallet, en beskrivelse og zoner, der følger tærsklerne nedenfor. reasons[].points er scorepoint, der trækkes fra denne score fra 0 til 100.
Meddelelsen er normal, alert, warn eller alarm. Den ryddes ved at udgive tilstanden normal, ikke null: en forbruger, der kun behandler null som ryddet, bør også behandle normal som ryddet. Som standard giver båndet degraded warn, og båndet untrusted giver alarm, med method: ["visual","sound"]. Den sænkes efter clearAfterEpochs epoker ved en bedre tilstand. Hvis der ikke kommer nogen epoke i staleAfterS sekunder, advarer den om, at scoren ikke opdateres. Kalibrering udløser aldrig en meddelelse. Kilden $PKSHT har ingen alarms-liste (sætningen har kun båndet, scoren og de to øverste årsager).
Konfiguration (hver tærskel)#
| Nøgle | Standard | Betydning |
|---|---|---|
source |
spawn-signalk-nmea |
se ovenfor |
command |
kshana |
den kørbare fil (spawn-tilstande). Den kører enhver kørbar fil som serverens bruger: kun en administrator af Signal K-serveren bør kunne ændre pluginets konfiguration |
sessionFile |
/etc/kshana/session.toml |
fartøjets grænser, tærskler og scorevægte (spawn-tilstande) |
inputArgs |
[] |
argumenter, der føjes til kshana receiver-trust live <sessionFile> i begge spawn-tilstande: input til spawn-args, ekstra flag såsom --replay (en gemt log fodret hurtigere end realtid) til spawn-signalk-nmea. Pluginet afviser --gate, --listen, --json og --pksht (det læser JSON fra kshana på standardoutput) og for spawn-signalk-nmea også inputflagene (--stdin, --file, --tcp, --udp, --follow, --from-end) |
host, port |
127.0.0.1, 10111 |
TCP-tilstande (gaten leverer på 10110: angiv porten for tcp-pksht) |
thresholdMode |
band |
band: det bånd, Kshana rapporterer, med grænserne i sessionsfilen. score: de to scorer nedenfor |
warnBelowScore |
90 |
tilstand score: herunder er tilstanden degradedState (Kshanas standardgrænse for nominal) |
alarmBelowScore |
55 |
tilstand score: herunder er tilstanden alarm (Kshanas standardgrænse for degraded) |
degradedState |
warn |
tilstand for båndet degraded: normal, alert eller warn |
raiseAfterEpochs |
1 |
på hinanden følgende epoker ved en dårligere tilstand, før meddelelsen udløses |
clearAfterEpochs |
10 |
på hinanden følgende epoker ved en bedre tilstand, før den sænkes |
staleAfterS |
10 |
advar, når der ikke kommer nogen epoke så længe; 0 slår den fra |
method |
["visual","sound"] |
meddelelsesmetoder |
Pluginet fungerer ikke som gate: det ændrer aldrig en positionsbestemmelse. At markere en positionsbestemmelse som ugyldig for et kortsystem er gaten, nedenfor.
Tests#
cd integrations/signalk && npm test
node:test, ingen afhængigheder, intet netværk ud over 127.0.0.1. Testene fortolker og afspiller et uddrag på 66 epoker af de JSON-linjer og $PKSHT-sætninger, som kshana receiver-trust live skrev for den syntetiske Østersø-demo (opdigtede data, kun tekst), og kontrollerer, at de to formater er enige, samt hold- og rydningsadfærden, scoretilstand, forældelse og de tre inputstier mod en lokal feed og en stand-in-børneproces. Disse tests starter ikke en rigtig Signal K-server; en særskilt scriptet kørsel gør, se nedenfor.
Kørsel i en rigtig Signal K-server#
integrations/signalk/evidence/ rummer et script, der indlæser pluginet i den fastlåste pakke signalk-server 2.33.0 (i et privat netværksnavnerum kun med loopback) og optager, hvad serverens egne REST- og WebSocket-API'er viser. Tillidsstierne vises, meddelelsen går warn, alarm, normal (efter holdet) og igen warn, når dataene stopper, og med den rigtige kshana, fodret af serverens eget NMEA-input, udgav den også reportedPosition, aldrig navigation.position. Én serverversion, én kørsel, intet virkeligt fartøj; begrænsninger og gengivelse står i evidens-README'en.
OpenCPN#
OpenCPN læser NMEA fra netværket, og kshana receiver-trust live --gate kan selv levere den gatede strøm på en TCP-port.
Anbefalet: den direkte forbindelse.
some-nmea-source | kshana receiver-trust live session.toml --gate --listen tcp:10110
(some-nmea-source er modtagerens serielle port læst med stty og cat, en multiplexer eller inputtene --tcp/--udp i kshana selv; referencebygningens kshana-gate.service gør dette under systemd.) --listen tcp:<port> binder loopback-adressen; et vilkårligt antal skrivebeskyttede klienter kan forbinde, og en, der ikke kan følge med, droppes uden at forsinke de øvrige.
Alternativ: relayet. integrations/opencpn/nmea-tcp-relay.mjs er en afhængighedsfri Node-fan-out, der gør det samme for en kshana uden --listen, eller leverer enhver anden linjestrøm (containermuligheden bruger den til JSON-epokerne):
some-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl \
| node integrations/opencpn/nmea-tcp-relay.mjs --listen 10110
Den videresender bytes uændret, kun hele linjer, og dropper en klient, der ikke læser. Foretræk den direkte forbindelse: én proces mindre i kæden.
I OpenCPN: Options, Connections, Add Connection, Network, protokol TCP, adresse 127.0.0.1, port 10110, retning Input. Så længe tilliden ikke er brudt sammen, er strømmen modtagerens egen plus én sætning $PKSHT pr. cyklus. Når den er brudt sammen, har den videresendte GGA kvaliteten 0, RMC-status V, og tilstandsindikatorerne siger ingen positionsbestemmelse, med genberegnede kontrolsummer: udstyret ser modtageren selv erklære positionsbestemmelsen for ugyldig og udløser sin egen alarm. Sætningerne $PKSHT kan ses i OpenCPN's NMEA-fejlfindingsvindue (Options, Connections, "NMEA debug window"). Positionsfelterne er uændret, som de blev modtaget.
Læs "Gate mode" i MARITIME-TRUST.md, før du stoler på dette: den er til valg, tilføjer latenstid (en cyklus holdes, indtil dens epoke er scoret), er et enkelt punkt i kæden og kan holde en god positionsbestemmelse tilbage lige så vel som lade en forfalsket passere.
Tests#
cd integrations/opencpn && npm test
test/relay.test.mjs afspiller et optaget uddrag af den syntetiske gatede strøm (186 sætninger omkring det øjeblik, hvor tilliden brister, skrevet af kshana receiver-trust live --gate) gennem relayet over en rigtig TCP-socket og kontrollerer, hvad en forbruger modtager: strømmen byte for byte under vilkårlig opdeling; gyldige kontrolsummer på hver sætning, også de omskrevne; GGA og RMC, der er enige, gyldige og derefter ugyldige uden flimmer; én $PKSHT pr. cyklus med dens gate-felt W præcis dér, hvor positionsbestemmelsen er ugyldig; to forbrugere identiske; en delvis linje, der aldrig videresendes. Dette kontrollerer den strøm, OpenCPN får, ikke OpenCPN's egen skærm.
En kontrol fra ende til anden med den rigtige binære fil, ikke en del af standardtestene (den kræver 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 kører den syntetiske demo på en time og kontrollerer, at positionsbestemmelsen bliver gyldig og derefter ugyldig, med en $PKSHT pr. epoke.
Native plugin#
integrations/opencpn/plugin/ er et scorepanel til OpenCPN (score, bånd, gate, de vigtigste årsager, en advarsel, når tilliden bliver untrusted), der læser $PKSHT fra OpenCPN's egen NMEA-strøm, så det ikke kræver nogen forbindelse ud over den ovenfor. Det bygges med CMake mod OpenCPN's plugin-API-header (medbragt, med sin kildekommit) og wxWidgets; ctest kører logiktestene uden wx og kontrollerer, at biblioteket eksporterer de indgangspunkter, OpenCPN slår op. Det er kørt inde i OpenCPN 5.8.4 under en virtuel skærm på den syntetiske gatede strøm (OpenCPN gav $PKSHT videre til pluginet, panelet blev rødt, og OpenCPN's egen position frøs, da gaten gik i indgreb; skærmbilleder, log og script i integrations/opencpn/evidence/), men ikke på et rigtigt skrivebord, andre versioner eller platforme, og det er ikke pakket til OpenCPN's plugin-manager. Se pluginets README.md. Det er licenseret under GPL-3.0-or-later, i modsætning til resten af repositoriet (LICENSING.md).
Skærmbilleder fra den kørsel, i integrations/opencpn/evidence/ (én kørsel, OpenCPN 5.8.4 under en virtuel skærm, syntetiske data; README.md angiver begrænsningerne):
Disse viser rørføringen og den gatede positionsbestemmelse, der når frem til OpenCPN, ikke at nogen alarm er rettidig eller korrekt for et virkeligt fartøj. Vejledende software, ikke typegodkendt udstyr.
Referencebygning#
deploy/reference-build/: en generisk stykliste, OS-opsætning, to systemd-enheder (den vejledende monitor og gaten, der er til valg), en containermulighed og Signal K-forbindelsen. deploy/reference-build/check-units.sh kører systemd-analyze verify på enhederne uden at starte noget.
Begrænsninger#
- Scoren er kun så god som de kontroller, der ligger bag den, og de ser på et skibs fysik og dets andre sensorer; en selvkonsistent forfalskning med et ur, der passer, ses ikke af monitorer, der kun bruger NMEA (
MARITIME-TRUST.md). Fravær af en alarm er ikke belæg for en god positionsbestemmelse. - Intet tal på denne side er en målt detektions- eller falsk-alarm-rate. Testene ovenfor kontrollerer rørføringen på syntetisk tekst; de siger intet om, hvordan en monitor klarer sig over for virkelig interferens.
- Ikke typegodkendt; operatøren er fortsat ansvarlig.