機械翻訳であり、ネイティブスピーカーによる確認は行われていません。英語版が基準です。

受信機の信頼性と海事GitHub で編集ソース:docs/MARINE-INTEGRATIONS.md

海事向けの連携:ブリッジでの信頼スコア

Kshana の海事向け信頼スコア(MARITIME-TRUST.md)は、船乗りがすでに使っているソフトウェアから利用できます:Signal K サーバープラグインと、TCP 上のゲートモード NMEA を介した OpenCPN です。リファレンスビルドでは、受信機の隣にある小型コンピューターにこれを載せます。

助言用ソフトウェア。Kshana は、型式承認を受けた航法装置(IEC 61108、IEC 61162)ではなく、いかなる性能規格に対しても評価を受けていません。このページにあるものはすべて、航海士の判断を助けるものです。船舶の安全な航行、および測位解に依拠する、または依拠をやめるという判断の責任は、引き続き運用者にあります。ここでは何も送信せず、測位解をより正確にするものもありません。

構成要素 場所 0.35 での状況
Signal K プラグイン integrations/signalk/ 提供済み。記録した合成出力でユニットテスト済み。npm には公開していません
TCP 上のゲートモード NMEA を介した OpenCPN integrations/opencpn/ 提供済みでテスト済み(利用側のリプレイ)。OpenCPN のユーザーインターフェース自体は、どのテストでも操作していません
OpenCPN ネイティブのスコアパネルプラグイン integrations/opencpn/plugin/ ビルド済み、ロジックはユニットテスト済みで、仮想ディスプレイ上の OpenCPN 5.8.4 の内部で実行済み(証拠は integrations/opencpn/evidence/)。プラグインマネージャー用にはパッケージ化されていません。レビュー後にのみ提供されます
リファレンスビルド deploy/reference-build/ 部品、OS の手順、systemd ユニット(ドライランで検査)、コンテナの選択肢。船舶ではテストしていません

すべては一つのものを読み取ります:kshana receiver-trust live の出力(JSON Lines、$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)にコピーまたはリンクし、サーバーを再起動して、Server、Plugin Config で Kshana GNSS trust を有効にします。

エポックの取得元(source)#

source プラグインの動作
spawn-signalk-nmea(既定) kshana receiver-trust live <sessionFile> を実行し、サーバーが受信した生の NMEA 0183 センテンスをすべて(サーバーの nmea0183 イベント)その標準入力に書き込みます。終了した場合は、バックオフを置いて再起動します | NMEA ソースが一つだけのサーバーでのみ使用してください:すべてのプロバイダーのすべてのセンテンスを混在させて渡すため、二台目の GNSS 受信機や AIS があると、位置が飛ぶ一台の受信機のように見え、スプーフィングとして採点されることがあります。ソースが複数ある場合は、spawn-args でその受信機自身の --tcp ストリームを使うか、ゲートからの tcp-pksht を使ってください。
spawn-args kshana receiver-trust live <sessionFile> <inputArgs...> を実行します。例:["--tcp","192.0.2.10:10110"] または ["--udp","10110"]
tcp-json kshana が書き出す JSON Lines のフィードに接続します(例: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(ゲートが別の場所で動作している場合。ない場合は $PKSHT からの null)
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 の信頼スコアで、比率でも確率でもなくスコアであるため、SI 単位はありません。そのメタデータには、範囲、説明、および下記のしきい値に従うゾーンが含まれます。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 の入力、spawn-signalk-nmea の --replay(実時間より速く入力される保存済みログ)などの追加フラグ。プラグインは --gate、--listen、--json、--pksht を拒否し(kshana の標準出力の JSON を読み取るため)、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 になります(nominal に対する Kshana の既定の境界値)
alarmBelowScore 55 score モード:これを下回ると、状態は alarm になります(degraded に対する Kshana の既定の境界値)
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 以外のネットワークなし。テストは、kshana receiver-trust live が合成のバルト海デモ(作成したデータで、テキストのみ)向けに書き出した JSON Lines と $PKSHT センテンスの 66 エポックの抜粋を解析して再生し、二つの形式の一致、保持と解除の動作、スコアモード、陳腐化、そしてローカルのフィードと代役の子プロセスに対する三つの入力経路を検査します。これらのテストは実際の Signal K サーバーを起動しません。別のスクリプト実行がそれを行います(下記を参照)。

実際の Signal K サーバーでの実行#

integrations/signalk/evidence/ には、固定した signalk-server 2.33.0 パッケージにプラグインを読み込ませ(ループバック専用の専用ネットワーク名前空間内で)、サーバー自身の REST と WebSocket の API が示す内容を記録するスクリプトがあります。信頼性のパスが現れ、通知は warn、alarm、normal(保持の後)となり、データが止まると再び warn になります。また、サーバー自身の NMEA 入力から供給される実際の kshana では、reportedPosition を公開し、navigation.position は一度も公開しませんでした。サーバーのバージョンは一つ、実行は一回で、実際の船はありません。制約と再現手順は、evidence の 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 で読み取る受信機のシリアルポート、マルチプレクサー、または kshana 自身の --tcp/--udp 入力です。リファレンスビルドの kshana-gate.service は、systemd のもとでこれを行います。)--listen tcp:<port> はループバックアドレスにバインドします。読み取り専用のクライアントはいくつでも接続でき、追従できないクライアントは、他のクライアントを遅らせることなく切断されます。

