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 assinala o instante preciso, ao lado do logótipo kshanaKshana: a marca, uma retícula de bússola que assinala o instante preciso, ao lado do logótipo 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 face a referências independentes externas Cerca de 95% de cobertura de linhas, com um mínimo de 85% na integração contínua Licença: AGPL-3.0-only, ou uma licença comercial DOI 10.5281/zenodo.20528627

Ensaiar o minuto em que o GNSS fica às escuras: a consola de missão do Kshana, desenhada a partir de uma execução real do motor, uma campanha encadeada de jamming, spoofing, holdover e integridade sobre os 102 satélites do GPS, Galileo, BeiDou e GLONASSEnsaiar o minuto em que o GNSS fica às escuras: a consola de missão do Kshana, desenhada a partir de uma execução real do motor, uma campanha encadeada de jamming, spoofing, holdover e integridade sobre os 102 satélites do GPS, Galileo, BeiDou e GLONASS

Ensaiar o minuto em que o GNSS fica às escuras#

O Kshana repete jamming, spoofing e holdover de relógio quando os sinais GNSS (Global Navigation Satellite System) falham, e diz por quanto tempo um sistema mantém a hora e a posição dentro do seu orçamento, e qual o relógio ou sensor que compra mais margem. Este é o pacote WebAssembly: o motor completo em JavaScript, no navegador ou em Node.js. Cada 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 completo no seu navegador, compilado para WebAssembly, e não carrega nada.

Evidências#

176 de 401 capacidades validadas face a referências independentes externas; 221 etiquetadas com honestidade como modeladas, 4 pertencentes a parceiros. Cada capacidade traz uma única etiqueta num registo 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 face ao Orekit 12,2.

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

Instalar#

npm install kshana

Utilização#

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 é a forma como o binário WebAssembly é carregado.

No navegador (através de um empacotador, ou de uma página que sirva node_modules/kshana/), init() obtém 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 ficheiro local), pelo que se lê o binário do disco e se 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

Guarde a versão Node.js como um ficheiro .mjs (ou defina "type": "module" no seu package.json) para que import funcione. A partir daí ambas 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 êxito). Os campos próprios de cada documento de resultado variam consoante o tipo de cenário; ResultDocument tipifica o envelope partilhado (schema_version, engine_version e o bloco units de 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);

