Skip to main content

Module building

Module building 

Source
Expand description

A rocket, part by part from the nose back.

Rocket::new takes a name and the airframe’s outside diameter. The add_ methods then stack its parts in the order they sit, from the nose tip aft:

Every part names its material (material finds a built-in one by id), and a hollow part its wall. There are no defaults for either, since each would be a guess at the rocket’s mass. Each number is checked as the part is added, and a part out of order is refused with Error::Order.

Once built, a rocket weighs itself (mass_properties) and finds its stability margin (margin):

use hpr::rocket::{Fins, Mass, MotorTube, Nose, Tube, material};
use hpr::{FinPlanform, Motor, NoseShape, Position, Rocket};

let mut rocket = Rocket::new("Small", 0.0563)?;
rocket
    .add_nose(Nose::hollow(
        NoseShape::Ogive { radius_ratio: 1.0 },
        0.22,
        0.0015,
        material("abs")?,
    ))?
    .add_tube(Tube::new(0.9, 0.00115, material("kraft_phenolic")?))?
    .add_fins(Fins::new(
        3,
        FinPlanform::Trapezoidal {
            root_chord_m: 0.1,
            tip_chord_m: 0.04,
            span_m: 0.045,
            sweep_m: 0.05,
        },
        0.003175,
        material("birch_plywood")?,
    ))?
    .add_motor_tube(MotorTube::new(0.2, 0.029, 0.001, material("kraft_phenolic")?))?
    // The parachute and its bay as one 200 g mass, 7 cm below the top of the tube.
    .add_mass(Mass::new(0.2, Position::Top { aft_offset_m: 0.07 }))?
    .set_motor(Motor::from_catalog("H54")?)?;

// At liftoff, 0 s after ignition, with the air along the axis at Mach 0.3.
let liftoff = rocket.mass_properties(0.0)?;
let margin = rocket.margin(0.0, 0.3)?;
assert!(liftoff.mass_kg > 0.4);
assert!(margin.margin_cal.is_some_and(|calibres| calibres > 1.0));

The site’s page The builder walks through a whole rocket, with a recovery bay and a parachute.