Machinevertaling, niet beoordeeld door een moedertaalspreker. Engels is de referentie.

Ontvangervertrouwen en maritiemBewerken op GitHubBron: docs/RECEIVER-TRUST.md

Ontvangervertrouwen: een echt GNSS-ontvangerlogboek beoordelen

kshana receiver-trust leest een logboek van een echte ontvanger voor het global navigation satellite system (GNSS), draait er epoche voor epoche vertrouwensmonitors overheen en zegt wanneer en waarom de positiebepaling van de ontvanger niet langer te vertrouwen was. Het kan het logboek ook scoren aan events en voorspellingen die u vóór de run vastlegt: of elk event op tijd is gedetecteerd, en of een gemodelleerde daling van de draaggolf-ruisdichtheid (C/N0) overeenkomt met wat de ontvanger heeft gemeten.

De waarneembare grootheden zijn die van de ontvanger zelf; de monitors en hun drempelwaarden zijn die van de engine en van u. Elk resultaat draagt dat label, de SHA-256 van het logboek en elke drempel waarmee het draaide, zodat een run kan worden herhaald en geauditeerd.

Voor een vaartuig onderweg, met een live score en een optionele gate voor een kaartsysteem, zie MARITIME-TRUST.md.

De eigen spoofingvlag van de ontvanger gezet naast de alarmen van Kshana, uit een echte run van engine v0.40.0 op een verzonnen UBX-log (200 epochs met 1 Hz). C/N0 daalt 20 dB bij 80 tot 90 s en 120 tot 130 s; de ontvanger vlagt 120 tot 130 s en 160 tot 165 s. Van 140 epochs die na kalibratie zijn vergeleken, vlagden 11 beide, 6 alleen de ontvanger, 11 alleen Kshana en 112 geen van beide. Geen van beide kanten is de referentie en overeenstemming is geen validatie. Adviserend: analyse-uitvoer van een onderzoeks- en engineeringtool, geen typegoedgekeurde navigatieapparatuur en geen veiligheidsdienst voor mensenlevens.De eigen spoofingvlag van de ontvanger gezet naast de alarmen van Kshana, uit een echte run van engine v0.40.0 op een verzonnen UBX-log (200 epochs met 1 Hz). C/N0 daalt 20 dB bij 80 tot 90 s en 120 tot 130 s; de ontvanger vlagt 120 tot 130 s en 160 tot 165 s. Van 140 epochs die na kalibratie zijn vergeleken, vlagden 11 beide, 6 alleen de ontvanger, 11 alleen Kshana en 112 geen van beide. Geen van beide kanten is de referentie en overeenstemming is geen validatie. Adviserend: analyse-uitvoer van een onderzoeks- en engineeringtool, geen typegoedgekeurde navigatieapparatuur en geen veiligheidsdienst voor mensenlevens.

Uitvoeren#

kshana receiver-trust examples/receiver-trust/session.toml

Dit schrijft session.result.json, session.trust.csv (één rij per epoche) en session.trust.svg (gemiddelde C/N0 over de tijd met de vertrouwenstoestand eronder) naast het scenario, en drukt een oordeel van één regel af. Het voorbeeldlogboek is synthetisch, gemaakt om het formaat te tonen; wijs path naar het logboek van uw eigen ontvanger.

Vertrouwensscore over één synthetische overtocht, uit een echte run van engine v0.40.0 op examples/maritime-trust (een verzonnen NMEA-log van een veerboot op de route Tallinn-Helsinki, 3001 epochs bij 1 Hz). Drie banen delen één tijdas. Boven: de afstand tussen de positie die de ontvanger meldt en de werkelijke positie van het vaartuig, die tot ongeveer 1576 s binnen enkele meters blijft, wanneer de gescripte positie-drag-off van het log haar wegtrekt, terwijl de ontvanger een geldige positiebepaling blijft melden. Midden: de vertrouwensscore van 0 tot 100, niet berekend tijdens de eerste 300 s kalibratie, in de band nominal (ten minste 90) tot aan de drag-off, daarna dalend door de band degraded (ten minste 55) naar de band untrusted. Onder: de band van elke epoch als een gekleurd lint met zijn naam. De score is adviserend. Adviserende software, geen typegoedgekeurde navigatieapparatuur (IEC 61108, IEC 61162): de gezagvoerder of exploitant blijft verantwoordelijk voor de navigatie van het vaartuig. Het log is verzonnen om het formaat en de monitors te tonen; het is geen meting en zegt niets over hoe enige ontvanger zou presteren.Vertrouwensscore over één synthetische overtocht, uit een echte run van engine v0.40.0 op examples/maritime-trust (een verzonnen NMEA-log van een veerboot op de route Tallinn-Helsinki, 3001 epochs bij 1 Hz). Drie banen delen één tijdas. Boven: de afstand tussen de positie die de ontvanger meldt en de werkelijke positie van het vaartuig, die tot ongeveer 1576 s binnen enkele meters blijft, wanneer de gescripte positie-drag-off van het log haar wegtrekt, terwijl de ontvanger een geldige positiebepaling blijft melden. Midden: de vertrouwensscore van 0 tot 100, niet berekend tijdens de eerste 300 s kalibratie, in de band nominal (ten minste 90) tot aan de drag-off, daarna dalend door de band degraded (ten minste 55) naar de band untrusted. Onder: de band van elke epoch als een gekleurd lint met zijn naam. De score is adviserend. Adviserende software, geen typegoedgekeurde navigatieapparatuur (IEC 61108, IEC 61162): de gezagvoerder of exploitant blijft verantwoordelijk voor de navigatie van het vaartuig. Het log is verzonnen om het formaat en de monitors te tonen; het is geen meting en zegt niets over hoe enige ontvanger zou presteren.

