Tradução automática, não revista por um falante nativo. O inglês é a referência.

APIs e integraçõesEditar no GitHubFonte: docs/ARCHITECTURE.md

Kshana — Arquitetura

O Kshana é um só motor organizado em camadas sobre um núcleo partilhado: 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 o 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 a efemérides precisas de agências); uma camada de tempo e referenciais (escalas de tempo 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, alt-PNT (PNT: posicionamento, navegação e temporização) e lunar (RAIM/ARAIM/SBAS (RAIM: monitorização autónoma de integridade pelo recetor; ARAIM: monitorização autónoma de integridade pelo recetor avançada; SBAS: sistema de aumentação baseado em satélites), deteção de jamming e de spoofing em várias camadas, correspondência de mapas de gravidade/terreno/magnéticos e PNT cislunar); e as camadas mais recentes de LEO-PNT (PNT em órbita terrestre baixa), espetro, sistema solar e projeto de constelações, temporização de rede e campanhas, com os escritores de relatórios, animações e interoperabilidade que todas as execuções podem usar (§1d). Em todas elas, o motor nada sabe sobre "quântico" vs "clássico": conduz modelos de erro de sensores através de um cenário de falha 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 nos seus parâmetros de erro (publicados, citados) e nas suas sementes de ruído independentes.

Este documento reúne os diagramas estruturais e comportamentais. A §1 é o núcleo dos pacotes de sensores; a §1a mapeia as camadas de astrodinâmica, fusão e alt-PNT acrescentadas desde então; as §1b–§1d as camadas de estudo, de domínio e de saída. Para a utilização, consulte o README; para o que é e não é validado, consulte VALIDATION; para a tabela de maturidade por capacidade, consulte CAPABILITY.

Abreviaturas 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, a norma de recetores SBAS da RTCA (Radio Technical Commission for Aeronautics); EKF, filtro de Kalman estendido; FM, modulação de frequência; GSE, equipamento de apoio em terra; 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, ligação entre satélites; ITU-T, o Setor de Normalização das Telecomunicações da União Internacional das Telecomunicações; J2–J6, os harmónicos zonais do campo gravítico 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 terrestre baixa; LOO, validação deixando 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-este-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 de ponto; PSD, densidade espetral 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 embutido; SH, harmónico esférico; SigMF, Signal Metadata Format; SIR, reamostragem por importância; SRIF, filtro de informação em raiz quadrada; SRP, pressão da radiação solar; SSC, coeficiente de separação espetral; STK, Systems Tool Kit; SVG, Scalable Vector Graphics; TDEV, desvio de tempo; TDM, a 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 / de â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 comandos) e ambas as ligações convergem num único ponto de entrada api::run_toml, pelo que nunca divergem. Os pacotes reutilizam o núcleo partilhado (types, scenario, allan); o Pacote 4 (hybrid) compõe os modelos e estimadores dos Pacotes 1–3 em vez de os reimplementar; orbit deriva uma cronologia GNSS a partir da geometria, que depois alimenta a execução do Pacote 1. O módulo navsignal situa-se ao nível do sinal entre o balanço de ligação e o domínio das medições: deriva o coeficiente de separação espetral κ a partir dos espetros de potência reais do sinal e do jammer, a partir do qual jamming passa agora a calcular o seu Q = 1/(R_c·κ) anti-jam em vez de tomar uma constante representativa (verificado por comparação em CI (integração contínua)); transporta também o compromisso de projeto do código de medição de distância (sequência-m/Gold).

Três outros módulos formam a espinha dorsal da resiliência sem GNSS. holdover responde diretamente à pergunta operacional — durante quanto tempo pode este relógio funcionar livremente antes de o seu erro de temporização exceder o orçamento? — expondo a forma fechada do erro de deriva de van Loan como uma inversão do holdover até ao limiar, verificada por comparação com a recursão de covariância de vários passos de clock_state. O seu gémeo inercial vive em inertial::quantum_imu (QuantumNavBudget), que compõe a deriva de ruído branco do interferómetro de átomos frios com o erro de enviesamento e de fator de escala num orçamento de deriva de posição durante o holdover (o termo de enviesamento verificado por comparação com o integrador independente AccelModel). verification desenha toda a matriz do motor de exigência, módulo, teste, referência independente e estado, com invariantes testados por unidades que proíbem um rótulo validado sem uma referência independente externa — pelo que a alegação de garantia não pode divergir do código.

1a. Camadas de astrodinâmica, fusão e alt-PNT#

