Valetudo - Projeto Jupiter - 2019#

Valetudo launch from Projeto Jupiter (University of São Paulo, Brazil). Permission to use flight data given by Guilherme Fernandes, 2020

[80]:
%load_ext autoreload
%autoreload 2
The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload
[81]:
# Importing libraries
import matplotlib.pyplot as plt

from rocketpy import Environment, Flight, Rocket, SolidMotor
[82]:
plt.style.use("seaborn-v0_8-dark-palette")

RocketPy Simulation#

Define a dictionary with the inputs for the simulation

[83]:
parameters = {
    # Mass Details
    "rocket_mass": (8.257, 0.001),
    # Propulsion Details
    "impulse": (1415.15, 35.3),
    "burn_time": (5.274, 1),
    "nozzle_radius": (21.642 / 1000, 0.5 / 1000),
    "throat_radius": (8 / 1000, 0.5 / 1000),
    "grain_separation": (6 / 1000, 1 / 1000),
    "grain_density": (1707, 50),
    "grain_outer_radius": (21.4 / 1000, 0.375 / 1000),
    "grain_initial_inner_radius": (9.65 / 1000, 0.375 / 1000),
    "grain_initial_height": (120 / 1000, 1 / 1000),
    # Aerodynamic Details
    "inertia_I": (3.675, 0.03675),
    "inertia_Z": (0.007, 0.00007),
    "radius": (40.45 / 1000, 0.001),
    "distance_rocket_nozzle": (-1.024, 0.001),
    "distance_rocket_propellant": (-0.571, 0.001),
    "power_off_drag": (0.9081 / 1.05, 0.033),
    "power_on_drag": (0.9081 / 1.05, 0.033),
    "nose_length": (0.274, 0.001),
    "nose_distance_to_cm": (1.134, 0.001),
    "fin_span": (0.077, 0.0005),
    "fin_root_chord": (0.058, 0.0005),
    "fin_tip_chord": (0.018, 0.0005),
    "fin_distance_to_cm": (-0.906, 0.001),
    # Launch and Environment Details
    "wind_direction": (0, 2),
    "wind_speed": (1, 0.033),
    "inclination": (84.7, 1),
    "heading": (53, 2),
    "rail_length": (5.7, 0.0005),
    # Parachute Details
    "cd_s_drogue": (0.349 * 1.3, 0.07),
    "lag_rec": (1, 0.5),
    # Electronic Systems Details
    "lag_se": (0.73, 0.16),
}

Environment#

Define the Environment object

[84]:
# Environment conditions
env = Environment(
    date=(2019, 8, 10, 21),
    latitude=-23.363611,
    longitude=-48.011389,
    elevation=668,
)

env.set_atmospheric_model(
    type="Reanalysis",
    file="../../tests/fixtures/acceptance/PJ_Valetudo/valetudo_weather_data_ERA5.nc",
    dictionary="ECMWF",
)

Visualize the Environment object

[85]:
env.info()

Gravity Details

Acceleration of Gravity at Lauch Site: 9.786388824688004 m/s²


Launch Site Details

Launch Date: 2019-08-10 21:00:00 UTC
Launch Site Latitude: -23.36361°
Launch Site Longitude: -48.01139°
Reference Datum: SIRGAS2000
Launch Site UTM coordinates: 192123.24 W    7413017.14 S
Launch Site UTM zone: 23K
Launch Site Surface Elevation: 668.0 m


Atmospheric Model Details

Atmospheric Model Type: Reanalysis
Reanalysis Maximum Height: 4.438 km
Reanalysis Time Period: From  2019-08-10 00:00:00  to  2019-08-10 21:00:00  UTC
Reanalysis Hour Interval: 5  hrs
Reanalysis Latitude Range: From  -22.0 ° To  -24.0 °
Reanalysis Longitude Range: From  -49.0 ° To  -47.0 °


Surface Atmospheric Conditions

