Kshana — Arquitetura
O Kshana é um só motor organizado em camadas sobre um núcleo compartilhado: os pacotes de sensores (relógio, inercial, transferência de tempo, híbrido); uma camada de astrodinâmica / numérica (SGP4/SDP4 analítico (SGP4: Simplified General Perturbations 4; SDP4: Simplified Deep-space Perturbations 4), um propagador numérico de Cowell com seu modelo de forças de sete perturbações, projeto de manobras, determinação de órbita a partir de distâncias de estações terrestres e o ajuste do modelo de forças contra efemérides precisas de agências); uma camada de tempo e referencial (escalas de tempo do IERS (International Earth Rotation and Reference Systems Service), precessão–nutação IAU (International Astronomical Union) 2006/2000A e a redução CIO (Celestial Intermediate Origin) GCRS↔ITRS (GCRS: Geocentric Celestial Reference System; ITRS: International Terrestrial Reference System)); uma camada de fusão (os estimadores GNSS/INS (GNSS: sistema global de navegação por satélite; INS: sistema de navegação inercial)); e as camadas de integridade, resiliência, PNT alternativo (PNT: posicionamento, navegação e temporização) e lunar (RAIM/ARAIM/SBAS (RAIM: monitoramento autônomo de integridade pelo receptor; ARAIM: monitoramento autônomo avançado de integridade pelo receptor; SBAS: sistema de aumento baseado em satélites), jamming e detecção de spoofing em várias camadas, correspondência de mapas de gravidade/terreno/magnéticos e PNT cislunar); e as camadas mais novas LEO-PNT (PNT em órbita baixa da Terra), espectro, sistema solar e projeto de constelações, temporização de rede e campanha, com os gravadores de relatório, animação e interoperabilidade que toda execução pode usar (§1d). Em todas elas, o motor nada sabe sobre "quântico" versus "clássico": ele conduz modelos de erro de sensores por um cenário de interrupção de GNSS, executa um estimador e pontua o resultado. Um dispositivo quântico e um clássico são, portanto, comparados no mesmo cenário, diferindo apenas em seus parâmetros de erro (publicados, citados) e em suas sementes de ruído independentes.
Este documento reúne os diagramas estruturais e comportamentais. A §1 é o núcleo de pacotes de sensores; a §1a mapeia as camadas de astrodinâmica, fusão e PNT alternativo acrescentadas desde então; as §1b–§1d, as camadas de estudo, de domínio e de saída. Para o uso, veja o README; para o que é e o que não é validado, veja VALIDATION; para a tabela de maturidade por capacidade, veja CAPABILITY.
Abreviações usadas nos diagramas e não explicadas onde aparecem: ADEV, desvio de Allan; BW, largura de banda; CAI, interferômetro de átomos frios; CZML, a Cesium Language; Δ-DOR, medição de distância unidirecional diferencial delta; DO-229E, o padrão de receptor SBAS da RTCA (Radio Technical Commission for Aeronautics); EKF, filtro de Kalman estendido; FM, modulação em frequência; GSE, equipamento de apoio em solo; HPL/VPL, nível de proteção horizontal/vertical; IMU, unidade de medição inercial; IOAG, Interagency Operations Advisory Group; IQ, amostras em fase/quadratura; ISL, enlace entre satélites; ITU-T, o Setor de Normalização das Telecomunicações da União Internacional de Telecomunicações; J2–J6, os harmônicos gravitacionais zonais da Terra de grau 2 a 6; KIF, o Kshana Interchange Format; KML, Keyhole Markup Language; KPI, indicador-chave de desempenho; L1/L5, bandas de portadora GNSS (o L2 das órbitas halo do CR3BP é, em vez disso, o ponto de Lagrange Terra–Lua 2); LEO, órbita baixa da Terra; LOO, deixar um de fora; LTC, Tempo Lunar Coordenado; MEO, órbita terrestre média; MTIE, erro máximo de intervalo de tempo; N2, o número de diversidade de Hill de ordem 2; NED, norte-leste-baixo; NTN, rede não terrestre; OD, determinação de órbita; OPS-SAT, o satélite-laboratório de software em órbita da Agência Espacial Europeia; PPP, posicionamento preciso por ponto; PSD, densidade espectral de potência; PVT, posição, velocidade e tempo; RINEX, Receiver Independent Exchange Format; RK4 / RK5(4), integradores de Runge–Kutta de quarta ordem e de quinta(quarta) ordem embutida; SH, harmônico esférico; SigMF, Signal Metadata Format; SIR, reamostragem por importância amostral; SRIF, filtro de informação de raiz quadrada; SRP, pressão de radiação solar; SSC, coeficiente de separação espectral; STK, Systems Tool Kit; SVG, Scalable Vector Graphics; TDEV, desvio de tempo; TDM, o Tracking Data Message do CCSDS (Consultative Committee for Space Data Systems); TLE, conjunto de elementos de duas linhas; TPL, Timing Protection Level; UBX, o protocolo binário da u-blox; UHF, frequência ultra-alta; VLBI, interferometria de linha de base muito longa; VRW / ARW, passeio aleatório de velocidade / ângulo; WASM, WebAssembly.
1. Estrutura de módulos#
flowchart TD
main["main.rs<br/>CLI (thin wrapper)"]
py["python.rs<br/>PyO3 (feature)"]
wasm["wasm.rs<br/>wasm-bindgen (feature)"]
api["api.rs<br/>run_toml: parse · dispatch by kind · json+svg+summary"]
subgraph shared["Shared core"]
types["types.rs<br/>Seconds · TimeGrid · ModelSpec"]
scenario["scenario.rs<br/>GnssState · GnssTimeline · ClockCfg · Scenario"]
allan["allan.rs<br/>overlapping Allan deviation"]
end
subgraph pack1["Pack 1 · Clock holdover"]
models["models.rs<br/>ErrorModel · ClockModel (incl. flicker FM)"]
estimator["estimator.rs<br/>HoldoverEstimator"]
kalman["kalman.rs<br/>KalmanClock → Integrity bound"]
security["security.rs<br/>clock-aided spoof detection → Security"]
fom["fom.rs<br/>Sample · FoMScores · score · worst_case_holdover"]
report["report.rs<br/>RunResult · hash · to_svg"]
run["run.rs<br/>run / run_clock / run_orbit_clock"]
end
inertial["inertial/<br/>Pack 2 · AccelModel (accel + gyro + bias instability/RW) · run_inertial · quantum_imu CAI + QuantumNavBudget dead-reckoning-over-holdover"]
timetransfer["timetransfer.rs<br/>Pack 3 · TimeTransferLink · run_timetransfer"]
hybrid["hybrid.rs<br/>Pack 4 · run_suite · score_hybrid · run_hybrid (+ integrity/security)"]
fusion["fusion/<br/>joint Kalman PNT estimator · run_fusion"]
orbit["orbit.rs<br/>Propagator (Kepler | SGP4) · Walker / TLE / multi-constellation · visibility · DOP"]
tle["tle.rs<br/>two-line element parsing (line 2 → Kepler, full TLE → SGP4)"]
sgp4mod["sgp4.rs<br/>SGP4 / SDP4 propagator (deep-space + resonance)"]
ensemble["ensemble.rs<br/>Monte Carlo confidence bands"]
sweep["sweep.rs<br/>trade-study parameter sweeps"]
spoof["spoof.rs<br/>active spoofing-attack demonstrator"]
jamming["jamming.rs<br/>link-budget anti-jam C/N₀ (J/S · processing gain · Q)"]
navsignal["navsignal.rs<br/>signal level: BPSK-R / BOC PSD · SSC κ · Gabor BW · DLL jitter · multipath · ranging-code (m-seq/Gold) design-trade"]
holdover["holdover.rs<br/>GNSS-denied clock holdover: van-Loan coast → holdover-to-threshold · quantum-clock classes"]
verification["verification.rs<br/>machine-checked requirement→module→test→oracle→status matrix"]
main --> api
py --> api
wasm --> api
api --> run
api --> inertial
api --> timetransfer
api --> hybrid
api --> ensemble
api --> sweep
api --> fusion
api --> spoof
spoof --> security
api --> jamming
api --> holdover
api --> verification
navsignal -. derives anti-jam Q (κ → Q=1/(R_c·κ)) .-> jamming
jamming -. uses PSD / SSC .-> navsignal
holdover -. coast-variance vs van-Loan recursion .-> kalman
ensemble --> run
sweep --> run
orbit --> tle
tle --> sgp4mod
orbit -. SGP4 propagator .-> sgp4mod
fusion -. composes .-> models
fusion -. composes .-> inertial
fusion --> kalman
run --> models
run --> estimator
run --> kalman
run --> security
run --> fom
run --> report
run --> orbit
models --> types
scenario --> types
inertial --> scenario
timetransfer --> types
orbit --> scenario
hybrid -. composes .-> models
hybrid -. composes .-> estimator
hybrid -. composes .-> inertial
hybrid -. composes .-> timetransfer
pack1 --> shared
inertial --> allan
A CLI (interface de linha de comando) e ambos os bindings passam por um único ponto de entrada api::run_toml, de modo que nunca divergem. Os pacotes reutilizam o núcleo compartilhado (types, scenario, allan); o Pacote 4 (hybrid) compõe os modelos e estimadores dos Pacotes 1–3 em vez de reimplementá-los; orbit deriva uma linha do tempo GNSS a partir da geometria, que então alimenta a execução do Pacote 1. O módulo navsignal fica no nível de sinal entre o orçamento de enlace e o domínio de medição: ele deriva o coeficiente de separação espectral κ a partir dos espectros de potência reais do sinal e do jammer, a partir do qual jamming agora calcula seu Q = 1/(R_c·κ) antijam, em vez de tomar uma constante representativa (conferido em CI (integração contínua)); ele também traz o compromisso de projeto de código de distanciamento (sequência m/Gold).
Mais três módulos formam a espinha dorsal de resiliência sem GNSS. holdover responde diretamente à pergunta operacional — por quanto tempo este relógio pode correr livre antes que seu erro de temporização exceda o orçamento? — expondo a forma fechada de erro de deriva de van Loan como uma inversão de holdover até o limiar, conferida contra a recursão de covariância de vários passos de clock_state. Seu par inercial está em inertial::quantum_imu (QuantumNavBudget), que compõe a deriva de ruído branco do interferômetro de átomos frios com o erro de viés e de fator de escala em um orçamento de deriva de posição durante o holdover (o termo de viés conferido contra o integrador independente AccelModel). verification renderiza toda a matriz do motor de requisito para módulo, teste, referência independente e estado, com invariantes testados por unidade que proíbem um rótulo validado sem uma referência independente externa — de modo que a afirmação de garantia não pode se afastar do código.
1a. Camadas de astrodinâmica, fusão e PNT alternativo#
Além do núcleo de pacotes de sensores, três subsistemas compartilham o mesmo núcleo e alimentam (ou são alimentados por) orbit. A camada de astrodinâmica / numérica acrescenta um propagador de Cowell não analítico ao lado do caminho analítico SGP4/SDP4; a camada de fusão traz os estimadores GNSS/INS; e a camada de PNT alternativo é a correspondência de mapas de gravidade com GPS (Global Positioning System) negado. Estas são capacidades de biblioteca/cenário (veja CAPABILITY para saber quais estão ligadas a um tipo de cenário (kind) e quais são acessíveis como uma API (interface de programação de aplicações) Rust).
flowchart TD
subgraph astro["Astrodynamics & numerical"]
orbit2["orbit · sgp4 · tle · walker<br/>analytic SGP4/SDP4 · Walker design"]
prop["propagator<br/>Cowell driver (accel_at / accel_rv)"]
forces["forces<br/>two-body · J2–J6 · EGM2008 d/o-70 · 3rd-body · SRP · drag · Schwarzschild + Lense–Thirring · tides"]
integ["integrator<br/>RK4 step-doubling · Dormand–Prince RK5(4)"]
ephem["ephem<br/>low-precision Sun & Moon"]
man["maneuver<br/>impulsive/finite burns · Izzo Lambert · porkchop"]
od["orbit_determination<br/>Gauss–Newton batch (batch_ls) · sequential UKF"]
end
subgraph fusion["Fusion (GNSS/INS)"]
ekf["fusion/gnss_ins_ekf · closed_loop · pack<br/>15-state loosely-coupled EKF"]
tc["fusion/tightly_coupled (8-state)<br/>fusion/tightly_coupled17 (17-state, quantum-CAI)"]
ukf["fusion/ukf — sigma-point core"]
coup["fusion/coupled — clock+position cross-covariance"]
end
subgraph alt["Alt-PNT (GPS-denied)"]
grav["gravimeter<br/>cold-atom model + SH anomaly field + mascons"]
pf["particle_filter — SIR"]
mm["mapmatch — field-match likelihood"]
end
prop --> forces
prop --> integ
forces --> ephem
man --> integ
od --> forces
od --> integ
od --> ukf
tc --> ukf
tc -. coasts on .-> forces
grav --> pf
mm --> pf
grav --> mm
ekf -. drives .-> strap["inertial/ strapdown (quaternion · NED · IMU errors)"]
tc -. drives .-> strap
grav -. CAI floor .-> strap
Os termos de força do propagador numérico vêm desligados por padrão, de modo que ativá-los nunca perturba os goldens publicados. O filtro de Kalman unscented (UKF) de 17 estados, fortemente acoplado, atravessa uma interrupção de GNSS com o passeio aleatório de velocidade derivado do acelerômetro CAI quântico; a determinação de órbita reutiliza os mesmos forces/integrator para propagar um estado candidato ao longo do arco de rastreamento.
O mesmo núcleo compartilhado traz ainda quatro subsistemas não desenhados acima (seus pacotes aparecem no despacho da §4): uma camada de tempo e referencial (timescales, jd2, precession, nutation, cio, frames, eop) que reduz TEME↔GCRS↔ITRS (TEME: equador verdadeiro, equinócio médio) e alimenta o pacote ephemeris/traço no solo; uma camada de integridade (raim, sbas) para RAIM/ARAIM/SBAS; uma camada de resiliência (jamming, spoof, spoof_detect, spoof_monitors, detection) para jamming e detecção de spoofing em várias camadas, com uma camada de sinal de navegação (navsignal) no nível de sinal — densidades espectrais de potência BPSK-R (BPSK: modulação por chaveamento de fase binário) / BOC (BOC: portadora de deslocamento binário) senoidal, o coeficiente de separação espectral κ que agora deriva o Q antijam de jamming, a largura de banda de distanciamento RMS (Gabor), o jitter de rastreamento de código do DLL (malha de travamento de atraso) coerente adiantado–atrasado e o envelope de erro de multipercurso (análise de desempenho de sinal, não projeto de carga útil de RF (RF: radiofrequência) / hardware de antena — papel de um parceiro de carga útil); e uma camada lunar / cislunar (lunar, lunar_frame, lunar_od, cr3bp) para a dinâmica do CR3BP (problema circular restrito de três corpos) — incluindo a matriz de transição de estado 6×6 e um corretor diferencial de tiro único (cr3bp_jacobian, propagate_state_stm, differential_correct_halo) que produz órbitas halo/NRHO (NRHO: órbita halo quase retilínea) genuinamente periódicas, reproduzindo a NRHO sul L2 9:2 publicada (a órbita do Gateway) com período ≈ 6,57 d / perilúnio ≈ 3.250 km (publicado ≈ 6,56 d / ≈ 3.370 km); a transformação MCI/MCMF selenocêntrica (MCI: inercial centrado na Lua; MCMF: centrado e fixo na Lua) de uma órbita corrigida e a continuação de famílias continuam como etapas seguintes, e a NRHO é uma solução do CR3BP (circular, sem Sol), não validada contra uma efeméride real do LANS/Gateway (LANS: Lunar Augmented Navigation Service) — e a integridade do LunaNet. O ajuste do modelo de forças às efemérides de agências (precise_od, lunar_od, tides, gravity_sh) e o conjunto completo de campos de PNT alternativo (igrf, altpnt/terrain, gravimeter) completam a lista de módulos; veja CAPABILITY para a maturidade por módulo.
1b. Estudos de resiliência, avaliação de aprendizado de máquina e artefatos reprodutíveis#
Mais cinco grupos de módulos formam a camada aberta de estudos reprodutíveis por trás dos artigos de pesquisa do projeto. Ao contrário dos tipos de cenário (kind), estes são alcançados como geradores cargo run --example / --bin que gravam artefatos determinísticos byte a byte (sementes fixas, versão do motor e hash da configuração registrados). Todos são MODELLED (calibração sintética ou de conjunto de dados público) e trazem rótulos de validação honestos — nenhum é uma certificação.
flowchart TD
gen["study generators<br/>examples/ · bin/ (cargo run) → byte-deterministic artifacts"]
subgraph timing["Timing integrity"]
tplm["tpl<br/>conditional Timing Protection Level: k-σ floor · van-Loan coast · CUSUM"]
end
subgraph resilm["Resilience scoring & decision-instability"]
arch["resilience/arch · score<br/>architecture model + RPCF-aligned scoring"]
stats["resilience/stats<br/>Dirichlet · Kendall-τ · flip-rate · bootstrap"]
div["resilience/diversity · timeline<br/>Hill-N2 common-mode collapse · KPIs"]
study["resilience/study · report · panel<br/>instability study + integrity-hashed assurance report"]
end
subgraph aiml["RF-impairment optimism-gap (Machine learning)"]
ie["impairment_eval<br/>labelled synthetic corpus · ROC/AUC harness"]
is["impairment_study<br/>13-detector panel · scaling laws · LOO predictor"]
ml["impairment_ml<br/>logistic-regression + one-hidden-layer MLP"]
es["eval_stats<br/>bootstrap CI · DeLong · Spearman · ridge"]
sdrm["sdr · realdata<br/>IQ/IF → E/P/L taps → SQM + ingest adapters"]
end
subgraph trade["Quantum-vs-classical"]
cross["crossover<br/>resilience crossover map under parameter uncertainty"]
qt["quantum_trade<br/>measured-ADEV holdover benefit vs classical"]
end
gen --> timing
gen --> resilm
gen --> aiml
gen --> trade
tplm -. cross-checked vs .-> recursion["holdover · clock_state · allan"]
is --> ie
is --> ml
is --> es
ie -. real recordings via .-> sdrm
cross -. composes .-> packs2["clock · inertial packs"]
tpl— o Timing Protection Level condicional: um limite limitado por holdover para o erro de tempo não detectado sob spoofing, que compõe um piso de monitor de k-σ, a variância de deriva de van Loan sobre a latência de detecção e um tempo até o alarme de CUSUM (soma cumulativa); calibrado em um spoof real gravado (JammerTest 2024). Não existe limite incondicional finito — o TPL é condicional a que uma verificação cruzada independente detecte o ataque.resilience/— um motor de pontuação de resiliência PNT alinhado a referenciais (categorias do RPCF (Resilient PNT Conformance Framework) do DHS (Department of Homeland Security)) mais um estudo de instabilidade de decisão: um simplex de ponderação de Dirichlet, instabilidade de ranking de Kendall-τ, taxa de troca do vencedor top-1 e colapso de diversidade de modo comum (Hill-N2), com um relatório de garantia com hash de integridade e 35 testes de referência independente derivados à mão. Veja RESILIENCE-CROSSWALK. Arquiteturas sintéticas alinhadas ao RPCF v2.0 — uma autoavaliação, não uma certificação.impairment_eval/impairment_study/impairment_ml/eval_stats— o estudo da lacuna de otimismo de degradações de RF: um corpus sintético rotulado e um arcabouço ROC/AUC (ROC: característica de operação do receptor; AUC: área sob a curva) independente de detector, um painel de 13 detectores (energia/AGC/SQM/paridade (AGC: controle automático de ganho; SQM: monitoramento de qualidade de sinal) mais detectores de regressão logística e de MLP (MLP: perceptron multicamadas) de uma camada oculta, com sementes), leis de escala dentro e fora da distribuição com uma hipótese nula por permutação, e um preditor leave-one-out da degradação fora da distribuição. As métricas de avaliação são validadas bit a bit contra o scikit-learn.sdr/realdata— um front end de receptor definido por software (IQ/IF bruto (IQ: em fase/quadratura; IF: frequência intermediária) → derivações adiantada/imediata/atrasada do correlator → SQM) e adaptadores de ingestão (RINEX, u-blox UBX, GnssLogger, JammerTest, Yunnan, SatGrid) que deixam os mesmos detectores rodarem sobre gravações fornecidas localmente; nenhum conjunto de dados é versionado no repositório.crossover/quantum_trade— o mapa de cruzamento de resiliência quântico contra clássico sob incerteza de parâmetros, e o compromisso de benefício de holdover com ADEV medido; os núcleos numéricos do compromisso são validados contra o scipy.
1c. Camadas de integridade, GNSS, espaço profundo, lunar e de missão#
Os demais domínios se conectam ao mesmo despacho api e reutilizam o núcleo compartilhado, os referenciais e a geometria. Tudo aqui é MODELLED, a menos que uma linha da matriz verification cite uma referência independente externa (núcleo RAIM contra o SciPy, SBAS contra o fork do RTKLIB (uma biblioteca de código aberto de posicionamento cinemático em tempo real), o núcleo de DOP (diluição da precisão) do gnss_lib_py, a avaliação OPS-SAT, o núcleo de nível de proteção ARAIM lunar, a consistência de efemérides lunares entre provedores) — o restante da suíte lunar e o demonstrador quântico são modelados, ilustrativos, de fonte pública, e não trazem nenhuma afirmação de TRL (nível de maturidade tecnológica) / herança / endosso de agência.
flowchart TD
api["api.rs — run_toml / run_scenario · 92 kinds"]
subgraph gnss["Integrity & GNSS measurement"]
raim["raim — RAIM/ARAIM · HPL/VPL (kernel vs SciPy)"]
sbas["sbas — DO-229E PL · L1/L5 (vs RTKLIB fork)"]
meas["gnss_sim · ionex · pvt · glonass — pseudorange · iono maps · single-point PVT"]
imp["integrity_impact · frugal — miss→integrity · cost-per-coverage"]
end
subgraph deep["Deep-space & Mars"]
core2["body · ephem_provider · clock_state — multi-body · ephemeris seam · onboard clock"]
radio["radiometric · ccsds_tdm — light-time · Doppler/range · Δ-DOR · TDM"]
mars["deepspace_od · mars_frame · mars_atmos · mars_pnt · linkbudget · gse_sim — SRIF OD · Mars frame · relay-PNT · GSE sim"]
end
subgraph lunar["Lunar PNT suite (evidence tier per piece in the matrix · illustrative public-source)"]
cis["cr3bp · lunar · lunar_frame · lunar_od — CR3BP · halo/NRHO · cislunar ARAIM · MCI↔MCMF"]
suite["lunar_time · lunar_vlbi · lunar_combination · lunar_frame_realise — LTC time · VLBI · joint OD+clock · frame realisation"]
suite2["lunar_service · lunar_dpnt · lunar_interop — Moonlight service-volume · differential PNT · LunaNet/IOAG interop"]
end
subgraph quantum["Quantum-Enabled PNT demonstrator (MODELLED)"]
qd["quantum_devices · quantum_faults · quantum_nav_od — device error models · fault catalogue · GNSS-free OD"]
qt["qtrade · timetransfer_chain · representativeness — unified trade · time-transfer chain · gaps-to-flight ledger"]
end
subgraph mission["Mission analysis, environment & interop"]
ma["launch · reentry · eo_payload · attitude_budget · passes · linkbudget — first-order budgets"]
env["space_weather — Jacchia-71 density"]
iop["rinex · rinex_obs · sp3 · oem · omm · ccsds_tdm · space_packet · interchange · permalink — interop formats + KIF"]
ver["verification — requirement→module→test→oracle→status matrix"]
end
api --> gnss & deep & lunar & quantum & mission
raim -. reuses .-> meas
suite -. reuses validated DOP / SBAS kernels .-> gnss
qt -. rides validated kernels (scipy / sklearn) .-> quantum
1d. LEO PNT, espectro, sistema solar, temporização de rede, campanhas e saídas#
As camadas mais novas seguem o mesmo padrão: cada uma é um ou mais tipos de cenário (kind) despachados a partir de api, construídos sobre o núcleo compartilhado, e MODELLED, a menos que uma linha da matriz nomeie uma referência independente externa.
flowchart TD
api["api.rs — run_toml / run_scenario"]
subgraph leo["LEO PNT (low Earth orbit positioning, navigation and timing)"]
lsig["leo_signal — signal design: acquisition, code tracking, GNSS compatibility, band trade"]
lpass["leo_pass · leo_link (geometry · antenna · itu · iono · energy · spoof · presets) — pass and per-band link budget"]
lnav["leo_navmsg (elements · fit · codec · sisre · services · text) — broadcast ephemeris and clock message"]
lfus["leo_fusion (doppler · joint_pvt · ppp · ntn · timing · polar · presets) — fused MEO+LEO PVT · PPP · 5G NTN"]
lchain["leo_pnt_chain — one system end to end, each stage handing its output to the next"]
end
subgraph rf["Spectrum"]
spec["spectrum · navsignal — L-band (and UHF/S/C) PSD waterfall under a jammer timeline"]
sig["sigmf — SigMF recording read/write · Welch PSD of complex IQ"]
end
subgraph sky["Solar system & constellations"]
ss["solar_system · body · ephem · ephem_provider — bodies, constants, light time at one epoch"]
bp["body_pnt — positioning around any body with a local constellation"]
cd["constellation · walker — Walker delta/star, multi-shell, published GNSS slots, coverage/DOP maps"]
end
subgraph net["Network timing"]
tel["telecom_timing — time error, MTIE, TDEV vs ITU-T masks"]
slot["slot_timing — seconds until a free-running clock leaves a slot guard"]
end
subgraph comp["Composition & outputs"]
camp["campaign · study · suite — chained phases, sweeps, Monte Carlo, shared conditions"]
rep["advanced_report — report.html + report.json with a reproducibility record"]
anim["animation — SVG / HTML / frame animations"]
iop["interop (czml · kml · geojson · stk) · sigmf — exchange files for --export"]
end
api --> leo & rf & sky & net & comp
lchain -. composes .-> lsig & lpass & lnav & lfus
lsig -. SSC chain .-> spec
lfus -. GNSS presets .-> cd
bp -. reuses .-> ss
camp -. runs other kinds through .-> api
O detalhe por tipo de cenário está em LEO-PNT, LEO-SIGNAL, LEO-PASS, LEO-NAVMSG, LEO-PNT-FUSION, SPECTRUM, CONSTELLATION-DESIGN, TELECOM-TIMING, SLOT-TIMING, CAMPAIGNS, REPORTS, ANIMATION e INTEROP.
1e. Camadas de confiança do receptor, evidências, telemetria, treinamento e compliance (0,35)#
Estas camadas leem o log do próprio receptor ou gravam arquivos para outras ferramentas; nenhuma delas sintetiza ou transmite um sinal de radiofrequência. Elas ficam ao lado de api e não sob os tipos de cenário, exceto o próprio receiver-trust, que é um tipo de cenário. Todas são MODELLED, a menos que uma linha da matriz nomeie uma referência independente externa, e as saídas marítimas são consultivas, não um equipamento de navegação homologado.
| Módulo | O que faz | Documentado em |
|---|---|---|
receiver_trust |
pontua um log de receptor época a época com os monitores de confiança; uma plataforma de embarcação acrescenta os monitores marítimos e a pontuação de 0-100 com motivos | RECEIVER-TRUST, MARITIME-TRUST |
receiver_trust::live |
a mesma pontuação sobre um fluxo à medida que chega (stdin, um arquivo em acréscimo, TCP ou UDP), a sentença $PKSHT e o portão opcional; LiveEngine é o todo disso, sem entrada nem saída |
MARITIME-TRUST |
evidence |
um pacote assinado e encadeado por hash de uma janela de log, sua configuração e o resultado do motor, verificável offline; token de carimbo de tempo RFC 3161 opcional | EVIDENCE-PACKS |
telemetry |
o fluxo de confiança como métricas Prometheus, eventos syslog (CEF ou LEEF) e OpenTelemetry opcional (recurso otlp, desativado por padrão) |
TRUST-TELEMETRY |
nmea_synth |
ponte NMEA 0183 sintética com eventos roteirizados de jamming, arrasto (drag-off), falsificação de tempo e repetição (replay) e um registro do instrutor, para treinamento de tripulações (somente texto) | NMEA-TRAINING |
interference_map |
mapas agregados de navegação degradada a partir de relatórios de aeronaves e navios com licença aberta, e a exposição de uma rota a eles; somente arquivos locais | INTERFERENCE-MAP |
osnma |
um verificador do lado do receptor para o OSNMA do Galileo: lê páginas I/NAV (páginas simples, CSV vetorial, um fluxo UBX), verifica a chave assinada, a cadeia TESLA e os MACs, e informa por satélite se os dados de navegação estão autenticados; osnma::cli::verify_report é o único caminho que a linha de comando, o Python e o WebAssembly compartilham; apenas estado de autenticação, não um serviço de integridade |
OSNMA |
compliance |
mapeia as saídas do Kshana para frameworks públicos de resiliência e preenche o mapeamento a partir de documentos de resultados; run_from_text e assess_texts recebem textos, não caminhos |
compliance/ |
interop::testbench |
o movimento do veículo e os eventos de um cenário como um CSV de movimento, NMEA, texto de waypoints e arquivos de eventos para um simulador GNSS de laboratório; nenhum sinal é gerado | TEST-BENCH |
As integrações para embarcações (o plugin Signal K, o modo gate do OpenCPN e a compilação de referência) chamam a ferramenta de linha de comando; veja MARINE-INTEGRATIONS.
2. Pipeline do motor (por execução)#
Cada execução percorre um único modelo de sensor ao longo da grade de tempo, disciplinando-o sempre que o GNSS está nominal e deixando-o em funcionamento livre (holdover / navegação estimada) durante a interrupção.
flowchart TD
A["for each time step t"] --> B{"i > 0 ?"}
B -- yes --> C["model.step(dt, rng)<br/>evolve noise state"]
B -- no --> D
C --> D{"GNSS state at t ?"}
D -- "Nominal" --> E["discipline to truth<br/>(estimator sync / dead-reckoning reset)<br/>error = 0"]
D -- "Denied/Degraded" --> F["estimator predicts;<br/>error = truth − prediction"]
E --> G["record Sample(t, error, gnss)"]
F --> G
G --> A
A -. after loop .-> H["score(series, spec)<br/>→ figures of merit"]
H --> I["assemble Result<br/>(specs · series · FoM · scenario hash)"]
Um cenário executa este pipeline duas vezes, uma para o sensor quântico e outra para o sensor clássico, com sementes independentes (classical_seed = seed + 0x9e3779b97f4a7c15), de modo que as duas realizações de ruído sejam não correlacionadas.
3. A interface do modelo de erro (o ponto de extensão)#
Todo sensor implementa a mesma ideia: um objeto com estado cujo step() avança seu erro estocástico interno e cujo estado acumulado é lido a cada tique. Os relógios expõem a fase acumulada; os acelerômetros expõem a posição duplamente integrada; os enlaces expõem o jitter por medição.
classDiagram
class ErrorModel {
<<trait>>
+step(dt, rng)
+spec() ModelSpec
}
class ClockModel {
+y0, q_wf, q_rw, drift, flicker
+phase() s
+det_freq() +drift_rate()
}
class AccelModel {
+bias, q_va, gyro_bias, q_arw
+pos() m +theta() rad
+reset()
}
class TimeTransferLink {
+sigma_j
+sample(rng) s
}
ErrorModel <|.. ClockModel
ClockModel : white FM + random-walk FM + flicker FM + aging
AccelModel : accel bias + VRW + gyro bias + ARW (gravity-tilt)
TimeTransferLink : white timing jitter
ModelSpec { id, kind, provenance, params } acompanha o resultado, de modo que cada valor na saída seja rastreável até a fonte publicada indicada em provenance.
Junto com o HoldoverEstimator analítico, o pacote de relógio executa um filtro de Kalman de dois estados (fase, frequência) (KalmanClock) cujo ruído de processo corresponde ao modelo verdadeiro. Em deriva durante uma interrupção, sua variância do erro de fase cresce exatamente até q_wf·T + q_rw·T³/3, a relação analítica de holdover, e seu limite de 1-σ online é usado para preencher a figura de mérito de integridade (fração das amostras da interrupção cujo erro permanece dentro do limite de k-σ).
4. Despacho (CLI e bindings)#
api::run_toml(src) é o ponto de entrada único: ele examina o kind de nível superior, desserializa o cenário correspondente, executa o pacote e devolve { json, svg, summary, csv } (csv só está presente nos tipos de cenário que publicam uma tabela de reprodutibilidade). A CLI grava esses itens em arquivos, além do relatório (report.html, report.json) e de qualquer saída de --export / --animate; os bindings de Python e WebAssembly os devolvem ao host. Um único despacho, sem divergência.
flowchart TD
F["api::run_toml(src) · run_scenario(src)"] --> K{"ScenarioKind::classify<br/>typed · exhaustive · 92 kinds<br/>(absent kind → clock; unknown kind → InvalidInput)"}
K --> G1["Timing<br/>clock · timetransfer · quantum-time-transfer · telecom-timing · slot-timing"]
K --> G2["Inertial & fusion<br/>inertial · hybrid · hybrid-ukf · fusion · gnss-ins · quantum-gnss-free-nav · ins-trn-coast · hybrid-optical-rf"]
K --> G3["Orbit, geometry & positioning<br/>orbit · ephemeris · constellation-design · gnss-sim · pvt"]
K --> G4["Integrity<br/>integrity · lunar-integrity · araim-reference-check"]
K --> G5["Resilience & spectrum<br/>jamming · spoof · spoof-detect · quantum-anomaly-detect · tracking-loop · spectrum · conflict-resilience"]
K --> G6["Alt-PNT (GPS-denied)<br/>gravity-map · terrain-nav · terrain-slam · combined-altpnt"]
K --> G7["LEO PNT<br/>leo-signal · leo-pass · leo-navmsg · leo-pvt · leo-ppp · ntn-positioning · leo-pnt-chain"]
K --> G8["Lunar / cislunar suite (MODELLED)<br/>lunar-time-offset · lunar-time-budget · lunar-vlbi · lunar-vlbi-fim · lunar-joint-od-clock<br/>lunar-frame-realisation · lunar-frame-campaign · lunar-llr-datum · realtime-frame-eop<br/>moonlight-service-volume · lunar-differential-pnt · lunar-interop-export · lunar-beacon<br/>lunar-jamming · lunar-attack-surface · earth-gnss-lunar · cislunar-observability · cislunar-arc-recovery"]
K --> G9["Deep space & solar system<br/>mars-pnt · solar-system · body-pnt"]
K --> G10["Machine learning & trade<br/>impairment-eval · quantum-trade"]
K --> G11["Mission analysis & environment<br/>launch-window · reentry · eo-coverage · attitude-budget · aperture-duty-cycle<br/>passes · link-budget · space-packet · space-weather"]
K --> G12["Trade studies, campaigns & interop<br/>sweep · sweep-nd · campaign · oem-interop"]
G1 & G2 & G3 & G4 & G5 & G6 & G7 & G8 & G9 & G10 & G11 & G12 --> W["RunOutput { json, svg, summary, csv }<br/>+ SHA-256 scenario_hash"]
O despacho é feito sobre um enum ScenarioKind tipado, verificado de forma exaustiva (veja a próxima subseção), de modo que adicionar um pacote é uma mudança verificada na compilação. Um kind ausente recorre ao pacote clock, de modo que os cenários existentes de um único tipo são desserializados sem alteração (serde ignora o campo kind em cada struct de cenário). Um kind não reconhecido é recusado com KshanaError::InvalidInput, que indica o tipo de cenário embutido mais próximo quando o nome parece um erro de digitação.
Despacho tipado e a API estruturada#
O despacho é feito sobre um enum ScenarioKind tipado, não sobre uma comparação de strings brutas: ScenarioKind::classify(src) resolve o campo kind para uma variante, e o despachante a verifica de forma exaustiva; adicionar um pacote é uma mudança verificada na compilação, não um erro de digitação em string. Duas superfícies tipadas ficam ao lado do run_toml, que devolve strings (mantido para a CLI e os bindings existentes):
run_scenario(src) -> Result<RunOutput, KshanaError>: a entrada tipada, com uma taxonomia estruturada de erros (InvalidInput,NonConvergence,Unsupported,IoError). Cada erro carrega umkind_tag()estável, para que o chamador possa ramificar pela categoria da falha em vez de analisar a mensagem. Os bindings expõem isso comoerror_kind(toml).list_scenario_kinds() -> Vec<ScenarioMeta>(elist_scenario_kinds_json(), exposto nos bindings comolist_kinds()): introspecção programática, com o nome, a descrição e os campos obrigatórios/opcionais de cada tipo de cenário, para o preenchimento automático da UI (interface de usuário) e de notebooks.
Estendendo o Kshana com um pacote externo#
Um pacote de terceiros implementa dois traits pequenos e estáveis em semver a partir de api:
use kshana::api::{ExternalPack, KshanaError, RunOutput, Scenario, ScenarioMeta};
struct MyPack {
threshold: f64, // the deserialized scenario fields
}
impl Scenario for MyPack {
fn run(&self) -> Result<RunOutput, KshanaError> {
// Run the model, then build the unified output envelope.
Ok(RunOutput {
json: format!("{{\"threshold\": {}}}", self.threshold),
svg: String::from("<svg xmlns=\"http://www.w3.org/2000/svg\"/>"),
summary: format!("my-pack | threshold {}", self.threshold),
csv: None,
})
}
}
impl ExternalPack for MyPack {
fn kind_name(&self) -> &'static str {
"my-pack"
}
fn meta(&self) -> ScenarioMeta {
ScenarioMeta {
name: "my-pack",
description: "An out-of-tree example pack.",
required_fields: &["threshold"],
optional_fields: &[],
}
}
}
ExternalPack também tem um método register_into(&mut PackRegistry) padrão, que não faz nada, a menos que um pacote opte pelo ponto de despacho do registro em src/registry.rs. O pacote jamming embutido é conectado por meio de Scenario como exemplo trabalhado; pacotes fora da árvore seguem o mesmo contrato sem bifurcar o núcleo (espelhando o ponto de extensão ErrorModel em §3, que a camada privada de resiliência utiliza).
O Kshana tem, portanto, dois pontos de extensão estáveis: adicionar um sensor implementando ErrorModel (§3), ou adicionar um tipo de cenário inteiro implementando Scenario + ExternalPack; ambos estáveis em semver, e nenhum exige bifurcar o núcleo:
classDiagram
class ErrorModel {
<<trait — sensor seam>>
+step(dt, rng)
+spec() ModelSpec
}
class Scenario {
<<trait — pack seam>>
+run() RunOutput
}
class ExternalPack {
<<trait : Scenario>>
+kind_name() str
+meta() ScenarioMeta
}
ErrorModel <|.. ClockModel
ErrorModel <|.. AccelModel
ErrorModel <|.. TimeTransferLink
Scenario <|.. ExternalPack
Scenario <|.. JammingPack : worked example
ExternalPack <|.. ThirdPartyPack : out-of-tree, no core fork
5. O pacote híbrido final#
O pacote híbrido executa uma suíte (um relógio + um sensor inercial) e exige que tanto a temporização quanto a posição permaneçam dentro da especificação; pnt_holdover é o tempo até que um deles seja violado. Opcionalmente, um enlace óptico entre satélites ressincroniza o relógio durante a interrupção, apenas como auxílio de tempo; a posição não é ressincronizada, porque a transferência de tempo fornece tempo, não posição. É isso que isola o sensor inercial como fator limitante.
flowchart LR
subgraph suite["PNT suite (per technology)"]
clk["clock → timing error"]
acc["inertial sensor → position error"]
isl["optical ISL<br/>re-sync clock at interval"] -. aids .-> clk
end
clk --> J["both within spec ?"]
acc --> J
J --> P["pnt_holdover = first breach<br/>(timing OR position)"]
6. Disponibilidade de GNSS derivada da geometria#
orbit.rs é uma camada de geometria determinística e sem dependências. Um Propagator é o Orbit kepleriano analítico (dois corpos, opcionalmente com J2 secular) ou um propagador Sgp4 completo construído a partir de um conjunto completo de elementos de duas linhas (TLE); um gerador Walker-delta produz constelações sintéticas, e a visibilidade em linha de visada = oclusão pela Terra + máscara de elevação. A contagem de satélites visíveis é mapeada para um estado GNSS (≥4 = nominal, 1–3 = degradado, 0 = negado), e build_timeline converte isso na linha do tempo de disponibilidade que conduz a execução padrão de holdover do relógio. A disponibilidade é, portanto, derivada da geometria e não definida manualmente, enquanto a execução, o estimador e a pontuação permanecem inalterados.
Uma constelação fornecida como TLEs completos é propagada com o modelo SGP4/SDP4 em sgp4.rs (validado em relação aos vetores AIAA (American Institute of Aeronautics and Astronautics) 2006-6753); elementos apenas da linha 2 mantêm o caminho analítico de dois corpos. Os dois podem ser misturados em um mesmo bloco de constelação.
flowchart LR
U["user orbit"] --> V
C["Walker constellation"] --> V["visible_count(t)<br/>occultation + mask"]
V --> S["gnss_state: ≥4 / 1–3 / 0"]
S --> T["build_timeline → GnssTimeline"]
T --> R["run_orbit_clock → clock holdover"]
7. Bindings#
O núcleo é compilado sem alteração para nativo, para uma extensão Python e para WebAssembly. Os módulos Python (python.rs, PyO3 abi3) e WebAssembly (wasm.rs, wasm-bindgen) são dependências opcionais, controladas por recursos (--features python / --features wasm): a compilação padrão e a suíte de testes nunca as compilam, enquanto a verificação de auditoria de dependências (cargo deny --all-features) inspeciona suas árvores de dependências, porque esses crates são distribuídos dentro do wheel e do pacote npm. Ambos chamam api::run_toml, de modo que todas as superfícies devolvem resultados idênticos. O módulo WebAssembly sustenta o playground de navegador em web/ e exporta treze funções: run, run_all (uma execução do motor que devolve resultado, gráfico, resumo e tabela juntos), chart_svg, summary, table_csv, list_kinds, error_kind, version, o codec de URL (URL: endereço web) compartilhável encode_permalink / decode_permalink, e os três exportadores export_sp3 / export_omm / export_oem que sustentam o menu de exportação do playground. Duas outras portas de entrada chegam à mesma api: o servidor MCP (Model Context Protocol) (mcp/kshana-mcp, um crate rmcp excluído do workspace que expõe quinze ferramentas: run_scenario, list_scenario_kinds, validate_scenario, list_example_scenarios, get_example_scenario, report_scenario, animate_scenario, list_export_formats, export_interop, import_route, export_sp3, export_omm, export_oem, export_table_csv, assess_receiver_log; as duas ferramentas de exemplo leem os cenários embutidos por meio do recurso bundled-scenarios da biblioteca, desativado por padrão e ativado apenas por este servidor) e o plugin para IDE (ambiente de desenvolvimento integrado) JetBrains (ide/jetbrains, um projeto Kotlin que chama a CLI kshana em vez de vincular a biblioteca).
flowchart LR
cli["CLI · main.rs<br/>native binary"] --> api
py["Python · python.rs (PyO3 abi3)<br/>RunOutput class + run · run_full · run_typed · scenario_kinds · list_kinds · validate_toml · error_kind · version"] --> api
wasm["WebAssembly · wasm.rs (wasm-bindgen)<br/>run · run_all · chart_svg · summary · table_csv · list_kinds · error_kind · version · encode/decode_permalink<br/>export_sp3 · export_omm · export_oem"] --> api
mcp["MCP server · mcp/kshana-mcp (rmcp)<br/>tools: run_scenario · list_scenario_kinds · validate_scenario<br/>list_example_scenarios · get_example_scenario<br/>report_scenario · animate_scenario<br/>list_export_formats · export_interop · import_route<br/>export_sp3 · export_omm · export_oem · export_table_csv"] --> api
ide["JetBrains plugin · ide/jetbrains (Kotlin)"] -- spawns process --> cli
api["api::run_toml / run_scenario / list_scenario_kinds"] --> out["identical { json, svg, summary } on every surface"]
Controle por recursos: Python e WASM são --features python / --features wasm; a tabela de cenários embutidos é --features bundled-scenarios (o único uso dela pelo servidor MCP); o servidor MCP e as verificações cruzadas de xval/* são crates EXCLUÍDOS do workspace; o plugin para IDE não vincula nada: ele executa a CLI.
8. Determinismo e reprodutibilidade#
- Toda a aleatoriedade passa por um único
ChaCha8Rngcom semente por execução; a ordem dos passos é fixa, de modo que(scenario, seed, engine version) → identical bits. - O resultado traz um
scenario_hashSHA-256 (SHA: Secure Hash Algorithm);scripts/check-reproducible.shexecuta um cenário de referência duas vezes e afirma que a saída é idêntica byte a byte. - O mesmo motor é compilado para nativo, para uma extensão Python e para
wasm32-unknown-unknown, para execuções no navegador que produzem os mesmos números.
9. Estrutura adiada / futura#
As camadas de astrodinâmica, fusão e alt-PNT da §1a — o propagador SGP4/SDP4 completo, o propagador numérico de Cowell com seu modelo de forças de sete perturbações e dois integradores adaptativos, o projeto de manobras/trajetórias, a determinação de órbita, os estimadores GNSS/INS de 15, 8 e 17 estados, o filtro acoplado de relógio + posição e o casamento com mapas de gravidade — foram todas entregues, junto com a FoM de segurança com um demonstrador ativo de spoofing, geometria real de TLE/multiconstelação, bandas de Monte Carlo, varreduras de estudos de compromisso, o relatório HTML (HyperText Markup Language) imprimível com seu gêmeo legível por máquina, e os fluxos de trabalho de release/publicação/wheels/páginas.
Vários recursos antes listados aqui como trabalho futuro foram entregues desde então e são tratados acima ou em VALIDATION: a nutação completa IAU 2000A e a redução GCRS↔ITRS / ITRF (International Terrestrial Reference Frame) baseada no CIO, livre de equinócio (validada bit a bit em relação ao SOFA/ERFA (SOFA: Standards of Fundamental Astronomy; ERFA: Essential Routines for Fundamental Astronomy)), o geopotencial EGM2008 (Earth Gravitational Model 2008) até grau/ordem 70, o termo de arrasto de referencial de Lense–Thirring, marés sólidas/oceânicas/atmosféricas, uma validação cruzada de efemérides de nível DE (DE440/ANISE (DE440: Development Ephemeris 440; ANISE: Attitude, Navigation, Instrument, Spacecraft, Ephemeris — um kit de ferramentas de geometria planetária em Rust puro)), a validação cruzada externa do Orekit 12,2 do propagador numérico de Cowell (0,08 m em 24 h) e da determinação de órbita em lote e sequencial, e o navegador fortemente acoplado de 17 estados exposto como o tipo de cenário hybrid-ukf.
Os desdobramentos restantes são acompanhados em CHANGELOG [Unreleased] e o roteiro por capacidade em CAPABILITY: um valor de referência independente externo para o avaliador de alto grau do EGM (Earth Gravitational Model) exatamente sobre o eixo polar e uma comparação próxima ao polo limpa com o pyshtools (o avaliador até o grau 2190 e seu carregador .gfc em tempo de execução estão entregues, MODELLED; veja xval/high-degree-gravity/), um condutor de clima espacial variável no tempo para o nível opcional de densidade de arrasto NRLMSISE-00 (NRLMSISE: Naval Research Laboratory Mass Spectrometer and Incoherent Scatter Radar Extended atmosphere model) (a densidade de arrasto padrão é o modelo exponencial estático, e a densidade Jacchia-71 do tipo de cenário space-weather é caracterizada em relação ao NRLMSISE-00, mas não substituída por ele), uma verificação externa da sombra opcional com escurecimento de limbo solar, o acoplamento forte GNSS/INS com fase da portadora e um mapa de gravidade real EGM2008/EIGEN (EIGEN: European Improved Gravity model of the Earth by New techniques) para o casador alt-PNT.
Um repositório de camada privada guarda a profundidade de resiliência sensível à exportação; ele se conecta pela mesma interface ErrorModel (e pelo contrato ExternalPack em §4) sem alterar o motor público.