astrodyn 0.1.1

Pipeline orchestration, VehicleBuilder, and recipes — single API surface for ECS adapters
Documentation
# astrodyn

Pipeline orchestration, the typestate `VehicleBuilder`, and the
recipes module — the single API surface that any consumer (the Bevy
adapter or a non-Bevy runner) depends on.

`astrodyn` composes the
[`astrodyn_*`](https://github.com/simnaut/astrodyn/tree/main/crates) physics
crates into pipeline stages and re-exports their types so a downstream
crate only needs `astrodyn` to access the entire physics surface.
Pure Rust, zero Bevy dependency.

**Status:** pre-1.0. Tier 3 cross-validated against JEOD Trick simulations
(see the [Tier3-Regeneration wiki page](https://github.com/simnaut/astrodyn/wiki/Tier3-Regeneration)).
API may change before 1.0.

## Quick start

Most users want one of the consumer crates rather than this orchestration
layer directly:

- `astrodyn_bevy` for the Bevy-ECS production runtime,
- `astrodyn_runner` for plain-Rust batch propagation and Tier 3 tests.

If you are building a custom adapter on top of the pipeline, depend on
`astrodyn` directly:

```toml
[dependencies]
astrodyn = "0.1"
```

```rust,no_run
use astrodyn::{
    recipes::{earth, orbital_elements, vehicle},
    F64Ext, GravityControl, VehicleBuilder,
};

let mu = earth::point_mass().source.mu.m3_per_s2();
let cfg = VehicleBuilder::new()
    .from_orbital_elements(orbital_elements::iss(), mu)
    .three_dof_point_mass(vehicle::iss_mass())
    .rk4()
    .gravity(GravityControl::new_spherical(0_usize, false))
    .build();
// `cfg` is a `VehicleConfig` ready to hand to either
// `astrodyn_bevy::spawn_bevy::<Earth>(...)` or
// `astrodyn_runner::Simulation::add_vehicle(...)`.
# let _ = cfg;
```

The typestate `VehicleBuilder` rejects misuse at compile time
(no integrator chosen, no state set, mismatched coordinate frames).

## Layered architecture

```
astrodyn_bevy        (Bevy ECS adapter)
   ↓
astrodyn         ←  this crate (pure Rust, zero Bevy)
   ↓
astrodyn_dynamics, astrodyn_gravity, astrodyn_time, astrodyn_frames,
astrodyn_atmosphere, astrodyn_interactions, astrodyn_ephemeris,
astrodyn_planet, astrodyn_math, astrodyn_quantities
```

`astrodyn` (this crate) sits at the workspace root. The Bevy-ECS
adapter is `astrodyn_bevy` (`crates/astrodyn_bevy/`), and `astrodyn` is
also exercised directly by the standalone `astrodyn_runner` Tier 3
harness; both consumers share the same API surface. See the
[Strategy wiki page](https://github.com/simnaut/astrodyn/wiki/Strategy)
for the layered-architecture rules.

## Public surface

- `VehicleBuilder` — typestate builder that refuses `.build()` until
  state, mass, and integrator are set.
- `recipes::*``earth`, `moon`, `mars`, `sun`, `orbital_elements`,
  `vehicle`, `scenarios`. Mission-facing only; the JEOD-source-backed
  Tier 3 verification scaffolding lives in `astrodyn_verif_jeod`.
- Per-stage pipeline functions (`accumulate_gravity`,
  `validate_body`, …) that mirror the `AstrodynSet` schedule slot the
  Bevy adapter exposes.
- Frame-tree orchestration helpers shared by `astrodyn_bevy` and
  `astrodyn_runner`: `SourceFrameIds` (root + per-source frame IDs),
  `sync_pfix_rotation` (writes a planet-fixed child's rotation +
  angular velocity into a `FrameTree`),
  `evaluate_and_apply_frame_switch::<SourceId, F>` (generic
  on-approach/on-departure switch driver), and the source-state
  mutators `set_source_position` / `set_source_state`. Lifted out
  of `astrodyn_runner` in #71 so both consumers share one implementation.

## Performance toolkit

Three criterion microbenches measure the hot path under `cargo bench`:

- `cargo bench -p astrodyn_gravity --bench accumulate` — spherical-harmonics
  kernel at degree 4 / 20 / 60.
- `cargo bench -p astrodyn_gravity --bench integration` — RK4 6-DOF
  step, with and without realistic Moon LP150Q gravity.
- `cargo bench -p astrodyn_verif_jeod --bench step` — full `Simulation::step`
  for the Earth–Moon Clementine scenario.

Flamegraph SVGs land under `target/criterion/<group>/<bench>/profile/`
via `pprof`'s criterion integration.

For steady-state per-step measurement with JSON output (used by CI's
`perf-baseline-track` job), the `tier3_perf_runner` binary wraps the
canonical scenarios:

```bash
cargo xtask perf-baseline                     # default Earth–Moon run
cargo xtask perf-baseline --phase-timing      # adds per-phase µs/step
cargo xtask perf-baseline --help              # see all options
```

Direct invocation (skipping the xtask wrapper) is also available:

```bash
cargo run --profile release-with-debug \
    -p astrodyn_verif_jeod --bin tier3_perf_runner -- \
    --scenario earth_moon_clem --steps 100000 --warmup 1000 --repeat 5
```

## See also

- [Project README]https://github.com/simnaut/astrodyn/blob/main/README.md and
  [`CLAUDE.md`]https://github.com/simnaut/astrodyn/blob/main/CLAUDE.md — workspace-level architecture.
- [`crates/astrodyn_bevy/examples/typed_mission.rs`]https://github.com/simnaut/astrodyn/blob/main/crates/astrodyn_bevy/examples/typed_mission.rs
  — canonical worked example.
- Rendered rustdoc:
  <https://docs.rs/astrodyn>