Kshana · क्षण · точный миг
Симулятор устойчивости PNT (позиционирование, навигация и время) с открытым исходным кодом.
Выпуск v0.40.0 176 из 401 возможностей проверены по независимым внешним оракулам Около 95% покрытия строк, с порогом 85% в непрерывной интеграции Лицензия: только AGPL-3.0 или коммерческая лицензия DOI 10.5281/zenodo.20528627
Отрепетируйте минуту, когда ГНСС пропадает#
Kshana воспроизводит подавление, спуфинг и holdover часов при отказе сигналов ГНСС (глобальной навигационной спутниковой системы) и показывает, как долго система сохраняет время и положение в пределах бюджета и какие часы или датчик дают наибольший запас. Это пакет WebAssembly: весь движок на JavaScript, в браузере или в Node.js. Каждый прогон побитно воспроизводим по сценарию, начальному значению (seed) и версии движка.
Сначала попробуйте то, что не требует установки: Kshana Studio выполняет весь движок в вашем браузере, скомпилированный в WebAssembly, и ничего не загружает.
Доказательства#
176 из 401 возможностей проверены по независимым внешним оракулам; 221 честно помечены как смоделированные, 4 принадлежат партнёру. Каждая возможность несёт одну метку в машинно проверяемом реестре (ledger): VALIDATED (независимый внешний оракул согласуется: реальные данные, независимая реализация или опубликованные эталонные векторы), MODELLED (внутренне согласовано, и об этом сказано прямо) или PARTNER (отвечает аппаратный партнёр). Среди проверок: все 666 векторов SGP4 (Simplified General Perturbations 4) из AIAA (Американский институт аэронавтики и астронавтики) 2006-6753 с точностью до 4,12 мм и модель сил Коуэлла с точностью до 0,08 м относительно Orekit 12,2.
Установка#
npm install kshana
Использование#
Пакет — это модуль ES (ECMAScript, стандартный JavaScript) с полезной нагрузкой WebAssembly, собранный для браузера. Инициализируйте его один раз, затем вызывайте движок синхронно. Единственное различие между браузером и Node.js — способ загрузки двоичного файла WebAssembly.
В браузере (через сборщик или страницу, которая отдаёт node_modules/kshana/) init() загружает kshana_bg.wasm из места рядом с модулем:
import init, { run, summary, chart_svg, version } from "kshana";
await init(); // fetch and compile the WebAssembly binary
В Node.js init() завершается ошибкой TypeError: fetch failed (fetch в Node не умеет читать локальный файл), поэтому прочитайте двоичный файл с диска и передайте его в initSync:
import { readFileSync } from "node:fs";
import { createRequire } from "node:module";
import { initSync, run, summary, chart_svg, version } from "kshana";
const wasmPath = createRequire(import.meta.url).resolve("kshana/kshana_bg.wasm");
initSync({ module: readFileSync(wasmPath) }); // compile the WebAssembly binary
Сохраните версию для Node.js как файл .mjs (или задайте "type": "module" в вашем package.json), чтобы import работал. Дальше оба варианта одинаковы:
// A complete scenario, not a sketch: scenarios/clock-holdover.toml without its comment
// lines. It runs 2 h, 10 min of GNSS then about 1.8 h with GNSS denied, and asks how long
// a strontium optical clock and a chip-scale atomic clock (CSAC) each hold time to within
// 20 ns. sigma_y(1s) is a clock's Allan deviation at an averaging time of one second;
// q_wf, the white-frequency-noise intensity, is its square.
const toml = `
seed = 42
threshold_ns = 20.0
[time]
step_s = 10.0
duration_s = 7200.0
[gnss]
windows = [
{ t0 = 0.0, t1 = 600.0, state = "nominal" },
{ t0 = 600.0, t1 = 7200.0, state = "denied" },
]
[clock_quantum]
id = "optical-sr-lattice"
provenance = "Strontium optical lattice clock, space-oriented goal sigma_y(1s)=1e-15 (Origlia/Schiller/Bongs et al., arXiv:1503.08457); q_wf=sigma_y(1s)^2; ground-demonstrator maturity, not flown; flicker/aging not modeled"
y0 = 5.0e-17
q_wf = 1.0e-30
q_rw = 0.0
[clock_classical]
id = "csac-sa45s"
provenance = "Microchip SA65 / SA.45s CSAC datasheet sigma_y(1s)=3e-10; q_wf=sigma_y(1s)^2; flicker/aging not modeled"
y0 = 5.0e-10
q_wf = 9.0e-20
q_rw = 0.0
`;
const result = JSON.parse(run(toml)); // the full result document
// timing_p95_ns: the 95th-percentile timing error over the GNSS outage, in nanoseconds
console.log(version(), result.classical.fom.timing_p95_ns);
console.log(summary(toml)); // the one-line result string
const svg = chart_svg(toml); // the same chart the command-line interface (CLI) writes
TypeScript видит типизированные результаты: run_typed(toml) возвращает RunOutput (json, svg, summary, csv: string | null, data: ResultDocument), scenario_kinds() — KindMeta[], у которого name принадлежит объединению ScenarioKind всех видов, а error_kind() — ErrorKind (или "" при успехе). Собственные поля документа каждого результата различаются по виду; ResultDocument описывает типами общую оболочку (schema_version, engine_version и блок units из FieldUnit).
import { run_typed, scenario_kinds, type ScenarioKind } from "kshana";
const out = run_typed(toml);
const units = out.data.units; // Record<string, FieldUnit>
const kinds: ScenarioKind[] = scenario_kinds().map((k) => k.name);
Ещё четыре функции описывают движок для интерфейсной части. kind_modules() возвращает объект JSON, сопоставляющий вид и модули, которые названы в строках его матрицы верификации, field_importance() — объект, сопоставляющий вид и поля результата, отвечающие на его вопрос (метаданные для показа; движок их никогда не читает), iq_signals() — названия сигналов, которые принимает iq_run_short, а iq_run_short(fs_hz, duration_s, signal, ids, dopplers_hz, cn0_dbhz, seed) — короткую синтетическую сцену IQ, захваченную и отслеженную в памяти (не более 0,25 с, 1 000 000 отсчётов и 8 спутников), с тем же ответом, что и у собственной сборки.
import { list_examples, get_example, export_scenario, animate_scenario } from "kshana";
const names = JSON.parse(list_examples("")).scenarios.map((s) => s.name); // the bundled scenarios
const toml = get_example("orbit-gnss-challenged"); // its TOML, byte for byte
const czml = JSON.parse(export_scenario(toml, "czml")).files[0].content; // a CZML file, in memory
const player = JSON.parse(animate_scenario(toml, "html", 0, NaN, 0)).files; // {name: html text}
В интерфейсе WebAssembly каждая точка входа — отдельный вызов: run (документ результата в виде строки JSON), summary, chart_svg, table_csv (таблица CSV (значения, разделённые запятыми) сценария в виде строки или undefined для видов, не публикующих таблицу; при недопустимом сценарии выбрасывает исключение), run_all (один прогон движка, возвращающий {json, svg, summary, csv} в виде строки JSON — используйте его, когда нужно больше одного вывода, так как любой другой вызов заново запускает сценарий), run_typed (те же выводы в виде одного типизированного объекта, с документом, уже разобранным как data), version, list_kinds / scenario_kinds / error_kind (интроспекция; scenario_kinds возвращает разобранный список), encode_permalink / decode_permalink — кодек ссылки для обмена (URL, унифицированный указатель ресурса), который Kshana Studio использует для кругового переноса всего сценария через фрагмент адресной строки, — и export_sp3 / export_omm / export_oem, артефакты эфемерид SP3-c (редакция c формата Standard Product 3) и CCSDS (Консультативный комитет по космическим системам передачи данных) — OMM, сообщение со средними элементами орбиты, и OEM, сообщение с эфемеридами орбиты, — которые пишет CLI, — и receiver_trust, который оценивает журнал реального приёмника, описанный сценарием receiver-trust, и возвращает {json, csv, svg, summary} в виде строки JSON (в браузере нет файловой системы, поэтому журнал и любой навигационный файл должны быть встроены в сценарий как text или base64; таблица [platform] kind = "vessel" добавляет морские мониторы и оценку доверия по шкале 0–100, только консультативного характера), export_formats / export_scenario (какие форматы совместимости поддерживает сценарий, без его запуска, и один экспорт в памяти: czml, kml, geojson, stk или sigmf в виде JSON {format, spec_url, files}, побайтно идентичный для одного и того же сценария, ничего не загружается), import_route (маршрут GeoJSON, записанный в сценарий с путевыми точками, — это --import-route командной строки), animate_scenario (временной ряд прогона в виде анимированного SVG, одного HTML-проигрывателя или кадров SVG), list_examples / get_example (встроенные эталонные сценарии и их TOML), evidence_attach_timestamp (привязать токен RFC 3161 к пакету доказательств в памяти; пакет по-прежнему должен проходить проверку, а подпись службы меток времени не проверяется), osnma_verify (данные навигации Galileo каких спутников подтверждает файл страниц I/NAV или поток UBX, с доверенным корнем Меркла или открытыми ключами и необязательным независимым эталонным временем; он подтверждает подлинность данных и не заявляет никакой эффективности защиты от спуфинга; ничего не загружается), receiver_trust_replay (ограниченный фрагмент NMEA, оцениваемый так, как его оценивает живой режим; без порога), assess_vessel_log (журнал NMEA судна как пакетный прогон), trust_telemetry (поток доверия или результат в виде текста Prometheus, строк syslog CEF или LEEF либо полезной нагрузки OTLP; ничего не отправляется), evidence_verify (проверить подписанный пакет доказательств; ничего не загружается; пакеты создаются с помощью CLI, Python или MCP), bench_export (движение и события сценария в виде текста для лабораторного имитатора; сигнал не записывается), compliance_report и compliance_mapping (какие строки требований публичных рамочных документов подкрепляются доказательствами документов результатов, с пробелом для каждой строки; это не вывод о том, что рамочный документ выполнен), и interference_map (текст CSV ADS-B или AIS в GeoJSON kshana-interference-map/v1 за каждые сутки UTC; только агрегированно), route_exposure (доля маршрута, проходящая через ухудшенные ячейки этих карт; не прогноз), nmea_training (синтетический мостиковый NMEA и журнал инструктора для обучения экипажей; только текст, ни в коем случае не для действующих навигационных систем судна) и функции геометрии неба sky_geometry, sky_monte_carlo, skyline_presets, skyline_profile и skyplot_svg (какие спутники видны в точке, когда часть неба закрывают здания, причалы или рельеф, с геометрическим фактором DOP (ухудшение точности), горизонтальным эллипсом ошибок, облаком Монте-Карло с начальным значением и диаграммой неба в виде текста SVG; решение о видимости и эллипс проверены по независимым библиотекам, пресеты — это репрезентативные геометрии, а не съёмки, а контур горизонта убирает спутники прямой видимости и ничего больше). Нет в сборке для браузера: receiver-trust live с порогом и слушателем TCP, потоковый учебный NMEA и экспортёры телеметрии (Prometheus, OpenTelemetry, syslog) — это долгоживущие сетевые процессы, и они остаются в инструменте командной строки; для создания пакета доказательств нужен ключ подписи, который остаётся у CLI или Python. Вызова run_full одним действием здесь нет; эта привязка существует только в колесе Python.
Каждая возможность в матрице верификации помечена как validated (проверена по независимому внешнему оракулу), modelled или принадлежит партнёру; показатели оптических часов — это космические цели на наземном оборудовании (ни одни стронциевые оптические часы не летали). Зрелость не одинакова по областям: PNT на Земле проверена по реальным данным; навигация в дальнем космосе и на Марсе моделируется, и по внешним оракулам проверены лишь её строительные блоки (время распространения света, положения планет); определение орбиты (OD) в реальных миссиях в дальнем космосе есть в дорожной карте.
Возможности#
В движке 92 видов сценариев; kshana kinds перечисляет их с полями. Новое в 0.38.0: gnss-ssv (сигналы ГНСС для космических аппаратов выше орбит ГНСС, на них и за их пределами) и lunar-infrastructure (лунная орбита и поверхность как навигационная и геодезическая инфраструктура), оба MODELLED, и holdover-test (запись ошибки времени относительно масок ITU-T).
- Спектр: как источник подавления занимает L-диапазон ГНСС, диапазон за диапазоном.
- Часы и синхронизация времени: holdover относительно порога, передача времени и телекоммуникационный holdover относительно масок сектора стандартизации Международного союза электросвязи (ITU-T).
- Орбитальные группировки вокруг любого тела: покрытие, геометрический фактор DOP (ухудшение точности) и доступность вокруг Земли, Луны или Марса и Солнечная система в одну эпоху.
- Навигация на низкой околоземной орбите: сигнал, пролёт и линия связи, навигационное сообщение и объединённое решение, этап за этапом.
- Кампании: сквозная миссия, перебор или ансамбль Монте-Карло в одном сценарии.
- Отчёты, анимация и экспорт: каждый показатель с единицей и меткой; анимированный рисунок прогона; сообщения об орбитах SP3 (Standard Product 3), CCSDS (Консультативный комитет по космическим системам передачи данных), файлы CZML (Cesium Language), KML (Keyhole Markup Language), GeoJSON, STK (Systems Tool Kit) и SigMF (Signal Metadata Format).
Архитектура#
Один и тот же файл сценария даёт одни и те же байты на любой поверхности. MCP — это Model Context Protocol: kshana-mcp позволяет ИИ-помощнику (искусственному интеллекту) запускать движок.
Исследования#
На открытом движке построены шесть статей на arXiv, у каждой есть команда, стоящая за ней: arXiv:2606,22054 (разрыв в оптимизме детекторов помех), arXiv:2606,24210 (условный уровень защиты времени), arXiv:2607,05415 (насколько стабильна оценка устойчивости PNT), arXiv:2607,02566 (наблюдаемость лунной поверхностной станции методом радиоинтерферометрии со сверхдлинной базой), arXiv:2607,06212 (геометрия южного полярного района Луны и поверхностные маяки) и arXiv:2610,23871 (цислунная навигация как задача наблюдаемости: длина дуги, обусловленность грамиана и рычаг Доплера). См. Исследования.
Редакции#
Весь движок свободен по лицензии AGPL-3.0. Kshana Pro, проприетарная надстройка, которая зависит от открытого движка и никогда его не ответвляет, и индивидуальные исследования доступны по договору с Ashforde® OÜ: contact@ashforde.org. Цен нет; см. docs/PRO.md.
Подробнее#
- Полный README → https://github.com/AshfordeOU/kshana
- Kshana Studio (движок в вашем браузере, в виде WebAssembly) → https://kshana.dev
- Возможности → docs/CAPABILITY.md
- Проверка и происхождение → docs/VALIDATION.md · docs/PROVENANCE.md
- Матрица верификации → docs/VERIFICATION-MATRIX.md
- Цитирование → CITATION.cff · DOI 10.5281/zenodo.20528627
Лицензия#
Бесплатно и с открытым исходным кодом по лицензии GNU AGPL-3.0-only (Стандартная общественная лицензия GNU Affero, только версия 3). Коммерческая лицензия предоставляется Ashforde® OÜ (эстонское частное общество с ограниченной ответственностью; OÜ = osaühing) для закрытой интеграции; см. LICENSING.md. Разработано и поддерживается профессионалами в Ashforde® OÜ.