代替:リレー。 integrations/opencpn/nmea-tcp-relay.mjs は、依存パッケージのない Node のファンアウトで、--listen のない kshana に対して同じことを行うか、他の任意の行ストリームを提供します(コンテナの選択肢では 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 センテンスは、OpenCPN の NMEA デバッグウィンドウ(Options、Connections、"NMEA debug window")で確認できます。位置フィールドは受信したままです。

これに依拠する前に、MARITIME-TRUST.md の「Gate mode」を読んでください:これはオプトインであり、遅延を加え(サイクルは、そのエポックが採点されるまで保留されます)、チェーンの中の単一の点であり、偽造された測位解を通してしまうだけでなく、正しい測位解を保留してしまうこともあります。

テスト#

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 になったときのアラート)。OpenCPN 自身の NMEA ストリームから $PKSHT を読み取るため、上記の接続以外の接続は不要です。CMake で、OpenCPN のプラグイン API ヘッダー(コミットとともに同梱)と 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 を参照):

合成のゲート済みストリームで Kshana スコアパネルプラグインを動かしている OpenCPN のチャートウィンドウ(信頼性が崩れる前):パネルは開いておらず(警報で自動的に開きます)、ステータスバーの自船位置は 54 32.4659 N 018 46.1670 E、速力 16.48 kn、針路 088 を示し、右上の測位インジケーターは三本のバーを表示しています。 崩れた後の同じ OpenCPN ウィンドウ:Kshana パネルが赤で開き、スコア 47 と UNTRUSTED の文字、gate: fix marked invalid、cn0-spread -30.0、speed-log -21.0、age 2 s の各行、そしてこれは助言用ソフトウェアであって型式承認を受けた航法装置ではなく、運用者が引き続き責任を負うという記載が表示されています。ステータスバーは引き続き 54 32.4672 N 018 46.2227 E を示し、測位インジケーターは二本のバーに下がっています。 kshana receiver-trust live --gate --listen から直接入力を受けた OpenCPN:Kshana パネルが赤で開き、スコア 44 と UNTRUSTED、gate: fix marked invalid、cn0-spread -30.0、speed-log -18.8、age 1 s の各行、そして助言の記載が表示されています。この実行は位置凍結の観察を裏付けません:OpenCPN は、最初のエポックの集中的な入力を処理している途中でした。

これらが示すのは配線と、ゲートされた測位解が OpenCPN に届くことであり、実際の船で警報がタイミングよく正しいことではありません。助言用ソフトウェアであり、型式承認を受けた機器ではありません。

リファレンスビルド#

deploy/reference-build/:汎用の部品リスト、OS のセットアップ、二つの systemd ユニット(助言用モニターとオプトインのゲート)、コンテナの選択肢、Signal K の結線。deploy/reference-build/check-units.sh は、何も起動せずに、ユニットに対して systemd-analyze verify を実行します。

制限#

  • スコアは、その背後にあるチェックの質以上のものにはなりません。チェックは船の物理と他のセンサーを見ているため、時計も一致した自己無矛盾な偽造は、NMEA のみのモニターでは検出されません(MARITIME-TRUST.md)。警報がないことは、測位解が良好であることの証拠ではありません。
  • このページの数値は、実測した検出率や誤警報率ではありません。上記のテストは、合成テキストで配線を検査するものであり、実際の干渉に対してどのモニターがどう動作するかについては何も述べません。
  • 型式承認を受けていません。運用者が引き続き責任を負います。