Машинний переклад, не перевірений носієм мови. Еталоном є англійська версія.

Довіра до приймача та морська галузьРедагувати на GitHubДжерело: docs/NMEA-TRAINING.md

Навчальні потоки NMEA: kshana nmea-scenario

Морські академії та центри тренажерів можуть подавати згенерований Kshana NMEA 0183 на місток-симулятор або картплотер, щоб навчати екіпажі розпізнавати глушіння та спуфінг GNSS.

Лише для навчання та тестування. Згенеровані потоки синтетичні. Їх ніколи не можна подавати на живі навігаційні системи судна. Kshana є консультативним засобом, а не навігаційним обладнанням із затвердженням типу. Кожен потік починається із власницького речення-маркера $PKSHT,TRAINING,SYNTHETIC,NOT-FOR-NAVIGATION і повторює його кожні десять секунд; приймачі його ігнорують; --no-marker вилучає його для симулятора, який відхиляє невідомі речення. Це записує лише текст NMEA: виходу RF, IQ чи сигналу немає, і ніщо не передається, окрім тексту на вказану вами адресу.

Навчальний потік зі сценарію coastal-drag-off (рушій v0.40.0, зерно 22, 25 хвилин при одному визначенні на 10 с журналу інструктора). Карта показує справжній трек судна та трек, який повідомляє приймач: вони збігаються, доки не починається сценарний зсув позиції на 421 с, після чого повідомлений трек віддаляється від справжнього, тоді як приймач зберігає дійсне визначення, і повертається назад, коли подія закінчується на 1140 с. Поруч — відстань між двома треками в часі та середня щільність несівна-шум, яку повідомляє приймач і яка зростає до одного піднятого рівня, поки триває подія. Синтетичні навчальні дані, згенеровані Kshana. Лише для навчання та тестування: ніколи не подавайте цей потік на живі навігаційні системи судна. Лише консультативно: це не навігаційне обладнання із затвердженням типу. Консультативне програмне забезпечення, не навігаційне обладнання із затвердженням типу (IEC 61108, IEC 61162): відповідальність за навігацію судна залишається на операторі. Позиції, дати та треки вигадані.Навчальний потік зі сценарію coastal-drag-off (рушій v0.40.0, зерно 22, 25 хвилин при одному визначенні на 10 с журналу інструктора). Карта показує справжній трек судна та трек, який повідомляє приймач: вони збігаються, доки не починається сценарний зсув позиції на 421 с, після чого повідомлений трек віддаляється від справжнього, тоді як приймач зберігає дійсне визначення, і повертається назад, коли подія закінчується на 1140 с. Поруч — відстань між двома треками в часі та середня щільність несівна-шум, яку повідомляє приймач і яка зростає до одного піднятого рівня, поки триває подія. Синтетичні навчальні дані, згенеровані Kshana. Лише для навчання та тестування: ніколи не подавайте цей потік на живі навігаційні системи судна. Лише консультативно: це не навігаційне обладнання із затвердженням типу. Консультативне програмне забезпечення, не навігаційне обладнання із затвердженням типу (IEC 61108, IEC 61162): відповідальність за навігацію судна залишається на операторі. Позиції, дати та треки вигадані.

Рисунок побудовано за журналом інструктора scenarios/training/coastal-drag-off.toml.

Використання#

# 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
Параметр Значення
--out <file> записати потік у файл; без мережевого виходу типовим є <name>.nmea
--instructor-log <prefix> записати <prefix>.instructor.json і <prefix>.instructor.txt (типово: поруч із файлом)
--tcp <addr:port> або <port> сервер TCP; прогін починається, коли під'єднався клієнт (--wait-clients <n>). Голий порт слухає лише 127.0.0.1
--udp <addr:port> або <port> UDP, одне речення на датаграму; --broadcast дозволяє широкомовну адресу. Голий порт надсилає на 127.0.0.1
--realtime, --speed <x> темп потоку; --speed 0 означає якнайшвидше. Мережевий вихід типово працює в реальному часі, файли — якнайшвидше
--seed <n> замінити зерно сценарію
--no-marker пропустити речення-маркер

Автентифікації немає. Сервер TCP із нелокальною адресою віддає потік кожному, хто може до нього дістатися, а UDP надсилає на будь-яку вказану вами адресу. Клієнт TCP, який не забирає свої дані протягом двох секунд, відключається, тож один завислий споживач не може затримати інших.