Surface Wind Speed: 3.27 m/s
Surface Wind Direction: 276.77°
Surface Wind Heading: 96.77°
Surface Pressure: 941.84 hPa
Surface Temperature: 301.53 K
Surface Air Density: 1.088 kg/m³
Surface Speed of Sound: 348.11 m/s


Atmospheric Model Plots

../_images/examples_valetudo_flight_sim_11_1.png

Motor#

Define the SolidMotor object

[86]:
keron = SolidMotor(
    thrust_source="../../data/motors/keron/thrustCurve.csv",
    burn_time=parameters.get("burn_time")[0],
    dry_mass=0.001,
    dry_inertia=(0, 0, 0),
    center_of_dry_mass_position=0.42,
    grains_center_of_mass_position=0.42,
    grain_number=6,
    grain_separation=parameters.get("grain_separation")[0],
    grain_density=parameters.get("grain_density")[0],
    grain_outer_radius=parameters.get("grain_outer_radius")[0],
    grain_initial_inner_radius=parameters.get("grain_initial_inner_radius")[0],
    grain_initial_height=parameters.get("grain_initial_height")[0],
    nozzle_radius=parameters.get("nozzle_radius")[0],
    throat_radius=parameters.get("throat_radius")[0],
    interpolation_method="linear",
    nozzle_position=0,
    coordinate_system_orientation="nozzle_to_combustion_chamber",
)
[87]:
keron.info()
Nozzle Details
Nozzle Radius: 0.021641999999999998 m
Nozzle Throat Radius: 0.008 m

Grain Details
Number of Grains: 6
Grain Spacing: 0.006 m
Grain Density: 1707 kg/m3
Grain Outer Radius: 0.0214 m
Grain Inner Radius: 0.00965 m
Grain Height: 0.12 m
Grain Volume: 0.000 m3
Grain Mass: 0.235 kg

Motor Details
Total Burning Time: 5.274 s
Total Propellant Mass: 1.409 kg
Average Propellant Exhaust Velocity: 1004.589 m/s
Average Thrust: 268.327 N
Maximum Thrust: 1068.36 N at 1.508 s after ignition.
Total Impulse: 1415.154 Ns

../_images/examples_valetudo_flight_sim_15_1.png

Rocket#

Create the Rocket object

[88]:
valetudo = Rocket(
    radius=parameters.get("radius")[0],
    mass=parameters.get("rocket_mass")[0],
    inertia=(
        parameters.get("inertia_I")[0],
        parameters.get("inertia_I")[0],
        parameters.get("inertia_Z")[0],
    ),
    power_off_drag="../../tests/fixtures/acceptance/PJ_Valetudo/valetudo_drag_power_off.csv",
    power_on_drag="../../tests/fixtures/acceptance/PJ_Valetudo/valetudo_drag_power_on.csv",
    center_of_mass_without_motor=0,
)
valetudo.set_rail_buttons(0.224, -0.93, 30)
valetudo.add_motor(motor=keron, position=parameters.get("distance_rocket_nozzle")[0])

Adding aerodynamic surfaces

[89]:
nose_cone = valetudo.add_nose(
    length=parameters.get("nose_length")[0],
    kind="tangent",
    position=parameters.get("nose_distance_to_cm")[0],
)
fin_set = valetudo.add_trapezoidal_fins(
    3,
    span=parameters.get("fin_span")[0],
    root_chord=parameters.get("fin_root_chord")[0],
    tip_chord=parameters.get("fin_tip_chord")[0],
    position=parameters.get("fin_distance_to_cm")[0],
)
Due to the chosen bluffness ratio, the nose cone length was reduced to 0.274 m.

Adding Parachute

[90]:
drogue = valetudo.add_parachute(
    "Drogue",
    cd_s=parameters.get("cd_s_drogue")[0],
    trigger="apogee",
    sampling_rate=105,
    lag=parameters.get("lag_rec")[0],
    noise=(0, 8.3, 0.5),
)

Modify the Drag Coefficient curve

