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

APIs e integraçõesEditar no GitHubFonte: README.npm.md

Kshana: a marca, uma retícula de bússola que marca o instante preciso, ao lado do logotipo kshanaKshana: a marca, uma retícula de bússola que marca o instante preciso, ao lado do logotipo kshana

Kshana · क्षण · o instante preciso
Um simulador de código aberto para a resiliência de PNT (posicionamento, navegação e temporização).

Versão v0.40.0 176 de 401 capacidades validadas em relação a referências independentes externas Cerca de 95% de cobertura de linhas, com mínimo exigido de 85% na integração contínua Licença: AGPL-3.0-only, ou uma licença comercial DOI 10.5281/zenodo.20528627

Ensaie o minuto em que o GNSS apaga: o console de missão do Kshana, desenhado a partir de uma execução real do motor, uma campanha encadeada de jamming, spoofing, holdover e integridade sobre os 102 satélites de GPS, Galileo, BeiDou e GLONASSEnsaie o minuto em que o GNSS apaga: o console de missão do Kshana, desenhado a partir de uma execução real do motor, uma campanha encadeada de jamming, spoofing, holdover e integridade sobre os 102 satélites de GPS, Galileo, BeiDou e GLONASS

Ensaie o minuto em que o GNSS apaga#

O Kshana reproduz jamming, spoofing e holdover de relógio quando os sinais de GNSS (Global Navigation Satellite System, sistema global de navegação por satélite) falham, e diz por quanto tempo um sistema mantém tempo e posição dentro do seu orçamento e qual relógio ou sensor compra mais margem. Este é o pacote WebAssembly: o motor inteiro em JavaScript, no navegador ou em Node.js. Toda execução é reproduzível bit a bit a partir do cenário, da semente e da versão do motor.

Experimente primeiro sem nada para instalar: o Kshana Studio executa o motor inteiro no seu navegador, compilado para WebAssembly, e não envia nada.

Evidências#

176 de 401 capacidades validadas em relação a referências independentes externas; 221 rotuladas com honestidade como modeladas, 4 pertencentes a parceiros. Cada capacidade traz um único rótulo em um registro verificado por máquina: VALIDATED (uma referência independente externa concorda: dados reais, uma implementação independente ou vetores de referência publicados), MODELLED (internamente consistente, e dito em voz alta) ou PARTNER (um parceiro de hardware é o responsável). Entre as verificações: todos os 666 vetores SGP4 (Simplified General Perturbations 4) do AIAA (American Institute of Aeronautics and Astronautics) 2006-6753 até 4,12 mm, e o modelo de forças de Cowell até 0,08 m em relação ao Orekit 12,2.

Como uma capacidade obtém seu rótulo: capacidade, referência independente, teste, rótulo no registro. O estado de verificação das 401 capacidades: 176 validadas, 221 modeladas, 4 pertencentes a parceirosComo uma capacidade obtém seu rótulo: capacidade, referência independente, teste, rótulo no registro. O estado de verificação das 401 capacidades: 176 validadas, 221 modeladas, 4 pertencentes a parceiros

Instalar#

npm install kshana

Uso#

O pacote é um módulo ES (ECMAScript, JavaScript padrão) com uma carga WebAssembly, construído para o navegador. Inicialize-o uma vez e depois chame o motor de forma síncrona. A única diferença entre o navegador e o Node.js é como o binário WebAssembly é carregado.

No navegador (por meio de um bundler, ou de uma página que serve node_modules/kshana/), init() busca kshana_bg.wasm ao lado do módulo:

import init, { run, summary, chart_svg, version } from "kshana";

await init();                                   // fetch and compile the WebAssembly binary

No Node.js, init() falha com TypeError: fetch failed (o fetch do Node não consegue ler um arquivo local), de modo que se lê o binário do disco e se o entrega a 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

Salve a versão para Node.js como um arquivo .mjs (ou defina "type": "module" no seu package.json) para que import funcione. Daí em diante os dois são iguais:

// 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

O TypeScript vê resultados tipados: run_typed(toml) devolve um RunOutput (json, svg, summary, csv: string | null, data: ResultDocument), scenario_kinds() um KindMeta[] cujo name é a união ScenarioKind de todos os tipos de cenário, e error_kind() um ErrorKind (ou "" em caso de sucesso). Os campos próprios de cada documento de resultado variam conforme o tipo de cenário; ResultDocument tipa o envelope compartilhado (schema_version, engine_version e o bloco units de FieldUnits).

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);

Quatro funções a mais descrevem o motor para um front end. kind_modules() devolve um objeto JSON do tipo de cenário para os módulos que as linhas da sua matriz de verificação nomeiam, field_importance() um do tipo de cenário para os campos de resultado que respondem à sua pergunta (metadados de exibição; o motor nunca os lê), iq_signals() os nomes de sinais que iq_run_short aceita, e iq_run_short(fs_hz, duration_s, signal, ids, dopplers_hz, cn0_dbhz, seed) uma cena IQ sintética curta, adquirida e rastreada em memória (no máximo 0,25 s, 1.000.000 amostras e 8 satélites), com a mesma resposta da compilação nativa.

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}

