Skip to content

Commit

Permalink
TST: adds prometheus apogee acceptance test
Browse files Browse the repository at this point in the history
  • Loading branch information
Gui-FernandesBR committed May 16, 2024
1 parent 5b510f6 commit 3327620
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
70 changes: 70 additions & 0 deletions tests/acceptance/test_prometheus_rocket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from rocketpy import Flight
from rocketpy.simulation.flight_data_importer import FlightDataImporter


def test_prometheus_rocket_data_asserts_acceptance(
environment_spaceport_america_2023, prometheus_rocket
):
"""Tests the Prometheus rocket flight data against acceptance criteria.
This function simulates a rocket flight using the given environment and
rocket parameters, then compares the simulated apogee with real flight data
to ensure the relative error is within acceptable thresholds.
Parameters
----------
environment_spaceport_america_2023 : Environment
An environment configuration for Spaceport America in 2023.
prometheus_rocket : Rocket
The Prometheus rocket configuration.
Raises
------
AssertionError
If the relative error between the simulated apogee and the real apogee
exceeds the threshold.
"""
# Define relative error threshold (defined manually based on data)
apogee_threshold = 7.5 / 100

# Simulate the flight
test_flight = Flight(
rocket=prometheus_rocket,
environment=environment_spaceport_america_2023,
inclination=80,
heading=75,
rail_length=5.18,
)

# Read the flight data
columns_map = {
"time": "time",
"altitude": "z",
"height": "altitude",
"acceleration": "acceleration",
"pressure": "pressure",
"accel_x": "ax",
"accel_y": "ay",
"accel_z": "az",
"latitude": "latitude",
"longitude": "longitude",
}

altimeter_data = FlightDataImporter(
name="Telemetry Mega",
paths="data/prometheus/2022-06-24-serial-6583-flight-0003-TeleMega.csv",
columns_map=columns_map,
units=None,
interpolation="linear",
extrapolation="zero",
delimiter=",",
encoding="utf-8",
)

# Calculate errors and assert values
real_apogee = altimeter_data.altitude.max
rocketpy_apogee = test_flight.apogee - test_flight.env.elevation
a_error = abs(real_apogee - rocketpy_apogee)
r_error = a_error / real_apogee

assert r_error < apogee_threshold, f"Apogee relative error is {r_error*100:.2f}%"
27 changes: 27 additions & 0 deletions tests/fixtures/environment/environment_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,30 @@ def env_analysis():
)

return env_analysis


@pytest.fixture
def environment_spaceport_america_2023():
"""Creates an Environment object for Spaceport America with a 2023 launch
conditions.
Returns
-------
rocketpy.Environment
Environment object configured for Spaceport America in 2023.
"""
env = Environment(
latitude=32.939377,
longitude=-106.911986,
elevation=1401,
)
env.set_date(date=(2023, 6, 24, 9), timezone="America/Denver")

env.set_atmospheric_model(
type="Reanalysis",
file="data/weather/spaceport_america_pressure_levels_2023_hourly.nc",
dictionary="ECMWF",
)

env.max_expected_height = 6000
return env
24 changes: 24 additions & 0 deletions tests/fixtures/motor/generic_motor_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,27 @@ def generic_motor():
)

return motor


@pytest.fixture
def generic_motor_cesaroni_M1520():
"""Defines a Cesaroni M1520 motor for the Prometheus rocket using the
GenericMotor class.
Returns
-------
GenericMotor
The Cesaroni M1520 motor for the Prometheus rocket.
"""
return GenericMotor(
# burn specs: https://www.thrustcurve.org/simfiles/5f4294d20002e900000006b1/
thrust_source="data/motors/cesaroni/Cesaroni_7579M1520-P.eng",
burn_time=4.897,
propellant_initial_mass=3.737,
dry_mass=2.981,
# casing specs: Pro98 3G Gen2 casing
chamber_radius=0.064,
chamber_height=0.548,
chamber_position=0.274,
nozzle_radius=0.027,
)
79 changes: 79 additions & 0 deletions tests/fixtures/rockets/rocket_fixtures.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import numpy as np
import pytest

from rocketpy import Rocket
Expand Down Expand Up @@ -276,3 +277,81 @@ def dimensionless_calisto(kg, m, dimensionless_cesaroni_m1670):
)
example_rocket.add_motor(dimensionless_cesaroni_m1670, position=(-1.373) * m)
return example_rocket


@pytest.fixture
def prometheus_rocket(generic_motor_cesaroni_M1520):
"""Create a simple object of the Rocket class to be used in the tests. This
is the Prometheus rocket, a rocket documented in the Flight Examples section
of the RocketPy documentation.
Parameters
----------
generic_motor_cesaroni_M1520 : GenericMotor
An object of the GenericMotor class. This is a pytest fixture too.
"""

def prometheus_cd_at_ma(mach):
"""Gives the drag coefficient of the rocket at a given mach number."""
if mach <= 0.15:
return 0.422
elif mach <= 0.45:
return 0.422 + (mach - 0.15) * (0.38 - 0.422) / (0.45 - 0.15)
elif mach <= 0.77:
return 0.38 + (mach - 0.45) * (0.32 - 0.38) / (0.77 - 0.45)
elif mach <= 0.82:
return 0.32 + (mach - 0.77) * (0.3 - 0.32) / (0.82 - 0.77)
elif mach <= 0.88:
return 0.3 + (mach - 0.82) * (0.3 - 0.3) / (0.88 - 0.82)
elif mach <= 0.94:
return 0.3 + (mach - 0.88) * (0.32 - 0.3) / (0.94 - 0.88)
elif mach <= 0.99:
return 0.32 + (mach - 0.94) * (0.37 - 0.32) / (0.99 - 0.94)
elif mach <= 1.04:
return 0.37 + (mach - 0.99) * (0.44 - 0.37) / (1.04 - 0.99)
elif mach <= 1.24:
return 0.44 + (mach - 1.04) * (0.43 - 0.44) / (1.24 - 1.04)
elif mach <= 1.33:
return 0.43 + (mach - 1.24) * (0.42 - 0.43) / (1.33 - 1.24)
elif mach <= 1.49:
return 0.42 + (mach - 1.33) * (0.39 - 0.42) / (1.49 - 1.33)
else:
return 0.39

prometheus = Rocket(
radius=0.06985, # 5.5" diameter circle
mass=13.93,
inertia=(
4.87,
4.87,
0.05,
),
power_off_drag=prometheus_cd_at_ma,
power_on_drag=lambda x: prometheus_cd_at_ma(x) * 1.02, # 5% increase in drag
center_of_mass_without_motor=0.9549,
coordinate_system_orientation="tail_to_nose",
)

prometheus.set_rail_buttons(0.69, 0.21, 60)

prometheus.add_motor(motor=generic_motor_cesaroni_M1520, position=0)
nose_cone = prometheus.add_nose(length=0.742, kind="Von Karman", position=2.229)
fin_set = prometheus.add_trapezoidal_fins(
n=3,
span=0.13,
root_chord=0.268,
tip_chord=0.136,
position=0.273,
sweep_length=0.066,
)
drogue_chute = prometheus.add_parachute(
"Drogue",
cd_s=1.6 * np.pi * 0.3048**2, # Cd = 1.6, D_chute = 24 in
trigger="apogee",
)
main_chute = prometheus.add_parachute(
"Main",
cd_s=2.2 * np.pi * 0.9144**2, # Cd = 2.2, D_chute = 72 in
trigger=457.2, # 1500 ft
)
return prometheus

0 comments on commit 3327620

Please sign in to comment.