NMEA 訓練ストリーム:kshana nmea-scenario
海事アカデミーやシミュレーターセンターは、Kshana が生成した NMEA 0183 をブリッジシミュレーターやチャートプロッターに入力して、乗組員が GNSS のジャミングやスプーフィングを見分ける訓練を行えます。
訓練と試験のみ。生成されるストリームは合成です。船舶の実際の航法システムには決して入力しないでください。Kshana は助言用であり、型式承認を受けた航法装置ではありません。どのストリームも、独自仕様のマーカーセンテンス
$PKSHT,TRAINING,SYNTHETIC,NOT-FOR-NAVIGATIONで始まり、十秒ごとに繰り返します。受信機はこれを無視し、未知のセンテンスを拒否するシミュレーター向けには--no-markerで取り除けます。これが書き出すのは NMEA のテキストのみです。RF、IQ、波形の出力はなく、指定したアドレスへのテキスト以外は何も送信しません。
この図は 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 クライアントは切断されるため、停滞した受信側が一つあっても、他の受信側を待たせることはありません。
同じシードは、同一のプラットフォームでは同じバイト列を与え、ペース調整がバイト列を変えることはありません。プラットフォーム間では、ジェネレーター自身の演算はビット単位で同一です(ポータブルな数学層を使用)が、衛星の位置と見通し角はホストの数学ライブラリを呼び出すエンジンの関数から得られるため、まれな境界的なケースでは、GSV の丸めた仰角、方位角、C/N0 の桁がプラットフォーム間で異なることがあります。
書き出される内容#
各エポック(毎秒 1、2、5、または 10 回)には次が含まれます:RMC、GGA、GNS(測位解、位置、時刻)、GSA(使用した衛星と DOP、コンステレーションごとに一つ)、GSV(視界内の衛星と、仰角、方位角、dB-Hz 単位の SNR、コンステレーションごとに一組、NMEA 4.10 の信号 ID)、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 のスロット表、Galileo と BeiDou の MEO Walker パターン、GLONASS ICD)から得られ、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 に従うため、偽の航跡は速度のステップなしに始まり、止まります。そのピークは、D m にわたる T s のランプの場合、1.5 D/T m/s と 6 D/T^2 m/s の二乗です(どちらも記録される)。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 s 以上の変化率)は、ステップ(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 |
m/s の二乗 | 毎秒の速度変化の最大値(真の値と、連続する報告された測位解の間のもの) |
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 |
m/s、m/s の二乗、または null | ドラッグオフ:ドラッグが偽の航跡に加えるピーク |
timeline[] |
デブリーフ用の瞬間を、時刻順に | |
timeline[].t_s, .utc |
開始からの s、ISO 8601 UTC | 時刻(真の時刻) |
timeline[].event |
整数または null | イベント ID;受信機の状態変化では null |
timeline[].what |
文字列 | onset、full-effect、recovery-begins、recovered(イベント);fix-lost、fix-regained(受信機) |
timeline[].text |
文字列 | 説明 |
track[] |
log_interval_s ごとに一行 |
|
track[].t_s, .utc |
s、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 |
m または null | 真の位置から報告された位置までの水平距離 |
track[].time_offset_s |
s | 報告された UTC から真の UTC を引いたもの |
track[].n_used, .n_tracked |
整数 | 測位解に使用した衛星数と追跡した衛星数 |
track[].mean_cn0_dbhz |
dB-Hz または null | 追跡した衛星の平均 C/N0 |
track[].active_events |
整数 | この瞬間に効果を持つイベントの ID |
フィールドを追加しても、スキーマのタグは変わりません。フィールドの名前変更や削除、フィールドの意味や単位の変更を行うと、番号が上がります(/2)。
シナリオライブラリ#
scenarios/training/、それぞれ数分間の航行で、TOML に訓練担当者向けのメモを含みます:
| ファイル | 示す内容 |
|---|---|
open-sea-jamming.toml |
C/N0 が一斉に低下し、衛星が脱落し、測位解が失われて復帰する |
coastal-drag-off.toml |
有効で健全に見える測位解が、岸に向かって 1.4 km ドラッグされる;一様に高い C/N0 |
port-approach-time-spoof.toml |
位置は正しく、ゆっくりとした入港の間に UTC が 45 s 先行するようにドリフトする |
combined-event.toml |
ジャミング、続いてドラッグオフと時刻オフセットを伴う偽装による乗っ取り、その後にリプレイ遅延 |
fjord-natural-degradation.toml |
遮られた空であり、干渉ではない:フィヨルドの壁(REPRESENTATIVEな fjord スカイラインのプリセット)が東と西の衛星を隠し、その後水路が再び開く(イベント natural-degradation、skyline テーブルを使用) |
位置、日付、航跡は架空のものであり、このライブラリには実在の船舶、運用者、記録は含まれません。いかなる受信機やシステムが干渉に対してどう動作するかについても、何も述べるものではありません。
モデル化の選択#
このジェネレーターは外部のオラクルを持たない訓練用ツールであり、その数値はモデル化上の選択であって、いかなる受信機の測定値でもありません。数値は、通常の受信機ログのように見えるよう選んでいます:天頂から水平線にかけての C/N0 の傾きは天頂レベル(既定 47 dB-Hz)より 14 dB 低く、衛星ごとのオフセットは ±1.5 dB、97 s で 0.8 dB および 31 s で 0.5 dB の緩やかなフェージング、0.3 dB のジッタ;追跡(20 dB-Hz)と使用(28 dB-Hz)のしきい値;位置雑音(HDOP 1 で 1.5 m、30 s にわたって相関し、垂直方向はその二倍);0.05 度のジャイロ雑音と 0.03 kn の偏流雑音;船舶モデルの 20 s の操舵時定数とウェイポイントの到達半径;方位セクターによる衛星選択。既定値は [receiver] と [vessel] にあり、すべてシナリオで変更できます。
読み戻す#
kshana receiver-trust はこれらのファイルを取り込めます(format = "nmea")。テストは、ライブラリのすべてのシナリオのすべてのセンテンスを、それぞれのフィールド数とチェックサムの規則に照らして検査し、ファイルをそのリーダーに通します。リーダーは GGA、RMC、GSV を解釈し、他の種類は一つも飛ばさずに通過させます。テストはシナリオごとに基準となる抜粋を固定しており(tests/fixtures/nmea_training/)、意図した変更の後は KSHANA_BLESS_GOLDEN=1 で再生成してください。