Maritim tillid: kan broen stole på denne positionsbestemmelse?
kshana receiver-trust kan for et skib i bevægelse give en løbende tillidsværdi fra 0 til 100 for hver positionsbestemmelse ud fra det, enhver modtager allerede lægger på bussen (først NMEA 0183), og angive, hvilke kontroller der sænkede den. Det er et softwarelag, der sidder ved siden af en modtager. Det er ikke en modtager, det erstatter ikke en, og det gør ikke en positionsbestemmelse mere nøjagtig.
Vejledende software. Kshana er ikke typegodkendt navigationsudstyr (IEC 61108, IEC 61162) og er ikke vurderet i forhold til nogen ydeevnestandard. Dens score og dens gate er hjælpemidler 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.
Denne side siger, hvad kontrollerne ser på, hvad hver af dem kan og ikke kan fange, hvordan den køres live, og hvad gaten gør. Scoreafbildningen og hver standardværdi står i RECEIVER-TRUST.md.
Hvad den læser#
Et fartøj erklæres i sessionsfilen, med dets grænser angivet før kørslen:
[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
| Sætning | Læst |
|---|---|
| GGA | position, kvalitet af positionsbestemmelsen (0 = ingen positionsbestemmelse), højde over middelvandstand, geoideseparation, HDOP |
| RMC | status (A gyldig, V ikke), fart og kurs over grunden, dato, tilstand |
| VTG | fart og kurs over grunden, hvor RMC ingen har |
| HDT, THS | kurs (THS kun, når dens tilstand ikke er V) |
| VHW, VBW | fart gennem vandet (VBW kun, når dens status er A) |
| ZDA | tid |
| GSV | signalstyrke pr. satellit (dB-Hz), elevation og azimut (til geometrien) |
| GSA | dilution of precision og anvendte satellitter (til geometrien, hvor GSV ikke giver nogen himmel; og den angivne HDOP, som vagten sammenligner) |
$PKSOS,<A/F/N> |
en OSNMA-status, som en modtager rapporterede, oversat til denne sætning af den adapter, der læser modtageren: A autentificeret, F mislykkedes, N intet resultat |
Epoker, som modtageren selv siger ikke er en satellitpositionsbestemmelse (GGA-kvalitet 0 eller 6 til 8: estimeret, manuel, simulator; RMC-status V eller tilstand E, M, S, N), bruges ikke til positionskontrollerne og er hverken belæg for eller imod: det har modtageren allerede selv sagt.
De første calibration_s sekunder danner baselinen og scores aldrig. Hver monitor ser kun på den aktuelle og tidligere epoker, så en afgørelse ved en epoke ændrer sig ikke, når senere data ankommer, og en live-strøm giver samme score som den samme tekst læst som en fil.
Hvad hver kontrol fanger, og hvad den ikke kan#
Retninger mellem positionsbestemmelser (sporets pejling, som drejningshastighedskontrollen bruger, den kurs, to positioner antyder) er retningen af korden mellem dem, som er geodætens middelazimut mellem positionsbestemmelserne, ikke fremadazimutten ved den første; de to adskiller sig med omkring halvdelen af meridiankonvergensen mellem positionsbestemmelserne (0,001 grader for en baseline på 260 m ved 59,5 graders bredde).
En forfalsket position skal stemme med et skibs fysik og med skibets øvrige sensorer. Hver kontrol sammenligner positionsbestemmelsen med én af dem. En kontrol er kun så uafhængig som sin anden kilde: en kurs fra et GNSS-kompas eller en "fart gennem vandet" udledt af GNSS er ikke uafhængig af den modtager, der testes, og tilføjer intet.
| Kontrol | Fanger | Kan ikke |
|---|---|---|
kinematic |
et positionsspring; et spor, hvis bevægelse den rapporterede fart og kurs ikke forklarer; en antydet fart, acceleration eller drejningshastighed over fartøjets angivne grænser | en bortledning, hvis rapporterede fart og kurs følger det forfalskede spor og holder sig inden for grænserne (modtageren udleder dem af sin egen løsning, så de stemmer med hinanden); en fartgrænse, der er angivet for højt |
heading-course |
et spor, der afviger fra den retning, skibet peger, med mere end den angivne krabbevinkel | en bortledning langs kursen (kursen ændrer sig ikke); en kurs fra den samme modtager eller et GNSS-kompas; en sidestrøm over tolerancen (falsk alarm); farter under min_speed_kn |
speed-log |
en bortledning, der ændrer farten over grunden i forhold til farten gennem vandet | et log, der er udledt af GNSS; en strøm over tilladelsen (falsk alarm); en bortledning langsommere end tilladelsen |
sea-level |
en højde, der ikke er dér, hvor havoverfladen og den angivne antennehøjde placerer den | en spoofer, der holder højden sandsynlig; tolerancen er bred, fordi den lodrette fejl for en enkeltstående modtager er stor; geoideseparationen registreres, men kontrolleres ikke, fordi motoren ikke har nogen geoidemodel |
cn0-spread, cn0-rise |
signaturen fra én sender: C/N0 på tværs af satellitterne, der falder sammen eller stiger sammen i forhold til kalibreringens baseline | en spoofer, der former effekten pr. satellit; alt, mens selve baselinen bliver spoofet; en GSV-kadence, der er for langsom til at følge med |
time-consistency |
modtagerens tid, der springer uregelmæssigt eller løber baglæns; i forhold til denne computers ur, at modtagerens tid driver væk fra det (kun realtidsstrømme) | en forfalsket tid, der er konsistent og jævn; et ur, der er forkert fra starten |
osnma |
en rapporteret OSNMA-autentifikationsfejl | statussen læses, ikke verificeres; en spoofer, der undertrykker rapporten, ses ikke |
cn0-drop, loss-of-lock, agc, jam-ind |
effektafvisning og tab af satellitter, som i det statiske tilfælde | de siger, at omgivelserne er fjendtlige, ikke at positionsbestemmelsen er forkert |
Hvad monitorer, der kun bruger NMEA, ikke kan. En spoofer, der gengiver hele konstellationen med en selvkonsistent position, hastighed, kurs der passer til retningen, sandsynlig effekt pr. satellit og et ur, der passer, er usynlig for hver kontrol ovenfor: intet i sætningerne skelner dens positionsbestemmelse fra en virkelig. Det samme gælder en afspilning af optagede virkelige signaler. Autentifikation (OSNMA eller en modtager med sin egen beskyttelse mod spoofing) og uafhængige navigationssensorer er det, der lukker dette hul; dette lag kan kun bruge deres rapporterede status. En strøm, der allerede bliver spoofet, mens baselinen dannes, har ingen ren baseline. Fravær af en alarm er ikke belæg for en god positionsbestemmelse.
Tillidsscore#
Hver epoke efter kalibrering får en score fra 0 til 100 og årsagerne til, at den ikke er 100: hvilke kontroller der trak fra, deres statistik i forhold til tærsklen og deres point. Bånd (grænser angivet i sessionen): nominal ved 90 eller derover, degraded ved 55 eller derover, untrusted derunder. Afbildningen, hver vægt og dens begrundelse står i RECEIVER-TRUST.md; den er deterministisk og fastlagt, før en log scores, uden læring og uden noget, der er tilpasset hændelser.
Hvert fartøjsoutput bærer den vejledende erklæring: nøglen advisory i resultat-JSON og i hver live-linje, en første kommentarlinje # i CSV (læsere springer den over med deres kommentarindstilling), <desc> og en fodtekst i SVG. Output fra en batchkørsel: session.result.json (med scoremodellen og hver epokes fradrag), session.trust.csv (med kolonnerne score og score_reasons) og session.trust.svg, som for et fartøj er det af modtageren rapporterede spor farvet efter tillidsbånd over scoren over tid.
En syntetisk demo#
examples/maritime-trust/ rummer en opdigtet NMEA-log fra en færge på en rute fra Tallinn til Helsinki (et uddrag på 50 minutter, omkring 17 kn, 1 Hz: GGA, RMC, VTG, en gyrokurs, et fartlog, GSV med en sandsynlig himmel), hvor en bortledning af positionen fra 1500 s trækker den rapporterede position væk fra fartøjets virkelige. Modtageren bliver ved med at rapportere en gyldig positionsbestemmelse hele vejen; det er tillidsscoren, der falder, gennem båndet degraded ned i untrusted. session.toml angiver hver tærskel, fartøjets grænser og hver scorevægt før kørslen.
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
Loggen er tekst skrevet til en fil af cargo run --example gen_maritime_trust_demo: den modellerer intet radiosignal og sender intet. Den er ikke en måling, og ruten er illustrativ, ikke et søkort. tests/receiver_trust_maritime_demo.rs fastholder loggen og det forventede output som regressionsvagter på de syntetiske data; de siger intet om, hvordan en monitor klarer sig over for virkelig interferens.
Figuren tegnes af tools/gen_readme_assets.py ud fra en virkelig kørsel af denne demo (kshana receiver-trust examples/maritime-trust/session.toml); scoren er vejledende, og loggen er opdigtet.
Specifikation af Studio-visningen#
Til den, der bygger Studio-visningen af en fartøjskørsel. Intet i dette afsnit er endnu implementeret i Studio; motorsiden (dataene nedenfor) er.
Input. Et af følgende:
- en batchkørsels resultat-JSON (
kshana receiver-trust <session.toml>, eller det samme gennemreceiver_trust(toml)i WebAssembly-pakken med loggen direkte i teksten):score_model(båndgrænser, rampe, evidenshold, hver vægt),monitors_run,statesogepochs[], hver medt_s,state,alarms,score.{score,band,deductions[]},marine.{position:[lat,lon], stats, ratios}, og fra 0,36geometryog hvert fradragsclass, medgeometry_modeloggeometry_summarypå øverste niveau; eller - de levende JSON-linjer (skemaet ovenfor), ét objekt pr. epoke, tilføjet, mens strømmen kører. Hver linje bærer den af modtageren rapporterede
position(skema 1,1).
Demosættet er examples/maritime-trust/: session.toml, tallinn-helsinki.nmea (loggen) og tallinn-helsinki.truth.csv (t_s,true_lat_deg,true_lon_deg: hvor fartøjet virkelig var, hvilket ingen virkelig log har). En visning bør køre sessionen og læse referencefilen ved siden af.
Hvad der skal tegnes.
- Spor, nord opad, én skala på begge akser: de af modtageren rapporterede positioner som en linje farvet efter epokens bånd (grå kalibrerer, grøn nominal, rav degraded, rød untrusted), start og slut markeret, en målestok. For demoen det sande spor som en tynd neutral linje under det, så bortledningen vises som de to, der skilles; en kontakt til det sande spor og en aflæsning af forskydningen i meter ved markørens tidspunkt.
- Scoretidslinje: scoren fra 0 til 100 mod tid, båndgrænserne (
nominal_min,degraded_minfrascore_model) som stiplede linjer, båndet som en strimmel nedenunder og starten på en angivet hændelse som en markør. Tidsaksen deles med sporet. - Årsager: for den epoke, markøren står på, fradragene (monitor, forhold i forhold til tærskel, point) som vandrette søjler, den største først, med den vægt, hver monitor har fra
score_model.weights; monitorer, der kørte og ikke kostede noget, vist svagt, monitorer, der ikke kørte (ikke imonitors_run), opført som "not run", aldrig som bestået. Monitorengeometryhar ingen post iscore_model.weights: dens loft ergeometry_model.cap_in_force. - Monitorstrimler: én tynd strimmel pr. monitor i
monitors_run, der viser dens forhold over tid (alarm ved 1), så en læser kan se, hvilken kontrol der bevægede sig først. - Gate-tilstand: i en live-visning hver epokes
gate(off,passed,withheld) som en strimmel under bånd-strimlen og den seneste$PKSHT. I en batchvisning er de epoker, en gate ville have holdt tilbage, dem, hvis bånd er untrusted, med frigivelsesholdet anvendt. - Geometribane (0,36): en strimmel under bånd-strimlen farvet efter
geometry.status(grøn god, rav degraded, grå skraveret ukendt), i en farvefamilie, der er forskellig fra banerne for inkonsistens og omgivelser, med forklaringen "geometry: the sky, not the signal". Fradrag farvet efterclass(geometri, omgivelser, inkonsistens) i årsagspanelet og monitorstrimlerne og antallet af epoker pr. klasse frageometry_summaryved siden af båndantallene. For den epoke, markøren står på:geometry.note,n_used, HDOP, PDOP, VDOP,source,age_sog et flag, nårreported_derived_mismatcher sat (geometrifradraget er så en inkonsistens).unknownvises som "geometry unknown: no GSV or GSA in the log", aldrig som god. Tærsklerne i[geometry]og deres proveniens frageometry_modelplaceres ved siden af scoreindstillingerne. Den vejledende note bliver. - Af modtageren rapporteret positionsbestemmelse: demoens modtager rapporterer en gyldig positionsbestemmelse hele vejen (GGA-kvalitet 1, RMC-status A); sig det i forklaringen, for det er pointen med visningen.
Interaktioner. Én tidsmarkør delt af hvert panel (træk, piletaster og en afspilningsknap, der afspiller ved 1x til 60x); at holde musen over sporet eller en strimmel flytter den. Et klik på et fradrag fremhæver de epoker, hvor den monitor var over sin start. Et båndfilter (vis kun epoker med degraded og untrusted) og et spring til det første fradrag og til den første untrusted epoke. Hjælpetekst ved hvert monitornavn med enlinjebeskrivelsen fra denne side. Sessionens tærskler og vægte vises, skrivebeskyttede, ved siden af diagrammet, så det, scoren brugte, er på skærmen.
Ordlyd, der skal bevares. Siden skal sige, at det er vejledende software og ikke typegodkendt navigationsudstyr, at demoen er syntetisk tekst med en opdigtet bortledning, og at en positionsbestemmelse uden alarm ikke dermed er en god positionsbestemmelse (se begrænsningerne ovenfor). Intet tal på siden må læses som et mål for, hvordan kontrollerne klarer sig over for virkelig interferens.
Fra kode#
Til kaldere, der har sessionen og bytes i hukommelsen (ingen filer, intet ur, ingen sockets; sikkert for WebAssembly), har kshana::receiver_trust::assess:
assess_vessel_log(session_toml, log_bytes) -> Result<ReceiverTrustResult, String>: en hel log, scoret som en batchkørsel; det samme resultat somkshana receiver-trust <session.toml>, som serialiseres til resultat-JSON (score_model,monitors_run,epochs[]med scorer og fradrag).assess_stream_excerpt(session_toml, excerpt_bytes) -> Result<ExcerptAssessment, String>: et afgrænset stykke af en strøm (højst 2 MiB og 20.000 epoker, og langt nok til at rumme kalibreringsvinduet), scoret, som live-tilstand scorer, og returneret i live-JSON-linjeskemaet (epochs[], den sidste$PKSHT, et resumé af båndantal, laveste og endelige score, første untrusted tidspunkt). Modtagerens tid sammenlignes ikke med et værtsur. Den langvarige live-tilstand (sockets, en fil, der tilføjes til, gaten) hører til den binære fil.
Begge kræver en session med [platform] kind = "vessel"; dens tabel [log] er valgfri.
Kør den live#
# 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
Sessionen er den samme session.toml som i en batchkørsel, med en tabel [platform], der erklærer kind = "vessel"; dens tabel [log] er ikke nødvendig. Serielle porte åbnes endnu ikke direkte: læs porten med det værktøj, du allerede bruger (stty og cat, en terminalserver, en multiplexer), og send den videre med pipe eller videresendelse. Direkte serielt input kan komme senere.
Hver afsluttet epoke skriver én JSON-linje på standardoutput:
{"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 er calibrating, nominal, degraded eller untrusted (scorens bånd, med grænserne i sessionens tabel [score]); score er fraværende under kalibrering; deductions angiver, hvilke kontroller der tog point af, og hvor mange, den største først.
JSON-linjeskema (version 1,1)#
Ét JSON-objekt pr. afsluttet epoke, nøgler i denne rækkefølge:
| Nøgle | Type | Betydning |
|---|---|---|
seq |
heltal | antal rapporterede epoker, fra 1 |
t_s |
tal | sekunder siden strømmens første epoke |
time |
streng eller null | epokens tid, som strømmen angiver den (ISO-8601 UTC med en dato, når en RMC er set, ellers hh:mm:ss.mmm UTC (date not in log)) |
state |
streng | calibrating, nominal, degraded eller untrusted |
score |
tal eller null | 0 til 100, ét decimal; null under kalibrering, eller når note forklarer, hvorfor ingen kunne beregnes |
deductions |
array | {"monitor": string, "ratio": number, "points": number, "class": string}, flest point først; ratio er statistik i forhold til tærskel (alarm ved 1 eller mere); kun monitorer, der kostede point, er opført; class (tilføjet i 1,3) er geometry, environment eller inconsistency |
alarms |
array af streng | monitorer ved eller over deres tærskel |
gate |
streng | off, passed eller withheld |
note |
streng eller null | hvorfor ingen score blev beregnet (for eksempel en erklæret kurssensor, der er fraværende) |
position |
objekt eller null | (tilføjet i 1,1) den position, modtageren rapporterede ved denne epoke, {"lat_deg", "lon_deg", "height_m"} (højde ellipsoidisk, hvor sætningen angiver geoideseparationen, ellers over middelvandstand); null, når modtageren ingen gav, herunder kalibreringsepoker uden positionsbestemmelse |
advisory |
streng | (tilføjet i 1,2) hvad denne software er og ikke er: vejledende, ikke typegodkendt navigationsudstyr, operatøren er fortsat ansvarlig |
geometry |
objekt | (tilføjet i 1,3) satellitgeometrien: status (good, degraded, unknown, når strømmen ingen GSV-elevationer og -azimutter og ingen GSA har), 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 (satellitter i sigte, men ikke sporet, mens DOP i sigte er god: geometrifradraget er så environment), label (good, fair, poor, unknown: rapporteres altid, scores aldrig; scoren trækker kun fra for poor) (se RECEIVER-TRUST.md) |
Monitornavne (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 og fra 1,3 geometry. Nye navne kan tilføjes i senere versioner; forbrugere bør behandle et ukendt monitornavn som en monitor. Layoutet $PKSHT nedenfor bærer en formatversion i sit første felt; dette JSON-skema er version 1,3: 1,1 tilføjede position, 1,2 advisory, 1,3 geometry til sidst og class i hvert fradrag, og det ændres kun ved at tilføje nøgler til sidst.
Autentifikationsinput#
Monitoren osnma tager autentifikationsstatus pr. satellit fra en autentifikationskilde gennem MarineObs::sat_auth (en liste af (satellite, status), status Authenticated, Failed eller Unavailable), ved siden af den samlede MarineObs::osnma. På NMEA-siden bæres det samme af $PKSOS,<A|F|N>[,<sat>:<A|F|N>...], for eksempel $PKSOS,A,E11:A,E19:F. Enhver fejl, samlet eller på én satellit, udløser monitorens alarm og koster hele dens vægt (den får forholdet 1,5); succes er ikke belæg. Kshana verificerer intet her: den kilde, der gør, er ansvarlig for den status, den rapporterer.
En epoke er afsluttet, når den næste tidsstemplede sætning ankommer; sætninger fra langsommere eller usynkroniserede instrumenter (en gyro nogle tiendedele af et sekund efter modtageren), der ankommer før da, hører til den. Hvis strømmen går i stå i [live] idle_flush_s (standard 1,5 s, sæt den over det længste mellemrum mellem din modtagers tidsstemplede sætninger), afsluttes epoken, som den står. De første calibration_s sekunder af strømmen danner baselinen og scores aldrig, så en strøm, der allerede bliver spoofet, når den første gang forbindes, har ingen ren baseline: start laget før rejsen eller mens positionsbestemmelsen vides at være god. Kalibreringsvinduet lukker én gang, efter ankomst: en epoke, hvis tid er tidligere end en tid, der allerede er set (en tilbagespoling, en genafspilning af strømmens start), er aldrig kalibrering, uanset hvad dens tid siger; den scores med et fuldt fradrag for time-consistency, hvilket er untrusted. Live-motoren scorer hver epoke over kalibreringsepokerne og det sidste minut eller deromkring af strømmen, så dens omkostning pr. epoke vokser med calibration_s gange epokeraten; hold vinduet kort på en hurtig modtager. Dens buffere er afgrænsede (en strøm af linjer uden en tidsstemplet sætning afsluttes for hver 5.000 linjer, kalibrering og historik er begrænset til 20.000 epoker).
Modtagerens tid sammenlignes også med denne computers monotone ur, hvilket kun betyder noget for en strøm, der ankommer i realtid. En gemt log, der fødes ind i fuld hastighed gennem stdin, TCP eller UDP, udløser pr. konstruktion den kontrol: angiv --replay. (--file uden --follow indebærer det allerede.) En --file ... --follow læses som en genafspilning, indtil den er læst til ende, og værtsuret er koblet til derfra, så en bagkant ikke læses som en urfejl; kontrollen kræver så, at kalibreringsvinduet stadig er åbent (ellers har den ingen baseline og kører ikke).
Strømafslutning og fejl: stdin og en fil, læst til ende, afsluttes normalt (exit 0). En TCP-forbindelse, der lukkes af modparten, er ikke en normal afslutning for en strøm, der skal fortsætte: laget afsluttes med en værdi forskellig fra nul, efter at det har scoret og skrevet alt, det havde modtaget, og forbinder ikke igen, så kør det under en supervisor, der genstarter det. UDP-datagrammer, der deler en sætning, samles; læserne af stdin, en fil og TCP understøttes af en afgrænset kø, der skubber tilbage mod afsenderen (intet går tabt), mens UDP, som ikke kan skubbe tilbage, dropper datagrammer, som motoren ikke kan tage imod, og siger det på stderr. --udp <port> binder loopback-adressen; angiv --udp <addr>:<port> for at lytte et andet sted (der udskrives en advarsel).
$PKSHT: den proprietære sætning#
Hver epoke producerer også én NMEA 0183-sætning med en gyldig kontrolsum, som --pksht <path|-> skriver til en fil eller stdout, og som gaten indsætter i den videresendte strøm:
$PKSHT,1,080140.25,30.0,U,W,heading-course:40.0/cn0-spread:30.0*2F
| Felt | Betydning |
|---|---|
| 1 | 1: formatversionen |
| 2 | UTC-tid for epoken, hhmmss.ss; tom, hvis strømmen ikke gav nogen |
| 3 | tillidsscore 0 til 100, ét decimal; tom under kalibrering, eller når ingen kunne beregnes |
| 4 | bånd: C kalibrerer, N nominal, D degraded, U untrusted |
| 5 | gate: - fra, P passeret, W holdt tilbage (positionsbestemmelsen blev markeret som ugyldig i den videresendte cyklus) |
| 6 | op til to årsager, monitor:points forbundet med /; tom, når intet blev trukket fra |
Adressen er P + producentens mnemonik KSH + T. Udstyr, der ikke kender en proprietær sætning, ignorerer den. Kshana ignorerer sin egen $PKSHT ved input.
Gate-tilstand#
--gate placerer Kshana mellem modtageren og det udstyr, der bruger dens positionsbestemmelse (et kortsystem, et sporstyringssystem). NMEA-strømmen går ind, kommer ud på stdout og er:
- sendt uændret igennem, mens epoken ikke er untrusted (og under kalibrering), med en
$PKSHTefter hver cyklus af sætninger; og - markeret som ugyldig, mens den er untrusted: GGA-kvalitet
0; RMC-statusV(og dens tilstandsindikatorNog navigationsstatusV, hvor de findes); GNS-tilstandNi hver position; GLL-statusVog tilstandN; VTG-tilstandN, hvor den har en. Positionsfelterne er uændret, som de var: pointen er, at udstyret ser modtageren selv erklære positionsbestemmelsen for ugyldig og udløser sin egen alarm. Hver omskrevet sætning får sin kontrolsum genberegnet.
Når positionsbestemmelsen først er holdt tilbage, frigives den først, efter at epokerne har været uden for båndet untrusted i [live] gate_release_s (standard 30 s), så en score ved båndgrænsen ikke kan få positionsbestemmelsen til at flimre. JSON-linjerne går kun dertil, hvor --json <path> angiver (som standard ingen steder, fordi strømmen har stdout).
receiver-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl | downstream-equipment
For at lade en kortplotter forbinde direkte skal den gatede strøm leveres over TCP i stedet for stdout:
receiver-nmea-source | kshana receiver-trust live session.toml --gate --listen tcp:10110
--listen tcp:<port> lytter på loopback-adressen; tcp:<addr>:<port> lytter et andet sted (der udskrives en advarsel, fordi enhver, der kan nå adressen, kan læse strømmen). Et vilkårligt antal klienter kan forbinde; hver får den samme strøm fra det øjeblik, den forbinder, og klienter læser kun. Hver klient har sin egen afgrænsede kø og skriver, så en, der ikke kan følge med, droppes (dens forbindelse lukkes, en linje på stderr) og forsinker aldrig de øvrige eller inputtet. --listen kræver --gate; stdout bærer så intet af strømmen, så --json - er ledig.
Hvad gaten ikke gør, og hvad man bør vide, før man bruger den:
- Den er til valg. Intet markerer en positionsbestemmelse som ugyldig, medmindre
--gateer angivet. - Den tilføjer latenstid: en cyklus holdes, indtil dens epoke er scoret, hvilket er tiden til den næste tidsstemplede sætning (omkring én cyklus: et sekund for en modtager på 1 Hz), eller
idle_flush_sefter den sidste, når strømmen går i stå. Udstyr, der har brug for en sætning inden for nogle få tiendedele af et sekund efter modtagerens output, må ikke sidde bag den. - Den er et enkelt punkt i kæden: hvis den stopper, stopper strømmen. Kør den under supervision, og beslut på forhånd, hvad det efterfølgende udstyr gør uden en strøm.
- Den fejler lukket ved sine egne fejl: hvis monitorerne ikke kan beregne en score efter kalibrering (en erklæret kurssensor, der intet sender, for få kalibreringsepoker), er epoken untrusted, bærer en
noteog holdes tilbage; frigivelsesholdet tidsmåles på denne computers ur, ikke på modtagerens tid, som er det, en spoofer styrer (ved en genafspilning findes kun modtagerens tid). - Den kan tilbageholde en god positionsbestemmelse (en falsk alarm) og lade en spoofet slippe igennem (en misset). Monitorerne kontrollerer en positionsbestemmelse mod et skibs fysik og dets øvrige sensorer; en forfalskning, der stemmer med dem alle, bliver ikke opdaget (se begrænsningerne nedenfor).
- Den forventer en ren NMEA 0183-tekststrøm. Binære frames, der er blandet ind i strømmen, videresendes uændret, men en
$PKSHTkan så havne mellem bytes i en frame. - Den er ikke typegodkendt, og intet i den er vurderet mod IEC 61108 eller IEC 61162. Operatøren er fortsat ansvarlig for fartøjets navigation.