スカイラインマスクと天空のジオメトリ
0.36 までは、エンジン内の地球の可視性判定はすべて一つの仰角のしきい値 mask_deg でした。衛星は、方向に関係なく、その一つの数値以上にあれば数えられていました。街路、岸壁、フィヨルド、クレーンは空の一部を遮り、残りを開けたままにします。skyline は、方位に依存する仰角のカットです。天空ジオメトリ関数は、サイト、時刻、コンステレーション、skyline から、可視集合、精度低下率(DOP)、ジオメトリの共分散、水平誤差楕円、モンテカルロの雲、スカイプロットを求めます。設計は docs/design/2026-10-12-geometry-and-skyline-design.md にあります(項目 1 と 2)。
エビデンス:マスクをかけた可視性の判定(測地的な見上げ角、表のマスク、可視集合とその DOP)は、事前登録した比較で Orekit 12.2 と gnss_lib_py 1.0.4 に対して VALIDATED であり、誤差楕円と系ごとのコファクターも同様です(numpy、事前登録)。キャニオン、セクター、地形の縮約、プリセット、そして天空ジオメトリ関数の残りは MODELLED です(エビデンス)。skyline が取り除くのは見通し線上の衛星だけで、それ以上のことはしません。プリセットはREPRESENTATIVEなジオメトリであり、測量ではありません。
skyline#
skyline は、四つの記述の点ごとの最大値です。方位は、サイトのローカルな東・北・上の座標系で、真北から時計回りに測った度です。仰角は [0, 90) です。
| 説明 | TOML | 内容 |
|---|---|---|
| テーブル | table = [[az, el], ...] |
方位について線形補間した仰角で、360° で折り返します。方位は [0, 360) で厳密に増加しなければならず、行数は最大 3600 です。 |
| 街路のキャニオン | street_az_deg, width_m, height_left_m, height_right_m, antenna_m, length_m |
二本の直線の平行な壁(下を参照)。 |
| セクター | sectors = [{ az_from, az_to, el_deg }] |
境界がはっきりした区間で、az_from(含む)から az_to(含まない)まで時計回りに指定します。北をまたいでもかまいません。最大 360 個です。 |
| 地形 | terrain = [{ az, distance_m, height_m }] |
表に縮約した点:仰角 atan((height_m − d²/(2 R_eff)) / d)、および R_eff = 4/3 × 6371 km に対する曲率による降下(選んで明記した定数)。height_m はアンテナより上の高さです。 |
preset = "<name>" は名前付きのジオメトリから始まります。その後、キャニオンのフィールドがプリセットのキャニオンをフィールドごとに上書きし、table、sectors、terrain がそこに追加されます。
受信機の mask_deg は意味を保ちます。それは平坦な skyline です。方位 az での有効なカットは max(mask_deg, skyline(az)) であり、衛星の仰角がそれ以上であれば可視です。これは、平坦なマスクが常に使ってきたのと同じ >= です。mask_deg より上にあるが skyline より下にある衛星は、skyline によってマスクされたものです。
街路のキャニオン#
街路が方位 s に沿って走り、壁の間が w メートル、アンテナは中心線上で a メートルの高さにあります。方位 az では、θ = az − s のとき、光線は d(az) = (w/2) / |sin θ| の後に壁に届くため、高さ h の壁は次のようにカットします
cut(az) = atan( (h − a) / d(az) ) (the right wall for sin θ > 0, the side at s + 90°)
開いた帯は街路に沿って延びています。length_m = L(アンテナは中央)の場合、d(az) · |cos θ| > L/2 のとき、光線は開いた端から抜け、壁は何もカットしません。アンテナより高くない壁は、何もカットしません。antenna_m の既定値は 1.5 m です(車の屋根、または手持ちの受信機。選んで明記した値)。新しいキャニオンには width_m が必要です。
プリセット#
選んで明記した寸法(設計メモのもの)であり、実在するどの場所の測量でもありません。kshana skyline --preset <name> は、その一つを出所とともに、度ごとのカットを付けて表示します。
| プリセット | ジオメトリ | 来歴 |
|---|---|---|
city-street |
キャニオン:街路 0°、幅 20 m、壁は 30 m と 30 m、アンテナ 1.5 m。街路を横切る方向で 70.7°、街路に沿う方向は開いています。 | 高さと幅の比 1.5 は、Oke(1988)、Street design and urban canopy layer climate、Energy and Buildings 11、103–113 にある、街路キャニオンのアスペクト比の範囲 0.5–2 の内側にあります。 |
harbour-approach |
セクター:090–270 の海側は開いている(180°)。315–045 の岸壁の建物は 8°(90°)。防波堤とその灯台は、045–090 と 270–315 で 3°。 | 選んで明記した値(例:約 285 m 離れた 40 m の倉庫)。 |
fjord |
地形:南北方向の水路の両側 1500 m の位置で、アンテナより 600 m 高い壁が、度ごとに一つの点で(1500/|sin az| m で)立ち、曲率による降下を適用。軸に沿う方向では、横切る方向で 21.8°、1° 未満。 |
西ノルウェーの深いフィヨルドの幅と起伏のオーダー(Holtedahl(1967)、Notes on the formation of fjords and fjord-valleys、Geografiska Annaler 49A、193–203)。 |
container-terminal |
セクター:陸側の半分 000–180 でコンテナの積み重ねが 12°。クレーンのブームは 245–255 で 35°、285–295 で 25°。それ以外は水面に向かって開いています。 | 高さ 2 m のアンテナから約 60 m 離れた、五つの ISO 668 ハイキューブコンテナ(14.5 m)。70 m と 100 m の位置で岸壁から約 50 m 上にあるブームは、ポストパナマックスのクレートのオーダーです。クレーンのセクターは不透明です。 |
シナリオでの使い方#
kind 自身のしきい値に優先する、任意の [skyline] セクション。
| 種類 | skyline が変えるもの | サンプルごと |
|---|---|---|
orbit(user_site を伴う) |
可視性のタイムライン(GNSS の可用性)と DOP の要約。 | — |
integrity(user_site を伴う) |
RAIM と ARAIM(araim_dual)が使う衛星。 |
epochs[].masked_by_skyline |
gnss-sim |
擬似距離をシミュレートして RAIM で使う衛星。 | gnss_measurements[].masked_by_skyline |
jamming |
ジャマーの前に、受信機が追跡できる衛星。 | epochs[].masked_by_skyline |
leo-pvt |
各モードの可視集合は、各システム自身のマスクを超えるもので、極域の掃引も含みます(すべてのサイトで同じ skyline)。ドップラーモードのエンベロープと、設計した単一パスは、受信機が扱わなければならないものの境界であり、各システムのマスクを保ちます。 | joint.epochs[].masked_by_skyline |
leo-pass |
どのエポックがマスクより上として数えられるか、その上にある時間、GNSS 比較の衛星。 | satellites[].pass.epochs_masked_by_skyline |
nmea-scenario(訓練用の NMEA) |
GSV と測位解に含まれる衛星。方位は、船首方位ではなく、地面に固定された真方位です。 | — |
orbit と integrity の地上サイト。どちらの kind も、軌道上のユーザーを、地心の仰角と、地球固定の方位なしでモデル化するため、skyline を使えるのは、設計メモの地上サイトモードを使う場合に限ります。つまり、user の代わりに user_site = { lat_deg, lon_deg, height_m } を使います(どちらか一つだけ)。各サンプルは絶対的な一つの時刻 epoch + t です。すべての衛星はその時刻まで伝搬され(要素セット、放送エフェメリス、SP3 ファイルは、それ自身のエポックから進められ、Walker 衛星は epoch から t を数えます)、その時刻で地球固定に回転されるため、サイトからは一貫した一つの空が見えます。epoch はその orbit シナリオ自身のものです。ない場合(また、持たない integrity では常に)、エポックを持つ衛星のうち最も新しいエポックとなり、Walker パターンだけの場合は J2000 となります。仰角と方位は測地的です(WGS-84)。integrity kind の ARAIM 保護レベルと Stanford 垂直誤差の水平・垂直の分割も、同じ測地的な上方向(WGS-84 楕円体の法線で、緯度 45° では地心動径から約 0.19° ずれる)を使います。スナップショット RAIM はすでにそれを使っていました。skyline のない user_site は通常の地上ユーザーであり、軌道上の user の経路は変わりません。
kind = "integrity"
mask_deg = 5.0
# ...
[user_site]
lat_deg = 59.45
lon_deg = 24.75
height_m = 15.0
[skyline]
preset = "harbour-approach"
後方互換性。[skyline] セクションがない場合、シナリオは、skyline のコードが存在する前に同じエンジンが出していたものとバイト単位で同一です。tests/skyline_scenarios.rs は、これらの kind のいずれかを実行する、出荷済みのすべてのシナリオの JSON、グラフ、要約と、すべての訓練シナリオの NMEA テキストを、「0.36 portable」ベースラインの SHA-256 ダイジェストに照らして検査します(0.35.0 リリースのコミットのダイジェストで、エンジンがポータブルな数学に移行した際に再基準化し、記録としてテストに保持しています:docs/revisions/STUDIO15-portable-math-rebaseline.md)。空の [skyline] セクションは何もカットしません。その場合の結果は、追加された skyline ブロックと、ゼロの masked_by_skyline の件数を除いて、セクションなしの実行と等しくなります。
拒否されるもの(メッセージに理由が付きます):軌道上の user に対する skyline、user と user_site の併用、未知のプリセット、width_m のないキャニオン、[0, 360) で厳密に増加していないテーブル、[0, 90) の範囲外の仰角、空のセクター、正でない地形の距離、上限を超える入力、未知のキー。
結果には、セクションがある場合に skyline: { source, open_fraction, provenance } が加わります。source は preset:<name>、preset:<name>+overrides、custom のいずれかです。open_fraction は、max(mask_deg, skyline) より上の上半球の立体角の割合です(方位にわたる 1 − sin(cut) の平均で、マスクがゼロなら 1、平坦な 30° のカットなら 0.5)。provenance は、プリセットの行、またはシナリオ自身のものです。単位と出所の区分は units ブロックにあります。
同梱の例(kshana example <name>):
| 例 | 示すもの(比較するには [skyline] セクションを取り除きます) |
|---|---|
orbit-urban-canyon-skyline |
city-street の底での GPS + Galileo:289 サンプル中 17 サンプルが測位解を保ち、PDOP の中央値は 70.5(開けた空では 1.14)。 |
integrity-harbour-approach |
港に入るときの二系統コンステレーションの ARAIM:70 衛星エポックが隠れ、可用性は変わらず(145 中 145)。 |
gnss-sim-container-terminal-skyline |
岸壁での擬似距離と RAIM:44 衛星エポックが隠れ、RAIM の可用性は 0.59(開けた空では 0.85)。 |
jamming-harbour-approach-skyline |
港の 2 W のジャマー:83 衛星エポックが隠れ、トラッキングは変わらず(ジャマーがすでに奪っていたため)。 |
leo-pvt-fjord-skyline |
フィヨルドでの GPS + Galileo + LEO レイヤー:統合 PDOP の中央値は 1.14(開けた空では 0.93)。 |
leo-vertical-autonomous-vehicle-skyline |
leo-vertical-autonomous-vehicle のキャニオンを、平坦な 35° のカットとした場合と、車の進行方向に合わせて回した city-street とした場合:GPS と Galileo の衛星は 4 から 5 機に対して 8 機。統合後の平均誤差はどちらも 2.1 m。1.5 m のアラームは、エポックの 51 % と 59 %。 |
天空の幾何#
五つのエンジン関数(src/geometry.rs)。すべてのサーフェスで同じです。
| 関数 | 入力 → 出力 |
|---|---|
sky_geometry(request) |
衛星ごとの id、system、az_deg、el_deg、cut_deg、visible、masked、n_visible、n_masked、open_fraction、dop(GDOP、PDOP、HDOP、VDOP、TDOP、tdop_by_clock)、states、cofactor_enu(単位分散)、covariance_enu_m2、要求した信頼度での ellipse_1sigma と ellipse、label、statement、advisory |
sky_monte_carlo(request, seed, n) |
seed でシードした ChaCha8 ストリームから、σ_UERE の独立したガウス測距誤差のもとで求めた n 個(最大 5000、入力の上限)の最小二乗誤差:samples_enu_m、経験的な共分散、水平および 3 次元の RMS(σ_UERE × HDOP と σ_UERE × PDOP と並べて)、95 % 楕円の内側に入る割合 |
skyline_presets() |
ラベル、説明、出所、度ごとのカット、open_fraction を付けたプリセット |
skyline_profile(skyline) |
エンジンが使う 360 エントリのテーブルに縮約した skyline セクション。source、provenance、open_fraction を付けます |
skyplot_svg(request) |
静的な SVG としてのスカイプロット(スクリプトなし、外部参照なし、すべての入力文字列をエスケープ) |
リクエスト:
{
"site": {"lat_deg": 59.91, "lon_deg": 10.75, "height_m": 5},
"time_s": 3600,
"systems": ["gps-baseline", "galileo", "beidou-meo", "xona-pulsar"],
"mask_deg": 5,
"skyline": {"preset": "fjord"},
"clock": "per-system",
"sigma_uere_m": 1.5,
"confidence": 0.95
}
systems は、エンジンのコンステレーションプリセット(constellation-design の gps-baseline、galileo、beidou-meo、glonass など。LEO プリセットの xona-pulsar、iridium-stl など)、または完全な leo-pvt の [[system]] テーブルで、time_s まで伝搬されます(永年 J2 を伴うケプラー運動。leo-pvt の統合モードの軌道)。それらの相対位相は異なる基準エポックに由来するため、天空は代表的なジオメトリであって、その日付のその場所の空ではありません。衛星は、代わりに(または併せて)直接指定することもできます:"satellites": [{"id": "G05", "system": "GPS", "az_deg": 120, "el_deg": 35}, ...]、または "ecef_m": [x, y, z] と、site または user_ecef_m を使って。既定値:各システム自身のマスク(GNSS は 5°、LEO は 10°。直接指定した衛星は 5°)、システムごとに一つの受信機クロック(共有する一つのクロックには "common")、σ_UERE は 1 m(代表的な二周波のバジェット行)、信頼度は 0.95。入力の上限:地平線より上の衛星は最大 2000 機(それ以上を求めるシステムテーブルは、構築される前に拒否されます)、受信機クロックは 16 個です。
要素セットから求める、日付付きの天空。 "tle" は、二行軌道要素セットのテキストを受け取ります(各セットの前の名前行は任意。最大 4 MiB、入力の上限)。これをエンジンの SGP4(WGS-72。orbit-real-tle が使う伝搬器)で "epoch" に time_s を足した時刻まで伝搬し、UT1 を UTC とし極運動なしとして地球固定に回転し、site から見ます。"epoch" は UTC の ISO 8601(2026-06-07T12:00:00Z)で、要素セットの日付だけを定めます(プリセットには日付がないため、tle のない epoch は拒否されます)。"tle_system" は、システムごとのクロックのために要素セットにラベルを付けます(既定は TLE)。すべての結果は、どの天空であるかを sky_source と sky_statement に記します。
sky_source |
天空 |
|---|---|
presets |
エンジンのコンステレーションプリセット:代表的なジオメトリ |
tle-at-epoch |
指定したエポックまで伝搬した要素セット:それらの要素セットがそのエポックに与える天空であって、その実測ではありません(精度は SGP4 と要素セットの古さによります) |
tle-at-element-epoch |
epoch なし:最新のセットの自身のエポックに time_s を足した時刻まで伝搬した要素セットで、代表的な天空 |
satellites |
直接指定した衛星。指定されたとおり |
組み合わせは + で結びます。epoch_utc は要素セットを伝搬した時刻で、tle_skipped は、テキストのうち使われなかったものを、理由とともに示します。形式が不正な、または孤立した要素セットの行(行番号付き)、パーサーが拒否したセット、そして、その時刻まで SGP4 が伝搬できなかったセット(軌道減衰、または有効範囲外)です。最大 100 エントリまでで、その後に、残りの件数を数える最後の一つのエントリが付きます。空の systems リストはプリセットを追加しません。スカイプロットは、フッターにその根拠を示します。
一つのカーネル。コファクター行列は orbit::cofactor_from_los で、orbit::dop の背後にあるデザイン行列の組み立てとガウス・ジョルダン法の逆行列です。orbit::dop_cov は共分散を公開し、orbit::dop はその縮約であるため、VALIDATED のスカラー値は変わらず、引き続き tests/dop_reference.rs で固定されています。DOP の実装が二つ目あるわけではありません。
楕円。東・北ブロックの固有値 λ に対する半軸 k σ √λ。k = √(−2 ln(1 − p)) を使い(95 % では √5.991 = 2.448、39.35 % では 1)、長軸の方位は北から [0, 180) の範囲の ½ atan2(2 Q_EN, Q_NN − Q_EE) です。
| 利用形態 | エントリポイント |
|---|---|
| CLI | kshana sky <request.json|toml> または kshana sky --site <lat,lon[,h]> (--systems <a,b> | --tle <file>) [--epoch] [--tle-system] [--time] [--mask] [--skyline-preset] [--uere] [--clock]、--monte-carlo <n> --seed <s> または --svg を付けて。kshana skyline --preset <name> | --presets | --profile <file> |
| Rust | kshana::geometry::{sky_geometry, sky_monte_carlo, skyline_presets, skyline_profile, skyplot_svg}、同名の kshana::surface::* |
| Python | kshana.sky_geometry, sky_monte_carlo, skyline_presets, skyline_profile, skyplot_svg |
| WASM | sky_geometry(request_json), sky_monte_carlo(request_json, seed, n), skyline_presets(), skyline_profile(skyline_json), skyplot_svg(request_json) |
| MCP | sky_geometry(request、または skyline_preset)。MCP 経由のモンテカルロはなし(エージェントが運ぶのではなく要約すべき大量のサンプルであるため) |
すべての結果には、label(MODELLED)、statement(明記した誤差モデルのもとでのジオメトリ:独立で等分散、平均ゼロのガウス測距誤差。受信機の実際の誤差の予測ではなく、実際の誤差にはバイアス、マルチパス、見通し外の誤差も含まれます。インテグリティの境界でもありません)、および助言が付きます:助言用ソフトウェアであり、型式承認を受けた航法装置(IEC 61108、IEC 61162)ではありません。船舶の航行の責任は引き続き運用者にあります。
エビデンス#
台帳の五つの行(docs/VERIFICATION-MATRIX.md)。設計メモが定める範囲のとおりです。
| 行 | ステータス | オラクル |
|---|---|---|
| 方位依存のスカイラインマスク:可視集合、方位角と仰角、マスク下の DOP | VALIDATED | Orekit 12.2(TopocentricFrame の見上げ角、ElevationMask)と gnss_lib_py 1.0.4(get_dop と DOP 行列)。どちらかを実行する前に xval/orekit-skyline/PREREGISTRATION.md に事前登録(コミット e4b9d912)済み。六つのサイトと四つのエポックでの 1173 個の見上げ角、六つのテーブル、142 個の可視集合。仰角の最悪値は 1.3e-13°、方位角は 2.3e-13°、マスクは 1.1e-12°(許容値 1e-9°)。可視集合は同一で、境界帯に入るものはなし。DOP は相対で 3.3e-13、コファクターは行列スケールの 6.6e-13(許容値 1e-9)。範囲:テーブルのマスク、測地的な見上げ角、マスクをかけた集合と、その共通クロックの DOP およびコファクター。 |
| ストリートキャニオン、セクター、地形のテーブルへの縮約 | MODELLED | 手計算した値。上の比較はそれらのテーブルを入力として読み込むだけで、検査しません |
| skyline プリセット | MODELLED | なし:選んで明記した寸法(それ自身に対してのみ確認) |
| 幾何の共分散から得る水平誤差楕円とシステムごとのコファクター | VALIDATED | numpy 2.5.4 の linalg.inv と linalg.eigh(標準の P2)を、コミット済みの 142 個の可視集合に適用し、共通クロックとシステムごとの一つのクロックで、xval/numpy-ellipse/PREREGISTRATION.md に事前登録(コミット 0bbeeaee)済み:270 ケース、軸は相対で 5.1e-13、向きは 5.3e-12°、コファクターは行列スケールの 1.0e-12(許容値は 1e-9 と 1e-6°) |
| 天空ジオメトリ関数 | MODELLED | 合成:プリセットの伝搬による代表的な天空、モンテカルロの雲(サンプリング元のジオメトリに対して確認)、サーフェス |
[skyline] セクションがないことは、0.35.0 の出力に対してバイト単位で検査されており、これは後方互換性を示すもので、独立した参照との照合による確認にはなりません。gnss_lib_py が適用するのは単一の仰角マスクだけなので、ここでは DOP のオラクルであって、マスクのオラクルではありません。
skyline がモデル化しないもの:壁の縁での回折、実際の受信機がなお追跡しうる反射や見通し外の信号(劣化するのではなく、除去されます)、部分的な透過(格子状のクレーンは、そのセクター全体で不透明)、与えた点を超える地形、そしてキャニオンとセクターの形式の内側での地球の曲率。