Source code for rocketpy.prints.flight_prints

"""rocketpy/prints/flight_prints.py

This module contains the _FlightPrints class, which is responsible for printing
flight information in a user-friendly manner.

Notes
-----
- This module does not have any external dependencies (avoid importing libraries).
- We assume that all flight information is valid, no validation checks is run.
- Avoid calculating values here, only print the values from the Flight class.
- The _FlightPrints is a private class, it is subjected to change without notice.
"""


[docs] class _FlightPrints: """Class that holds prints methods for Flight class. Attributes ---------- _FlightPrints.flight : Flight Flight object that will be used for the prints. """
[docs] def __init__( self, flight, ): """Initializes _FlightPrints class Parameters ---------- flight: Flight Instance of the Flight class. Returns ------- None """ self.flight = flight
[docs] def initial_conditions(self): """Prints initial conditions data available about the flight, including position, velocity, attitude, euler angles, angular velocity, and stability margin. Returns ------- None """ print("\nInitial Conditions\n") t_init = self.flight.time[0] print(f"Initial time: {t_init:.3f} s") print( f"Position - x: {self.flight.x(t_init):.2f} m | " f"y: {self.flight.y(t_init):.2f} m | " f"z: {self.flight.z(t_init):.2f} m" ) print( f"Velocity - Vx: {self.flight.vx(t_init):.2f} m/s | " f"Vy: {self.flight.vy(t_init):.2f} m/s | " f"Vz: {self.flight.vz(t_init):.2f} m/s" ) print( f"Attitude (quaternions) - e0: {self.flight.e0(t_init):.3f} | " f"e1: {self.flight.e1(t_init):.3f} | " f"e2: {self.flight.e2(t_init):.3f} | " f"e3: {self.flight.e3(t_init):.3f}" ) print( f"Euler Angles - Spin φ : {self.flight.phi(t_init):.2f}° | " f"Nutation θ: {self.flight.theta(t_init):.2f}° | " f"Precession ψ: {self.flight.psi(t_init):.2f}°" ) print( f"Angular Velocity - ω1: {self.flight.w1(t_init):.2f} rad/s | " f"ω2: {self.flight.w2(t_init):.2f} rad/s | " f"ω3: {self.flight.w3(t_init):.2f} rad/s" ) print(f"Initial Stability Margin: {self.flight.initial_stability_margin:.3f} c")
[docs] def numerical_integration_settings(self): """Prints out the numerical integration settings available about the flight, this includes the maximum allowed flight time, maximum allowed time step, and other settings. Returns ------- None """ print("\nNumerical Integration Settings\n") print(f"Maximum Allowed Flight Time: {self.flight.max_time:.2f} s") print(f"Maximum Allowed Time Step: {self.flight.max_time_step:.2f} s") print(f"Minimum Allowed Time Step: {self.flight.min_time_step:.2e} s") print(f"Relative Error Tolerance: {self.flight.rtol}") print(f"Absolute Error Tolerance: {self.flight.atol}") print(f"Allow Event Overshoot: {self.flight.time_overshoot}") print(f"Terminate Simulation on Apogee: {self.flight.terminate_on_apogee}") print(f"Number of Time Steps Used: {len(self.flight.time_steps)}") print( "Number of Derivative Functions Evaluation: " f"{sum(self.flight.function_evaluations_per_time_step)}" ) avg_func_evals_per_step = sum( self.flight.function_evaluations_per_time_step ) / len(self.flight.time_steps) print( f"Average Function Evaluations per Time Step: {avg_func_evals_per_step:.3f}" )
[docs] def surface_wind_conditions(self): """Prints out the Surface Wind Conditions for the flight. Returns ------- None """ print("\nSurface Wind Conditions\n") print(f"Frontal Surface Wind Speed: {self.flight.frontal_surface_wind:.2f} m/s") print(f"Lateral Surface Wind Speed: {self.flight.lateral_surface_wind:.2f} m/s")
[docs] def launch_rail_conditions(self): """Prints out the Launch Rail Conditions available about the flight, including the length, inclination, and heading of the launch rail. Returns ------- None """ print("\nLaunch Rail\n") print(f"Launch Rail Length: {self.flight.rail_length} m") print(f"Launch Rail Inclination: {self.flight.inclination:.2f}°") print(f"Launch Rail Heading: {self.flight.heading:.2f}°")
[docs] def out_of_rail_conditions(self): """Prints out the Out of Rail Conditions available about the flight, including the time, velocity, stability margin, angle of attack, thrust to weight ratio, and Reynolds number. Returns ------- None """ print("\nRail Departure State\n") print(f"Rail Departure Time: {self.flight.out_of_rail_time:.3f} s") print(f"Rail Departure Velocity: {self.flight.out_of_rail_velocity:.3f} m/s") print( "Rail Departure Stability Margin: " f"{self.flight.out_of_rail_stability_margin:.3f} c" ) print( "Rail Departure Angle of Attack: " f"{self.flight.angle_of_attack(self.flight.out_of_rail_time):.3f}°" ) print( "Rail Departure Thrust-Weight Ratio: " f"{self.flight.rocket.thrust_to_weight(self.flight.out_of_rail_time):.3f}" ) print( "Rail Departure Reynolds Number: " f"{self.flight.reynolds_number(self.flight.out_of_rail_time):.3e}" )
[docs] def burn_out_conditions(self): """Prints out the Burn Out Conditions available about the flight, including the burn out time, altitude, speed, freestream speed, Mach number, and kinetic energy. Returns ------- None """ print("\nBurn out State\n") print(f"Burn out time: {self.flight.rocket.motor.burn_out_time:.3f} s") print( "Altitude at burn out: " f"{self.flight.z(self.flight.rocket.motor.burn_out_time):.3f} m (ASL) | " f"{self.flight.altitude(self.flight.rocket.motor.burn_out_time):.3f} " "m (AGL)" ) print( "Rocket speed at burn out: " f"{self.flight.speed(self.flight.rocket.motor.burn_out_time):.3f} m/s" ) stream_velocity = self.flight.free_stream_speed( self.flight.rocket.motor.burn_out_time ) print(f"Freestream velocity at burn out: {stream_velocity:.3f} m/s") print( "Mach Number at burn out: " f"{self.flight.mach_number(self.flight.rocket.motor.burn_out_time):.3f}" ) print( "Kinetic energy at burn out: " f"{self.flight.kinetic_energy(self.flight.rocket.motor.burn_out_time):.3e} " "J" )
[docs] def apogee_conditions(self): """Prints out the Apogee Conditions available about the flight, including the apogee time, altitude, freestream speed, latitude, and longitude. Returns ------- None """ print("\nApogee State\n") print(f"Apogee Time: {self.flight.apogee_time:.3f} s") print( f"Apogee Altitude: {self.flight.apogee:.3f} m (ASL) | " f"{self.flight.altitude(self.flight.apogee_time):.3f} m (AGL)" ) print(f"Apogee Freestream Speed: {self.flight.apogee_freestream_speed:.3f} m/s") print(f"Apogee X position: {self.flight.x(self.flight.apogee_time):.3f} m") print(f"Apogee Y position: {self.flight.y(self.flight.apogee_time):.3f} m") print(f"Apogee latitude: {self.flight.latitude(self.flight.apogee_time):.7f}°") print( f"Apogee longitude: {self.flight.longitude(self.flight.apogee_time):.7f}°" )
[docs] def events_registered(self): """Prints out the Events Registered available about the flight. Returns ------- None """ print("\nParachute Events\n") if len(self.flight.parachute_events) == 0: print("No Parachute Events Were Triggered.") for event in self.flight.parachute_events: trigger_time = event[0] parachute = event[1] open_time = trigger_time + parachute.lag speed = self.flight.free_stream_speed(open_time) altitude = self.flight.z(open_time) name = parachute.name.title() print(f"Parachute: {name}") print(f"\tEjection time: {trigger_time:.3f} s") print(f"\tInflation time: {open_time:.3f} s") print(f"\tFreestream speed at inflation: {speed:.3f} m/s") print( f"\tAltitude at inflation: {altitude:.3f} m (ASL) | " f"{self.flight.altitude(trigger_time):.3f} m (AGL)" )
[docs] def impact_conditions(self): """Prints out the Impact Conditions available about the flight. Returns ------- None """ if len(self.flight.impact_state) != 0: print("\nImpact Conditions\n") print(f"Time of impact: {self.flight.t_final:.3f} s") print(f"X impact: {self.flight.x_impact:.3f} m") print(f"Y impact: {self.flight.y_impact:.3f} m") print( f"Altitude impact: {self.flight.z(self.flight.t_final):.3f} m (ASL) | " f"{self.flight.altitude(self.flight.t_final):.3f} m (AGL) " ) print(f"Latitude: {self.flight.latitude(self.flight.t_final):.7f}°") print(f"Longitude: {self.flight.longitude(self.flight.t_final):.7f}°") print(f"Vertical velocity at impact: {self.flight.impact_velocity:.3f} m/s") num_parachute_events = sum( 1 for event in self.flight.parachute_events if event[0] < self.flight.t_final ) print( f"Number of parachutes triggered until impact: {num_parachute_events}" ) elif self.flight.terminate_on_apogee is False: print("End of Simulation") t_final = self.flight.time[-1] print(f"Time: {t_final:.3f} s") print( f"Altitude: {self.flight.z(t_final)} m (ASL) | " f"{self.flight.altitude(t_final):.3f} m (AGL)" ) print(f"Latitude: {self.flight.latitude(t_final):.7f}°") print(f"Longitude: {self.flight.longitude(t_final):.7f}°")
[docs] def maximum_values(self): """Prints out the Maximum Values available about the flight. Returns ------- None """ print("\nMaximum Values\n") print( f"Maximum Speed: {self.flight.max_speed:.3f} m/s " f"at {self.flight.max_speed_time:.2f} s" ) print( f"Maximum Mach Number: {self.flight.max_mach_number:.3f} Mach " f"at {self.flight.max_mach_number_time:.2f} s" ) print( f"Maximum Reynolds Number: {self.flight.max_reynolds_number:.3e} " f"at {self.flight.max_reynolds_number_time:.2f} s" ) print( f"Maximum Dynamic Pressure: {self.flight.max_dynamic_pressure:.3e} Pa " f"at {self.flight.max_dynamic_pressure_time:.2f} s" ) print( "Maximum Acceleration During Motor Burn: " f"{self.flight.max_acceleration_power_on:.3f} m/s² " f"at {self.flight.max_acceleration_power_on_time:.2f} s" ) print( "Maximum Gs During Motor Burn: " f"{self.flight.max_acceleration_power_on / self.flight.env.standard_g:.3f} " f"g at {self.flight.max_acceleration_power_on_time:.2f} s" ) print( "Maximum Acceleration After Motor Burn: " f"{self.flight.max_acceleration_power_off:.3f} m/s² " f"at {self.flight.max_acceleration_power_off_time:.2f} s" ) print( "Maximum Gs After Motor Burn: " f"{self.flight.max_acceleration_power_off / self.flight.env.standard_g:.3f}" f" Gs at {self.flight.max_acceleration_power_off_time:.2f} s" ) print( f"Maximum Stability Margin: {self.flight.max_stability_margin:.3f} c " f"at {self.flight.max_stability_margin_time:.2f} s" ) if ( len(self.flight.rocket.rail_buttons) == 0 or self.flight.out_of_rail_time_index == 0 ): pass else: print( "Maximum Upper Rail Button Normal Force: " f"{self.flight.max_rail_button1_normal_force:.3f} N" ) print( "Maximum Upper Rail Button Shear Force: " f"{self.flight.max_rail_button1_shear_force:.3f} N" ) print( "Maximum Lower Rail Button Normal Force: " f"{self.flight.max_rail_button2_normal_force:.3f} N" ) print( "Maximum Lower Rail Button Shear Force: " f"{self.flight.max_rail_button2_shear_force:.3f} N" )
[docs] def stability_margin(self): """Prints out the stability margins of the flight at different times. This method prints the following: Initial Stability Margin, Out of Rail Stability Margin, Maximum Stability Margin, and Minimum Stability Margin Each stability margin is printed along with the time it occurred. Notes ----- The stability margin is typically measured in calibers (c), where 1 caliber is the diameter of the rocket. """ print("\nStability Margin\n") print( f"Initial Stability Margin: {self.flight.initial_stability_margin:.3f} c " f"at {self.flight.time[0]:.2f} s" ) print( "Out of Rail Stability Margin: " f"{self.flight.out_of_rail_stability_margin:.3f} c " f"at {self.flight.out_of_rail_time:.2f} s" ) print( f"Maximum Stability Margin: {self.flight.max_stability_margin:.3f} c " f"at {self.flight.max_stability_margin_time:.2f} s" ) print( f"Minimum Stability Margin: {self.flight.min_stability_margin:.3f} c " f"at {self.flight.min_stability_margin_time:.2f} s" )
[docs] def all(self): """Prints out all data available about the Flight. This method invokes all other print methods in the class. Returns ------- None """ self.initial_conditions() print() self.surface_wind_conditions() print() self.launch_rail_conditions() print() self.out_of_rail_conditions() print() self.burn_out_conditions() print() self.apogee_conditions() print() self.events_registered() print() self.impact_conditions() print() self.stability_margin() print() self.maximum_values() print() self.numerical_integration_settings() print()