Те саме зерно дає ті самі байти на одній платформі, а темп ніколи не змінює байти. Між платформами власна арифметика генератора побітово ідентична (використовується переносний математичний шар), але положення супутників і кути огляду надходять із функцій рушія, які викликають математичну бібліотеку хоста, тож у рідкісному межовому випадку округлена цифра висоти, азимута чи C/N0 у GSV може відрізнятися між платформами.

Що записується#

Кожна епоха (1, 2, 5 або 10 на секунду) містить: RMC, GGA, GNS (визначення, позиція, час), GSA (використані супутники та DOP, по одному на орбітальне угруповання), GSV (супутники в полі зору з висотою, азимутом і SNR у дБ-Гц, один набір на орбітальне угруповання, ідентифікатор сигналу NMEA 4,10), VTG (курс і швидкість відносно землі), ZDA (час і дата), HDT (курс за гіроскопом) і VBW (швидкість відносно води та землі за лагом). Передавач — GN для кількох орбітальних угруповань, інакше власний для угруповання. Рядки закінчуються CRLF і мають правильні контрольні суми.

HDT і VBW замінюють незалежні датчики (гірокомпас і доплерівський лаг). Жодна подія їх не зачіпає, і це свідомо: розбіжність між тим, що повідомляє GNSS, і тим, що кажуть гіроскоп і лаг, є підказкою для розбору.

Коли визначення втрачено, якість GGA дорівнює 0, статус RMC — V, поля позиції порожні, а поля часу тривають (годинник приймача продовжує йти), як у реальних приймачів.

Судно#

[vessel] і [[waypoint]] задають початкову позицію, швидкість і точки, через які веде судно. Судно веде до наступної шляхової точки з обмеженням швидкості повороту (max_rot_deg_per_min, типово 30), обмеженням того, як швидко наростає швидкість повороту (max_rot_accel_deg_per_s2) і обмеженням зміни швидкості (max_accel_kn_per_min). Швидкість ділянки — це speed_kn шляхової точки. [environment] додає течію, тому швидкість відносно землі відрізняється від швидкості відносно води, а курс відрізняється від курсу відносно землі, а також магнітне схилення. stop_at_end зупиняє судно в останній шляховій точці.

Геометрія супутників#

Супутники беруться з власних номінальних орбітальних угруповань рушія (таблиця слотів GPS, шаблони Волкера MEO для Galileo і BeiDou, ICD GLONASS), поширюються функцією constellation::satellite_positions_fixed (задача двох тіл плюс вікове J2, обертання Землі) і видимі з судна за кутами огляду WGS-84 рушія. Кількість видимих супутників, висоти й азимути в GSV правдоподібні для місця та часу доби. Це номінальне небо, а не ефемериди на дату потоку: PRN призначаються в порядку слотів, і кожне орбітальне угруповання зберігає свою опубліковану схему слотів, безперервно поширену від епохи таблиці слотів GPS (2016-12-31) під дією J2, тож схема цілісна, але її орієнтація не відповідає реальному небу на дату потоку. C/N0 залежить від висоти (номінальний рівень у зеніті задається в [receiver]) із фіксованим зсувом для кожного супутника, повільними завмираннями та шумом. Супутник нижче track_threshold_dbhz має порожнє поле SNR; нижче use_threshold_dbhz — відстежується, але не використовується. Використовується до max_used (типово 12, межа NMEA GGA) придатних супутників, обраних за геометрією (спершу найвищий супутник у кожному азимутному секторі 30 градусів). Якщо придатних супутників менше чотирьох, визначення втрачається, і воно повертається через reacquire_s придатного сигналу.

Події#

Кожна [[event]] має kind, початок start_s, duration_s (від початку до початку припинення), наростання на початку ramp_s і спадання при припиненні recovery_s. Інтенсивність лінійно зростає протягом ramp_s, утримується, потім спадає протягом recovery_s; 0 — це стрибок. Усі ефекти масштабуються цією інтенсивністю. Параметри, що не належать до цього виду, відхиляються.