[91]:
valetudo.draw()
../_images/examples_valetudo_flight_sim_24_0.png
[92]:
valetudo.info()

Inertia Details

Rocket Mass: 8.257 kg
Rocket Dry Mass: 8.258 kg (With Motor)
Rocket Mass: 9.667 kg (With Propellant)
Rocket Inertia (with motor, but without propellant) 11: 3.677 kg*m2
Rocket Inertia (with motor, but without propellant) 22: 3.677 kg*m2
Rocket Inertia (with motor, but without propellant) 33: 0.007 kg*m2
Rocket Inertia (with motor, but without propellant) 12: 0.000 kg*m2
Rocket Inertia (with motor, but without propellant) 13: 0.000 kg*m2
Rocket Inertia (with motor, but without propellant) 23: 0.000 kg*m2


Geometrical Parameters

Rocket Maximum Radius: 0.04045 m
Rocket Frontal Area: 0.005140 m2

Rocket Distances
Rocket Center of Dry Mass - Center of Mass withour Motor: 0.000 m
Rocket Center of Dry Mass - Nozzle Exit Distance: 1.024 m
Rocket Center of Dry Mass - Center of Propellant Mass: 1.444 m
Rocket Center of Mass - Rocket Loaded Center of Mass: 0.210 m


Aerodynamics Lift Coefficient Derivatives

Nose Cone Lift Coefficient Derivative: 2.000/rad
Fins Lift Coefficient Derivative: 4.402/rad

Aerodynamics Center of Pressure

Nose Cone Center of Pressure to CM: 1.007 m
Fins Center of Pressure to CM: -0.933 m
Distance - Center of Pressure to Center of Dry Mass: 0.116 m
Initial Static Margin: 1.437 c
Final Static Margin: 4.038 c


Parachute Details

Parachute Drogue with a cd_s of 0.4537 m2
Ejection signal trigger: At Apogee
Ejection system refresh rate: 105.000 Hz
Time between ejection signal is triggered and the parachute is fully opened: 1.0 s


Flight#

[93]:
test_flight = Flight(
    rocket=valetudo,
    environment=env,
    rail_length=parameters.get("rail_length")[0],
    inclination=parameters.get("inclination")[0],
    heading=parameters.get("heading")[0],
)
[94]:
test_flight.info()
test_flight.plots.trajectory_3d()

Initial Conditions

Position - x: 0.00 m | y: 0.00 m | z: 668.00 m
Velocity - Vx: 0.00 m/s | Vy: 0.00 m/s | Vz: 0.00 m/s
Attitude - e0: 0.894 | e1: -0.041 | e2: 0.021 | e3: -0.446
Euler Angles - Spin φ : 0.00° | Nutation θ: -5.30° | Precession ψ: -53.00°
Angular Velocity - ω1: 0.00 rad/s | ω2: 0.00 rad/s| ω3: 0.00 rad/s


Surface Wind Conditions

Frontal Surface Wind Speed: 2.33 m/s
Lateral Surface Wind Speed: -2.30 m/s


Launch Rail

Launch Rail Length: 5.7  m
Launch Rail Inclination: 84.70°
Launch Rail Heading: 53.00°


Rail Departure State

Rail Departure Time: 1.084 s
Rail Departure Velocity: 22.598 m/s
Rail Departure Static Margin: 1.886 c
Rail Departure Angle of Attack: 8.439°
Rail Departure Thrust-Weight Ratio: 8.214
Rail Departure Reynolds Number: 1.074e+05


Burn out State

Burn out time: 5.274 s
Altitude at burn out: 429.330 m (AGL)
Rocket velocity at burn out: 94.951 m/s
Freestream velocity at burn out: 94.830 m/s
Mach Number at burn out: 0.274
Kinetic energy at burn out: 3.723e+04 J


Apogee State

Apogee Altitude: 1493.387 m (ASL) | 825.387 m (AGL)
Apogee Time: 14.075 s
Apogee Freestream Speed: 8.974 m/s