Mais quatro funções descrevem o motor a uma interface. kind_modules() devolve um objeto JSON de tipo de cenário para os módulos que as suas linhas da matriz de verificação nomeiam, field_importance() um de tipo de cenário para os campos de resultado que respondem à sua pergunta (metadados de apresentaçã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 curta cena IQ sintética, adquirida e seguida em memória (no máximo 0,25 s, 1 000 000 amostras e 8 satélites), com a mesma resposta que a 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 cadeia JSON), summary, chart_svg, table_csv (a tabela CSV (valores separados por vírgulas) do cenário como cadeia, ou undefined para tipos de cenário que não publicam tabela; lança um erro perante um cenário inválido), run_all (uma execução do motor que devolve {json, svg, summary, csv} como cadeia JSON — usá-la quando se quer mais de uma saída, uma vez que cada outra chamada executa o cenário de novo), run_typed (as mesmas saídas como um objeto tipado, com o documento já analisado como data), version, list_kinds / scenario_kinds / error_kind (introspeção; scenario_kinds devolve a lista analisada), encode_permalink / decode_permalink — o codec de ligação partilhável (URL, localizador uniforme de recursos) que o Kshana Studio usa para fazer a ida e volta de um cenário inteiro através do fragmento da barra de endereços — e export_sp3 / export_omm / export_oem, os artefactos 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 escreve — e receiver_trust, que avalia um registo real de recetor descrito por um cenário receiver-trust e devolve {json, csv, svg, summary} como cadeia JSON (o navegador não tem sistema de ficheiros, pelo que o registo, e qualquer ficheiro de navegação, tem de 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 (que formatos de interoperabilidade um cenário suporta, sem o executar, 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 é carregado), import_route (uma rota GeoJSON escrita num cenário de trajetória por pontos de passagem, o --import-route da linha de comandos), animate_scenario (a série temporal da execução como SVG animado, um leitor HTML único ou fotogramas SVG), list_examples / get_example (os cenários de referência fornecidos e o seu TOML), evidence_attach_timestamp (ligar um token RFC 3161 a um pacote de evidências em memória; o pacote tem de continuar a verificar-se, e a assinatura da autoridade de carimbo temporal não é verificada), osnma_verify (que dados de navegação Galileo de que satélites um ficheiro de páginas I/NAV ou um fluxo UBX autentica, com a raiz de Merkle fiável ou as chaves públicas e uma hora de referência independente opcional; autentica dados e não faz nenhuma afirmação de desempenho antispoofing; nada é carregado), receiver_trust_replay (um excerto NMEA limitado pontuado como o modo em direto o pontua; sem barreira), assess_vessel_log (um registo 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 (verificar um pacote de evidências assinado; nada é carregado; 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 é escrito), compliance_report e compliance_mapping (a que linhas de requisitos de quadros públicos os documentos de resultado fornecem elementos de prova em apoio de, com a lacuna de cada linha; não é uma constatação de que um quadro é satisfeito), e interference_map (texto CSV de ADS-B ou AIS para um GeoJSON kshana-interference-map/v1 por dia UTC; apenas agregado), route_exposure (a parte de uma rota através de células degradadas desses mapas; não é uma previsão), nmea_training (NMEA de ponte sintético e um registo do instrutor para formação de tripulações; apenas texto, nunca para os sistemas de navegação em funcionamento 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 (que satélites um local vê quando edifícios, cais ou terreno bloqueiam parte do céu, com a diluição da 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 face a bibliotecas independentes, as predefinições são geometrias representativas e não levantamentos, e uma linha do horizonte remove satélites em linha de vista e nada mais). Não existem na compilação para navegador: receiver-trust live com a sua barreira e o seu recetor TCP, o NMEA de formação em fluxo, e os exportadores de telemetria (Prometheus, OpenTelemetry, syslog) são processos de rede de longa duração e ficam na ferramenta de linha de comandos; criar um pacote de evidências precisa de uma chave de assinatura, que pertence à CLI ou ao Python. Aqui não há uma chamada única run_full; essa ligação existe apenas no wheel de Python.

Cada capacidade da matriz de verificação é etiquetada como validada (verificada face a uma referência independente externa), modelada ou da responsabilidade de parceiros; os valores dos relógios óticos são objetivos espaciais em hardware de solo (nenhum relógio ótico de estrôncio voou). A maturidade não é uniforme entre domínios — o PNT terrestre é validado face a dados reais; a navegação no espaço profundo e em Marte é modelada, com apenas os seus blocos de construção (tempo de luz, posições dos planetas) validados face a referências independentes externas; a determinação de órbita (OD) em espaço profundo de missões reais consta do roteiro.

Capacidades#

O motor tem 92 tipos de cenário; kshana kinds os lista com os respetivos campos. Novos na 0.38.0: gnss-ssv (sinais GNSS para veículos espaciais acima, em torno 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 registo de erro de tempo face às máscaras da ITU-T).

  • Espetro: como um emissor de jamming ocupa a banda L do GNSS, banda a banda.
  • Relógios e temporização: holdover face a um limiar, transferência de tempo e holdover de telecomunicações face às máscaras do setor de normalização da União Internacional das Telecomunicações (ITU-T).
  • Constelações em torno de qualquer corpo: cobertura, diluição da precisão e disponibilidade em torno da Terra, da Lua ou de Marte, e do sistema solar numa época.
  • Navegação em órbita terrestre baixa: sinal, passagem e ligação, mensagem de navegação e uma solução de posição fundida, fase a fase.
  • Campanhas: uma missão encadeada, uma varredura ou um conjunto de Monte Carlo num só cenário.
  • Relatórios, animação e exportações: cada valor com a sua unidade e etiqueta; um desenho animado de uma execução; ficheiros 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 ao centro, kshana 0.40.0, com um despacho tipado sobre 75 tipos de cenário; à sua volta a linha de comandos, a biblioteca Rust, o Python, o WebAssembly e o Kshana Studio, o servidor MCP, a imagem Docker e o plugin JetBrains; por baixo o Kshana Pro, uma camada proprietária que depende do motor aberto e nunca o bifurcaUm motor aberto ao centro, kshana 0.40.0, com um despacho tipado sobre 75 tipos de cenário; à sua volta a linha de comandos, a biblioteca Rust, o Python, o WebAssembly e o Kshana Studio, o servidor MCP, a imagem Docker e o plugin JetBrains; por baixo o Kshana Pro, uma camada proprietária que depende do motor aberto e nunca o bifurca

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

Investigação#

Seis artigos no arXiv assentam no motor aberto, cada um com o comando que está por trás: arXiv:2606,22054 (a lacuna de otimismo dos detetores 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 à superfície lunar com interferometria de base muito longa), arXiv:2607,06212 (geometria polar sul lunar e faróis de superfície) e arXiv:2610,23871 (navegação cisluar como um problema de observabilidade: comprimento do arco, condicionamento do Gramiano e a alavanca do Doppler). Ver Investigação.

Edições#

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

Saber mais#

Licença#

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