вид параметри ефект
jamming cn0_drop_db, spread_db (типово 6) C/N0 кожного супутника падає щонайбільше на cn0_drop_db (розкид для кожного супутника), супутники випадають, починаючи з найнижчих, визначення втрачається, коли придатних менше чотирьох, і відновлюється після припинення та reacquire_s
drag-off final_offset_m, одне з bearing_deg (істинний) або relative_bearing_deg (до курсу на початку, далі утримується), необов'язково max_accel_mps2, counterfeit_cn0_dbhz приймач зберігає дійсне визначення, позиція якого відходить від істини; SOG і COG містять зсув. Зсув слідує за smoothstep на наростаннях, тож хибний трек починається й закінчується без стрибка швидкості; його піки — 1.5 D/T м/с і 6 D/T^2 м/с на квадрат для наростання T с на D м (обидва записуються в журнал), а сценарій, що перевищив би max_accel_mps2, відхиляється. Стрибок (ramp_s = 0) зсуває позицію, не торкаючись швидкості
time-spoof offset_s, counterfeit_cn0_dbhz час RMC, GGA, GNS і ZDA зсувається від істинного UTC; позиція залишається істинною
replay-delay delay_s, affect_time (типово true), counterfeit_cn0_dbhz позиція, швидкість (і час) — такі, якими були в судна delay_s тому, із затримкою за smoothstep на наростаннях і швидкістю, що повідомляється, помноженою на 1 - d(delay)/dt, поки вона змінюється: спрощена абстракція в стилі міконінгу, а не модель поширення

counterfeit_cn0_dbhz: поки активні зсув, спуфінг часу чи затримка відтворення, кожен відстежуваний супутник показує цей єдиний піднятий рівень — класична ознака. Пропустіть його для непомітної події, у якій зберігається справжній розподіл C/N0. Поки активна будь-яка підроблена подія, приймач слідує за підробленим сигналом, тож глушіння його не скидає; визначення, втрачене через раніше глушіння, повертається через reacquire_s на підробленому сигналі (див. combined-event). Зміна часу, через яку повідомлений час зупинився б або йшов назад (швидкість 1 с за секунду чи більше), відхиляється, якщо це не стрибок (ramp_s = 0).

Події можуть перекриватися; їхні ефекти додаються (зсуви, зміни часу, затримки) або береться найсильніший (глушіння). onset на часовій шкалі — це перша епоха, в якій подія має ефект, на одну епоху пізніше за сценарний start_s, коли подія наростає.

Журнал інструктора#

Разом із потоком <prefix>.instructor.json і <prefix>.instructor.txt містять:

  • події, як їх уведено, простою мовою з кожним параметром, і їхній початок у UTC;
  • часову шкалу: початок, повний ефект, початок відновлення, відновлено, а також власні fix-lost і fix-regained приймача;
  • істинний трек порівняно з повідомленим з інтервалом log_interval_s: істинна та повідомлена позиція, швидкість і курс, похибка позиції в метрах, зсув часу, використані та відстежувані супутники, середній C/N0 і які події були активні;
  • пікову швидкість і прискорення істинного та повідомленого треку;
  • trainer_note сценарію.

Показуйте журнал лише під час розбору.

поля JSON (схема kshana-nmea-training/1)#

