Tutorial 1 — A minha primeira órbita: onde estão os satélites GPS
Kind: orbit · Cenário: scenarios/orbit-sgp4-gps.toml (cópia didática: scenarios/orbit.toml) · Dificuldade: principiante · ~15 min
No final, terá propagado a constelação GPS operacional real, lido a sua disponibilidade e geometria e exportado uma tabela de onde cada satélite está realmente no espaço — e saberá que essa tabela é validada face a uma referência externa, não face a si própria.
O que é este cenário#
Os satélites GPS (Global Positioning System) dizem a um utilizador onde está e que horas são. Antes de tudo isso, é preciso saber onde estão os satélites e quantos deles um utilizador consegue ver. Isso é geometria, e a geometria estabelece o limite mínimo da exatidão com que se pode ser posicionado (a diluição da precisão, ou DOP). Este tutorial:
- toma um instantâneo genuíno
gps-opsdo Celestrak da constelação GPS (2021-07-28, 30 satélites, elementos de duas linhas reais, TLE), - propaga cada satélite com o modelo SGP4/SDP4 validado (Simplified General Perturbations 4 / Simplified Deep-space Perturbations 4),
- em cada passo de tempo calcula que satélites um utilizador em órbita terrestre baixa consegue ver (linha de vista, ocultação pela Terra e uma máscara de elevação de 5°),
- transforma essa geometria num PDOP (diluição da precisão da posição) e numa exatidão de posição, e
- exporta as posições efetivas dos satélites, centradas na Terra e fixas à Terra (ECEF), para um ficheiro SP3 (Standard Product 3, o formato de órbita precisa do International GNSS Service, IGS; GNSS é Global Navigation Satellite System).
A espinha dorsal é: TLE → propagação SGP4 → ECEF por época → visibilidade → número de satélites visíveis → PDOP → sigma da posição = PDOP · σ_UERE, em que σ_UERE é o erro equivalente de distância do utilizador (o erro de medição de distância de 1-σ por satélite).
Execute-o#
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"])
Ou abra o Studio no navegador e escolha o cenário de órbita.
Ler o resumo de uma linha#
A execução determinística (seed = 17) imprime:
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)
Campo a campo:
scenario 4c51512369a6— o hash do cenário, de 12 carateres. Identifica as entradas exatas (seed, limiares, parâmetros do modelo, o bloco TLE). Altere qualquer entrada e este valor muda; mantenha-as iguais e reproduz a execução bit a bit. O mesmo hash está carimbado no rodapé do gráfico e no ficheiro JSON (JavaScript Object Notation) do resultado.345/361 samples GNSS-nominal— dos 361 passos de tempo, o utilizador tem uma solução de posição utilizável em 345 (95,6 %). A execução é uma passagem de 12 h (43 200 s) com um passo de 120 s.best PDOP 1.07— a melhor diluição da precisão da posição (a mais baixa) ao longo da passagem. Um PDOP próximo de 1 é uma geometria excelente; quanto mais baixo, melhor.pos 1.07m— a melhor exatidão de posição: sigma da posição = PDOP · σ_UERE. Neste cenáriosigma_uere_m = 1.0, pelo que os dois números são numericamente iguais aqui — mas a regra é PDOP × UERE, não “posição = PDOP.” Com um UERE de 3 m, o sigma da posição seria ~3,2 m. (Ver a armadilha no final.)- Os valores do relógio (
holdover,p95,integrity,security) aparecem porque o pacote de órbita também transporta um relógio ao longo da passagem; são o foco do Tutorial 2, não deste. (securitylê-sen/a (no attack)porque nenhum ataque está configurado.)
O bloco de geometria no JSON contém os números subjacentes:
"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
}
Onde estão os satélites? (a recompensa)#
A geometria é boa porque os satélites estão realmente na camada GPS. Prove-o — exporte as suas posições fixas à Terra:
cargo run -- scenarios/orbit-sgp4-gps.toml --export-sp3 gps.sp3
Os três primeiros satélites no primeiro passo de amostragem, ECEF em km (o ficheiro SP3 traz uma quarta coluna, de relógio, escrita com o marcador de “sem valor” 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
Tome o raio geocêntrico do PG01:
|r(PG01)| = sqrt(9771.575585^2 + 24612.128830^2 + 0.003744^2) = 26480.9 km
A referência independente não circular: é mesmo uma órbita GPS?#
Um tutorial que verifica o motor face a si próprio não prova nada. Eis a âncora externa e não circular para cada afirmação acima.
1. Os satélites situam-se na camada real da órbita terrestre média (MEO) do GPS. O semieixo maior nominal do GPS é a = 26 560 km, altitude ≈ 20 180 km acima do raio médio da Terra de 6 378 km (IS-GPS-200, a especificação de interface do GPS; o GPS Standard Positioning Service (SPS) Performance Standard, Departamento de Defesa dos EUA (DoD); Misra & Enge, Global Positioning System, 2.ª ed.). O raio instantâneo do PG01, de 26 480,9 km, situa-se a algumas centenas de km de a — exatamente o que a excentricidade real do GPS (~0,005–0,02) produz. O teste tests/tutorials.rs::tutorial1_satellites_are_in_the_gps_meo_shell afirma 26000 km < |r(PG01)| < 27200 km face a este a publicado, que é externo ao Kshana.
2. A duração da passagem é uma revolução GPS. A terceira lei de Kepler dá o período T = 2π√(a³/μ) com a = 26,560 km e μ = 398,600.4418 km³/s² (World Geodetic System 1984, WGS-84; relatório técnico NIMA TR8350.2 da National Imagery and Mapping Agency): T = 43,078 s = 11.967 h, meio dia sideral. A duração do cenário de 43 200 s (“~uma revolução GPS”) coincide com isso a menos de 0,3 %, e a projeção no solo do GPS repete-se a cada dia sideral (duas revoluções), segundo a IS-GPS-200.
3. As posições propagadas são validadas, não apenas autoconsistentes. O propagador SGP4/SDP4 que produziu esta tabela ECEF coincide com todos os 666 vetores de verificação AIAA (American Institute of Aeronautics and Astronautics) 2006-6753 até um pior caso de 4,12 mm (tests/sgp4_verification.rs, docs/SGP4-VALIDATION.md) e coincide com a crate independente sgp4 a menos de um mícron. Assim, a tabela exportada é verificada face a uma implementação de referência externa, não face à aritmética do próprio Kshana.
Uma nota sobre as datas do SP3. O cabeçalho de época do SP3 mostra uma data de calendário provisória (2000-01-01); a propagação decorre, na realidade, a partir da época própria de cada TLE (2021). Leia a tabela como “posições ECEF no primeiro passo de amostragem”, não “em 1 de janeiro de 2000.”
O que o teste fixa#
tests/tutorials.rs transforma cada número acima num contrato de CI:
tutorial1_orbit_headline_holds—best_pdop ≈ 1.071,best_position_sigma_m == best_pdop(porquesigma_uere_m = 1.0),samples_total == 361, e o resumo contém345/361.tutorial1_satellites_are_in_the_gps_meo_shell— o raio do PG01 está na banda da camada GPS, verificado face aoa = 26,560 kmpublicado.
Se o motor alguma vez deixar de produzir uma camada GPS real, a compilação fica vermelha.
Armadilhas e unidades#
- O sigma da posição é PDOP × UERE, não PDOP. Os dois são iguais apenas porque
sigma_uere_m = 1.0aqui. Altere o UERE e separam-se. - Os valores de temporização estão em nanossegundos, o valor de posição em metros. Não os misture.
holdover_sé quantizado pela grelha (um limite inferior ao passo da grelha de tempo). Nesta passagem o utilizador está essencialmente sempre com solução de posição, pelo que o holdover é 0 s (sem interrupção a atravessar) — esse é o caso bom.
Para onde ir a seguir#
- Aperte ou alargue a máscara de elevação (
mask_deg) e veja a disponibilidade mudar — é um exercício de Nível 2. - Substitua por um instantâneo TLE novo com
scripts/fetch_tles.sh(Nível 2 “utilizar dados novos”). - Avance para o Tutorial 2 — Holdover do relógio, onde o sinal GNSS é retirado e o relógio de bordo tem de navegar em inércia.