机器翻译,未经母语人士审校。以英文版为准。

入门在GitHub上编辑来源:docs/tutorials/01-first-orbit.md

教程1——我的第一条轨道:GPS卫星在哪里

Kind: orbit · 场景:scenarios/orbit-sgp4-gps.toml(教学副本:scenarios/orbit.toml) · 难度:入门 · 约15分钟

学完本教程,你将对真实的在役GPS星座完成轨道外推,读出其可用性与几何构型,并导出一张列出每颗卫星在空间中实际位置的表——同时你会知道,这张表是经独立外部参考核对过的,而不是与自身比对。

这个场景是什么#

GPS(全球定位系统)卫星告诉用户自己在哪里以及现在是几点。在此之前,你需要知道卫星在哪里,以及用户能看到其中多少颗。这就是几何问题,而几何构型决定了定位精度的下限(即精度因子,DOP)。本教程将:

  1. 取一份真实的Celestrak gps-ops GPS星座快照(2021-07-28,30颗卫星,真实的两行根数,TLE),
  2. 用经独立外部参考核对过的SGP4/SDP4模型(Simplified General Perturbations 4 / Simplified Deep-space Perturbations 4)外推每一颗卫星,
  3. 在每个时间步计算低地球轨道用户能看到哪些卫星(视线、地球遮挡,以及5° 的高度截止角),
  4. 把这种几何构型转换为PDOP(位置精度因子)和位置精度,并
  5. 把卫星实际的地心地固(ECEF)位置导出为SP3文件(Standard Product 3,国际GNSS服务组织IGS的精密轨道格式;GNSS即全球导航卫星系统)。

主线是:TLE → SGP4外推 → 每历元的ECEF → 可见性 → 可见卫星数 → PDOP → 位置sigma = PDOP · σ_UERE,其中 σ_UERE是用户等效测距误差(每颗卫星的1-σ 测距误差)。

运行#

cargo run -- scenarios/orbit-sgp4-gps.toml

Python:

import json, kshana
result = json.loads(kshana.run(open("scenarios/orbit-sgp4-gps.toml").read()))
print(result["geometry"]["best_pdop"], result["geometry"]["best_position_sigma_m"])

也可以打开浏览器版Studio,选择轨道场景。

读取单行概括#

确定性运行(随机种子 = 17)输出:

scenario 4c51512369a6 | 345/361 samples GNSS-nominal | best PDOP 1.07 pos 1.07m | quantum holdover 0s p95 2.59e-5ns integrity 1.000 security n/a (no attack) | classical holdover 0s p95 6.7ns integrity 1.000 security n/a (no attack)

逐字段说明:

  • scenario 4c51512369a6——12位字符的场景哈希。它为全部输入(随机种子、阈值、模型参数、TLE数据块)生成指纹。改动任何输入,它都会变化;保持输入不变,则可逐位复现该次运行。同一哈希还印在图表页脚和结果JSON(JavaScript Object Notation)文件中。
  • 345/361 samples GNSS-nominal——在361个时间步中,用户有345个时间步具备可用定位解(95.6 %)。本次运行是一个12 h的过境(43,200 s),步长120 s。
  • best PDOP 1.07——整个过境期间最佳(最低)的位置精度因子。PDOP接近1即为极佳的几何构型;越低越好。
  • pos 1.07m——最佳位置精度:位置sigma = PDOP · σ_UERE。在本场景中sigma_uere_m = 1.0,因此这两个数值在此处数值相等——但规则是PDOP × UERE,而不是“位置 = PDOP”。若UERE为3 m,位置sigma约为3.2 m。(见末尾的易错点。)
  • 时钟相关数据(holdover、p95、integrity、security)会一并给出,因为该轨道包在整个过境期间还带有一个时钟;它们是教程2的重点,而非本教程的重点。(security显示n/a (no attack),因为没有配置任何攻击。)

JSON中的几何块给出了底层数值:

"geometry": {
  "samples_total": 361,
  "samples_with_fix": 345,
  "sigma_uere_m": 1.0,
  "best_pdop": 1.0713624151805556,
  "median_pdop": 2.318376881311817,
  "best_position_sigma_m": 1.0713624151805556,
  "median_position_sigma_m": 2.318376881311817
}

卫星在哪里?(真正的收获)#

