Skip to content

Enhance SGP4 with WASM backend, new sensors, and orbit design tools - #51

Open
thkruz wants to merge 20 commits into
mainfrom
develop
Open

Enhance SGP4 with WASM backend, new sensors, and orbit design tools#51
thkruz wants to merge 20 commits into
mainfrom
develop

Conversation

@thkruz

@thkruz thkruz commented Jul 26, 2026

Copy link
Copy Markdown
Owner

This pull request introduces a new integration with the official USSF Astro Standards SGP4 WebAssembly (Wasm) wrappers, adds robust TLE exponential formatting, and makes several related improvements and fixes. The most notable changes are the addition of new wrapper classes for SGP4 and SGP4-XP, comprehensive type definitions and error handling for the Wasm interface, and fixes to TLE formatting to prevent field overflow and ensure strict compliance with TLE line length requirements.

USSF Astro Standards SGP4 WebAssembly Integration

  • Added Sgp4Wasm and Sgp4XpWasm classes to wrap the official USSF Astro Standards SGP4 and SGP4-XP WebAssembly builds, exposing all 19 exported functions as a typed TypeScript API. [1] [2]
  • Added a detailed README.md in src/external/ explaining how to obtain and use the Emscripten artifacts, with API mapping and usage notes.
  • Updated ESLint configuration to gitignore the restricted Emscripten artifacts (src/external/Sgp4Prop*.js).

Type Definitions and Error Handling

  • Introduced Sgp4WasmTypes.ts, defining types for satellite keys, propagation records, error codes, and the Emscripten module/FS interface, with human-readable error messages for common failure modes.

TLE Formatting and Testing

  • Rewrote FormatTle.formatTleExponential to guarantee an 8-character field, correctly handle edge cases (including exact powers of ten and out-of-range values), and prevent TLE line overflow/corruption.
  • Added comprehensive tests for TLE exponential formatting, including regression tests for field overflow and edge cases, ensuring correct TLE line lengths and column alignment.

Other Improvements

  • Added a new sensor type, TT_C_ANTENNA, to the SensorType enum.
  • Fixed Hill.ts to compare Epoch objects by their raw POSIX seconds, preventing subtle bugs in maneuver filtering.

thkruz added 12 commits July 8, 2026 06:39
…ellant budget

- TwoBurnOrbitTransfer.hohmannTransferWithPlaneChange folds an inclination
  change into the cheaper burn (burn 2 when raising, burn 1 when lowering)
  as a single law-of-cosines impulse and reports the assignment
- PropellantBudget adds Tsiolkovsky helpers (massAfterBurn, propellantUsed,
  deltaVRemaining) for tracking a delta-V budget across a burn sequence
- Tests cover the canonical LEO-GEO 28.5 deg case, lowering-transfer
  assignment, pure plane change, and Tsiolkovsky round trips
…windows

Coarse-then-fine scan over a search window for the launch time whose
achievable orbital plane best matches a target RAAN, with drift-aware
matching via meanRaanAt for satellites that regress over the window.
…kStateVector

Add groundTrackStateVector: a closed-form TEME state builder that places a
satellite at perigee directly over a geodetic sub-point on an orbit of a given
shape and inclination, moving North/South. Feed it to rv2tle to fit SGP4 mean
elements. The fitted ground track passes within ~10-40 m of the target vs the
old OrbitFinder search's ~2.8 km tolerance, with no iterative SGP4 loop.

This retires and deletes OrbitFinder (the Inc/RAAN ground-track rotation
search) and its test; LaunchWindowFinder's physical cross-check is re-pointed at
the new primitive.

Two subtleties handled:
- Position is built on the WGS84 ellipsoid so it round-trips through eci2lla
  (which is geodetic, unlike the spherical lla2eci).
- Eccentricity is floored at 1e-3: an exactly-circular state has an undefined
  eccentricity vector, so the downstream osculating-to-mean fit can decompose it
  to an argument of latitude inconsistent with the position (a grid sweep
  diverged in 37/290 near-circular cases, worst ~20000 km; the floor -> 0/290).
Adds a TT_C_ANTENNA SensorType and a TtcAntenna sensor class for
telemetry, tracking, and command dishes (DSN, SCN, ESTRACK, Galileo).
Horizons pads header labels before the colon for column alignment (e.g.
"Output units    : KM-S"), which an exact 'Label:' prefix match missed.
Match label-then-colon instead and strip spacecraft name suffixes.
A BSTAR of exactly 0.01 formatted to the 9-character " 100000-2", which pushed
every later column of TLE line 1 one place right and corrupted the ephemeris
type, element number and checksum. Math.log10(0.01) is exact, so the mantissa
came back as 0.09999999999999999, tripped the "< 0.1" correction and then
rounded up to a six-digit 100000.

