Машинный перевод, не проверенный носителем языка. Эталоном служит английская версия.

Доверие к приёмнику и морская отрасльПравить на GitHubИсточник: docs/MARINE-INTEGRATIONS.md

Морские интеграции: оценка доверия на мостике

Морская оценка доверия Kshana (MARITIME-TRUST.md) доступна из программ, которыми судоводители уже пользуются: плагин сервера Signal K и OpenCPN через NMEA в режиме gate по TCP. Эталонная сборка размещает её на небольшом компьютере рядом с приёмником.

Программное обеспечение консультативного характера. Kshana не является навигационным оборудованием с утверждённым типом (IEC 61108, IEC 61162) и не оценивалась по какому-либо стандарту характеристик. Всё на этой странице — вспомогательное средство для суждения штурмана. Ответственность за безопасное судовождение и за любое решение полагаться на определение места или перестать полагаться на него остаётся на операторе. Ничто здесь ничего не передаёт, и ничто здесь не делает определение места точнее.

Компонент Где Состояние в 0,35
Плагин Signal K integrations/signalk/ поставляется, проверен модульными тестами на записанных синтетических выходных данных; не опубликован в npm
OpenCPN через NMEA в режиме gate по TCP integrations/opencpn/ поставляется и проверен (воспроизведение на стороне потребителя); сам интерфейс OpenCPN не проверяется ни одним тестом
Нативный плагин панели оценки OpenCPN integrations/opencpn/plugin/ создан, логика проверена модульными тестами и запущена в OpenCPN 5.8.4 на виртуальном дисплее (свидетельства в integrations/opencpn/evidence/); не упакован для менеджера плагинов; будет поставляться только после проверки
Эталонная сборка deploy/reference-build/ детали, шаги для ОС, юниты systemd (проверены пробным запуском), вариант с контейнером; на судне не проверялась

Всё это читает одно: выходные данные kshana receiver-trust live (строки JSON, предложение $PKSHT, шлюз). Форматы передачи описаны в MARITIME-TRUST.md. Плагин Signal K хранит знания о них в одном файле, integrations/signalk/lib/adapter.js; изменение формата — это правка одного файла.

Плагин Signal K#

Зависимостей npm нет. Сам плагин работает на Node 18 или новее; текущим выпускам signalk-server нужен Node 22 или новее, поэтому на практике используйте 22. Скопируйте или свяжите integrations/signalk/ с каталогом node_modules сервера (например, ~/.signalk/node_modules/signalk-kshana-trust), перезапустите сервер и включите Kshana GNSS trust в разделе Server, Plugin Config.

Откуда берутся эпохи (source)#

source Что делает плагин
spawn-signalk-nmea (по умолчанию) Запускает kshana receiver-trust live <sessionFile> и записывает на его стандартный вход каждое необработанное предложение NMEA 0183, которое получает сервер (событие nmea0183 сервера). Перезапускает его с задержкой, нарастающей при повторах, если он завершается | Используйте его только на сервере с одним источником NMEA: он передаёт каждое предложение от каждого поставщика вперемешку, поэтому второй приёмник ГНСС или AIS выглядит как один приёмник, у которого скачет положение, и может быть оценён как спуфинг. При нескольких источниках используйте spawn-args с собственным потоком --tcp этого приёмника или tcp-pksht от шлюза.
spawn-args Запускает kshana receiver-trust live <sessionFile> <inputArgs...>, например ["--tcp","192.0.2.10:10110"] или ["--udp","10110"]
tcp-json Подключается к потоку строк JSON, которые записывает kshana (например, от ретранслятора в integrations/opencpn/)
tcp-pksht Подключается к потоку NMEA (например, к выходу шлюза службы или контейнера в эталонной сборке, порт 10110) и читает только его предложения $PKSHT

У потока, который уже подвергается спуфингу к моменту первого подключения монитора, нет чистого базового уровня (первые calibration_s с никогда не оцениваются). Запустите его до рейса.

Публикуемые пути#

Каждая эпоха обновляет (источник kshana-trust):