Na face WebAssembly cada ponto de entrada é uma chamada separada: run (o documento de resultado como uma cadeia JSON), summary, chart_svg, table_csv (a tabela CSV (valores separados por vírgula) do cenário como uma cadeia, ou undefined para tipos de cenário que não publicam tabela; lança erro diante de um cenário inválido), run_all (uma execução do motor devolvendo {json, svg, summary, csv} como uma cadeia JSON — use-a quando quiser mais de uma saída, pois toda outra chamada executa o cenário de novo), run_typed (as mesmas saídas como um único objeto tipado, com o documento já analisado como data), version, list_kinds / scenario_kinds / error_kind (introspecção; scenario_kinds devolve a lista analisada), encode_permalink / decode_permalink — o codec de link compartilhável (URL, localizador uniforme de recursos) que o Kshana Studio usa para fazer ida e volta de um cenário inteiro pelo fragmento da barra de endereços — e export_sp3 / export_omm / export_oem, os artefatos de efemérides SP3-c (revisão c do formato Standard Product 3) e CCSDS (Consultative Committee for Space Data Systems) — OMM, a Orbit Mean-elements Message, e OEM, a Orbit Ephemeris Message — que a CLI grava — e receiver_trust, que avalia um log real de receptor descrito por um cenário receiver-trust e devolve {json, csv, svg, summary} como uma cadeia JSON (o navegador não tem sistema de arquivos, de modo que o log, e qualquer arquivo de navegação, deve estar em linha no cenário como text ou base64; uma tabela [platform] kind = "vessel" acrescenta os monitores marítimos e a pontuação de confiança de 0-100, apenas consultiva), export_formats / export_scenario (quais formatos de interoperabilidade um cenário suporta, sem executá-lo, e uma exportação em memória: czml, kml, geojson, stk ou sigmf como JSON {format, spec_url, files}, idêntica byte a byte para o mesmo cenário, nada enviado), import_route (uma rota GeoJSON escrita num cenário de trajetória por pontos de passagem, o --import-route da linha de comando), animate_scenario (a série temporal da execução como um SVG animado, um único player HTML ou quadros SVG), list_examples / get_example (os cenários de referência incluídos e o seu TOML), evidence_attach_timestamp (vincular um token RFC 3161 a um pacote de evidências em memória; o pacote ainda deve verificar, e a assinatura da autoridade de carimbo de tempo não é verificada), osnma_verify (quais dados de navegação Galileo de satélites um arquivo de páginas I/NAV ou um fluxo UBX autentica, com a raiz Merkle confiável ou chaves públicas e um tempo de referência independente opcional; ele autentica dados e não faz nenhuma afirmação de desempenho antispoofing; nada é enviado), receiver_trust_replay (um trecho NMEA limitado pontuado do modo como o modo ao vivo pontua; sem gate), assess_vessel_log (o log NMEA de uma embarcação como execução em lote), trust_telemetry (um fluxo ou resultado de confiança como texto Prometheus, linhas syslog CEF ou LEEF ou uma carga OTLP; nada é enviado), evidence_verify (verifica um pacote de evidências assinado; nada é enviado; os pacotes são feitos com a CLI, o Python ou o MCP), bench_export (o movimento e os eventos de um cenário como texto para um simulador de laboratório; nenhum sinal é gravado), compliance_report e compliance_mapping (quais linhas de requisitos de estruturas públicas os documentos de resultado fornecem evidências em apoio de, com a lacuna de cada linha; não uma constatação de que uma estrutura é satisfeita), e interference_map (texto CSV de ADS-B ou AIS para um GeoJSON kshana-interference-map/v1 por dia UTC; somente agregado), route_exposure (a parcela de uma rota que passa por células degradadas desses mapas; não uma previsão), nmea_training (NMEA sintético de ponte e um log do instrutor para treinamento de tripulação; somente texto, nunca para os sistemas de navegação em operação de uma embarcação) e as funções de geometria do céu sky_geometry, sky_monte_carlo, skyline_presets, skyline_profile e skyplot_svg (quais satélites um sítio vê quando edifícios, cais ou terreno bloqueiam parte do céu, com a diluição de precisão, a elipse de erro horizontal, uma nuvem de Monte Carlo com semente e um skyplot como texto SVG; a decisão de visibilidade e a elipse são verificadas contra bibliotecas independentes, as predefinições são geometrias representativas e não levantamentos, e um skyline remove satélites em linha de visada e nada mais). Não estão na compilação para navegador: receiver-trust live com o seu gate e o listener TCP, o NMEA de treinamento em fluxo e os exportadores de telemetria (Prometheus, OpenTelemetry, syslog) são processos de rede de longa duração e permanecem na ferramenta de linha de comando; criar um pacote de evidências exige uma chave de assinatura, que pertence à CLI ou ao Python. Não há aqui uma chamada única run_full; essa ligação existe apenas no wheel Python.

