Go to file
ApsisRS contributors fd847a9669 docs: describe the notation at the precision it uses
The comment said the inclination was rounded to one decimal place, but
the format prints it at full precision, so 53.25 degrees came out intact
where the comment promised 53.2. The notation is an identifier, so
truncating it would lose information for nothing.
2026-10-02 00:19:37 +08:00
.github/workflows bench: add a parallel scale benchmark 2026-09-30 17:53:48 +08:00
crates docs: describe the notation at the precision it uses 2026-10-02 00:19:37 +08:00
docs/design docs: add the bilingual glossary 2026-10-02 00:13:34 +08:00
scripts workspace: enforce the layer dependency rule 2026-09-26 23:33:20 +08:00
validation docs: give every note an English and a Chinese version 2026-09-30 19:23:26 +08:00
.gitignore workspace: add geodesy and time cross-check scripts 2026-09-26 13:47:59 +08:00
Cargo.lock access: search a constellation's tracks across several threads 2026-09-30 18:37:02 +08:00
Cargo.toml orbit: add Keplerian elements and two-body propagation 2026-09-26 14:20:09 +08:00
LICENSE workspace: initialize workspace with all layer crates 2026-09-26 12:53:13 +08:00
README.md docs: add the bilingual glossary 2026-10-02 00:13:34 +08:00
README.zh.md docs: add the bilingual glossary 2026-10-02 00:13:34 +08:00
rust-toolchain.toml workspace: initialize workspace with all layer crates 2026-09-26 12:53:13 +08:00

README.md

ApsisRS

Computational kernels for commercial spaceflight and satellite internet, in Rust.

English | 简体中文

Scope

  • Pure Rust, standard library only, no third-party crate dependency
  • Clear domain boundaries with a one-way dependency order between layers
  • The public facade crate is apsis-rs; its library name is apsis
  • Every crate is publish = false at this stage, so none of them is released

Layers

foundation -> physics -> orbit -> rf -> network -> ops -> sim -> apsis-rs

The rules:

  • Dependencies flow to the left only. A lower layer may use any layer to its left; a higher layer may not use any layer to its right. So network may use orbit, but orbit may not use network. A leftward dependency may cross as many layers as it needs, because the layers in between need not offer a type that carries the value forward.
  • apsis-core in foundation is the global baseline that any crate in any layer may use. apsis-math is the same, because linear algebra is shared across the layers.
  • Within a layer, that layer's facade crate (apsis-orbit, apsis-rf, apsis-sim) is the integration point.

scripts/check-layers.sh enforces these rules and CI runs it.

Layer Responsibility Crates
foundation Base types, units, mathematics, macros apsis-core, apsis-units, apsis-math, apsis-macros
physics Time, leap seconds, coordinates, datum apsis-time, apsis-leap, apsis-coord, apsis-geodesy, apsis-frames
orbit TLE, SGP4, two-body, ephemeris, maneuvers apsis-tle, apsis-sgp4, apsis-kepler, apsis-ephemeris, apsis-maneuver, apsis-orbit
rf Radio frequency, antennas, link budget apsis-rf, apsis-antenna, apsis-doppler, apsis-atmosphere, apsis-noise, apsis-interference, apsis-link
network Constellations, coverage, access, topology, routing apsis-constellation, apsis-coverage, apsis-access, apsis-topology, apsis-isl, apsis-routing, apsis-handover, apsis-mesh
ops Resources, tasks, scheduling, conflicts, schedules apsis-resource, apsis-task, apsis-scheduler, apsis-conflict, apsis-schedule
sim Simulation engine, scenarios, events, output apsis-sim-engine, apsis-scenario, apsis-event, apsis-output, apsis-sim
facade Public facade apsis-rs

Building

Run every Rust command from the repository root:

cargo check --workspace
cargo test -p apsis-core -p apsis-units -p apsis-math

The apsis-rs facade selects the layers it needs by feature:

[dependencies]
apsis-rs = { path = "...", features = ["orbit"] }

The features are foundation, physics, orbit, rf, network, ops, sim and full. A layer feature enables the layers below it. full enables everything including sim; ops is every layer except sim, for a project that does not run simulations.

Conventions

  • Toolchain stable, edition 2024, rust-version 1.85
  • No third-party crate by default, including dev-dependencies and build scripts
  • Library code uses no unwrap, expect or panic. A failure on external input is always a Result or an Option. An expect is allowed on an internal invariant that a check just above already guards, such as the element just pushed onto a vector, or a value whose absence the line above ruled out. There are thirteen such sites and each is listed with its guard in docs/design/errors.md.
  • Every public item carries a documentation comment, and the comment is self-contained
  • Tests live in each crate's tests/ directory, separate from src/. They are integration tests and reach the crate only through its public API; no inline #[cfg(test)] module is used
  • Documentation follows the X.md and X.zh.md convention, with English in X.md and Simplified Chinese in X.zh.md

Layout

apsis-rs/
├── Cargo.toml
├── crates/          # Rust workspace members
│   └── apsis-rs/
│       ├── examples/   # validation dumps and cross-layer checks
│       └── ...
├── scripts/         # repository check scripts
├── validation/      # Python cross-checks
└── docs/design/     # design notes

Tests live in each crate's tests/ directory. The cross-layer integration checks and the dependency-free benchmarks are examples of the facade:

# Cross-layer integration checks, which CI runs
cargo run -p apsis-rs --features network --example integrate_network
cargo run -p apsis-rs --features ops --example integrate_ops
cargo run -p apsis-rs --features sim --example integrate_sim

# Hot path benchmark, run in release
cargo run --release -p apsis-rs --features full --example bench

# Scale sweep: the input grows and the cost per unit of work shows the trend
cargo run --release -p apsis-rs --features full --example bench_scale

# Parallel sweep: the same work over 1, 2, 4, 8 and 16 threads
cargo run --release -p apsis-rs --features full --example bench_parallel

Documentation

The design notes record the cross-crate decisions that a reader of a single crate cannot infer:

Licence

GPL-3.0-or-later, see LICENSE.