Путь Значение
navigation.gnss.kshana.band calibrating, nominal, degraded или untrusted
navigation.gnss.kshana.score от 0 до 100 или null во время калибровки
navigation.gnss.kshana.reasons [{monitor, points}], сначала наибольшие: какие проверки снизили оценку
navigation.gnss.kshana.alarms мониторы, которые сейчас превышают свой порог
navigation.gnss.kshana.gate off, passed или withheld (когда шлюз работает в другом месте; null из $PKSHT, если его нет)
navigation.gnss.kshana.reportedPosition {latitude, longitude, altitude}: положение, которое проверяемый приёмник сообщил в эту эпоху (схема JSON 1,1 или новее; не публикуется, если в потоке его нет, например от $PKSHT или более старого kshana). Только контекст доверия: плагин никогда не пишет navigation.position, поэтому собственный путь положения судна не затрагивается
notifications.navigation.gnss.kshana.trust публикуется при смене состояния: {state, method, message}

Плагин также один раз при запуске отправляет метаданные Signal K для этих путей. score — оценка доверия Kshana от 0 до 100: именно оценка, а не отношение и не вероятность, поэтому у неё нет единицы СИ; её метаданные задают диапазон, описание и зоны, следующие порогам ниже. reasons[].points — баллы оценки, вычтенные из этой оценки от 0 до 100.

Уведомление имеет состояние normal, alert, warn или alarm. Оно снимается публикацией состояния normal, а не null: потребитель, который считает снятым только null, должен считать снятым и normal. По умолчанию полоса degraded даёт warn, а полоса untrusted даёт alarm, с method: ["visual","sound"]. Оно понижается через clearAfterEpochs эпох при лучшем состоянии. Если эпохи не поступают в течение staleAfterS с, выдаётся предупреждение, что оценка не обновляется. Калибровка никогда не вызывает уведомления. Источник $PKSHT не содержит списка alarms (в предложении есть только полоса, оценка и две главные причины).

Конфигурация (каждый порог)#

Ключ По умолчанию Значение
source spawn-signalk-nmea см. выше
command kshana исполняемый файл (режимы запуска). Он запускает любой исполняемый файл от имени пользователя сервера: изменять конфигурацию плагина должен мочь только администратор сервера Signal K
sessionFile /etc/kshana/session.toml ограничения судна, пороги и веса оценки (режимы запуска)
inputArgs [] аргументы, добавляемые к kshana receiver-trust live <sessionFile> в обоих режимах запуска: вход для spawn-args, дополнительные флаги, например --replay (сохранённый журнал подаётся быстрее реального времени), для spawn-signalk-nmea. Плагин отклоняет --gate, --listen, --json и --pksht (он читает JSON от kshana на стандартном выводе), а для spawn-signalk-nmea также входные флаги (--stdin, --file, --tcp, --udp, --follow, --from-end)
host, port 127.0.0.1, 10111 Режимы TCP (шлюз обслуживает порт 10110: задайте порт для tcp-pksht)
thresholdMode band band: полоса, о которой сообщает Kshana, с границами в файле сессии. score: две оценки ниже
warnBelowScore 90 Режим score: ниже этого значения состояние degradedState (граница Kshana по умолчанию для nominal)
alarmBelowScore 55 Режим score: ниже этого значения состояние alarm (граница Kshana по умолчанию для degraded)
degradedState warn состояние для полосы degraded: normal, alert или warn
raiseAfterEpochs 1 число последовательных эпох с худшим состоянием до выдачи уведомления
clearAfterEpochs 10 число последовательных эпох с лучшим состоянием до его понижения
staleAfterS 10 предупреждать, если эпохи не поступают столько времени; 0 отключает
method ["visual","sound"] способы уведомления

Плагин не работает как шлюз: он никогда не изменяет определение места. Пометка определения места как недействительного для картографической системы — это шлюз, см. ниже.

Тесты#

cd integrations/signalk && npm test

node:test, без зависимостей, без сети, кроме 127.0.0.1. Тесты разбирают и воспроизводят фрагмент из 66 эпох строк JSON и предложений $PKSHT, которые kshana receiver-trust live записал для синтетической демонстрации в Балтийском море (вымышленные данные, только текст), проверяют согласие двух форматов, поведение удержания и снятия, режим оценки, устаревание и три пути ввода на локальном потоке и на подставном дочернем процессе. Эти тесты не запускают настоящий сервер Signal K; это делает отдельный сценарный запуск, см. ниже.

Запуск на настоящем сервере Signal K#

В integrations/signalk/evidence/ лежит скрипт, который загружает плагин в закреплённый пакет signalk-server 2.33.0 (в отдельном сетевом пространстве имён только с локальной петлёй) и записывает то, что показывают собственные API REST и WebSocket сервера. Пути доверия появляются, уведомление проходит warn, alarm, normal (после удержания) и снова warn, когда данные прекращаются, а при настоящем kshana, получающем собственный вход NMEA сервера, он также публиковал reportedPosition, но никогда navigation.position. Одна версия сервера, один прогон, настоящего судна нет; ограничения и воспроизведение описаны в README свидетельств.

OpenCPN#

OpenCPN читает NMEA из сети, а kshana receiver-trust live --gate может сам обслуживать отфильтрованный шлюзом поток на порту TCP.

Рекомендуется: прямое подключение.

some-nmea-source | kshana receiver-trust live session.toml --gate --listen tcp:10110

(some-nmea-source — последовательный порт приёмника, прочитанный через stty и cat, мультиплексор или входы --tcp/--udp самого kshana; kshana-gate.service эталонной сборки делает это под systemd.) --listen tcp:<port> привязывается к адресу петли; подключиться может любое число клиентов только для чтения, а тот, кто не успевает, отключается без задержки остальных.

Альтернатива: ретранслятор. integrations/opencpn/nmea-tcp-relay.mjs — разветвитель на Node без зависимостей, делающий то же для kshana без --listen или обслуживающий любой другой построчный поток (вариант с контейнером использует его для эпох JSON):

some-nmea-source | kshana receiver-trust live session.toml --gate --json trust.jsonl \
  | node integrations/opencpn/nmea-tcp-relay.mjs --listen 10110

Он передаёт байты без изменений, только целые строки, и отключает клиента, который не читает. Предпочтительно прямое подключение: в цепочке одним процессом меньше.

В OpenCPN: Options, Connections, Add Connection, Network, протокол TCP, адрес 127.0.0.1, порт 10110, направление Input. Пока доверие не упало, поток — это собственный поток приёмника плюс одно предложение $PKSHT за цикл. Когда оно упало, пересылаемое GGA имеет качество 0, статус RMC V, а индикаторы режима сообщают об отсутствии определения места, с пересчитанными контрольными суммами: оборудование видит, как сам приёмник объявляет определение места недействительным, и поднимает собственную тревогу. Предложения $PKSHT видны в окне отладки NMEA в OpenCPN (Options, Connections, «NMEA debug window»). Поля положения остаются такими, как получены.

Прочтите «Gate mode» в MARITIME-TRUST.md, прежде чем на это полагаться: это включается по желанию, добавляет задержку (цикл удерживается, пока его эпоха не оценена), является единой точкой в цепочке и может задержать хорошее определение места так же, как пропустить подложное.

Тесты#

cd integrations/opencpn && npm test

test/relay.test.mjs воспроизводит записанный фрагмент синтетического потока, прошедшего шлюз (186 предложений вокруг момента, когда доверие падает, записанных kshana receiver-trust live --gate), через ретранслятор по настоящему сокету TCP и проверяет, что получает потребитель: поток байт в байт при произвольном разбиении на части; корректные контрольные суммы в каждом предложении, включая переписанные; согласие GGA и RMC, сначала корректных, затем некорректных без мерцания; одно $PKSHT за цикл с полем шлюза W ровно там, где определение места недействительно; два одинаковых потребителя; неполная строка никогда не пересылается. Это проверяет поток, который получает OpenCPN, а не собственный экран OpenCPN.

Сквозная проверка с настоящим исполняемым файлом, не входящая в тесты по умолчанию (нужен собранный kshana):

KSHANA_BIN=target/release/kshana npm run e2e            # kshana --gate --listen | TCP consumer; the consumer's bytes must equal the gate's stdout
KSHANA_BIN=target/release/kshana npm run e2e -- relay   # kshana --gate | relay | TCP consumer