Para além do núcleo dos pacotes de sensores, três subsistemas partilham 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 transporta os estimadores GNSS/INS; e a camada de alt-PNT é a correspondência de mapas de gravidade sem GPS (GPS: Global Positioning System). São capacidades de biblioteca/cenário (ver 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 estão desligados por predefinição, pelo que ativá-los nunca perturba os goldens publicados. O filtro de Kalman unscented (UKF) fortemente acoplado de 17 estados faz a deriva de uma falha de GNSS com a velocidade derivada do passeio aleatório do acelerómetro quântico CAI; a determinação de órbita reutiliza os mesmos forces/integrator para propagar um estado candidato ao longo do arco de seguimento.

O mesmo núcleo partilhado transporta ainda quatro outros subsistemas não desenhados acima (os seus pacotes aparecem no despacho da §4): uma camada de tempo e referenciais (timescales, jd2, precession, nutation, cio, frames, eop) que reduz TEME↔GCRS↔ITRS (TEME: equador verdadeiro, equinócio médio) e alimenta o pacote de 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 deteção de jamming e de spoofing em várias camadas, com uma camada de sinal de navegação (navsignal) ao nível do sinal — densidades espetrais de potência BPSK-R (BPSK: modulação por desvio de fase binária) / sine-BOC (BOC: portadora de desvio binário), o coeficiente de separação espetral κ que agora deriva o Q anti-jam de jamming, a largura de banda de medição de distância RMS (Gabor), o jitter de seguimento de código DLL (malha de bloqueio de atraso) coerente early–late e a envolvente do erro de multipercurso (análise de desempenho de sinal, não projeto de hardware de carga útil de RF (RF: radiofrequência) / antena — o papel de um parceiro de carga útil); e uma camada lunar / cislunar (lunar, lunar_frame, lunar_od, cr3bp) para a dinâmica CR3BP (problema circular restrito de três corpos) — incluindo a matriz de transição de estado de 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 9:2 publicada de L2 (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 à Lua) de uma órbita corrigida e a continuação de famílias continuam por fazer, e a NRHO é uma solução CR3BP (circular, sem Sol), não validada face a uma efeméride real LANS/Gateway (LANS: Lunar Augmented Navigation Service) — e a integridade 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 alt-PNT (igrf, altpnt/terrain, gravimeter) completam a lista de módulos; ver CAPABILITY para a maturidade por módulo.

1b. Estudos de resiliência, avaliação de aprendizagem automática e artefactos reproduzíveis#

Cinco outros grupos de módulos formam a camada de estudo aberto e reproduzível por trás dos artigos de investigação do projeto. Ao contrário dos tipos de cenário (kind), estes são alcançados como geradores cargo run --example / --bin que escrevem artefactos deterministas ao byte (sementes fixas, versão do motor registada + hash da configuração). Todos são MODELLED (calibração sintética ou de conjuntos de dados públicos) e levam 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 pelo holdover, do erro de tempo não detetado sob spoofing, que compõe um piso de monitor de k-σ, a variância de deriva de van Loan ao longo da latência de deteção e um tempo até ao alarme de CUSUM (soma cumulativa); calibrado com um spoof real gravado (JammerTest 2024). Não há nenhum limite incondicional finito — o TPL é condicional a uma verificação cruzada independente que detete o ataque.
  • resilience/ — um motor de pontuação de resiliência PNT alinhado com referenciais (categorias 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 ordenação 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. Ver RESILIENCE-CROSSWALK. Arquiteturas sintéticas alinhadas com o 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 para degradações de RF: um corpus sintético rotulado e um arnês ROC/AUC (ROC: característica de operação do recetor; AUC: área sob a curva) agnóstico quanto ao detetor, um painel de 13 detetores (energia/AGC/SQM/paridade (AGC: controlo automático de ganho; SQM: monitorização da qualidade do sinal) mais detetores de regressão logística e de MLP (MLP: perceptrão multicamada) de uma camada oculta com sementes), leis de escala dentro e fora da distribuição com um nulo de 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 face ao scikit-learn.
  • sdr / realdata — um front end de recetor definido por software (IQ/IF (IQ: em fase/quadratura; IF: frequência intermédia) brutos → derivações early/prompt/late do correlador → SQM) e adaptadores de ingestão (RINEX, u-blox UBX, GnssLogger, JammerTest, Yunnan, SatGrid) que deixam os mesmos detetores correr sobre gravações fornecidas localmente; nenhum conjunto de dados é submetido ao repositório.
  • crossover / quantum_trade — o mapa de cruzamento de resiliência quântico-vs-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 face ao scipy.

1c. Camadas de integridade, GNSS, espaço profundo, lunar e de missão#

Os restantes domínios ligam-se ao mesmo despacho api e reutilizam o núcleo partilhado, os referenciais e a geometria. Tudo aqui é MODELLED, salvo se uma linha da matriz verification citar uma referência independente externa (núcleo RAIM face ao SciPy, SBAS face ao fork do RTKLIB (uma biblioteca aberta de posicionamento cinemático em tempo real), o núcleo DOP (diluição da precisão) verificado com o gnss_lib_py, a avaliação OPS-SAT, o núcleo de nível de proteção ARAIM lunar, a coerência entre fornecedores das efemérides lunares) — o resto do conjunto lunar e o demonstrador quântico são modelados, ilustrativos, de fonte pública e não levam nenhuma alegação de TRL (nível de maturidade tecnológica) / herança / aval de agências.

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, espetro, sistema solar, temporização de rede, campanhas e saídas#

As camadas mais recentes 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 partilhado e MODELLED, salvo se uma linha da matriz citar 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 recetor, evidências, telemetria, formação e compliance (0,35)#

Estas camadas leem o registo do próprio recetor ou escrevem ficheiros para outras ferramentas; nenhuma sintetiza ou transmite um sinal de radiofrequência. Situam-se 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, salvo se uma linha da matriz citar 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 registo de recetor é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 ficheiro a ser acrescentado, TCP ou UDP), a sentença $PKSHT e o gate opcional; LiveEngine é a totalidade disso, sem entrada nem saída MARITIME-TRUST
evidence um pacote assinado, encadeado por hashes, de uma janela de registo, da sua configuração e do resultado do motor, verificável offline; token de marca temporal RFC 3161 opcional EVIDENCE-PACKS
telemetry o fluxo de confiança como métricas Prometheus, eventos syslog (CEF ou LEEF) e, opcionalmente, OpenTelemetry (funcionalidade otlp, desativada por predefinição) TRUST-TELEMETRY
nmea_synth NMEA 0183 sintético de ponte, com eventos programados de jamming, drag-off, time spoof e replay e um registo de instrutor, para a formação de tripulações (apenas texto) NMEA-TRAINING
interference_map mapas agregados de navegação degradada a partir de relatórios de aeronaves e navios de licença aberta, e a exposição de uma rota a esses mapas; apenas ficheiros locais INTERFERENCE-MAP
osnma um verificador do lado do recetor para o OSNMA do Galileo: lê páginas I/NAV (páginas simples, CSV de vetores, um fluxo UBX), verifica a chave assinada, a cadeia TESLA e os MAC, e indica, por satélite, se os dados de navegação estão autenticados; osnma::cli::verify_report é o único caminho que a linha de comandos, o Python e o WebAssembly partilham; apenas estado de autenticação, não é um serviço de integridade OSNMA
compliance associa os resultados do Kshana a referenciais públicos de resiliência e preenche a associação 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 CSV de movimento, NMEA, texto de pontos de passagem e ficheiros de eventos para um simulador GNSS de laboratório; não é escrito nenhum sinal TEST-BENCH

As integrações para embarcações (o plugin Signal K, o modo de barreira do OpenCPN e a compilação de referência) chamam a ferramenta de linha de comandos; ver MARINE-INTEGRATIONS.

2. Pipeline do motor (por execução)#

Cada execução avança um único modelo de sensor ao longo da grelha temporal, disciplinando-o sempre que o GNSS está nominal e deixando-o em funcionamento livre (holdover / dead-reckoning) durante a indisponibilidade.

flowchart TD
    A["for each time step t"] --> B{"i &gt; 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, outra para o sensor clássico — com sementes independentes (classical_seed = seed + 0x9e3779b97f4a7c15), de modo que as duas realizações de ruído não estejam correlacionadas.

3. A interface do modelo de erro (o ponto de extensão)#

Todos os sensores implementam a mesma ideia: um objeto com estado cujo step() faz avançar o seu erro estocástico interno e cujo estado acumulado é lido a cada instante. Os relógios expõem a fase acumulada; os acelerómetros expõem a posição duplamente integrada; as ligações expõem a instabilidade (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 da saída é rastreável até à fonte publicada indicada em provenance.

Além do 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 coincide com o do modelo de referência. Ao deslizar durante uma indisponibilidade, a variância do seu erro de fase cresce exatamente até q_wf·T + q_rw·T³/3 — a relação analítica de holdover — e o seu limite em linha de 1-σ é usado para preencher a figura de mérito de integridade (fração das amostras da indisponibilidade cujo erro se mantém dentro do limite de k-σ).

4. Despacho (CLI e ligações)#

api::run_toml(src) é o ponto de entrada único: lê de relance 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 escreve-os em ficheiros, juntamente com o relatório (report.html, report.json) e qualquer saída --export / --animate; as ligações Python e WebAssembly devolvem-nos ao anfitrião. Um só despacho, sem divergências.

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 faz-se sobre uma enumeração tipada ScenarioKind, com correspondência exaustiva (ver a subsecção seguinte), pelo que acrescentar um pacote é uma alteração verificada em tempo de compilação. Um kind ausente recorre ao pacote clock, de modo que os cenários existentes de um só tipo se desserializam sem alterações (o serde ignora o campo kind em cada estrutura de cenário). Um kind não reconhecido é recusado com KshanaError::InvalidInput, que indica o tipo incorporado mais próximo quando o nome parece um erro de escrita.

Despacho tipado e a API estruturada#

O despacho faz-se sobre uma enumeração tipada ScenarioKind, não sobre uma correspondência de cadeias em bruto: ScenarioKind::classify(src) resolve o campo kind numa variante e o despachante faz a correspondência exaustiva sobre ela — acrescentar um pacote é uma alteração verificada em tempo de compilação, não um erro de escrita numa cadeia. Duas superfícies tipadas coexistem com o run_toml que devolve cadeias (mantido para a CLI e para as ligações existentes):

  • run_scenario(src) -> Result<RunOutput, KshanaError> — a entrada tipada, com uma taxonomia de erros estruturada (InvalidInput, NonConvergence, Unsupported, IoError). Cada erro transporta um kind_tag() estável, para que quem chama possa ramificar consoante a categoria da falha em vez de analisar a mensagem. As ligações expõem-no como error_kind(toml).
  • list_scenario_kinds() -> Vec<ScenarioMeta> (e list_scenario_kinds_json(), exposto nas ligações como list_kinds()) — introspeção programática: 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 utilizador) e de notebooks.

Estender o Kshana com um pacote externo#

Um pacote de terceiros implementa dois pequenos traits, estáveis segundo semver, 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 tem também um método register_into(&mut PackRegistry) predefinido, sem efeito a menos que um pacote opte pelo ponto de despacho do registo em src/registry.rs. O pacote jamming incorporado está ligado através de Scenario como exemplo trabalhado; os pacotes externos à árvore seguem o mesmo contrato sem bifurcar o núcleo (espelhando o ponto de extensão ErrorModel da §3, que a camada privada de resiliência utiliza).

O Kshana tem, assim, dois pontos de extensão estáveis — acrescentar um sensor implementando ErrorModel (§3), ou acrescentar um tipo de cenário completo implementando Scenario + ExternalPack — ambos estáveis segundo semver, nenhum exigindo uma bifurcação do 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 elemento de síntese híbrido#

O pacote híbrido executa uma suite (um relógio e um sensor inercial) e exige que tanto a temporização como a posição se mantenham dentro da especificação; pnt_holdover é o tempo até um dos dois ser violado. Opcionalmente, uma ligação ótica entre satélites volta a sincronizar o relógio durante a indisponibilidade — apenas auxílio de tempo; a posição não é novamente sincronizada, porque a transferência de tempo dá tempo, não posição. É isto 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 GNSS derivada da geometria#

orbit.rs é uma camada de geometria determinista e sem dependências. Um Propagator é o Orbit kepleriano analítico (dois corpos, opcionalmente J2 secular) ou um propagador Sgp4 completo construído a partir de um conjunto completo de elementos de duas linhas; um gerador Walker-delta produz constelações sintéticas, e a visibilidade em linha de vista = ocultação pela Terra + máscara de elevação. O número de satélites visíveis corresponde a um estado GNSS (≥4 = nominal, 1–3 = degradado, 0 = negado), e build_timeline transforma-o na cronologia de disponibilidade que conduz a execução normal de holdover do relógio. A disponibilidade é, assim, derivada da geometria e não definida à mão, enquanto a execução, o estimador e a pontuação permanecem inalterados.

Uma constelação fornecida como TLE completos é propagada com o modelo SGP4/SDP4 em sgp4.rs (validado face aos vetores AIAA (American Institute of Aeronautics and Astronautics) 2006-6753); os elementos apenas da linha 2 mantêm o caminho analítico de dois corpos. Os dois podem ser combinados num 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. Ligações#

O núcleo compila-se sem alterações 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, condicionadas por funcionalidades (--features python / --features wasm): a compilação predefinida e o conjunto de testes nunca os compilam, ao passo que a barreira de auditoria de dependências (cargo deny --all-features) inspeciona as suas árvores de dependências, porque essas crates seguem dentro do wheel e do pacote npm. Ambos chamam api::run_toml, pelo que todas as superfícies devolvem resultados idênticos. O módulo WebAssembly suporta o playground do navegador em web/ e exporta treze funções: run, run_all (uma execução do motor que devolve em conjunto o resultado, o gráfico, o resumo e a tabela), chart_svg, summary, table_csv, list_kinds, error_kind, version, o codec de URL (URL: endereço web) partilhável encode_permalink / decode_permalink e os três exportadores export_sp3 / export_omm / export_oem que suportam o menu de exportação do playground. Duas outras portas de entrada chegam à mesma api: o servidor MCP (Model Context Protocol) (mcp/kshana-mcp, uma crate rmcp excluída 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 exemplos leem os cenários incluídos através da funcionalidade bundled-scenarios da biblioteca, desativada por predefinição, que só este servidor ativa) e o plugin para o IDE (ambiente de desenvolvimento integrado) JetBrains (ide/jetbrains, um projeto Kotlin que invoca a CLI kshana em vez de ligar 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"]

Condicionamento por funcionalidades: o Python e o WASM são --features python / --features wasm; a tabela de cenários incluídos é --features bundled-scenarios (a única utilização que o servidor MCP faz dela); o servidor MCP e as verificações cruzadas xval/* são crates EXCLUÍDAS do workspace; o plugin do IDE não liga nada — executa a CLI.

8. Determinismo e reprodutibilidade#

  • Toda a aleatoriedade passa por um único ChaCha8Rng com semente por execução; a ordem dos passos é fixa, pelo que (scenario, seed, engine version) → identical bits.
  • O resultado inclui um scenario_hash SHA-256 (SHA: Secure Hash Algorithm); scripts/check-reproducible.sh executa um cenário de referência duas vezes e confirma que a saída é idêntica byte a byte.
  • O mesmo motor compila-se 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 diferida / futura#

As camadas de astrodinâmica, fusão e alt-PNT da §1a — o propagador completo SGP4/SDP4, o propagador numérico de Cowell com o seu modelo de forças de sete perturbações e dois integradores adaptativos, a conceção de manobras/trajetórias, a determinação de órbita, os estimadores GNSS/INS de 15/8/17 estados, o filtro acoplado de relógio e posição e a correspondência de mapas gravíticos — foram todas entregues, a par da FoM de segurança com um demonstrador ativo de spoofing, da geometria real de TLE/multiconstelação, das bandas de Monte Carlo, das varreduras de estudos de compromisso, do relatório HTML (HyperText Markup Language) imprimível com o seu gémeo legível por máquina e dos fluxos de trabalho de lançamento/publicação/wheels/páginas.

Várias capacidades outrora listadas aqui como trabalho futuro foram entretanto entregues e estão descritas acima ou em VALIDATION: a nutação IAU 2000A completa e a redução GCRS↔ITRS / ITRF (International Terrestrial Reference Frame) CIO, sem equinócio (validada bit a bit face ao SOFA/ERFA (SOFA: Standards of Fundamental Astronomy; ERFA: Essential Routines for Fundamental Astronomy)), o geopotencial EGM2008 (Earth Gravitational Model 2008) até ao grau/ordem 70, o termo de arrastamento de referencial de Lense–Thirring, as 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 conjunto de ferramentas de geometria planetária em Rust puro)), a validação cruzada externa com o Orekit 12,2 do propagador numérico de Cowell (0,08 m ao longo de 24 h) e da determinação de órbita em lote e sequencial, e o navegador de 17 estados fortemente acoplado disponibilizado como o tipo de cenário hybrid-ukf.

Os restantes desenvolvimentos seguintes estão registados 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 limpa com o pyshtools perto do polo (o avaliador até ao grau 2190 e o seu carregador .gfc em tempo de execução são entregues, MODELLED; ver xval/high-degree-gravity/), um fator de meteorologia espacial variável no tempo para o nível opcional de densidade de arrastamento NRLMSISE-00 (NRLMSISE: Naval Research Laboratory Mass Spectrometer and Incoherent Scatter Radar Extended atmosphere model) (a densidade de arrastamento predefinida é o modelo exponencial estático, e a densidade Jacchia-71 do tipo de cenário space-weather é caracterizada face ao NRLMSISE-00, mas não substituída por ele), uma verificação externa da sombra opcional com escurecimento de bordo solar, o acoplamento forte GNSS/INS com fase da portadora e um mapa gravítico real EGM2008/EIGEN (EIGEN: European Improved Gravity model of the Earth by New techniques) para o correlacionador de alt-PNT.

Um repositório de camada privada contém a profundidade de resiliência sujeita a controlo de exportação; liga-se através da mesma interface ErrorModel (e do contrato ExternalPack da §4) sem alterar o motor público.