NMEA-treningsstrømmer: kshana nmea-scenario
Maritime akademier og simulatorsentre kan mate NMEA 0183 generert av Kshana inn i en brosimulator eller en kartplotter for å trene mannskap i å gjenkjenne GNSS-jamming og -spoofing.
Kun for trening og testing. De genererte strømmene er syntetiske. De må aldri mates inn i et fartøys levende navigasjonssystemer. Kshana er veiledende, ikke typegodkjent navigasjonsutstyr. Hver strøm starter med, og gjentar hvert tiende sekund, en proprietær markørsetning,
$PKSHT,TRAINING,SYNTHETIC,NOT-FOR-NAVIGATION, som mottakere ignorerer;--no-markerfjerner den for en simulator som avviser ukjente setninger. Dette skriver bare NMEA-tekst: det er ingen RF-, IQ- eller bølgeformutdata, og ingenting sender annet enn teksten til adressen du oppgir.
Figuren er tegnet fra instruktørloggen til scenarios/training/coastal-drag-off.toml.
Bruk#
# write a file (default <name>.nmea) and the instructor log next to it
kshana nmea-scenario scenarios/training/coastal-drag-off.toml --out drag.nmea
# serve over TCP in real time on this machine only (waits for the simulator to connect)
kshana nmea-scenario scenarios/training/open-sea-jamming.toml --tcp 10110
# reachable from the bridge-simulator host: name the address in full
kshana nmea-scenario scenarios/training/open-sea-jamming.toml --tcp 192.168.1.20:10110
# UDP, one sentence per datagram, ten times faster than real time
kshana nmea-scenario scenarios/training/combined-event.toml --udp 192.168.1.50:10110 --speed 10
# UDP broadcast
kshana nmea-scenario scenarios/training/combined-event.toml --udp 192.168.1.255:10110 --broadcast
| Valg | Betydning |
|---|---|
--out <file> |
skriv strømmen til en fil; uten nettverksutdata er standarden <name>.nmea |
--instructor-log <prefix> |
skriv <prefix>.instructor.json og <prefix>.instructor.txt (standard: ved siden av filen) |
--tcp <addr:port> eller <port> |
TCP-server; kjøringen starter når en klient har koblet til (--wait-clients <n>). En bar port lytter bare på 127.0.0.1 |
--udp <addr:port> eller <port> |
UDP, én setning per datagram; --broadcast tillater en kringkastingsadresse. En bar port sender til 127.0.0.1 |
--realtime, --speed <x> |
styr tempoet på strømmen; --speed 0 er så raskt som mulig. Nettverksutdata går som standard i sanntid, filer så raskt som mulig |
--seed <n> |
erstatt scenarioets seed |
--no-marker |
utelat markørsetningen |
Det er ingen autentisering. En TCP-server med en ikke-lokal adresse serverer strømmen til alle som kan nå den, og UDP sender til den adressen du oppgir. En TCP-klient som ikke tar imot dataene sine innen to sekunder, kobles fra, så én fastlåst forbruker ikke kan holde de andre oppe
Det samme seedet gir de samme bytene på én plattform, og tempostyring endrer aldri bytene. På tvers av plattformer er generatorens egen aritmetikk bit-identisk (den bruker det portable matematikklaget), men satellittposisjoner og siktevinkler kommer fra motorfunksjoner som kaller vertens matematikkbibliotek, så i et sjeldent grensetilfelle kan et avrundet siffer for elevasjon, azimut eller C/N0 i GSV avvike mellom plattformer.
Hva som skrives#
Hver epoke (1, 2, 5 eller 10 per sekund) inneholder: RMC, GGA, GNS (posisjonsbestemmelse, posisjon, tid), GSA (brukte satellitter og DOP, én per konstellasjon), GSV (satellitter i sikte med elevasjon, azimut og SNR i dB-Hz, ett sett per konstellasjon, NMEA 4,10 signal-ID), VTG (kurs og fart over grunnen), ZDA (tid og dato), HDT (gyrokurs) og VBW (fart gjennom vannet og over grunnen fra loggen). Talker er GN med flere konstellasjoner, ellers konstellasjonens egen. Linjene ender i CRLF og har gyldig sjekksum.
HDT og VBW representerer uavhengige sensorer (et gyrokompass og en Doppler-logg). Ingen hendelse berører dem, noe som er bevisst: forskjellen mellom det GNSS rapporterer og det gyroen og loggen sier, er et signal i debriefen.
Når posisjonsbestemmelsen går tapt, er GGA-kvaliteten 0, RMC-statusen er V, posisjonsfeltene er tomme og tidsfeltene fortsetter (mottakerens klokke går videre), slik ekte mottakere gjør.
Fartøyet#
[vessel] og [[waypoint]] gir en startposisjon, en fart og punktene det skal styres gjennom. Fartøyet styres mot neste veipunkt under en grense for svingehastighet (max_rot_deg_per_min, standard 30), en grense for hvor fort svingehastigheten bygges opp (max_rot_accel_deg_per_s2) og en grense for fartsendring (max_accel_kn_per_min). Farten på en etappe er veipunktets speed_kn. [environment] legger til en strøm, så farten over grunnen avviker fra farten gjennom vannet og kursen avviker fra kursen over grunnen, og en magnetisk misvisning. stop_at_end bringer fartøyet i ro ved det siste veipunktet.
Satellittgeometri#
Satellittene kommer fra motorens egne nominelle konstellasjoner (GPS-slottabell, Walker-mønstre for Galileo og BeiDou MEO, GLONASS-ICD), propagert av constellation::satellite_positions_fixed (tolegemebane pluss sekulær J2, jordrotasjon) og sett fra fartøyet med motorens WGS-84-siktevinkler. Antall synlige, elevasjoner og azimuter i GSV er plausible for stedet og tiden på døgnet. Dette er en nominell himmel, ikke en efemeride for strømmens dato: PRN-er tildeles i slot-rekkefølge, og hver konstellasjon beholder sitt publiserte slot-oppsett, propagert kontinuerlig fra epoken i GPS-slottabellen (2016-12-31) under J2, så oppsettet er intakt, men orienteringen er ikke den til den virkelige himmelen på strømmens dato. C/N0 følger elevasjonen (et nominelt senitnivå, satt i [receiver]), med en fast forskyvning per satellitt, langsom fading og støy. En satellitt under track_threshold_dbhz har et tomt SNR-felt; en under use_threshold_dbhz spores, men brukes ikke. Opptil max_used (standard 12, taket i NMEA GGA) brukbare satellitter brukes, valgt for geometri (den høyeste satellitten i hver azimutsektor på 30 grader først). Færre enn fire brukbare satellitter gir tap av posisjonsbestemmelsen, og den kommer tilbake etter reacquire_s med brukbart signal.
Hendelser#
Hver [[event]] har en kind, et starttidspunkt start_s, en duration_s (fra start til begynnelsen av avslippingen), en rampe ved start ramp_s og en rampe ved avslipping recovery_s. Styrken stiger lineært over ramp_s, holdes, og faller deretter over recovery_s; 0 er et trinn. Alle virkningene skalerer med den styrken. Parametere som ikke hører til typen, avvises.
| kind | parametere | virkning |
|---|---|---|
jamming |
cn0_drop_db, spread_db (standard 6) |
hver satellitts C/N0 faller med opptil cn0_drop_db (spredning per satellitt), satellitter faller ut med de laveste først, posisjonsbestemmelsen går tapt når færre enn fire er brukbare, og kommer tilbake etter avslippingen og reacquire_s |
drag-off |
final_offset_m, én av bearing_deg (sann) eller relative_bearing_deg (til kursen ved start, deretter holdt), valgfritt max_accel_mps2, counterfeit_cn0_dbhz |
mottakeren beholder en gyldig posisjonsbestemmelse hvis posisjon går bort fra sannheten; SOG og COG inkluderer draget. Draget følger smoothstep på rampene, så det falske sporet starter og stopper uten hastighetstrinn; toppene er 1.5 D/T m/s og 6 D/T^2 m/s i annen for en rampe på T s over D m (begge logget), og et scenario som ville overskride max_accel_mps2, avvises. Et trinn (ramp_s = 0) flytter posisjonen uten å berøre hastigheten |
time-spoof |
offset_s, counterfeit_cn0_dbhz |
tiden i RMC, GGA, GNS og ZDA flyttes fra sann UTC; posisjonen forblir sann |
replay-delay |
delay_s, affect_time (standard true), counterfeit_cn0_dbhz |
posisjon, hastighet (og tid) er de til fartøyet for delay_s siden, der forsinkelsen følger smoothstep på rampene og den rapporterte farten skaleres med 1 - d(delay)/dt mens den endres: en forenklet abstraksjon i stil med meaconing, ikke en utbredelsesmodell |
counterfeit_cn0_dbhz: mens en drag-off, tidsspoofing eller replay-forsinkelse er aktiv, viser hver sporede satellitt dette ene hevede nivået, et klassisk tegn. Utelat den for en subtil hendelse der det ekte C/N0-mønsteret beholdes. Mens en forfalskningshendelse er aktiv, følger mottakeren det forfalskede signalet, så jamming får den ikke til å falle ut; en posisjonsbestemmelse som er tapt på grunn av tidligere jamming, kommer tilbake etter reacquire_s på det forfalskede signalet (se combined-event). En tidsendring som ville fått rapportert tid til å stoppe eller gå bakover (rate på 1 s per sekund eller mer), avvises med mindre det er et trinn (ramp_s = 0).
Hendelser kan overlappe; virkningene deres legges sammen (forskyvninger, tidsendringer, forsinkelser) eller den sterkeste gjelder (jamming). Tidslinjens onset er den første epoken der hendelsen har en virkning, én epoke etter det skriptede start_s når hendelsen rampes inn.
Instruktørloggen#
Sammen med strømmen gir <prefix>.instructor.json og <prefix>.instructor.txt:
- hendelsene slik de ble injisert, på vanlig språk med hver parameter, og UTC-tidspunktet de begynte;
- en tidslinje: start, full virkning, gjenoppretting begynner, gjenopprettet, og mottakerens egne
fix-lostogfix-regained; - det sanne sporet mot det rapporterte ved
log_interval_sintervall: sann og rapportert posisjon, fart og kurs, posisjonsfeil i meter, tidsforskyvning, brukte og sporede satellitter, middel-C/N0, og hvilke hendelser som var aktive; - toppfarten og toppakselerasjonen til det sanne og det rapporterte sporet;
- scenarioets
trainer_note.
Vis loggen først i debriefen.
JSON-felt (skjema kshana-nmea-training/1)#
| felt | type, enhet | betydning |
|---|---|---|
schema |
streng | kshana-nmea-training/1 |
warning |
streng | erklæringen om at den bare er for trening |
scenario, description, trainer_note |
streng | fra scenarioet |
seed |
heltall | brukt seed |
start_utc |
ISO 8601 UTC | start på kjøringen |
duration_s |
s | lengden på kjøringen |
summary.true_peak_sog_kn, summary.reported_peak_sog_kn |
knop | høyeste sanne og rapporterte fart over grunnen |
summary.true_peak_accel_mps2, summary.reported_peak_accel_mps2 |
m/s i annen | største hastighetsendring per sekund, sann og mellom påfølgende rapporterte posisjonsbestemmelser |
events[] |
én per skriptet hendelse | |
events[].id |
heltall | 1-basert; brukes av timeline[].event og track[].active_events |
events[].description |
streng | beskrivelse på vanlig språk med parameterne |
events[].start_utc |
ISO 8601 UTC | skriptet start |
events[].parameters |
objekt | hendelsen nøyaktig slik den er skrevet (kind, start_s, duration_s, ramp_s, recovery_s og typens egne parametere; fraværende utelates) |
events[].resolved_bearing_deg |
grader sann kurs eller null | drag-off: retningen som ble brukt (en relativ peiling løses ved start) |
events[].peak_drag_speed_mps, events[].peak_drag_accel_mps2 |
m/s, m/s i annen eller null | drag-off: toppene draget legger til det falske sporet |
timeline[] |
øyeblikk for debriefen, i tidsrekkefølge | |
timeline[].t_s, .utc |
s fra start, ISO 8601 UTC | når (sann tid) |
timeline[].event |
heltall eller null | hendelses-id; null for endringer i mottakerens tilstand |
timeline[].what |
streng | onset, full-effect, recovery-begins, recovered (hendelser); fix-lost, fix-regained (mottaker) |
timeline[].text |
streng | forklaring |
track[] |
én rad per log_interval_s |
|
track[].t_s, .utc |
s, ISO 8601 UTC | når (sann tid) |
track[].true_lat_deg, .true_lon_deg |
grader | sann posisjon |
track[].true_sog_kn, .true_cog_deg, .true_heading_deg |
knop, grader sann kurs | sann fart og kurs over grunnen, og gyrokurs |
track[].fix_valid |
boolsk | mottakeren rapporterte en posisjonsbestemmelse |
track[].reported_lat_deg, .reported_lon_deg, .reported_sog_kn, .reported_cog_deg |
grader, knop, grader sann kurs, eller null | det mottakeren rapporterte; null mens posisjonsbestemmelsen er tapt |
track[].position_error_m |
m eller null | horisontal avstand fra sann til rapportert posisjon |
track[].time_offset_s |
s | rapportert UTC minus sann UTC |
track[].n_used, .n_tracked |
heltall | satellitter brukt i posisjonsbestemmelsen, og sporede |
track[].mean_cn0_dbhz |
dB-Hz eller null | middel-C/N0 for de sporede satellittene |
track[].active_events |
heltall | id-er for hendelser med en virkning i dette øyeblikket |
Å legge til et felt endrer ikke skjemaetiketten. Å endre navn på eller fjerne et felt, eller endre betydningen eller enheten til et felt, øker nummeret (/2).
Scenariobiblioteket#
scenarios/training/, hver noen få minutter av en seilas med en trenermerknad i sin TOML:
| fil | hva den viser |
|---|---|
open-sea-jamming.toml |
C/N0 faller samlet, satellitter faller ut, posisjonsbestemmelsen går tapt og kommer tilbake |
coastal-drag-off.toml |
en gyldig, sunt utseende posisjonsbestemmelse dras 1,4 km mot land; ensartet hevet C/N0 |
port-approach-time-spoof.toml |
posisjonen er riktig, UTC drifter 45 s foran under en langsom havneinnseiling |
combined-event.toml |
jamming, deretter forfalsket overtakelse med drag-off og tidsforskyvning, deretter en replay-forsinkelse |
fjord-natural-degradation.toml |
en blokkert himmel, ikke interferens: veggene i en fjord (skyline-forhåndsinnstillingen fjord, REPRESENTATIVE) skjuler satellittene mot øst og vest, deretter åpner kanalen seg igjen (hendelse natural-degradation, med en skyline-tabell) |
Posisjoner, datoer og spor er oppdiktet; biblioteket inneholder ingen ekte fartøy, operatør eller opptak. Det gir ingen påstand om hvordan noen mottaker eller noe system ville klart seg mot interferens.
Modelleringsvalg#
Generatoren er et treningsverktøy uten ekstern referanse, og tallene er modelleringsvalg, ikke målinger av noen mottaker. De er valgt for å se ut som en vanlig mottakerlogg: C/N0-stigningstallet på 14 dB fra senit til horisont under senitnivået (standard 47 dB-Hz) og forskyvningen per satellitt på +/-1.5 dB, langsom fading på 0,8 dB over 97 s og 0,5 dB over 31 s, 0,3 dB jitter; terskelene for sporing (20 dB-Hz) og bruk (28 dB-Hz); posisjonsstøyen (1,5 m ved HDOP 1, korrelert over 30 s, vertikalt det dobbelte); 0,05 graders gyrostøy og 0,03 kn avdriftsstøy; styringstidskonstanten på 20 s og ankomstradiene for veipunkter i fartøymodellen; og valget av satellitter etter azimutsektor. Standardene ligger i [receiver] og [vessel] og kan alle endres i scenarioet.
Lese den tilbake#
kshana receiver-trust kan lese inn disse filene (format = "nmea"). Testene kontrollerer hver setning i hvert bibliotekscenario mot sine egne regler for feltantall og sjekksum, og kjører filene gjennom den leseren, som tolker GGA, RMC og GSV og går forbi de andre typene uten å hoppe over noen. Testene fester et gullutdrag per scenario (tests/fixtures/nmea_training/); generer på nytt med KSHANA_BLESS_GOLDEN=1 etter en tilsiktet endring.