Lateral-Directional Stability Flight Test (flight-test-operations/stability/lateral-directional-stability-flight-test)
Use when the task is planning and reducing the static lateral-directional
stability flight test of a fixed-wing aircraft from steady-heading
sideslip (SHS) data: the sideslip sweep matrix, the fitted rudder,
aileron and pedal-force gradients, and the signed directional and lateral
stability estimates that gate the demonstration. This leaf implements the
reduction in pure Python, stdlib only. It pairs with the pitch-axis
static stability flight test sibling (trim and margin demonstration) and
the dynamic mode damping sibling for the rest of the stability picture.
Domain quick reference
- Sign convention (documented for every reduction): beta is the sideslip
angle in degrees, positive when the nose is LEFT of the velocity vector
(left slip); delta_r positive = right pedal; delta_a positive = right
aileron (left roll). Measured in steady-heading sideslip maneuvers at
constant CAS and altitude, the pilot holding heading with aileron and
setting the slip with rudder.
- Rudder gradient: s_r = d(delta_r)/d(beta) in deg/deg (unitless). For a
directionally stable aircraft the pilot pushes the rudder INTO the slip
to increase it, so s_r is positive with the conventional control sign.
- Aileron gradient: s_a = d(delta_a)/d(beta) in deg/deg. For a laterally
stable aircraft (dihedral effect) the pilot holds the left slip with
aileron against the roll, so s_a is negative.
- Pedal-force gradient: g_p = d(F_pedal)/d(beta) in N/deg, from the
rudder-free run (the force the pilot must apply at each beta).
- Signed estimates from the trim balances:
Cn_beta_est = -cn_dr * s_r and Cl_beta_est = -cl_da * s_a, both in
/rad. The deg/deg gradient ratios enter as unitless slopes because the
deg/deg and rad/rad ratios are numerically identical. cn_dr < 0 and
cl_da < 0 are the conventional signed control powers (right pedal yaws
the nose right, right aileron rolls left). A stable aircraft yields
Cn_beta_est > 0 (weathercock stable) and Cl_beta_est < 0 (dihedral
stable).
- Least squares: fit_slope fits offset plus slope (dy/dx) through the
sweep points; from two points up, more points tighten the fit, and any
vertical point set (zero x variance) is rejected.
- Test limit: build_sideslip_matrix holds every commanded beta target
inside the declared +-15 deg limit (SIDESLIP_LIMIT_DEG) at the constant
CAS. A sweep needs at least 2 points (BETA_SWEEP_MIN) up to a 40 point
planning cap (BETA_SWEEP_MAX).
- FAR 25.177 frames the static lateral-directional stability
demonstration criteria; only paraphrased criteria appear here
(weathercock stable when the directional estimate is positive, lateral
stable when the dihedral estimate is negative). Regulation text is
never reproduced.
Workflow
- Plan the sweep: build_sideslip_matrix over the commanded beta targets
at the constant CAS and altitude, with rudder-fixed and rudder-free
runs inside the declared +-15 deg limit.
- Fit the control gradients from the rudder-fixed run:
rudder_gradient(beta_deg, delta_r_deg) and
aileron_gradient(beta_deg, delta_a_deg).
- Fit the rudder-free case: pedal_force_gradient(beta_deg,
pedal_force_N).
- Declare the control-power inputs cn_dr_per_rad and cl_da_per_rad
(predicted by the flight-mechanics analysis leaf or wind tunnel; they
are inputs here, never claimed as measured).
- Form the signed estimates: signed_directional_estimate(cn_dr_per_rad,
s_r) and signed_lateral_estimate(cl_da_per_rad, s_a).
- Judge the demonstration: weathercock_verdict on the directional
estimate and dihedral_verdict on the lateral estimate.
- For a full sweep, call reduce_sideslip_sweep once with the optional
pedal-force and control-power arguments; the convenience dict returns
every gradient, estimate, verdict and the point count, with None
fields for any optional input not supplied.
- Confirm the deterministic checks with the contract test.
Worked example
Stable transport configuration at constant CAS 80 m/s and altitude
3000 m. Measured sweep beta (deg) = [2, 5, 8, 11, 14]; rudder deflection
(deg) = [+0.24, +0.58, +0.96, +1.34, +1.70]; aileron deflection (deg) =
[-0.35, -0.80, -1.30, -1.80, -2.30]; rudder-free pedal force (N) =
[0, -95, -185, -275, -360]. Declared control powers cn_dr = -0.90 /rad
and cl_da = -0.35 /rad. Real module outputs:
- Rudder gradient s_r = +0.1227 deg/deg (spec magnitude 0.10-0.15): the
pilot pushes the right pedal into the left slip, positive slope.
- Aileron gradient s_a = -0.1633 deg/deg (spec magnitude -0.20 to
-0.12): aileron holds the slip against the dihedral roll, negative
slope.
- Pedal-force gradient g_p = -30.0 N/deg (spec magnitude -40 to -20).
- Directional estimate Cn_beta_est = -(-0.90) * (+0.1227) = +0.110 /rad
(spec 0.08-0.15), weathercock verdict "stable".
- Lateral estimate Cl_beta_est = -(-0.35) * (-0.1633) = -0.057 /rad
(spec -0.10 to -0.03), dihedral verdict "stable".
- build_sideslip_matrix([0, 5, 10], 80, 3000) returns 3 rows with
beta_target_deg [0, 5, 10] and cas_ms 80; a beta target of 20 deg
raises ValueError (outside the declared +-15 deg limit).
Pitfalls
- Misreading the gradient sign conventions: a positive rudder slope
(+0.1227 deg/deg, the pilot pushing the right pedal into the left
slip) is stable weathercocking, and the negative aileron slope
(-0.1633 deg/deg) is stable dihedral; a negative rudder slope or a
positive aileron slope returns "unstable", and an estimate of
exactly 0.0 is "unstable" at the threshold edge.
- Building sideslip points beyond the declared limit: beta targets
past +-15 deg raise ValueError, so the sweep matrix must stay inside
the declared envelope.
- Flipping the control-power sign in the estimate: Cn_beta_est =
-cn_dr * s_r = -(-0.90) * (+0.1227) = +0.110 /rad, so using the
wrong declared cn_dr or cl_da sign turns a stable verdict into an
unstable one; cn_dr = 0 or cl_da = 0 raises ValueError.
- Feeding mismatched or too-short series: the gradients are least
squares over the swept points, and mismatched lengths, too-short
series, or zero x variance all raise ValueError.
- Hand-picking two sweep points instead of the full series: the
reported gradients come from the exact least-squares fit through all
five measured points, and the spec magnitudes (0.10-0.15 rudder,
-0.20 to -0.12 aileron, -40 to -20 N/deg pedal) are checked against
that fit.
- Comparing runs at different conditions: the sweep must be at
constant CAS (80 m/s) and altitude (3000 m), so points from other
conditions need their own reduction.
Verification
- Confirm the worked sweep gradients: rudder +0.1227 (positive), aileron
-0.1633 (negative), pedal -30.0 N/deg, exact least squares through the
five points.
- Confirm the signed estimates +0.110 /rad and -0.057 /rad and the
"stable" weathercock and dihedral verdicts.
- Sign logic: a negative rudder slope (reverse control or directionally
unstable aircraft) returns "unstable" for weathercock_verdict; a
positive aileron slope returns "unstable" for dihedral_verdict; an
estimate of exactly 0.0 returns "unstable" at the threshold edge.
- Confirm ValueError rejection of non-physical inputs: mismatched or
too-short series, zero x variance, cn_dr = 0, cl_da = 0, beta targets
beyond +-15 deg, and non-positive CAS.
- Determinism: no RNG anywhere; run-to-run floats are identical.
- Run the offline contract test: python3
scripts/test_lateral_directional_stability_flight_test.py.
Related leaves
- flight-test-operations/stability/static-stability-flight-test: the
pitch-axis static stability demonstration alongside this one.
- flight-test-operations/stability/dynamic-stability-flight-test: the
mode damping complement to the static lateral-directional picture.
- flight-mechanics/stability-control/lateral-directional-stability: the
prediction sibling that supplies the control-power parameters this leaf
takes as declared inputs.
- flight-test-operations/planning/test-point-matrix-design: sweep matrix
planning for the test campaign.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline):
python3 scripts/test_lateral_directional_stability_flight_test.py
The test covers the worked example end to end (gradients and estimates
within the spec magnitude bounds and exact to 6 places), the least
squares core and its ValueError rejections, the sign logic and verdict
threshold edges, the sideslip matrix row contract and declared limit
enforcement, the convenience dict keys and None fields for optional
inputs, and run-to-run determinism.
Compliance
- FAR 25.177 is cited reference-only per standards-map.yaml; the static
lateral-directional stability criteria above are paraphrased
summary-only, never reproduced from the regulation.
- compliance: STANDARDS-REF, gated: false.
1---2name: lateral-directional-stability-flight-test3description: Use when you must plan and reduce the static lateral-directional stability flight test from steady-heading sideslip data: build the rudder-fixed and rudder-free sideslip sweep matrix at constant airspeed, fit the rudder and aileron deflection gradients versus sideslip angle, estimate the directional stability from the fitted rudder gradient with a declared rudder control power and the lateral dihedral stability from the fitted aileron gradient with a declared aileron control power, record the pedal-force gradient, and issue the weathercock and dihedral stability verdicts for the stability demonstration. Produces the sweep matrix, the fitted gradients, the signed directional and lateral stability estimates, the pedal-force gradient and the verdicts that gate the demonstration. Trigger: steady-heading sideslip, sideslip sweep, rudder gradient, aileron gradient, rudder-fixed stability, rudder-free stability, weathercock stability, dihedral effect, pedal-force gradient.4license: Apache-2.05---67# Lateral-Directional Stability Flight Test (flight-test-operations/stability/lateral-directional-stability-flight-test)89Use when the task is planning and reducing the static lateral-directional10stability flight test of a fixed-wing aircraft from steady-heading11sideslip (SHS) data: the sideslip sweep matrix, the fitted rudder,12aileron and pedal-force gradients, and the signed directional and lateral13stability estimates that gate the demonstration. This leaf implements the14reduction in pure Python, stdlib only. It pairs with the pitch-axis15static stability flight test sibling (trim and margin demonstration) and16the dynamic mode damping sibling for the rest of the stability picture.1718## Domain quick reference1920- Sign convention (documented for every reduction): beta is the sideslip21 angle in degrees, positive when the nose is LEFT of the velocity vector22 (left slip); delta_r positive = right pedal; delta_a positive = right23 aileron (left roll). Measured in steady-heading sideslip maneuvers at24 constant CAS and altitude, the pilot holding heading with aileron and25 setting the slip with rudder.26- Rudder gradient: s_r = d(delta_r)/d(beta) in deg/deg (unitless). For a27 directionally stable aircraft the pilot pushes the rudder INTO the slip28 to increase it, so s_r is positive with the conventional control sign.29- Aileron gradient: s_a = d(delta_a)/d(beta) in deg/deg. For a laterally30 stable aircraft (dihedral effect) the pilot holds the left slip with31 aileron against the roll, so s_a is negative.32- Pedal-force gradient: g_p = d(F_pedal)/d(beta) in N/deg, from the33 rudder-free run (the force the pilot must apply at each beta).34- Signed estimates from the trim balances:35 Cn_beta_est = -cn_dr * s_r and Cl_beta_est = -cl_da * s_a, both in36 /rad. The deg/deg gradient ratios enter as unitless slopes because the37 deg/deg and rad/rad ratios are numerically identical. cn_dr < 0 and38 cl_da < 0 are the conventional signed control powers (right pedal yaws39 the nose right, right aileron rolls left). A stable aircraft yields40 Cn_beta_est > 0 (weathercock stable) and Cl_beta_est < 0 (dihedral41 stable).42- Least squares: fit_slope fits offset plus slope (dy/dx) through the43 sweep points; from two points up, more points tighten the fit, and any44 vertical point set (zero x variance) is rejected.45- Test limit: build_sideslip_matrix holds every commanded beta target46 inside the declared +-15 deg limit (SIDESLIP_LIMIT_DEG) at the constant47 CAS. A sweep needs at least 2 points (BETA_SWEEP_MIN) up to a 40 point48 planning cap (BETA_SWEEP_MAX).49- FAR 25.177 frames the static lateral-directional stability50 demonstration criteria; only paraphrased criteria appear here51 (weathercock stable when the directional estimate is positive, lateral52 stable when the dihedral estimate is negative). Regulation text is53 never reproduced.5455## Workflow56571. Plan the sweep: build_sideslip_matrix over the commanded beta targets58 at the constant CAS and altitude, with rudder-fixed and rudder-free59 runs inside the declared +-15 deg limit.602. Fit the control gradients from the rudder-fixed run:61 rudder_gradient(beta_deg, delta_r_deg) and62 aileron_gradient(beta_deg, delta_a_deg).633. Fit the rudder-free case: pedal_force_gradient(beta_deg,64 pedal_force_N).654. Declare the control-power inputs cn_dr_per_rad and cl_da_per_rad66 (predicted by the flight-mechanics analysis leaf or wind tunnel; they67 are inputs here, never claimed as measured).685. Form the signed estimates: signed_directional_estimate(cn_dr_per_rad,69 s_r) and signed_lateral_estimate(cl_da_per_rad, s_a).706. Judge the demonstration: weathercock_verdict on the directional71 estimate and dihedral_verdict on the lateral estimate.727. For a full sweep, call reduce_sideslip_sweep once with the optional73 pedal-force and control-power arguments; the convenience dict returns74 every gradient, estimate, verdict and the point count, with None75 fields for any optional input not supplied.768. Confirm the deterministic checks with the contract test.7778## Worked example7980Stable transport configuration at constant CAS 80 m/s and altitude813000 m. Measured sweep beta (deg) = [2, 5, 8, 11, 14]; rudder deflection82(deg) = [+0.24, +0.58, +0.96, +1.34, +1.70]; aileron deflection (deg) =83[-0.35, -0.80, -1.30, -1.80, -2.30]; rudder-free pedal force (N) =84[0, -95, -185, -275, -360]. Declared control powers cn_dr = -0.90 /rad85and cl_da = -0.35 /rad. Real module outputs:8687- Rudder gradient s_r = +0.1227 deg/deg (spec magnitude 0.10-0.15): the88 pilot pushes the right pedal into the left slip, positive slope.89- Aileron gradient s_a = -0.1633 deg/deg (spec magnitude -0.20 to90 -0.12): aileron holds the slip against the dihedral roll, negative91 slope.92- Pedal-force gradient g_p = -30.0 N/deg (spec magnitude -40 to -20).93- Directional estimate Cn_beta_est = -(-0.90) * (+0.1227) = +0.110 /rad94 (spec 0.08-0.15), weathercock verdict "stable".95- Lateral estimate Cl_beta_est = -(-0.35) * (-0.1633) = -0.057 /rad96 (spec -0.10 to -0.03), dihedral verdict "stable".97- build_sideslip_matrix([0, 5, 10], 80, 3000) returns 3 rows with98 beta_target_deg [0, 5, 10] and cas_ms 80; a beta target of 20 deg99 raises ValueError (outside the declared +-15 deg limit).100101## Pitfalls102103- Misreading the gradient sign conventions: a positive rudder slope104 (+0.1227 deg/deg, the pilot pushing the right pedal into the left105 slip) is stable weathercocking, and the negative aileron slope106 (-0.1633 deg/deg) is stable dihedral; a negative rudder slope or a107 positive aileron slope returns "unstable", and an estimate of108 exactly 0.0 is "unstable" at the threshold edge.109- Building sideslip points beyond the declared limit: beta targets110 past +-15 deg raise ValueError, so the sweep matrix must stay inside111 the declared envelope.112- Flipping the control-power sign in the estimate: Cn_beta_est =113 -cn_dr * s_r = -(-0.90) * (+0.1227) = +0.110 /rad, so using the114 wrong declared cn_dr or cl_da sign turns a stable verdict into an115 unstable one; cn_dr = 0 or cl_da = 0 raises ValueError.116- Feeding mismatched or too-short series: the gradients are least117 squares over the swept points, and mismatched lengths, too-short118 series, or zero x variance all raise ValueError.119- Hand-picking two sweep points instead of the full series: the120 reported gradients come from the exact least-squares fit through all121 five measured points, and the spec magnitudes (0.10-0.15 rudder,122 -0.20 to -0.12 aileron, -40 to -20 N/deg pedal) are checked against123 that fit.124- Comparing runs at different conditions: the sweep must be at125 constant CAS (80 m/s) and altitude (3000 m), so points from other126 conditions need their own reduction.127128## Verification129130- Confirm the worked sweep gradients: rudder +0.1227 (positive), aileron131 -0.1633 (negative), pedal -30.0 N/deg, exact least squares through the132 five points.133- Confirm the signed estimates +0.110 /rad and -0.057 /rad and the134 "stable" weathercock and dihedral verdicts.135- Sign logic: a negative rudder slope (reverse control or directionally136 unstable aircraft) returns "unstable" for weathercock_verdict; a137 positive aileron slope returns "unstable" for dihedral_verdict; an138 estimate of exactly 0.0 returns "unstable" at the threshold edge.139- Confirm ValueError rejection of non-physical inputs: mismatched or140 too-short series, zero x variance, cn_dr = 0, cl_da = 0, beta targets141 beyond +-15 deg, and non-positive CAS.142- Determinism: no RNG anywhere; run-to-run floats are identical.143- Run the offline contract test: python3144 scripts/test_lateral_directional_stability_flight_test.py.145146## Related leaves147148- flight-test-operations/stability/static-stability-flight-test: the149 pitch-axis static stability demonstration alongside this one.150- flight-test-operations/stability/dynamic-stability-flight-test: the151 mode damping complement to the static lateral-directional picture.152- flight-mechanics/stability-control/lateral-directional-stability: the153 prediction sibling that supplies the control-power parameters this leaf154 takes as declared inputs.155- flight-test-operations/planning/test-point-matrix-design: sweep matrix156 planning for the test campaign.157158## Behavior contract (gate 3)159160Run the deterministic contract test (stdlib unittest, offline):161162 python3 scripts/test_lateral_directional_stability_flight_test.py163164The test covers the worked example end to end (gradients and estimates165within the spec magnitude bounds and exact to 6 places), the least166squares core and its ValueError rejections, the sign logic and verdict167threshold edges, the sideslip matrix row contract and declared limit168enforcement, the convenience dict keys and None fields for optional169inputs, and run-to-run determinism.170171## Compliance172173- FAR 25.177 is cited reference-only per standards-map.yaml; the static174 lateral-directional stability criteria above are paraphrased175 summary-only, never reproduced from the regulation.176- compliance: STANDARDS-REF, gated: false.