From 297d38a905757601554e078bf3183804e45fe6eb Mon Sep 17 00:00:00 2001 From: chasgior214 Date: Tue, 26 Aug 2025 20:33:03 -0400 Subject: [PATCH] BUG: Fix no time initialization when passing initial_solution as array to Flight object ## Pull request type - [x] Code changes (bugfix, features) - [x] Code maintenance (refactoring, formatting, tests) ## Checklist - [ ] Tests for the changes have been added (if needed) - [ ] Docs have been reviewed and added / updated - [ ] Lint (`black rocketpy/ tests/`) has passed locally - [ ] All tests (`pytest tests -m slow --runslow`) have passed locally - [ ] `CHANGELOG.md` has been updated (if relevant) ## Current behavior Passing initial_solution to a Flight object raises `AttributeError: 'Flight' object has no attribute 't_initial'` when running a simulation involving a controller. Attempt to run [this script](https://github.com/werocketry/airbrakes-lookuptable-generator/blob/main/main.py) to reproduce. ## New behavior Initializes t_initial in __init_flight_state when an array is provided as the initial solution. As a result, a simulation can successfully run from an initial condition when controllers are used. Additionally, minor fixes to docstrings in Flight.py ## Breaking change - [ ] Yes - [x] No --- rocketpy/simulation/flight.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/rocketpy/simulation/flight.py b/rocketpy/simulation/flight.py index 5283fd12a..202b6068a 100644 --- a/rocketpy/simulation/flight.py +++ b/rocketpy/simulation/flight.py @@ -143,7 +143,7 @@ class Flight: Flight.heading : int, float Launch heading angle relative to north given in degrees. Flight.initial_solution : list - List defines initial condition - [tInit, x_init, + List defines initial condition - [t_initial, x_init, y_init, z_init, vx_init, vy_init, vz_init, e0_init, e1_init, e2_init, e3_init, w1_init, w2_init, w3_init] Flight.t_initial : int, float @@ -155,10 +155,6 @@ class Flight: Current integration time. Flight.y : list Current integration state vector u. - Flight.initial_solution : list - List defines initial condition - [tInit, x_init, - y_init, z_init, vx_init, vy_init, vz_init, e0_init, e1_init, - e2_init, e3_init, w1_init, w2_init, w3_init] Flight.out_of_rail_time : int, float Time, in seconds, in which the rocket completely leaves the rail. @@ -544,7 +540,7 @@ def __init__( # pylint: disable=too-many-arguments,too-many-statements rtol : float, array, optional Maximum relative error tolerance to be tolerated in the integration scheme. Can be given as array for each - state space variable. Default is 1e-3. + state space variable. Default is 1e-6. atol : float, optional Maximum absolute error tolerance to be tolerated in the integration scheme. Can be given as array for each @@ -1168,6 +1164,7 @@ def __init_flight_state(self): self.out_of_rail_state = self.initial_solution[1:] self.out_of_rail_time = self.initial_solution[0] self.out_of_rail_time_index = 0 + self.t_initial = self.initial_solution[0] self.initial_derivative = self.u_dot_generalized if self._controllers or self.sensors: # Handle post process during simulation, get initial accel/forces @@ -2080,7 +2077,7 @@ def x(self): @funcify_method("Time (s)", "Y (m)", "spline", "constant") def y(self): - """Rocket y position relative to the lauch pad as a Function of + """Rocket y position relative to the launch pad as a Function of time.""" return self.solution_array[:, [0, 2]] @@ -2976,7 +2973,7 @@ def max_rail_button2_shear_force(self): "Time (s)", "Horizontal Distance to Launch Point (m)", "spline", "constant" ) def drift(self): - """Rocket horizontal distance to tha launch point, in meters, as a + """Rocket horizontal distance to the launch point, in meters, as a Function of time.""" return np.column_stack( (self.time, (self.x[:, 1] ** 2 + self.y[:, 1] ** 2) ** 0.5)