ENH: Galejs body lift with planform geometry (nose cone, tail) and new BodyTube surface - #1184
Draft
ViniciusCMB wants to merge 8 commits into
Draft
Conversation
Adds the nonlinear sin²α body-lift term (Galejs, K=1.1) to compute_forces_and_moments, with blended CP between the slender-body and planform-centroid positions. The low-speed / high-α damping factor (M/0.05)² is applied at apogee-like conditions. Backward-compatible: the body-lift attributes default to zero, so all existing surfaces behave identically until they opt in by setting _planform_area, _planform_centroid and _cp_slender.
Adds closed-form tests for the body-lift hook: Galejs sin^2 alpha magnitude, low-speed/high-alpha damping, force-weighted CP blend bounds, the pure-tube zero-linear-term limit and backward compatibility for non-opted surfaces. Also converts the class docstring to a raw string and removes redundant lambdas to satisfy pylint (10.00/10).
NoseCone computes the planform area and centroid by trapezoidal integration of its contour (valid for every nose kind); Tail uses the closed-form trapezoid of a conical frustum. Both store the slender-body CP required by the CP blend, recompute on geometry setters, and thus opt in to the nonlinear sin^2 alpha body-lift term like OpenRocket's SymmetricComponentCalc.
New constant-radius cylindrical surface whose normal force comes entirely from the Galejs body-lift term (clalpha identically zero), applied at the planform centroid, matching OpenRocket's treatment of straight tubes. Exported from rocketpy and rocket.aero_surface; tests cover geometry, the pure-Galejs force/moment and rocket integration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull request type
Checklist
make lint) has passed locallypytest tests -m slow --runslow) have passed locally (37 passed, 2 skipped; the only failure istest_wyoming_sounding_atmosphere, a network-dependent Environment test unrelated to this PR — it also fails/skips on a clean checkout)CHANGELOG.mdhas been updated (if relevant)Current behavior
RocketPy has no body-lift model: constant-radius body tubes generate zero normal force, and nose/transition lift is strictly linear (
CNα·α), following the classic Barrowman method. This is one of the gaps identified in the RocketPy vs OpenRocket physics comparison — OpenRocket applies the Galejs nonlinearsin²αterm (K = 1.1) to every symmetric component, migrating the CP aft at high angle of attack (a real, stabilizing effect, dominant near apogee).Draft note: opened as draft to discuss the open points listed at the bottom, especially the expected-value updates needed in
tests/unit/simulation/test_flight.py.New behavior
_BarrowmanSurface.compute_forces_and_momentsoptionally adds the Galejs body-lift term with the low-speed/high-α damping factor(M/0.05)², applied at a force-weighted blend between the slender-body CP and the planform centroid.NoseConecomputes its planform area/centroid by integrating its contour (valid for all kinds);Tailuses the closed-form trapezoid of a conical frustum. Both opt in automatically.BodyTubesurface (clalpha ≡ 0; normal force comes entirely from the Galejs term at the planform centroid), exported asrocketpy.BodyTube, with aRocket.add_body_tube(length, position)convenience method.Breaking change
Simulations with nose cones and/or tails now produce different results at high angle of attack (near-apogee flight, strong winds, non-nominal flights). The CP migrates aft, increasing static margin — matching OpenRocket's behavior. Low-α portions of flight are essentially unaffected.
Additional information
Open points before this leaves draft:
tests/unit/simulation/test_flight.py.The Calisto fixtures' expected values were captured without body lift:
test_aerodynamic_moments/forces/velocities/accelerations,test_rail_buttons_forces: frozen numbers diverge beyond tolerance (e.g. rail-button normal force +78%).test_stability_static_margins(12 params): rockets are calibrated to an exact linear static margin, but the Galejs term stabilizes at high α, so margin≈0/negative cases no longer show the assumed moment behavior. Options: zero out fixture planforms to isolate the linear mechanism, recalibrate including Galejs, or relax assertions.auto_body_tubes=True) considered but not implemented — explicit API only for now.References: Galejs, "Body Lift Extension to Barrowman's CP Calculation" (2003); OpenRocket
SymmetricComponentCalc.