kshana 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -64
- package/kshana_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
<a href="tests/sgp4_verification.rs"><img src="https://img.shields.io/badge/SGP4-666%2F666%20AIAA%20vectors%20%C2%B7%204.12mm-3fb950" alt="SGP4 validated against all 666 AIAA 2006-6753 vectors, worst 4.12 mm"></a>
|
|
15
15
|
<a href="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml"><img src="https://img.shields.io/badge/coverage-~97%25%20line-3fb950" alt="~97% line coverage on src/ (cargo-tarpaulin LLVM engine), gated at 85% in CI"></a>
|
|
16
16
|
<a href="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml"><img src="https://github.com/ashfordeOU/kshana/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
17
|
-
<a href="https://github.com/ashfordeOU/kshana/releases"><img src="https://img.shields.io/
|
|
17
|
+
<a href="https://github.com/ashfordeOU/kshana/releases"><img src="https://img.shields.io/badge/release-v0.16.0-c79e63" alt="Release v0.16.0"></a>
|
|
18
|
+
<a href="https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator"><img src="https://img.shields.io/badge/JetBrains-Marketplace-c79e63" alt="Kshana on the JetBrains Marketplace"></a>
|
|
18
19
|
<a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue.svg" alt="License: Apache-2.0"></a>
|
|
19
20
|
<a href="Cargo.toml"><img src="https://img.shields.io/badge/rust-1.75%2B-orange.svg" alt="Rust 1.75+"></a>
|
|
20
21
|
<a href="https://doi.org/10.5281/zenodo.20528627"><img src="https://img.shields.io/badge/DOI-10.5281%2Fzenodo.20528627-blue.svg" alt="DOI 10.5281/zenodo.20528627"></a>
|
|
@@ -43,7 +44,7 @@ citable table in [`docs/PROVENANCE.md`](docs/PROVENANCE.md).
|
|
|
43
44
|
*Free and open source under Apache-2.0, professionally developed and maintained by
|
|
44
45
|
Ashforde OÜ — commercial support, integration, and proprietary extensions available.*
|
|
45
46
|
|
|
46
|
-
> **Status: v0.
|
|
47
|
+
> **Status: v0.16.0 · a simulation substrate, not yet a product.** A validated,
|
|
47
48
|
> fully reproducible engine spanning the PNT stack — orbit geometry and constellation
|
|
48
49
|
> design, a numerical (Cowell) propagator with a six-perturbation force model, maneuver
|
|
49
50
|
> and trajectory design, time systems, inertial navigation (incl. map-aided and
|
|
@@ -104,7 +105,8 @@ geometry, inertial navigation, GNSS/INS fusion, integrity, clocks, and timing. I
|
|
|
104
105
|
runs a scenario (often a GNSS outage), evolves calibrated sensor error models
|
|
105
106
|
through the appropriate estimator, and scores the result against the operational
|
|
106
107
|
figures of merit — emitting a reproducible JSON result and an SVG chart, from a
|
|
107
|
-
Rust library, CLI, Python extension,
|
|
108
|
+
Rust library, a CLI, a Python extension, an in-browser WebAssembly module, a
|
|
109
|
+
**Model Context Protocol (MCP) server** for AI agents, or a **JetBrains IDE plugin**.
|
|
108
110
|
|
|
109
111
|
**It is not:** flight hardware, a quantum-payload design, a full GNSS signal
|
|
110
112
|
receiver, or a certified avionics product. Quantum-hardware fidelity comes from
|
|
@@ -127,14 +129,16 @@ the P2 roadmap and [get in touch](#support--professional-services) to collaborat
|
|
|
127
129
|
| Domain | Capability |
|
|
128
130
|
|--------|------------|
|
|
129
131
|
| **Orbit & geometry** | SGP4/SDP4 propagation (validated to 4.12 mm against all 666 AIAA 2006-6753 vectors); real two-line elements (a committed, date-stamped Celestrak `gps-ops` snapshot) or synthetic Walker-delta constellations whose mean elements realise the `i:T/P/F` formula to under 1 km over a 24 h propagation; multi-constellation visibility, dilution of precision, and GNSS availability; a gradient-free constellation-design optimiser, streets-of-coverage minimum-satellite sizing, a multi-constellation comparison tool, and a Walker **design sweep** that tabulates coverage / PDOP / revisit-time over a planes × satellites grid and reports the Pareto-optimal designs. |
|
|
130
|
-
| **Numerical propagator** | A **Cowell** numerical propagator (`src/propagator.rs`) complementing the analytic SGP4/SDP4 path, with a hierarchical **six-perturbation** force model (`src/forces.rs`): two-body + the full **J2–J6 zonal** field (the exact analytic gradient of its disturbing potential), **epoch-driven Sun and Moon third-body** gravity (a built-in low-precision ephemeris, no DE/SPK kernel), **solar-radiation pressure** (cannonball model with a conical umbra+penumbra shadow), **atmospheric drag** (Vallado piecewise-exponential density, co-rotating atmosphere),
|
|
132
|
+
| **Numerical propagator** | A **Cowell** numerical propagator (`src/propagator.rs`) complementing the analytic SGP4/SDP4 path, with a hierarchical **six-perturbation** force model (`src/forces.rs`): two-body + the full **J2–J6 zonal** field (the exact analytic gradient of its disturbing potential), an optional **EGM2008 tesseral spherical-harmonic geopotential to degree/order 70** (`src/gravity_sh.rs`; real NGA coefficients, Holmes–Featherstone normalized-Legendre recurrence, cross-checked against the closed-form Legendre functions and the analytic ∇V identity), **epoch-driven Sun and Moon third-body** gravity (a built-in low-precision ephemeris, no DE/SPK kernel), **solar-radiation pressure** (cannonball model with a conical umbra+penumbra shadow), **atmospheric drag** (Vallado piecewise-exponential density, co-rotating atmosphere), the **post-Newtonian Schwarzschild relativistic correction**, and the **Lense–Thirring frame-dragging** term (IERS 2010 §10, linear in Earth's angular momentum, ~1–2 orders below Schwarzschild) — driven by a choice of two adaptive integrators (RK4 step-doubling or the **Dormand–Prince RK5(4)** embedded pair). Validated against analytic truth stronger than a cross-tool would give: the unperturbed orbit matches the exact universal-variable Kepler solution to **sub-metre over 24 h**, energy/angular-momentum conserve to ~1e-9, and each perturbation matches a hand-derived closed-form signature. |
|
|
131
133
|
| **Maneuvers & trajectory design** | Impulsive ΔV nodes with 6×6 covariance propagation (ECI / LVLH execution-error frames), finite-burn integration checked against the closed-form **Tsiolkovsky** rocket equation to < 0.01 %, an **Izzo-2015** single-revolution **Lambert** solver, an exact universal-variable **Kepler** propagator, and a **porkchop** (launch × arrival) C3 / arrival-V∞ sweep emitted as a JSON contour grid — the performance-simulation layer above GMAT/Orekit, with every Lambert output round-tripped against two-body truth and the porkchop minimum checked against the analytic Hohmann floor. |
|
|
132
134
|
| **Time systems & reference frames** | IERS leap-second **UTC / TAI / TT / UT1** scales, a Julian-date API, the IAU-2000 **Earth Rotation Angle**, GMST-based **TEME ↔ ECEF** with WGS-84 geodetic frames, IAU 2006 precession (Fukushima–Williams), full **IAU 2000A/2000B nutation**, IERS **polar motion**, and the equinox-free **CIO-based IAU 2006/2000A GCRS↔ITRS** reduction — all validated **bit-for-bit** against the SOFA/ERFA vectors, and **independently cross-checked against ANISE** (the pure-Rust NAIF/SPICE reimplementation): kshana's GCRS→ITRS vs ANISE's ITRF93 from JPL's `earth_latest_high_prec.bpc`, the same IERS Earth-orientation parameters fed to both, agree to **≤ 0.86 m on the ground / ≤ 3.6 m at GNSS orbit** (max 0.028″) across eight epochs 2020–2023. |
|
|
133
135
|
| **Inertial** | Three-axis strapdown INS — quaternion attitude, WGS-84 NED mechanization, coning/sculling compensation, and a deterministic IMU error model (scale-factor, misalignment, g-sensitivity, quantization, drift); a **first-principles cold-atom-interferometer accelerometer** (Mach–Zehnder phase, quantum projection noise, contrast decay, vibration coupling) that *derives* the velocity-random-walk coefficient; and a sequential-importance-resampling **particle filter** for map-aided (terrain-/gravity-referenced) GPS-denied navigation. |
|
|
134
|
-
| **
|
|
136
|
+
| **Alt-PNT (GPS-denied)** | A cold-atom **gravimeter measurement model** whose white-noise floor (`σ = ASD/√τ`) is derived from the CAI accelerometer physics; a low-degree, fully-normalised **spherical-harmonic gravity-anomaly field** (validated against the closed-form Legendre functions and a hand-derived single-term anomaly) plus synthetic mascons; and a **gravity-map-matching particle filter** that recovers a GPS-denied track from the anomaly sequence it flies through. It extends to **terrain-referenced navigation** (TERCOM/SITAN against an SRTM `.hgt` DEM, `src/altpnt/terrain.rs`), an **IGRF-14 geomagnetic main field** to degree/order 13 (`src/igrf.rs`, validated against the tilted-dipole closed form and ∇V finite differences), and a **combined gravity + magnetic + terrain** navigator that fuses all three scalar channels through one particle filter (information is additive — no channel makes the fix worse). A **60-minute GPS-denied benchmark** (a ~700 km / one-hour outage where the inertial solution drifts to ~70 km) is recovered to **~145 m (< 500 m)** by a hierarchical coarse-to-fine matcher — the ESA NAVISP *Quantum Wayfarer* target. |
|
|
135
137
|
| **Fusion** | Loosely-coupled 15-state GNSS/INS error-state EKF with closed-loop feedback (the `gnss-ins` pack); a **tightly-coupled** pseudorange update that keeps correcting with fewer than four satellites; a coupled **clock + position** filter; a general **unscented (sigma-point) Kalman** estimator for strongly nonlinear measurements; a tightly-coupled GNSS/INS **UKF navigator** (pseudorange + Doppler) whose force-model orbital coast is validated to **0.77 m RMS** over a 30-minute curving LEO pass that includes a 120-second GNSS outage; and a full **17-state tightly-coupled GNSS/INS UKF** (position, velocity, attitude error, accelerometer and gyro biases, clock bias and drift) whose **quantum-CAI dead-reckoning** coasts a 120-second outage on the cold-atom accelerometer's derived velocity-random-walk. |
|
|
136
138
|
| **Orbit determination** | Recovery of an orbital state `[r, v]` from ground-station range tracking, composing the two-body + J2 force model and RK4 integrator with a **Gauss–Newton batch** corrector (`determine_orbit_batch`, sub-metre / mm·s⁻¹ from noiseless ranges, ~2 m at a 5 m noise floor) and a **sequential** unscented-filter variant (`determine_orbit_sequential`). |
|
|
137
|
-
| **
|
|
139
|
+
| **Lunar & cislunar** | An Earth–Moon **circular restricted three-body (CR3BP)** propagator in the rotating frame — conserved Jacobi constant and all five Lagrange points (`src/cr3bp.rs`) — plus **LunaNet / LNIS** cislunar PNT geometry (MCI↔MCMF reduction, selenographic coordinates) with a **lunar south-pole ARAIM** pass that honestly surfaces the integrity gap: a ~30 m σ_URE drives the protection level well above a 50 m alert limit (`src/lunar.rs`, `scenarios/lunanet-araim.toml`). |
|
|
140
|
+
| **Integrity** | Snapshot and solution-separation (ARAIM-style) RAIM with horizontal/vertical protection levels (HPL/VPL), fault detection & exclusion, and Stanford integrity diagrams; an explicit integrity-risk-budget (**MHSS**) protection level, including the **dual-/multi-constellation constellation-wide fault mode** (EU ARAIM / DO-316), exercised on a real GPS + Galileo snapshot (`scenarios/araim-gps-galileo.toml`). |
|
|
141
|
+
| **Augmentation (SBAS)** | **SBAS / WAAS protection levels** in the DO-229E weighted-least-squares form (precision-approach and en-route K-factors) and the **L1/L5 dual-frequency ionosphere-free** combination (IS-GPS-705, γ₁₅ ≈ 1.793) that underpins DO-316 — `src/sbas.rs`, with the protection-level geometry cross-checked against a NumPy `inv(GᵀG)` reference. |
|
|
138
142
|
| **Clock & timing** | Two-state Kalman holdover (Joseph-form covariance, NIS/NEES consistency health); Allan-family stability (ADEV / MDEV / TDEV / HDEV) with noise-type-specific confidence intervals and a full **IEEE-1139 five-coefficient power-law fit**; geometric corrections (Sagnac, GNSS common-view); and the operational transfer methods — **TWSTFT** with the BIPM Sagnac closed form, **GNSS common-view**, **PPP** ionosphere-free time transfer, a free-space **optical** link with turbulence scintillation, and an inverse-variance **clock-ensemble (paper) timescale** below the best contributing clock. |
|
|
139
143
|
| **GNSS measurement domain** | Forward pseudorange / Doppler synthesis with **Klobuchar** (broadcast) and **IONEX / TEC-grid** (measured) ionosphere — including an IONEX file parser, time interpolation between maps, and the thin-shell slant-obliquity mapping — **Saastamoinen + Niell** troposphere, and snapshot RAIM (HPL/VPL). |
|
|
140
144
|
| **Resilience** | Link-budget **jamming** (J/S → effective C/N₀ → loss of lock); a stochastic **time-spoof detector** (Neyman–Pearson / χ²₁ energy test with closed-form and Monte-Carlo P_fa/P_md and a Security FoM of 1 − P_md); and a **multi-layer spoof detector** fusing a RAIM-consistency parity test (with the common-mode blind spot modelled honestly), an RF AGC-power monitor, and a signal-quality (SQM early-minus-late) monitor. |
|
|
@@ -167,6 +171,13 @@ The capstone shows the fusion thesis: optical inter-satellite time-transfer keep
|
|
|
167
171
|
a classical *clock* locked, isolating the *inertial* sensor as the classical suite's
|
|
168
172
|
weak link — i.e. quantum inertial + optical timing together.
|
|
169
173
|
|
|
174
|
+
<p align="center">
|
|
175
|
+
<img src="docs/assets/clock-holdover.svg" alt="Clock holdover: phase error during a GNSS outage — the optical clock stays within the 20 ns spec for the whole outage while the chip-scale clock breaches it mid-outage" width="80%">
|
|
176
|
+
<br><em>Clock holdover through a GNSS outage: the optical clock (blue) stays inside the
|
|
177
|
+
20 ns spec for the full coast; the chip-scale clock (red) breaches it part-way.
|
|
178
|
+
Generated by Kshana from <code>scenarios/clock-holdover.toml</code>.</em>
|
|
179
|
+
</p>
|
|
180
|
+
|
|
170
181
|
A further scenario, `orbit-gnss-challenged.toml`, derives GNSS availability from
|
|
171
182
|
**orbital geometry** rather than hand-authored windows: a spacecraft inside the GNSS
|
|
172
183
|
shell is propagated against a GPS-like Walker constellation, and the visible-satellite
|
|
@@ -175,6 +186,14 @@ step. Over a day the user is in fix only ~59% of the time; the quantum clock hol
|
|
|
175
186
|
5 ns timing solution through every gap (availability **1.0**), the chip-scale clock
|
|
176
187
|
only **~0.83**.
|
|
177
188
|
|
|
189
|
+
<p align="center">
|
|
190
|
+
<img src="docs/assets/orbit-gnss-challenged.svg" alt="Orbit GNSS-challenged: visible-satellite count and fix state over a day for a spacecraft inside the GNSS shell" width="80%">
|
|
191
|
+
<br><em>GNSS availability derived from orbital geometry: the visible-satellite count
|
|
192
|
+
(line-of-sight, Earth-occultation, elevation mask) sets the fix state at each step,
|
|
193
|
+
so the clock must coast every gap. Generated by Kshana from
|
|
194
|
+
<code>scenarios/orbit-gnss-challenged.toml</code>.</em>
|
|
195
|
+
</p>
|
|
196
|
+
|
|
178
197
|
The constellation can also be given as real two-line element sets. A *full* TLE
|
|
179
198
|
(line 1 + line 2) is propagated with the full **SGP4/SDP4** model — including
|
|
180
199
|
atmospheric drag and the deep-space lunar-solar and 12 h / 24 h resonance terms that
|
|
@@ -322,15 +341,17 @@ Then register `kshana-mcp` in your client's `mcpServers` config — see
|
|
|
322
341
|
server is a standalone, workspace-excluded crate (the `rmcp` SDK is edition 2024), so it
|
|
323
342
|
never affects the lean published `kshana` crate or its build.
|
|
324
343
|
|
|
325
|
-
**In a JetBrains IDE** you can also install the
|
|
326
|
-
|
|
327
|
-
|
|
344
|
+
**In a JetBrains IDE** you can also install the
|
|
345
|
+
[**Kshana — PNT simulator**](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator)
|
|
346
|
+
plugin from the JetBrains Marketplace (or *Settings → Plugins → Marketplace → search
|
|
347
|
+
"Kshana"*) to run scenarios from a right-click — see [`ide/jetbrains/`](ide/jetbrains/).
|
|
328
348
|
|
|
329
349
|
## Scenario format
|
|
330
350
|
|
|
331
|
-
Scenarios are declarative TOML. A top-level `kind` selects the pack
|
|
332
|
-
the default if omitted
|
|
333
|
-
`gnss-ins`, `orbit`, `gnss-sim`, `integrity`, `
|
|
351
|
+
Scenarios are declarative TOML. A top-level `kind` selects the pack — **seventeen** in
|
|
352
|
+
all (`clock` is the default if omitted): `inertial`, `timetransfer`, `hybrid`, `fusion`,
|
|
353
|
+
`gnss-ins`, `orbit`, `gnss-sim`, `integrity`, `lunar-integrity`, `spoof`, `jamming`,
|
|
354
|
+
`sweep`, `sweep-nd`, `gravity-map`, `terrain-nav`, and `combined-altpnt`.
|
|
334
355
|
Common fields: `seed`, a `[time]` grid, a `[gnss]` availability timeline (the outage
|
|
335
356
|
driver), and per-sensor blocks with `provenance` strings citing the source of every
|
|
336
357
|
figure. Example (clock):
|
|
@@ -473,6 +494,20 @@ phasing_f = 1.0
|
|
|
473
494
|
[clock_classical] # ... as above
|
|
474
495
|
```
|
|
475
496
|
|
|
497
|
+
The **GPS-denied alt-PNT** kinds navigate with no GNSS at all, matching a measured field
|
|
498
|
+
sequence against a map through a particle filter. A `gravity-map` scenario flies a track
|
|
499
|
+
through a spherical-harmonic gravity-anomaly field and recovers it from a cold-atom
|
|
500
|
+
gravimeter's reading (`scenarios/gps-denied-gravity-nav.toml`); a `terrain-nav` scenario
|
|
501
|
+
does the same against an SRTM elevation DEM (TERCOM/SITAN, `scenarios/terrain-nav.toml`);
|
|
502
|
+
and a `combined-altpnt` scenario fuses **gravity + IGRF magnetic + terrain** in one filter
|
|
503
|
+
(`scenarios/combined-altpnt.toml`).
|
|
504
|
+
|
|
505
|
+
A `lunar-integrity` scenario evaluates **cislunar** PNT: it runs a lunar south-pole
|
|
506
|
+
ARAIM protection-level pass against a LunaNet/LNIS relay set and honestly reports the
|
|
507
|
+
integrity gap — a ~30 m lunar σ_URE drives the protection level well above a 50 m alert
|
|
508
|
+
limit, so the service is *unavailable* under aviation-style integrity rules
|
|
509
|
+
(`scenarios/lunanet-araim.toml`).
|
|
510
|
+
|
|
476
511
|
See `scenarios/` for one example of every kind.
|
|
477
512
|
|
|
478
513
|
## Output
|
|
@@ -515,11 +550,24 @@ New to these terms? Each is defined in plain language in the [glossary](docs/GLO
|
|
|
515
550
|
|
|
516
551
|
## Architecture
|
|
517
552
|
|
|
518
|
-
One engine
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
553
|
+
**One engine, many front doors.** A single Rust core (`kshana`) runs every scenario,
|
|
554
|
+
reached through a CLI, a Python extension, an in-browser WebAssembly module, an **MCP
|
|
555
|
+
server** for AI agents, and a **JetBrains IDE plugin** — all converging on one
|
|
556
|
+
`api::run_toml` dispatch. Inside, the sensor packs plug into a common error-model
|
|
557
|
+
interface; alongside them sit a **reference-frame layer** (IAU 2006/2000A
|
|
558
|
+
precession–nutation and the CIO-based GCRS↔ITRS reduction), an **astrodynamics/numerical
|
|
559
|
+
layer** (analytic SGP4/SDP4 **and** a numerical Cowell propagator with its
|
|
560
|
+
EGM2008/perturbation force model, maneuver design, and orbit determination), an
|
|
561
|
+
**integrity/GNSS layer** (RAIM/ARAIM, SBAS, the measurement domain, jamming, cislunar),
|
|
562
|
+
and a **fusion / alt-PNT layer** (the GNSS/INS estimators and the gravity/terrain/magnetic
|
|
563
|
+
map-matchers).
|
|
564
|
+
|
|
565
|
+
Two standalone, **workspace-excluded** crates sit beside the core — `mcp/kshana-mcp`
|
|
566
|
+
(the MCP server, built on the edition-2024 `rmcp` SDK) and `xval/anise-frames` (the
|
|
567
|
+
ANISE/SPICE frame cross-check, which pulls MPL-2.0 deps) — kept out of the published
|
|
568
|
+
crate's dependency graph, `Cargo.lock`, license gate, and MSRV build by the root
|
|
569
|
+
`Cargo.toml` `exclude` list. The JetBrains plugin (`ide/jetbrains`) is a separate Kotlin
|
|
570
|
+
project. See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full set of diagrams.
|
|
523
571
|
|
|
524
572
|
```mermaid
|
|
525
573
|
flowchart LR
|
|
@@ -534,85 +582,138 @@ flowchart LR
|
|
|
534
582
|
|
|
535
583
|
```mermaid
|
|
536
584
|
flowchart TD
|
|
537
|
-
cli["CLI · Python · WebAssembly"] --> api["api — run_toml
|
|
585
|
+
cli["CLI · Python · WebAssembly · MCP server · JetBrains plugin"] --> api["api — run_toml: typed dispatch over 17 kinds"]
|
|
538
586
|
subgraph shared["Shared core"]
|
|
539
|
-
types["types"]
|
|
540
|
-
|
|
541
|
-
|
|
587
|
+
types["types · scenario · GNSS timeline"]
|
|
588
|
+
allan["allan — ADEV/MDEV/TDEV/HDEV"]
|
|
589
|
+
end
|
|
590
|
+
subgraph frames["Time & reference frames"]
|
|
591
|
+
ts["timescales · jd2 — UTC/TAI/TT/UT1"]
|
|
592
|
+
pn["precession · nutation — IAU 2006/2000A"]
|
|
593
|
+
cio["cio — GCRS↔ITRS (CIO, SOFA-anchored)"]
|
|
542
594
|
end
|
|
543
595
|
subgraph packs["Sensor packs"]
|
|
544
|
-
p1["
|
|
596
|
+
p1["clock — models · estimator · kalman · security"]
|
|
545
597
|
p2["inertial — strapdown INS + quantum-CAI"]
|
|
546
|
-
p3["timetransfer
|
|
598
|
+
p3["timetransfer — optical/RF/TWSTFT/PPP"]
|
|
547
599
|
p4["hybrid — fused PNT suite"]
|
|
548
600
|
end
|
|
549
601
|
subgraph astro["Astrodynamics & numerical"]
|
|
550
|
-
orbit["orbit — geometry → GNSS
|
|
602
|
+
orbit["orbit · walker — geometry → GNSS + DOP"]
|
|
551
603
|
sgp4["sgp4 · tle — SGP4/SDP4"]
|
|
552
604
|
prop["propagator — Cowell"]
|
|
553
|
-
forces["forces — J2–J6 · 3rd-body · SRP · drag ·
|
|
605
|
+
forces["forces — J2–J6 · 3rd-body · SRP · drag · GR"]
|
|
606
|
+
gsh["gravity_sh — EGM2008 d/o 70"]
|
|
554
607
|
integ["integrator — RK4 · DOPRI"]
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
608
|
+
man["maneuver · orbit_determination"]
|
|
609
|
+
cr["cr3bp — Earth–Moon CR3BP"]
|
|
610
|
+
end
|
|
611
|
+
subgraph intg["Integrity & GNSS"]
|
|
612
|
+
raim["raim — RAIM/ARAIM · HPL/VPL"]
|
|
613
|
+
sbas["sbas — DO-229E PL · L1/L5"]
|
|
614
|
+
gsim["gnss_sim · ionex — measurement domain"]
|
|
615
|
+
jam["jamming — J/S → C/N₀"]
|
|
616
|
+
lun["lunar — cislunar ARAIM"]
|
|
558
617
|
end
|
|
559
618
|
subgraph fnav["Fusion & alt-PNT"]
|
|
560
619
|
fus["fusion — EKF · UKF · 17-state · coupled"]
|
|
561
620
|
grav["gravimeter · mapmatch · particle_filter"]
|
|
621
|
+
terr["altpnt/terrain · igrf — terrain + magnetic"]
|
|
622
|
+
end
|
|
623
|
+
subgraph io["Interop formats"]
|
|
624
|
+
iofmt["rinex · sp3 · oem · omm · glonass"]
|
|
562
625
|
end
|
|
563
626
|
api --> packs
|
|
564
627
|
api --> astro
|
|
628
|
+
api --> intg
|
|
565
629
|
api --> fnav
|
|
566
630
|
packs --> shared
|
|
631
|
+
astro --> frames
|
|
567
632
|
orbit --> sgp4
|
|
568
633
|
prop --> forces
|
|
634
|
+
prop --> gsh
|
|
569
635
|
prop --> integ
|
|
570
|
-
|
|
571
|
-
man --> integ
|
|
572
|
-
od --> forces
|
|
573
|
-
od --> integ
|
|
636
|
+
cr --> integ
|
|
574
637
|
fus --> p2
|
|
575
638
|
grav --> p2
|
|
639
|
+
terr --> grav
|
|
576
640
|
orbit --> p1
|
|
641
|
+
orbit --> io
|
|
577
642
|
p4 -. composes .-> p1
|
|
578
643
|
p4 -. composes .-> p2
|
|
579
644
|
p4 -. composes .-> p3
|
|
580
645
|
```
|
|
581
646
|
|
|
647
|
+
**Components & distribution.** The core crate ships through the Rust, Python, and
|
|
648
|
+
JavaScript ecosystems; the MCP server and IDE plugin reach AI agents and JetBrains IDEs.
|
|
649
|
+
Each `vX.Y.Z` tag republishes every channel automatically (see
|
|
650
|
+
[Versioning & releases](#versioning--releases)).
|
|
651
|
+
|
|
652
|
+
```mermaid
|
|
653
|
+
flowchart LR
|
|
654
|
+
subgraph repo["One repository"]
|
|
655
|
+
core["kshana core<br/>library + CLI"]
|
|
656
|
+
mcp["mcp/kshana-mcp<br/>MCP server (excluded crate)"]
|
|
657
|
+
ide["ide/jetbrains<br/>Kotlin IDE plugin"]
|
|
658
|
+
xval["xval/anise-frames<br/>SPICE cross-check (excluded)"]
|
|
659
|
+
end
|
|
660
|
+
core --> crates["crates.io"]
|
|
661
|
+
core --> pypi["PyPI — wheels"]
|
|
662
|
+
core --> npm["npm — WebAssembly"]
|
|
663
|
+
core --> rel["GitHub Releases<br/>binaries · SBOM · SLSA · validation summary"]
|
|
664
|
+
core --> pages["kshana.dev<br/>GitHub Pages playground"]
|
|
665
|
+
core -. archived .-> zen["Zenodo DOI"]
|
|
666
|
+
mcp --> crates
|
|
667
|
+
mcp --> ghcr["ghcr.io — OCI image"]
|
|
668
|
+
mcp --> reg["official MCP registry"]
|
|
669
|
+
ide --> jb["JetBrains Marketplace"]
|
|
670
|
+
```
|
|
671
|
+
|
|
582
672
|
## Repository layout
|
|
583
673
|
|
|
584
674
|
```
|
|
585
675
|
kshana/
|
|
586
|
-
├── src/
|
|
587
|
-
│ ├──
|
|
588
|
-
│ ├──
|
|
589
|
-
│ ├──
|
|
676
|
+
├── src/ # the kshana core crate (library + CLI)
|
|
677
|
+
│ ├── api.rs · main.rs · lib.rs # typed dispatch (17 kinds) + CLI + crate root
|
|
678
|
+
│ ├── python.rs · wasm.rs # optional PyO3 / wasm-bindgen bindings
|
|
679
|
+
│ ├── types.rs · scenario.rs · allan.rs # shared core (time grid, GNSS timeline, Allan)
|
|
590
680
|
│ │
|
|
591
|
-
│ ├── models.rs · estimator.rs · kalman.rs
|
|
592
|
-
│ ├── security.rs · detection.rs · spoof.rs · spoof_monitors.rs
|
|
681
|
+
│ ├── models.rs · estimator.rs · kalman.rs # Pack 1 — clock holdover + integrity
|
|
682
|
+
│ ├── security.rs · detection.rs · spoof.rs · spoof_monitors.rs # spoof detection
|
|
593
683
|
│ ├── filter_health.rs · fom.rs · report.rs · chart.rs · run.rs # health · scoring · output
|
|
594
|
-
│ ├── inertial/
|
|
595
|
-
│ ├── timetransfer.rs · timetransfer_adv.rs · timegeo.rs
|
|
596
|
-
│ ├── hybrid.rs · ensemble.rs · sweep.rs
|
|
684
|
+
│ ├── inertial/ # Pack 2 — strapdown INS (attitude · mechanization · imu_errors · quantum_imu)
|
|
685
|
+
│ ├── timetransfer.rs · timetransfer_adv.rs · timegeo.rs # Pack 3 — TWSTFT/CV/PPP/optical, Sagnac
|
|
686
|
+
│ ├── hybrid.rs · ensemble.rs · sweep.rs # Pack 4 — fused PNT, Monte-Carlo, trade sweeps
|
|
687
|
+
│ │
|
|
688
|
+
│ ├── timescales.rs · jd2.rs · ephem.rs # time systems, two-part JD, Sun/Moon ephemeris
|
|
689
|
+
│ ├── precession.rs · nutation.rs · cio.rs # IAU 2006/2000A precession-nutation + CIO GCRS↔ITRS
|
|
690
|
+
│ ├── frames.rs · *_data.rs # TEME↔ECEF + generated nutation/CIO/EGM2008/IGRF tables
|
|
597
691
|
│ │
|
|
598
692
|
│ ├── orbit.rs · sgp4.rs · tle.rs · walker.rs # geometry, SGP4/SDP4, TLE, Walker design
|
|
599
|
-
│ ├── propagator.rs · forces.rs · integrator.rs
|
|
600
|
-
│ ├──
|
|
601
|
-
│ ├──
|
|
693
|
+
│ ├── propagator.rs · forces.rs · gravity_sh.rs · integrator.rs # Cowell + perturbations (EGM2008 d/o70, GR) + RK4/DOPRI
|
|
694
|
+
│ ├── maneuver.rs · batch_ls.rs · orbit_determination.rs # burns/Lambert/porkchop, Gauss-Newton, OD
|
|
695
|
+
│ ├── cr3bp.rs · lunar.rs # Earth–Moon CR3BP, cislunar/LunaNet ARAIM
|
|
602
696
|
│ │
|
|
603
|
-
│ ├── fusion/
|
|
604
|
-
│ ├──
|
|
605
|
-
│ ├──
|
|
606
|
-
│ ├──
|
|
607
|
-
│
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
├──
|
|
611
|
-
├──
|
|
612
|
-
├──
|
|
613
|
-
|
|
614
|
-
├──
|
|
615
|
-
|
|
697
|
+
│ ├── fusion/ # GNSS/INS — EKF · UKF · tightly_coupled(17) · coupled · closed_loop
|
|
698
|
+
│ ├── raim.rs · sbas.rs # RAIM/ARAIM HPL/VPL, SBAS DO-229E PLs + L1/L5 iono-free
|
|
699
|
+
│ ├── gnss_sim.rs · ionex.rs · jamming.rs # measurement domain, ionosphere maps, jamming
|
|
700
|
+
│ ├── gravimeter.rs · igrf.rs · mapmatch.rs · particle_filter.rs · altpnt/ # gravity/magnetic/terrain alt-PNT
|
|
701
|
+
│ ├── rinex.rs · rinex_obs.rs · glonass.rs · sp3.rs · oem.rs · omm.rs · permalink.rs # interop formats
|
|
702
|
+
│ └── bin/validation_report.rs # builds the release validation-summary HTML
|
|
703
|
+
│
|
|
704
|
+
├── mcp/kshana-mcp/ # standalone, workspace-EXCLUDED crate — the MCP server (+ Dockerfile, server.json)
|
|
705
|
+
├── ide/jetbrains/ # standalone Kotlin/Gradle IntelliJ-Platform plugin
|
|
706
|
+
├── xval/anise-frames/ # standalone, workspace-EXCLUDED crate — ANISE/SPICE frame cross-check
|
|
707
|
+
│
|
|
708
|
+
├── scenarios/ # one cited .toml per kind + geometry-driven + GPS-denied
|
|
709
|
+
├── scripts/ # reproducibility + repo-hygiene + SBOM guards
|
|
710
|
+
├── docs/ # CONCEPTS, ARCHITECTURE, CAPABILITY, VALIDATION, PROVENANCE, GLOSSARY, …
|
|
711
|
+
├── web/ # the WebAssembly playground + kshana.dev site
|
|
712
|
+
├── tools/ # table generators (EGM2008 · IGRF · nutation · CIO) + fetch_tles.sh
|
|
713
|
+
├── .github/workflows/ # ci · release · publish · wheels · pages · mcp-publish · jetbrains-plugin · frame-xval
|
|
714
|
+
├── pyproject.toml # Python packaging (maturin)
|
|
715
|
+
├── CHANGELOG.md # Keep a Changelog + SemVer
|
|
716
|
+
└── CITATION.cff · ROADMAP.md · CONTRIBUTING.md · SECURITY.md
|
|
616
717
|
```
|
|
617
718
|
|
|
618
719
|
## Documentation
|
|
@@ -627,7 +728,15 @@ kshana/
|
|
|
627
728
|
| [Provenance](docs/PROVENANCE.md) | reviewers / citers | every sensor parameter, model, and dataset traced to its published source, in one citable table |
|
|
628
729
|
| [Reproducibility & provenance](docs/REPRODUCIBILITY.md) | reviewers / packagers | determinism guarantees, golden-pinning, SBOM, build provenance |
|
|
629
730
|
| [Positioning](docs/POSITIONING.md) | evaluators | where Kshana sits vs RTKLIB/gLAB (complementary), and the zero-install browser tier |
|
|
731
|
+
| [Technical report](paper/kshana-technical-report.md) · [JOSS paper](paper/paper.md) | reviewers / citers / evaluators | the full extended research paper — architecture, per-domain models, validation, case studies, and limitations — plus the concise JOSS submission |
|
|
630
732
|
| [SGP4 validation](docs/SGP4-VALIDATION.md) | reviewers / citers | agreement with the AIAA 2006-6753 reference (666 states, ~4 mm) **and** a head-to-head against the independent `sgp4` crate (agree to sub-micron / 4.12 mm) |
|
|
733
|
+
| [Integrity FoM](docs/INTEGRITY.md) | evaluators | what the `integrity` / `security` figures mean — and what they are **not** vs aviation HPL/VPL |
|
|
734
|
+
| [Quantum models](docs/QUANTUM.md) · [details](docs/QUANTUM-MODELS.md) | reviewers | the cold-atom-interferometer physics layer, and where coefficients are still looked up |
|
|
735
|
+
| [Compliance](docs/COMPLIANCE.md) | evaluators | DO-229E / DO-316 algorithm scope, and what is **not** a conformance claim |
|
|
736
|
+
| [Result schema](docs/SCHEMA.md) | integrators | every field of the result JSON, with units and a source pointer |
|
|
737
|
+
| [Claims vs reality](docs/CLAIMS-VS-REALITY.md) | reviewers | the overclaim-closure ledger + the CI guard (`tests/no_overclaims.rs`) that keeps it resolved |
|
|
738
|
+
| [Roadmap](ROADMAP.md) | everyone | the phased roadmap — what has shipped and what is next |
|
|
739
|
+
| [MCP server](mcp/kshana-mcp/README.md) · [JetBrains plugin](ide/jetbrains/README.md) | agents / IDE users | run Kshana from an AI assistant or a JetBrains IDE |
|
|
631
740
|
| [Changelog](CHANGELOG.md) | everyone | released history (Keep a Changelog + SemVer) |
|
|
632
741
|
| [Contributing](CONTRIBUTING.md) | contributors | build, guards, test/citation discipline, DCO |
|
|
633
742
|
| [Code of Conduct](CODE_OF_CONDUCT.md) | community | expected conduct (Contributor Covenant) |
|
|
@@ -646,6 +755,32 @@ kshana/
|
|
|
646
755
|
- Maturity is stated honestly: optical-clock and optical-link figures are *targets /
|
|
647
756
|
ground-demonstrator* results, not flown.
|
|
648
757
|
|
|
758
|
+
### Validation at a glance
|
|
759
|
+
|
|
760
|
+
Every row is enforced by a named test in CI; the full evidence (and what is *not*
|
|
761
|
+
modelled) is in [`docs/VALIDATION.md`](docs/VALIDATION.md) and the per-release
|
|
762
|
+
[`kshana-validation-summary.html`](https://github.com/AshfordeOU/kshana/releases)
|
|
763
|
+
artifact (generated by `cargo run --bin validation_report`, SLSA-attested).
|
|
764
|
+
|
|
765
|
+
| Capability | Agreement | Reference / oracle |
|
|
766
|
+
|------------|-----------|--------------------|
|
|
767
|
+
| SGP4/SDP4 propagation | 666/666 vectors, worst **4.12 mm** | AIAA 2006-6753 (Vallado `tcppver.out`) + head-to-head vs the independent `sgp4` crate |
|
|
768
|
+
| Reference frames — IAU 2000A/B nutation, IAU 2006/2000A CIO chain, ERA | **bit-for-bit** (X,Y to 1e-14, s to 1e-18, ERA to 1e-12) | ERFA/SOFA `eraXys06a` · `eraC2ixys` · `eraEra00` · `eraNut00a/b` |
|
|
769
|
+
| GCRS→ITRS vs an independent SPICE engine | max **0.028″** → ≤ 0.86 m ground, ≤ 3.6 m GNSS orbit | ANISE (pure-Rust NAIF/SPICE), same IERS `finals2000A` EOP, 8 epochs 2020–2023 |
|
|
770
|
+
| EGM2008 geopotential (degree/order 70) | acceleration = ∇V to **< 1e-6**; zonal collapse to validated J2 | NGA EGM2008 coefficients + analytic ∇V identity |
|
|
771
|
+
| Allan estimators (ADEV/MDEV/TDEV/HDEV) + confidence bands | reproduce reference deviations; χ² bands match | NIST SP 1065 (Riley), 1000-point Table 31/32 |
|
|
772
|
+
| IMU error model — ARW / VRW / bias-instability | recovered to **< 5 %** (bias-instability < 15 %) | Analog Devices ADIS16465 datasheet; NaveGo reference profile |
|
|
773
|
+
| Numerical (Cowell) propagator, unperturbed | **sub-metre over 24 h**; energy/momentum conserve ~1e-9 | exact universal-variable Kepler |
|
|
774
|
+
| Lambert · Tsiolkovsky · porkchop | round-trip to two-body truth; ΔV **< 0.01 %** | Izzo 2015 · rocket equation · analytic Hohmann floor |
|
|
775
|
+
| Orbit determination (Gauss–Newton batch) | sub-m / mm·s⁻¹ noiseless; ~2 m at a 5 m noise floor | two-body + J2 over an RK4 arc |
|
|
776
|
+
| Tightly-coupled GNSS/INS UKF | **0.77 m RMS** over a 30-min LEO pass incl. a 120 s outage | force-model coast, hand-derived |
|
|
777
|
+
| GPS-denied gravity-map navigation | ~70 km INS drift → **~145 m** recovered | ESA NAVISP *Quantum Wayfarer* target |
|
|
778
|
+
| Terrain-referenced navigation (TERCOM/SITAN) | 70 km drift → **< 500 m** (grid-resolution floor ~140 m) | SRTM `.hgt` DEM; hand-injected drift (non-circular check) |
|
|
779
|
+
| IGRF-14 main field (degree/order 13) | pole ~80.7°N, dipole ~29.7 µT, physical 22–67 µT band | IAGA `igrf14coeffs.txt` (Schmidt semi-normalised) |
|
|
780
|
+
| ARAIM dual-constellation integrity | constellation-wide fault mode on real GPS + Galileo | EU ARAIM TR / DO-316; Celestrak `gps-ops` 2021-07-28 |
|
|
781
|
+
| Cross-platform reproducibility | bit-identical input + shape goldens on 3 OSes | Linux / macOS / Windows CI matrix, SHA-256 goldens |
|
|
782
|
+
| Test coverage | **~97 % line** on `src/`, gated ≥ 85 % | cargo-tarpaulin (LLVM engine) |
|
|
783
|
+
|
|
649
784
|
## FAQ
|
|
650
785
|
|
|
651
786
|
**Do I need to understand quantum physics to use this?**
|
|
@@ -738,7 +873,7 @@ entry for every user-visible change. Participation is governed by our
|
|
|
738
873
|
|
|
739
874
|
If you use Kshana in academic or technical work, please cite it. Machine-readable
|
|
740
875
|
metadata is in [`CITATION.cff`](CITATION.cff) (GitHub renders a "Cite this repository"
|
|
741
|
-
button from it); cite the version you used (e.g. `v0.
|
|
876
|
+
button from it); cite the version you used (e.g. `v0.16.0`) together with the
|
|
742
877
|
scenario and seed for full reproducibility. Every release is archived on Zenodo with
|
|
743
878
|
a citable DOI — the concept DOI [10.5281/zenodo.20528627](https://doi.org/10.5281/zenodo.20528627)
|
|
744
879
|
always resolves to the latest version.
|
|
@@ -748,12 +883,28 @@ always resolves to the latest version.
|
|
|
748
883
|
## Versioning & releases
|
|
749
884
|
|
|
750
885
|
Kshana follows [Semantic Versioning](https://semver.org). While pre-1.0 the public
|
|
751
|
-
scenario/result schema may still change; breaking changes are called out explicitly
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
886
|
+
scenario/result schema may still change; breaking changes are called out explicitly in
|
|
887
|
+
the [`CHANGELOG.md`](CHANGELOG.md). Every result is reproducible from
|
|
888
|
+
`scenario + seed + engine version`.
|
|
889
|
+
|
|
890
|
+
**Every `vX.Y.Z` tag publishes all channels automatically** — one CI pipeline fans out to:
|
|
891
|
+
|
|
892
|
+
| Channel | Install / get | Contents |
|
|
893
|
+
|---------|---------------|----------|
|
|
894
|
+
| [crates.io](https://crates.io/crates/kshana) | `cargo install kshana` · `kshana = "0.16"` | Rust library + CLI |
|
|
895
|
+
| [crates.io](https://crates.io/crates/kshana-mcp) | `cargo install kshana-mcp` | the MCP server |
|
|
896
|
+
| [PyPI](https://pypi.org/project/kshana/) | `pip install kshana` | abi3 wheels (Linux/macOS/Windows) + sdist |
|
|
897
|
+
| [npm](https://www.npmjs.com/package/kshana) | `npm install kshana` | WebAssembly module + JS wrapper |
|
|
898
|
+
| [ghcr.io](https://github.com/AshfordeOU/kshana/pkgs/container/kshana-mcp) | `docker run -i ghcr.io/ashfordeou/kshana-mcp` | multi-arch OCI image — no toolchain needed |
|
|
899
|
+
| official MCP registry | auto-discovered by MCP clients | `io.github.ashfordeOU/kshana-mcp` |
|
|
900
|
+
| [JetBrains Marketplace](https://plugins.jetbrains.com/plugin/32181-kshana--pnt-simulator) | IDE → Plugins → search "Kshana" | the **Kshana — PNT simulator** IDE plugin |
|
|
901
|
+
| [GitHub Releases](https://github.com/AshfordeOU/kshana/releases) | download | `kshana` + `kshana-mcp` binaries, a CycloneDX **SBOM**, **SLSA** build provenance, and an HTML validation summary |
|
|
902
|
+
| [Zenodo](https://doi.org/10.5281/zenodo.20528627) | DOI | a citable archive of every release |
|
|
903
|
+
| [kshana.dev](https://kshana.dev) | open in a browser | the WebAssembly playground (redeployed from `main`) |
|
|
904
|
+
|
|
905
|
+
The MCP server's crate / image / registry version tracks the engine (it bundles the
|
|
906
|
+
library); the JetBrains plugin versions independently (it shells out to your installed
|
|
907
|
+
`kshana` binary).
|
|
757
908
|
|
|
758
909
|
## License
|
|
759
910
|
|
package/kshana_bg.wasm
CHANGED
|
Binary file
|
package/package.json
CHANGED