Expand description
§astrodyn_bevy
A Rust port of NASA JEOD (JSC Engineering Orbital Dynamics, v5.4) with Bevy ECS wiring on top.
astrodyn_bevy reimplements JEOD’s spacecraft dynamics — spherical-harmonics
gravity, Earth rotation (precession/nutation/polar motion), atmospheric
drag, solar radiation pressure, gravity-gradient torque, multi-step
integrators, time-scale conversion (TAI/UTC/UT1/TDB/TT/GMST), DE4xx
ephemerides — as pure Rust crates, then exposes them through a thin Bevy
adapter so they slot into any Bevy app.
Status: pre-1.0. Tier 3 cross-validated against JEOD Trick simulations (see the Tier3-Regeneration wiki page). API may change before 1.0.
§Architecture
Three layers, separated by hard dependency rules:
astrodyn_*— pure Rust physics crates, zero Bevy dependency. Math, integrators, frame transforms, gravity, time scales, ephemerides.astrodyn— orchestration and recipes. Composesastrodyn_*into a pipeline; the single API surface for any ECS adapter. Zero Bevy dependency.astrodyn_bevy(this crate) — thin Bevy glue. Components, systems that delegate toastrodyn, plugin registration. Depends only onastrodyn+bevy.
See the Strategy and Type-System wiki pages for architecture detail and the typed-quantity layer.
§Quick start
[dependencies]
bevy = "0.18"
astrodyn_bevy = "0.1"use bevy::prelude::*;
use astrodyn_bevy::prelude::*;
use astrodyn_bevy::recipes::{earth, orbital_elements, vehicle};
use astrodyn::Earth;
fn setup(mut commands: Commands) {
let earth_recipe = earth::point_mass();
let mu = earth_recipe.source.mu.m3_per_s2();
let earth_entity = commands
.spawn((
GravitySourceC(earth_recipe.source),
SourceInertialPositionC::default(),
TranslationalStateC::<Earth>::default(),
))
.id();
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, GravityGradient::Skip))
.build();
cfg.spawn_bevy::<Earth>(&mut commands, &[earth_entity]);
}
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_astrodyn(10.0)
.add_systems(Startup, setup)
.run();
}The typestate VehicleBuilder rejects misuse at compile time
(no integrator chosen, no state set, mismatched coordinate frames).
Errors render in physics language — “expected Position<RootInertial>,
found Position<Ecef> — apply a FrameTransform<Ecef, RootInertial> first” —
not as PhantomData mismatches.
A full worked example lives in
examples/typed_mission.rs.
§Verification
Three test tiers, all part of the definition of done for every release:
- Tier 1 — unit tests on pure functions (round-trips, convergence).
- Tier 2 — comparison against static reference vectors extracted from JEOD source files (gravity test cases, Euler angle tables).
- Tier 3 — end-to-end trajectory cross-validation: propagate from the same initial conditions as a JEOD Trick simulation and compare position, velocity, attitude, and angular velocity over hours or days. Reference CSVs are committed to the repo.
cargo nextest run --workspace -E 'not test(tier3_)' # fast: Tier 1 + 2
cargo nextest run --workspace -E 'test(tier3_)' # Tier 3cargo nextest run --workspace works on a fresh clone without
$JEOD_HOME — every tier (unit, Tier 2, Tier 3) reads from committed
fixtures under test_data/. $JEOD_HOME is required only when
regenerating those fixtures via the extract_* binaries under
crates/astrodyn_verif_jeod/src/bin/ or refreshing the verbatim mirror at
crates/astrodyn_verif_jeod/test_data/jeod_inputs/. See
CLAUDE.md for the full build / test / regen workflow.
§Documentation
Most docs live on the project wiki: architecture and phase history (Strategy), typed-quantity primer (Type-System), Tier 3 regeneration recipe (Tier3-Regeneration), the JEOD↔astrodyn_bevy capability matrix, per-SIM coverage map, and audit findings.
The one exception that stays in the repo is
docs/JEOD_invariants.md — the catalog of JEOD
C++ invariants and where each is enforced in our Rust port. It lives next
to the code because tags like // JEOD_INV: XX.YY in source are
consistency-checked against the catalog.
§License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
NASA JEOD itself is distributed under NASA’s open-source license and is not redistributed by this project.
Re-exports§
pub use app_ext::AstrodynAppExt;pub use body_action::add_body_action_via;pub use body_action::body_action_intake_system;pub use body_action::body_action_system;pub use body_action::body_action_unregistered_planet_fence_system;pub use body_action::BodyActionCommandsExt;pub use body_action::BodyActionEvent;pub use body_action::BodyActionsR;pub use body_action::RegisteredPlanetsR;pub use frame_attach_system::frame_attach_system;pub use frame_attach_system::propagate_frame_attached_state_post_integration_system;pub use frame_attach_system::propagate_frame_attached_state_system;pub use kinematic_propagation::propagate_state_from_root_post_integration_system;pub use kinematic_propagation::propagate_state_from_root_system;pub use mass_tree::composite_mass_system;pub use mass_tree::MassTreeQueries;pub use mass_tree::MassTreeView;pub use scenario::ScenarioHandles;pub use scenario::SimulationBuilderBevyExt;pub use source_mutator::SourceMutator;pub use source_mutator::SourceReader;pub use wrench::wrench_aggregation_system;pub use bundles::*;pub use components::*;pub use sets::*;pub use systems::*;
Modules§
- app_ext
AstrodynAppExt— ergonomicAppsetup and fixed-step advancement.- body_
action - Bevy adapter for
astrodyn::BodyAction: queue body actions against an entity at startup or mid-sim, then have them applied bybody_action_systemeach tick before the rest of the pipeline runs. - bundles
- Convenience bundles for spawning common entity types.
- components
- Bevy
Componentnewtypes wrappingastrodyntyped siblings (state, mass, gravity controls, interactions, derived states). - frame_
attach_ system - Bevy systems for frame-attached body integration.
- frame_
param - Bevy-native
SystemParams for cross-frame state computation (Frame-Tree-ECS-Native § 13). - kinematic_
propagation - Bevy system for kinematic state propagation root → leaves.
- mass_
tree - Bevy-side ECS mass-tree adapter.
- prelude
- Mission-crate prelude:
use astrodyn_bevy::prelude::*;. - recipes
- Recipe catalogue re-export:
use astrodyn_bevy::recipes::*;. - scenario
SimulationBuilder → Bevy Appbridge — the canonical mission entry point for whole-scenario composition.- sets
AstrodynSet— the BevySystemSetpartition that mirrors JEOD’s per-step pipeline.- source_
mutator - Source-state read/write API for Bevy missions.
- systems
- Bevy
Systems that delegate per-body work toastrodynper-body orchestration functions. Each system queries the relevant components, calls intoastrodyn, and writes the result back. No physics algorithms live here. - validation
- Runtime validation of JEOD invariants.
- wrench
- Bevy system for composite-rigid-body wrench aggregation.
Structs§
- Astrodyn
Plugin - Unified JEOD plugin — registers all pipeline systems and schedule sets.
- Atmosphere
Config - Planet-level atmosphere configuration (ECS-agnostic).
- Atmosphere
ModelR - Bevy resource wrapping
AtmosphereConfigwith an entity reference for the planet whose rotation matrix is used for geodetic conversion. - EphemerisR
- Bevy resource wrapping
astrodyn::Ephemerisfor DE4xx ephemeris access. - Integration
DtR - Bit-exact f64 pipeline integration timestep.
- Mass
TreeR - Bevy resource wrapping
MassTreefor multi-body vehicles. - Polar
MotionR - Optional Bevy resource for polar motion (xp, yp) in radians.
- Root
Frame EntityR - Bevy resource holding the
Entityof the root frame entity in the ECS-native frame hierarchy. The root frame entity carriescomponents::FrameTransC/components::FrameRotC/components::FrameAngVelCat identity and is the parent of every source’s inertial frame entity (which is the parent of every body or pfix frame entity, and so on). Spawned byAstrodynPlugin::buildbefore any source/body registration so the registration systems canChildOf-link their frame entities to it. Mission code reads cross-frame state viacrate::frame_param::RelativeFrameStateandcrate::frame_param::FrameOrigin. - Simulation
TimeR - Bevy resource wrapping
SimulationTime.
Enums§
- Atmosphere
Model - Selectable atmosphere model.
Traits§
- Vehicle
Config Bevy Ext - Bevy-side terminal for
astrodyn::VehicleBuilder.
Functions§
- register_
planet_ systems - Register the planet-generic system instantiations needed for a downstream multi-planet mission.