Оба запускают часовую синтетическую демонстрацию и проверяют, что определение места становится сначала действительным, затем недействительным, с $PKSHT на каждую эпоху.

Нативный плагин#

integrations/opencpn/plugin/ — панель оценки для OpenCPN (оценка, полоса, шлюз, главные причины, предупреждение, когда доверие становится untrusted), читающая $PKSHT из собственного потока NMEA OpenCPN, поэтому ей не нужно никакого подключения, кроме описанного выше. Она собирается с помощью CMake против заголовка API плагинов OpenCPN (вендорного, с его исходным коммитом) и wxWidgets; ctest запускает тесты логики без wx и проверяет, что библиотека экспортирует точки входа, которые ищет OpenCPN. Она запускалась внутри OpenCPN 5.8.4 на виртуальном дисплее на синтетическом потоке, прошедшем шлюз (OpenCPN передал $PKSHT плагину, панель стала красной, а собственное положение OpenCPN замерло, когда включился шлюз; снимки экрана, журнал и скрипт в integrations/opencpn/evidence/), но не на настоящем рабочем столе, не в других версиях и не на других платформах, и она не упакована для менеджера плагинов OpenCPN. См. README.md плагина. Она распространяется под GPL-3.0-or-later, в отличие от остальной части репозитория (LICENSING.md).

Снимки экрана из этого прогона, в integrations/opencpn/evidence/ (один прогон, OpenCPN 5.8.4 на виртуальном дисплее, синтетические данные; ограничения указаны в README.md):

Окно карты OpenCPN с плагином панели оценки Kshana на синтетическом потоке, прошедшем шлюз, до падения доверия: ни одна панель не открыта (она открывается сама при тревоге), положение судна в строке состояния — 54 32,4659 N 018 46,1670 E со скоростью 16,48 kn и курсом 088, а индикатор определения места вверху справа показывает три полоски. То же окно OpenCPN после падения: панель Kshana открыта красной с оценкой 47 и словом НЕДОВЕРЕННЫЙ, строки gate: fix marked invalid, cn0-spread -30.0, speed-log -21.0 и возраст 2 с, и заявление о том, что это программное обеспечение консультативного характера, не навигационное оборудование с утверждённым типом и что ответственность остаётся на операторе. Строка состояния по-прежнему показывает 54 32,4672 N 018 46,2227 E, а индикатор определения места снизился до двух полосок. OpenCPN, получающий данные напрямую от kshana receiver-trust live --gate --listen: панель Kshana открыта красной с оценкой 44 и НЕДОВЕРЕННЫЙ, строки gate: fix marked invalid, cn0-spread -30.0, speed-log -18.8 и возраст 1 с, и консультативное заявление. Этот прогон не подтверждает наблюдение замирания положения: OpenCPN ещё обрабатывал начальный всплеск эпох.

Это показывает прокладку каналов и то, что определение места после шлюза доходит до OpenCPN, но не то, что какая-либо тревога своевременна или верна для настоящего судна. Программное обеспечение консультативного характера, не оборудование с утверждённым типом.

Эталонная сборка#

deploy/reference-build/: общий перечень деталей, настройка ОС, два юнита systemd (консультативный монитор и включаемый по желанию шлюз), вариант с контейнером и подключение к Signal K. deploy/reference-build/check-units.sh запускает systemd-analyze verify на юнитах, ничего не запуская.

Ограничения#

  • Оценка так же хороша, как проверки за ней, которые смотрят на физику судна и его другие датчики; самосогласованная подделка с совпадающими часами не видна мониторам, работающим только по NMEA (MARITIME-TRUST.md). Отсутствие тревоги не является свидетельством хорошего определения места.
  • Ни одна величина на этой странице не является измеренной частотой обнаружения или ложной тревоги. Приведённые выше тесты проверяют прокладку каналов на синтетическом тексте; они ничего не говорят о том, как какой-либо монитор справляется с реальными помехами.
  • Не является оборудованием с утверждённым типом; ответственность остаётся на операторе.