De figuur hierboven is de vaartuigdemo van MARITIME-TRUST.md: een verzonnen logboek, een adviserende score.

Hetzelfde scenario draait vanuit Python (kshana.receiver_trust(toml)), vanuit het WebAssembly-pakket (receiver_trust(toml), met het logboek inline) en vanuit het hulpmiddel assess_receiver_log van de Model Context Protocol-server (MCP).

Logboeken die het leest#

format Bron Wat wordt gelezen
ubx u-blox binair NAV-SAT C/N0, elevatie en azimut per satelliet, NAV-PVT-positie, MON-RF automatische versterkingsregeling (AGC) en de jammingindicator jamInd, NAV-TIMEGPS-week, en de eigen vlaggen van de ontvanger: NAV-STATUS spoofDetState en SEC-SIG (self_report, zie RECEIVER-PROTOCOLS.md)
rinex RINEX 3-waarnemingsbestand S-codes (C/N0) per satelliet en signaal; met een bestand met uitgezonden navigatiegegevens (nav) de pseudoranges voor de eigen positiebepaling van de engine
android Android GnssLogger-CSV Raw-rijen: C/N0 en AgcDb per satelliet; Fix-rijen: positie
nmea NMEA 0183-tekst GSV-signaal-ruisverhouding per satelliet (dB-Hz, met of zonder het signaal-ID van 4,10) en zijn elevatie en azimut, GSA-dilution of precision en gebruikte satellieten, GGA- en RMC-tijd en -positie
sbf Septentrio binair (0,38, alleen lezen) PVTGeodetic-positie, MeasEpoch C/N0 per satelliet en signaal, RFStatus-aantal banden; zie RECEIVER-PROTOCOLS.md
rtklib-pos RTKLIB-oplossingsbestand (.pos) tijd, positie (breedte-/lengtegraad of ECEF, omgerekend) en gebruikte satellieten per epoche; bestanden met graden-minuten-seconden worden met een bericht geweigerd
novatel ASCII- of binaire logboeken van NovAtel OEM7 BESTPOS-positie (alleen een berekende oplossing), RANGE C/No per satelliet en signaal; RXSTATUS-jammervlaggen worden de self_report van de epoche (jammingtoestand 2 wanneer de ontvanger een jammer vlagt, 1 wanneer niet; in RXSTATUS bestaat geen spoofingvlag), afgezet tegen de alarmen van Kshana door de vergelijking receiver-self-report
gnss-sdr Monitor- en PVT-monitorstromen van GNSS-SDR als JSON-regels C/N0 per kanaal, positiebepaling, gebruikte satellieten, HDOP, azimut en elevatie; gemaakt door integrations/gnss-sdr/relay.py

Details, bronnen en beperkingen van deze drie: MACHINE-INPUTS.md.

Elke epoche die de lezers produceren draagt ook source_span, [start, end) byte-offsets in de invoer: het kleinste aaneengesloten bereik met de records die eraan hebben bijgedragen, zodat het exacte ruwe segment voor een eventvenster kan worden gehasht. NMEA: elke regel die wordt gelezen terwijl de epoche actueel is (een superset wanneer een niet-gerelateerde regel tussen haar zinnen staat). UBX: de frames van de epoche. RINEX 3: de epocherecords van elke >-regel tot de volgende. Android: de Raw-rijen van de epoche (een Fix-rij alleen voor een epoche zonder Raw-rijen). Afwezig bij een live stroom en overal waar het niet goed gedefinieerd is (RINEX 2).

Het bestand komt binnen via path (opgelost ten opzichte van de eigen map van het scenario), of inline als text of base64 (de enige keuzes in een browser).

Een IMU-logboek als tweede sensor#

[log.imu] voegt een traagheidslogboek toe op dezelfde klok:

