Důvěra v přijímač: posuzování skutečného záznamu přijímače GNSS
kshana receiver-trust čte záznam ze skutečného přijímače globálního družicového navigačního systému (GNSS), provozuje nad ním monitory důvěry epochu po epoše a říká, kdy a proč přestalo být určení polohy přijímače důvěryhodné. Umí také ohodnotit záznam proti událostem a předpovědím, které stanovíte před během: zda byla každá událost detekována včas a zda modelovaný pokles hustoty nosné k šumu (C/N0) souhlasí s tím, co přijímač naměřil.
Pozorované veličiny jsou vlastní veličiny přijímače; monitory a jejich prahy jsou vlastní enginu a vaše. Každý výsledek nese toto označení, SHA-256 záznamu a každý práh, s nímž běžel, takže běh lze opakovat a auditovat.
Pro plavidlo za plavby, s živým skóre a volitelnou bránou před systémem map, viz MARITIME-TRUST.md.
Spusťte jej#
kshana receiver-trust examples/receiver-trust/session.toml
Zapíše session.result.json, session.trust.csv (jeden řádek na epochu) a session.trust.svg (průměrné C/N0 v čase se stavem důvěry pod ním) vedle scénáře a vypíše jednořádkový verdikt. Příkladový záznam je syntetický, vytvořený k ukázce formátu; v path nasměrujte na záznam vlastního přijímače.
Obrázek výše je ukázka plavidla z MARITIME-TRUST.md: vymyšlený záznam, poradní skóre.
Tentýž scénář běží z Pythonu (kshana.receiver_trust(toml)), z balíčku WebAssembly (receiver_trust(toml), se záznamem vloženým přímo) a z nástroje assess_receiver_log serveru Model Context Protocol (MCP).
Záznamy, které čte#
format |
Zdroj | Co se čte |
|---|---|---|
ubx |
Binární formát u-blox | NAV-SAT C/N0, elevace a azimut po družicích, poloha NAV-PVT, MON-RF automatické řízení zesílení (AGC) a indikátor rušení jamInd, týden NAV-TIMEGPS a vlastní příznaky přijímače: NAV-STATUS spoofDetState a SEC-SIG (self_report, viz RECEIVER-PROTOCOLS.md) |
rinex |
Pozorovací soubor RINEX 3 | kódy S (C/N0) na družici a signál; s vysílaným navigačním souborem (nav) pseudovzdálenosti pro vlastní určení polohy enginu |
android |
CSV z Android GnssLogger | řádky Raw: C/N0 a AgcDb na družici; řádky Fix: poloha |
nmea |
Text NMEA 0183 | GSV poměr signálu k šumu na družici (dB-Hz, s ID signálu 4,10 nebo bez něj) a její elevace a azimut, GSA faktor DOP (zhoršení přesnosti) a použité družice, GGA a RMC čas a poloha |
sbf |
Binární formát Septentrio (0,38, pouze čtení) | poloha PVTGeodetic, C/N0 MeasEpoch na družici a signál, počet pásem RFStatus; viz RECEIVER-PROTOCOLS.md |
rtklib-pos |
Soubor řešení RTKLIB (.pos) |
čas, poloha (zeměpisná šířka/délka nebo ECEF, převedeno) a použité družice na epochu; soubory ve stupních, minutách a vteřinách jsou odmítnuty se zprávou |
novatel |
Textové nebo binární záznamy NovAtel OEM7 | poloha BESTPOS (pouze vypočtené řešení), C/No RANGE na družici a signál; příznaky rušiček RXSTATUS se stávají self_report epochy (stav rušení 2, když přijímač označí rušičku, 1, když ne; v RXSTATUS neexistuje příznak spoofingu), postavené proti poplachům Kshany srovnáním receiver-self-report |
gnss-sdr |
Proudy GNSS-SDR Monitor a PVT-monitor jako řádky JSON | C/N0 po kanálech, určení polohy, použité družice, HDOP, azimut a elevace; vytváří integrations/gnss-sdr/relay.py |
Podrobnosti, zdroje a omezení těchto tří: MACHINE-INPUTS.md.
Každá epocha, kterou čtečky vytvoří, nese také source_span, bajtové posuny [start, end) do vstupu: nejmenší souvislý rozsah obsahující záznamy, které k ní přispěly, takže přesný surový výřez lze zahashovat pro okno události. NMEA: každý řádek přečtený, dokud je epocha aktuální (nadmnožina tam, kde mezi jejími větami stojí nesouvisející řádek). UBX: rámce epochy. RINEX 3: záznamy epochy od každého řádku > do dalšího. Android: řádky Raw epochy (řádek Fix jen pro epochu bez řádků Raw). Chybí u živého proudu a všude tam, kde není dobře definováno (RINEX 2).
Soubor se předává přes path (vyhodnoceno vůči složce samotného scénáře), nebo vložený jako text či base64 (jediné možnosti v prohlížeči).
Záznam IMU jako druhý senzor#
[log.imu] přidává inerciální záznam na stejných hodinách:
[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
Úhlová rychlost stáčení se integruje z heading0_deg a doplňuje kurz všude, kde záznam přijímače žádný nenese, takže monitor heading-course (který na platformě potřebuje heading_sensor = true) srovnává kurz z gyroskopu s kurzem nad zemí. Gyroskop driftuje: kurz je tak dobrý, jak dobré je okno integrace, a hdg_cog_tol_deg rozhoduje, co se považuje za neshodu. Rozložení csv je zdokumentováno v MACHINE-INPUTS.md. Bajty IMU jsou součástí hashe scénáře i hashe scénáře balíčku důkazů. Vložení (text/base64) funguje na každém povrchu; path je odmítnuta tam, kde se soubory nečtou.
Platforma: statická nebo plavidlo#
Výše uvedené monitory předpokládají pevnou anténu. Scénář stanoví platformu před během v tabulce [platform] nejvyšší úrovně; bez ní je platforma static a nic se nemění.
[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)
| Klíč | Výchozí hodnota | Proč tato hodnota |
|---|---|---|
max_speed_kn |
30 | Nad provozní rychlostí obchodních trupů a většiny osobních plavidel, takže jí skutečné plavidlo nikdy nedosáhne; daleko pod rychlostí, kterou implikuje odtažení polohy. Pomalejší plavidlo má stanovit nižší limit: čím nižší limit, tím dříve se odtažení zachytí. |
max_accel_mps2 |
0.5 | Velká loď mění rychlost o mnohem méně než 0,1 m/s²; malé rychlé plavidlo dosáhne při prudké změně plynu několika desetin. |
max_turn_rate_dps |
6 | Velká loď se otáčí rychlostí hluboko pod 1 °/s a malé plavidlo při prudké zatáčce několika. |
antenna_height_m |
žádné | Vlastnost instalace; odhad by byl skrytým prahem. |
heading_sensor |
false | Deklarováno true a v záznamu chybí je chyba, takže chybějící senzor nemůže projít jako čistá kontrola. |
Klíče plavidla jsou pod kind = "static" odmítnuty. Pro plavidlo monitor position-jump neběží, protože měří vzdálenost od kalibračního průměru, což je u pohybující se antény chybné; monitor_config výsledku zaznamenává platformu a použité limity.
Syntetické proudy NMEA z kshana nmea-scenario, vytvořené pro výcvik posádek, čtečka NMEA přijímá a lze je tímto druhem spustit jako jakýkoli záznam NMEA.
Monitory#
Každý monitor potřebuje svá data; monitor, jehož data v záznamu nejsou, neběží a není uveden v monitors_run. Prvních calibration_s sekund (výchozí 60) stanoví základ a nikdy nevyvolá poplach.
| Monitor | Poplach při | Potřebuje |
|---|---|---|
cn0-drop |
průměrné C/N0 přes družice společné se základem klesne o cn0_drop_db nebo více (výchozí 6 dB) |
C/N0 |
loss-of-lock |
sledované družice klesnou o sats_lost nebo více pod medián základu (výchozí 4) |
C/N0 |
agc |
hodnota AGC se odchýlí od svého základu o více než agc_k_sigma směrodatných odchylek (výchozí 5) |
UBX MON-RF nebo Android AgcDb |
jam-ind |
jamInd u-blox překročí jam_ind_threshold (výchozí 80 z 255) |
UBX MON-RF |
position-jump |
vlastní určení polohy přijímače je od svého kalibračního průměru vzdáleno více než position_jump_m (výchozí 50 m) |
hlášená poloha |
raim |
paritní autonomní monitorování integrity v přijímači (RAIM) na vlastním jednobodovém určení polohy enginu zamítne sadu měření | záznam RINEX s nav |
solve-failure |
jednobodové určení polohy enginu selže při pěti nebo více družicích | záznam RINEX s nav |
clock |
hodiny přijímače se odchýlí od své předpovězené přímky o více než minimální detekovatelný posun jejich kalibračního šumu | záznam RINEX s nav |
Kalibrovaný profil (dobrovolný). [monitors] profile = "jammertest-2024-calibrated" nahrazuje tři prahy interference hodnotami kalibrovanými na veřejné datové sadě JammerTest 2024 (jeden u-blox ZED-F9P na scénář; Zenodo 15911589): cn0_drop_db = 1.5, agc_k_sigma = 3.5, jam_ind_threshold = 29. Kalibrace byla předregistrována (xval/jammertest-trust/PREREGISTRATION.md) a profil je MODELLED, nafitovaný na jedné veřejné kampani: jeho práh cn0_drop_db nesplnil předregistrovaný práh falešných poplachů na utajené sadě (0,0231 proti 0,02); prahy AGC a indikátoru rušení a práh sjednocení (falešné poplachy 0,033, detekce 0,81) splněny byly (xval/jammertest-trust/RESULTS.md). Platí pro tento typ přijímače při dané události, proti plánovaným slotům útoků, a byl kalibrován na záznamech CSV této sady (její záznamy UBX dávají více falešných poplachů ve dvou složkách). Výsledek spuštěný s profilem zrcadlí uplatněné prahy a nese profile_note, který říká toto všechno. Bez profilu platí výše uvedené výchozí hodnoty a každý výstup je beze změny.
Pro platformu vessel běží také monitory pohybující se platformy (prahy v tabulce [maritime] nejvyšší úrovně, každá výchozí hodnota je zdokumentována v src/receiver_trust/maritime.rs); každý potřebuje svá data a v monitors_run je uveden, jen když rozhodl:
| Monitor | Poplach při | Potřebuje |
|---|---|---|
kinematic |
změna polohy se neshoduje s hlášenou rychlostí a kurzem, nebo implikuje rychlost, zrychlení či úhlovou rychlost otáčení nad limity plavidla | určení polohy; rychlost a kurz (RMC nebo VTG) pro část s dead reckoningem |
heading-course |
kurz z gyroskopu a kurz nad zemí se liší o více než hdg_cog_tol_deg (rychlost nad min_speed_kn) |
kurz HDT, THS nebo VHW, heading_sensor = true |
speed-log |
rychlost vůči vodě a rychlost nad zemí se liší o více než stw_sog_tol_kn |
VHW nebo VBW a rychlost nad zemí |
sea-level |
výška GGA se od antenna_height_m liší o více než sea_level_tol_m |
výška GGA, antenna_height_m |
cn0-spread |
rozptyl C/N0 přes družice klesne na cn0_spread_frac svého kalibračního mediánu |
GSV |
cn0-rise |
C/N0 společných družic vzrostlo v průměru o cn0_rise_db a vzrostlo u cn0_rise_frac z nich |
GSV |
time-consistency |
po sobě jdoucí časy epoch skáčou nepravidelně, běží pozpátku nebo se odchylují od hodin hostitele | čas NMEA; u poslední části hodiny hostitele |
osnma |
přijímač hlásí selhání autentizace OSNMA (čte se hlášený stav; nic se neověřuje; k ověření OSNMA ze samotných stránek I/NAV viz docs/OSNMA.md) | Stavová věta $PKSOS |
Epocha je nedůvěryhodná, pokud alarm vyvolá RAIM, monitor hodin, selhání řešení nebo skok polohy, nebo pokud pokles C/N0 dosáhne dvojnásobku svého prahu; zhoršená při jakémkoli jiném alarmu; a jinak nominální.
Cesta enginu (raim, solve-failure, clock) je tentýž výpočet jako orákulum spoofingu JammerTest 2024 v tests/jammertest_spoof_oracle_support: tests/receiver_trust_jammertest.rs ověřuje, že u všech osmi zveřejněných nástupů připadne první alarm na stejnou epochu a je téhož druhu.
Skóre důvěryhodnosti (platforma plavidla)#
U plavidla získá každá epocha po kalibraci také skóre od 0 do 100 a důvody, proč není 100. Mapování je deterministické a pevně dané dříve, než se jakýkoli záznam skóruje: žádné učení, nic přizpůsobeného událostem. Každý monitor převede své důkazy na poměr statistic / threshold (alarm při hodnotě 1 nebo vyšší); poměr stojí skóre
points = weight * clamp((ratio - onset_ratio) / (full_ratio - onset_ratio), 0, 1)
score = round_to_0.1( clamp(100 - sum of points, 0, 100) )
takže monitor nestojí nic, dokud je pod onset_ratio svého prahu (výchozí 0,5), stojí polovinu své váhy na svém prahu a celou ji při full_ratio násobku prahu (výchozí 1,5); skóre je nerostoucí v každé statistice. Zdroj, který v dané epoše nehlásí, si ponechá svou poslední statistiku po dobu evidence_hold_s (výchozí 10 s: dva cykly věty C/N0 odesílané každých 5 s), jako alarm i jako srážku.
Zaokrouhluje se směrem nahoru od poloviny (floor(x * 10 + 0.5) / 10), pásmo se určuje podle zaokrouhleného skóre a omezení rozsahu předchází zaokrouhlení. Ve srážkách jsou uvedeny jen monitory, jejichž body jsou nad nulou, spolu s jejich poměrem a nezaokrouhlenými body, nejvíce bodů jako první; srážky se stejným počtem bodů jsou řazeny v pořadí názvů monitorů 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. Monitoru, jehož test končí úspěchem nebo selháním (selhání řešení, selhání autentizace), se přiřadí poměr 1,5, tedy plná váha. Uvedené body jsou body před omezením rozsahu na 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áha (body) | Monitory | Proč |
|---|---|---|
| 70 | osnma |
selhání autentizace je tvrzení, nikoli statistika |
| 60 | kinematic, raim, clock, position-jump, time-consistency |
padělaná poloha musí odporovat fyzice nebo vlastním kontrolám přijímače a čas nemůže běžet pozpátku; jedno porušení v plné síle (1,5 násobek prahu: 60 bodů, skóre 40) je nedůvěryhodné a na prahu (30 bodů, skóre 70) zhoršené |
| 40 | heading-course, speed-log, solve-failure |
jeden nezávislý senzor, který nesouhlasí, je zhoršený stav; dva v plné síle jsou nedůvěryhodné |
| 30 | sea-level, cn0-spread, cn0-rise, cn0-drop |
signálové prostředí nebo slabě vypovídající kontrola |
| 25 | loss-of-lock, agc, jam-ind |
prostředí je nepřátelské; to samo o sobě neukazuje, že určení polohy je chybné |
až 15, [geometry] |
geometry (0.36) |
není to váha na této rampě: nic, pokud není obloha špatná, poté až cap_points (15); samotná geometrie dosáhne nejvýše zhoršeného stavu, nikdy nedůvěryhodného, a nevyvolá žádný alarm (viz „Geometrie“ níže) |
Hranice pásem vyplývají z vah: nejlehčí monitor, který vyvolá alarm, stojí na svém prahu 12,5 bodu, takže každý alarm opustí nominální pásmo; žádný jednotlivý monitor pod 60 bodů nemůže sám dosáhnout nedůvěryhodného pásma (několik společně může). Výsledek zaznamenává model skóre (score_model) a každá epocha nese score.deductions: které monitory srážely, jejich poměry a jejich body. U plavidla je stav epochy dán pásmem jejího skóre.
Geometrie: přirozené zhoršení odlišené od nesrovnalostí podobných útoku#
Přijímač u kontejnerového jeřábu, v plavební komoře nebo pod vysokým trupem ztrácí družice a jeho určení polohy se zhoršuje z jiného důvodu než kvůli útoku. Od verze 0,36, podle návrhové poznámky ke geometrii (docs/design/2026-10-12-geometry-and-skyline-design.md, oddíl 4), nese každá epocha svou geometrii družic, skóre plavidla má monitor geometrie a každá srážka nese třídu: geometry (obloha), environment (signálové prostředí) nebo inconsistency (důkaz podobný útoku).
Odkud geometrie pochází. Elevace a azimut každé sledované družice (NMEA GSV, UBX NAV-SAT), z nichž se odvodí faktor DOP (zhoršení přesnosti) jediným jádrem DOP enginu (orbit::dop, VALIDATED proti gnss_lib_py): source = derived. Pokud ty nejsou, použije se DOP a družice použité podle stavu přijímače (NMEA GSA): source = reported. Polohy na obloze a GSA se počítají po dobu evidence_hold_s skóre (výchozí 10 s), protože mnoho sběrnic posílá GSV jednou za několik sekund; sada GSV neúplná v dané epoše (konec výřezu, ztracená věta) se nepoužije. Záznam, který nemá ani jedno, například NMEA jen s GGA a RMC nebo záznamy Android a RINEX v současnosti, získá stav unknown s poznámkou „geometry unknown“: engine si geometrii, kterou nedostal, nevymýšlí, a monitor geometrie neběží.
geometry.status |
Význam |
|---|---|
good |
dostatek družic a DOP v mezích prahů |
degraded |
jeden nebo více důvodů: few-satellites, high-pdop, high-hdop a (informativně, do skóre se nepočítá) sky-blocked, pokud se všechny sledované družice nacházejí v jedné polovině obzoru |
unknown |
záznam pro tuto epochu neuvádí žádnou geometrii družic |
Stav je popisný a pro skóre rozhoduje štítek (níže): degraded zahrnuje informativní případ sky-blocked, který se může objevit i s dobrým nebo uspokojivým DOP, a skóruje se pouze štítek poor.
Štítek (vždy se uvádí, nikdy se neskóruje). geometry.label každé epochy je good (HDOP nejvýše hdop_good 2, PDOP nejvýše pdop_good 3 a alespoň used_good 6 družic), poor (HDOP nad hdop_max 4, PDOP nad pdop_max 6 nebo méně než min_used 5 družic), fair mezi tím, nebo unknown. Poznámka epochy vždy začíná štítkem a čísly, například „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)“, a při výskytu přidá „, signal loss“.
Monitor geometrie (skóre plavidla). Srazí nic, pokud není geometrie špatná: jeho poměr je max(hdop / hdop_max, pdop / pdop_max, min_used / n_used) a dokud je nejvýše 1 (dobrá nebo uspokojivá geometrie, včetně otevřené oblohy jen pro GPS s 8 družicemi), nestojí nic, takže takový záznam dostane přesně stejné skóre jako ve verzi 0,35. Nad hodnotou 1 srážka lineárně roste až na cap_points (15) při full_ratio (1,5 násobek prahů: HDOP 6, PDOP 9, 3 družice): 7,5 bodu při poměru 1,25 (HDOP 5 nebo 4 družice), 15 od 1,5 výše (skóre 85, zhoršený stav). Samo o sobě nikdy nesníží skóre pod floor (výchozí: degraded_min skóre, 55), takže samotná geometrie dosáhne nejvýše zhoršeného pásma a nikdy nedůvěryhodného: platný strop je min(cap_points, 100 - floor), takže tabulka [score], která zvýší degraded_min (například tabulka verze 0,35 s degraded_min 90), sníží strop na 100 - degraded_min, místo aby byla odmítnuta, a floor nastavená pod degraded_min je odmítnuta. Monitor nevyvolává žádný alarm; je uveden jako poslední v monitors_run, pokud v některé epoše rozhodoval (plavidlo, jehož záznam geometrii uvádí), a do identity verze 0,35 se nepočítá; není položkou [score.weights] (jeho nastavení je odmítnuto) a platný strop a práh se zaznamenávají v geometry_model.cap_in_force a geometry_model.floor_in_force. Poznámka špatné epochy říká proč, například „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“.
Třídy. Každá srážka (score.deductions[].class):
| Třída | Monitory |
|---|---|
geometry |
geometry (špatná geometrie); loss-of-lock, pokud byla každá družice ztracená oproti kalibračnímu základu při svém posledním hlášení pod low_elev_deg |
environment |
cn0-drop, cn0-spread, cn0-rise, agc, jam-ind, loss-of-lock jinak; geometry při ztrátě signálu (níže) |
inconsistency |
kinematic, heading-course, speed-log, sea-level, time-consistency, clock, raim, position-jump, osnma, solve-failure; a geometry, pokud je geometrie špatná a uvedený HDOP nesouhlasí s uvedenou oblohou (níže) |
Ochrana proti padělané špatné obloze. Spoofer by mohl poslat řídké GSV nebo hlásit vysoký HDOP, aby si vykoupil toleranci. Engine štítkuje a neodpouští: špatná geometrie nerozšiřuje žádnou jinou kontrolu a HDOP, který přijímač uvádí (GSA v rámci doby podržení, jinak GGA), se porovnává s HDOP odvozeným z oblohy, kterou uvádí. Liší-li se o více než max(reported_vs_derived_tol, reported_vs_derived_rel × derived HDOP) (1,0 nebo 25 % odvozeného HDOP, podle toho, co je větší), nese epocha reported_derived_mismatch: true a při špatné geometrii je její srážka zařazena do třídy inconsistency. Při dobré nebo uspokojivé geometrii se nesoulad hlásí a neskóruje: nic se nesrazí, pokud není geometrie špatná. Jde o záměrnou volbu (0,36): „nula, pokud není špatná“ platí pro každou epochu, takže dobrá a uspokojivá geometrie dostane přesně stejné skóre jako ve verzi 0,35 a padělaný HDOP nikdy neprojde mlčky. Příznak (reported_derived_mismatch) je u každé epochy výsledku a každého živého řádku, poznámka říká „…beyond the tolerance: reported, not scored (the geometry is not poor)“ nebo „…: the geometry deduction is classed an inconsistency“, geometry_summary.hdop_mismatch počítá epochy a stránka souhrnu důkazů uvádí jejich počet, včetně nuly. Hodnota 25 % je REPRESENTATIVE inženýrská volba, nikoli změřená ani normová hodnota: přijímač, který řeší jedny hodiny na konstelaci nebo používá podmnožinu družic, které sleduje (elevační maska, odříznutí C/N0, vyloučení RAIM), uvádí HDOP, který se od HDOP s jedněmi hodinami pro všechny sledované družice liší o hodnotu rostoucí s HDOP, takže by pevná tolerance sama přirozeně špatnou geometrii četla jako nesrovnalost. Větší rozdíl se za nesrovnalost považuje i nadále. Srážka zařazená do třídy geometry je tvrzení o obloze, nikoli zjištění, že k žádnému útoku nedošlo.
Ztráta signálu není obloha. Pokud družice, které přijímač uvádí jako viditelné (nad low_elev_deg), nejsou sledovány, engine odvodí také DOP všech viditelných družic. Je-li tento DOP viditelných družic v mezích prahů a buď není sledována žádná, nebo jsou nesledované družice rozloženy po obzoru (nejsou omezeny na jednu jeho polovinu), obloha tam byla a signál ne: epocha nese signal_loss: true, poznámku „satellites in view but not tracked: signal environment, not geometry“ a srážka geometrie je zařazena do třídy environment. Nesledované družice omezené na jednu polovinu obzoru se dál čtou jako zablokovaná obloha (zeď, útes, nábřeží). Dvoustranná překážka (kaňon nebo úzký fjord) se čte jako ztráta signálu, dokud není nastaven obzorový profil. Hodnoty přijímače bez určení polohy nejsou DOP: uvedený HDOP nebo PDOP 99 či více, kvalita GGA 0 a režim GSA 1 neposkytují žádný uvedený DOP.
Klíč [geometry] |
Výchozí hodnota | Původ |
|---|---|---|
hdop_max |
4 | zvoleno (návrhová poznámka 4,2): při sigma_uere_m 1,5 m je HDOP 4 rovno 2drms 12 m, což je kin_pos_tol_m kinematické kontroly. O IEC 61108-1 se běžně uvádí, že své požadavky na přesnost stanoví pro HDOP ≤ 4 (nebo PDOP ≤ 6): vybaveno z druhotné literatury o přijímačích GNSS, žádný konkrétní druhotný zdroj nebyl konzultován a norma nebyla přečtena; je třeba ověřit podle znění normy |
pdop_max |
6 | práh dostupnosti PDOP z scenarios/polar-arctic-leo-coverage.toml; GPS SPS Performance Standard, 5. vyd. (2020), PDOP ≤ 6, jak je citováno v tests/constellation_availability_published_spec_oracle.rs; je třeba ověřit podle znění normy |
min_used |
5 | o jednu více, než určení polohy potřebuje, takže jediná ztráta neukončí určení polohy; nejmenší počet s jedním nadbytečným měřením pro RAIM |
sigma_uere_m |
1.5 | uvedený vstup pro spoj 2drms z hdop_max; nastavte vlastní hodnotu přijímače |
reported_vs_derived_tol |
1,0 HDOP | zvoleno (návrhová poznámka 4,2): absolutní část tolerance; nesoulad nad toleranci není geometrie |
reported_vs_derived_rel |
0.25 | REPRESENTATIVE inženýrská volba: relativní část, pro přijímače s hodinami pro každou konstelaci nebo s řešením z podmnožiny |
low_elev_deg |
15 | návrhová poznámka 4,3: družice ztracené pod ní jsou ztraceny kvůli obloze; obzorový profil (položka 1 verze 0,36) to rozšíří |
azimuth_gap_deg |
180 | geometrické, informativní: všechny družice v jedné polovině obzoru |
cap_points |
15 | návrhová poznámka 4,2: samotná geometrie posune skóre z nominálního do zhoršeného a nikdy do nedůvěryhodného; sráží se jen tehdy, je-li geometrie špatná (rozhodnutí zakladatele B1, 0,36) |
full_ratio |
1.5 | vlastní full_ratio skóre: rampa dosáhne cap_points při 1,5 násobku prahů špatné geometrie |
floor |
degraded_min skóre (55) |
samotná geometrie nikdy nedosáhne nedůvěryhodného pásma; platný strop je min(cap_points, 100 - floor); práh pod degraded_min je odmítnut |
hdop_good |
2 | REPRESENTATIVE, pouze pro štítek: polovina hdop_max (počáteční poměr skóre verze 0,35) |
pdop_good |
3 | REPRESENTATIVE, pouze pro štítek: polovina pdop_max |
used_good |
6 | REPRESENTATIVE, pouze pro štítek: o jednu více než min_used, takže jediná ztráta stále ponechá nadbytečné měření |
Co se ve výstupech změnilo a co ne. Žádné skóre se nemění, pokud není geometrie špatná; štítek se uvádí vždy. Přidané klíče: epochs[].geometry (status, reasons, source, n_used, hdop, pdop, vdop zaokrouhlené na 0,001, open_fraction (null, dokud není nastaven obzorový profil), max_azimuth_gap_deg, age_s, reported_hdop, reported_derived_mismatch, note, in_view (družice uvedené nad low_elev_deg), signal_loss, label), class u každé srážky a na konci geometry_model (prahy, doba podržení, platný strop a práh, původ, pravidla tříd) a geometry_summary (epochy podle stavu, podle štítku a podle třídy srážky a epochy s nesouladem uvedeného HDOP); score_model.weights je jako ve verzi 0,35. Dva testy to po odstranění těchto klíčů drží na úrovni bajtů základu „0,36 portable“ (hashe verze 0.35.0, přepočtené při přechodu enginu na přenositelnou matematiku a ponechané v testech jako záznam toho, co verze 0.35.0 vydala: docs/revisions/STUDIO15-portable-math-rebaseline.md). tests/geometry_trust_no_change.rs drží každý výstup obou ukázkových relací (výsledek JSON, CSV, SVG, verdikt, přehrané živé řádky, $PKSHT, Prometheus, CEF, LEEF). tests/geometry_corpus_identity.rs drží dávkový výsledek, souhrn, živé řádky a $PKSHT každého zapsaného korpusu NMEA plavidel (demo a referenční maritime fixtury, každý také jako otevřená obloha jen pro GPS s 8 družicemi, a výcvikové scénáře generované z jejich seedů); ve dvou výcvikových scénářích, kde rušení činí geometrii špatnou, je každá epocha, která špatná není, shodná a každá špatná se liší pouze srážkou geometrie. Záznam, jehož geometrie je špatná, ztratí až 15 bodů, které ve verzi 0,35 neztratil; to je zamýšlená změna. V demu se strhnutí čte jako inconsistency; tests/geometry_trust.rs upravuje záznam tak, aby zamaskoval západní oblohu (uspokojivá: štítkuje se, neskóruje), aby zamaskoval ji a dvě východní družice (špatná: srážky geometrie, ztráta zachycení environment, protože zmizely i vysoké družice), aby ztratil jen družice pod 15° (ztráta zachycení geometry) a aby uvedl HDOP, který obloha nevysvětluje (srážka špatné geometrie se stane inconsistency). Prahy jsou MODELLED: zvolené, nepřizpůsobené žádnému záznamu; nic zde netvrdí, jak často se na skutečných datech rozliší přirozené zhoršení od útoků.
Uvádění událostí a předpovědí#
[[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
U každé události výsledek uvádí falešné poplachy mezi kalibrací a nástupem, první alarm a jeho monitory, latenci, výsledek (detected, late, missed nebo not-evaluable) a pozorovaný medián poklesu C/N0 oproti předpovědi (agree, disagree, no-prediction nebo not-evaluable). Nesoulad se hlásí, nikdy se neladí pryč: tolerance jsou ve scénáři a scénář je v hashi výsledku.
Co toto netvrdí#
Monitory důvěryhodnosti jsou MODELLED: jejich prahy jsou vstupy a jejich detekční výkon na skutečné interferenci je to, co měří skórování událostí, nikoli něco, co tento druh tvrdí. V relacích spoofingu JammerTest 2024 zachytí monitory cesty enginu některé nástupy do 10 s a u jiných jsou opožděné; čísla viz řádek „Clock-aided χ², RAIM, AGC, SQM fused per-epoch security FoM“ v VERIFICATION-MATRIX.md. Předpověď, která souhlasí s jedním záznamem, je jeden datový bod, nikoli validace.