Toda capacidade na matriz de verificação é rotulada como validada (verificada contra uma referência independente externa), modelada ou de propriedade de parceiro; as cifras de relógios ópticos são metas espaciais em hardware de solo (nenhum relógio óptico de estrôncio voou). A maturidade não é uniforme entre os domínios — o PNT terrestre é validado contra dados reais; a navegação de espaço profundo e de Marte é modelada, com apenas os seus blocos de construção (tempo de luz, posições de planetas) validados contra referências independentes externas; a OD (determinação de órbita) de espaço profundo em missões reais está no roteiro.

Capacidades#

O motor tem 92 tipos de cenário; kshana kinds os lista com seus campos. Novos na 0.38.0: gnss-ssv (sinais GNSS para espaçonaves acima, ao redor e além das órbitas GNSS) e lunar-infrastructure (órbita e superfície lunares como infraestrutura de navegação e geodésica), ambos MODELLED, e holdover-test (um registro de erro de tempo em relação às máscaras da ITU-T).

  • Espectro: como um jammer toma a banda L do GNSS, banda a banda.
  • Relógios e temporização: holdover contra um limiar, transferência de tempo e holdover de telecomunicações contra as máscaras do setor de normalização da União Internacional de Telecomunicações (ITU-T).
  • Constelações em torno de qualquer corpo: cobertura, diluição de precisão e disponibilidade em torno da Terra, da Lua ou de Marte, e o sistema solar numa época.
  • Navegação em órbita terrestre baixa: sinal, passagem e enlace, mensagem de navegação e uma solução fundida, etapa por etapa.
  • Campanhas: uma missão encadeada, uma varredura ou um ensemble de Monte Carlo num único cenário.
  • Relatórios, animação e exportações: toda cifra com a sua unidade e o seu rótulo; um desenho animado de uma execução; arquivos SP3 (Standard Product 3), mensagens de órbita CCSDS (Consultative Committee for Space Data Systems), CZML (Cesium Language), KML (Keyhole Markup Language), GeoJSON, STK (Systems Tool Kit) e SigMF (Signal Metadata Format).

Arquitetura#

Um motor aberto no centro, kshana 0.40.0, com um despacho tipado sobre 75 tipos de cenário; ao redor, a linha de comando, a biblioteca Rust, o Python, o WebAssembly e o Kshana Studio, o servidor MCP, a imagem Docker e o plugin JetBrains; abaixo, o Kshana Pro, uma camada proprietária que depende do motor aberto e nunca o bifurcaUm motor aberto no centro, kshana 0.40.0, com um despacho tipado sobre 75 tipos de cenário; ao redor, a linha de comando, a biblioteca Rust, o Python, o WebAssembly e o Kshana Studio, o servidor MCP, a imagem Docker e o plugin JetBrains; abaixo, o Kshana Pro, uma camada proprietária que depende do motor aberto e nunca o bifurca

O mesmo arquivo de cenário dá os mesmos bytes em todas as superfícies. MCP é o Model Context Protocol: kshana-mcp permite que um assistente de IA (inteligência artificial) execute o motor.

Pesquisa#

Seis artigos no arXiv são construídos sobre o motor aberto, cada um com o comando por trás dele: arXiv:2606,22054 (a lacuna de otimismo dos detectores de interferência), arXiv:2606,24210 (um nível de proteção de temporização condicional), arXiv:2607,05415 (quão estável é uma pontuação de resiliência de PNT), arXiv:2607,02566 (observabilidade de estações de superfície lunar com interferometria de linha de base muito longa), arXiv:2607,06212 (geometria polar sul lunar e faróis de superfície) e arXiv:2610,23871 (navegação cislunar como problema de observabilidade: comprimento de arco, condicionamento do Gramiano e a alavanca Doppler). Veja Pesquisa.

Edições#

O motor inteiro é livre sob a AGPL-3.0. O Kshana Pro, uma camada proprietária que depende do motor aberto e nunca o bifurca, e estudos personalizados estão disponíveis sob contrato com a Ashforde® OÜ: contact@ashforde.org. Não há preços; veja docs/PRO.md.

Saiba mais#

Licença#

Software livre e de código aberto sob a GNU AGPL-3.0-only (a GNU Affero General Public License, versão 3 apenas). Uma licença comercial está disponível junto à Ashforde® OÜ (uma sociedade privada de responsabilidade limitada da Estônia; OÜ = osaühing) para integração fechada; veja LICENSING.md. Desenvolvido e mantido profissionalmente pela Ashforde® OÜ.