[log.imu]
format = "csv"          # or "euroc"
path = "imu.csv"        # or text / base64
heading0_deg = 90.0     # heading at the first IMU sample
yaw_axis_down = true    # body z down (NED/FRD); false for z up (ENU/FLU)
time_offset_s = 0.0     # added to the IMU clock to reach the log's t_s

De giersnelheid wordt geïntegreerd uit heading0_deg en vult de koers overal waar het ontvangerlogboek er geen bevat, zodat de monitor heading-course (die heading_sensor = true op het platform nodig heeft) de gyrokoers vergelijkt met de koers over de grond. Een gyro drijft: de koers is slechts zo goed als het integratievenster en hdg_cog_tol_deg bepaalt wat als verschil telt. De indeling csv is gedocumenteerd in MACHINE-INPUTS.md. De IMU-bytes maken deel uit van de scenario-hash en van de scenario-hash van een bewijspakket. Inline (text/base64) werkt op elk oppervlak; een path wordt geweigerd waar geen bestanden worden gelezen.

Platform: statisch of vaartuig#

De monitors hierboven gaan uit van een vaste antenne. Een scenario legt het platform vóór de run vast in een tabel [platform] op het hoogste niveau; zonder die tabel is het platform static en verandert er niets.

[platform]
kind = "vessel"            # "static" (default) or "vessel"
max_speed_kn = 30.0        # default 30
max_accel_mps2 = 0.5       # default 0.5
max_turn_rate_dps = 6.0    # default 6
antenna_height_m = 18.0    # no default: without it the sea-level monitor does not run
heading_sensor = false     # true: the stream carries a gyro heading (HDT or THS)
Sleutel Standaard Waarom die waarde
max_speed_kn 30 Boven de dienstsnelheid van koopvaardijschepen en de meeste passagiersvaartuigen, zodat een echt vaartuig haar nooit bereikt; ver onder de snelheid die een positie-drag-off impliceert. Een langzamer vaartuig moet een lagere limiet opgeven: hoe lager de limiet, hoe eerder een drag wordt opgemerkt.
max_accel_mps2 0.5 Een groot schip verandert van snelheid met ruim minder dan 0,1 m/s²; een klein snel vaartuig haalt enkele tienden bij een harde gaswisseling.
max_turn_rate_dps 6 Een groot schip draait met ruim minder dan 1 deg/s en een klein vaartuig in een scherpe bocht met enkele.
antenna_height_m geen Een eigenschap van de installatie; een gok zou een verborgen drempel zijn.
heading_sensor false Gedeclareerd true en afwezig in het logboek is een fout, zodat een ontbrekende sensor niet als een schone controle kan doorgaan.

De vaartuigsleutels worden onder kind = "static" geweigerd. Voor een vaartuig draait de monitor position-jump niet, omdat die de afstand tot het kalibratiegemiddelde meet, wat op een bewegende antenne onjuist is; de monitor_config van het resultaat legt het platform en de gebruikte limieten vast.

De synthetische NMEA-stromen van kshana nmea-scenario, gemaakt voor bemanningstraining, worden door de NMEA-lezer geaccepteerd en kunnen net als elk NMEA-logboek door dit type worden gehaald.

Monitors#

Elke monitor heeft zijn eigen gegevens nodig; een monitor waarvan de gegevens niet in het log staan, wordt niet uitgevoerd en niet vermeld in monitors_run. De eerste calibration_s seconden (standaard 60) leggen de basislijn vast en geven nooit alarm.

Monitor Alarm wanneer Vereist
cn0-drop de gemiddelde C/N0 over de satellieten die met de basislijn gemeenschappelijk zijn, daalt met cn0_drop_db of meer (standaard 6 dB) C/N0
loss-of-lock het aantal gevolgde satellieten daalt sats_lost of meer onder de mediaan van de basislijn (standaard 4) C/N0
agc de AGC-waarde wijkt meer dan agc_k_sigma standaardafwijkingen af van haar basislijn (standaard 5) UBX MON-RF of Android AgcDb
jam-ind u-blox jamInd overschrijdt jam_ind_threshold (standaard 80 van 255) UBX MON-RF
position-jump de eigen positiebepaling van de ontvanger ligt meer dan position_jump_m van haar kalibratiegemiddelde (standaard 50 m) een gerapporteerde positie
raim pariteits-RAIM (receiver autonomous integrity monitoring) op de eigen enkelpuntspositiebepaling van de engine verwerpt de meetset RINEX-log met nav
solve-failure de enkelpuntspositiebepaling van de engine mislukt bij vijf of meer satellieten RINEX-log met nav
clock de ontvangerklok wijkt van haar voorspelde lijn af met meer dan de minimaal detecteerbare afwijking van haar kalibratieruis RINEX-log met nav