Round to an integer mantissa first and renormalize on that integer, so the carry
cannot widen the field, and saturate the two magnitudes the eight-character
field cannot express at all. Non-finite input now formats as an empty field
rather than "NaN".

Found on NORAD 12833 (COSMOS 1109 DEB).
Main-belt asteroids rendered as real bodies need a type of their own: they are
not dwarf planets and not moons, and consumers key hover text, search filtering
and selection routing off this enum.
@thkruz thkruz self-assigned this Jul 26, 2026
@thkruz thkruz added Enhancement New feature or request Feature New functionality to be added labels Jul 26, 2026
@github-actions

Copy link
Copy Markdown
# npm audit report

brace-expansion  <=5.0.7
Severity: high
brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups - https://github.com/advisories/GHSA-3jxr-9vmj-r5cp
brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups - https://github.com/advisories/GHSA-3jxr-9vmj-r5cp
brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash - https://github.com/advisories/GHSA-mh99-v99m-4gvg
fix available via `npm audit fix`
node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion
node_modules/brace-expansion
node_modules/npm/node_modules/brace-expansion

postcss  <=8.5.17
Severity: high
PostCSS: Path Traversal in Previous Source Map Auto-Loading (sourceMappingURL) leads to Arbitrary .map File Disclosure - https://github.com/advisories/GHSA-r28c-9q8g-f849
fix available via `npm audit fix`
node_modules/postcss

tar  <=7.5.20
Severity: moderate
node-tar: Uncontrolled recursion in mapHas/filesFilter allows uncatchable stack-overflow DoS via crafted long-path tar with member selection - https://github.com/advisories/GHSA-r292-9mhp-454m
fix available via `npm audit fix --force`
Will install semantic-release@15.9.3, which is a breaking change
node_modules/npm/node_modules/tar
  npm  *
  Depends on vulnerable versions of tar
  node_modules/npm
    @semantic-release/npm  >=5.0.0
    Depends on vulnerable versions of npm
    Depends on vulnerable versions of semantic-release
    node_modules/@semantic-release/npm
      semantic-release  >=15.9.4
      Depends on vulnerable versions of @semantic-release/commit-analyzer
      Depends on vulnerable versions of @semantic-release/github
      Depends on vulnerable versions of @semantic-release/npm
      Depends on vulnerable versions of @semantic-release/release-notes-generator
      node_modules/semantic-release
        @semantic-release/commit-analyzer  >=7.0.0-beta.1
        Depends on vulnerable versions of semantic-release
        node_modules/@semantic-release/commit-analyzer
        @semantic-release/exec  >=3.4.0-beta.1
        Depends on vulnerable versions of semantic-release
        node_modules/@semantic-release/exec
        @semantic-release/git  >=7.1.0-beta.1
        Depends on vulnerable versions of semantic-release
        node_modules/@semantic-release/git
        @semantic-release/github  5.3.0-beta.1 - 5.3.0-beta.8 || 5.4.0-beta.1 || 5.5.0-beta.1 || >=5.6.0-beta.1
        Depends on vulnerable versions of semantic-release
        node_modules/@semantic-release/github
        @semantic-release/release-notes-generator  >=10.0.0-beta.1
        Depends on vulnerable versions of semantic-release
        node_modules/@semantic-release/release-notes-generator

11 vulnerabilities (9 moderate, 2 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

thkruz added 8 commits July 26, 2026 09:59
Both switch/if chains are exhaustive, so the seed values were dead stores. Declaring the bindings without an initializer lets TypeScript's definite-assignment analysis prove coverage instead.
…ranch

The estimate() orbit binding was only ever read inside the block that computes it, so hoisting it to the function body kept a nullable that could never be observed.
ESLint 10 no longer hoists @eslint/js, so it is now declared directly. It also promotes no-useless-assignment into the recommended set; sgp4.ts is exempted because it is a line-by-line port of the AIAA reference implementation whose zero-initialized declarations must stay diffable against the original.
pnpm-workspace.yaml is what anchors the workspace root, not the lockfile. ootk lives inside keeptrack-space as a submodule and pnpm resolves its root by walking up the tree, so without this file every pnpm command run from here silently operated on the parent project instead.

package-lock.json is removed and gitignored alongside yarn.lock so a stray npm install cannot reintroduce one. esbuild stays pinned past the dev-server path-traversal advisory via pnpm.overrides, and the default isolated linker works here without any phantom-dependency failures.
pnpm/action-setup runs before actions/setup-node because its cache: 'pnpm' option needs pnpm on PATH first. The npm-audit-action compliance job becomes a plain pnpm audit step, and the node_modules cache keys now hash pnpm-lock.yaml.
pnpm lockfiles carry no root package version, so a release has nothing to bump there. semantic-release still publishes through the npm CLI it vendors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request Feature New functionality to be added

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant