-
Notifications
You must be signed in to change notification settings - Fork 0
Equations
This page is the mathematical reference for RigidFlightLab: the paper's own published equations, and how this project's code implements them. Notation follows the paper's own nomenclature (Section 1, p. 1-2/12).
Source: Khalil, M., Abdalla, H., and Kamal, O., "Dispersion Analysis for Spinning Artillery Projectile", ASAT-13-FM-03, Military Technical College, Cairo, Egypt, May 2009. Equations (1)-(4), p. 4/12.
| Symbol | Meaning |
|---|---|
[u v w] |
body-frame velocity components, m/s |
p, q, r |
body-frame roll, pitch, yaw rates, rad/s |
phi, theta, psi |
roll (bank), pitch (inclination), yaw (azimuth) angles |
[Tx Ty Tz] |
resultant external force in the body-fixed frame, N |
Ix, Iy, Iz |
axial and transverse moments of inertia, kg.m^2 |
Ixy, Iyz, Izx |
products of inertia, kg.m^2 |
alpha |
angle of attack |
beta |
angle of sideslip |
L, M, N |
roll, pitch, yaw moments |
g |
normal gravity |
CA |
total axial force coefficient |
CA_alpha2 |
second-order axial force coefficient |
CN_alpha |
normal force coefficient derivative with angle of attack |
C_Ypalpha |
Magnus force coefficient derivative |
Clp |
roll-damping coefficient derivative |
Cm_alpha |
pitching moment coefficient derivative with angle of attack |
Cmq |
pitching moment coefficient derivative with pitch rate |
Cnpalpha |
Magnus moment coefficient derivative |
M (italic) |
Mach number |
[ u_dot ] [ Tx - A_axial ] [ -sin(theta) ] [ p_B^E + p ] [ u ]
[ v_dot ] = 1/m [ Ty + A_side ] + g * [ cos(theta)sin(phi) ] + [ q_B^E + q ] x [ v ]
[ w_dot ] [ Tz - A_normal] [ cos(theta)cos(phi) ] [ r_B^E + r ] [ w ]
A_axial, A_side, A_normal are the aerodynamic force components;
[p_B^E q_B^E r_B^E] is the Earth's angular velocity resolved into the
body frame (Earth-rotation effect - see equation (3)).
This project: implements the same physics in the non-rolling
frame instead of the full body-fixed frame (see docs/model.md for why),
which for an axisymmetric body (Iy = Iz) is an exact reformulation.
The transport-theorem form used in src/simulator/dynamics.py is:
dV/dt |non-rolling frame = F/m - Omega x V, Omega = (0, q, r)
Earth's rotation terms are omitted (see Limitations in docs/model.md).
p_dot = L/Ix + Izx(r_dot + p.q)/Ix + (Iy - Iz).q.r / Ix
q_dot = M/Iy + [Izx(r^2 - p^2) + (Iz - Ix).r.p] / Iy
r_dot = N/Iz + Izx(p_dot - q.r)/Iz + (Ix - Iy).p.q / Iz
For this project's axisymmetric case (Izx = 0, Iy = Iz), Omega =
(0, q, r) for the non-rolling frame, and the general rigid-body law
dH/dt|frame + Omega x H = M (with H = (Ix.p, Iy.q, Iy.r)) reduces
to exactly:
p_dot = Mx / Ix
q_dot = (My - Ix.p.r) / Iy
r_dot = (Mz + Ix.p.q) / Iy
which is what src/simulator/dynamics.py implements.
[P] [p] [ (omega_E + mu_dot).cos(phi) ]
[Q] = [q] - L_BE * [ -lambda_dot ]
[R] [r] [ -(omega_E + mu_dot).sin(phi) ]
Not implemented in this project (see Limitations) - the simulator uses a flat, non-rotating Earth, appropriate for the range/altitude regime of this example case.
[ cos(theta)cos(psi) cos(theta)sin(psi) -sin(theta) ]
L_BE = [ sin(phi)sin(theta)cos(psi) - cos(phi)sin(psi) sin(phi)sin(theta)sin(psi) + cos(phi)cos(psi) sin(phi)cos(theta) ]
[ cos(phi)sin(theta)cos(psi) + sin(phi)sin(psi) cos(phi)sin(theta)sin(psi) - sin(phi)cos(psi) cos(phi)cos(theta) ]
This project: body_to_inertial_dcm() in src/simulator/dynamics.py
implements the equivalent transform for a z-up (altitude-positive)
inertial frame with a nose-up-positive pitch convention, which flips
some signs relative to the paper's own (implicitly NED-style, z-down)
convention above. See the docstring there for the exact derivation.
Given the total angle of attack alpha (angle between the relative
wind and the symmetry axis) and dynamic pressure q_dyn = 0.5 * rho * V^2, reference area A = (pi/4) d^2, reference length d (caliber):
Axial force = q_dyn * A * [ CA + CA_alpha2 * sin^2(alpha) ]
Normal force = q_dyn * A * |CN_alpha| * sin(alpha)
Magnus force = q_dyn * A * |C_Ypalpha| * (p.d / 2V) * sin(alpha)
Overturning moment = -q_dyn * A * d * Cm_alpha * sin(alpha) [see sign note below]
Magnus moment = -q_dyn * A * d * Cnpalpha(M, alpha) * (p.d / 2V)
Pitch damping moment = q_dyn * A * d^2/(2V) * Cmq * (q or r)
Spin damping moment = q_dyn * A * d * (p.d / 2V) * Clp
Cnpalpha is looked up by bilinear interpolation over the paper's own
(Mach, alpha) grid (Table 1's four alpha columns: 0, 2, 5, 10 deg)
rather than treated as a constant per-radian slope, matching how the
paper itself tabulates it.
Sign note: CN_alpha and C_Ypalpha are negative in the paper's
own body-axis convention; this project uses their magnitude since the
force direction is reconstructed geometrically (see aero.py
docstring). The overturning and Magnus moments carry an explicit minus
sign here because of how this project's moment-axis vector (e_x cross
e_v) is defined - the important physical fact, preserved exactly, is
that Cm_alpha's published positive sign is aerodynamically
destabilizing (the shell relies on gyroscopic, not aerodynamic, static
stability), which is what makes the gyroscopic-precession terms in
Euler's equations above load-bearing for flight stability.
- Default projectile/launch parameters: paper Section 4.1 -
src/data/default_case.py. - Aerodynamic coefficient table: paper Table 1, Section 4.2 -
src/simulator/aero.py. - Dispersion uncertainty parameters: paper Table 2, Section 4.4 -
DispersionSettingsinsrc/data/default_case.py.