Gekalibreerd profiel (op aanvraag). [monitors] profile = "jammertest-2024-calibrated" vervangt de drie interferentiedrempels door waarden die zijn gekalibreerd op de openbare JammerTest 2024-dataset (één u-blox ZED-F9P per scenario; Zenodo 15911589): cn0_drop_db = 1.5, agc_k_sigma = 3.5, jam_ind_threshold = 29. De kalibratie was vooraf vastgelegd (xval/jammertest-trust/PREREGISTRATION.md) en het profiel is MODELLED, gefit op één openbare campagne: de drempel cn0_drop_db haalde de vooraf vastgelegde drempel voor achtergehouden valse alarmen niet (0,0231 tegenover 0,02); de drempels voor AGC en de jamming-indicator en de unie-drempel (valse alarmen 0,033, detectie 0,81) werden gehaald (xval/jammertest-trust/RESULTS.md). Het geldt voor dat ontvangertype bij die gebeurtenis, tegen geplande aanvalsvensters, en is gekalibreerd op de CSV-logs van de dataset (de UBX-logs geven meer valse alarmen in twee mappen). Een resultaat van een run met het profiel herhaalt de toegepaste drempels en bevat een profile_note waarin dit alles staat. Zonder het profiel gelden de standaardwaarden hierboven en blijft elke uitvoer ongewijzigd.

Voor een vessel-platform worden ook de monitors voor bewegende platforms uitgevoerd (drempels in een [maritime]-tabel op het hoogste niveau, elke standaardwaarde gedocumenteerd in src/receiver_trust/maritime.rs); elk heeft zijn eigen gegevens nodig en wordt alleen in monitors_run vermeld als het een besluit heeft genomen:

