Rigid-body flight
In short
- What it models: a rocket’s flight from the pad to the ground, rail included: a rigid body free to move and turn in every direction (six degrees of freedom) that gets lighter as its motor burns.
- Sources: the equations of motion in RocketPy’s technical documentation (RocketPy 1.13.0), and the RocketPy paper (Ceotto et al., 2021), which is cited but was not fetched.
- How well it is validated: by analytic and unit tests (a tumbling rocket’s center of mass stays on the exact parabola in a vacuum to 1.7e-6 m over 22 s), and against RocketPy. Five of its example rockets, flown from the pad to the ground by both codes with the same declared drag, agree on height, speed, time and acceleration within 3%; the largest scored difference is +1.783%, a peak acceleration on the rail (validation report, whole flights against RocketPy). So does the path, except for rockets that leave the rail slowly in a wind. There hpr’s body lift, which RocketPy’s normal force leaves out, its later release from the rail and, for Juno III, its simpler fin model put the apogee drift −4.333% to −38.158% from RocketPy’s (validation report; the causes in ADR-026). A sixth, Prometheus 2022, passes Mach 1 on its drag table and agrees as well, its drifts again apart from RocketPy’s by body lift. With hpr’s own drag, against RocketPy flying the drag its examples ship, hpr’s heights differ from RocketPy’s by −7.280% to +10.302% (validation report), the larger gaps where the two drags differ most: hpr’s is well below the example’s for two rockets, and above it at high speed for Prometheus 2022, which flies through Mach 1 on hpr’s drag since M1.8b1 (drag through Mach 1) (Accuracy). Seven flights have been compared with their teams’ altitude logs, apogee and climb only (Accuracy: real flights).
- What it leaves out: staging and delayed ignition, tip-off (the pivot as the rocket leaves the rail), turbulence and thrust misalignment. Its small-angle aerodynamics are used at every angle of attack (the angle between the rocket’s axis and its path through the air), with no stall. A flight that reaches Mach 5, the top of the aerodynamic models, stops with an error.
What the equations do
At each instant of a flight, hpr adds up every force on the rocket and every turning effect (a moment): the thrust, the weight, the air’s forces, and the effects of the propellant burning away. From those it works out how fast the rocket speeds up and how fast its turning changes. The integrator (Time integration) then carries the rocket forward, one short step at a time.
Burning propellant makes the rocket lighter, moves its center of mass, and lets the exhaust carry away some of the rocket’s turning (jet damping). The equations keep all three. They are RocketPy’s, from its technical documentation ([RP-EOM], under Code and sources), and are written out under Equations of motion.
Code and sources
Code: hpr_sim::{dynamics, flight, rail, recorder, state}. Decisions: ADR-011
(equations of motion, aerodynamic coupling, rail, phases and termination). The integrator and
events are in Time integration, and the frames in Frames.
Sources:
- [RP-EOM] RocketPy technical documentation, “Equations of Motion” v0 (Kane’s method with the
Reynolds transport theorem) and v1 (the form solved),
docs/technical/equations_of_motion.rstandequations_of_motion_v1.rstin RocketPy 1.13.0 (refs/rocketpy, MIT). - [C21] G. H. Ceotto, R. N. Schmitt, G. F. Alves, L. A. Pezente and B. S. Carmo, “RocketPy: Six Degree-of-Freedom Rocket Trajectory Simulator”, J. Aerosp. Eng. 34(6), 2021, doi:10.1061/(ASCE)AS.1943-5525.0001331. Cited, not fetched.
State
- Components. The state is the nose tip
O’s positionr_Oand velocityv_Oin the launch frameL, the attitude quaternionq(four numbers that give the rocket’s orientation, turning body axes intoL’s), and the body ratesω(how fast it turns about each body axis) relative toL, in body axes: 13 components. - Why the nose tip. It is fixed in the body and is the body origin (ADR-007, the
design tree). The center of mass
r(fromO, body axes) moves as propellant burns. - The quaternion. Its norm (its length, 1 for a pure rotation) drifts slightly between steps. Every use normalizes it, and it is never reset at an event (Time integration).
Equations of motion
[RP-EOM] v0 derives the motion of a variable-mass system (one whose mass changes as it flies) about a point fixed in the body. It uses two standard tools:
- Kane’s equations, a systematic way to write the equations of motion, for the rigid parts;
- the Reynolds transport theorem, which accounts for mass flowing across a boundary, for the propellant and the gas leaving the nozzle.
Its assumptions:
- the gas flow inside the motor is quasi-steady (it changes slowly enough to treat as steady at each instant), so the integrals over the space it flows through, the control volume, don’t change;
- the flow is axisymmetric: the same all round the rocket’s axis;
- the exhaust momentum is lumped into the thrust at the nozzle exit.
v1 solves the result for v̇ and ω̇, the rates of change of the velocity and of the body rates.
The lines below are that form, in body axes, with primes for time derivatives seen from the
rocket. T03, T04, T20 and T21 are labels carried over from [RP-EOM] v1, so each line can
be matched against it:
T03comes from the momentum of mass moving inside the rocket: gas flowing to the nozzles, and the center of mass shifting as propellant burns. The rotation turns that momentum into a force,ω×T03, as it does for anything moving inside a turning body (a Coriolis force).T04is the thrustTwith the propellant’s internal-momentum terms (Measured thrust curves and the internal-momentum terms, below).T20gathers every force:T04, the weightW, the air forceA, and two terms from the rotation,ω×T03and−ω×(ω×m r), the second because the center of mass is not atO.T21gathers every moment aboutO: from the rotation itself, from the jet and the changing inertia (Σ ṁ_k S_k − I_O′), and from the weight, the air and the thrust. Its last term,ω×h + h′, is for parts that move along the airframe, withhtheir angular momentum aboutOrelative to it: zero for a part on the axis, and zero when nothing moves (Moving mass).- The last three lines give the angular acceleration
ω̇, the nose tip’s accelerationa_O, and the rate at which the attitudeqchanges.
T03 = 2 Σ ṁ_k (n_k − r) − 2 m r′
T04 = T − m r″ − 2 ṁ r′ + Σ m̈_k (n_k − r)
T20 = −ω×(ω×m r) + ω×T03 + T04 + W + A
T21 = −ω×(I_O ω) + (Σ ṁ_k S_k − I_O′) ω + r×W + M_A + M_T − ω×h − h′
ω̇ = I_c⁻¹ (T21 − r × T20)
a_O = T20/m − ω̇ × r (then a_L = q a_O q*)
q̇ = ½ q ⊗ (0, ω)
- Mass terms.
m,ṁ = Σ ṁ_k ≤ 0andm̈_kare the mass, its rate and each motor’s mass acceleration.I_OandI_care the inertia aboutOand about the center of mass (I_O = I_c + m(|r|² 1 − r rᵀ)).n_kis motork’s nozzle exit.
- Forces and moments.
Tis the thrust alongz_B, the motors’thrust_at_pressure_n, with momentM_T = Σ n_k × T_kaboutO.Wis the weight: normal gravity (centrifugal term included) plus the Coriolis force−2m Ω×v_cg, both acting at the center of mass.AandM_Aare the aerodynamic force and its moment aboutO(below).
- Nozzle gyration tensor.
S_kdescribes how the exhaust leaving motork’s exit disc is spread aboutO; times the mass flowṁ_k, it gives the jet damping inT21.S_k = (r_e²/4) diag(1, 1, 2) + |n_k|² 1 − n_k n_kᵀ, integrated here from v0’s boxed rotational equation. The jet term there is∫ r×(ω×r) dṁover the exit disc of radiusr_e, with a uniform jet. For a disc atn_kon the axis, this gives(r_e²/4 + n_k², r_e²/4 + n_k², r_e²/2).- RocketPy 1.13.0’s code (
rocket.py:984-985,evaluate_nozzle_gyration_tensor) uses0.25·n²for the transverse distance term instead ofn². Itsnis measured from the center of dry mass, not from the nose tip, so the entries can’t be compared directly. The RocketPy code-to-code suite (M2.1) should compare the jet-damping coefficient about the center of mass. - A motor that gives no nozzle exit radius contributes
r_e = 0.
- RocketPy 1.13.0’s code (
- The classical limit. For an axisymmetric rocket turning slowly about a transverse axis, the
equations reduce exactly to the classical jet damping about the center of mass,
I_c ω̇ = [ṁ (r_e²/4 + l²) − İ_c] ω, withlfrom the center of mass to the nozzle exit. Theṁ l²part damps, and the falling inertia partly offsets it (dynamics::tests::jet_damping_matches_the_classical_form). - Time derivatives of the mass properties.
r′,r″,ṁandI_O′come from central differences ofAssembly::mass_propertieswith a half-width of 1e-4 s.- The stencil, the times each difference samples, is kept inside the current integration interval. Every thrust-curve knot and burnout is a stop time, so no difference straddles a change in the thrust’s slope. Near an interval’s end the derivative is taken at the nearest valid center and extended linearly.
m̈_kdifferences each motor’s mass flow the same way.- After burnout (an interval starting past every burnout) the rates are zero, and so are they over intervals shorter than 2e-5 s, where differences would be rounding noise.
- A part that moves along the airframe adds its own rates in closed form, not by differences (Moving mass).
- Motors at the ends of an interval. A motor that burns through an interval is evaluated at
its one-sided limit inside the burn,
tclamped to(0, t_end). The last stage of the step ending at burnout (or the first after ignition) then sees the burning motor, including the pressure correction that switches off att_end. Without this, fixed-step RK4 converged at first order (5.1 mm of apogee at 2 ms). - Measured thrust curves and the internal-momentum terms. A static test measures
T_exit − dP_int/dt, whereP_int = m r′ − ṁ(n − r)is the internal momentum of the burning propellant, so a.engcurve already contains it.T04subtracts−m r″ − 2ṁ r′ + m̈(n − r)again.- hpr keeps the terms as RocketPy does, for parity in the RocketPy comparison (M2.1). The form is exact for the [RP-EOM] model, not for a measured curve.
- The size of the double count on Valetudo: it lifts off at 1.56 ms with 73 N of thrust against
95 N of weight, 21 N coming from
m̈(n − r), and it changes the burnout speed by at most 0.05 m/s.
- Earth’s rotation. It enters only through the Coriolis force. The rotational equations use
ωrelative toL, which differs from the inertial rate by at most 7.3e-5 rad/s (Frames, and the rigid-body flight decision ADR-011).
Aerodynamics in flight
hpr-aero gives coefficients at a flow condition (Aerodynamics). The engine applies them as follows.
- Airspeed. The air velocity uses the wind at the center of mass’s height. Wind vectors are
taken in
L’s axes. - Axial force.
−q A C_A z_Bfrom the whole rocket’s drag, at the center of mass’s airspeed, Mach number, angle of attack and Reynolds number per meter (V/ν). The drag is power-on (DragConditions::thrusting, with the burning motors’ cross-section) while any motor burns in the interval.Simulation::with_full_base_drag_under_powerkeeps the whole base’s drag instead, as OpenRocket does, for comparisons with it (base drag under power). The force acts along the axis, so it has no moment aboutO. - Normal and side forces, component by component. Each body and fin set is evaluated at its
own local flow:
v_O − wind + ω × p_iat the stationp_ithe aerodynamics gives it (AeroModel::component_station_m). That station is the component’s small-angle center of pressure wherever one model carries the component. Faster than sound, where the shock-expansion method and slender-body theory share one, it is not: the station is joined between the two models while the force joins their slopes and moments, and the two agree only at the ends of the join. On a body that sits between the models at every speed (a lip riding half in its boattail’s wake), a tube’s station can sit two calibres from its own center of pressure (issue #106), which moves the lever arm the damping below uses by that much. ItsC_Nacts along the crossing airŵand itsC_Yalongz_B × ŵ(Frames), with moments−q A M_N (z_B × ŵ) + q A M_Y ŵaboutOfrom the component’s moment coefficients. - Fins at any angle of attack. A fin set’s normal force follows the crossflow
V sin α: its model’sC_N = C_Nα αis used asC_Nα sin α, the substitution Niskanen keeps for bodies (eq. 3.16–3.17). No source in hand gives a large-angle fin model, and stall is not modeled.- At small angles nothing changes (1.5% less at 0.3 rad).
- The force now vanishes for axial flow from the tail as well as from the nose.
- A force linear in
αstays large atα = πand flips with rounding noise in the lateral velocity. A calm vertical flight falling tail first after apogee then collapsed the step size and never landed (tests::a_calm_vertical_flight_falls_tail_first_and_lands).
- Damping. The rotation’s contribution to each local flow is the only aerodynamic pitch and
yaw damping. At a component’s station the rotation adds a velocity
ω × p_i, which changes the angle at which the air meets that component. The station is the lever arm, so where it is not the center of pressure (above) the damping is levered from the wrong point by the same distance.- Only components with a normal-force slope damp this way: nose cones, transitions and fin sets. A boattail’s slope is negative, so it takes some away.
- Body tubes give none at small angles: their own slope is 0, and their body lift grows with
sin² α. hpr-aerohas no pitch or yaw damping coefficients; they would have to replace the local-flow damping, not add to it.- A flight on another tool’s normal force keeps this damping. The table (The normal force from RASAero II) gives the normal force at the center of mass’s airflow, and each component adds only its force in its own local flow minus its force in the center of mass’s airflow: the part the rotation makes. Without rotation that part is exactly zero (ADR-032).
- Roll. The fins’ cant drives the roll and the roll rate damps it: a moment
q A d (C_l0 cos α + C_lp p d/2V)aboutz_B, withqthe dynamic pressure,Aanddthe reference area and diameter,C_l0the cant’s rolling moment,C_lpthe damping andp = ω_z, at the center of mass’s Mach number; the cant’s forcing follows the axial flow,cos α, so it vanishes broadside and reverses tail first (AeroModel::roll, Roll: forcing and damping). The damping is writtenρ V A d² C_lp p/4, so it fades smoothly as the airspeed does. The roll rate also changes through inertia coupling (turning about one axis driving turning about another) for a rocket whose mass isn’t symmetric about its axis, and, while a motor burns, through the jet and the falling inertia inT21. At constant speed a canted rocket spins up to the steady rate where cant and damping balance, as the closed form gives (tests::canted_fins_spin_to_the_analytic_balance). - Limits.
- The models are small-angle: no stall, and body lift and fins extended by
sin α. They overstate the forces at largeα. In normal flights largeαoccurs near apogee, where the dynamic pressure is small, and off the rail in strong crosswinds.Sample::angle_of_attack_radshows where it happens. - The normal force and the drag buildup cover Mach 0 to 5
(Fins through Mach 1,
Drag through Mach 1, and ADR-028, the drag’s
decision); a fin set’s CP moves with the Mach number, and each component takes its local
airflow at its CP for the center of mass’s Mach number. At Mach 5 or faster they refuse the
flow, and the flight stops with
SimError::Aero. A drag override table covers drag at any Mach, but the normal force still stops at Mach 5.
- The models are small-angle: no stall, and body lift and fins extended by
Phases
- Pad.
- The rocket starts with its aft end (its body’s aft end or its aft-most nozzle exit) at the rail’s foot, at rest, with the rail’s attitude.
- It stays until the force along the rail,
T20·z_Bwithω = 0, exceeds frictionμ |T20_⊥|(the liftoff event).T20_⊥is the rail’s reaction: the weight, the aerodynamic force and the mass terms across the axis.
- Rail.
- One degree of freedom:
a = (T20·z_B − μ |T20_⊥|)/malong the rail, with no rotation. - It ends when the aft edge of the aft-most rail button or launch lug passes the top of the rail, or the aft end with no guides (Rail geometry, below).
- If the speed along the rail falls to zero, the rocket returns to the pad phase, at rest where it stopped. It is held there, even if the force down the rail exceeds friction and a real rocket would slide back.
- One degree of freedom:
- Free. Six degrees of freedom until the ground.
- Rail geometry.
- A button’s axial extent is its outer diameter, and a lug’s is its length.
- The rocket leaves after travelling
L − (s_aft − s_guide). RocketPy ends its rail phase when the forward button reaches the top (flight.py:1716-1730,effective_1rl). hpr keeps the rocket guided to the last guide (Loft lesson L26). - The pivot about the last guide (“tip-off”) is not modeled, and the rocket leaves the rail with no angular velocity.
- Friction is Coulomb friction: a user coefficient times the net reaction
|ΣN|, the force pressing the guides onto the rail. With a moment across two buttons (a crosswind at low speed), the true frictionμ(|N₁| + |N₂|)is larger. No source gives a default coefficient, so the default is zero.
Events and termination
-
Stop times. Thrust-curve knots, burnouts and the time cap. A burnout that is reached records a
Burnoutevent. -
Liftoff and stall. Liftoff is the pad force margin rising through zero (checked also at each interval’s start, for a thrust that jumps at a knot). Stall is the speed along the rail falling through zero.
-
Rail exit. The travel along the rail reaching the exit travel.
-
Apogee. The center of mass’s ellipsoidal-height rate,
û(r_cg) · v_cg, falling through zero.ûis the ellipsoid normal at its position. A flight that has let a part go records one apogee (Released mass). -
Ground hit. The center of mass’s ellipsoidal height reaching the launch site’s, descending (Frames, Loft lesson L35).
-
User events. A function of the
Sample, in free flight. -
Mass shifts and releases. A part starting to move along the airframe (
Shift) or leaving it (MassRelease), on its trigger (Moving mass, Released mass). -
Heights. Atmosphere and wind heights are
h − N, the height above sea level:his the ellipsoidal height, and the geoid undulationN, the height of sea level above the ellipsoid, is given inEnvironment(no geoid model). -
Termination (Loft lesson L25). The flight ends in exactly one of these ways:
GroundHit;NoLiftoff(the last burnout passes on the pad);StalledOnRail(it lifted off, then stopped on the rail after burnout);TimeCap;StepLimit.
Any other failure is an error.
-
Not yet modeled. Turbulence and thrust misalignment. Recovery is modeled, and has its own page; so are motors lit at their own times and a powered separation, on Staging.
Integration settings
-
Defaults.
FlightSettings::default()uses Dormand–Prince 5(4) withrtol = atol = 1e-8and unit weights, a one-hour cap and 10⁶ steps. -
Accuracy against cost. Measured on Valetudo (K400C), with a 5 m/s wind from the west, compared with the apogee at 1e-11 (873.98272 m):
rtol = atolapogee error flight time (release) 1e-4 2.3e-2 m 0.36 ms 1e-6 6.8e-5 m 0.59 ms 1e-8 1.1e-6 m 1.13 ms 1e-10 1e-7 m 2.72 ms
Verification
Unit tests in hpr_sim::tests, hpr_sim::dynamics::tests and hpr_sim::rail::tests, at the
default settings. The numbers were measured on 2026-09-17.
- Vacuum ballistic. A tumbling, spinning Valetudo in a vacuum, from the nose tip at 500 m with
v = (30, −20, 80)m/s.- The center of mass stays on the closed-form parabola to 1.7e-6 m over 22 s.
- The angular momentum stays constant to 7.8e-7 (relative).
- Apogee and ground contact are within 4.7e-7 s and 1.1e-8 s of the parabola’s. Those times are located (root-found) on the exact ellipsoidal height.
- Terminal velocity. Falling nose down through uniform air with
C_D = 0.5, the speed followsv_t tanh(g t/v_t)to 5.5e-9v_t, and isv_tto 1e-5 after 150 s. - Torque-free precession (the wobble of a spinning body with no torque on it). Valetudo
(
I_a/I_t= 0.0019) spinning at 25 rad/s with a transverse rate turns in body axes atΩ = (I_a − I_t) ω_z/I_t= −24.95 rad/s. The rate matches to 4.7e-7 rad/s over 3 s, and the angular momentum inLholds to 1.5e-6. - Pitch oscillation against linear theory. At 100 m/s with no drag or gravity, the two-state
linear model (path turning, restoring moment
K₁, rotational dampingK₂) predicts a 1.44954 s period. The flight measures 1.44965 s (8e-5), and the decay per half period is within 0.2% of the model’s. - Jet damping. The flight equations give the classical jet damping to 1e-6, and the mass rate
equals the motor’s
−F/cto 1e-6, including stencils clipped by an interval’s end. - Powered climb. A vertical climb in vacuum from 0.5 s to 3.0 s ends at the speed of the axial equation, integrated independently from the motor and the assembly, to 4.3e-8 m/s.
- Rail friction. At 60°,
μ = 0.3removes exactlyμ g cos Efrom the acceleration along the rail. - Loft lesson L20, weathercocking. In a 5 m/s wind from the west, Valetudo’s unit axis has an east component of −0.12 at burnout. Its apogee is 96 m upwind, against 1.0 m (Earth rotation) in calm air.
- Calm vertical. With no wind and no Earth rotation the rocket falls tail first after apogee and still lands, in under 20,000 evaluations.
- Solvers agree. RK4 at 2, 1 and 0.5 ms gives the same apogee as Dormand–Prince to 1.2e-5 m and 2.1e-7 s.
- Burnout at an event. A user event on the thrust fires at burnout, and burnout is still recorded once.
StalledOnRail. A 2000 m rail gives it, with only liftoff and burnout recorded.- Errors and reuse. Observer errors end the flight with that error. Starts before ignition
or underground are refused. A cleared recorder records the same rows again.
Simulation,EnvironmentandRecorderareSend + Sync. - Loft lesson L24. Two runs of one
Simulation, and a secondSimulationbuilt the same way, record the same bits for every channel at every step. - Loft lesson L25. A normal flight hits the ground. A rail with
μ = 20at 60° givesNoLiftoffat rest. A 5 s cap givesTimeCapat exactly 5 s, and a 40-step limit givesStepLimit. - Loft lesson L26. On a 3 m rail tilted to 1.3 rad, the rail exit comes at the last
button’s travel to 1e-6 m. Across the rail the rocket stays within 1e-9 m, with no rotation.
Friction (
μ = 0.3) delays the exit and slows it. - A tilted rail against OpenRocket. From a 1 m rod tilted 5 to 20 degrees, hpr’s rocket is on
OpenRocket’s bearing at apogee to within 0.03 degrees and loses the same apogee to within 0.27
percentage points (
.ork: a tilted launch rod). - Events and recorder. Events come in order: liftoff, rail exit, burnout, apogee, ground hit. Apogee’s vertical speed is below 1e-6 m/s and ground contact’s height below 1e-6 m. Recorder rows fall on the interval or at events.
- Through Mach 1. The synthetic 54 mm rocket on an I175 passes Mach 1 and lands, both on hpr’s own drag and on a constant drag table.
- Cost. About 1.1 ms per Valetudo flight to the ground (
docs/perf.md).
Whole flights against RocketPy
cargo xtask validate flies six of RocketPy’s example rockets from the pad to the ground and
compares fifteen numbers of each with RocketPy 1.13.0’s own flight
(ADR-021, the whole-flight comparison). Both codes fly one declared drag coefficient,
a constant C_D0 of 0.5 on the same reference area. So what is compared is the equations of
motion, the motor and the air, not the drag. The rest is RocketPy’s where hpr has it: its gravity
formula, standard atmosphere, frictionless rail, the example’s rail angles, parachutes and motor,
and a declared wind.
| result | value |
|---|---|
| cases scored | 6, one of them (Prometheus 2022) past Mach 1, since M1.8a |
| height, speed, time, acceleration | all scored, all within 3% of RocketPy’s |
| largest of those | +1.783%, Bella Lui’s peak acceleration, on the rail |
| largest in apogee | +1.208%, Prometheus 2022; RocketPy flown with hpr’s body lift and rail release comes within 0.01% (case file) |
| path without wind (drift of apogee and landing) | all scored, within 1.9% (largest −1.811%, Valetudo’s landing, in still air) |
| path in wind | Calisto’s scored (largest +1.257%), and NDRT 2020’s landing; Juno III’s, Bella Lui’s and Prometheus 2022’s, and NDRT 2020’s apogee drift, differ by 4.3 to 38% and are reported, not scored: hpr’s body lift and rail release, and Juno III’s fin slope (ADR-026) |
What the two codes still do differently, and how much it moves:
- The wind. A rocket that leaves the rail slowly in a wind meets the air at a steep angle: Juno III at 18 m/s in an 8.5 m/s wind, 26° off the airflow. There hpr’s normal force includes body lift (Aerodynamics), which RocketPy’s leaves out. Much of it acts ahead of the center of mass, the nose’s above all, so it moves the center of pressure forward and weakens the turn into the wind, and hpr turns into it less: Juno III’s apogee is 245.3 m from the pad in hpr and 396.6 m in RocketPy. Given hpr’s body lift, its rail release and its flat-plate fin slope (it cannot model the airfoil lift curve Juno III’s example gives its fins), RocketPy puts it 248.3 m out, and every windy drift within 1.3% of hpr’s (ADR-026). hpr’s growth of drag with the angle of attack moves no drift by more than 0.1%.
- RocketPy’s equations, corrected. hpr’s equations of motion follow RocketPy’s technical documentation, which measures the center of mass from the center of dry mass. RocketPy 1.13.0’s code reads that vector the other way round, so during the burn it takes the turning moments about the wrong point and its rockets turn into the wind too far. The fix is proposed in a pull request to RocketPy, still open, built on one that is merged but not yet released; RocketPy 1.13.0 as installed still has the error, and the comparison applies both fixes. Without them, hpr’s drifts in wind were up to −60.8% short of RocketPy’s at apogee and +151% beyond it at landing (ADR-026, issue #50).
- The rail. hpr’s rail equation keeps the terms for the center of mass moving inside the
body as the propellant burns. RocketPy’s rail equation (
udot_rail1) leaves them out. At a sharp ignition spike, with thrust and mass the same to five digits, hpr’s acceleration is 1.2 to 1.3 m/s² higher. hpr also guides the rocket until its last rail button leaves, where RocketPy frees it at the first. - Calisto’s two peaks. Its acceleration peaks twice, 0.9% apart, and the rail terms make hpr’s maximum the other peak. So the time of the peak (−96.8%) is reported but not scored.
- The parachutes. RocketPy counts the air a canopy drags along (added mass); hpr has none. So the peak deceleration as NDRT 2020’s main opens is 83% higher in hpr, and that number is reported but not scored. The speeds at landing agree within 0.03%.
The metrics are measured as RocketPy defines them: speeds and accelerations at the center of dry
mass; heights from that point’s height at launch, since RocketPy’s starts at the ground; and the
rail exit when the rocket has travelled RocketPy’s effective_1rl, the forward button at the top
of the rail, where hpr’s own rail-exit event waits for the last one. Each case file argues its
tolerances; Accuracy gives every result.