キャンペーン
単一のシナリオが答えるのは、一つの状況についての一つの問いです。ミッションは状況の連なりであり、設計検討はその一群です。campaign シナリオの種類は、既存の種類をどれも再実装することなく 一回の実行にまとめます。すべてのメンバーは、独自の kind を持つ通常のシナリオテーブルで、kshana <file>.toml が実行するのとまったく同じように api::run_toml を通じてディスパッチされ、キャンペーンは結果ドキュメントから数値を読み戻すだけです。
キャンペーンはMODELLEDです。構成上の恒等関係は(下記のとおり)テストされていますが、フェーズをつなぐことはモデリング上の選択であり、各フェーズの確からしさは、それを実行した種類の確からしさにとどまります。
他のシナリオと同様に実行します。
kshana scenarios/campaign-jam-spoof-holdover-integrity.toml
# writes .result.json, .chart.svg, .report.html and .report.json next to the file
キャンペーンには 四つのセクションを任意に組み合わせて含められます。どれも含まないものも実行でき、その要約には何も構成しなかったと表示されます。
[[phases]]:一本のタイムライン上でつないだミッション#
各フェーズは、共有のミッションタイムラインの区間で、一つ以上のシナリオを実行します。たとえば、ホールドオーバー中の時計と、同時に惰性航行する慣性航法装置(INS)などです。各実行の出力は名前付きのチャンネルに読み込まれ、フェーズの開始時刻に配置され、ゼロ次ホールドによって共通のグリッド([timeline] step_s)にリサンプルされます。グリッド上の時刻には、そのフェーズの実行のうち、その時刻以前で最新のサンプルが採用され、そのフェーズのどの実行もそのチャンネルを提供しない場合は null になります。
| チャンネル | 単位 | 内容 | プリセットのソース |
|---|---|---|---|
time_error_ns |
ns | 時計の時刻誤差 | clock: <side>.series[].error_ns; spoof: <side>.series[].offset_ns |
guard_ns |
ns | 時刻誤差のガード | その実行自身の threshold_ns |
cn0_dbhz |
dB-Hz | 可視衛星での実効搬送波電力対雑音密度比(C/N0)の平均 | jamming:epochs[].sats[].cn0_effective_dbhz の平均 |
cn0_floor_dbhz |
dB-Hz | 追尾喪失の下限 | jamming:シナリオの tracking_threshold_dbhz(指定がある場合) |
tracking |
個数 | 追尾を継続している衛星 | jamming: epochs[].tracking |
protection_level_m |
m | 垂直保護レベル | integrity: epochs[].vpl_m |
alert_limit_m |
m | 垂直アラートリミット | integrity: al_v_m |
position_error_m |
m | 位置誤差 | gnss-ins: <side>.series[].error_m |
position_threshold_m |
m | 位置誤差のしきい値 | gnss-ins: threshold_m |
alarm |
1 | フェーズのいずれかのモニターが警報を出している間は 1 | 下記を参照 |
<side> は、実行が side = "quantum" を指定しない限り classical です。それ以外の量は、明示的な [[phases.runs.series]] エントリーで読み取ります。行を指定する一つの [] を持つ時間経路(epochs[].t)、それらの行を共有する値の経路、またはすべての行にブロードキャストされるスカラー(接頭辞 input: は、実行の結果ではなく、その実行のシナリオを読みます)、一つの行の下に複数の値がある場合のオプションの集約(mean、min、max、count)、スケール、そしてキャンペーンが知らないチャンネル用の単位です。
警報は 三か所から来て、フェーズ内で論理和により結合されます。
- 実行から読み取るプリセットのフラグ:
jammingは、追尾する衛星が 四機未満の間に警報を出します(独自の可用性の定義)。integrityは、それが利用不可とマークしたエポックで警報を出します。 - フェーズのチャンネルに対するプリセットのルールで、
carryの後に評価されます。clockは、時刻誤差の絶対値がguard_nsを超えている間に警報を出し、gnss-insは、位置誤差がposition_threshold_mを超えている間に警報を出します。明示的なルールは[[phases.runs.alarms]]に書きます。 - 警報を出すイベント:
spoofは、時計補助モニターのdetect_time_sで 一件を発生させ、spoof-detectは、融合した判定が警報を出す場合に、フェーズの開始時に一件を発生させます。
状態の引き継ぎは、フェーズ間で 三つの明示的な方法で行われます。
carry = ["time_error_ns"]は、前のフェーズの終了時点でのチャンネルの値を、このフェーズのそのチャンネルの値に加算します。スプーファーに引っ張られた時計の位相が、ホールドオーバーの出発点になります。オフセットの加算は、周波数を積分する時計の位相については厳密です。位置誤差については、二つの誤差が同一直線上にあると仮定することになり、これは悲観的なケースです。[[phases.handoff]]は、前のフェーズの数値(チャンネルの終了値ならchannel:<name>、または前の実行の任意の結果パス)を、このフェーズのシナリオのドット区切りのキーに、実行前に書き込みます。スケールとオフセットは任意です。end_at = "<result path>"は、実行が算出した時刻でフェーズを終了させ、上限はduration_sです。同梱のミッションは、スプーフィングのフェーズをclassical.detect_time_sで終了させます。
skip_s は、実行自身のタイムラインの最初の数秒(ウォームアップ)を、フェーズ時刻ゼロの前に破棄します。
同梱のミッション#
scenarios/campaign-jam-spoof-holdover-integrity.toml は、10 秒グリッド上の 六つのフェーズにわたって 18 個のメンバーシナリオを実行します。
| フェーズ | 実行 | タイムラインが示すもの |
|---|---|---|
| 正常、600 秒 | clock、jamming(ジャマーなし)、integrity |
時刻誤差 0 ns、C/N0 43.0 dB-Hz(下限 25 dB-Hz に対して)、垂直保護レベル 9.1 m から 21.6 m(アラートリミット 50 m に対して) |
| ジャミング、600 秒 | 同じ条件で、ジャマーは -30 dBW、1 km | C/N0 は 27.7 dB-Hz まで低下し、8 機すべてが追尾を継続 |
スプーフィング、370 秒で end_at により終了 |
spoof(0.1 ns/s の時刻ランプ)、spoof-detect、jamming |
時刻誤差は 36 ns までランプし、無線周波数検出器はフェーズの開始時に、時計補助モニターは 370 秒で警報を出す |
| ホールドオーバー、1800 秒 | clock(利用不可、37.0 ns を引き継ぎ)、gnss-ins(惰性航行する戦術級ユニット)、10 dBW の jamming |
すべての衛星を喪失(C/N0 は約 -12 dB-Hz)、時刻誤差は 36.4 から 62.7 ns(ガード 50 ns に対して)、位置誤差は最大 24 km |
| integrity-alarm、600 秒 | clock(59.6 ns を引き継ぎ)、jamming、仰角マスク 25 deg の integrity |
5 機が追尾。保護レベルは 19 から 135 m で、グリッド時刻 60 点のうち 18 点で欠落。引き継いだ時刻誤差 52.1 から 61.7 ns は 50 ns のガードを上回り続けるため、フェーズ全体で警報が出ている |
| recovery、600 秒 | clock、jamming(ジャマーなし)、integrity |
時刻誤差は 0 ns に戻り、警報は出ていない |
インテグリティの実行では、ジャミング用受信機の固定地点ではなく、integrity サンプル自身のユーザートラック(高度 0.4 km の円軌道)を使い、仰角マスク 25 deg は、再捕捉中の受信機が見える空の一部だけを代用して表したものです。これらはシナリオ上の選択であり、ファイルに明記されています。
L バンドスペクトルで駆動するミッション#
scenarios/campaign-spectrum-holdover-integrity.toml は、1 秒グリッド上の三つのフェーズにわたって 8 個のメンバーシナリオを実行します。GPS L1 C/A と Galileo E1 の C/N0 は、jamming の種類の衛星ごとの表からではなく、spectrum の種類(SPECTRUM.md を参照)から読み取ります。ジャマーは scenarios/l-band-waterfall-jamming.toml にあるものです。
| フェーズ | 実行 | タイムラインが示すもの |
|---|---|---|
onset、10 秒で end_at により終了 |
clock、spectrum(10 秒からのチャープ)、integrity |
L1 C/A は 43.48、E1 は 44.73 dB-Hz。フェーズは、スペクトルの実行自身による L1 C/A の最初の喪失(timeline.bands[0].first_loss_t_s)で終了。保護レベルは 21.6 m(50 m に対して) |
| holdover、600 秒 | clock(利用不可、開始時の誤差を引き継ぎ、ここでは 0 ns)、spectrum(チャープあり) |
L1 C/A は 3.38、E1 は 4.44 dB-Hz で、どちらも 25 dB-Hz の下限を下回る。時刻誤差は -0.07 から 5.06 ns(50 ns のガードに対して)。警報が出ている |
| galileo-fallback、300 秒 | clock(再同期済み)、spectrum(L1 搬送波上の CW トーン)、Galileo に似た Walker 24/3/1 の integrity |
L1 C/A は 17.98 dB-Hz を維持し、E1 は 44.73 dB-Hz に回復。保護レベルは 6.1 から 17.7 m。警報は出ていない |
CW トーンの下での E1 の回復は、スペクトルの種類が連続スペクトルとして扱っていることに依存しています。トーンは MBOC スペクトルのヌルに位置し、何の結合も生じません。実際のトーンはコードのスペクトル線を通じて結合します。これはファイルと SPECTRUM.md に明記されています。
[sweep]:任意の種類に対するパラメーターグリッド#
ドット区切りのシナリオキーを一つから三つ指定し、それぞれ線形または対数の範囲を取ります。軸の値は sweep-nd の種類が使うものと同じです。すべての軸に名前と単位があり、すべての指標に名前と結果パスがあります。指標の単位は、キャンペーンが宣言しない限り、スイープ対象の種類自身の単位ブロックから読み取ります。runs > 1 を指定すると、すべてのノードがシード付きのモンテカルロアンサンブルとなり(実現値 k は、ノードのシードに k を加えたもの)、以下の統計量が報告されます。scenarios/campaign-sweep-jammer-power.toml は、受信機から 1 km の位置にあるジャマーを -50 から +10 dBW までスイープします。平均のジャマー対信号比は dB ごとにちょうど 1 dB 変化し(12.2 から 72.2 dB)、可用性は -30 から -25 dBW の間で 1 から 0 に低下します。
ドット区切りのキーは、位置によってテーブルの配列を指定できます。system.2.sisre_m は三番目の [[system]] テーブルの sisre_m であり、case.0.system.0.shell.0.altitude_km は三階層下まで到達します。
[monte_carlo]:シード付きアンサンブル#
実現値 k は、シナリオのシードキーを base_seed + k に設定して実行します。これは時計アンサンブルがすでに使っている規約であり、アンサンブルは正確に再現されます。各指標は、平均、母標準偏差、最近順位法による第5、第50、第95パーセンタイル、平均に対する固定シードのパーセンタイルブートストラップによる 95% 信頼区間(2000 回のリサンプリング)、そしてデフォルトではシード順のすべてのサンプルを報告します。結果パスは配列を指定できます。classical.series[-1].error_ns は最後のサンプルです。
[compose]:共有条件下の複数のシナリオ#
名前付きの共有値(数値または数値の配列で、単位付き)は、各メンバーが結び付けているキーに書き込まれるため、メンバー間で共有条件が食い違うことはありません。すべてのメンバーが実行され、各指標について、結合された要約がメンバー全体の最小値、最大値、平均値を示し、最良と最悪を挙げます。scenarios/campaign-shared-jammer-sea-road.toml は、フィンランド湾の船舶(約 30 km 離れた位置)とヘルシンキの海岸道路を走る自動車(約 50 km)の間に 8 dBW のジャマーを一つ置きます。船舶はすべての衛星を失いますが(平均のジャマー対信号比は 39.0 dB)、自動車は少なくとも四機を保ちます(34.6 dB)。
[optimize]:一つの指標の最良値#
ドット区切りのシナリオキーを一つから三つ指定し、それぞれ lin または log のスケールで [lo, hi] に範囲を限定して、一つの指標の最良値を探索します(goal = "minimize"、"maximize"、または target からの距離を最小化する "target")。
方法は二つあります。
method = "grid"は、キーごとにsteps点のグリッドのすべてのノードを、スイープの軸の値上で実行します。method = "nelder-mead"(デフォルト)は、キーごとに [0, 1] に正規化した座標で、決定論的な Nelder–Mead シンプレックスを実行します。試行点は範囲の箱に射影されます。このセクションは、max_evals、初期のstep、および停止許容差ftolとxtolを取ります。
指標が存在しない、または有限でない実行は最悪のスコアとなり、トレースに残されます。runs > 1 を指定すると、指標は評価のたびに同じシードにわたる平均になります。結果には、best_coords、best_metric、best_score、evals、stop_reason、そして trace 内のすべての評価が含まれます。
scenarios/campaign-optimize-link-budget.toml は、3 dB のリンクマージンを得るための距離とデータレートを探索します。最適解は箱と開始点に対して局所的です。MODELLED であり、大域的な主張ではありません。
プロトコルと事前登録した合格基準は docs/design/evidence/cap32-optimize/ にあります。テストは tests/campaign_optimize_reference.rs です。結果は次のとおりです。
- 1 次元の目標値の解は、閉形式と 6e-15 まで一致する。
- グリッド法は、独立した総当たりのループとビット単位で一致する。
- シンプレックスは、41 × 41 のグリッドと少なくとも同等の結果を、その約十分の一の実行回数で得る。
ラウンド 1 の 1 次元の合格基準は NOT MET と記録されています。事前登録した箱に解が含まれていませんでした。
再現性#
すべてのキャンペーン結果には scenario_hash が含まれます。これは、キャンペーンドキュメントの正準な JavaScript Object Notation(JSON)形式(キーの順序や書式は影響しません)の SHA-256(Secure Hash Algorithm 2、256 ビットのダイジェスト)です。また、メンバーの実行回数と run_digest(ディスパッチ順にすべてのメンバー結果のダイジェストを対象とした SHA-256)を持つ reproducibility ブロックも含まれます。同じダイジェストを持つ二回の実行は、バイト単位で同一のメンバー結果を生成しました。各フェーズの実行も、その種類、種類が持つ場合は独自の scenario_hash、結果ドキュメントの SHA-256 を記録します。ドキュメント内のすべての数値に、単位のエントリーがあります。
コアは逐次的で、ファイルを読み込まないため、キャンペーンは WebAssembly ビルドでも変更なしで実行できます。キャンペーンの中にキャンペーンを含めることはできません。
エクスポート#
キャンペーンに対する --export は、ジオメトリを持つ各メンバーシナリオを、それぞれ独自のファイルセットとして書き出します。メンバーのラベルは、フォーマットの接尾辞の前に挿入されます。対象は、すべてのフェーズの実行(<phase>、フェーズに複数の実行がある場合は <phase>-<k>)、スイープのベースシナリオ(sweep)、モンテカルロのシナリオ(monte-carlo)、そして構成された各メンバー(独自のラベルと、結び付けた共有値を書き込んだもの)です。以前のものと同一のメンバーは一度だけ書き出されます。実行時に適用されるハンドオフやスイープ・シードの値は、エクスポートされるシナリオには含まれません。
kshana scenarios/campaign-shared-jammer-sea-road.toml --export kml
# after the usual result, chart and report files:
# wrote scenarios/campaign-shared-jammer-sea-road.ship-strait.kml
# wrote scenarios/campaign-shared-jammer-sea-road.car-coast-road.kml
どのメンバーも記述できないフォーマットは、その理由を示して拒否されます。シナリオごとの表は INTEROP.md にあります。
LEO-PNT キャンペーン#
同梱の十五件のキャンペーンは、低軌道(LEO)の測位・航法・時刻(PNT)に関する問いを扱います。それぞれが何を示すかは LEO-PNT.md に記載されています。各キャンペーンが何を実行するかを、コマンドラインの要約に沿って示します。
| シナリオ | モード | 問い |
|---|---|---|
leo-focus-data-services.toml |
compose、4 メンバー | フレーム長に対する航法メッセージのサービスデータ |
leo-focus-fused-pnt-sisre.toml |
leo-pvt のスイープ、7 ノード |
LEO の信号空間レンジ誤差(SISRE)に対する、MEO と LEO を融合した測位 |
leo-focus-indoor-uhf.toml |
compose、2 メンバー | バンドと建物クラスごとの屋内 LEO-PNT |
leo-focus-iot-eirp.toml |
leo-pass のスイープ、9 ノード |
LEO の UHF 送信電力に対する、モノのインターネット(IoT)の測位一回あたりのエネルギー |
leo-focus-ntn-bandwidth.toml |
ntn-positioning のスイープ、9 ノード |
参照信号の帯域幅に対する、非地上系ネットワーク(NTN)の測位 |
leo-focus-ppp-altitude.toml |
leo-ppp のスイープ、3 ノード |
192 機の LEO 層の高度に対する、精密単独測位(PPP)の収束 |
leo-resilience-gnss-jammed-leo-carries.toml |
chain、2100 秒にわたる 3 フェーズ | 全球測位衛星システム(GNSS)がジャミングされ、LEO 層がユーザーを支え、インテグリティが維持される |
leo-resilience-multiband-diversity.toml |
spectrum のスイープ、13 ノード |
L バンドのバラージジャマーに対する LEO のバンド多様性 |
leo-resilience-spoof-monitors.toml |
compose、4 メンバー | 四つのスプーファーに対するスプーフィング監視 |
leo-vertical-5g-network-timing.toml |
chain、86,400 秒にわたる 1 フェーズ | 5G 基地局のタイミング:ホールドオーバーと LEO 時刻 |
leo-vertical-asset-tracking-iot.toml |
chain、1440 秒にわたる 3 フェーズ | LEO UHF によるコンテナ追跡:移動経路に沿った測位一回あたりのエネルギー |
leo-vertical-autonomous-vehicle.toml |
chain、1500 秒にわたる 2 フェーズ | LEO 層を使う、都市の谷間での自動運転車両 |
leo-vertical-autonomous-vehicle-skyline.toml |
chain、1800 秒にわたる 2 フェーズ | 同じ都市の谷間を、一律の遮断角 35 deg の場合と、city-street のスカイラインの場合で比較 |
leo-vertical-critical-infrastructure-timing.toml |
chain、87,000 秒にわたる 2 フェーズ | 重要インフラのタイミング:LEO 時刻を使ったホールドオーバー |
leo-vertical-polar-arctic.toml |
chain、10,800 秒にわたる 3 フェーズ | 極軌道の LEO 層を使う、極域・北極域のユーザー |
leo-vertical-rail-maritime.toml |
chain、2520 秒にわたる 3 フェーズ | LEO 層を使う、鉄道・海上のユーザー |
MEO は中軌道(medium Earth orbit)、UHF は極超短波(ultra-high frequency)、5G は第五世代移動通信網です。
検証している内容#
tests/campaign_composition_reference.rs は、構成の恒等関係を固定します。
- 単一フェーズのキャンペーンは、単独実行をビット単位で再現します。
clock、integrity、jammingでは、メンバーの結果ドキュメントはシナリオファイルに対するrun_tomlとバイト単位で同一で、そのダイジェストはキャンペーンが報告するものと一致し、グリッドを実行自身のステップに合わせると、整列したすべての値が単独実行の系列の値と等しくなります(ジャミングの C/N0 は、単独実行のドキュメントから独立に計算した平均と等しくなります)。 - 一ノードのスイープと一メンバーの構成は、単独実行の数値をそのまま読み取ります。
- 固定シードのアンサンブルはバイト単位で安定しており、実現値
kはseed + kでの単独実行と厳密に一致します。キャンペーンのハッシュはキーの順序を無視します。 - 解析的なケース。
scenarios/campaign-monte-carlo-clock-holdover.tomlは、白色周波数雑音のみを持つチップスケール原子時計(q_wf = 9e-20 s^2/s、Microchip SA.45s の sigma_y(1 s) = 3e-10)を 200 個のシードで実行します。時計は 590 秒まで同期され、3600 秒まで惰性で進みます。最終的な時刻誤差は、平均 0、標準偏差 sqrt(q_wf * 3010 s) = 16.459 ns のガウス分布に従います(白色周波数雑音の下での位相のランダムウォーク。米国国立標準技術研究所(NIST)Technical Note 1337)。報告された区間 [-2.52, 1.59] ns は真の平均 0 を含みます。標本標準偏差 14.93 ns からは、自由度 199 でカイ二乗統計量 164.5 が得られ、これは両側 99% 区間 [151.37, 254.14] の内側です。シード 3000 個では、同じシナリオで 16.31 ns になります。 - スペクトル駆動の chain は、単独実行の数値を読み取ります。onset フェーズはスペクトルの実行の最初の喪失時刻とちょうど同じ長さで、タイムライン上の L1 C/A と E1 のすべての値は、同じジャマーの状態(正常、チャープのみ、CW トーンのみ)に対する単独のウォーターフォール例の行と、1e-9 dB の範囲で等しくなります。
- chain は、記載どおりに状態を引き継ぎます。スプーフィングのフェーズはスプーフィング実行の検出時刻とちょうど同じ長さで、ホールドオーバーはスプーフィング実行の検出時点のオフセットをそのまま引き継ぎ、recovery は何も引き継がず、警報は保護レベルが欠落しているか、アラートリミットを超えているところでは常に出ています。
これらが確認するのは、構成しても、変わってはならないものは何も変わらないということです。つなげたミッションを実測のものと照合して validated するものではなく、そのため VERIFICATION-MATRIX.md の三つのキャンペーンの行は MODELLED です。