几何构型之所以好,正是因为卫星确实位于GPS轨道壳层中。来证明这一点——导出它们的地固位置:

cargo run -- scenarios/orbit-sgp4-gps.toml --export-sp3 gps.sp3

第一个采样步上的前三颗卫星,ECEF坐标,单位km(SP3文件还带有第四列,即时钟列,以999999.999999这一“无值”标记写出):

PG01   9771.575585  24612.128830      0.003744 999999.999999
PG02  20449.643959 -11875.958365 -12379.457079 999999.999999
PG03  26467.367408     45.510223   4010.411755 999999.999999

取PG01的地心半径:

|r(PG01)| = sqrt(9771.575585^2 + 24612.128830^2 + 0.003744^2) = 26480.9 km

非循环的参考基准(oracle):这真的是GPS轨道吗?#

只拿引擎与自身核对的教程什么也证明不了。下面是上述每一项结论的外部非循环锚点。

1. 卫星位于真实的GPS中地球轨道(MEO)壳层上。GPS标称半长轴为a = 26,560 km,高度约20,180 km(相对于6,378 km的平均地球半径)(IS-GPS-200,即GPS接口规范;美国国防部(DoD)的GPS标准定位服务(SPS)性能标准;Misra & Enge,Global Positioning System,第2版)。PG01的瞬时半径26,480.9 km与a相差仅数百km——这正是真实GPS的偏心率(约0.005–0.02)所造成的。测试tests/tutorials.rs::tutorial1_satellites_are_in_the_gps_meo_shell针对这一公开发布的a断言26000 km < |r(PG01)| < 27200 km,而该值独立于Kshana之外。

2. 过境时长是GPS绕地一圈。开普勒第三定律给出周期T = 2π√(a³/μ),其中a = 26,560 km、μ = 398,600.4418 km³/s²(世界大地坐标系1984,WGS-84;美国国家影像与测绘局技术报告NIMA TR8350.2):T = 43,078 s = 11.967 h,即半个恒星日。场景时长43,200 s(“约一个GPS圈”)与此吻合,偏差小于0.3 %;并且依据IS-GPS-200,GPS星下点轨迹每个恒星日重复一次(两圈)。

3. 外推得到的位置经独立外部参考核对,而非仅自洽。生成这张ECEF表的SGP4/SDP4外推器与全部666个AIAA(美国航空航天学会)2006-6753验证向量一致,最坏情况为4.12 mm(tests/sgp4_verification.rs,docs/SGP4-VALIDATION.md),并与独立的sgp4 crate在亚微米量级上吻合。因此,你导出的这张表是对照外部参考实现核对的,而不是对照Kshana自己的运算。

关于SP3日期的说明。SP3历元头部显示的是一个占位日历日期(2000-01-01);外推实际上从各TLE自身的历元(2021)开始。请把这张表理解为“第一个采样步的ECEF位置”,而不是“2000年一月1日的位置”。

测试固定了什么#

tests/tutorials.rs把上面每个数字都变成一项CI约定:

  • tutorial1_orbit_headline_holds——best_pdop ≈ 1.071、best_position_sigma_m == best_pdop(因为sigma_uere_m = 1.0)、samples_total == 361,且摘要包含345/361。
  • tutorial1_satellites_are_in_the_gps_meo_shell——PG01的半径位于GPS壳层范围内,并对照公开发布的a = 26,560 km核对。

一旦引擎不再产生真实的GPS壳层,构建就会变红。

易错点与单位#

  • 位置sigma是PDOP × UERE,而不是PDOP。两者相等,只是因为此处sigma_uere_m = 1.0。改变UERE,它们就会分开。
  • 授时数值以纳秒为单位,位置数值以米为单位。不要混用。
  • holdover_s是按网格量化的(即时间网格步长上的下界)。在本次过境中,用户基本始终处于可定位状态,因此守时(holdover)为0 s(没有需要滑行度过的中断)——这是好的情形。

接下来去哪里#

  • 收紧或放宽高度截止角(mask_deg),观察可用性如何变化——这是第2级的练习。
  • 用scripts/fetch_tles.sh换入新的TLE快照(第2级“使用最新数据”)。
  • 继续学习教程2——时钟守时:在那里GNSS信号被撤走,星载时钟必须独自滑行。