ENH: support fixed-time parachute deployment triggers (#437) - #1133
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1133 +/- ##
===========================================
+ Coverage 84.45% 84.47% +0.01%
===========================================
Files 131 131
Lines 17495 17515 +20
===========================================
+ Hits 14775 14795 +20
Misses 2720 2720 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Conflicting with |
Conflicts, both from RocketPy-Team#1121 ("evaluate parachute triggers once per time node"), which landed after this branch was cut: - rocketpy/simulation/flight.py: RocketPy-Team#1121 moved the parachute loop out of __simulate into __check_and_handle_parachute_triggers, and in doing so already changed the trigger evaluation time from self.t to node.t. This branch had made the same self.t -> node.t change by hand, so that part of it is now redundant upstream. Resolved to develop's extracted helper; the only thing this branch still changes in flight.py is the one line setting parachute._eval_time. - tests/unit/test_parachute_triggers.py: both sides appended a test to the end of the file. Kept both. Two follow-ups while here: - Parachute.__init__ now declares self._eval_time = None next to _trigger_falling_only and _trigger_needs_height, so the attribute is part of the object's state rather than something Flight conjures onto it. The trigger closure reads self._eval_time directly; the getattr default was unreachable anyway, since triggerfunc only exists once __init__ has run. - docs/user/parachute_triggers.rst gained a "Fixed-time trigger" section. That page documents the "apogee" and numeric-altitude forms and tells readers a burnout delay needs a custom trigger, so leaving the new built-in form out of it was the one real gap. Includes the ("time", motor.burn_out_time + delay) composition and a note that firing at speed produces large loads. Verified: tests/unit 2131 passed, 17 skipped; the new integration test and the three parachute unit modules pass; ruff check and format clean; pylint 10.00/10. Checked in a real flight that ("time", 3.0) and ("time", 8.0) deploy at exactly those times while still ascending (vz +268 and +192 m/s), and that a plain "apogee" chute still fires at apogee. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
RocketPy-Team#1116 widened the height check to numbers.Real and, to stop the two copies of that check drifting apart, gave Parachute a single _is_a_height_trigger that stochastic/ now calls. This branch had edited the same predicate and the same two test modules, so it conflicted in three files. The two changes compose better than either alone: - _is_a_trigger keeps its ("time", t_deploy) branch, and the height case defers to _is_a_height_trigger as RocketPy-Team#1116 intended. - The time delay now uses that same predicate instead of a float() coercion wrapped in try/except. That was a real disagreement waiting to happen: float("3.0") succeeds, so ("time", "3.0") was accepted by Parachute while the stochastic check refused it. A string delay is now refused on both sides rather than quietly coerced. - RocketPy-Team#1116's drift guard grew the time forms, so it now covers this shape too. Reverting the Parachute side to the lenient coercion makes it fail with ('time', '3.0'): stochastic/ says False, Parachute says True. - Both test modules had appended to the same lists and to the end of the same files; kept both sides throughout, and added ("time", "3.0") to the refused-trigger cases. Verified: tests/unit 2154 passed, 17 skipped; the parachute unit modules and the new integration test give 89 passed; ruff check and format clean; pylint 10.00/10. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Brought this up to date with Round one: #1121 ("evaluate parachute triggers once per time node"). It landed after your branch was cut and moved the parachute loop out of Round two: #1116 landed mid-review and widened the height check to
Two other things while I was in here:
On the design, for the record: I checked the two things that could have made this quietly wrong and both are right. The overshoot fast path skips a parachute only when I also verified it in a real flight rather than only through the unit tests: One note for you: the |
Summary
trigger=("time", t_deploy)so parachutes can deploy at a fixed flight time from launch (motor delay-charge style), addressing ENH: Addition of Time Delay Parachute Deployment #437.parachute._eval_timebefore evaluating triggers; no change to the public(p, h, y, sensors, u_dot)triggerfunc signature.("time", motor.burn_out_time + delay). A native("burnout", delay)trigger is left as a follow-up to avoid coupling Parachute construction to motor state.Test plan
("time", t)True/False at boundary times, ascent-safe behavior, invalid forms, serializationFlight._evaluate_parachute_triggersets_eval_timeand fires correctlyt_deployFixes #437