Kshana — архитектура
Kshana — это один движок, организованный в слои над общим ядром: пакеты датчиков (часы, инерциальные, передача времени, гибридные); слой астродинамики и численных методов (аналитический SGP4/SDP4 (SGP4: Simplified General Perturbations 4; SDP4: Simplified Deep-space Perturbations 4), численный пропагатор Коуэлла с моделью сил из семи возмущений, проектирование манёвров, определение орбиты по дальностям от наземных станций и подгонка модели сил к прецизионным эфемеридам агентств); слой времени и систем отсчёта (шкалы времени IERS (International Earth Rotation and Reference Systems Service), прецессия–нутация IAU (International Astronomical Union) 2006/2000A и приведение GCRS↔ITRS по CIO (Celestial Intermediate Origin) (GCRS: Geocentric Celestial Reference System; ITRS: International Terrestrial Reference System)); слой объединения данных (оценщики GNSS/INS (GNSS: глобальная навигационная спутниковая система; INS: инерциальная навигационная система)); слои целостности, устойчивости, альтернативных PNT (PNT: позиционирование, навигация и время) и лунные (RAIM/ARAIM/SBAS (RAIM: автономный контроль целостности приёмником; ARAIM: расширенный автономный контроль целостности приёмником; SBAS: спутниковая система функционального дополнения), обнаружение подавления и многоуровневое обнаружение спуфинга, сопоставление с гравитационными, рельефными и магнитными картами и цислунные PNT); а также более новые слои LEO-PNT (PNT на низкой околоземной орбите), спектра, Солнечной системы и проектирования орбитальных группировок, сетевой синхронизации времени и кампаний, с модулями записи отчётов, анимации и взаимодействия, которые можно использовать в любом прогоне (§1d). Во всех этих слоях движок ничего не знает о «квантовом» и «классическом»: он прогоняет модели ошибок датчиков через сценарий пропадания GNSS, запускает оценщик и оценивает результат. Поэтому квантовое и классическое устройства сравниваются на одном и том же сценарии и различаются только своими (опубликованными, с указанием источников) параметрами ошибок и независимыми начальными значениями шума.
В этом документе собраны структурные и поведенческие диаграммы. §1 — ядро пакетов датчиков; §1a описывает слои астродинамики, объединения данных и альтернативных PNT, добавленные позднее; §1b–§1d — слои исследований, предметных областей и вывода. По вопросам использования см. README; о том, что проверено и что нет, см. VALIDATION; о таблице зрелости по возможностям см. CAPABILITY.
Сокращения, используемые на диаграммах и не расшифрованные там, где они встречаются: ADEV, девиация Аллана; BW, полоса пропускания; CAI, интерферометр на холодных атомах; CZML, Cesium Language; Δ-DOR, дельта-дифференциальное одностороннее измерение дальности; DO-229E, стандарт приёмников SBAS RTCA (Radio Technical Commission for Aeronautics); EKF, расширенный фильтр Калмана; FM, частотная модуляция; GSE, наземное вспомогательное оборудование; HPL/VPL, горизонтальный/вертикальный уровень защиты; IMU, инерциальный измерительный блок; IOAG, Interagency Operations Advisory Group; IQ, отсчёты синфазной и квадратурной составляющих; ISL, межспутниковая линия; ITU-T, Сектор стандартизации электросвязи Международного союза электросвязи; J2–J6, зональные гармоники гравитационного поля Земли степеней от 2 до 6; KIF, Kshana Interchange Format; KML, Keyhole Markup Language; KPI, ключевой показатель эффективности; L1/L5, несущие диапазоны GNSS (L2 гало-орбит CR3BP — это, напротив, точка Лагранжа 2 системы Земля–Луна); LEO, низкая околоземная орбита; LOO, исключение по одному; LTC, Координированное лунное время; MEO, средняя околоземная орбита; MTIE, максимальная ошибка временного интервала; N2, число разнообразия Хилла порядка 2; NED, север–восток–вниз; NTN, нетерриториальная сеть; OD, определение орбиты; OPS-SAT, орбитальный лабораторный спутник Европейского космического агентства для программного обеспечения; PPP, прецизионное абсолютное позиционирование; PSD, спектральная плотность мощности; PVT, положение, скорость и время; RINEX, Receiver Independent Exchange Format; RK4 / RK5(4), интеграторы Рунге–Кутты четвёртого порядка и вложенный пятого (четвёртого) порядка; SH, сферическая гармоника; SigMF, Signal Metadata Format; SIR, выборка по значимости с передискретизацией; SRIF, корневой информационный фильтр; SRP, давление солнечного излучения; SSC, коэффициент спектрального разделения; STK, Systems Tool Kit; SVG, Scalable Vector Graphics; TDEV, девиация времени; TDM, Tracking Data Message CCSDS (Consultative Committee for Space Data Systems); TLE, двухстрочный набор элементов; TPL, уровень защиты синхронизации времени; UBX, двоичный протокол u-blox; UHF, ультравысокие частоты; VLBI, радиоинтерферометрия со сверхдлинной базой; VRW / ARW, случайное блуждание скорости / угла; WASM, WebAssembly.
1. Структура модулей#
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
CLI (интерфейс командной строки) и обе привязки сходятся в одной точке входа api::run_toml, поэтому никогда не расходятся. Пакеты используют общее ядро (types, scenario, allan); пакет 4 (hybrid) компонует модели и оценщики пакетов 1–3, а не реализует их заново; orbit выводит из геометрии временную шкалу GNSS, которая затем питает прогон пакета 1. Модуль navsignal находится на уровне сигнала между бюджетом линии и областью измерений: он выводит коэффициент спектрального разделения κ из фактических спектров мощности сигнала и передатчика помех, и по нему jamming теперь вычисляет свой антиджамминговый Q = 1/(R_c·κ), а не берёт репрезентативную константу (перекрёстная проверка в CI (непрерывная интеграция)); он также содержит компромиссы проектирования дальномерных кодов (m-последовательность/Голда).
Ещё три модуля образуют основу устойчивости в условиях отсутствия GNSS. holdover отвечает на практический вопрос напрямую — как долго эти часы могут работать в свободном режиме, пока ошибка времени не превысит бюджет? — представляя замкнутую форму ошибки выбега по ван Лоану как обращение «holdover до порога» и перекрёстно проверяя её по многошаговой рекурсии ковариации clock_state. Его инерциальный двойник находится в inertial::quantum_imu (QuantumNavBudget), который объединяет белошумовой дрейф интерферометра на холодных атомах со смещением и ошибкой масштабного коэффициента в бюджет дрейфа положения за время holdover (член смещения перекрёстно проверен по независимому интегратору AccelModel). verification строит матрицу всего движка: требование, модуль, тест, оракул, статус, с проверяемыми модульными тестами инвариантами, запрещающими метку validated без независимого внешнего оракула, так что утверждение об уровне уверенности не может разойтись с кодом.
1a. Слои астродинамики, объединения данных и альтернативных PNT#
Помимо ядра пакетов датчиков, три подсистемы используют то же общее ядро и питают orbit или питаются от него. Слой астродинамики и численных методов добавляет неаналитический пропагатор Коуэлла рядом с аналитическим путём SGP4/SDP4; слой объединения данных содержит оценщики GNSS/INS; а слой альтернативных PNT — это сопоставление с гравитационной картой в условиях отсутствия GPS (GPS: Global Positioning System). Это возможности библиотеки и сценариев (о том, какие из них подключены к kind сценария, а какие доступны как API Rust (программный интерфейс приложений), см. CAPABILITY).
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
Силовые члены численного пропагатора по умолчанию отключены, поэтому их включение никогда не нарушает выпущенные эталонные результаты. 17-мерный сильно связанный UKF (сигма-точечный фильтр Калмана) проходит пропадание GNSS на выведенной скорости случайного блуждания квантового акселерометра CAI; определение орбиты использует те же forces/integrator, чтобы распространять кандидатное состояние по дуге слежения.
То же общее ядро несёт ещё четыре подсистемы, не показанные выше (их пакеты видны в диспетчеризации §4): слой времени и систем отсчёта (timescales, jd2, precession, nutation, cio, frames, eop), выполняющий приведение TEME↔GCRS↔ITRS (TEME: истинный экватор, среднее равноденствие) и питающий пакет ephemeris/трассы на поверхности; слой целостности (raim, sbas) для RAIM/ARAIM/SBAS; слой устойчивости (jamming, spoof, spoof_detect, spoof_monitors, detection) для подавления и многоуровневого обнаружения спуфинга, со слоем навигационного сигнала (navsignal) на уровне сигнала — спектральные плотности мощности BPSK-R (BPSK: двоичная фазовая манипуляция) / sine-BOC (BOC: бинарная смещённая несущая), коэффициент спектрального разделения κ, по которому теперь выводится антиджамминговый Q модуля jamming, среднеквадратическая (по Габору) ширина полосы дальнометрии, джиттер слежения за кодом когерентной схемы DLL (петля захвата задержки) «раньше–позже» и огибающая ошибки многолучевости (анализ характеристик сигнала, не проектирование полезной нагрузки РЧ (РЧ: радиочастотной) или антенного оборудования — это роль партнёра по полезной нагрузке); и слой лунный / цислунный (lunar, lunar_frame, lunar_od, cr3bp) для динамики CR3BP (круговая ограниченная задача трёх тел), включая матрицу перехода состояния 6×6 и дифференциальный корректор с одиночной стрельбой (cr3bp_jacobian, propagate_state_stm, differential_correct_halo), который даёт по-настоящему периодические орбиты гало/NRHO (NRHO: околопрямолинейная гало-орбита), воспроизводя опубликованную южную NRHO L2 9:2 (орбита Gateway) с периодом ≈ 6,57 сут / перилунием ≈ 3 250 км (опубликовано ≈ 6,56 сут / ≈ 3 370 км); селеноцентрическое преобразование MCI/MCMF (MCI: селеноцентрическая инерциальная; MCMF: селеноцентрическая, жёстко связанная с Луной) скорректированной орбиты и продолжение по семейству остаются на будущее, а NRHO — это решение CR3BP (круговое, без Солнца), не проверенное по реальной эфемериде LANS/Gateway (LANS: Lunar Augmented Navigation Service), — и целостность LunaNet. Подгонка модели сил к эфемеридам агентств (precise_od, lunar_od, tides, gravity_sh) и полный набор полей альтернативных PNT (igrf, altpnt/terrain, gravimeter) завершают список модулей; о зрелости каждого модуля см. CAPABILITY.
1b. Исследования устойчивости, оценка машинного обучения и воспроизводимые артефакты#
Пять дополнительных групп модулей образуют слой открытых воспроизводимых исследований за научными статьями проекта. В отличие от сценариев kind, они вызываются как генераторы cargo run --example / --bin, которые пишут побайтно детерминированные артефакты (фиксированные начальные значения (seed), записанные версия движка и хеш конфигурации). Все они имеют уровень MODELLED (калибровка по синтетическим или публичным наборам данных) и несут честные метки валидации — ни одна не является сертификацией.
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— условный уровень защиты синхронизации времени (TPL): ограниченная holdover граница необнаруженной ошибки времени при спуфинге, объединяющая нижний порог монитора в k σ, дисперсию выбега по ван Лоану за время задержки обнаружения и время до тревоги по CUSUM (кумулятивной сумме); откалиброван по реальной записанной атаке спуфинга (JammerTest 2024). Конечной безусловной границы не существует — TPL зависит от того, что независимая перекрёстная проверка обнаруживает атаку.resilience/— механизм оценки устойчивости PNT по рамочной программе (категории DHS (Министерство внутренней безопасности США) RPCF (Resilient PNT Conformance Framework)) плюс исследование нестабильности решения: симплекс весов Дирихле, нестабильность рангов по Кендаллу τ, частота смены победителя top-1 и коллапс разнообразия по общей причине (Hill-N2), с отчётом об уровне уверенности, защищённым хешем целостности, и 35 тестами оракула, выведенными вручную. См. RESILIENCE-CROSSWALK. Синтетические архитектуры, согласованные с RPCF v2.0, — самооценка, а не сертификация.impairment_eval/impairment_study/impairment_ml/eval_stats— исследование разрыва оптимизма при РЧ-нарушениях: размеченный синтетический корпус и не зависящий от детектора стенд ROC/AUC (ROC: рабочая характеристика приёмника; AUC: площадь под кривой), панель из 13 детекторов (энергия/AGC/SQM/чётность (AGC: автоматическая регулировка усиления; SQM: контроль качества сигнала), а также детекторы на основе логистической регрессии и однослойного MLP (MLP: многослойный перцептрон) с фиксированными начальными значениями), законы масштабирования внутри и вне распределения с перестановочным нулём и предсказатель деградации вне распределения методом исключения по одному. Метрики оценки побитово сверены с scikit-learn.sdr/realdata— входной тракт программно определяемого приёмника (необработанные IQ/IF (IQ: синфазная и квадратурная составляющие; IF: промежуточная частота) → отводы коррелятора «раньше/в точке/позже» → SQM) и адаптеры приёма данных (RINEX, u-blox UBX, GnssLogger, JammerTest, Yunnan, SatGrid), позволяющие запускать те же детекторы на записях, предоставленных локально; наборы данных в репозиторий не включаются.crossover/quantum_trade— карта точки пересечения устойчивости квантовых и классических устройств при неопределённости параметров и компромисс по выигрышу holdover по измеренной ADEV; численные ядра компромисса проверены по scipy.
1c. Слои целостности, GNSS, дальнего космоса, Луны и миссий#
Остальные области подключаются к той же диспетчеризации api и используют общее ядро, системы отсчёта и геометрию. Всё здесь имеет уровень MODELLED, если строка матрицы verification не ссылается на внешний оракул (ядро RAIM против SciPy, SBAS против ответвления RTKLIB (библиотека кинематического позиционирования в реальном времени с открытым исходным кодом), ядро DOP (геометрический фактор) gnss_lib_py, оценка OPS-SAT, ядро уровня защиты лунного ARAIM, согласованность лунных эфемерид разных поставщиков); остальная часть лунного набора и квантовый демонстратор смоделированы, иллюстративны, основаны на публичных источниках и не несут утверждений о TRL (уровень технологической готовности) / лётной истории / одобрении агентств.
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, спектр, Солнечная система, сетевая синхронизация времени, кампании и выходные данные#
Самые новые слои следуют той же схеме: каждый — это один или несколько видов сценариев kind, диспетчеризуемых из api, построенных на общем ядре и имеющих уровень MODELLED, если строка матрицы не называет внешний оракул.
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
Подробности по каждому виду см. в LEO-PNT, LEO-SIGNAL, LEO-PASS, LEO-NAVMSG, LEO-PNT-FUSION, SPECTRUM, CONSTELLATION-DESIGN, TELECOM-TIMING, SLOT-TIMING, CAMPAIGNS, REPORTS, ANIMATION и INTEROP.
1e. Слои доверия к приёмнику, доказательств, телеметрии, обучения и compliance (0,35)#
Эти слои читают собственный журнал приёмника или записывают файлы для других инструментов; ни один из них не синтезирует и не передаёт радиочастотный сигнал. Они находятся рядом с api, а не под видами сценариев, за исключением самого receiver-trust, который является видом сценария. Все они имеют уровень MODELLED, если строка матрицы не называет внешний оракул, а морские выходные данные носят консультативный характер и не являются навигационным оборудованием с утверждённым типом.
| Модуль | Что делает | Описано в |
|---|---|---|
receiver_trust |
оценивает журнал приёмника эпоха за эпохой мониторами доверия; платформа судна добавляет морские мониторы и оценку 0–100 с причинами | RECEIVER-TRUST, MARITIME-TRUST |
receiver_trust::live |
та же оценка на потоке по мере его поступления (stdin, дописываемый файл, TCP или UDP), предложение $PKSHT и необязательный шлюз; LiveEngine — это всё целиком, без входа и выхода |
MARITIME-TRUST |
evidence |
подписанный пакет журнала за окно, его конфигурации и результата движка, связанный цепочкой хешей и проверяемый офлайн; необязательный токен метки времени RFC 3161 | EVIDENCE-PACKS |
telemetry |
поток доверия в виде метрик Prometheus, событий syslog (CEF или LEEF) и необязательной телеметрии OpenTelemetry (функция otlp, по умолчанию отключена) |
TRUST-TELEMETRY |
nmea_synth |
синтетические мостиковые NMEA 0183 со сценарными событиями подавления, ухода, подмены времени и повтора и журналом инструктора, для обучения экипажа (только текст) | NMEA-TRAINING |
interference_map |
агрегированные карты ухудшенной навигации по отчётам воздушных и морских судов под открытыми лицензиями и экспозиция маршрута к ним; только локальные файлы | INTERFERENCE-MAP |
osnma |
приёмная сторона проверки Galileo OSNMA: читает страницы I/NAV (простые страницы, векторный CSV, поток UBX), проверяет подписанный ключ, цепочку TESLA и MAC и сообщает по каждому спутнику, аутентифицированы ли навигационные данные; osnma::cli::verify_report — единый путь, общий для командной строки, Python и WebAssembly; только статус аутентификации, не служба целостности |
OSNMA |
compliance |
сопоставляет выходные данные Kshana с публичными рамочными программами устойчивости и заполняет сопоставление по документам результатов; run_from_text и assess_texts принимают тексты, а не пути |
compliance/ |
interop::testbench |
движение транспортного средства и события сценария в виде CSV движения, NMEA, текста путевых точек и файлов событий для лабораторного имитатора GNSS; сигнал не записывается | TEST-BENCH |
Интеграции для лодок (плагин Signal K, режим шлюза OpenCPN и эталонная сборка) вызывают инструмент командной строки; см. MARINE-INTEGRATIONS.
2. Конвейер движка (на один прогон)#
Каждый прогон проводит одну модель датчика по сетке времени, подстраивая её, пока GNSS в норме, и позволяя ей работать в свободном режиме (holdover / счисление пути) во время пропадания сигнала.
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)"]
Сценарий запускает этот конвейер дважды — один раз для квантового датчика, один раз для классического — с независимыми начальными значениями (seed) (classical_seed = seed + 0x9e3779b97f4a7c15), чтобы две реализации шума были некоррелированными.
3. Интерфейс модели ошибок (точка расширения)#
Каждый датчик реализует одну и ту же идею: объект с состоянием, у которого step() продвигает внутреннюю стохастическую ошибку, а накопленное состояние считывается на каждом такте. Часы выдают накопленную фазу; акселерометры выдают дважды проинтегрированное положение; линии выдают джиттер каждого измерения.
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 } попадает в результат, так что каждое значение в выходных данных можно проследить до опубликованного источника, названного в provenance.
Наряду с аналитическим HoldoverEstimator пакет часов запускает двухсостоятельный (фаза, частота) фильтр Калмана (KalmanClock), шум процесса которого соответствует истинной модели. При выбеге через пропадание сигнала дисперсия его ошибки фазы вырастает ровно до q_wf·T + q_rw·T³/3 — аналитического соотношения для holdover — а его онлайн-граница 1 σ используется для заполнения показателя качества целостности (доля отсчётов пропадания, в которых ошибка остаётся внутри границы k σ).
4. Диспетчеризация (CLI и привязки)#
api::run_toml(src) — единственная точка входа: она считывает kind верхнего уровня, десериализует соответствующий сценарий, запускает пакет и возвращает { json, svg, summary, csv } (csv присутствует только для видов, публикующих таблицу воспроизводимости). CLI записывает их в файлы, а также отчёт (report.html, report.json) и любые выходные данные --export / --animate; привязки Python и WebAssembly возвращают их хосту. Одна диспетчеризация, без расхождений.
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"]
Диспетчеризация выполняется по типизированному перечислению ScenarioKind с исчерпывающим сопоставлением (см. следующий подраздел), поэтому добавление пакета — это изменение, проверяемое при компиляции. Отсутствующий kind заменяется пакетом clock, так что существующие сценарии одного вида десериализуются без изменений (serde игнорирует поле kind в каждой структуре сценария). Нераспознанный kind отклоняется с KshanaError::InvalidInput, который называет ближайший встроенный вид, если название похоже на опечатку.
Типизированная диспетчеризация и структурированный API#
Диспетчеризация выполняется по типизированному перечислению ScenarioKind, а не по сопоставлению с необработанной строкой: ScenarioKind::classify(src) приводит поле kind к варианту, а диспетчер исчерпывающе сопоставляет его — добавление пакета является изменением, проверяемым при компиляции, а не опечаткой в строке. Рядом с возвращающим строку run_toml (сохранённым для CLI и существующих привязок) находятся две типизированные поверхности:
run_scenario(src) -> Result<RunOutput, KshanaError>— типизированная точка входа со структурированной таксономией ошибок (InvalidInput,NonConvergence,Unsupported,IoError). Каждая ошибка несёт стабильныйkind_tag(), так что вызывающая сторона может ветвиться по категории сбоя, а не разбирать сообщение. Привязки предоставляют это какerror_kind(toml).list_scenario_kinds() -> Vec<ScenarioMeta>(иlist_scenario_kinds_json(), доступный в привязках какlist_kinds()) — программная интроспекция: название, описание и обязательные/необязательные поля каждого вида для пользовательского интерфейса (UI) и автодополнения в блокнотах.
Расширение Kshana внешним пакетом#
Сторонний пакет реализует два небольших трейта со стабильной семантической версией из 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 есть также метод register_into(&mut PackRegistry) по умолчанию, который ничего не делает, если пакет не подключается к точке диспетчеризации реестра в src/registry.rs. Встроенный пакет jamming подключён через Scenario как рабочий пример; внешние пакеты следуют тому же контракту без ответвления ядра (по аналогии с точкой расширения ErrorModel в §3, которую использует закрытая надстройка устойчивости).
Таким образом, у Kshana есть два стабильных места расширения — добавить датчик, реализовав ErrorModel (§3), или добавить целый вид сценария, реализовав Scenario + ExternalPack; оба со стабильной семантической версией, и ни одно не требует ответвления ядра:
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. Гибридный венец#
Гибридный пакет запускает набор (одни часы и один инерциальный датчик) и требует, чтобы и время, и положение оставались в пределах спецификации; pnt_holdover — это время до нарушения любого из них. Дополнительно оптическая межспутниковая линия повторно синхронизирует часы во время пропадания сигнала — только помощь по времени; положение повторно не синхронизируется, потому что передача времени даёт время, а не положение. Именно это выделяет инерциальный датчик как ограничивающий фактор.
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. Доступность GNSS, выведенная из геометрии#
orbit.rs — детерминированный слой геометрии без зависимостей. Propagator — это либо аналитический кеплеровский Orbit (двух тел, при необходимости с вековым J2), либо полный пропагатор Sgp4, построенный из полного двухстрочного набора элементов; генератор Walker-delta создаёт синтетические орбитальные группировки, а видимость по прямой = затенение Землёй + маска возвышения. Число видимых спутников отображается в состояние GNSS (≥4 = норма, 1–3 = ухудшено, 0 = недоступно), а build_timeline превращает это во временную шкалу доступности, управляющую стандартным прогоном holdover часов. Таким образом, доступность выводится из геометрии, а не задаётся вручную, тогда как прогон, оценщик и оценивание остаются неизменными.
Орбитальная группировка, заданная полными TLE, распространяется моделью SGP4/SDP4 в sgp4.rs (проверено по векторам AIAA (American Institute of Aeronautics and Astronautics) 2006-6753); элементы только из строки 2 сохраняют аналитический путь двух тел. Оба способа можно смешивать в одном блоке орбитальной группировки.
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. Привязки#
Ядро без изменений компилируется для нативной среды, для расширения Python и для WebAssembly. Модули Python (python.rs, PyO3 abi3) и WebAssembly (wasm.rs, wasm-bindgen) — необязательные зависимости, включаемые флагами (--features python / --features wasm): сборка по умолчанию и набор тестов никогда их не компилируют, тогда как шлюз аудита зависимостей (cargo deny --all-features) проверяет их деревья зависимостей, потому что эти крейты поставляются внутри колеса и пакета npm. Обе привязки вызывают api::run_toml, поэтому каждая поверхность возвращает одинаковые результаты. Модуль WebAssembly обслуживает браузерную песочницу в web/ и экспортирует тринадцать функций: run, run_all (один прогон движка, возвращающий результат, график, сводку и таблицу вместе), chart_svg, summary, table_csv, list_kinds, error_kind, version, кодек общих URL (URL: веб-адрес) encode_permalink / decode_permalink и три экспортёра export_sp3 / export_omm / export_oem, обслуживающие меню экспорта песочницы. К тому же api ведут ещё две точки входа: сервер MCP (Model Context Protocol) (mcp/kshana-mcp, крейт rmcp, исключённый из рабочей области, предоставляющий пятнадцать инструментов — 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; два инструмента примеров читают поставляемые сценарии через отключённую по умолчанию функцию библиотеки bundled-scenarios, которую включает только этот сервер) и плагин для JetBrains IDE (интегрированная среда разработки) (ide/jetbrains, проект на Kotlin, который обращается к CLI kshana через оболочку, а не подключает библиотеку).
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"]
Включение функциями: Python и WASM — это --features python / --features wasm; таблица поставляемых сценариев — --features bundled-scenarios (единственное её использование сервером MCP); сервер MCP и перекрёстные проверки xval/* — крейты, ИСКЛЮЧЁННЫЕ из рабочей области; плагин IDE ничего не подключает — он запускает CLI.
8. Детерминизм и воспроизводимость#
- Вся случайность идёт через один
ChaCha8Rngс начальным значением (seed) на прогон; порядок шагов фиксирован, поэтому(scenario, seed, engine version) → identical bits. - Результат содержит
scenario_hashSHA-256 (SHA: Secure Hash Algorithm);scripts/check-reproducible.shзапускает эталонный сценарий дважды и проверяет побайтную идентичность вывода. - Тот же движок компилируется для нативной среды, для расширения Python и для
wasm32-unknown-unknownдля прогонов в браузере, дающих те же числа.
9. Отложенная / будущая структура#
Слои астродинамики, объединения данных и альтернативных PNT из §1a — полный пропагатор SGP4/SDP4, численный пропагатор Коуэлла с моделью сил из семи возмущений и двумя адаптивными интеграторами, проектирование манёвров и траекторий, определение орбиты, оценщики GNSS/INS на 15, 8 и 17 состояний, связанный фильтр часов и положения и сопоставление с гравитационной картой — уже поставлены, наряду с показателем качества безопасности с активным демонстратором спуфинга, реальной геометрией по TLE и нескольким орбитальным группировкам, полосами Монте-Карло, перебором для исследований компромиссов, печатным отчётом HTML (HyperText Markup Language) с его машиночитаемым двойником и процессами выпуска, публикации, колёс и страниц.
Несколько возможностей, когда-то перечисленных здесь как будущая работа, с тех пор поставлены и описаны выше или в VALIDATION: полная нутация IAU 2000A и приведение GCRS↔ITRS / ITRF (International Terrestrial Reference Frame) по CIO без равноденствия (проверено побитово по SOFA/ERFA (SOFA: Standards of Fundamental Astronomy; ERFA: Essential Routines for Fundamental Astronomy)), геопотенциал EGM2008 (Earth Gravitational Model 2008) до степени/порядка 70, член увлечения инерциальных систем Лензе–Тирринга, твёрдые/океанические/атмосферные приливы, перекрёстная проверка эфемерид уровня DE (DE440/ANISE (DE440: Development Ephemeris 440; ANISE: Attitude, Navigation, Instrument, Spacecraft, Ephemeris — набор инструментов планетной геометрии на чистом Rust)), внешняя перекрёстная проверка численного пропагатора Коуэлла по Orekit 12,2 (0,08 м за 24 ч) и пакетного и последовательного определения орбиты, а также 17-мерный сильно связанный навигатор, представленный как вид сценария hybrid-ukf.
Остальные доработки отслеживаются в CHANGELOG [Unreleased], а дорожная карта по возможностям — в CAPABILITY: значение внешнего оракула для высокостепенного вычислителя EGM (Earth Gravitational Model) точно на полярной оси и чистое по pyshtools сравнение вблизи полюса (вычислитель до степени 2190 и его загрузчик .gfc во время выполнения поставляются, MODELLED; см. xval/high-degree-gravity/), зависящий от времени драйвер космической погоды для включаемого по желанию уровня плотности торможения NRLMSISE-00 (NRLMSISE: Naval Research Laboratory Mass Spectrometer and Incoherent Scatter Radar Extended atmosphere model) (плотность торможения по умолчанию задаётся статической экспоненциальной моделью, а плотность Jacchia-71 вида space-weather охарактеризована относительно NRLMSISE-00, но не заменена ею), внешняя проверка включаемой по желанию тени с потемнением к лимбу Солнца, тесная связь GNSS/INS по фазе несущей и реальная гравитационная карта EGM2008/EIGEN (EIGEN: European Improved Gravity model of the Earth by New techniques) для сопоставителя альтернативных PNT.
Закрытый репозиторий-надстройка содержит глубину устойчивости, чувствительную к экспортному контролю; он подключается через тот же интерфейс ErrorModel (и контракт ExternalPack в §4) без изменения публичного движка.