Parachute Events

Drogue Ejection Triggered at: 14.076 s
Drogue Parachute Inflated at: 15.076 s
Drogue Parachute Inflated with Freestream Speed of: 12.999 m/s
Drogue Parachute Inflated at Height of: 820.553 m (AGL)


Impact Conditions

X Impact: 388.136 m
Y Impact: 76.276 m
Time of Impact: 61.170 s
Velocity at Impact: -18.133 m/s


Maximum Values

Maximum Speed: 124.103 m/s at 2.61 s
Maximum Mach Number: 0.357 Mach at 2.61 s
Maximum Reynolds Number: 5.830e+05 at 2.59 s
Maximum Dynamic Pressure: 8.260e+03 Pa at 2.59 s
Maximum Acceleration During Motor Burn: 108.160 m/s² at 1.60 s
Maximum Gs During Motor Burn: 11.029 g at 1.60 s
Maximum Acceleration After Motor Burn: 0.000 m/s² at 0.01 s
Maximum Gs After Motor Burn: 0.000 g at 0.01 s
Maximum Upper Rail Button Normal Force: 1.438 N
Maximum Upper Rail Button Shear Force: 0.390 N
Maximum Lower Rail Button Normal Force: 0.137 N
Maximum Lower Rail Button Shear Force: 0.037 N


Numerical Integration Settings

Maximum Allowed Flight Time: 600.000000 s
Maximum Allowed Time Step: inf s
Minimum Allowed Time Step: 0.000000e+00 s
Relative Error Tolerance:  1e-06
Absolute Error Tolerance:  [0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 1e-06, 1e-06, 1e-06, 1e-06, 0.001, 0.001, 0.001]
Allow Event Overshoot:  True
Terminate Simulation on Apogee:  False
Number of Time Steps Used:  533
Number of Derivative Functions Evaluation:  2021
Average Function Evaluations per Time Step: 3.791745

../_images/examples_valetudo_flight_sim_28_1.png

Comparison with the real flight data#

[95]:
# The flight recordings were lost after the launch. Only three useful information were recovered:
# - The apogee altitude (AGL): 860 m
# - East/West drift: 350 m
# - North/South drift: 25 m
# - Total drift: 350.9 m
[96]:
actual_data = {
    "apogee": 860,
    "east_west_drift": 350,
    "north_south_drift": 25,
    "total_drift": 350.9,
}
[97]:
simulated = {
    "apogee": test_flight.apogee - test_flight.env.elevation,
    "east_west_drift": test_flight.x(test_flight.t_final),
    "north_south_drift": test_flight.y(test_flight.t_final),
    "total_drift": test_flight.drift(test_flight.t_final),
}
[98]:
apogee_actual = actual_data.get("apogee")
apogee_simulated = simulated.get("apogee")
apogee_error = abs(apogee_actual - apogee_simulated)
apogee_percentage_error = apogee_error / apogee_actual * 100

print("Apogee (AGL): ")
print(f"Actual: {apogee_actual:.2f} m")
print(f"Simulated: {apogee_simulated:.2f} m")
print(f"Error: {apogee_error:.2f} m")
print(f"Percentage Error: {apogee_percentage_error:.2f}%")
Apogee (AGL):
Actual: 860.00 m
Simulated: 825.39 m
Error: 34.61 m
Percentage Error: 4.02%
[99]:
drift_actual = actual_data.get("total_drift")
drift_simulated = simulated.get("total_drift")
drift_error = abs(drift_actual - drift_simulated)
drift_percentage_error = drift_error / drift_actual * 100

print("Drift")
print(f"Actual: {drift_actual:.2f} m")
print(f"Simulated: {drift_simulated:.2f} m")
print(f"Error: {drift_error:.2f} m")
print(f"Percentage Error: {drift_percentage_error:.2f}%")
Drift
Actual: 350.90 m
Simulated: 395.56 m
Error: 44.66 m
Percentage Error: 12.73%