Modtagertillid: vurdering af en virkelig GNSS-modtagerlog
kshana receiver-trust læser en log fra en virkelig global navigation satellite system-modtager (GNSS), kører tillidsmonitorer over den epoke for epoke og siger, hvornår og hvorfor modtagerens positionsbestemmelse holdt op med at være pålidelig. Den kan også score loggen mod hændelser og forudsigelser, du angiver før kørslen: om hver hændelse blev opdaget i tide, og om et modelleret fald i forholdet mellem bærebølge og støjtæthed (C/N0) stemmer med det, modtageren målte.
Observablerne er modtagerens egne; monitorerne og deres tærskler er motorens og dine. Hvert resultat bærer det mærke, loggens SHA-256 og hver tærskel, det kørte med, så en kørsel kan gentages og revideres.
For et fartøj under sejlads, med en levende score og en valgfri gate foran et kortsystem, se MARITIME-TRUST.md.
Kør den#
kshana receiver-trust examples/receiver-trust/session.toml
Dette skriver session.result.json, session.trust.csv (én række pr. epoke) og session.trust.svg (middel-C/N0 over tid med tillidstilstanden nedenunder) ved siden af scenariet og udskriver en afgørelse på én linje. Eksempellogen er syntetisk, lavet for at vise formatet; peg path på din egen modtagers log.
Figuren ovenfor er fartøjsdemoen fra MARITIME-TRUST.md: en opdigtet log, en vejledende score.
Det samme scenarie kan køres fra Python (kshana.receiver_trust(toml)), fra WebAssembly-pakken (receiver_trust(toml), med loggen indlejret) og fra værktøjet assess_receiver_log i Model Context Protocol-serveren (MCP).
Logs, den læser#
format |
Kilde | Hvad der læses |
|---|---|---|
ubx |
u-blox binær | NAV-SAT C/N0, elevation og azimut pr. satellit, NAV-PVT position, MON-RF automatisk forstærkningsregulering (AGC) og jamming-indikatoren jamInd, NAV-TIMEGPS uge og modtagerens egne flag: NAV-STATUS spoofDetState og SEC-SIG (self_report, se RECEIVER-PROTOCOLS.md) |
rinex |
RINEX 3 observationsfil | S-koder (C/N0) pr. satellit og signal; med en broadcast-navigationsfil (nav) pseudoafstandene til motorens egen positionsbestemmelse |
android |
Android GnssLogger CSV | Raw-rækker: C/N0 og AgcDb pr. satellit; Fix-rækker: position |
nmea |
NMEA 0183-tekst | GSV signal-til-støj pr. satellit (dB-Hz, med eller uden signal-ID'et 4,10) og dens elevation og azimut, GSA dilution of precision og anvendte satellitter, GGA og RMC tid og position |
sbf |
Septentrio binær (0,38, kun læsning) | PVTGeodetic position, MeasEpoch C/N0 pr. satellit og signal, RFStatus antal bånd; se RECEIVER-PROTOCOLS.md |
rtklib-pos |
RTKLIB-løsningsfil (.pos) |
tid, position (bredde/længde eller ECEF, omregnet) og anvendte satellitter pr. epoke; filer med grader-minutter-sekunder afvises med en meddelelse |
novatel |
NovAtel OEM7 ASCII- eller binære logs | BESTPOS position (kun beregnet løsning), RANGE C/No pr. satellit og signal; RXSTATUS-flag for jammere bliver epokens self_report (jammingtilstand 2, når modtageren flager en jammer, 1, når den ikke gør; der findes intet spoofingflag i RXSTATUS), stillet over for Kshanas alarmer af sammenligningen receiver-self-report |
gnss-sdr |
GNSS-SDR Monitor- og PVT-monitor-strømme som JSON-linjer | C/N0 pr. kanal, positionsbestemmelse, anvendte satellitter, HDOP, azimut og elevation; lavet af integrations/gnss-sdr/relay.py |
Detaljer, kilder og begrænsninger for disse tre: MACHINE-INPUTS.md.
Hver epoke, læserne producerer, bærer også source_span, [start, end)-byteoffsets i inputtet: det mindste sammenhængende interval, der rummer de poster, der bidrog til den, så den præcise rå udsnit kan hashes for et hændelsesvindue. NMEA: hver linje, der læses, mens epoken er aktuel (en overmængde, hvor en urelateret linje står mellem dens sætninger). UBX: epokens rammer. RINEX 3: epokeposterne fra hver >-linje til den næste. Android: epokens Raw-rækker (en Fix-række kun for en epoke uden Raw-rækker). Fraværende for en levende strøm og overalt, hvor det ikke er veldefineret (RINEX 2).
Filen angives med path (opløst mod scenariets egen mappe) eller indlejret som text eller base64 (de eneste valg i en browser).
En IMU-log som anden sensor#
[log.imu] tilføjer en inertiallog på det samme ur:
[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
Gyrodrejningshastigheden integreres fra heading0_deg og udfylder kursen, hvor modtagerloggen ingen har, så monitoren heading-course (som kræver heading_sensor = true på platformen) sammenligner gyrokurs med kurs over grunden. En gyro driver: kursen er kun så god som integrationsvinduet, og hdg_cog_tol_deg afgør, hvad der tæller som uenighed. Layoutet csv er dokumenteret i MACHINE-INPUTS.md. IMU-bytes indgår i scenariehashen og i en bevispakkes scenariehash. Indlejret (text/base64) virker på alle overflader; en path afvises, hvor filer ikke læses.
Platform: statisk eller fartøj#
Monitorerne ovenfor antager en fast antenne. Et scenarie angiver platformen før kørslen i en [platform]-tabel på øverste niveau; uden en er platformen static, og intet ændres.
[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)
| Nøgle | Standard | Hvorfor den værdi |
|---|---|---|
max_speed_kn |
30 | Over driftshastigheden for handelsskibe og de fleste passagerfartøjer, så et virkeligt fartøj aldrig når den; langt under den hastighed, et position-drag-off indebærer. Et langsommere fartøj bør angive en lavere grænse: jo lavere grænse, jo tidligere fanges en drag. |
max_accel_mps2 |
0.5 | Et stort skib ændrer hastighed med langt under 0,1 m/s²; et lille hurtigt fartøj når nogle få tiendedele ved et hårdt gasskift. |
max_turn_rate_dps |
6 | Et stort skib drejer med langt under 1 deg/s og et lille fartøj i et hårdt sving med nogle få. |
antenna_height_m |
ingen | En egenskab ved installationen; et gæt ville være en skjult tærskel. |
heading_sensor |
false | Hvis true er erklæret og mangler i loggen, er det en fejl, så en manglende sensor ikke kan passere som en ren kontrol. |
Fartøjsnøglerne afvises under kind = "static". For et fartøj kører monitoren position-jump ikke, fordi den måler afstanden fra kalibreringsmiddelværdien, hvilket er forkert på en antenne i bevægelse; resultatets monitor_config registrerer platformen og de grænser, der blev brugt.
De syntetiske NMEA-strømme fra kshana nmea-scenario, lavet til besætningstræning, accepteres af NMEA-læseren og kan køres gennem denne type som enhver NMEA-log.
Monitorer#
Hver monitor har brug for sine data; en monitor, hvis data ikke findes i loggen, kører ikke og opføres ikke i monitors_run. De første calibration_s sekunder (standard 60) fastlægger baseline og udløser aldrig alarm.
| Monitor | Alarmerer, når | Kræver |
|---|---|---|
cn0-drop |
middel-C/N0 over de satellitter, der er fælles med baseline, falder med cn0_drop_db eller mere (standard 6 dB) |
C/N0 |
loss-of-lock |
sporede satellitter falder sats_lost eller mere under medianen for baseline (standard 4) |
C/N0 |
agc |
AGC-aflæsningen afviger fra sin baseline med mere end agc_k_sigma standardafvigelser (standard 5) |
UBX MON-RF eller Android AgcDb |
jam-ind |
u-blox jamInd overstiger jam_ind_threshold (standard 80 af 255) |
UBX MON-RF |
position-jump |
modtagerens egen positionsbestemmelse ligger mere end position_jump_m fra dens kalibreringsmiddelværdi (standard 50 m) |
en rapporteret position |
raim |
paritets-RAIM (receiver autonomous integrity monitoring) på motorens egen enkeltpunktspositionsbestemmelse afviser målingssættet | RINEX-log med nav |
solve-failure |
motorens enkeltpunktspositionsbestemmelse mislykkes med fem eller flere satellitter | RINEX-log med nav |
clock |
modtagerens ur afviger fra sin forudsagte linje med mere end den mindste påviselige forskydning for dets kalibreringsstøj | RINEX-log med nav |
Kalibreret profil (tilvalg). [monitors] profile = "jammertest-2024-calibrated" erstatter de tre interferenstærskler med værdier, der er kalibreret på det offentlige JammerTest 2024-datasæt (én u-blox ZED-F9P pr. scenarie; Zenodo 15911589): cn0_drop_db = 1.5, agc_k_sigma = 3.5, jam_ind_threshold = 29. Kalibreringen blev præregistreret (xval/jammertest-trust/PREREGISTRATION.md), og profilen er MODELLED, tilpasset én offentlig kampagne: dens tærskel cn0_drop_db nåede ikke den præregistrerede tærskel for falske alarmer i det tilbageholdte datasæt (0,0231 mod 0,02); tærsklerne for AGC og jamming-indikator og unionstærsklen (falske alarmer 0,033, detektion 0,81) blev nået (xval/jammertest-trust/RESULTS.md). Den gælder for den modtagertype ved den hændelse, mod planlagte angrebsslots, og blev kalibreret på datasættets CSV-logs (dets UBX-logs giver flere falske alarmer i to mapper). Et resultat, der er kørt med profilen, gentager de tærskler, det anvendte, og bærer en profile_note, der siger alt dette. Uden profilen gælder standardværdierne ovenfor, og alt output er uændret.
For en vessel-platform kører monitorerne for platforme i bevægelse også (tærskler i en [maritime]-tabel på øverste niveau, hver standardværdi dokumenteret i src/receiver_trust/maritime.rs); hver har brug for sine data og opføres i monitors_run kun, når den har afgjort noget:
| Monitor | Alarmerer, når | Kræver |
|---|---|---|
kinematic |
positionsændring er uenig med den rapporterede fart og kurs, eller indebærer en fart, acceleration eller drejehastighed over fartøjets grænser | positioner; fart og kurs (RMC eller VTG) til dead reckoning-delen |
heading-course |
gyrokurs og kurs over grunden afviger med mere end hdg_cog_tol_deg (fart over min_speed_kn) |
HDT-, THS- eller VHW-kurs, heading_sensor = true |
speed-log |
fart gennem vandet og fart over grunden afviger med mere end stw_sog_tol_kn |
VHW eller VBW og fart over grunden |
sea-level |
GGA-højden afviger fra antenna_height_m med mere end sea_level_tol_m |
GGA-højde, antenna_height_m |
cn0-spread |
spredningen af C/N0 på tværs af satellitter falder til cn0_spread_frac af dens kalibreringsmedian |
GSV |
cn0-rise |
C/N0 for de fælles satellitter steg i gennemsnit med cn0_rise_db, og cn0_rise_frac af dem steg |
GSV |
time-consistency |
tiderne for på hinanden følgende epoker springer uregelmæssigt, løber baglæns eller forlader værtens ur | NMEA-tid; værtens ur for den sidste del |
osnma |
modtageren rapporterer en fejl i OSNMA-autentificering (en rapporteret status læses; intet verificeres; for at verificere OSNMA ud fra selve I/NAV-siderne se docs/OSNMA.md) | $PKSOS-statussætning |
En epoke er ikke betroet, når RAIM, urmonitoren, en mislykket løsning eller et positionsspring alarmerer, eller faldet i C/N0 når det dobbelte af sin tærskel; degraderet ved enhver anden alarm; og ellers nominel.
Motorstien (raim, solve-failure, clock) er den samme beregning som den uafhængige reference for spoofing i JammerTest 2024 i tests/jammertest_spoof_oracle_support: tests/receiver_trust_jammertest.rs kontrollerer, at den første alarm på alle otte offentliggjorte starttidspunkter falder på samme epoke og er af samme art.
Tillidsscore (fartøjsplatform)#
For et fartøj får hver epoke efter kalibrering også en score fra 0 til 100 og de grunde, til at den ikke er 100. Afbildningen er deterministisk og fastlagt, før nogen log scores: ingen læring, intet tilpasset til hændelser. Hver monitor reducerer sin evidens til et forhold statistic / threshold (en alarm ved 1 eller mere); et forhold koster scoren
points = weight * clamp((ratio - onset_ratio) / (full_ratio - onset_ratio), 0, 1)
score = round_to_0.1( clamp(100 - sum of points, 0, 100) )
så en monitor koster intet, mens den er under onset_ratio af sin tærskel (standard 0,5), halvdelen af sin vægt ved sin tærskel og hele vægten ved full_ratio gange tærsklen (standard 1,5); scoren er ikke-voksende i hver statistik. En kilde, der ikke rapporterer ved en epoke, beholder sin sidste statistik i evidence_hold_s (standard 10 s: to cyklusser af en C/N0-sætning, der sendes hvert 5 s), både som alarm og som fradrag.
Afrundingen er halv op (floor(x * 10 + 0.5) / 10), båndet er det for den afrundede score, og begrænsningen kommer før afrundingen. Kun monitorer, hvis point er over nul, opføres i fradragene, med deres forhold og uafrundede point, største point først; fradrag med lige mange point opføres i rækkefølgen af monitornavnene 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. En monitor, hvis test er bestået eller ikke bestået (en mislykket løsning, en mislykket autentificering), får forholdet 1,5, den fulde vægt. De opførte point er dem før begrænsningen ved 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
| Vægt (point) | Monitorer | Hvorfor |
|---|---|---|
| 70 | osnma |
en mislykket autentificering er en erklæring, ikke en statistik |
| 60 | kinematic, raim, clock, position-jump, time-consistency |
en forfalsket position skal modsige fysikken eller modtagerens egne kontroller, og tiden kan ikke løbe baglæns; én overtrædelse med fuld styrke (1,5 gange sin tærskel: 60 point, score 40) er ikke betroet, og ved sin tærskel (30 point, score 70) degraderet |
| 40 | heading-course, speed-log, solve-failure |
én uafhængig sensor, der er uenig, er degraderet; to med fuld styrke er ikke betroet |
| 30 | sea-level, cn0-spread, cn0-rise, cn0-drop |
signalmiljøet eller en kontrol med svag informationsværdi |
| 25 | loss-of-lock, agc, jam-ind |
miljøet er fjendtligt; det alene viser ikke, at positionsbestemmelsen er forkert |
op til 15, [geometry] |
geometry (0.36) |
ikke en vægt på denne rampe: intet, medmindre himlen er dårlig, derefter op til cap_points (15); geometri alene når degraderet, aldrig ikke betroet, og udløser ingen alarm (se "Geometri" nedenfor) |
Båndgrænserne følger af vægtene: den letteste monitor, der alarmerer, koster 12,5 point ved sin tærskel, så enhver alarm forlader det nominelle bånd; ingen enkelt monitor under 60 point kan nå det ikke betroede bånd alene (flere sammen kan). Resultatet registrerer scoremodellen (score_model), og hver epoke bærer score.deductions: hvilke monitorer der trak fra, deres forhold og deres point. For et fartøj er epokens tilstand scorens bånd.
Geometri: naturlig forringelse adskilt fra angrebslignende inkonsistens#
En modtager ved siden af en kajkran, i en sluse eller under et højt skrog mister satellitter, og dens positionsbestemmelse bliver dårligere af en grund, der ikke er et angreb. Fra 0,36, efter designnoten om geometri (docs/design/2026-10-12-geometry-and-skyline-design.md, afsnit 4), bærer hver epoke sin satellitgeometri, et fartøjs score har en geometrimonitor, og hvert fradrag bærer en klasse: geometry (himlen), environment (signalmiljøet) eller inconsistency (angrebslignende evidens).
Hvor geometrien kommer fra. Elevationen og azimutten for hver sporet satellit (NMEA GSV, UBX NAV-SAT), hvoraf dilution of precision (DOP) udledes med motorens ene DOP-kerne (orbit::dop, VALIDATED mod gnss_lib_py): source = derived. Hvis det ikke er muligt, den DOP og de anvendte satellitter, modtageren selv angiver (NMEA GSA): source = reported. Himmelpositioner og GSA tæller for scorens evidence_hold_s (standard 10 s), fordi mange busser sender GSV hvert få sekunder; et GSV-sæt, der er ufuldstændigt i en epoke (slutningen af et uddrag, en tabt sætning), bruges ikke. En log med ingen af delene, såsom NMEA med kun GGA og RMC, eller Android- og RINEX-logs i dag, får status unknown med noten "geometry unknown": motoren gætter ikke på en geometri, den ikke har fået, og geometrimonitoren kører ikke.
geometry.status |
Betydning |
|---|---|
good |
nok satellitter og DOP inden for tærsklerne |
degraded |
en eller flere grunde: few-satellites, high-pdop, high-hdop og (kun til information, ikke i scoren) sky-blocked, når hver sporet satellit ligger i den ene halvdel af horisonten |
unknown |
loggen giver ingen satellitgeometri for denne epoke |
Status er beskrivende, og mærket (nedenfor) er det, der tæller for scoren: degraded omfatter det informative tilfælde sky-blocked, som kan optræde med god eller rimelig DOP, og kun et poor-mærke scores.
Mærket (altid rapporteret, aldrig scoret). Hver epokes geometry.label er good (HDOP højst hdop_good 2, PDOP højst pdop_good 3 og mindst used_good 6 satellitter), poor (HDOP over hdop_max 4, PDOP over pdop_max 6 eller færre end min_used 5 satellitter), fair imellem de to, eller unknown. Epokens note åbner altid med mærket og tallene, for eksempel "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)", og tilføjer ", signal loss", når det gælder.
Geometrimonitoren (fartøjsscore). Den trækker intet fra, medmindre geometrien er dårlig: dens forhold er max(hdop / hdop_max, pdop / pdop_max, min_used / n_used), og så længe det højst er 1 (god eller rimelig geometri, herunder en åben himmel med kun GPS og 8 satellitter), koster den intet, så en sådan log scorer præcis som i 0,35. Over 1 stiger fradraget lineært til cap_points (15) ved full_ratio (1,5 gange tærsklerne: HDOP 6, PDOP 9, 3 satellitter): 7,5 point ved forholdet 1,25 (HDOP 5, eller 4 satellitter), 15 fra 1,5 og opefter (score 85, degraderet). Alene kan den aldrig tage scoren under floor (standard: scorens degraded_min, 55), så geometri alene når højst det degraderede bånd og aldrig det ikke betroede: den gældende begrænsning er min(cap_points, 100 - floor), så en [score]-tabel, der hæver degraded_min (for eksempel en fra 0,35 med degraded_min 90), sænker begrænsningen til 100 - degraded_min i stedet for at blive afvist, og en floor sat under degraded_min afvises. Monitoren udløser ingen alarm; den opføres sidst i monitors_run, når den har afgjort noget ved en epoke (et fartøj, hvis log giver geometrien), og tælles ikke med i identiteten med 0,35; den er ikke en post i [score.weights] (at sætte en afvises), og begrænsningen og gulvet, der gælder, registreres i geometry_model.cap_in_force og geometry_model.floor_in_force. En dårlig epokes note siger hvorfor, for eksempel "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".
Klasser. Hvert fradrag (score.deductions[].class):
| Klasse | Monitorer |
|---|---|
geometry |
geometry (dårlig geometri); loss-of-lock, når hver satellit, der blev mistet i forhold til kalibreringens baseline, lå under low_elev_deg ved sin sidste rapport |
environment |
cn0-drop, cn0-spread, cn0-rise, agc, jam-ind, ellers loss-of-lock; geometry under signaltab (nedenfor) |
inconsistency |
kinematic, heading-course, speed-log, sea-level, time-consistency, clock, raim, position-jump, osnma, solve-failure; og geometry, når geometrien er dårlig, og den angivne HDOP er uenig med den angivne himmel (nedenfor) |
Værn mod en forfalsket dårlig himmel. En spoofer kunne sende en tynd GSV eller rapportere en høj HDOP for at købe tolerance. Motoren mærker og tilgiver ikke: ingen anden kontrol udvides af en dårlig geometri, og den HDOP, modtageren angiver (GSA inden for holdet, ellers GGA), sammenlignes med den HDOP, der udledes af den himmel, den angiver. Når de afviger med mere end max(reported_vs_derived_tol, reported_vs_derived_rel × derived HDOP) (1,0 eller 25 % af den udledte HDOP, alt efter hvad der er størst), bærer epoken reported_derived_mismatch: true, og når geometrien er dårlig, klassificeres dens fradrag som inconsistency. Ved god eller rimelig geometri rapporteres uenigheden og scores ikke: intet trækkes fra, medmindre geometrien er dårlig. Det er et bevidst valg (0,36): "nul, medmindre dårlig" gælder for hver epoke, så god og rimelig geometri scorer præcis som i 0,35, og en forfalsket HDOP er aldrig tavs. Flaget (reported_derived_mismatch) står på hver epoke i resultatet og hver levende linje, noten siger "…beyond the tolerance: reported, not scored (the geometry is not poor)" eller "…: the geometry deduction is classed an inconsistency", geometry_summary.hdop_mismatch tæller epokerne, og siden med sammenfatning af evidens viser antallet, også nul. De 25 % er et REPRESENTATIVE ingeniørmæssigt valg, ikke et målt eller standardiseret tal: en modtager, der løser for ét ur pr. konstellation eller med en delmængde af de satellitter, den sporer (en elevationsmaske, en afskæring i C/N0, en RAIM-udelukkelse), angiver en HDOP, der afviger fra enkeltur-HDOP for hver sporet satellit med et beløb, der vokser med HDOP, så en fast tolerance alene ville læse naturlig dårlig geometri som en inkonsistens. En større forskel læses stadig som en. Et fradrag klassificeret som geometry er en udtalelse om himlen, ikke en konstatering af, at intet angreb fandt sted.
Signaltab er ikke himlen. Når satellitter, som modtageren opfører som i sigte (over low_elev_deg), ikke spores, udleder motoren også DOP for hver satellit i sigte. Hvis den DOP i sigte ligger inden for tærsklerne, og enten intet spores, eller de usporede satellitter er spredt rundt om horisonten (ikke samlet i den ene halvdel), var himlen der, og signalet var ikke: epoken bærer signal_loss: true, noten "satellites in view but not tracked: signal environment, not geometry", og geometrifradraget klassificeres som environment. Usporede satellitter samlet i den ene halvdel af horisonten læses stadig som en blokeret himmel (en mur, en klippe, en kaj). En tosidet hindring (en kløft eller en smal fjord) læses som signaltab, indtil en horisontprofil er konfigureret. Modtagerens sentinelværdier for ingen positionsbestemmelse er ikke DOP: en angivet HDOP eller PDOP på 99 eller mere, GGA-kvalitet 0 og GSA-tilstand 1 giver ingen angivet DOP.
[geometry]-nøgle |
Standard | Proveniens |
|---|---|---|
hdop_max |
4 | valgt (designnote 4,2): ved sigma_uere_m 1,5 m er HDOP 4 en 2drms på 12 m, kinematikkontrollens kin_pos_tol_m. IEC 61108-1 nævnes almindeligvis som angivende sine krav til nøjagtighed for HDOP ≤ 4 (eller PDOP ≤ 6): erindret fra sekundær litteratur om GNSS-modtagere, ingen bestemt sekundær kilde konsulteret og standarden ikke læst; skal kontrolleres mod standardens tekst |
pdop_max |
6 | tærsklen for PDOP-tilgængelighed i scenarios/polar-arctic-leo-coverage.toml; GPS SPS Performance Standard, 5. udg. (2020), PDOP ≤ 6, som citeret i tests/constellation_availability_published_spec_oracle.rs; skal kontrolleres mod standardens tekst |
min_used |
5 | én mere, end en positionsbestemmelse har brug for, så et enkelt tab ikke afslutter positionsbestemmelsen; det færreste med én redundant måling til RAIM |
sigma_uere_m |
1.5 | et angivet input til 2drms-koblingen for hdop_max; sæt modtagerens eget tal |
reported_vs_derived_tol |
1,0 HDOP | valgt (designnote 4,2): tolerancens absolutte del; en uenighed ud over tolerancen er ikke geometri |
reported_vs_derived_rel |
0.25 | REPRESENTATIVE ingeniørmæssigt valg: den relative del, for modtagere med ure pr. konstellation eller delmængdeløsninger |
low_elev_deg |
15 | designnote 4,3: satellitter, der mistes under den, mistes til himlen; en horisontprofil (0,36 punkt 1) vil udvide dette |
azimuth_gap_deg |
180 | geometrisk, kun til information: hver satellit i den ene halvdel af horisonten |
cap_points |
15 | designnote 4,2: geometri alene flytter scoren fra nominel til degraderet og aldrig til ikke betroet; trækkes kun fra, når geometrien er dårlig (grundlæggerens beslutning B1, 0,36) |
full_ratio |
1.5 | scorens eget full_ratio: rampen når cap_points ved 1,5 gange tærsklerne for dårlig |
floor |
scorens degraded_min (55) |
geometri alene når aldrig det ikke betroede bånd; den gældende begrænsning er min(cap_points, 100 - floor); et gulv under degraded_min afvises |
hdop_good |
2 | REPRESENTATIVE, kun mærket: halvdelen af hdop_max (forholdet for begyndelsen i scoren fra 0,35) |
pdop_good |
3 | REPRESENTATIVE, kun mærket: halvdelen af pdop_max |
used_good |
6 | REPRESENTATIVE, kun mærket: én mere end min_used, så et enkelt tab stadig efterlader en redundant måling |
Hvad der ændrede sig i outputtet, og hvad der ikke gjorde. Ingen score ændres, medmindre geometrien er dårlig; mærket rapporteres altid. Tilføjede nøgler: epochs[].geometry (status, reasons, source, n_used, hdop, pdop, vdop afrundet til 0,001, open_fraction (null, indtil en horisontprofil er konfigureret), max_azimuth_gap_deg, age_s, reported_hdop, reported_derived_mismatch, note, in_view (satellitter opført over low_elev_deg), signal_loss, label), class på hvert fradrag og til sidst geometry_model (tærskler, hold, begrænsning og gulv i kraft, proveniens, klasseregler) og geometry_summary (epoker efter status, efter mærke og efter fradragsklasse og de epoker, hvor den angivne HDOP er uenig); score_model.weights er som i 0,35. To tests binder dette til bytes i baseline "0,36 portable", når disse nøgler er fjernet (hashene fra 0.35.0, rebaseret, da motoren gik over til portabel matematik, og bevaret i testene som registrering af, hvad 0.35.0 udgav: docs/revisions/STUDIO15-portable-math-rebaseline.md). tests/geometry_trust_no_change.rs binder hvert output fra begge eksempelsessioner (resultat-JSON, CSV, SVG, afgørelse, genafspillede levende linjer, $PKSHT, Prometheus, CEF, LEEF). tests/geometry_corpus_identity.rs binder batchresultatet, sammenfatningen, de levende linjer og $PKSHT for hvert indlagt NMEA-korpus for fartøjer (demoen og de maritime referencefixtures, hver også som åben himmel med kun GPS og 8 satellitter, og træningsscenarierne for besætning, der genereres ud fra deres seeds); i de to træningsscenarier, hvor jamming gør geometrien dårlig, er hver epoke, der ikke er dårlig, identisk, og hver dårlig adskiller sig alene ved geometrifradraget. En log, hvis geometri er dårlig, mister op til 15 point, den ikke mistede i 0,35; det er den tilsigtede ændring. På demoen læses drag-off som inconsistency; tests/geometry_trust.rs redigerer loggen til at maskere den vestlige himmel (rimelig: mærket, ikke scoret), til at maskere den og to østlige satellitter (dårlig: geometrifradrag, tab af lås environment, fordi høje satellitter også gik tabt), til kun at miste satellitter under 15° (tab af lås geometry) og til at angive en HDOP, himlen ikke forklarer (fradraget for dårlig geometri bliver inconsistency). Tærsklerne er MODELLED: valgt, ikke tilpasset nogen log; intet her påstår, hvor ofte naturlig forringelse og angreb kan skelnes på virkelige data.
Angivelse af hændelser og forudsigelser#
[[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
For hver hændelse giver resultatet de falske alarmer mellem kalibrering og start, den første alarm og dens monitorer, ventetiden, udfaldet (detected, late, missed eller not-evaluable) og det observerede median-fald i C/N0 mod forudsigelsen (agree, disagree, no-prediction eller not-evaluable). Uenighed rapporteres, aldrig tunet væk: tolerancerne står i scenariet, og scenariet står i resultatets hash.
Hvad dette ikke påstår#
Tillidsmonitorerne er MODELLED: deres tærskler er input, og deres detektionsevne på virkelig interferens er det, som scoringen af hændelser måler, ikke noget, denne type påstår. På JammerTest 2024-sessionerne med spoofing fanger monitorerne i motorstien nogle starttidspunkter inden for 10 s og er sene på andre; se rækken "Clock-aided χ², RAIM, AGC, SQM fused per-epoch security FoM" i VERIFICATION-MATRIX.md for tallene. En forudsigelse, der er enig med én log, er ét datapunkt, ikke en validering.