rockets-engine v0.6.1
Point-mass powered flight for Rust — prescribed motor burns, staging and guidance hooks on the ballistics-engine force kernel.
# Cargo.toml
rockets-engine = "0.6"
rockets-engine = "0.6"
What it does
- Prescribed thrust curves — piecewise-linear burns with analytic propellant mass; no separate fuel integrator to drift.
- Serial & parallel staging — any number of stages, each with its own motor schedule and separation time; mass stays analytic across separations.
- Discontinuity-aware RK4 — ignition, curve knots, separations and burnout split the integration grid; one-sided forces at every event.
- Guidance hooks — application-owned controllers called once per public step; the integrator holds the command constant across substeps.
- Real force models — ballistics-engine gravity, drag and ICAO atmosphere; central (inverse-square) gravity and altitude switching for planet-scale ECI arcs.
- Modified point-mass — opt-in Magnus/yaw-of-repose spin, Coriolis and rail tip-off, plus angle-of-attack body lift and induced drag. No attitude integration required.
- CLI & browser terminal —
cargo install rockets-engine --features clifor therocketstool, or fly it in the browser terminal; one shared parser, native and WASM. Monte-Carlo dispersion and elevation solving built in. - Guidance composition — prograde gravity turns, thrust-misalignment dispersion, actuator lag and launch rails, with downrange-segmented atmosphere and wind.
- Reduced-order dynamics — second-order weathercock with CP/CG curves and a scalar roll channel: body-axis response and spin history without a 6-DOF attitude model.
- SI throughout — metres, seconds, kilograms, newtons. Simulation time in, state out; the solver owns no evolving state.
Use them together
The boundary: rockets-engine owns the powered flight — motor, mass, integration, guidance. ballistics-engine supplies the atmosphere and drag kernel through the adapter.
use rockets_engine::{
ballistics::{Atmosphere, BallisticForces},
ControlInput, FlightState, IntegratorSettings, Motor, Rocket, Simulator,
ThrustCurve, ThrustPoint, Vec3,
};
fn main() -> Result<(), rockets_engine::Error> {
// rockets-engine: prescribed motor burn
let curve = ThrustCurve::new(vec![
ThrustPoint { time_s: 0.0, thrust_n: 0.0 },
ThrustPoint { time_s: 0.1, thrust_n: 20.0 },
ThrustPoint { time_s: 0.9, thrust_n: 15.0 },
ThrustPoint { time_s: 1.0, thrust_n: 0.0 },
])?;
let rocket = Rocket::new(0.18, Some(Motor::new(curve, 0.04, 0.2)?))?;
// ballistics-engine: atmosphere + drag kernel (via the adapter)
let forces = BallisticForces::new(
0.025,
vec![(0.0, 0.45), (0.8, 0.5), (1.2, 0.7), (3.0, 0.4)],
Atmosphere::default(),
Vec3::new(2.0, 0.0, 0.0),
)?;
let sim = Simulator::new(rocket, forces, IntegratorSettings::default())?;
let mut state = FlightState {
time_s: 0.0,
position_m: Vec3::new(0.0, 2.0, 0.0),
velocity_mps: Vec3::new(2.0, 8.0, 0.0),
};
for _ in 0..100 {
let result = sim.step(&state, 0.05, ControlInput::along(Vec3::new(0.3, 1.0, 0.0)))?;
state = result.state;
}
Ok(())
}
In Cargo.toml: rockets-engine = "0.6"; add ballistics-engine = "=0.48.0" only if you call its API directly. Full source: examples/with_ballistics.rs. Flying something unpowered? Drive ballistics-engine directly instead.