From e5f34e83660dfba5739c762a2d35bdf0bc8784dc Mon Sep 17 00:00:00 2001 From: Aasit Vora Date: Sun, 4 Oct 2026 19:35:02 +0530 Subject: [PATCH] feat(flight): report parachute deployment times in the simulation A client plotting deployment markers could previously only derive them, and only for trigger='apogee': an altitude-triggered main deploys when the trajectory crosses a height, which no summary scalar encodes. Deriving it from the encoded `altitude` series is possible but imprecise - that series is downsampled to 25 points, so on a 190s flight both of Razzo's descent deployments fall inside a single 7.9s gap and interpolating across the kink where the canopy opened puts the marker ~2s out. RocketPy already knows the answer. flight.parachute_events carries the exact deployment time for every chute that opened, including callable triggers that cannot be derived at all. The field is projected to {name, time} in the service rather than declared and left to the encoder: encoding the Parachute objects wholesale drags each one's noise_signal - thousands of samples per chute - into every simulate response. --- src/services/flight.py | 9 +++++++++ src/views/flight.py | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/src/services/flight.py b/src/services/flight.py index 489b120..b19873c 100644 --- a/src/services/flight.py +++ b/src/services/flight.py @@ -500,6 +500,15 @@ def get_flight_simulation(self) -> FlightSimulation: ], ) flight_simulation = FlightSimulation(**encoded_attributes) + + # Project the deployment list down to name + time. Encoding the + # Parachute objects wholesale drags each one's noise_signal - thousands + # of samples per chute - into every simulate response, and a client + # plotting deployment markers needs neither. + flight_simulation.parachute_events = [ + {"name": parachute.name, "time": deploy_time} + for deploy_time, parachute in self.flight.parachute_events + ] return flight_simulation def get_flight_kml(self) -> bytes: diff --git a/src/views/flight.py b/src/views/flight.py index cc6f00a..5097c27 100644 --- a/src/views/flight.py +++ b/src/views/flight.py @@ -20,6 +20,13 @@ class FlightSimulation(ApiBaseView): message: str = "Flight successfully simulated" + # [{name, time}] for every chute that opened, projected in the service + # from RocketPy's flight.parachute_events. Without it a client can only + # *derive* trigger times, and only for `trigger='apogee'` - an + # altitude-triggered main has no derivable timestamp and silently goes + # unreported. + parachute_events: Optional[Any] = None + # Core Flight attributes (always present) # Core Flight attributes (always present)