Monitor Alarm wanneer Vereist
kinematic de positieverandering komt niet overeen met de gerapporteerde snelheid en koers, of impliceert een snelheid, versnelling of draaisnelheid boven de grenzen van het vaartuig positiebepalingen; snelheid en koers (RMC of VTG) voor het dead-reckoning-deel
heading-course de gyrokoers en de koers over de grond verschillen met meer dan hdg_cog_tol_deg (snelheid boven min_speed_kn) HDT-, THS- of VHW-koers, heading_sensor = true
speed-log de snelheid door het water en de snelheid over de grond verschillen met meer dan stw_sog_tol_kn VHW of VBW, en snelheid over de grond
sea-level de GGA-hoogte verschilt met meer dan sea_level_tol_m van antenna_height_m GGA-hoogte, antenna_height_m
cn0-spread de spreiding van de C/N0 over de satellieten daalt tot cn0_spread_frac van haar kalibratiemediaan GSV
cn0-rise de C/N0 van de gemeenschappelijke satellieten steeg gemiddeld met cn0_rise_db en cn0_rise_frac van hen steeg GSV
time-consistency opeenvolgende epochetijden springen onregelmatig, lopen achteruit of wijken af van de hostklok NMEA-tijd; hostklok voor het laatste deel
osnma de ontvanger meldt een OSNMA-authenticatiefout (een gerapporteerde status wordt gelezen; er wordt niets geverifieerd; zie docs/OSNMA.md om OSNMA te verifiëren aan de hand van de I/NAV-pagina's zelf) $PKSOS-statuszin

Een epoche is onbetrouwbaar wanneer RAIM, de klokmonitor, een mislukte oplossing of een positiesprong alarm geeft, of de C/N0-daling tweemaal haar drempel bereikt; gedegradeerd bij elk ander alarm; en nominaal in de overige gevallen.

Het enginepad (raim, solve-failure, clock) is dezelfde berekening als de JammerTest 2024-spoofingreferentie in tests/jammertest_spoof_oracle_support: tests/receiver_trust_jammertest.rs controleert dat bij alle acht gepubliceerde begintijden het eerste alarm op dezelfde epoche valt en van dezelfde soort is.

Vertrouwensscore (vaartuigplatform)#

Voor een vaartuig krijgt elke epoche na de kalibratie ook een score van 0 tot 100 en de redenen waarom die niet 100 is. De afbeelding is deterministisch en vastgelegd voordat een log wordt gescoord: niets wordt geleerd, niets wordt gefit aan gebeurtenissen. Elke monitor herleidt zijn bewijs tot een verhouding statistic / threshold (een alarm bij 1 of meer); een verhouding kost de score

points = weight * clamp((ratio - onset_ratio) / (full_ratio - onset_ratio), 0, 1)
score  = round_to_0.1( clamp(100 - sum of points, 0, 100) )

zodat een monitor niets kost zolang hij onder onset_ratio van zijn drempel blijft (standaard 0,5), de helft van zijn gewicht bij zijn drempel, en alles bij full_ratio maal de drempel (standaard 1,5); de score is niet-stijgend in elke statistiek. Een bron die op een epoche niets rapporteert, behoudt zijn laatste statistiek gedurende evidence_hold_s (standaard 10 s: twee cycli van een C/N0-zin die elke 5 s wordt verzonden), zowel als alarm als als aftrek.

De afronding is naar boven vanaf de helft (floor(x * 10 + 0.5) / 10), de band is die van de afgeronde score en de begrenzing komt vóór de afronding. Alleen monitors met punten boven nul staan in de aftrekposten, met hun verhouding en onafgeronde punten, de meeste punten eerst; aftrekposten met gelijke punten staan in de volgorde van de monitornamen 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, geometry. Een monitor waarvan de test slaagt of faalt (een mislukte oplossing, een mislukte authenticatie) krijgt de verhouding 1,5, het volledige gewicht. De vermelde punten zijn die vóór de begrenzing op 0.

[score]
nominal_min = 90.0         # score >= 90: nominal
degraded_min = 55.0        # 55 <= score < 90: degraded; below 55: untrusted
onset_ratio = 0.5
full_ratio = 1.5
evidence_hold_s = 10.0
[score.weights]            # overrides; a monitor not listed keeps its default
sea-level = 30.0
Gewicht (punten) Monitors Waarom
70 osnma een authenticatiefout is een vaststelling, geen statistiek
60 kinematic, raim, clock, position-jump, time-consistency een vervalste positie moet de natuurkunde of de eigen controles van de ontvanger tegenspreken, en de tijd kan niet achteruitlopen; één overtreding op volle sterkte (1,5 maal haar drempel: 60 punten, score 40) is onbetrouwbaar, en bij haar drempel (30 punten, score 70) gedegradeerd
40 heading-course, speed-log, solve-failure één onafhankelijke sensor die afwijkt is gedegradeerd; twee op volle sterkte zijn onbetrouwbaar
30 sea-level, cn0-spread, cn0-rise, cn0-drop de signaalomgeving, of een zwak informatieve controle
25 loss-of-lock, agc, jam-ind de omgeving is vijandig; dat alleen toont niet aan dat de positiebepaling fout is
tot 15, [geometry] geometry (0.36) geen gewicht op deze helling: niets tenzij de hemel slecht is, dan tot cap_points (15); geometrie alleen bereikt gedegradeerd, nooit onbetrouwbaar, en geeft geen alarm (zie "Geometrie" hieronder)

De bandgrenzen volgen uit de gewichten: de lichtste monitor die alarm geeft kost 12,5 punten bij zijn drempel, dus elk alarm verlaat de nominale band; geen enkele monitor onder 60 punten kan de onbetrouwbare band alleen bereiken (meerdere samen wel). Het resultaat legt het scoremodel vast (score_model) en elke epoche bevat score.deductions: welke monitors hebben afgetrokken, hun verhoudingen en hun punten. Voor een vaartuig is de toestand van de epoche de band van haar score.

Geometrie: natuurlijke degradatie los van aanvalsachtige inconsistentie#

Een ontvanger naast een kadekraan, in een sluis of onder een hoge romp verliest satellieten en zijn positiebepaling wordt slechter om een reden die geen aanval is. Vanaf 0,36, volgens de ontwerpnotitie over geometrie (docs/design/2026-10-12-geometry-and-skyline-design.md, sectie 4), bevat elke epoche haar satellietgeometrie, heeft de score van een vaartuig een geometriemonitor en draagt elke aftrekpost een klasse: geometry (de hemel), environment (de signaalomgeving) of inconsistency (aanvalsachtig bewijs).

Waar de geometrie vandaan komt. De elevatie en azimut van elke gevolgde satelliet (NMEA GSV, UBX NAV-SAT), waaruit de dilution of precision (DOP) wordt afgeleid met de ene DOP-kernel van de engine (orbit::dop, VALIDATED tegen gnss_lib_py): source = derived. Bij ontstentenis daarvan de DOP en de gebruikte satellieten die de ontvanger opgeeft (NMEA GSA): source = reported. Hemelposities en GSA tellen mee voor de evidence_hold_s van de score (standaard 10 s), omdat veel bussen GSV om de paar seconden verzenden; een GSV-set die in een epoche onvolledig is (het einde van een fragment, een verloren zin) wordt niet gebruikt. Een log met geen van beide, zoals NMEA met alleen GGA en RMC, of Android- en RINEX-logs op dit moment, krijgt de status unknown met de opmerking "geometry unknown": de engine raadt geen geometrie die hij niet heeft gekregen, en de geometriemonitor wordt niet uitgevoerd.

geometry.status Betekenis
good genoeg satellieten en een DOP binnen de drempels
degraded een of meer redenen: few-satellites, high-pdop, high-hdop, en (informatief, niet in de score) sky-blocked wanneer elke gevolgde satelliet in één helft van de horizon staat
unknown het log geeft voor deze epoche geen satellietgeometrie

De status is beschrijvend en het label (hieronder) is wat voor de score telt: degraded omvat het informatieve geval sky-blocked, dat kan voorkomen bij goede of redelijke DOP, en alleen een label poor wordt gescoord.

Het label (altijd gerapporteerd, nooit gescoord). Het geometry.label van elke epoche is good (HDOP hoogstens hdop_good 2, PDOP hoogstens pdop_good 3 en ten minste used_good 6 satellieten), poor (HDOP boven hdop_max 4, PDOP boven pdop_max 6 of minder dan min_used 5 satellieten), fair daartussen, of unknown. De opmerking van de epoche begint altijd met het label en de getallen, bijvoorbeeld "geometry fair: HDOP 1,105, PDOP 1,831, VDOP 1,410, 8 satellites; not scored (the score deducts only above HDOP 4, PDOP 6 or below 5 satellites)", en voegt ", signal loss" toe wanneer dat geldt.

De geometriemonitor (vaartuigscore). Hij trekt niets af tenzij de geometrie slecht is: zijn verhouding is max(hdop / hdop_max, pdop / pdop_max, min_used / n_used), en zolang die hoogstens 1 is (goede of redelijke geometrie, een open hemel met alleen GPS en 8 satellieten inbegrepen) kost hij niets, zodat zo'n log precies scoort als in 0,35. Boven 1 loopt de aftrek lineair op tot cap_points (15) bij full_ratio (1,5 maal de drempels: HDOP 6, PDOP 9, 3 satellieten): 7,5 punten bij verhouding 1,25 (HDOP 5, of 4 satellieten), 15 vanaf 1,5 (score 85, gedegradeerd). Op zichzelf kan hij de score nooit onder floor brengen (standaard: de degraded_min van de score, 55), zodat geometrie alleen hoogstens de gedegradeerde band bereikt en nooit de onbetrouwbare: het geldende maximum is min(cap_points, 100 - floor), zodat een [score]-tabel die degraded_min verhoogt (bijvoorbeeld een 0,35-tabel met degraded_min 90) het maximum verlaagt tot 100 - degraded_min in plaats van te worden geweigerd, en een floor onder degraded_min wordt geweigerd. De monitor geeft geen alarm; hij staat als laatste in monitors_run wanneer hij op enige epoche een besluit heeft genomen (een vaartuig waarvan het log de geometrie geeft), en telt niet mee in de identiteit met 0,35; hij is geen item van [score.weights] (er een instellen wordt geweigerd), en het geldende maximum en de geldende ondergrens worden vastgelegd in geometry_model.cap_in_force en geometry_model.floor_in_force. De opmerking van een slechte epoche zegt waarom, bijvoorbeeld "geometry poor: HDOP 5,200, PDOP 7,900, VDOP 4,100, 7 satellites; degraded by geometry: HDOP 5,200 above 4 (derived from 7 logged satellites); not an inconsistency".

Klassen. Elke aftrekpost (score.deductions[].class):

Klasse Monitors
geometry geometry (slechte geometrie); loss-of-lock wanneer elke satelliet die ten opzichte van de kalibratiebasislijn verloren ging bij zijn laatste rapport onder low_elev_deg stond
environment cn0-drop, cn0-spread, cn0-rise, agc, jam-ind, anders loss-of-lock; geometry tijdens signaalverlies (hieronder)
inconsistency kinematic, heading-course, speed-log, sea-level, time-consistency, clock, raim, position-jump, osnma, solve-failure; en geometry wanneer de geometrie slecht is en de opgegeven HDOP niet overeenkomt met de opgegeven hemel (hieronder)

De bescherming tegen een vervalste slechte hemel. Een spoofer zou een ijle GSV kunnen sturen, of een hoge HDOP kunnen rapporteren, om tolerantie te kopen. De engine labelt en vergeeft niet: geen enkele andere controle wordt verruimd door een slechte geometrie, en de HDOP die de ontvanger opgeeft (GSA binnen de hold, anders GGA) wordt vergeleken met de HDOP afgeleid uit de hemel die hij opgeeft. Wanneer die meer dan max(reported_vs_derived_tol, reported_vs_derived_rel × derived HDOP) verschillen (1,0, of 25 % van de afgeleide HDOP, welke de grootste is), draagt de epoche reported_derived_mismatch: true en wordt, wanneer de geometrie slecht is, haar aftrek geklasseerd als inconsistency. Bij goede of redelijke geometrie wordt het verschil gerapporteerd en niet gescoord: er wordt niets afgetrokken tenzij de geometrie slecht is. Dit is een bewuste keuze (0,36): "nul tenzij slecht" geldt voor elke epoche, zodat goede en redelijke geometrie precies scoren als in 0,35, en een vervalste HDOP nooit onopgemerkt blijft. De vlag (reported_derived_mismatch) staat op elke epoche van het resultaat en elke live regel, de opmerking zegt "…beyond the tolerance: reported, not scored (the geometry is not poor)" of "…: the geometry deduction is classed an inconsistency", geometry_summary.hdop_mismatch telt de epochen, en de samenvattende bewijspagina toont het aantal, ook als het nul is. De 25 % is een REPRESENTATIVE technische keuze, geen gemeten of genormeerd getal: een ontvanger die per constellatie één klok oplost, of met een deel van de satellieten die hij volgt (een elevatiemasker, een C/N0-grens, een RAIM-uitsluiting), geeft een HDOP op die afwijkt van de HDOP met één klok van elke gevolgde satelliet met een verschil dat met de HDOP groeit, zodat een vaste tolerantie alleen natuurlijke slechte geometrie als inconsistentie zou lezen. Een groter verschil blijft als zodanig gelden. Een aftrek geklasseerd als geometry is een uitspraak over de hemel, geen vaststelling dat er geen aanval is geweest.

Signaalverlies is niet de hemel. Wanneer satellieten die de ontvanger als zichtbaar opgeeft (boven low_elev_deg) niet worden gevolgd, leidt de engine ook de DOP af van alle zichtbare satellieten. Als die DOP van de zichtbare satellieten binnen de drempels ligt en er ofwel niets wordt gevolgd ofwel de ongevolgde satellieten rond de horizon verspreid zijn (niet beperkt tot één helft ervan), was de hemel er en het signaal niet: de epoche draagt signal_loss: true, de opmerking "satellites in view but not tracked: signal environment, not geometry", en de geometrie-aftrek wordt geklasseerd als environment. Ongevolgde satellieten die beperkt zijn tot één helft van de horizon gelden nog steeds als een geblokkeerde hemel (een muur, een klif, een kade). Een obstructie aan twee kanten (een canyon of een smalle fjord) geldt als signaalverlies totdat een skyline is geconfigureerd. De no-fix-sentinels van de ontvanger zijn geen DOP: een opgegeven HDOP of PDOP van 99 of meer, GGA-kwaliteit 0 en GSA-modus 1 geven geen opgegeven DOP.

Sleutel [geometry] Standaard Herkomst
hdop_max 4 gekozen (ontwerpnotitie 4,2): bij sigma_uere_m 1,5 m is HDOP 4 een 2drms van 12 m, de kin_pos_tol_m van de kinematische controle. IEC 61108-1 wordt gewoonlijk aangehaald als stellend dat de nauwkeurigheidseisen gelden voor HDOP ≤ 4 (of PDOP ≤ 6): herinnerd uit secundaire GNSS-ontvangerliteratuur, geen specifieke secundaire bron geraadpleegd en de norm niet gelezen; nog te controleren aan de tekst van de norm
pdop_max 6 de PDOP-beschikbaarheidsdrempel van scenarios/polar-arctic-leo-coverage.toml; GPS SPS Performance Standard, 5e ed. (2020), PDOP ≤ 6, zoals aangehaald in tests/constellation_availability_published_spec_oracle.rs; nog te controleren aan de tekst van de norm
min_used 5 één meer dan een positiebepaling nodig heeft, zodat een enkel verlies de positiebepaling niet beëindigt; het minimum met één redundante meting voor RAIM
sigma_uere_m 1.5 een opgegeven invoer voor de 2drms-koppeling van hdop_max; stel het eigen cijfer van de ontvanger in
reported_vs_derived_tol 1,0 HDOP gekozen (ontwerpnotitie 4,2): het absolute deel van de tolerantie; een verschil buiten de tolerantie is geen geometrie
reported_vs_derived_rel 0.25 REPRESENTATIVE technische keuze: het relatieve deel, voor ontvangers met klokken per constellatie of oplossingen op een deelverzameling
low_elev_deg 15 ontwerpnotitie 4,3: satellieten die eronder verloren gaan, gaan verloren aan de hemel; een skyline (0,36 punt 1) zal dit uitbreiden
azimuth_gap_deg 180 geometrisch, informatief: elke satelliet in één helft van de horizon
cap_points 15 ontwerpnotitie 4,2: geometrie alleen brengt de score van nominaal naar gedegradeerd en nooit naar onbetrouwbaar; alleen afgetrokken wanneer de geometrie slecht is (besluit B1 van de oprichter, 0,36)
full_ratio 1.5 de eigen full_ratio van de score: de helling bereikt cap_points bij 1,5 maal de drempels voor slecht
floor de degraded_min van de score (55) geometrie alleen bereikt nooit de onbetrouwbare band; het geldende maximum is min(cap_points, 100 - floor); een ondergrens onder degraded_min wordt geweigerd
hdop_good 2 REPRESENTATIVE, alleen het label: de helft van hdop_max (de beginverhouding van de score van 0,35)
pdop_good 3 REPRESENTATIVE, alleen het label: de helft van pdop_max
used_good 6 REPRESENTATIVE, alleen het label: één meer dan min_used, zodat een enkel verlies nog steeds een redundante meting overlaat

Wat er in de uitvoer is veranderd, en wat niet. Er verandert geen score tenzij de geometrie slecht is; het label wordt altijd gerapporteerd. Toegevoegde sleutels: epochs[].geometry (status, reasons, source, n_used, hdop, pdop, vdop afgerond op 0,001, open_fraction (null totdat een skyline is geconfigureerd), max_azimuth_gap_deg, age_s, reported_hdop, reported_derived_mismatch, note, in_view (satellieten vermeld boven low_elev_deg), signal_loss, label), class bij elke aftrekpost, en aan het einde geometry_model (drempels, hold, het geldende maximum en de geldende ondergrens, herkomst, klasseregels) en geometry_summary (epochen per status, per label en per aftrekklasse, en de epochen met een afwijking van de opgegeven HDOP); score_model.weights is als in 0,35. Twee tests houden dit tot op de byte gelijk aan de basislijn "0,36 portable" zodra die sleutels zijn verwijderd (de hashes van 0.35.0, opnieuw vastgesteld toen de engine overging op portable wiskunde en in de tests bewaard als het verslag van wat 0.35.0 uitbracht: docs/revisions/STUDIO15-portable-math-rebaseline.md). tests/geometry_trust_no_change.rs legt elke uitvoer van beide voorbeeldsessies vast (resultaat-JSON, CSV, SVG, verdict, herhaalde live regels, $PKSHT, Prometheus, CEF, LEEF). tests/geometry_corpus_identity.rs legt het batchresultaat, de samenvatting, de live regels en $PKSHT vast van elk vastgelegd NMEA-corpus van vaartuigen (de demo en de maritieme referentiefixtures, elk ook als open hemel met alleen GPS en 8 satellieten, en de trainingsscenario's voor bemanningen die uit hun seeds worden gegenereerd); in de twee trainingsscenario's waarin jamming de geometrie slecht maakt, is elke epoche die niet slecht is identiek en wijkt elke slechte epoche alleen af door de geometrie-aftrek. Een log waarvan de geometrie slecht is, verliest tot 15 punten die het in 0,35 niet verloor; dat is de beoogde wijziging. In de demo leest de drag-off als inconsistency; tests/geometry_trust.rs bewerkt het log om de westelijke hemel te maskeren (redelijk: gelabeld, niet gescoord), om die en twee oostelijke satellieten te maskeren (slecht: geometrie-aftrekken, verlies van lock environment omdat ook hoge satellieten wegvielen), om alleen satellieten onder 15° te verliezen (verlies van lock geometry), en om een HDOP op te geven die de hemel niet verklaart (de aftrek voor slechte geometrie wordt inconsistency). De drempels zijn MODELLED: gekozen, niet gefit aan enig log; niets hier beweert hoe vaak natuurlijke degradatie en aanvallen op echte data van elkaar worden onderscheiden.

Gebeurtenissen en voorspellingen vaststellen#

[[events]]
label = "jammer on"
kind = "jamming"            # jamming, spoofing or other
onset_s = 120.0             # seconds since the first epoch of the log
end_s = 240.0               # optional; otherwise onset_s + compare.horizon_s
predicted_cn0_drop_db = 12.0  # optional, e.g. from a `jamming` scenario's link budget

[compare]
detect_tol_s = 10.0         # an alarm this soon after onset counts as a detection
cn0_tol_db = 3.0            # predicted and observed drops agree within this

Voor elke gebeurtenis geeft het resultaat de valse alarmen tussen kalibratie en begintijd, het eerste alarm en zijn monitors, de latentie, de uitkomst (detected, late, missed of not-evaluable), en de waargenomen mediane C/N0-daling tegenover de voorspelling (agree, disagree, no-prediction of not-evaluable). Afwijking wordt gerapporteerd, nooit weggestemd: de toleranties staan in het scenario, en het scenario zit in de hash van het resultaat.

Wat dit niet beweert#

De vertrouwensmonitors zijn MODELLED: hun drempels zijn invoer, en hun detectieprestatie bij echte interferentie is wat de gebeurtenisscoring meet, niet iets wat dit soort beweert. Bij de JammerTest 2024-spoofingsessies vangen de monitors op het enginepad sommige begintijden binnen 10 s en zijn ze bij andere te laat; zie de rij "Clock-aided χ², RAIM, AGC, SQM fused per-epoch security FoM" in VERIFICATION-MATRIX.md voor de cijfers. Een voorspelling die met één log overeenkomt, is één datapunt, geen validatie.