поле тип, одиниця значення
schema рядок kshana-nmea-training/1
warning рядок твердження про призначення лише для навчання
scenario, description, trainer_note рядок зі сценарію
seed ціле число використане зерно
start_utc ISO 8601 UTC початок прогону
duration_s s тривалість прогону
summary.true_peak_sog_kn, summary.reported_peak_sog_kn вузли найвища істинна та повідомлена швидкість відносно землі
summary.true_peak_accel_mps2, summary.reported_peak_accel_mps2 м/с на квадрат найбільша зміна швидкості за секунду, істинна та між послідовними повідомленими визначеннями
events[] по одному на кожну сценарну подію
events[].id ціле число нумерація з 1; використовується в timeline[].event і track[].active_events
events[].description рядок опис простою мовою з параметрами
events[].start_utc ISO 8601 UTC сценарний початок
events[].parameters об'єкт подія точно так, як записано (kind, start_s, duration_s, ramp_s, recovery_s і власні параметри виду; відсутні пропускаються)
events[].resolved_bearing_deg градуси істинні або null зсув: застосований напрямок (відносний пеленг визначається на початку)
events[].peak_drag_speed_mps, events[].peak_drag_accel_mps2 м/с, м/с на квадрат або null зсув: піки, які зсув додає до хибного треку
timeline[] моменти для розбору, у порядку часу
timeline[].t_s, .utc с від початку, ISO 8601 UTC коли (істинний час)
timeline[].event ціле число або null ідентифікатор події; null для змін стану приймача
timeline[].what рядок onset, full-effect, recovery-begins, recovered (події); fix-lost, fix-regained (приймач)
timeline[].text рядок пояснення
track[] один рядок на log_interval_s
track[].t_s, .utc с, ISO 8601 UTC коли (істинний час)
track[].true_lat_deg, .true_lon_deg градуси істинна позиція
track[].true_sog_kn, .true_cog_deg, .true_heading_deg вузли, градуси істинні істинна швидкість і курс відносно землі та курс за гіроскопом
track[].fix_valid логічне значення приймач повідомив про визначення
track[].reported_lat_deg, .reported_lon_deg, .reported_sog_kn, .reported_cog_deg градуси, вузли, градуси істинні або null що повідомив приймач; null, поки визначення втрачене
track[].position_error_m м або null горизонтальна відстань від істинної до повідомленої позиції
track[].time_offset_s s повідомлений UTC мінус істинний UTC
track[].n_used, .n_tracked цілі числа супутники, використані у визначенні, і відстежувані
track[].mean_cn0_dbhz дБ-Гц або null середній C/N0 відстежуваних супутників
track[].active_events цілі числа ідентифікатори подій, що діють у цей момент

Додавання поля не змінює тег схеми. Перейменування чи вилучення поля або зміна його значення чи одиниці збільшує номер (/2).

Бібліотека сценаріїв#

scenarios/training/, кожен — кілька хвилин переходу з приміткою тренера в його TOML:

файл що він показує
open-sea-jamming.toml C/N0 падає в усіх разом, супутники випадають, визначення втрачається й повертається
coastal-drag-off.toml дійсне, здорове на вигляд визначення зсувається на 1,4 км до берега; рівномірно піднятий C/N0
port-approach-time-spoof.toml позиція правильна, UTC випереджає на 45 с під час повільного заходу в порт
combined-event.toml глушіння, потім підроблене перехоплення зі зсувом і зсувом часу, потім затримка відтворення
fjord-natural-degradation.toml заблоковане небо, а не завади: стіни фіорду (REPRESENTATIVE шаблон обрію fjord) ховають супутники на сході та заході, потім канал знову відкривається (подія natural-degradation з таблицею skyline)

Позиції, дати та треки вигадані; бібліотека не містить жодного реального судна, оператора чи запису. Вона нічого не стверджує про те, як будь-який приймач чи система поводилися б за наявності завад.

Вибори моделювання#

Генератор — це навчальний інструмент без зовнішнього оракула, а його числа — вибори моделювання, а не вимірювання будь-якого приймача. Їх обрано так, щоб вони виглядали як звичайний журнал приймача: нахил C/N0 у 14 дБ від зеніту до горизонту нижче рівня зеніту (типово 47 дБ-Гц) і зсув для кожного супутника ±1,5 дБ, повільні завмирання 0,8 дБ за 97 с і 0,5 дБ за 31 с, тремтіння 0,3 дБ; пороги відстеження (20 дБ-Гц) і використання (28 дБ-Гц); шум позиції (1,5 м при HDOP 1, корельований за 30 с, вертикальний удвічі більший); шум гіроскопа 0,05 градуса та шум дрейфу 0,03 вуз.; стала часу керування 20 с і радіуси прибуття до шляхових точок моделі судна; а також вибір супутників за азимутними секторами. Типові значення містяться в [receiver] і [vessel] і всі можуть бути змінені в сценарії.

Зчитування назад#

kshana receiver-trust може приймати ці файли (format = "nmea"). Тести перевіряють кожне речення кожного сценарію бібліотеки за його власними правилами кількості полів і контрольної суми та пропускають файли через цей читач, який інтерпретує GGA, RMC і GSV та пропускає інші типи, не відкидаючи жодного. Тести фіксують еталонний уривок для кожного сценарію (tests/fixtures/nmea_training/); після навмисної зміни перегенеруйте за допомогою KSHANA_BLESS_GOLDEN=1.