diff --git a/lib/__init__.py b/lib/__init__.py index 0dbaa09..87832bf 100644 --- a/lib/__init__.py +++ b/lib/__init__.py @@ -22,7 +22,7 @@ def parse_error(error): exc_type = type(error).__name__ exc_obj = f"{error}".replace("\n", " ").replace(" ", " ") - return f"{exc_type} exception: {exc_obj}" + return f"{exc_type}: {exc_obj}" from lib.api import app diff --git a/lib/controllers/flight.py b/lib/controllers/flight.py index af2b307..901cddc 100644 --- a/lib/controllers/flight.py +++ b/lib/controllers/flight.py @@ -2,37 +2,22 @@ from fastapi import HTTPException, status from pymongo.errors import PyMongoError -from rocketpy.simulation.flight import Flight as RocketPyFlight import jsonpickle from lib import logger, parse_error -from lib.models.rocket import Rocket, RocketOptions -from lib.models.motor import MotorKinds -from lib.models.flight import Flight from lib.models.environment import Env +from lib.models.rocket import Rocket +from lib.models.flight import Flight from lib.views.flight import ( FlightSummary, - SurfaceWindConditions, - OutOfRailConditions, - BurnoutConditions, - ApogeeConditions, - MaximumValues, - InitialConditions, - NumericalIntegrationSettings, - ImpactConditions, - EventsRegistered, - LaunchRailConditions, - FlightData, FlightCreated, FlightUpdated, FlightDeleted, FlightPickle, ) from lib.repositories.flight import FlightRepository -from lib.controllers.environment import EnvController -from lib.controllers.rocket import RocketController -from lib.services.environment import EnvironmentService +from lib.services.flight import FlightService class FlightController: @@ -56,49 +41,17 @@ class FlightController: def __init__( self, flight: Flight, - *, - rocket_option: RocketOptions, - motor_kind: MotorKinds, ): self._flight = flight - self._rocket_option = rocket_option - self._motor_kind = motor_kind @property def flight(self) -> Flight: return self._flight - @property - def rocket_option(self) -> RocketOptions: - return self._rocket_option - - @property - def motor_kind(self) -> MotorKinds: - return self._motor_kind - @flight.setter def flight(self, flight: Flight): self._flight = flight - @staticmethod - def get_rocketpy_flight(flight: Flight) -> RocketPyFlight: - """ - Get the rocketpy flight object. - - Returns: - RocketPyFlight - """ - rocketpy_rocket = RocketController.get_rocketpy_rocket(flight.rocket) - rocketpy_env = EnvironmentService.from_env_model(flight.environment) - rocketpy_flight = RocketPyFlight( - rocket=rocketpy_rocket, - inclination=flight.inclination, - heading=flight.heading, - environment=rocketpy_env, - rail_length=flight.rail_length, - ) - return rocketpy_flight - async def create_flight(self) -> Union[FlightCreated, HTTPException]: """ Create a flight in the database. @@ -109,10 +62,7 @@ async def create_flight(self) -> Union[FlightCreated, HTTPException]: try: async with FlightRepository() as flight_repo: flight_repo.fetch_flight(self.flight) - await flight_repo.create_flight( - motor_kind=self.motor_kind, - rocket_option=self.rocket_option, - ) + await flight_repo.create_flight() except PyMongoError as e: logger.error(f"controllers.flight.create_flight: PyMongoError {e}") raise HTTPException( @@ -201,7 +151,7 @@ async def get_rocketpy_flight_as_jsonpickle( """ try: read_flight = await cls.get_flight_by_id(flight_id) - rocketpy_flight = cls.get_rocketpy_flight(read_flight) + rocketpy_flight = FlightService.from_flight_model(read_flight) except HTTPException as e: raise e from e except Exception as e: @@ -240,10 +190,7 @@ async def update_flight_by_id( try: async with FlightRepository() as flight_repo: flight_repo.fetch_flight(self.flight) - await flight_repo.create_flight( - motor_kind=self.motor_kind, - rocket_option=self.rocket_option, - ) + await flight_repo.create_flight() await flight_repo.delete_flight_by_id(flight_id) except PyMongoError as e: logger.error(f"controllers.flight.update_flight: PyMongoError {e}") @@ -291,10 +238,7 @@ async def update_env_by_flight_id( new_flight = Flight(**new_flight) async with FlightRepository() as flight_repo: flight_repo.fetch_flight(new_flight) - await flight_repo.create_flight( - motor_kind=read_flight.rocket.motor.motor_kind, - rocket_option=read_flight.rocket.rocket_option, - ) + await flight_repo.create_flight() await flight_repo.delete_flight_by_id(flight_id) except PyMongoError as e: logger.error( @@ -322,7 +266,7 @@ async def update_env_by_flight_id( @classmethod async def update_rocket_by_flight_id( - cls, flight_id: str, *, rocket: Rocket, rocket_option, motor_kind + cls, flight_id: str, *, rocket: Rocket ) -> Union[FlightUpdated, HTTPException]: """ Update a models.Flight.rocket in the database. @@ -340,16 +284,16 @@ async def update_rocket_by_flight_id( try: read_flight = await cls.get_flight_by_id(flight_id) updated_rocket = rocket.dict() - updated_rocket["rocket_option"] = rocket_option - updated_rocket["motor"]["motor_kind"] = motor_kind + updated_rocket["rocket_option"] = rocket.rocket_option.value + updated_rocket["motor"][ + "motor_kind" + ] = rocket.motor.motor_kind.value new_flight = read_flight.dict() new_flight["rocket"] = updated_rocket new_flight = Flight(**new_flight) async with FlightRepository() as flight_repo: flight_repo.fetch_flight(new_flight) - await flight_repo.create_flight( - motor_kind=motor_kind, rocket_option=rocket_option - ) + await flight_repo.create_flight() await flight_repo.delete_flight_by_id(flight_id) except PyMongoError as e: logger.error( @@ -435,257 +379,8 @@ async def simulate_flight( """ try: read_flight = await cls.get_flight_by_id(flight_id=flight_id) - flight = cls.get_rocketpy_flight(read_flight) - - _initial_conditions = InitialConditions( - initial_altitude="Attitude - e0: {:.3f} | e1: {:.3f} | e2: {:.3f} | e3: {:.3f}".format( - flight.e0(0), flight.e1(0), flight.e2(0), flight.e3(0) - ), - initial_velocity="Velocity - Vx: {:.2f} m/s | Vy: {:.2f} m/s | Vz: {:.2f} m/s".format( - flight.vx(0), flight.vy(0), flight.vz(0) - ), - initial_position="Position - x: {:.2f} m | y: {:.2f} m | z: {:.2f} m".format( - flight.x(0), flight.y(0), flight.z(0) - ), - initial_angular_position="Euler Angles - Spin φ : {:.2f}° | Nutation θ: {:.2f}° | Precession ψ: {:.2f}°".format( - flight.phi(0), flight.theta(0), flight.psi(0) - ), - initial_angular_velocity="Angular Velocity - ω1: {:.2f} rad/s | ω2: {:.2f} rad/s| ω3: {:.2f} rad/s".format( - flight.w1(0), flight.w2(0), flight.w3(0) - ), - ) - - _numerical_integration_settings = NumericalIntegrationSettings( - max_time="Maximum Allowed Flight Time: {:f} s".format( - flight.max_time - ), - max_time_step="Maximum Allowed Time Step: {:f} s".format( - flight.max_time_step - ), - min_time_step="Minimum Allowed Time Step: {:e} s".format( - flight.min_time_step - ), - relative_error_tolerance=f"Relative Error Tolerance: {flight.rtol}", - absolute_error_tolerance=f"Absolute Error Tolerance: {flight.atol}", - time_overshoot=f"Allow Event Overshoot: {flight.time_overshoot}", - terminate_on_apogee=f"Terminate Simulation on Apogee: {flight.terminate_on_apogee}", - number_of_time_steps=f"Number of Time Steps Used: {len(flight.time_steps)}", - function_evaluations_per_time_step=f"Number of Derivative Functions Evaluation: {sum(flight.function_evaluations_per_time_step)}", - avg_function_evaluations_per_time_step="Average Function Evaluations per Time Step: {:3f}".format( - sum(flight.function_evaluations_per_time_step) - / len(flight.time_steps) - ), - ) - - _launch_rail_conditions = LaunchRailConditions( - rail_length="Launch Rail Length: {:.2f} m".format( - flight.rail_length - ), - flight_inclination="Launch Rail Inclination: {:.2f}°".format( - flight.inclination - ), - flight_heading="Launch Rail Heading: {:.2f}°".format( - flight.heading - ), - ) - - _surface_wind_conditions = SurfaceWindConditions( - frontal_surface_wind_speed="Frontal Surface Wind Speed: {:.2f} m/s".format( - flight.frontal_surface_wind - ), - lateral_surface_wind_speed="Lateral Surface Wind Speed: {:.2f} m/s".format( - flight.lateral_surface_wind - ), - ) - - _out_of_rail_conditions = OutOfRailConditions( - out_of_rail_time="Rail Departure Time: {:.3f} s".format( - flight.out_of_rail_time - ), - out_of_rail_velocity="Rail Departure Velocity: {:.3f} m/s".format( - flight.out_of_rail_velocity - ), - out_of_rail_static_margin="Rail Departure Static Margin: {:.3f} c".format( - flight.rocket.static_margin(flight.out_of_rail_time) - ), - out_of_rail_angle_of_attack="Rail Departure Angle of Attack: {:.3f}°".format( - flight.angle_of_attack(flight.out_of_rail_time) - ), - out_of_rail_thrust_weight_ratio="Rail Departure Thrust-Weight Ratio: {:.3f}".format( - flight.rocket.thrust_to_weight(flight.out_of_rail_time) - ), - out_of_rail_reynolds_number="Rail Departure Reynolds Number: {:.3e}".format( - flight.reynolds_number(flight.out_of_rail_time) - ), - ) - - _burnout_conditions = BurnoutConditions( - burnout_time="Burn out time: {:.3f} s".format( - flight.rocket.motor.burn_out_time - ), - burnout_altitude="Altitude at burn out: {:.3f} m (AGL)".format( - flight.z(flight.rocket.motor.burn_out_time) - - flight.env.elevation - ), - burnout_rocket_velocity="Rocket velocity at burn out: {:.3f} m/s".format( - flight.speed(flight.rocket.motor.burn_out_time) - ), - burnout_freestream_velocity="Freestream velocity at burn out: {:.3f} m/s".format( - ( - flight.stream_velocity_x( - flight.rocket.motor.burn_out_time - ) - ** 2 - + flight.stream_velocity_y( - flight.rocket.motor.burn_out_time - ) - ** 2 - + flight.stream_velocity_z( - flight.rocket.motor.burn_out_time - ) - ** 2 - ) - ** 0.5 - ), - burnout_mach_number="Mach Number at burn out: {:.3f}".format( - flight.mach_number(flight.rocket.motor.burn_out_time) - ), - burnout_kinetic_energy="Kinetic energy at burn out: {:.3e}".format( - flight.kinetic_energy(flight.rocket.motor.burn_out_time) - ), - ) - - _apogee_conditions = ApogeeConditions( - apogee_altitude="Apogee Altitude: {:.3f} m (ASL) | {:.3f} m (AGL)".format( - flight.apogee, flight.apogee - flight.env.elevation - ), - apogee_time="Apogee Time: {:.3f} s".format(flight.apogee_time), - apogee_freestream_speed="Apogee Freestream Speed: {:.3f} m/s".format( - flight.apogee_freestream_speed - ), - ) - - _maximum_values = MaximumValues( - maximum_speed="Maximum Speed: {:.3f} m/s at {:.2f} s".format( - flight.max_speed, flight.max_speed_time - ), - maximum_mach_number="Maximum Mach Number: {:.3f} Mach at {:.2f} s".format( - flight.max_mach_number, flight.max_mach_number_time - ), - maximum_reynolds_number="Maximum Reynolds Number: {:.3e} at {:.2f} s".format( - flight.max_reynolds_number, flight.max_reynolds_number_time - ), - maximum_dynamic_pressure="Maximum Dynamic Pressure: {:.3e} Pa at {:.2f} s".format( - flight.max_dynamic_pressure, - flight.max_dynamic_pressure_time, - ), - maximum_acceleration_during_motor_burn="Maximum Acceleration During Motor Burn: {:.3f} m/s² at {:.2f} s".format( - flight.max_acceleration, flight.max_acceleration_time - ), - maximum_gs_during_motor_burn="Maximum Gs During Motor Burn: {:.3f} g at {:.2f} s".format( - flight.max_acceleration - / flight.env.gravity( - flight.z(flight.max_acceleration_time) - ), - flight.max_acceleration_time, - ), - maximum_acceleration_after_motor_burn="Maximum Acceleration After Motor Burn: {:.3f} m/s² at {:.2f} s".format( - flight.max_acceleration_power_off, - flight.max_acceleration_power_off_time, - ), - maximum_gs_after_motor_burn="Maximum Gs After Motor Burn: {:.3f} g at {:.2f} s".format( - flight.max_acceleration_power_off / flight.env.standard_g, - flight.max_acceleration_power_off_time, - ), - maximum_upper_rail_button_normal_force="Maximum Upper Rail Button Normal Force: {:.3f} N".format( - flight.max_rail_button1_normal_force - ), - maximum_upper_rail_button_shear_force="Maximum Upper Rail Button Shear Force: {:.3f} N".format( - flight.max_rail_button1_shear_force - ), - maximum_lower_rail_button_normal_force="Maximum Lower Rail Button Normal Force: {:.3f} N".format( - flight.max_rail_button2_normal_force - ), - maximum_lower_rail_button_shear_force="Maximum Lower Rail Button Shear Force: {:.3f} N".format( - flight.max_rail_button2_shear_force - ), - ) - - if len(flight.impact_state) != 0: - _impact_conditions = ImpactConditions( - x_impact_position="X Impact: {:.3f} m".format( - flight.x_impact - ), - y_impact_position="Y Impact: {:.3f} m".format( - flight.y_impact - ), - time_of_impact="Time of Impact: {:.3f} s".format( - flight.t_final - ), - impact_velocity="Velocity at Impact: {:.3f} m/s".format( - flight.impact_velocity - ), - ) - elif flight.terminate_on_apogee is False: - _impact_conditions = ImpactConditions( - time="Time: {:.3f} s".format(flight.solution[-1][0]), - altitude="Altitude: {:.3f} m".format( - flight.solution[-1][3] - ), - ) - - if len(flight.parachute_events) == 0: - _events_registered = EventsRegistered( - events_trace="No parachute event registered" - ) - else: - events = {} - for event in flight.parachute_events: - trigger_time = event[0] - parachute = event[1] - open_time = trigger_time + parachute.lag - velocity = flight.free_stream_speed(open_time) - altitude = flight.z(open_time) - name = parachute.name.title() - events[name] = [] - events[name].append( - name - + " Ejection Triggered at: {:.3f} s".format( - trigger_time - ) - ) - events[name].append( - name - + " Parachute Inflated at: {:.3f} s".format(open_time) - ) - events[name].append( - name - + " Parachute Inflated with Freestream Speed of: {:.3f} m/s".format( - velocity - ) - ) - events[name].append( - name - + " Parachute Inflated at Height of: {:.3f} m (AGL)".format( - altitude - flight.env.elevation - ) - ) - _events_registered = EventsRegistered(events_trace=events) - - _flight_data = FlightData( - initial_conditions=_initial_conditions, - numerical_integration_settings=_numerical_integration_settings, - surface_wind_conditions=_surface_wind_conditions, - launch_rail_conditions=_launch_rail_conditions, - out_of_rail_conditions=_out_of_rail_conditions, - burnout_conditions=_burnout_conditions, - apogee_conditions=_apogee_conditions, - maximum_values=_maximum_values, - impact_conditions=_impact_conditions, - events_registered=_events_registered, - ) - - flight_summary = FlightSummary(flight_data=_flight_data) + rocketpy_flight = FlightService.from_flight_model(read_flight) + flight_summary = rocketpy_flight.get_flight_summary() except HTTPException as e: raise e from e except Exception as e: diff --git a/lib/controllers/motor.py b/lib/controllers/motor.py index 2ba8588..3d98eb1 100644 --- a/lib/controllers/motor.py +++ b/lib/controllers/motor.py @@ -1,17 +1,14 @@ from typing import Union from fastapi import HTTPException, status from pymongo.errors import PyMongoError -from rocketpy.motors.solid_motor import SolidMotor -from rocketpy.motors.liquid_motor import LiquidMotor -from rocketpy.motors.hybrid_motor import HybridMotor import jsonpickle from lib import logger, parse_error from lib.models.motor import Motor, MotorKinds +from lib.services.motor import MotorService from lib.repositories.motor import MotorRepository from lib.views.motor import ( MotorSummary, - MotorData, MotorCreated, MotorUpdated, MotorDeleted, @@ -30,10 +27,9 @@ class MotorController: - Create a rocketpy.Motor object from a Motor model object. """ - def __init__(self, *, motor: Motor, motor_kind: MotorKinds): - self.guard(motor, motor_kind) + def __init__(self, motor: Motor): + self.guard(motor) self._motor = motor - self._motor_kind = motor_kind @property def motor(self) -> Motor: @@ -43,67 +39,8 @@ def motor(self) -> Motor: def motor(self, motor: Motor): self._motor = motor - @property - def motor_kind(self) -> MotorKinds: - return self._motor_kind - - @staticmethod - def get_rocketpy_motor( - motor: Motor, - ) -> Union[LiquidMotor, HybridMotor, SolidMotor]: - """ - Get the rocketpy motor object. - - Returns: - Union[LiquidMotor, HybridMotor, SolidMotor] - """ - - motor_core = { - "thrust_source": f"lib/data/engines/{motor.thrust_source.value}.eng", - "burn_time": motor.burn_time, - "nozzle_radius": motor.nozzle_radius, - "dry_mass": motor.dry_mass, - "dry_inertia": motor.dry_inertia, - "center_of_dry_mass_position": motor.center_of_dry_mass_position, - } - - match motor.motor_kind: - case MotorKinds.LIQUID: - rocketpy_motor = LiquidMotor(**motor_core) - case MotorKinds.HYBRID: - rocketpy_motor = HybridMotor( - **motor_core, - throat_radius=motor.throat_radius, - grain_number=motor.grain_number, - grain_density=motor.grain_density, - grain_outer_radius=motor.grain_outer_radius, - grain_initial_inner_radius=motor.grain_initial_inner_radius, - grain_initial_height=motor.grain_initial_height, - grain_separation=motor.grain_separation, - grains_center_of_mass_position=motor.grains_center_of_mass_position, - ) - case _: - rocketpy_motor = SolidMotor( - **motor_core, - grain_number=motor.grain_number, - grain_density=motor.grain_density, - grain_outer_radius=motor.grain_outer_radius, - grain_initial_inner_radius=motor.grain_initial_inner_radius, - grain_initial_height=motor.grain_initial_height, - grains_center_of_mass_position=motor.grains_center_of_mass_position, - grain_separation=motor.grain_separation, - throat_radius=motor.throat_radius, - interpolation_method=motor.interpolation_method, - ) - - if motor.motor_kind != MotorKinds.SOLID: - for tank in motor.tanks: - rocketpy_motor.add_tank(tank.tank, tank.position) - - return rocketpy_motor - - def guard(self, motor: Motor, motor_kind): - if motor_kind != MotorKinds.SOLID and motor.tanks is None: + def guard(self, motor: Motor): + if motor.motor_kind != MotorKinds.SOLID and motor.tanks is None: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Tanks must be provided for liquid and hybrid motors.", @@ -119,7 +56,7 @@ async def create_motor(self) -> Union[MotorCreated, HTTPException]: try: async with MotorRepository() as motor_repo: motor_repo.fetch_motor(self.motor) - await motor_repo.create_motor(motor_kind=self.motor_kind) + await motor_repo.create_motor() except PyMongoError as e: logger.error(f"controllers.motor.create_motor: PyMongoError {e}") raise HTTPException( @@ -208,7 +145,7 @@ async def get_rocketpy_motor_as_jsonpickle( """ try: read_motor = await cls.get_motor_by_id(motor_id) - rocketpy_motor = cls.get_rocketpy_motor(read_motor) + rocketpy_motor = MotorService.from_motor_model(read_motor) except HTTPException as e: raise e from e except Exception as e: @@ -247,7 +184,7 @@ async def update_motor_by_id( try: async with MotorRepository() as motor_repo: motor_repo.fetch_motor(self.motor) - await motor_repo.create_motor(motor_kind=self.motor_kind) + await motor_repo.create_motor() await motor_repo.delete_motor_by_id(motor_id) except PyMongoError as e: logger.error(f"controllers.motor.update_motor: PyMongoError {e}") @@ -330,38 +267,8 @@ async def simulate_motor( """ try: read_motor = await cls.get_motor_by_id(motor_id) - motor = cls.get_rocketpy_motor(read_motor) - - motor_simulation_numbers = MotorData( - total_burning_time="Total Burning Time: " - + str(motor.burn_out_time) - + " s", - total_propellant_mass="Total Propellant Mass: " - + "{:.3f}".format(motor.propellant_initial_mass) - + " kg", - average_propellant_exhaust_velocity="Average Propellant Exhaust Velocity: " - + "{:.3f}".format( - motor.exhaust_velocity.average(*motor.burn_time) - ) - + " m/s", - average_thrust="Average Thrust: " - + "{:.3f}".format(motor.average_thrust) - + " N", - maximum_thrust="Maximum Thrust: " - + str(motor.max_thrust) - + " N at " - + str(motor.max_thrust_time) - + " s after ignition.", - total_impulse="Total Impulse: " - + "{:.3f}".format(motor.total_impulse) - + " Ns\n", - ) - # motor_simulation_plots = MotorPlots( - # motor.thrust.plot(lower=lower_limit, upper=upper_limit) - # ) - motor_summary = MotorSummary( - motor_data=motor_simulation_numbers - ) # , plots=motor_simulation_plots ) + rocketpy_motor = MotorService.from_motor_model(read_motor) + motor_summary = rocketpy_motor.get_motor_summary() except HTTPException as e: raise e from e except Exception as e: diff --git a/lib/controllers/rocket.py b/lib/controllers/rocket.py index 90b54a3..968d1b1 100644 --- a/lib/controllers/rocket.py +++ b/lib/controllers/rocket.py @@ -1,6 +1,4 @@ from typing import Union -import os -import ast import jsonpickle from fastapi import HTTPException, status @@ -9,27 +7,11 @@ # TODO # from inspect import getsourcelines -from rocketpy.rocket.parachute import Parachute as RocketPyParachute -from rocketpy.rocket.rocket import Rocket as RocketPyRocket -from rocketpy.rocket.aero_surface import NoseCone as RocketPyNoseCone -from rocketpy.rocket.aero_surface import ( - TrapezoidalFins as RocketPyTrapezoidalFins, -) -from rocketpy.rocket.aero_surface import Tail as RocketPyTail - from lib import logger, parse_error -from lib.controllers.motor import MotorController -from lib.models.rocket import Rocket, RocketOptions -from lib.models.motor import MotorKinds -from lib.models.aerosurfaces import NoseCone, TrapezoidalFins, Tail -from lib.models.parachute import Parachute +from lib.services.rocket import RocketService +from lib.models.rocket import Rocket from lib.repositories.rocket import RocketRepository from lib.views.rocket import ( - InertiaDetails, - RocketGeometricalParameters, - RocketAerodynamicsQuantities, - ParachuteData, - RocketData, RocketSummary, RocketCreated, RocketUpdated, @@ -51,14 +33,9 @@ class RocketController: def __init__( self, - *, rocket: Rocket, - rocket_option: RocketOptions, - motor_kind: MotorKinds, ): self._rocket = rocket - self._rocket_option = rocket_option - self._motor_kind = motor_kind @property def rocket(self) -> Rocket: @@ -68,84 +45,6 @@ def rocket(self) -> Rocket: def rocket(self, rocket: Rocket): self._rocket = rocket - @property - def rocket_option(self) -> RocketOptions: - return self._rocket_option - - @property - def motor_kind(self) -> MotorKinds: - return self._motor_kind - - @classmethod - def get_rocketpy_rocket(cls, rocket: Rocket) -> RocketPyRocket: - """ - Get a rocketpy rocket object. - - Returns: - RocketPyRocket - """ - - rocketpy_rocket = RocketPyRocket( - radius=rocket.radius, - mass=rocket.mass, - inertia=rocket.inertia, - power_off_drag=os.path.join( - "lib/data", - f"{rocket.rocket_option.lower()}", - "powerOffDragCurve.csv", - ), - power_on_drag=os.path.join( - "lib/data", - f"{rocket.rocket_option.lower()}", - "powerOnDragCurve.csv", - ), - center_of_mass_without_motor=rocket.center_of_mass_without_motor, - coordinate_system_orientation=rocket.coordinate_system_orientation, - ) - - # RailButtons - rocketpy_rocket.set_rail_buttons( - upper_button_position=rocket.rail_buttons.upper_button_position, - lower_button_position=rocket.rail_buttons.lower_button_position, - angular_position=rocket.rail_buttons.angular_position, - ) - rocketpy_rocket.add_motor( - MotorController.get_rocketpy_motor(rocket.motor), - rocket.motor_position, - ) - - # NoseCone - nose = cls.get_rocketpy_nose(rocket.nose) - rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position) - rocketpy_rocket.evaluate_static_margin() - - # FinSet - # TODO: re-write this to match overall fins not only TrapezoidalFins - # Maybe a strategy with different factory methods? - finset = cls.get_rocketpy_finset(rocket.fins) - rocketpy_rocket.aerodynamic_surfaces.add(finset, finset.position) - rocketpy_rocket.evaluate_static_margin() - - # Tail - tail = cls.get_rocketpy_tail(rocket.tail) - rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position) - rocketpy_rocket.evaluate_static_margin() - - # Parachutes - for p in range(len(rocket.parachutes)): - parachute_trigger = rocket.parachutes[p].triggers[0] - if cls.check_parachute_trigger(parachute_trigger): - rocket.parachutes[p].triggers[0] = compile( - parachute_trigger, "", "eval" - ) - parachute = cls.get_rocketpy_parachute(rocket.parachutes, p) - rocketpy_rocket.parachutes.append(parachute) - else: - print("Parachute trigger not valid. Skipping parachute.") - continue - - return rocketpy_rocket - async def create_rocket(self) -> Union[RocketCreated, HTTPException]: """ Create a models.Rocket in the database. @@ -156,10 +55,7 @@ async def create_rocket(self) -> Union[RocketCreated, HTTPException]: try: async with RocketRepository() as rocket_repo: rocket_repo.fetch_rocket(self.rocket) - await rocket_repo.create_rocket( - rocket_option=self.rocket_option, - motor_kind=self.motor_kind, - ) + await rocket_repo.create_rocket() except PyMongoError as e: logger.error(f"controllers.rocket.create_rocket: PyMongoError {e}") raise HTTPException( @@ -249,7 +145,7 @@ async def get_rocketpy_rocket_as_jsonpickle( """ try: read_rocket = await cls.get_rocket_by_id(rocket_id) - rocketpy_rocket = cls.get_rocketpy_rocket(read_rocket) + rocketpy_rocket = RocketService.from_rocket_model(read_rocket) except HTTPException as e: raise e from e except Exception as e: @@ -288,10 +184,7 @@ async def update_rocket_by_id( try: async with RocketRepository() as rocket_repo: rocket_repo.fetch_rocket(self.rocket) - await rocket_repo.create_rocket( - rocket_option=self.rocket_option, - motor_kind=self.motor_kind, - ) + await rocket_repo.create_rocket() await rocket_repo.delete_rocket_by_id(rocket_id) except PyMongoError as e: logger.error(f"controllers.rocket.update_rocket: PyMongoError {e}") @@ -375,146 +268,8 @@ async def simulate_rocket( """ try: read_rocket = await cls.get_rocket_by_id(rocket_id) - rocket = cls.get_rocketpy_rocket(read_rocket) - - _inertia_details = InertiaDetails( - rocket_mass_without_propellant="Rocket Mass: {:.3f} kg (No Propellant)".format( - rocket.mass - ), - rocket_mass_with_propellant="Rocket Mass: {:.3f} kg (With Propellant)".format( - rocket.total_mass(0) - ), - rocket_inertia_with_motor_without_propellant=[ - "Rocket Inertia (with motor, but without propellant) 11: {:.3f} kg*m2".format( - rocket.dry_I_11 - ), - "Rocket Inertia (with motor, but without propellant) 22: {:.3f} kg*m2".format( - rocket.dry_I_22 - ), - "Rocket Inertia (with motor, but without propellant) 33: {:.3f} kg*m2".format( - rocket.dry_I_33 - ), - "Rocket Inertia (with motor, but without propellant) 12: {:.3f} kg*m2".format( - rocket.dry_I_12 - ), - "Rocket Inertia (with motor, but without propellant) 13: {:.3f} kg*m2".format( - rocket.dry_I_13 - ), - "Rocket Inertia (with motor, but without propellant) 23: {:.3f} kg*m2".format( - rocket.dry_I_23 - ), - ], - ) - - _rocket_geometrical_parameters = RocketGeometricalParameters( - rocket_maximum_radius="Rocket Maximum Radius: " - + str(rocket.radius) - + " m", - rocket_frontal_area="Rocket Frontal Area: " - + "{:.6f}".format(rocket.area) - + " m2", - rocket_codm_nozzle_exit_distance="Rocket Center of Dry Mass - Nozzle Exit Distance: " - + "{:.3f} m".format( - abs( - rocket.center_of_dry_mass_position - - rocket.motor_position - ) - ), - rocket_codm_center_of_propellant_mass="Rocket Center of Dry Mass - Center of Propellant Mass: " - + "{:.3f} m".format( - abs( - rocket.center_of_propellant_position(0) - - rocket.center_of_dry_mass_position - ) - ), - rocket_codm_loaded_center_of_mass="Rocket Center of Mass - Rocket Loaded Center of Mass: " - + "{:.3f} m".format( - abs( - rocket.center_of_mass(0) - - rocket.center_of_dry_mass_position - ) - ), - ) - - _aerodynamics_lift_coefficient_derivatives = {} - for surface, _position in rocket.aerodynamic_surfaces: - name = surface.name - _aerodynamics_lift_coefficient_derivatives[name] = [] - _aerodynamics_lift_coefficient_derivatives[name].append( - name - + " Lift Coefficient Derivative: {:.3f}".format( - surface.clalpha(0) - ) - + "/rad" - ) - - _aerodynamics_center_of_pressure = {} - for surface, _position in rocket.aerodynamic_surfaces: - name = surface.name - cpz = surface.cp[2] - _aerodynamics_center_of_pressure[name] = [] - _aerodynamics_center_of_pressure[name].append( - name - + " Center of Pressure to CM: {:.3f}".format(cpz) - + " m" - ) - - _rocket_aerodynamics_quantities = RocketAerodynamicsQuantities( - aerodynamics_lift_coefficient_derivatives=_aerodynamics_lift_coefficient_derivatives, - aerodynamics_center_of_pressure=_aerodynamics_center_of_pressure, - distance_cop_to_codm="Distance from Center of Pressure to Center of Dry Mass: " - + "{:.3f}".format( - rocket.center_of_mass(0) - rocket.cp_position(0) - ) - + " m", - initial_static_margin="Initial Static Margin: " - + "{:.3f}".format(rocket.static_margin(0)) - + " c", - final_static_margin="Final Static Margin: " - + "{:.3f}".format( - rocket.static_margin(rocket.motor.burn_out_time) - ) - + " c", - ) - - _parachute_details = {} - _parachute_ejection_signal_trigger = {} - _parachute_ejection_system_refresh_rate = {} - _parachute_lag = {} - for chute in rocket.parachutes: - _parachute_details[chute.name] = chute.__str__() - - if chute.trigger.__name__ == "": - # line = getsourcelines(chute.trigger)[0][0] - # _parachute_ejection_signal_trigger[chute.name] = "Ejection signal trigger: " + line.split("lambda ")[1].split(",")[0].split("\n")[0] - pass - - else: - _parachute_ejection_signal_trigger[chute.name] = ( - "Ejection signal trigger: " + chute.trigger.__name__ - ) - _parachute_ejection_system_refresh_rate[chute.name] = ( - "Ejection system refresh rate: {chute.sampling_rate:.3f} Hz" - ) - _parachute_lag[chute.name] = ( - "Time between ejection signal is triggered and the parachute is fully opened: {chute.lag:.1f} s\n" - ) - - _parachute_data = ParachuteData( - parachute_details=_parachute_details, - # parachute_ejection_signal_trigger = _parachute_ejection_signal_trigger, - parachute_ejection_system_refresh_rate=_parachute_ejection_system_refresh_rate, - parachute_lag=_parachute_lag, - ) - - _rocket_data = RocketData( - inertia_details=_inertia_details, - rocket_geometrical_parameters=_rocket_geometrical_parameters, - rocket_aerodynamics_quantities=_rocket_aerodynamics_quantities, - parachute_data=_parachute_data, - ) - - rocket_summary = RocketSummary(rocket_data=_rocket_data) + rocketpy_rocket = RocketService.from_rocket_model(read_rocket) + rocket_summary = rocketpy_rocket.get_rocket_summary() except HTTPException as e: raise e from e except Exception as e: @@ -530,141 +285,3 @@ async def simulate_rocket( logger.info( f"Call to controllers.rocket.simulate completed for Rocket {rocket_id}" ) - - @staticmethod - def get_rocketpy_nose(nose: NoseCone) -> RocketPyNoseCone: - """ - Get a rocketpy nose cone object. - - Returns: - RocketPyNoseCone - """ - - rocketpy_nose = RocketPyNoseCone( - length=nose.length, - kind=nose.kind, - base_radius=nose.base_radius, - rocket_radius=nose.rocket_radius, - ) - rocketpy_nose.position = nose.position - return rocketpy_nose - - @staticmethod - def get_rocketpy_finset( - trapezoidal_fins: TrapezoidalFins, - ) -> RocketPyTrapezoidalFins: - """ - Get a rocketpy finset object. - - Returns: - RocketPyTrapezoidalFins - """ - rocketpy_finset = RocketPyTrapezoidalFins( - n=trapezoidal_fins.n, - root_chord=trapezoidal_fins.root_chord, - tip_chord=trapezoidal_fins.tip_chord, - span=trapezoidal_fins.span, - cant_angle=trapezoidal_fins.cant_angle, - rocket_radius=trapezoidal_fins.radius, - airfoil=trapezoidal_fins.airfoil, - ) - rocketpy_finset.position = trapezoidal_fins.position - return rocketpy_finset - - @staticmethod - def get_rocketpy_tail(tail: Tail) -> RocketPyTail: - """ - Get a rocketpy tail object. - - Returns: - RocketPyTail - """ - rocketpy_tail = RocketPyTail( - top_radius=tail.top_radius, - bottom_radius=tail.bottom_radius, - length=tail.length, - rocket_radius=tail.radius, - ) - rocketpy_tail.position = tail.position - return rocketpy_tail - - @staticmethod - def get_rocketpy_parachute( - parachute: Parachute, p: int - ) -> RocketPyParachute: - """ - Get a rocketpy parachute object. - - Returns: - RocketPyParachute - """ - rocketpy_parachute = RocketPyParachute( - name=parachute[p].name[0], - cd_s=parachute[p].cd_s[0], - trigger=eval(parachute[p].triggers[0]), - sampling_rate=parachute[p].sampling_rate[0], - lag=parachute[p].lag[0], - noise=parachute[p].noise[0], - ) - return rocketpy_parachute - - @staticmethod - def check_parachute_trigger(expression: str) -> bool: - """ - Check if the trigger expression is valid. - - Args: - expression: str - - Returns: - bool: True if the expression is valid, False otherwise. - """ - - # Parsing the expression into an AST - try: - parsed_expression = ast.parse(expression, mode="eval") - except SyntaxError: - print("Invalid syntax.") - return False - - # Constant case (supported after beta v1) - if isinstance(parsed_expression.body, ast.Constant): - return True - # Name case (supported after beta v1) - if ( - isinstance(parsed_expression.body, ast.Name) - and parsed_expression.body.id == "apogee" - ): - global apogee - apogee = "apogee" - return True - - # Validating the expression structure - if not isinstance(parsed_expression.body, ast.Lambda): - print("Invalid expression structure (not a Lambda).") - return False - - lambda_node = parsed_expression.body - if len(lambda_node.args.args) != 3: - print("Invalid expression structure (invalid arity).") - return False - - if not isinstance(lambda_node.body, ast.Compare): - try: - for operand in lambda_node.body.values: - if not isinstance(operand, ast.Compare): - print("Invalid expression structure (not a Compare).") - return False - except AttributeError: - print("Invalid expression structure (not a Compare).") - return False - - # Restricting access to functions or attributes - for node in ast.walk(lambda_node): - if isinstance(node, ast.Call): - print("Calling functions is not allowed in the expression.") - return False - if isinstance(node, ast.Attribute): - print("Accessing attributes is not allowed in the expression.") - return False - return True diff --git a/lib/models/motor.py b/lib/models/motor.py index 1598b49..98d60fa 100644 --- a/lib/models/motor.py +++ b/lib/models/motor.py @@ -128,14 +128,14 @@ class Motor(BaseModel, frozen=True): "nozzle_to_combustion_chamber" ) - def __init__(self, motor_kind=MotorKinds.SOLID, **kwargs): - super().__init__(**kwargs) - self._motor_kind = motor_kind - @property def motor_kind(self) -> MotorKinds: return self._motor_kind + @motor_kind.setter + def motor_kind(self, motor_kind: MotorKinds): + self._motor_kind = motor_kind + @property def motor_id(self) -> str: return str(hash(self)) diff --git a/lib/models/rocket.py b/lib/models/rocket.py index b78e1b6..522e28e 100644 --- a/lib/models/rocket.py +++ b/lib/models/rocket.py @@ -40,10 +40,6 @@ class Rocket(BaseModel, frozen=True): # TODO: implement field validation so a list of possible tailToNose values is provided in the api docs coordinate_system_orientation: Optional[str] = "tail_to_nose" - def __init__(self, rocket_option=RocketOptions.CALISTO, **kwargs): - super().__init__(**kwargs) - self._rocket_option = rocket_option - @property def rocket_option(self) -> RocketOptions: return self._rocket_option diff --git a/lib/repositories/flight.py b/lib/repositories/flight.py index ac68549..8b3d3ab 100644 --- a/lib/repositories/flight.py +++ b/lib/repositories/flight.py @@ -54,24 +54,22 @@ async def delete_flight(self, flight_id: str): await collection.delete_one({"flight_id": flight_id}) return self - async def create_flight( - self, *, motor_kind: str = "SOLID", rocket_option: str = "CALISTO" - ): + async def create_flight(self): """ Creates a non-existing models.Flight in the database - Args: - rocket_option: models.rocket.RocketOptions - motor_kind: models.motor.MotorKinds - Returns: self """ try: flight_to_dict = self.flight.dict() flight_to_dict["flight_id"] = self.flight_id - flight_to_dict["rocket"]["rocket_option"] = rocket_option - flight_to_dict["rocket"]["motor"]["motor_kind"] = motor_kind + flight_to_dict["rocket"][ + "rocket_option" + ] = self.flight.rocket.rocket_option.value + flight_to_dict["rocket"]["motor"][ + "motor_kind" + ] = self.flight.rocket.motor.motor_kind.value await self.insert_flight(flight_to_dict) except PyMongoError as e: raise e from e diff --git a/lib/repositories/motor.py b/lib/repositories/motor.py index 806016a..2395953 100644 --- a/lib/repositories/motor.py +++ b/lib/repositories/motor.py @@ -55,20 +55,17 @@ async def delete_motor(self, motor_id: str): await collection.delete_one({"motor_id": motor_id}) return self - async def create_motor(self, motor_kind: str = "SOLID"): + async def create_motor(self): """ Creates a non-existing models.Motor in the database - Args: - motor_kind: models.motor.MotorKinds - Returns: self """ try: motor_to_dict = self.motor.dict() motor_to_dict["motor_id"] = self.motor_id - motor_to_dict["motor_kind"] = motor_kind + motor_to_dict["motor_kind"] = motor.motor_kind.value await self.insert_motor(motor_to_dict) except PyMongoError as e: raise e from e diff --git a/lib/repositories/repo.py b/lib/repositories/repo.py index 4a56810..9a9f7ae 100644 --- a/lib/repositories/repo.py +++ b/lib/repositories/repo.py @@ -1,12 +1,18 @@ import asyncio import threading -from lib import logger -from lib.secrets import Secrets + +from tenacity import ( + stop_after_attempt, + wait_fixed, + retry, +) from pydantic import BaseModel -from fastapi import HTTPException, status -from motor.motor_asyncio import AsyncIOMotorClient from pymongo.server_api import ServerApi -from tenacity import retry, stop_after_attempt, wait_fixed +from motor.motor_asyncio import AsyncIOMotorClient +from fastapi import HTTPException, status + +from lib import logger +from lib.secrets import Secrets class RepositoryNotInitializedException(HTTPException): diff --git a/lib/repositories/rocket.py b/lib/repositories/rocket.py index 2c74cee..e6a20d8 100644 --- a/lib/repositories/rocket.py +++ b/lib/repositories/rocket.py @@ -55,24 +55,20 @@ async def delete_rocket(self, rocket_id: str): await collection.delete_one({"rocket_id": rocket_id}) return self - async def create_rocket( - self, *, rocket_option: str = "CALISTO", motor_kind: str = "SOLID" - ): + async def create_rocket(self): """ Creates a non-existing models.Rocket in the database - Args: - rocket_option: models.rocket.RocketOptions - motor_kind: models.motor.MotorKinds - Returns: self """ try: rocket_to_dict = self.rocket.dict() rocket_to_dict["rocket_id"] = self.rocket_id - rocket_to_dict["rocket_option"] = rocket_option - rocket_to_dict["motor"]["motor_kind"] = motor_kind + rocket_to_dict["rocket_option"] = self.rocket.rocket_option.value + rocket_to_dict["motor"][ + "motor_kind" + ] = self.rocket.motor.motor_kind.value await self.insert_rocket(rocket_to_dict) except PyMongoError as e: raise e from e diff --git a/lib/routes/flight.py b/lib/routes/flight.py index 2d597c6..4ea4a9b 100644 --- a/lib/routes/flight.py +++ b/lib/routes/flight.py @@ -42,9 +42,9 @@ async def create_flight( ``` Flight object as JSON ``` """ with tracer.start_as_current_span("create_flight"): - return await FlightController( - flight, rocket_option=rocket_option, motor_kind=motor_kind - ).create_flight() + flight.rocket.rocket_option = rocket_option + flight.rocket.motor.motor_kind = motor_kind + return await FlightController(flight).create_flight() @router.get("/{flight_id}") @@ -107,11 +107,11 @@ async def update_flight_rocket( ``` """ with tracer.start_as_current_span("update_flight_rocket"): + rocket.rocket_option = rocket_option + rocket.motor.motor_kind = motor_kind return await FlightController.update_rocket_by_flight_id( flight_id, rocket=rocket, - rocket_option=rocket_option, - motor_kind=motor_kind, ) @@ -132,9 +132,9 @@ async def update_flight( ``` """ with tracer.start_as_current_span("update_flight"): - return await FlightController( - flight, rocket_option=rocket_option, motor_kind=motor_kind - ).update_flight_by_id(flight_id) + flight.rocket.rocket_option = rocket_option + flight.rocket.motor.motor_kind = motor_kind + return await FlightController(flight).update_flight_by_id(flight_id) @router.delete("/{flight_id}") diff --git a/lib/routes/motor.py b/lib/routes/motor.py index 5c4cbff..375e4fb 100644 --- a/lib/routes/motor.py +++ b/lib/routes/motor.py @@ -37,9 +37,8 @@ async def create_motor(motor: Motor, motor_kind: MotorKinds) -> MotorCreated: ``` Motor object as a JSON ``` """ with tracer.start_as_current_span("create_motor"): - return await MotorController( - motor=motor, motor_kind=motor_kind - ).create_motor() + motor.motor_kind = motor_kind + return await MotorController(motor).create_motor() @router.get("/{motor_id}") @@ -68,9 +67,8 @@ async def update_motor( ``` """ with tracer.start_as_current_span("update_motor"): - return await MotorController( - motor=motor, motor_kind=motor_kind - ).update_motor_by_id(motor_id) + motor.motor_kind = motor_kind + return await MotorController(motor).update_motor_by_id(motor_id) @router.delete("/{motor_id}") diff --git a/lib/routes/rocket.py b/lib/routes/rocket.py index 1d7301e..e2faa91 100644 --- a/lib/routes/rocket.py +++ b/lib/routes/rocket.py @@ -40,9 +40,9 @@ async def create_rocket( ``` Rocket object as a JSON ``` """ with tracer.start_as_current_span("create_rocket"): - return await RocketController( - rocket=rocket, rocket_option=rocket_option, motor_kind=motor_kind - ).create_rocket() + rocket.rocket_option = rocket_option + rocket.motor.motor_kind = motor_kind + return await RocketController(rocket).create_rocket() @router.get("/{rocket_id}") @@ -74,9 +74,9 @@ async def update_rocket( ``` """ with tracer.start_as_current_span("update_rocket"): - return await RocketController( - rocket=rocket, rocket_option=rocket_option, motor_kind=motor_kind - ).update_rocket_by_id(rocket_id) + rocket.rocket_option = rocket_option + rocket.motor.motor_kind = motor_kind + return await RocketController(rocket).update_rocket_by_id(rocket_id) @router.delete("/{rocket_id}") diff --git a/lib/services/flight.py b/lib/services/flight.py new file mode 100644 index 0000000..d8fcaca --- /dev/null +++ b/lib/services/flight.py @@ -0,0 +1,291 @@ +from typing import Self + +from rocketpy.simulation.flight import Flight as RocketPyFlight +from rocketpy.utilities import get_instance_attributes + +from lib.models.flight import Flight +from lib.services.environment import EnvironmentService +from lib.services.rocket import RocketService +from lib.views.flight import ( + FlightSummary, + SurfaceWindConditions, + OutOfRailConditions, + BurnoutConditions, + ApogeeConditions, + MaximumValues, + InitialConditions, + NumericalIntegrationSettings, + ImpactConditions, + EventsRegistered, + LaunchRailConditions, + FlightData, +) + + +class FlightService(RocketPyFlight): + + @classmethod + def from_flight_model(cls, flight: Flight) -> Self: + """ + Get the rocketpy flight object. + + Returns: + RocketPyFlight + """ + rocketpy_rocket = RocketService.from_rocket_model(flight.rocket) + rocketpy_env = EnvironmentService.from_env_model(flight.environment) + rocketpy_flight = RocketPyFlight( + rocket=rocketpy_rocket, + inclination=flight.inclination, + heading=flight.heading, + environment=rocketpy_env, + rail_length=flight.rail_length, + ) + return rocketpy_flight + + def get_flight_summary(self) -> FlightSummary: + """ + Get the summary of the flight. + + Returns: + FlightSummary + """ + flight = self + + _initial_conditions = InitialConditions( + initial_altitude="Attitude - e0: {:.3f} | e1: {:.3f} | e2: {:.3f} | e3: {:.3f}".format( + flight.e0(0), flight.e1(0), flight.e2(0), flight.e3(0) + ), + initial_velocity="Velocity - Vx: {:.2f} m/s | Vy: {:.2f} m/s | Vz: {:.2f} m/s".format( + flight.vx(0), flight.vy(0), flight.vz(0) + ), + initial_position="Position - x: {:.2f} m | y: {:.2f} m | z: {:.2f} m".format( + flight.x(0), flight.y(0), flight.z(0) + ), + initial_angular_position="Euler Angles - Spin φ : {:.2f}° | Nutation θ: {:.2f}° | Precession ψ: {:.2f}°".format( + flight.phi(0), flight.theta(0), flight.psi(0) + ), + initial_angular_velocity="Angular Velocity - ω1: {:.2f} rad/s | ω2: {:.2f} rad/s| ω3: {:.2f} rad/s".format( + flight.w1(0), flight.w2(0), flight.w3(0) + ), + ) + + _numerical_integration_settings = NumericalIntegrationSettings( + max_time="Maximum Allowed Flight Time: {:f} s".format( + flight.max_time + ), + max_time_step="Maximum Allowed Time Step: {:f} s".format( + flight.max_time_step + ), + min_time_step="Minimum Allowed Time Step: {:e} s".format( + flight.min_time_step + ), + relative_error_tolerance=f"Relative Error Tolerance: {flight.rtol}", + absolute_error_tolerance=f"Absolute Error Tolerance: {flight.atol}", + time_overshoot=f"Allow Event Overshoot: {flight.time_overshoot}", + terminate_on_apogee=f"Terminate Simulation on Apogee: {flight.terminate_on_apogee}", + number_of_time_steps=f"Number of Time Steps Used: {len(flight.time_steps)}", + function_evaluations_per_time_step=f"Number of Derivative Functions Evaluation: {sum(flight.function_evaluations_per_time_step)}", + avg_function_evaluations_per_time_step="Average Function Evaluations per Time Step: {:3f}".format( + sum(flight.function_evaluations_per_time_step) + / len(flight.time_steps) + ), + ) + + _launch_rail_conditions = LaunchRailConditions( + rail_length="Launch Rail Length: {:.2f} m".format( + flight.rail_length + ), + flight_inclination="Launch Rail Inclination: {:.2f}°".format( + flight.inclination + ), + flight_heading="Launch Rail Heading: {:.2f}°".format( + flight.heading + ), + ) + + _surface_wind_conditions = SurfaceWindConditions( + frontal_surface_wind_speed="Frontal Surface Wind Speed: {:.2f} m/s".format( + flight.frontal_surface_wind + ), + lateral_surface_wind_speed="Lateral Surface Wind Speed: {:.2f} m/s".format( + flight.lateral_surface_wind + ), + ) + + _out_of_rail_conditions = OutOfRailConditions( + out_of_rail_time="Rail Departure Time: {:.3f} s".format( + flight.out_of_rail_time + ), + out_of_rail_velocity="Rail Departure Velocity: {:.3f} m/s".format( + flight.out_of_rail_velocity + ), + out_of_rail_static_margin="Rail Departure Static Margin: {:.3f} c".format( + flight.rocket.static_margin(flight.out_of_rail_time) + ), + out_of_rail_angle_of_attack="Rail Departure Angle of Attack: {:.3f}°".format( + flight.angle_of_attack(flight.out_of_rail_time) + ), + out_of_rail_thrust_weight_ratio="Rail Departure Thrust-Weight Ratio: {:.3f}".format( + flight.rocket.thrust_to_weight(flight.out_of_rail_time) + ), + out_of_rail_reynolds_number="Rail Departure Reynolds Number: {:.3e}".format( + flight.reynolds_number(flight.out_of_rail_time) + ), + ) + + _burnout_conditions = BurnoutConditions( + burnout_time="Burn out time: {:.3f} s".format( + flight.rocket.motor.burn_out_time + ), + burnout_altitude="Altitude at burn out: {:.3f} m (AGL)".format( + flight.z(flight.rocket.motor.burn_out_time) + - flight.env.elevation + ), + burnout_rocket_velocity="Rocket velocity at burn out: {:.3f} m/s".format( + flight.speed(flight.rocket.motor.burn_out_time) + ), + burnout_freestream_velocity="Freestream velocity at burn out: {:.3f} m/s".format( + ( + flight.stream_velocity_x(flight.rocket.motor.burn_out_time) + ** 2 + + flight.stream_velocity_y( + flight.rocket.motor.burn_out_time + ) + ** 2 + + flight.stream_velocity_z( + flight.rocket.motor.burn_out_time + ) + ** 2 + ) + ** 0.5 + ), + burnout_mach_number="Mach Number at burn out: {:.3f}".format( + flight.mach_number(flight.rocket.motor.burn_out_time) + ), + burnout_kinetic_energy="Kinetic energy at burn out: {:.3e}".format( + flight.kinetic_energy(flight.rocket.motor.burn_out_time) + ), + ) + + _apogee_conditions = ApogeeConditions( + apogee_altitude="Apogee Altitude: {:.3f} m (ASL) | {:.3f} m (AGL)".format( + flight.apogee, flight.apogee - flight.env.elevation + ), + apogee_time="Apogee Time: {:.3f} s".format(flight.apogee_time), + apogee_freestream_speed="Apogee Freestream Speed: {:.3f} m/s".format( + flight.apogee_freestream_speed + ), + ) + + _maximum_values = MaximumValues( + maximum_speed="Maximum Speed: {:.3f} m/s at {:.2f} s".format( + flight.max_speed, flight.max_speed_time + ), + maximum_mach_number="Maximum Mach Number: {:.3f} Mach at {:.2f} s".format( + flight.max_mach_number, flight.max_mach_number_time + ), + maximum_reynolds_number="Maximum Reynolds Number: {:.3e} at {:.2f} s".format( + flight.max_reynolds_number, flight.max_reynolds_number_time + ), + maximum_dynamic_pressure="Maximum Dynamic Pressure: {:.3e} Pa at {:.2f} s".format( + flight.max_dynamic_pressure, + flight.max_dynamic_pressure_time, + ), + maximum_acceleration_during_motor_burn="Maximum Acceleration During Motor Burn: {:.3f} m/s² at {:.2f} s".format( + flight.max_acceleration, flight.max_acceleration_time + ), + maximum_gs_during_motor_burn="Maximum Gs During Motor Burn: {:.3f} g at {:.2f} s".format( + flight.max_acceleration + / flight.env.gravity(flight.z(flight.max_acceleration_time)), + flight.max_acceleration_time, + ), + maximum_acceleration_after_motor_burn="Maximum Acceleration After Motor Burn: {:.3f} m/s² at {:.2f} s".format( + flight.max_acceleration_power_off, + flight.max_acceleration_power_off_time, + ), + maximum_gs_after_motor_burn="Maximum Gs After Motor Burn: {:.3f} g at {:.2f} s".format( + flight.max_acceleration_power_off / flight.env.standard_g, + flight.max_acceleration_power_off_time, + ), + maximum_upper_rail_button_normal_force="Maximum Upper Rail Button Normal Force: {:.3f} N".format( + flight.max_rail_button1_normal_force + ), + maximum_upper_rail_button_shear_force="Maximum Upper Rail Button Shear Force: {:.3f} N".format( + flight.max_rail_button1_shear_force + ), + maximum_lower_rail_button_normal_force="Maximum Lower Rail Button Normal Force: {:.3f} N".format( + flight.max_rail_button2_normal_force + ), + maximum_lower_rail_button_shear_force="Maximum Lower Rail Button Shear Force: {:.3f} N".format( + flight.max_rail_button2_shear_force + ), + ) + + if len(flight.impact_state) != 0: + _impact_conditions = ImpactConditions( + x_impact_position="X Impact: {:.3f} m".format(flight.x_impact), + y_impact_position="Y Impact: {:.3f} m".format(flight.y_impact), + time_of_impact="Time of Impact: {:.3f} s".format( + flight.t_final + ), + impact_velocity="Velocity at Impact: {:.3f} m/s".format( + flight.impact_velocity + ), + ) + elif flight.terminate_on_apogee is False: + _impact_conditions = ImpactConditions( + time="Time: {:.3f} s".format(flight.solution[-1][0]), + altitude="Altitude: {:.3f} m".format(flight.solution[-1][3]), + ) + + if len(flight.parachute_events) == 0: + _events_registered = EventsRegistered( + events_trace="No parachute event registered" + ) + else: + events = {} + for event in flight.parachute_events: + trigger_time = event[0] + parachute = event[1] + open_time = trigger_time + parachute.lag + velocity = flight.free_stream_speed(open_time) + altitude = flight.z(open_time) + name = parachute.name.title() + events[name] = [] + events[name].append( + name + + " Ejection Triggered at: {:.3f} s".format(trigger_time) + ) + events[name].append( + name + " Parachute Inflated at: {:.3f} s".format(open_time) + ) + events[name].append( + name + + " Parachute Inflated with Freestream Speed of: {:.3f} m/s".format( + velocity + ) + ) + events[name].append( + name + + " Parachute Inflated at Height of: {:.3f} m (AGL)".format( + altitude - flight.env.elevation + ) + ) + _events_registered = EventsRegistered(events_trace=events) + + _flight_data = FlightData( + initial_conditions=_initial_conditions, + numerical_integration_settings=_numerical_integration_settings, + surface_wind_conditions=_surface_wind_conditions, + launch_rail_conditions=_launch_rail_conditions, + out_of_rail_conditions=_out_of_rail_conditions, + burnout_conditions=_burnout_conditions, + apogee_conditions=_apogee_conditions, + maximum_values=_maximum_values, + impact_conditions=_impact_conditions, + events_registered=_events_registered, + ) + + flight_summary = FlightSummary(flight_data=_flight_data) + return flight_summary diff --git a/lib/services/motor.py b/lib/services/motor.py new file mode 100644 index 0000000..2b56e9f --- /dev/null +++ b/lib/services/motor.py @@ -0,0 +1,103 @@ +from typing import Self +from rocketpy.motors.motor import Motor as RocketPyMotor +from rocketpy.motors.solid_motor import SolidMotor +from rocketpy.motors.liquid_motor import LiquidMotor +from rocketpy.motors.hybrid_motor import HybridMotor +from rocketpy.utilities import get_instance_attributes +from lib.models.motor import Motor, MotorKinds +from lib.views.motor import MotorSummary, MotorData, MotorPlots + + +class MotorService(RocketPyMotor): + + @classmethod + def from_motor_model(cls, motor: Motor) -> Self: + """ + Get the rocketpy motor object. + + Returns: + RocketPyMotor + """ + + motor_core = { + "thrust_source": f"lib/data/engines/{motor.thrust_source.value}.eng", + "burn_time": motor.burn_time, + "nozzle_radius": motor.nozzle_radius, + "dry_mass": motor.dry_mass, + "dry_inertia": motor.dry_inertia, + "center_of_dry_mass_position": motor.center_of_dry_mass_position, + } + + match motor.motor_kind: + case MotorKinds.LIQUID: + rocketpy_motor = LiquidMotor(**motor_core) + case MotorKinds.HYBRID: + rocketpy_motor = HybridMotor( + **motor_core, + throat_radius=motor.throat_radius, + grain_number=motor.grain_number, + grain_density=motor.grain_density, + grain_outer_radius=motor.grain_outer_radius, + grain_initial_inner_radius=motor.grain_initial_inner_radius, + grain_initial_height=motor.grain_initial_height, + grain_separation=motor.grain_separation, + grains_center_of_mass_position=motor.grains_center_of_mass_position, + ) + case _: + rocketpy_motor = SolidMotor( + **motor_core, + grain_number=motor.grain_number, + grain_density=motor.grain_density, + grain_outer_radius=motor.grain_outer_radius, + grain_initial_inner_radius=motor.grain_initial_inner_radius, + grain_initial_height=motor.grain_initial_height, + grains_center_of_mass_position=motor.grains_center_of_mass_position, + grain_separation=motor.grain_separation, + throat_radius=motor.throat_radius, + interpolation_method=motor.interpolation_method, + ) + + if motor.motor_kind != MotorKinds.SOLID: + for tank in motor.tanks: + rocketpy_motor.add_tank(tank.tank, tank.position) + + return rocketpy_motor + + def get_motor_summary(self) -> MotorSummary: + """ + Get the summary of the motor. + + Returns: + MotorSummary + """ + + motor_simulation_numbers = MotorData( + total_burning_time="Total Burning Time: " + + str(self.burn_out_time) + + " s", + total_propellant_mass="Total Propellant Mass: " + + "{:.3f}".format(self.propellant_initial_mass) + + " kg", + average_propellant_exhaust_velocity="Average Propellant Exhaust Velocity: " + + "{:.3f}".format(self.exhaust_velocity.average(*self.burn_time)) + + " m/s", + average_thrust="Average Thrust: " + + "{:.3f}".format(self.average_thrust) + + " N", + maximum_thrust="Maximum Thrust: " + + str(self.max_thrust) + + " N at " + + str(self.max_thrust_time) + + " s after ignition.", + total_impulse="Total Impulse: " + + "{:.3f}".format(self.total_impulse) + + " Ns\n", + ) + # motor_simulation_plots = MotorPlots( + # self.thrust.plot(lower=lower_limit, upper=upper_limit) + # ) + motor_summary = MotorSummary( + motor_data=motor_simulation_numbers + ) # , plots=motor_simulation_plots ) + + return motor_summary diff --git a/lib/services/rocket.py b/lib/services/rocket.py new file mode 100644 index 0000000..4bc604c --- /dev/null +++ b/lib/services/rocket.py @@ -0,0 +1,371 @@ +import os +import ast +from typing import Self +from rocketpy.rocket.rocket import Rocket as RocketPyRocket +from rocketpy.rocket.parachute import Parachute as RocketPyParachute +from rocketpy.rocket.aero_surface import NoseCone as RocketPyNoseCone +from rocketpy.rocket.aero_surface import ( + TrapezoidalFins as RocketPyTrapezoidalFins, +) +from rocketpy.rocket.aero_surface import Tail as RocketPyTail +from rocketpy.utilities import get_instance_attributes + +from lib.models.rocket import Rocket +from lib.models.aerosurfaces import NoseCone, TrapezoidalFins, Tail +from lib.models.parachute import Parachute +from lib.services.motor import MotorService +from lib.views.rocket import ( + InertiaDetails, + RocketGeometricalParameters, + RocketAerodynamicsQuantities, + ParachuteData, + RocketData, + RocketSummary, +) + + +class RocketService(RocketPyRocket): + + @classmethod + def from_rocket_model(cls, rocket: Rocket) -> Self: + """ + Get the rocketpy rocket object. + + Returns: + RocketPyRocket + """ + + rocketpy_rocket = RocketPyRocket( + radius=rocket.radius, + mass=rocket.mass, + inertia=rocket.inertia, + power_off_drag=os.path.join( + "lib/data", + f"{rocket.rocket_option.lower()}", + "powerOffDragCurve.csv", + ), + power_on_drag=os.path.join( + "lib/data", + f"{rocket.rocket_option.lower()}", + "powerOnDragCurve.csv", + ), + center_of_mass_without_motor=rocket.center_of_mass_without_motor, + coordinate_system_orientation=rocket.coordinate_system_orientation, + ) + + # RailButtons + rocketpy_rocket.set_rail_buttons( + upper_button_position=rocket.rail_buttons.upper_button_position, + lower_button_position=rocket.rail_buttons.lower_button_position, + angular_position=rocket.rail_buttons.angular_position, + ) + rocketpy_rocket.add_motor( + MotorService.from_motor_model(rocket.motor), + rocket.motor_position, + ) + + # NoseCone + nose = cls.get_rocketpy_nose(rocket.nose) + rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position) + rocketpy_rocket.evaluate_static_margin() + + # FinSet + # TODO: re-write this to match overall fins not only TrapezoidalFins + # Maybe a strategy with different factory methods? + finset = cls.get_rocketpy_finset(rocket.fins) + rocketpy_rocket.aerodynamic_surfaces.add(finset, finset.position) + rocketpy_rocket.evaluate_static_margin() + + # Tail + tail = cls.get_rocketpy_tail(rocket.tail) + rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position) + rocketpy_rocket.evaluate_static_margin() + + # Parachutes + for p, _ in enumerate(rocket.parachutes): + parachute_trigger = rocket.parachutes[p].triggers[0] + if cls.check_parachute_trigger(parachute_trigger): + rocket.parachutes[p].triggers[0] = compile( + parachute_trigger, "", "eval" + ) + parachute = cls.get_rocketpy_parachute(rocket.parachutes, p) + rocketpy_rocket.parachutes.append(parachute) + else: + print("Parachute trigger not valid. Skipping parachute.") + continue + + return rocketpy_rocket + + def get_rocket_summary(self) -> RocketSummary: + """ + Get the summary of the rocket. + + Returns: + RocketSummary + """ + + _inertia_details = InertiaDetails( + rocket_mass_without_propellant="Rocket Mass: {:.3f} kg (No Propellant)".format( + self.mass + ), + rocket_mass_with_propellant="Rocket Mass: {:.3f} kg (With Propellant)".format( + self.total_mass(0) + ), + rocket_inertia_with_motor_without_propellant=[ + "Rocket Inertia (with motor, but without propellant) 11: {:.3f} kg*m2".format( + self.dry_I_11 + ), + "Rocket Inertia (with motor, but without propellant) 22: {:.3f} kg*m2".format( + self.dry_I_22 + ), + "Rocket Inertia (with motor, but without propellant) 33: {:.3f} kg*m2".format( + self.dry_I_33 + ), + "Rocket Inertia (with motor, but without propellant) 12: {:.3f} kg*m2".format( + self.dry_I_12 + ), + "Rocket Inertia (with motor, but without propellant) 13: {:.3f} kg*m2".format( + self.dry_I_13 + ), + "Rocket Inertia (with motor, but without propellant) 23: {:.3f} kg*m2".format( + self.dry_I_23 + ), + ], + ) + + _rocket_geometrical_parameters = RocketGeometricalParameters( + rocket_maximum_radius="Rocket Maximum Radius: " + + str(self.radius) + + " m", + rocket_frontal_area="Rocket Frontal Area: " + + "{:.6f}".format(self.area) + + " m2", + rocket_codm_nozzle_exit_distance="Rocket Center of Dry Mass - Nozzle Exit Distance: " + + "{:.3f} m".format( + abs(self.center_of_dry_mass_position - self.motor_position) + ), + rocket_codm_center_of_propellant_mass="Rocket Center of Dry Mass - Center of Propellant Mass: " + + "{:.3f} m".format( + abs( + self.center_of_propellant_position(0) + - self.center_of_dry_mass_position + ) + ), + rocket_codm_loaded_center_of_mass="Rocket Center of Mass - Rocket Loaded Center of Mass: " + + "{:.3f} m".format( + abs(self.center_of_mass(0) - self.center_of_dry_mass_position) + ), + ) + + _aerodynamics_lift_coefficient_derivatives = {} + for surface, _position in self.aerodynamic_surfaces: + name = surface.name + _aerodynamics_lift_coefficient_derivatives[name] = [] + _aerodynamics_lift_coefficient_derivatives[name].append( + name + + " Lift Coefficient Derivative: {:.3f}".format( + surface.clalpha(0) + ) + + "/rad" + ) + + _aerodynamics_center_of_pressure = {} + for surface, _position in self.aerodynamic_surfaces: + name = surface.name + cpz = surface.cp[2] + _aerodynamics_center_of_pressure[name] = [] + _aerodynamics_center_of_pressure[name].append( + name + " Center of Pressure to CM: {:.3f}".format(cpz) + " m" + ) + + _rocket_aerodynamics_quantities = RocketAerodynamicsQuantities( + aerodynamics_lift_coefficient_derivatives=_aerodynamics_lift_coefficient_derivatives, + aerodynamics_center_of_pressure=_aerodynamics_center_of_pressure, + distance_cop_to_codm="Distance from Center of Pressure to Center of Dry Mass: " + + "{:.3f}".format(self.center_of_mass(0) - self.cp_position(0)) + + " m", + initial_static_margin="Initial Static Margin: " + + "{:.3f}".format(self.static_margin(0)) + + " c", + final_static_margin="Final Static Margin: " + + "{:.3f}".format(self.static_margin(self.motor.burn_out_time)) + + " c", + ) + + _parachute_details = {} + _parachute_ejection_signal_trigger = {} + _parachute_ejection_system_refresh_rate = {} + _parachute_lag = {} + for chute in self.parachutes: + _parachute_details[chute.name] = chute.__str__() + + if chute.trigger.__name__ == "": + # line = getsourcelines(chute.trigger)[0][0] + # _parachute_ejection_signal_trigger[chute.name] = "Ejection signal trigger: " + line.split("lambda ")[1].split(",")[0].split("\n")[0] + pass + + else: + _parachute_ejection_signal_trigger[chute.name] = ( + "Ejection signal trigger: " + chute.trigger.__name__ + ) + _parachute_ejection_system_refresh_rate[chute.name] = ( + "Ejection system refresh rate: {chute.sampling_rate:.3f} Hz" + ) + _parachute_lag[chute.name] = ( + "Time between ejection signal is triggered and the parachute is fully opened: {chute.lag:.1f} s\n" + ) + + _parachute_data = ParachuteData( + parachute_details=_parachute_details, + # parachute_ejection_signal_trigger = _parachute_ejection_signal_trigger, + parachute_ejection_system_refresh_rate=_parachute_ejection_system_refresh_rate, + parachute_lag=_parachute_lag, + ) + + _rocket_data = RocketData( + inertia_details=_inertia_details, + rocket_geometrical_parameters=_rocket_geometrical_parameters, + rocket_aerodynamics_quantities=_rocket_aerodynamics_quantities, + parachute_data=_parachute_data, + ) + + rocket_summary = RocketSummary(rocket_data=_rocket_data) + return rocket_summary + + @staticmethod + def get_rocketpy_nose(nose: NoseCone) -> RocketPyNoseCone: + """ + Get a rocketpy nose cone object. + + Returns: + RocketPyNoseCone + """ + + rocketpy_nose = RocketPyNoseCone( + length=nose.length, + kind=nose.kind, + base_radius=nose.base_radius, + rocket_radius=nose.rocket_radius, + ) + rocketpy_nose.position = nose.position + return rocketpy_nose + + @staticmethod + def get_rocketpy_finset( + trapezoidal_fins: TrapezoidalFins, + ) -> RocketPyTrapezoidalFins: + """ + Get a rocketpy finset object. + + Returns: + RocketPyTrapezoidalFins + """ + rocketpy_finset = RocketPyTrapezoidalFins( + n=trapezoidal_fins.n, + root_chord=trapezoidal_fins.root_chord, + tip_chord=trapezoidal_fins.tip_chord, + span=trapezoidal_fins.span, + cant_angle=trapezoidal_fins.cant_angle, + rocket_radius=trapezoidal_fins.radius, + airfoil=trapezoidal_fins.airfoil, + ) + rocketpy_finset.position = trapezoidal_fins.position + return rocketpy_finset + + @staticmethod + def get_rocketpy_tail(tail: Tail) -> RocketPyTail: + """ + Get a rocketpy tail object. + + Returns: + RocketPyTail + """ + rocketpy_tail = RocketPyTail( + top_radius=tail.top_radius, + bottom_radius=tail.bottom_radius, + length=tail.length, + rocket_radius=tail.radius, + ) + rocketpy_tail.position = tail.position + return rocketpy_tail + + @staticmethod + def get_rocketpy_parachute( + parachute: Parachute, p: int + ) -> RocketPyParachute: + """ + Get a rocketpy parachute object. + + Returns: + RocketPyParachute + """ + rocketpy_parachute = RocketPyParachute( + name=parachute[p].name[0], + cd_s=parachute[p].cd_s[0], + trigger=eval(parachute[p].triggers[0]), + sampling_rate=parachute[p].sampling_rate[0], + lag=parachute[p].lag[0], + noise=parachute[p].noise[0], + ) + return rocketpy_parachute + + @staticmethod + def check_parachute_trigger(expression: str) -> bool: + """ + Check if the trigger expression is valid. + + Args: + expression: str + + Returns: + bool: True if the expression is valid, False otherwise. + """ + + # Parsing the expression into an AST + try: + parsed_expression = ast.parse(expression, mode="eval") + except SyntaxError: + print("Invalid syntax.") + return False + + # Constant case (supported after beta v1) + if isinstance(parsed_expression.body, ast.Constant): + return True + # Name case (supported after beta v1) + if ( + isinstance(parsed_expression.body, ast.Name) + and parsed_expression.body.id == "apogee" + ): + global apogee + apogee = "apogee" + return True + + # Validating the expression structure + if not isinstance(parsed_expression.body, ast.Lambda): + print("Invalid expression structure (not a Lambda).") + return False + + lambda_node = parsed_expression.body + if len(lambda_node.args.args) != 3: + print("Invalid expression structure (invalid arity).") + return False + + if not isinstance(lambda_node.body, ast.Compare): + try: + for operand in lambda_node.body.values: + if not isinstance(operand, ast.Compare): + print("Invalid expression structure (not a Compare).") + return False + except AttributeError: + print("Invalid expression structure (not a Compare).") + return False + + # Restricting access to functions or attributes + for node in ast.walk(lambda_node): + if isinstance(node, ast.Call): + print("Calling functions is not allowed in the expression.") + return False + if isinstance(node, ast.Attribute): + print("Accessing attributes is not allowed in the expression.") + return False + return True diff --git a/lib/views/environment.py b/lib/views/environment.py index 15157db..e865e43 100644 --- a/lib/views/environment.py +++ b/lib/views/environment.py @@ -1,4 +1,3 @@ -from typing import List from pydantic import BaseModel diff --git a/pyproject.toml b/pyproject.toml index 190673c..3737d6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ dependencies = {file = ["requirements.txt"]} [project] name = "Infinity-API" -version = "1.2.2" +version = "2.0.0" description = "RESTFULL open API for rocketpy" dynamic = ["dependencies"] requires-python = ">=3.12" @@ -55,5 +55,6 @@ disable = """ wrong-import-position, consider-using-f-string, too-many-function-args, - no-member + no-member, + attribute-defined-outside-init """ diff --git a/tests/Infinity-API.postman_collection.json b/tests/Infinity-API.postman_collection.json deleted file mode 100644 index 4ff23fc..0000000 --- a/tests/Infinity-API.postman_collection.json +++ /dev/null @@ -1,4304 +0,0 @@ -{ - "info": { - "_postman_id": "00c970b2-c429-4ecd-a1f7-de23aa286d10", - "name": "Infinity-API", - "description": "# About this collection\n\nThe API under this collection includes four artifacts **{Environment, Flight, Motor and Rocket}** with 6 endpoints each covering artifact **creation, reading, editing, deleting, simulating and retrieving artifact as jsonpickle string.**\n\n- POST `api/artifact/{{artifact_id}}` { message, artifact_id }\n- GET `api/artifact/{{artifact_id}}` { Artifact }\n- GET `api/rocketpy/artifact/{{artifact_id}}` { json_pickle_string_artifact }\n- GET `api/simulate/artifact/{{artifact_id}}` { ArtifactSimulationSummary }\n- PUT `api/artifact/{{artifact_id}}` { message, new_artifact_id }\n- DELETE `api/artifact/{{artifact_id}}` { deleted_artifact_id, message }\n \n\n**Flight artifact** have also additional routes that allows to update its own artifacts.\n\n- POST `api/flight/{{flight_id}}/artifact/` { message, flight_id }\n \n\n## **Using this collection**\n\n- Run this collection by clicking on \"Run\".\n \n\n\n\n## Additional resources\n\n[Scripting in Postman](https://learning.postman.com/docs/writing-scripts/intro-to-scripts/)\n\n[Test script examples](https://learning.postman.com/docs/writing-scripts/script-references/test-examples/)\n\n[Postman Sandbox API reference](https://learning.postman.com/docs/sending-requests/grpc/postman-sandbox-api/#writing-assertions)\n\n[Using the Collection Runner](https://learning.postman.com/docs/collections/running-collections/intro-to-collection-runs/)", - "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", - "_exporter_id": "29631298", - "_collection_link": "https://rocketpy-team.postman.co/workspace/Team-Workspace~d228e0d7-1148-4935-8e58-7db52744ee04/collection/29631298-00c970b2-c429-4ecd-a1f7-de23aa286d10?action=share&source=collection_link&creator=29631298" - }, - "item": [ - { - "name": "Environment", - "item": [ - { - "name": "Create Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var envRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce date for future assert", - "envRequest.date = envRequest.date.substring(0, envRequest.date.length - 7);", - "", - "// save environment parameters", - "pm.environment.set('env_id', apiRspn.env_id) ", - "pm.environment.set('latitude', envRequest.latitude)", - "pm.environment.set('longitude', envRequest.longitude)", - "pm.environment.set('elevation', envRequest.elevation) ", - "pm.environment.set('atmospheric_model_type', envRequest.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', envRequest.atmospheric_model_file) ", - "pm.environment.set('date', envRequest.date) ", - "", - "//TEST", - "bdd = \"Given a valid environment POST request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Environment successfully created\");", - " });", - " pm.test(bdd + \" then response must contain a valid env_id\", function () {", - " pm.expect(apiRspn.env_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1400,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/environments/", - "host": [ - "{{endpoint}}" - ], - "path": [ - "environments", - "" - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Read Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "var returned_date = apiRspn.date;", - "var reduced_returned_date = returned_date.substring(0, returned_date.length - 7);", - "", - "//TEST", - "bdd = \"Given a valid Environment GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid environment\", function () {", - " pm.expect(apiRspn.latitude).to.eql(pm.environment.get('latitude'), \"latitude not matching\");", - " pm.expect(apiRspn.longitude).to.eql(pm.environment.get('longitude'), \"longitude not matching\"); ", - " pm.expect(apiRspn.elevation).to.eql(pm.environment.get('elevation'), \"elevation not matching\");", - " pm.expect(apiRspn.atmospheric_model_type).to.eql(pm.environment.get('atmospheric_model_type'), \"atmospheric_model_type not matching\");", - " pm.expect(apiRspn.atmospheric_model_file).to.eql(pm.environment.get('atmospheric_model_file'), \"atmospheric_model_file not matching\");", - " pm.expect(reduced_returned_date).to.eql(pm.environment.get('date'), \"date not matching\");", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/environments/{{env_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "environments", - "{{env_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Read rocketpy Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid rocketpy Environment GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.jsonpickle_rocketpy_env).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/environments/rocketpy/{{env_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "environments", - "rocketpy", - "{{env_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Simulate Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid rocketpy Environment simulate GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.env_data).to.exist; ", - " //pm.expect(apiRspn.env_data.grav).to.exist; ", - " pm.expect(apiRspn.env_data.wind_speed).to.exist;", - " pm.expect(apiRspn.env_data.model_type_max_expected_height).to.exist;", - " pm.expect(apiRspn.env_data.wind_speed).to.exist;", - " pm.expect(apiRspn.env_data.wind_direction).to.exist;", - " pm.expect(apiRspn.env_data.wind_heading).to.exist;", - " pm.expect(apiRspn.env_data.surface_pressure).to.exist;", - " pm.expect(apiRspn.env_data.surface_temperature).to.exist;", - " pm.expect(apiRspn.env_data.surface_air_density).to.exist;", - " pm.expect(apiRspn.env_data.surface_speed_of_sound).to.exist;", - " pm.expect(apiRspn.env_data.launch_date).to.exist;", - " pm.expect(apiRspn.env_data.lat).to.eql(pm.environment.get('latitude'), \"latitude not matching\");", - " pm.expect(apiRspn.env_data.lon).to.eql(pm.environment.get('longitude'), \"longitude not matching\"); ", - " pm.expect(apiRspn.env_data.elevation).to.eql(pm.environment.get('elevation'), \"elevation not matching\");", - " pm.expect(apiRspn.env_data.model_type).to.eql(pm.environment.get('atmospheric_model_type'), \"atmospheric_model_type not matching\"); ", - "", - " pm.expect(apiRspn.env_plots).to.exist; ", - " pm.expect(apiRspn.env_plots.grid).to.exist;", - " pm.expect(apiRspn.env_plots.wind_speed).to.exist;", - " pm.expect(apiRspn.env_plots.wind_direction).to.exist;", - " pm.expect(apiRspn.env_plots.speed_of_sound).to.exist;", - " pm.expect(apiRspn.env_plots.density).to.exist;", - " pm.expect(apiRspn.env_plots.wind_vel_x).to.exist;", - " pm.expect(apiRspn.env_plots.wind_vel_y).to.exist;", - " pm.expect(apiRspn.env_plots.pressure).to.exist;", - " pm.expect(apiRspn.env_plots.temperature).to.exist;", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/environments/{{env_id}}/simulate", - "host": [ - "{{endpoint}}" - ], - "path": [ - "environments", - "{{env_id}}", - "simulate" - ] - } - }, - "response": [] - }, - { - "name": "Update Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var envRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce date for future assert", - "envRequest.date = envRequest.date.substring(0, envRequest.date.length - 7);", - "", - "// save environment parameters", - "pm.environment.set('env_id', apiRspn.new_env_id) ", - "pm.environment.set('latitude', envRequest.latitude)", - "pm.environment.set('longitude', envRequest.longitude)", - "pm.environment.set('elevation', envRequest.elevation) ", - "pm.environment.set('atmospheric_model_type', envRequest.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', envRequest.atmospheric_model_file) ", - "pm.environment.set('date', envRequest.date) ", - "", - "//TEST", - "bdd = \"Given a valid Environment PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Environment successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_env_id\", function () {", - " pm.expect(apiRspn.new_env_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1400,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/environments/{{env_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "environments", - "{{env_id}}" - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Delete Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid Environment DELETE request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Environment successfully deleted\", \"message not matching\");", - " pm.expect(apiRspn.deleted_env_id).to.eql(pm.environment.get('env_id'), \"env_id not matching\"); ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{endpoint}}/environments/{{env_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "environments", - "{{env_id}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Flight", - "item": [ - { - "name": "Hybrid", - "item": [ - { - "name": "Create Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce environment date for future assertion", - "flightRequest.environment.date = flightRequest.environment.date.substring(0, flightRequest.environment.date.length - 7);", - "", - "// save flight parameters", - "pm.environment.set('rail_length', flightRequest.rail_length) ", - "pm.environment.set('inclination', flightRequest.inclination)", - "pm.environment.set('heading', flightRequest.heading)", - "", - "// flight environment", - "pm.environment.set('flight_id', apiRspn.flight_id) ", - "pm.environment.set('latitude', flightRequest.environment.latitude)", - "pm.environment.set('longitude', flightRequest.environment.longitude)", - "pm.environment.set('elevation', flightRequest.environment.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.environment.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.environment.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.environment.date) ", - "", - "// flight rocket", - "pm.environment.set('radius', flightRequest.rocket.radius)", - "pm.environment.set('mass', flightRequest.rocket.mass)", - "pm.environment.set('inertia', flightRequest.rocket.inertia)", - "pm.environment.set('power_off_drag', flightRequest.rocket.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.rocket.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.rocket.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.rocket.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rocket.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rocket.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rocket.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rocket.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.rocket.coordinate_system_orientation)", - "", - "// flight rocket motor", - "pm.environment.set('burn_time', flightRequest.rocket.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.rocket.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.rocket.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.rocket.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.rocket.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.rocket.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.rocket.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.rocket.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.rocket.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.rocket.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.rocket.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.rocket.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.rocket.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.rocket.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.rocket.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.rocket.motor.coordinate_system_orientation)", - "", - "// flight rocket nose", - "pm.environment.set('nose_length', flightRequest.rocket.nose.length)", - "pm.environment.set('kind', flightRequest.rocket.nose.kind)", - "pm.environment.set('nose_position', flightRequest.rocket.nose.position)", - "pm.environment.set('base_radius', flightRequest.rocket.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.rocket.nose.rocket_radius)", - "", - "// flight rocket fins", - "pm.environment.set('n', flightRequest.rocket.fins.n)", - "pm.environment.set('root_chord', flightRequest.rocket.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.rocket.fins.tip_chord)", - "pm.environment.set('span', flightRequest.rocket.fins.span)", - "pm.environment.set('fin_position', flightRequest.rocket.fins.position)", - "pm.environment.set('cant_angle', flightRequest.rocket.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.rocket.fins.radius)", - "pm.environment.set('airfoil', flightRequest.rocket.fins.airfoil)", - "", - "// flight rocket tail", - "pm.environment.set('top_radius', flightRequest.rocket.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.rocket.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.rocket.tail.length)", - "pm.environment.set('tail_position', flightRequest.rocket.tail.position)", - "pm.environment.set('tail_radius', flightRequest.rocket.tail.radius)", - "", - "// flight rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.rocket.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.rocket.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.rocket.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.rocket.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.rocket.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.rocket.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight POST request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully created\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight_id\", function () {", - " pm.expect(apiRspn.flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"environment\": {\n \"atmospheric_model_file\": \"GFS\",\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"date\": \"2023-12-29T10:22:00.921396\",\n \"elevation\": 1400,\n \"latitude\": 0,\n \"longitude\": 0\n },\n \"rocket\": {\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"mass\": 16.235,\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"motor_position\": -1.255,\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"radius\": 0.0632,\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n }\n },\n \"inclination\": 85,\n \"heading\": 0,\n \"rail_length\": 5.2\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/?rocket_option=Calisto&motor_kind=Hybrid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Hybrid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Read Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "var returned_date = apiRspn.environment.date;", - "var reduced_returned_date = returned_date.substring(0, returned_date.length - 7);", - "", - "//TEST", - "bdd = \"Given a valid Flight GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid flight \", function () {", - " pm.expect(apiRspn.inclination).to.eql(pm.environment.get('inclination'), \"flight inclination not matching\");", - " pm.expect(apiRspn.heading).to.eql(pm.environment.get('heading'), \"flight heading not matching\");", - " pm.expect(apiRspn.rail_length).to.eql(pm.environment.get('rail_length'), \"flight rail_length not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight environment\", function () {", - " pm.expect(apiRspn.environment.longitude).to.eql(pm.environment.get('longitude'), \"environment longitude not matching\"); ", - " pm.expect(apiRspn.environment.elevation).to.eql(pm.environment.get('elevation'), \"environment elevation not matching\");", - " pm.expect(apiRspn.environment.atmospheric_model_type).to.eql(pm.environment.get('atmospheric_model_type'), \"environment atmospheric_model_type not matching\");", - " pm.expect(apiRspn.environment.atmospheric_model_file).to.eql(pm.environment.get('atmospheric_model_file'), \"environment atmospheric_model_file not matching\");", - " pm.expect(reduced_returned_date).to.eql(pm.environment.get('date'), \"date not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket\", function () { ", - " pm.expect(apiRspn.rocket.radius).to.eql(pm.environment.get('radius'), \"rocket radius not matching\");", - " pm.expect(apiRspn.rocket.mass).to.eql(pm.environment.get('mass'), \"rocket mass not matching\");", - " pm.expect(apiRspn.rocket.inertia).to.eql(pm.environment.get('inertia'), \"rocket inertia not matching\");", - " pm.expect(apiRspn.rocket.power_off_drag).to.eql(pm.environment.get('power_off_drag'), \"rocket power_off_drag not matching\");", - " pm.expect(apiRspn.rocket.power_on_drag).to.eql(pm.environment.get('power_on_drag'), \"rocket power_on_drag not matching\");", - " pm.expect(apiRspn.rocket.center_of_mass_without_motor).to.eql(pm.environment.get('center_of_mass_without_motor'), \"rocket center_of_mass_without_motor not matching\");", - " pm.expect(apiRspn.rocket.coordinate_system_orientation).to.eql(pm.environment.get('rocket_coordinate_system_orientation'), \"rocket coordinate_system_orientation not matching\");", - " pm.expect(apiRspn.rocket.motor_position).to.eql(pm.environment.get('motor_position'), \"rocket motor_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons).to.eql(pm.environment.get('rail_buttons'), \"rocket rail_buttons not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.upper_button_position).to.eql(pm.environment.get('upper_button_position'), \"rocket rail_buttons upper_button_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.lower_button_position).to.eql(pm.environment.get('lower_button_position'), \"rocket rail_buttons lower_button_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.angular_position).to.eql(pm.environment.get('angular_position'), \"rocket rail_buttons angular_position not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket motor\", function () {", - " pm.expect(apiRspn.rocket.motor.burn_time).to.eql(pm.environment.get('burn_time'), \"rocket motor burn_time not matching\");", - " pm.expect(apiRspn.rocket.motor.dry_mass).to.eql(pm.environment.get('dry_mass'), \"rocket motor dry_mass not matching\");", - " pm.expect(apiRspn.rocket.motor.dry_inertia).to.eql(pm.environment.get('dry_inertia'), \"rocket motor dry_inertia not matching\");", - " pm.expect(apiRspn.rocket.motor.center_of_dry_mass_position).to.eql(pm.environment.get('center_of_dry_mass_position'), \"rocket motor center_of_dry_mass_position not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_number).to.eql(pm.environment.get('grain_number'), \"rocket motor grain_number not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_density).to.eql(pm.environment.get('grain_density'), \"rocket motor grain_density not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_outer_radius).to.eql(pm.environment.get('grain_outer_radius'), \"rocket motor grain_outer_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_initial_inner_radius).to.eql(pm.environment.get('grain_initial_inner_radius'), \"rocket motor grain_initial_inner_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_initial_height).to.eql(pm.environment.get('grain_initial_height'), \"rocket motor grain_initial_height not matching\");", - " pm.expect(apiRspn.rocket.motor.grains_center_of_mass_position).to.eql(pm.environment.get('grains_center_of_mass_position'), \"rocket motor grains_center_of_mass_position not matching\");", - " pm.expect(apiRspn.rocket.motor.thrust_source).to.eql(pm.environment.get('thrust_source'), \"rocket motor thrust_source not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_separation).to.eql(pm.environment.get('grain_separation'), \"rocket motor grain_separation not matching\");", - " pm.expect(apiRspn.rocket.motor.nozzle_radius).to.eql(pm.environment.get('nozzle_radius'), \"rocket motor nozzle_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.throat_radius).to.eql(pm.environment.get('throat_radius'), \"rocket motor throat_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.interpolation_method).to.eql(pm.environment.get('interpolation_method'), \"rocket motor interpolation_method not matching\");", - " pm.expect(apiRspn.rocket.motor.coordinate_system_orientation).to.eql(pm.environment.get('motor_coordinate_system_orientation'), \"motor coordinate_system_orientation not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket nose\", function () {", - " pm.expect(apiRspn.rocket.nose.length).to.eql(pm.environment.get('nose_length'), \"rocket nose length not matching\");", - " pm.expect(apiRspn.rocket.nose.kind).to.eql(pm.environment.get('kind'), \"rocket nose kind not matching\");", - " pm.expect(apiRspn.rocket.nose.position).to.eql(pm.environment.get('nose_position'), \"rocket nose position not matching\");", - " pm.expect(apiRspn.rocket.nose.base_radius).to.eql(pm.environment.get('base_radius'), \"rocket nose base_radius not matching\");", - " pm.expect(apiRspn.rocket.nose.rocket_radius).to.eql(pm.environment.get('rocket_radius'), \"rocket nose rocket_radius not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket fins\", function () {", - " pm.expect(apiRspn.rocket.fins.n).to.eql(pm.environment.get('n'), \"rocket fins 'n' not matching\");", - " pm.expect(apiRspn.rocket.fins.root_chord).to.eql(pm.environment.get('root_chord'), \"rocket fins root_chord not matching\");", - " pm.expect(apiRspn.rocket.fins.tip_chord).to.eql(pm.environment.get('tip_chord'), \"rocket fins tip_chord not matching\");", - " pm.expect(apiRspn.rocket.fins.span).to.eql(pm.environment.get('span'), \"rocket fins span not matching\");", - " pm.expect(apiRspn.rocket.fins.position).to.eql(pm.environment.get('fin_position'), \"rocket fins position not matching\");", - " pm.expect(apiRspn.rocket.fins.cant_angle).to.eql(pm.environment.get('cant_angle'), \"rocket fins cant_angle not matching\");", - " pm.expect(apiRspn.rocket.fins.radius).to.eql(pm.environment.get('fin_radius'), \"rocket fins radius not matching\");", - " pm.expect(apiRspn.rocket.fins.airfoil).to.eql(pm.environment.get('airfoil'), \"rocket fins airfoil not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket tail\", function () {", - " pm.expect(apiRspn.rocket.tail.top_radius).to.eql(pm.environment.get('top_radius'), \"rocket tail top_radius not matching\"); ", - " pm.expect(apiRspn.rocket.tail.bottom_radius).to.eql(pm.environment.get('bottom_radius'), \"rocket tail bottom_radius not matching\"); ", - " pm.expect(apiRspn.rocket.tail.length).to.eql(pm.environment.get('tail_length'), \"rocket tail length not matching\"); ", - " pm.expect(apiRspn.rocket.tail.position).to.eql(pm.environment.get('tail_position'), \"rocket tail position not matching\"); ", - " pm.expect(apiRspn.rocket.tail.radius).to.eql(pm.environment.get('tail_radius'), \"rocket tail radius not matching\"); ", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket parachutes\", function () {", - " pm.expect(apiRspn.rocket.parachutes.name).to.eql(pm.environment.get('parachutes_names'), \"rocket parachutes names not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.cd_s).to.eql(pm.environment.get('parachutes_cds'), \"rocket parachutes cd_s not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.sampling_rate).to.eql(pm.environment.get('parachutes_sampling_rate'), \"rocket parachutes sampling_rate not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.lag).to.eql(pm.environment.get('parachutes_lags'), \"rocket parachutes lags not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.noise).to.eql(pm.environment.get('parachutes_noises'), \"rocket parachutes noises not matching\");", - " pm.expect(apiRspn.rocket.parachutes.triggers).to.eql(pm.environment.get('parachutes_triggers'), \"rocket parachutes triggers not matching\");", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Read rocketpy Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid rocketpy Flight GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.jsonpickle_rocketpy_flight).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/rocketpy/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "rocketpy", - "{{flight_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Simulate Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid rocketpy Flight simulate GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.flight_data).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_position).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_angular_position).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_angular_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.max_time).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.max_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.min_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.relative_error_tolerance).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.absolute_error_tolerance).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.time_overshoot).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.terminate_on_apogee).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.number_of_time_steps).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.function_evaluations_per_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.avg_function_evaluations_per_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.rail_length).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.flight_inclination).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.flight_heading).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions.frontal_surface_wind_speed).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions.lateral_surface_wind_speed).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_time).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_static_margin).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_angle_of_attack).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_thrust_weight_ratio).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_reynolds_number).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_time).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_rocket_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_freestream_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_mach_number).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_kinetic_energy).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_time).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_freestream_speed).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_speed).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_mach_number).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_reynolds_number).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_dynamic_pressure).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_acceleration_during_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_acceleration_after_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_gs_during_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_gs_after_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_upper_rail_button_normal_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_upper_rail_button_shear_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_lower_rail_button_normal_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_lower_rail_button_shear_force).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.x_impact_position).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.y_impact_position).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.time_of_impact).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.impact_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace.Drogue).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace.Main).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/simulate", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "simulate" - ] - } - }, - "response": [] - }, - { - "name": "Update Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce environment date for future assertion", - "flightRequest.environment.date = flightRequest.environment.date.substring(0, flightRequest.environment.date.length - 7);", - "", - "// save flight parameters", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "pm.environment.set('rail_length', flightRequest.rail_length) ", - "pm.environment.set('inclination', flightRequest.inclination)", - "pm.environment.set('heading', flightRequest.heading)", - "", - "// flight environment", - "pm.environment.set('latitude', flightRequest.environment.latitude)", - "pm.environment.set('longitude', flightRequest.environment.longitude)", - "pm.environment.set('elevation', flightRequest.environment.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.environment.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.environment.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.environment.date) ", - "", - "// flight rocket", - "pm.environment.set('radius', flightRequest.rocket.radius)", - "pm.environment.set('mass', flightRequest.rocket.mass)", - "pm.environment.set('inertia', flightRequest.rocket.inertia)", - "pm.environment.set('power_off_drag', flightRequest.rocket.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.rocket.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.rocket.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.rocket.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rocket.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rocket.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rocket.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rocket.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.rocket.coordinate_system_orientation)", - "", - "// flight rocket motor", - "pm.environment.set('burn_time', flightRequest.rocket.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.rocket.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.rocket.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.rocket.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.rocket.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.rocket.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.rocket.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.rocket.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.rocket.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.rocket.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.rocket.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.rocket.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.rocket.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.rocket.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.rocket.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.rocket.motor.coordinate_system_orientation)", - "", - "// flight rocket nose", - "pm.environment.set('nose_length', flightRequest.rocket.nose.length)", - "pm.environment.set('kind', flightRequest.rocket.nose.kind)", - "pm.environment.set('nose_position', flightRequest.rocket.nose.position)", - "pm.environment.set('base_radius', flightRequest.rocket.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.rocket.nose.rocket_radius)", - "", - "// flight rocket fins", - "pm.environment.set('n', flightRequest.rocket.fins.n)", - "pm.environment.set('root_chord', flightRequest.rocket.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.rocket.fins.tip_chord)", - "pm.environment.set('span', flightRequest.rocket.fins.span)", - "pm.environment.set('fin_position', flightRequest.rocket.fins.position)", - "pm.environment.set('cant_angle', flightRequest.rocket.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.rocket.fins.radius)", - "pm.environment.set('airfoil', flightRequest.rocket.fins.airfoil)", - "", - "// flight rocket tail", - "pm.environment.set('top_radius', flightRequest.rocket.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.rocket.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.rocket.tail.length)", - "pm.environment.set('tail_position', flightRequest.rocket.tail.position)", - "pm.environment.set('tail_radius', flightRequest.rocket.tail.radius)", - "", - "// flight rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.rocket.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.rocket.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.rocket.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.rocket.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.rocket.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.rocket.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"environment\": {\n \"atmospheric_model_file\": \"GFS\",\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"date\": \"2023-12-29T10:22:00.921396\",\n \"elevation\": 1300,\n \"latitude\": 2,\n \"longitude\": 1\n },\n \"rocket\": {\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"mass\": 16.235,\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"motor_position\": -1.255,\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"radius\": 0.0632,\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n }\n },\n \"inclination\": 85,\n \"heading\": 0,\n \"rail_length\": 5.2\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/?rocket_option=Calisto&motor_kind=Hybrid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Hybrid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Update Flight Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// save new flight id", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "", - "// save environment parameters", - "pm.environment.set('env_id', apiRspn.new_env_id) ", - "pm.environment.set('latitude', flightRequest.latitude)", - "pm.environment.set('longitude', flightRequest.longitude)", - "pm.environment.set('elevation', flightRequest.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.date) ", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1400,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/env", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "env" - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Update Flight Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// save new flight id", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "", - "// save rocket parameters", - "pm.environment.set('rocket_id', apiRspn.new_rocket_id)", - "pm.environment.set('radius', flightRequest.radius)", - "pm.environment.set('mass', flightRequest.mass)", - "pm.environment.set('inertia', flightRequest.inertia)", - "pm.environment.set('power_off_drag', flightRequest.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.coordinate_system_orientation)", - "", - "// rocket motor", - "pm.environment.set('burn_time', flightRequest.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.motor.coordinate_system_orientation)", - "", - "// rocket nose", - "pm.environment.set('nose_length', flightRequest.nose.length)", - "pm.environment.set('kind', flightRequest.nose.kind)", - "pm.environment.set('nose_position', flightRequest.nose.position)", - "pm.environment.set('base_radius', flightRequest.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.nose.rocket_radius)", - "", - "// rocket fins", - "pm.environment.set('n', flightRequest.fins.n)", - "pm.environment.set('root_chord', flightRequest.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.fins.tip_chord)", - "pm.environment.set('span', flightRequest.fins.span)", - "pm.environment.set('fin_position', flightRequest.fins.position)", - "pm.environment.set('cant_angle', flightRequest.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.fins.radius)", - "pm.environment.set('airfoil', flightRequest.fins.airfoil)", - "", - "// rocket tail", - "pm.environment.set('top_radius', flightRequest.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.tail.length)", - "pm.environment.set('tail_position', flightRequest.tail.position)", - "pm.environment.set('tail_radius', flightRequest.tail.radius)", - "", - "// rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"motor\": {\n \"burn_time\": 6.8,\n \"center_of_dry_mass_position\": 0.512,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 10,\n \"liquid\": {\n \"density\": 10,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"center_of_mass_without_motor\": 0,\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"motor_position\": -1.255,\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"coordinate_system_orientation\": \"tail_to_nose\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/rocket?rocket_option=Calisto&motor_kind=Hybrid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "rocket" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Hybrid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Delete Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid Flight DELETE request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully deleted\", \"message not matching\");", - " pm.expect(apiRspn.deleted_flight_id).to.eql(pm.environment.get('flight_id'), \"flight_id not matching\"); ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Liquid", - "item": [ - { - "name": "Create Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce environment date for future assertion", - "flightRequest.environment.date = flightRequest.environment.date.substring(0, flightRequest.environment.date.length - 7);", - "", - "// save flight parameters", - "pm.environment.set('rail_length', flightRequest.rail_length) ", - "pm.environment.set('inclination', flightRequest.inclination)", - "pm.environment.set('heading', flightRequest.heading)", - "", - "// flight environment", - "pm.environment.set('flight_id', apiRspn.flight_id) ", - "pm.environment.set('latitude', flightRequest.environment.latitude)", - "pm.environment.set('longitude', flightRequest.environment.longitude)", - "pm.environment.set('elevation', flightRequest.environment.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.environment.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.environment.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.environment.date) ", - "", - "// flight rocket", - "pm.environment.set('radius', flightRequest.rocket.radius)", - "pm.environment.set('mass', flightRequest.rocket.mass)", - "pm.environment.set('inertia', flightRequest.rocket.inertia)", - "pm.environment.set('power_off_drag', flightRequest.rocket.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.rocket.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.rocket.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.rocket.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rocket.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rocket.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rocket.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rocket.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.rocket.coordinate_system_orientation)", - "", - "// flight rocket motor", - "pm.environment.set('burn_time', flightRequest.rocket.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.rocket.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.rocket.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.rocket.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.rocket.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.rocket.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.rocket.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.rocket.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.rocket.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.rocket.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.rocket.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.rocket.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.rocket.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.rocket.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.rocket.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.rocket.motor.coordinate_system_orientation)", - "", - "// flight rocket nose", - "pm.environment.set('nose_length', flightRequest.rocket.nose.length)", - "pm.environment.set('kind', flightRequest.rocket.nose.kind)", - "pm.environment.set('nose_position', flightRequest.rocket.nose.position)", - "pm.environment.set('base_radius', flightRequest.rocket.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.rocket.nose.rocket_radius)", - "", - "// flight rocket fins", - "pm.environment.set('n', flightRequest.rocket.fins.n)", - "pm.environment.set('root_chord', flightRequest.rocket.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.rocket.fins.tip_chord)", - "pm.environment.set('span', flightRequest.rocket.fins.span)", - "pm.environment.set('fin_position', flightRequest.rocket.fins.position)", - "pm.environment.set('cant_angle', flightRequest.rocket.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.rocket.fins.radius)", - "pm.environment.set('airfoil', flightRequest.rocket.fins.airfoil)", - "", - "// flight rocket tail", - "pm.environment.set('top_radius', flightRequest.rocket.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.rocket.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.rocket.tail.length)", - "pm.environment.set('tail_position', flightRequest.rocket.tail.position)", - "pm.environment.set('tail_radius', flightRequest.rocket.tail.radius)", - "", - "// flight rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.rocket.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.rocket.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.rocket.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.rocket.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.rocket.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.rocket.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight POST request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully created\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight_id\", function () {", - " pm.expect(apiRspn.flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"environment\": {\n \"atmospheric_model_file\": \"GFS\",\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"date\": \"2023-12-29T10:22:00.921396\",\n \"elevation\": 1400,\n \"latitude\": 0,\n \"longitude\": 0\n },\n \"rocket\": {\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"mass\": 16.235,\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"motor_position\": -1.255,\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"radius\": 0.0632,\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n }\n },\n \"inclination\": 85,\n \"heading\": 0,\n \"rail_length\": 5.2\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/?rocket_option=Calisto&motor_kind=Liquid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Liquid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Read Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "var returned_date = apiRspn.environment.date;", - "var reduced_returned_date = returned_date.substring(0, returned_date.length - 7);", - "", - "//TEST", - "bdd = \"Given a valid Flight GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid flight \", function () {", - " pm.expect(apiRspn.inclination).to.eql(pm.environment.get('inclination'), \"flight inclination not matching\");", - " pm.expect(apiRspn.heading).to.eql(pm.environment.get('heading'), \"flight heading not matching\");", - " pm.expect(apiRspn.rail_length).to.eql(pm.environment.get('rail_length'), \"flight rail_length not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight environment\", function () {", - " pm.expect(apiRspn.environment.longitude).to.eql(pm.environment.get('longitude'), \"environment longitude not matching\"); ", - " pm.expect(apiRspn.environment.elevation).to.eql(pm.environment.get('elevation'), \"environment elevation not matching\");", - " pm.expect(apiRspn.environment.atmospheric_model_type).to.eql(pm.environment.get('atmospheric_model_type'), \"environment atmospheric_model_type not matching\");", - " pm.expect(apiRspn.environment.atmospheric_model_file).to.eql(pm.environment.get('atmospheric_model_file'), \"environment atmospheric_model_file not matching\");", - " pm.expect(reduced_returned_date).to.eql(pm.environment.get('date'), \"date not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket\", function () { ", - " pm.expect(apiRspn.rocket.radius).to.eql(pm.environment.get('radius'), \"rocket radius not matching\");", - " pm.expect(apiRspn.rocket.mass).to.eql(pm.environment.get('mass'), \"rocket mass not matching\");", - " pm.expect(apiRspn.rocket.inertia).to.eql(pm.environment.get('inertia'), \"rocket inertia not matching\");", - " pm.expect(apiRspn.rocket.power_off_drag).to.eql(pm.environment.get('power_off_drag'), \"rocket power_off_drag not matching\");", - " pm.expect(apiRspn.rocket.power_on_drag).to.eql(pm.environment.get('power_on_drag'), \"rocket power_on_drag not matching\");", - " pm.expect(apiRspn.rocket.center_of_mass_without_motor).to.eql(pm.environment.get('center_of_mass_without_motor'), \"rocket center_of_mass_without_motor not matching\");", - " pm.expect(apiRspn.rocket.coordinate_system_orientation).to.eql(pm.environment.get('rocket_coordinate_system_orientation'), \"rocket coordinate_system_orientation not matching\");", - " pm.expect(apiRspn.rocket.motor_position).to.eql(pm.environment.get('motor_position'), \"rocket motor_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons).to.eql(pm.environment.get('rail_buttons'), \"rocket rail_buttons not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.upper_button_position).to.eql(pm.environment.get('upper_button_position'), \"rocket rail_buttons upper_button_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.lower_button_position).to.eql(pm.environment.get('lower_button_position'), \"rocket rail_buttons lower_button_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.angular_position).to.eql(pm.environment.get('angular_position'), \"rocket rail_buttons angular_position not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket motor\", function () {", - " pm.expect(apiRspn.rocket.motor.burn_time).to.eql(pm.environment.get('burn_time'), \"rocket motor burn_time not matching\");", - " pm.expect(apiRspn.rocket.motor.dry_mass).to.eql(pm.environment.get('dry_mass'), \"rocket motor dry_mass not matching\");", - " pm.expect(apiRspn.rocket.motor.dry_inertia).to.eql(pm.environment.get('dry_inertia'), \"rocket motor dry_inertia not matching\");", - " pm.expect(apiRspn.rocket.motor.center_of_dry_mass_position).to.eql(pm.environment.get('center_of_dry_mass_position'), \"rocket motor center_of_dry_mass_position not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_number).to.eql(pm.environment.get('grain_number'), \"rocket motor grain_number not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_density).to.eql(pm.environment.get('grain_density'), \"rocket motor grain_density not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_outer_radius).to.eql(pm.environment.get('grain_outer_radius'), \"rocket motor grain_outer_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_initial_inner_radius).to.eql(pm.environment.get('grain_initial_inner_radius'), \"rocket motor grain_initial_inner_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_initial_height).to.eql(pm.environment.get('grain_initial_height'), \"rocket motor grain_initial_height not matching\");", - " pm.expect(apiRspn.rocket.motor.grains_center_of_mass_position).to.eql(pm.environment.get('grains_center_of_mass_position'), \"rocket motor grains_center_of_mass_position not matching\");", - " pm.expect(apiRspn.rocket.motor.thrust_source).to.eql(pm.environment.get('thrust_source'), \"rocket motor thrust_source not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_separation).to.eql(pm.environment.get('grain_separation'), \"rocket motor grain_separation not matching\");", - " pm.expect(apiRspn.rocket.motor.nozzle_radius).to.eql(pm.environment.get('nozzle_radius'), \"rocket motor nozzle_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.throat_radius).to.eql(pm.environment.get('throat_radius'), \"rocket motor throat_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.interpolation_method).to.eql(pm.environment.get('interpolation_method'), \"rocket motor interpolation_method not matching\");", - " pm.expect(apiRspn.rocket.motor.coordinate_system_orientation).to.eql(pm.environment.get('motor_coordinate_system_orientation'), \"motor coordinate_system_orientation not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket nose\", function () {", - " pm.expect(apiRspn.rocket.nose.length).to.eql(pm.environment.get('nose_length'), \"rocket nose length not matching\");", - " pm.expect(apiRspn.rocket.nose.kind).to.eql(pm.environment.get('kind'), \"rocket nose kind not matching\");", - " pm.expect(apiRspn.rocket.nose.position).to.eql(pm.environment.get('nose_position'), \"rocket nose position not matching\");", - " pm.expect(apiRspn.rocket.nose.base_radius).to.eql(pm.environment.get('base_radius'), \"rocket nose base_radius not matching\");", - " pm.expect(apiRspn.rocket.nose.rocket_radius).to.eql(pm.environment.get('rocket_radius'), \"rocket nose rocket_radius not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket fins\", function () {", - " pm.expect(apiRspn.rocket.fins.n).to.eql(pm.environment.get('n'), \"rocket fins 'n' not matching\");", - " pm.expect(apiRspn.rocket.fins.root_chord).to.eql(pm.environment.get('root_chord'), \"rocket fins root_chord not matching\");", - " pm.expect(apiRspn.rocket.fins.tip_chord).to.eql(pm.environment.get('tip_chord'), \"rocket fins tip_chord not matching\");", - " pm.expect(apiRspn.rocket.fins.span).to.eql(pm.environment.get('span'), \"rocket fins span not matching\");", - " pm.expect(apiRspn.rocket.fins.position).to.eql(pm.environment.get('fin_position'), \"rocket fins position not matching\");", - " pm.expect(apiRspn.rocket.fins.cant_angle).to.eql(pm.environment.get('cant_angle'), \"rocket fins cant_angle not matching\");", - " pm.expect(apiRspn.rocket.fins.radius).to.eql(pm.environment.get('fin_radius'), \"rocket fins radius not matching\");", - " pm.expect(apiRspn.rocket.fins.airfoil).to.eql(pm.environment.get('airfoil'), \"rocket fins airfoil not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket tail\", function () {", - " pm.expect(apiRspn.rocket.tail.top_radius).to.eql(pm.environment.get('top_radius'), \"rocket tail top_radius not matching\"); ", - " pm.expect(apiRspn.rocket.tail.bottom_radius).to.eql(pm.environment.get('bottom_radius'), \"rocket tail bottom_radius not matching\"); ", - " pm.expect(apiRspn.rocket.tail.length).to.eql(pm.environment.get('tail_length'), \"rocket tail length not matching\"); ", - " pm.expect(apiRspn.rocket.tail.position).to.eql(pm.environment.get('tail_position'), \"rocket tail position not matching\"); ", - " pm.expect(apiRspn.rocket.tail.radius).to.eql(pm.environment.get('tail_radius'), \"rocket tail radius not matching\"); ", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket parachutes\", function () {", - " pm.expect(apiRspn.rocket.parachutes.name).to.eql(pm.environment.get('parachutes_names'), \"rocket parachutes names not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.cd_s).to.eql(pm.environment.get('parachutes_cds'), \"rocket parachutes cd_s not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.sampling_rate).to.eql(pm.environment.get('parachutes_sampling_rate'), \"rocket parachutes sampling_rate not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.lag).to.eql(pm.environment.get('parachutes_lags'), \"rocket parachutes lags not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.noise).to.eql(pm.environment.get('parachutes_noises'), \"rocket parachutes noises not matching\");", - " pm.expect(apiRspn.rocket.parachutes.triggers).to.eql(pm.environment.get('parachutes_triggers'), \"rocket parachutes triggers not matching\");", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Read rocketpy Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid rocketpy Flight GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.jsonpickle_rocketpy_flight).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/rocketpy/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "rocketpy", - "{{flight_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Simulate Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid rocketpy Flight simulate GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.flight_data).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_position).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_angular_position).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_angular_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.max_time).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.max_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.min_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.relative_error_tolerance).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.absolute_error_tolerance).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.time_overshoot).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.terminate_on_apogee).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.number_of_time_steps).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.function_evaluations_per_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.avg_function_evaluations_per_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.rail_length).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.flight_inclination).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.flight_heading).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions.frontal_surface_wind_speed).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions.lateral_surface_wind_speed).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_time).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_static_margin).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_angle_of_attack).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_thrust_weight_ratio).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_reynolds_number).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_time).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_rocket_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_freestream_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_mach_number).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_kinetic_energy).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_time).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_freestream_speed).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_speed).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_mach_number).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_reynolds_number).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_dynamic_pressure).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_acceleration_during_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_acceleration_after_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_gs_during_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_gs_after_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_upper_rail_button_normal_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_upper_rail_button_shear_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_lower_rail_button_normal_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_lower_rail_button_shear_force).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.x_impact_position).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.y_impact_position).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.time_of_impact).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.impact_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace.Drogue).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace.Main).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/simulate", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "simulate" - ] - } - }, - "response": [] - }, - { - "name": "Update Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce environment date for future assertion", - "flightRequest.environment.date = flightRequest.environment.date.substring(0, flightRequest.environment.date.length - 7);", - "", - "// save flight parameters", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "pm.environment.set('rail_length', flightRequest.rail_length) ", - "pm.environment.set('inclination', flightRequest.inclination)", - "pm.environment.set('heading', flightRequest.heading)", - "", - "// flight environment", - "pm.environment.set('latitude', flightRequest.environment.latitude)", - "pm.environment.set('longitude', flightRequest.environment.longitude)", - "pm.environment.set('elevation', flightRequest.environment.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.environment.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.environment.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.environment.date) ", - "", - "// flight rocket", - "pm.environment.set('radius', flightRequest.rocket.radius)", - "pm.environment.set('mass', flightRequest.rocket.mass)", - "pm.environment.set('inertia', flightRequest.rocket.inertia)", - "pm.environment.set('power_off_drag', flightRequest.rocket.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.rocket.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.rocket.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.rocket.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rocket.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rocket.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rocket.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rocket.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.rocket.coordinate_system_orientation)", - "", - "// flight rocket motor", - "pm.environment.set('burn_time', flightRequest.rocket.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.rocket.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.rocket.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.rocket.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.rocket.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.rocket.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.rocket.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.rocket.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.rocket.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.rocket.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.rocket.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.rocket.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.rocket.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.rocket.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.rocket.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.rocket.motor.coordinate_system_orientation)", - "", - "// flight rocket nose", - "pm.environment.set('nose_length', flightRequest.rocket.nose.length)", - "pm.environment.set('kind', flightRequest.rocket.nose.kind)", - "pm.environment.set('nose_position', flightRequest.rocket.nose.position)", - "pm.environment.set('base_radius', flightRequest.rocket.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.rocket.nose.rocket_radius)", - "", - "// flight rocket fins", - "pm.environment.set('n', flightRequest.rocket.fins.n)", - "pm.environment.set('root_chord', flightRequest.rocket.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.rocket.fins.tip_chord)", - "pm.environment.set('span', flightRequest.rocket.fins.span)", - "pm.environment.set('fin_position', flightRequest.rocket.fins.position)", - "pm.environment.set('cant_angle', flightRequest.rocket.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.rocket.fins.radius)", - "pm.environment.set('airfoil', flightRequest.rocket.fins.airfoil)", - "", - "// flight rocket tail", - "pm.environment.set('top_radius', flightRequest.rocket.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.rocket.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.rocket.tail.length)", - "pm.environment.set('tail_position', flightRequest.rocket.tail.position)", - "pm.environment.set('tail_radius', flightRequest.rocket.tail.radius)", - "", - "// flight rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.rocket.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.rocket.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.rocket.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.rocket.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.rocket.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.rocket.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"environment\": {\n \"atmospheric_model_file\": \"GFS\",\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"date\": \"2023-12-29T10:22:00.921396\",\n \"elevation\": 1300,\n \"latitude\": 2,\n \"longitude\": 1\n },\n \"rocket\": {\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"mass\": 16.235,\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"motor_position\": -1.255,\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"radius\": 0.0632,\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n }\n },\n \"inclination\": 85,\n \"heading\": 0,\n \"rail_length\": 5.2\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/?rocket_option=Calisto&motor_kind=Liquid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Liquid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Update Flight Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// save new flight id", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "", - "// save environment parameters", - "pm.environment.set('env_id', apiRspn.new_env_id) ", - "pm.environment.set('latitude', flightRequest.latitude)", - "pm.environment.set('longitude', flightRequest.longitude)", - "pm.environment.set('elevation', flightRequest.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.date) ", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1400,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/env", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "env" - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Update Flight Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// save new flight id", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "", - "// save rocket parameters", - "pm.environment.set('rocket_id', apiRspn.new_rocket_id)", - "pm.environment.set('radius', flightRequest.radius)", - "pm.environment.set('mass', flightRequest.mass)", - "pm.environment.set('inertia', flightRequest.inertia)", - "pm.environment.set('power_off_drag', flightRequest.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.coordinate_system_orientation)", - "", - "// rocket motor", - "pm.environment.set('burn_time', flightRequest.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.motor.coordinate_system_orientation)", - "", - "// rocket nose", - "pm.environment.set('nose_length', flightRequest.nose.length)", - "pm.environment.set('kind', flightRequest.nose.kind)", - "pm.environment.set('nose_position', flightRequest.nose.position)", - "pm.environment.set('base_radius', flightRequest.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.nose.rocket_radius)", - "", - "// rocket fins", - "pm.environment.set('n', flightRequest.fins.n)", - "pm.environment.set('root_chord', flightRequest.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.fins.tip_chord)", - "pm.environment.set('span', flightRequest.fins.span)", - "pm.environment.set('fin_position', flightRequest.fins.position)", - "pm.environment.set('cant_angle', flightRequest.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.fins.radius)", - "pm.environment.set('airfoil', flightRequest.fins.airfoil)", - "", - "// rocket tail", - "pm.environment.set('top_radius', flightRequest.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.tail.length)", - "pm.environment.set('tail_position', flightRequest.tail.position)", - "pm.environment.set('tail_radius', flightRequest.tail.radius)", - "", - "// rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"motor\": {\n \"burn_time\": 6.8,\n \"center_of_dry_mass_position\": 0.512,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 10,\n \"liquid\": {\n \"density\": 10,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"center_of_mass_without_motor\": 0,\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"motor_position\": -1.255,\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"coordinate_system_orientation\": \"tail_to_nose\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/rocket?rocket_option=Calisto&motor_kind=Liquid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "rocket" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Liquid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Delete Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid Flight DELETE request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully deleted\", \"message not matching\");", - " pm.expect(apiRspn.deleted_flight_id).to.eql(pm.environment.get('flight_id'), \"flight_id not matching\"); ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Solid", - "item": [ - { - "name": "Create Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce environment date for future assertion", - "flightRequest.environment.date = flightRequest.environment.date.substring(0, flightRequest.environment.date.length - 7);", - "", - "// save flight parameters", - "pm.environment.set('rail_length', flightRequest.rail_length) ", - "pm.environment.set('inclination', flightRequest.inclination)", - "pm.environment.set('heading', flightRequest.heading)", - "", - "// flight environment", - "pm.environment.set('flight_id', apiRspn.flight_id) ", - "pm.environment.set('latitude', flightRequest.environment.latitude)", - "pm.environment.set('longitude', flightRequest.environment.longitude)", - "pm.environment.set('elevation', flightRequest.environment.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.environment.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.environment.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.environment.date) ", - "", - "// flight rocket", - "pm.environment.set('radius', flightRequest.rocket.radius)", - "pm.environment.set('mass', flightRequest.rocket.mass)", - "pm.environment.set('inertia', flightRequest.rocket.inertia)", - "pm.environment.set('power_off_drag', flightRequest.rocket.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.rocket.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.rocket.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.rocket.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rocket.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rocket.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rocket.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rocket.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.rocket.coordinate_system_orientation)", - "", - "// flight rocket motor", - "pm.environment.set('burn_time', flightRequest.rocket.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.rocket.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.rocket.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.rocket.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.rocket.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.rocket.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.rocket.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.rocket.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.rocket.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.rocket.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.rocket.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.rocket.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.rocket.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.rocket.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.rocket.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.rocket.motor.coordinate_system_orientation)", - "", - "// flight rocket nose", - "pm.environment.set('nose_length', flightRequest.rocket.nose.length)", - "pm.environment.set('kind', flightRequest.rocket.nose.kind)", - "pm.environment.set('nose_position', flightRequest.rocket.nose.position)", - "pm.environment.set('base_radius', flightRequest.rocket.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.rocket.nose.rocket_radius)", - "", - "// flight rocket fins", - "pm.environment.set('n', flightRequest.rocket.fins.n)", - "pm.environment.set('root_chord', flightRequest.rocket.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.rocket.fins.tip_chord)", - "pm.environment.set('span', flightRequest.rocket.fins.span)", - "pm.environment.set('fin_position', flightRequest.rocket.fins.position)", - "pm.environment.set('cant_angle', flightRequest.rocket.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.rocket.fins.radius)", - "pm.environment.set('airfoil', flightRequest.rocket.fins.airfoil)", - "", - "// flight rocket tail", - "pm.environment.set('top_radius', flightRequest.rocket.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.rocket.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.rocket.tail.length)", - "pm.environment.set('tail_position', flightRequest.rocket.tail.position)", - "pm.environment.set('tail_radius', flightRequest.rocket.tail.radius)", - "", - "// flight rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.rocket.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.rocket.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.rocket.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.rocket.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.rocket.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.rocket.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight POST request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully created\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight_id\", function () {", - " pm.expect(apiRspn.flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"environment\": {\n \"atmospheric_model_file\": \"GFS\",\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"date\": \"2023-12-29T10:22:00.921396\",\n \"elevation\": 1400,\n \"latitude\": 0,\n \"longitude\": 0\n },\n \"rocket\": {\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"mass\": 16.235,\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"motor_position\": -1.255,\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"radius\": 0.0632,\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n }\n },\n \"inclination\": 85,\n \"heading\": 0,\n \"rail_length\": 5.2\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/?rocket_option=Calisto&motor_kind=Solid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Solid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Read Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "var returned_date = apiRspn.environment.date;", - "var reduced_returned_date = returned_date.substring(0, returned_date.length - 7);", - "", - "//TEST", - "bdd = \"Given a valid Flight GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid flight \", function () {", - " pm.expect(apiRspn.inclination).to.eql(pm.environment.get('inclination'), \"flight inclination not matching\");", - " pm.expect(apiRspn.heading).to.eql(pm.environment.get('heading'), \"flight heading not matching\");", - " pm.expect(apiRspn.rail_length).to.eql(pm.environment.get('rail_length'), \"flight rail_length not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight environment\", function () {", - " pm.expect(apiRspn.environment.longitude).to.eql(pm.environment.get('longitude'), \"environment longitude not matching\"); ", - " pm.expect(apiRspn.environment.elevation).to.eql(pm.environment.get('elevation'), \"environment elevation not matching\");", - " pm.expect(apiRspn.environment.atmospheric_model_type).to.eql(pm.environment.get('atmospheric_model_type'), \"environment atmospheric_model_type not matching\");", - " pm.expect(apiRspn.environment.atmospheric_model_file).to.eql(pm.environment.get('atmospheric_model_file'), \"environment atmospheric_model_file not matching\");", - " pm.expect(reduced_returned_date).to.eql(pm.environment.get('date'), \"date not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket\", function () { ", - " pm.expect(apiRspn.rocket.radius).to.eql(pm.environment.get('radius'), \"rocket radius not matching\");", - " pm.expect(apiRspn.rocket.mass).to.eql(pm.environment.get('mass'), \"rocket mass not matching\");", - " pm.expect(apiRspn.rocket.inertia).to.eql(pm.environment.get('inertia'), \"rocket inertia not matching\");", - " pm.expect(apiRspn.rocket.power_off_drag).to.eql(pm.environment.get('power_off_drag'), \"rocket power_off_drag not matching\");", - " pm.expect(apiRspn.rocket.power_on_drag).to.eql(pm.environment.get('power_on_drag'), \"rocket power_on_drag not matching\");", - " pm.expect(apiRspn.rocket.center_of_mass_without_motor).to.eql(pm.environment.get('center_of_mass_without_motor'), \"rocket center_of_mass_without_motor not matching\");", - " pm.expect(apiRspn.rocket.coordinate_system_orientation).to.eql(pm.environment.get('rocket_coordinate_system_orientation'), \"rocket coordinate_system_orientation not matching\");", - " pm.expect(apiRspn.rocket.motor_position).to.eql(pm.environment.get('motor_position'), \"rocket motor_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons).to.eql(pm.environment.get('rail_buttons'), \"rocket rail_buttons not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.upper_button_position).to.eql(pm.environment.get('upper_button_position'), \"rocket rail_buttons upper_button_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.lower_button_position).to.eql(pm.environment.get('lower_button_position'), \"rocket rail_buttons lower_button_position not matching\");", - " pm.expect(apiRspn.rocket.rail_buttons.angular_position).to.eql(pm.environment.get('angular_position'), \"rocket rail_buttons angular_position not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket motor\", function () {", - " pm.expect(apiRspn.rocket.motor.burn_time).to.eql(pm.environment.get('burn_time'), \"rocket motor burn_time not matching\");", - " pm.expect(apiRspn.rocket.motor.dry_mass).to.eql(pm.environment.get('dry_mass'), \"rocket motor dry_mass not matching\");", - " pm.expect(apiRspn.rocket.motor.dry_inertia).to.eql(pm.environment.get('dry_inertia'), \"rocket motor dry_inertia not matching\");", - " pm.expect(apiRspn.rocket.motor.center_of_dry_mass_position).to.eql(pm.environment.get('center_of_dry_mass_position'), \"rocket motor center_of_dry_mass_position not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_number).to.eql(pm.environment.get('grain_number'), \"rocket motor grain_number not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_density).to.eql(pm.environment.get('grain_density'), \"rocket motor grain_density not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_outer_radius).to.eql(pm.environment.get('grain_outer_radius'), \"rocket motor grain_outer_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_initial_inner_radius).to.eql(pm.environment.get('grain_initial_inner_radius'), \"rocket motor grain_initial_inner_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_initial_height).to.eql(pm.environment.get('grain_initial_height'), \"rocket motor grain_initial_height not matching\");", - " pm.expect(apiRspn.rocket.motor.grains_center_of_mass_position).to.eql(pm.environment.get('grains_center_of_mass_position'), \"rocket motor grains_center_of_mass_position not matching\");", - " pm.expect(apiRspn.rocket.motor.thrust_source).to.eql(pm.environment.get('thrust_source'), \"rocket motor thrust_source not matching\");", - " pm.expect(apiRspn.rocket.motor.grain_separation).to.eql(pm.environment.get('grain_separation'), \"rocket motor grain_separation not matching\");", - " pm.expect(apiRspn.rocket.motor.nozzle_radius).to.eql(pm.environment.get('nozzle_radius'), \"rocket motor nozzle_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.throat_radius).to.eql(pm.environment.get('throat_radius'), \"rocket motor throat_radius not matching\");", - " pm.expect(apiRspn.rocket.motor.interpolation_method).to.eql(pm.environment.get('interpolation_method'), \"rocket motor interpolation_method not matching\");", - " pm.expect(apiRspn.rocket.motor.coordinate_system_orientation).to.eql(pm.environment.get('motor_coordinate_system_orientation'), \"motor coordinate_system_orientation not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket nose\", function () {", - " pm.expect(apiRspn.rocket.nose.length).to.eql(pm.environment.get('nose_length'), \"rocket nose length not matching\");", - " pm.expect(apiRspn.rocket.nose.kind).to.eql(pm.environment.get('kind'), \"rocket nose kind not matching\");", - " pm.expect(apiRspn.rocket.nose.position).to.eql(pm.environment.get('nose_position'), \"rocket nose position not matching\");", - " pm.expect(apiRspn.rocket.nose.base_radius).to.eql(pm.environment.get('base_radius'), \"rocket nose base_radius not matching\");", - " pm.expect(apiRspn.rocket.nose.rocket_radius).to.eql(pm.environment.get('rocket_radius'), \"rocket nose rocket_radius not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket fins\", function () {", - " pm.expect(apiRspn.rocket.fins.n).to.eql(pm.environment.get('n'), \"rocket fins 'n' not matching\");", - " pm.expect(apiRspn.rocket.fins.root_chord).to.eql(pm.environment.get('root_chord'), \"rocket fins root_chord not matching\");", - " pm.expect(apiRspn.rocket.fins.tip_chord).to.eql(pm.environment.get('tip_chord'), \"rocket fins tip_chord not matching\");", - " pm.expect(apiRspn.rocket.fins.span).to.eql(pm.environment.get('span'), \"rocket fins span not matching\");", - " pm.expect(apiRspn.rocket.fins.position).to.eql(pm.environment.get('fin_position'), \"rocket fins position not matching\");", - " pm.expect(apiRspn.rocket.fins.cant_angle).to.eql(pm.environment.get('cant_angle'), \"rocket fins cant_angle not matching\");", - " pm.expect(apiRspn.rocket.fins.radius).to.eql(pm.environment.get('fin_radius'), \"rocket fins radius not matching\");", - " pm.expect(apiRspn.rocket.fins.airfoil).to.eql(pm.environment.get('airfoil'), \"rocket fins airfoil not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket tail\", function () {", - " pm.expect(apiRspn.rocket.tail.top_radius).to.eql(pm.environment.get('top_radius'), \"rocket tail top_radius not matching\"); ", - " pm.expect(apiRspn.rocket.tail.bottom_radius).to.eql(pm.environment.get('bottom_radius'), \"rocket tail bottom_radius not matching\"); ", - " pm.expect(apiRspn.rocket.tail.length).to.eql(pm.environment.get('tail_length'), \"rocket tail length not matching\"); ", - " pm.expect(apiRspn.rocket.tail.position).to.eql(pm.environment.get('tail_position'), \"rocket tail position not matching\"); ", - " pm.expect(apiRspn.rocket.tail.radius).to.eql(pm.environment.get('tail_radius'), \"rocket tail radius not matching\"); ", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket parachutes\", function () {", - " pm.expect(apiRspn.rocket.parachutes.name).to.eql(pm.environment.get('parachutes_names'), \"rocket parachutes names not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.cd_s).to.eql(pm.environment.get('parachutes_cds'), \"rocket parachutes cd_s not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.sampling_rate).to.eql(pm.environment.get('parachutes_sampling_rate'), \"rocket parachutes sampling_rate not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.lag).to.eql(pm.environment.get('parachutes_lags'), \"rocket parachutes lags not matching\"); ", - " pm.expect(apiRspn.rocket.parachutes.noise).to.eql(pm.environment.get('parachutes_noises'), \"rocket parachutes noises not matching\");", - " pm.expect(apiRspn.rocket.parachutes.triggers).to.eql(pm.environment.get('parachutes_triggers'), \"rocket parachutes triggers not matching\");", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Read rocketpy Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid rocketpy Flight GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.jsonpickle_rocketpy_flight).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/rocketpy/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "rocketpy", - "{{flight_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Simulate Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid rocketpy Flight simulate GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.flight_data).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_position).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_angular_position).to.exist;", - " pm.expect(apiRspn.flight_data.initial_conditions.initial_angular_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.max_time).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.max_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.min_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.relative_error_tolerance).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.absolute_error_tolerance).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.time_overshoot).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.terminate_on_apogee).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.number_of_time_steps).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.function_evaluations_per_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.numerical_integration_settings.avg_function_evaluations_per_time_step).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.rail_length).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.flight_inclination).to.exist;", - " pm.expect(apiRspn.flight_data.launch_rail_conditions.flight_heading).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions.frontal_surface_wind_speed).to.exist;", - " pm.expect(apiRspn.flight_data.surface_wind_conditions.lateral_surface_wind_speed).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_time).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_static_margin).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_angle_of_attack).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_thrust_weight_ratio).to.exist;", - " pm.expect(apiRspn.flight_data.out_of_rail_conditions.out_of_rail_reynolds_number).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_time).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_rocket_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_freestream_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_mach_number).to.exist;", - " pm.expect(apiRspn.flight_data.burnout_conditions.burnout_kinetic_energy).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_time).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_altitude).to.exist;", - " pm.expect(apiRspn.flight_data.apogee_conditions.apogee_freestream_speed).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_speed).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_mach_number).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_reynolds_number).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_dynamic_pressure).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_acceleration_during_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_acceleration_after_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_gs_during_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_gs_after_motor_burn).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_upper_rail_button_normal_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_upper_rail_button_shear_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_lower_rail_button_normal_force).to.exist;", - " pm.expect(apiRspn.flight_data.maximum_values.maximum_lower_rail_button_shear_force).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.x_impact_position).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.y_impact_position).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.time_of_impact).to.exist;", - " pm.expect(apiRspn.flight_data.impact_conditions.impact_velocity).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace.Drogue).to.exist;", - " pm.expect(apiRspn.flight_data.events_registered.events_trace.Main).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/simulate", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "simulate" - ] - } - }, - "response": [] - }, - { - "name": "Update Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// reduce environment date for future assertion", - "flightRequest.environment.date = flightRequest.environment.date.substring(0, flightRequest.environment.date.length - 7);", - "", - "// save flight parameters", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "pm.environment.set('rail_length', flightRequest.rail_length) ", - "pm.environment.set('inclination', flightRequest.inclination)", - "pm.environment.set('heading', flightRequest.heading)", - "", - "// flight environment", - "pm.environment.set('latitude', flightRequest.environment.latitude)", - "pm.environment.set('longitude', flightRequest.environment.longitude)", - "pm.environment.set('elevation', flightRequest.environment.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.environment.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.environment.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.environment.date) ", - "", - "// flight rocket", - "pm.environment.set('radius', flightRequest.rocket.radius)", - "pm.environment.set('mass', flightRequest.rocket.mass)", - "pm.environment.set('inertia', flightRequest.rocket.inertia)", - "pm.environment.set('power_off_drag', flightRequest.rocket.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.rocket.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.rocket.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.rocket.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rocket.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rocket.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rocket.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rocket.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.rocket.coordinate_system_orientation)", - "", - "// flight rocket motor", - "pm.environment.set('burn_time', flightRequest.rocket.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.rocket.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.rocket.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.rocket.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.rocket.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.rocket.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.rocket.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.rocket.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.rocket.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.rocket.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.rocket.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.rocket.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.rocket.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.rocket.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.rocket.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.rocket.motor.coordinate_system_orientation)", - "", - "// flight rocket nose", - "pm.environment.set('nose_length', flightRequest.rocket.nose.length)", - "pm.environment.set('kind', flightRequest.rocket.nose.kind)", - "pm.environment.set('nose_position', flightRequest.rocket.nose.position)", - "pm.environment.set('base_radius', flightRequest.rocket.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.rocket.nose.rocket_radius)", - "", - "// flight rocket fins", - "pm.environment.set('n', flightRequest.rocket.fins.n)", - "pm.environment.set('root_chord', flightRequest.rocket.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.rocket.fins.tip_chord)", - "pm.environment.set('span', flightRequest.rocket.fins.span)", - "pm.environment.set('fin_position', flightRequest.rocket.fins.position)", - "pm.environment.set('cant_angle', flightRequest.rocket.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.rocket.fins.radius)", - "pm.environment.set('airfoil', flightRequest.rocket.fins.airfoil)", - "", - "// flight rocket tail", - "pm.environment.set('top_radius', flightRequest.rocket.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.rocket.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.rocket.tail.length)", - "pm.environment.set('tail_position', flightRequest.rocket.tail.position)", - "pm.environment.set('tail_radius', flightRequest.rocket.tail.radius)", - "", - "// flight rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.rocket.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.rocket.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.rocket.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.rocket.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.rocket.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.rocket.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"environment\": {\n \"atmospheric_model_file\": \"GFS\",\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"date\": \"2023-12-29T10:22:00.921396\",\n \"elevation\": 1300,\n \"latitude\": 2,\n \"longitude\": 1\n },\n \"rocket\": {\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"mass\": 16.235,\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"motor_position\": -1.255,\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"radius\": 0.0632,\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n }\n },\n \"inclination\": 85,\n \"heading\": 0,\n \"rail_length\": 5.2\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/?rocket_option=Calisto&motor_kind=Solid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Solid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Update Flight Environment", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// save new flight id", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "", - "// save environment parameters", - "pm.environment.set('env_id', apiRspn.new_env_id) ", - "pm.environment.set('latitude', flightRequest.latitude)", - "pm.environment.set('longitude', flightRequest.longitude)", - "pm.environment.set('elevation', flightRequest.elevation) ", - "pm.environment.set('atmospheric_model_type', flightRequest.atmospheric_model_type) ", - "pm.environment.set('atmospheric_model_file', flightRequest.atmospheric_model_file) ", - "pm.environment.set('date', flightRequest.date) ", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1400,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/env", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "env" - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Update Flight Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var flightRequest = JSON.parse(pm.request.body.raw);", - "", - "// save new flight id", - "pm.environment.set('flight_id', apiRspn.new_flight_id) ", - "", - "// save rocket parameters", - "pm.environment.set('rocket_id', apiRspn.new_rocket_id)", - "pm.environment.set('radius', flightRequest.radius)", - "pm.environment.set('mass', flightRequest.mass)", - "pm.environment.set('inertia', flightRequest.inertia)", - "pm.environment.set('power_off_drag', flightRequest.power_off_drag)", - "pm.environment.set('power_on_drag', flightRequest.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', flightRequest.center_of_mass_without_motor)", - "pm.environment.set('motor_position', flightRequest.motor_position)", - "pm.environment.set('rail_buttons', flightRequest.rail_buttons)", - "pm.environment.set('upper_button_position', flightRequest.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', flightRequest.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', flightRequest.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', flightRequest.coordinate_system_orientation)", - "", - "// rocket motor", - "pm.environment.set('burn_time', flightRequest.motor.burn_time)", - "pm.environment.set('dry_mass', flightRequest.motor.dry_mass)", - "pm.environment.set('dry_inertia', flightRequest.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', flightRequest.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', flightRequest.motor.grain_number)", - "pm.environment.set('grain_density', flightRequest.motor.grain_density)", - "pm.environment.set('grain_outer_radius', flightRequest.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', flightRequest.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', flightRequest.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', flightRequest.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', flightRequest.motor.grain_separation)", - "pm.environment.set('thrust_source', flightRequest.motor.thrust_source)", - "pm.environment.set('nozzle_radius', flightRequest.motor.nozzle_radius)", - "pm.environment.set('throat_radius', flightRequest.motor.throat_radius)", - "pm.environment.set('interpolation_method', flightRequest.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', flightRequest.motor.coordinate_system_orientation)", - "", - "// rocket nose", - "pm.environment.set('nose_length', flightRequest.nose.length)", - "pm.environment.set('kind', flightRequest.nose.kind)", - "pm.environment.set('nose_position', flightRequest.nose.position)", - "pm.environment.set('base_radius', flightRequest.nose.base_radius)", - "pm.environment.set('rocket_radius', flightRequest.nose.rocket_radius)", - "", - "// rocket fins", - "pm.environment.set('n', flightRequest.fins.n)", - "pm.environment.set('root_chord', flightRequest.fins.root_chord)", - "pm.environment.set('tip_chord', flightRequest.fins.tip_chord)", - "pm.environment.set('span', flightRequest.fins.span)", - "pm.environment.set('fin_position', flightRequest.fins.position)", - "pm.environment.set('cant_angle', flightRequest.fins.cant_angle)", - "pm.environment.set('fin_radius', flightRequest.fins.radius)", - "pm.environment.set('airfoil', flightRequest.fins.airfoil)", - "", - "// rocket tail", - "pm.environment.set('top_radius', flightRequest.tail.top_radius)", - "pm.environment.set('bottom_radius', flightRequest.tail.bottom_radius)", - "pm.environment.set('tail_length', flightRequest.tail.length)", - "pm.environment.set('tail_position', flightRequest.tail.position)", - "pm.environment.set('tail_radius', flightRequest.tail.radius)", - "", - "// rocket parachute", - "pm.environment.set('parachutes_names', flightRequest.parachutes.name)", - "pm.environment.set('parachutes_cds', flightRequest.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', flightRequest.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', flightRequest.parachutes.lag)", - "pm.environment.set('parachutes_noises', flightRequest.parachutes.noise)", - "pm.environment.set('parachutes_triggers', flightRequest.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Flight PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_flight_id\", function () {", - " pm.expect(apiRspn.new_flight_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"motor\": {\n \"burn_time\": 6.8,\n \"center_of_dry_mass_position\": 0.512,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 10,\n \"liquid\": {\n \"density\": 10,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"center_of_mass_without_motor\": 0,\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"motor_position\": -1.255,\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"coordinate_system_orientation\": \"tail_to_nose\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}/rocket?rocket_option=Calisto&motor_kind=Solid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}", - "rocket" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Solid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Delete Flight", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid Flight DELETE request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Flight successfully deleted\", \"message not matching\");", - " pm.expect(apiRspn.deleted_flight_id).to.eql(pm.environment.get('flight_id'), \"flight_id not matching\"); ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{endpoint}}/flights/{{flight_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "flights", - "{{flight_id}}" - ] - } - }, - "response": [] - } - ] - } - ] - }, - { - "name": "Motor", - "item": [ - { - "name": "Create Motor", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var motorRequest = JSON.parse(pm.request.body.raw);", - "", - "// save motor parameters", - "pm.environment.set('motor_id', apiRspn.motor_id) ", - "pm.environment.set('burn_time', motorRequest.burn_time)", - "pm.environment.set('dry_mass', motorRequest.dry_mass)", - "pm.environment.set('dry_inertia', motorRequest.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', motorRequest.center_of_dry_mass_position)", - "pm.environment.set('grain_number', motorRequest.grain_number)", - "pm.environment.set('grain_density', motorRequest.grain_density)", - "pm.environment.set('grain_outer_radius', motorRequest.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', motorRequest.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', motorRequest.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', motorRequest.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', motorRequest.grain_separation)", - "pm.environment.set('thrust_source', motorRequest.thrust_source)", - "pm.environment.set('nozzle_radius', motorRequest.nozzle_radius)", - "pm.environment.set('throat_radius', motorRequest.throat_radius)", - "pm.environment.set('interpolation_method', motorRequest.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', motorRequest.coordinate_system_orientation)", - "", - "//TEST", - "bdd = \"Given a valid Motor POST request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Motor successfully created\");", - " });", - " pm.test(bdd + \" then response must contain a valid motor_id\", function () {", - " pm.expect(apiRspn.motor_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"thrust_source\": \"Cesaroni_M1670\",\n \"burn_time\": 3.9,\n \"nozzle_radius\": 0.033,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"center_of_dry_mass_position\": 0.317,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"grain_number\": 5,\n \"grain_density\": 1815,\n \"grain_outer_radius\": 0.033,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_initial_height\": 0.12,\n \"grains_center_of_mass_position\": -0.85704,\n \"grain_separation\": 0.005,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/motors/?motor_kind=Solid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "motors", - "" - ], - "query": [ - { - "key": "motor_kind", - "value": "Solid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Read Motor", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid Motor GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " }); ", - " pm.test(bdd + \" then response must contain a valid motor\", function () {", - " pm.expect(apiRspn.burn_time).to.eql(pm.environment.get('burn_time'), \"motor burn_time not matching\");", - " pm.expect(apiRspn.dry_mass).to.eql(pm.environment.get('dry_mass'), \"motor dry_mass not matching\");", - " pm.expect(apiRspn.dry_inertia).to.eql(pm.environment.get('dry_inertia'), \"motor dry_inertia not matching\");", - " pm.expect(apiRspn.center_of_dry_mass_position).to.eql(pm.environment.get('center_of_dry_mass_position'), \"motor center_of_dry_mass_position not matching\");", - " pm.expect(apiRspn.grain_number).to.eql(pm.environment.get('grain_number'), \"motor grain_number not matching\");", - " pm.expect(apiRspn.grain_density).to.eql(pm.environment.get('grain_density'), \"motor grain_density not matching\");", - " pm.expect(apiRspn.grain_outer_radius).to.eql(pm.environment.get('grain_outer_radius'), \"motor grain_outer_radius not matching\");", - " pm.expect(apiRspn.grain_initial_inner_radius).to.eql(pm.environment.get('grain_initial_inner_radius'), \"motor grain_initial_inner_radius not matching\");", - " pm.expect(apiRspn.grain_initial_height).to.eql(pm.environment.get('grain_initial_height'), \"motor grain_initial_height not matching\");", - " pm.expect(apiRspn.grains_center_of_mass_position).to.eql(pm.environment.get('grains_center_of_mass_position'), \"motor grains_center_of_mass_position not matching\");", - " pm.expect(apiRspn.thrust_source).to.eql(pm.environment.get('thrust_source'), \"motor thrust_source not matching\");", - " pm.expect(apiRspn.grain_separation).to.eql(pm.environment.get('grain_separation'), \"motor grain_separation not matching\");", - " pm.expect(apiRspn.nozzle_radius).to.eql(pm.environment.get('nozzle_radius'), \"motor nozzle_radius not matching\");", - " pm.expect(apiRspn.throat_radius).to.eql(pm.environment.get('throat_radius'), \"motor throat_radius not matching\");", - " pm.expect(apiRspn.interpolation_method).to.eql(pm.environment.get('interpolation_method'), \"motor interpolation_method not matching\");", - " pm.expect(apiRspn.coordinate_system_orientation).to.eql(pm.environment.get('motor_coordinate_system_orientation'), \"motor coordinate_system_orientation not matching\");", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/motors/{{motor_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "motors", - "{{motor_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Read rocketpy Motor", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid rocketpy Motor GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.jsonpickle_rocketpy_motor).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/motors/rocketpy/{{motor_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "motors", - "rocketpy", - "{{motor_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Simulate Motor", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid rocketpy Motor simulate GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.motor_data).to.exist;", - " pm.expect(apiRspn.motor_data.total_burning_time).to.exist;", - " pm.expect(apiRspn.motor_data.total_propellant_mass).to.exist;", - " pm.expect(apiRspn.motor_data.average_propellant_exhaust_velocity).to.exist;", - " pm.expect(apiRspn.motor_data.average_thrust).to.exist;", - " pm.expect(apiRspn.motor_data.maximum_thrust).to.exist;", - " pm.expect(apiRspn.motor_data.total_impulse).to.exist;", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/motors/{{motor_id}}/simulate", - "host": [ - "{{endpoint}}" - ], - "path": [ - "motors", - "{{motor_id}}", - "simulate" - ] - } - }, - "response": [] - }, - { - "name": "Update Motor", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var motorRequest = JSON.parse(pm.request.body.raw);", - "", - "// save motor parameters", - "pm.environment.set('motor_id', apiRspn.new_motor_id)", - "pm.environment.set('burn_time', motorRequest.burn_time)", - "pm.environment.set('dry_mass', motorRequest.dry_mass)", - "pm.environment.set('dry_inertia', motorRequest.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', motorRequest.center_of_dry_mass_position)", - "pm.environment.set('grain_number', motorRequest.grain_number)", - "pm.environment.set('grain_density', motorRequest.grain_density)", - "pm.environment.set('grain_outer_radius', motorRequest.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', motorRequest.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', motorRequest.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', motorRequest.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', motorRequest.grain_separation)", - "pm.environment.set('thrust_source', motorRequest.thrust_source)", - "pm.environment.set('nozzle_radius', motorRequest.nozzle_radius)", - "pm.environment.set('throat_radius', motorRequest.throat_radius)", - "pm.environment.set('interpolation_method', motorRequest.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', motorRequest.coordinate_system_orientation)", - "", - "//TEST", - "bdd = \"Given a valid Motor PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Motor successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid new_motor_id\", function () {", - " pm.expect(apiRspn.new_motor_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"thrust_source\": \"Cesaroni_M1670\",\n \"burn_time\": 3.9,\n \"nozzle_radius\": 0.033,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"center_of_dry_mass_position\": 0.317,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"grain_number\": 5,\n \"grain_density\": 1815,\n \"grain_outer_radius\": 0.033,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_initial_height\": 0.12,\n \"grains_center_of_mass_position\": -0.85704,\n \"grain_separation\": 0.005,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/motors/{{motor_id}}/?motor_kind=Liquid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "motors", - "{{motor_id}}", - "" - ], - "query": [ - { - "key": "motor_kind", - "value": "Liquid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Delete Motor", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid Motor DELETE request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Motor successfully deleted\", \"message not matching\");", - " pm.expect(apiRspn.deleted_motor_id).to.eql(pm.environment.get('motor_id'), \"motor_id not matching\"); ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{endpoint}}/motors/{{motor_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "motors", - "{{motor_id}}" - ] - } - }, - "response": [] - } - ] - }, - { - "name": "Rocket", - "item": [ - { - "name": "Create Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var rocketRequest = JSON.parse(pm.request.body.raw);", - "", - "// save rocket parameters", - "pm.environment.set('rocket_id', apiRspn.rocket_id)", - "pm.environment.set('radius', rocketRequest.radius)", - "pm.environment.set('mass', rocketRequest.mass)", - "pm.environment.set('inertia', rocketRequest.inertia)", - "pm.environment.set('power_off_drag', rocketRequest.power_off_drag)", - "pm.environment.set('power_on_drag', rocketRequest.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', rocketRequest.center_of_mass_without_motor)", - "pm.environment.set('motor_position', rocketRequest.motor_position)", - "pm.environment.set('rail_buttons', rocketRequest.rail_buttons)", - "pm.environment.set('upper_button_position', rocketRequest.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', rocketRequest.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', rocketRequest.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', rocketRequest.coordinate_system_orientation)", - "", - "// rocket motor", - "pm.environment.set('burn_time', rocketRequest.motor.burn_time)", - "pm.environment.set('dry_mass', rocketRequest.motor.dry_mass)", - "pm.environment.set('dry_inertia', rocketRequest.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', rocketRequest.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', rocketRequest.motor.grain_number)", - "pm.environment.set('grain_density', rocketRequest.motor.grain_density)", - "pm.environment.set('grain_outer_radius', rocketRequest.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', rocketRequest.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', rocketRequest.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', rocketRequest.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', rocketRequest.motor.grain_separation)", - "pm.environment.set('thrust_source', rocketRequest.motor.thrust_source)", - "pm.environment.set('nozzle_radius', rocketRequest.motor.nozzle_radius)", - "pm.environment.set('throat_radius', rocketRequest.motor.throat_radius)", - "pm.environment.set('interpolation_method', rocketRequest.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', rocketRequest.motor.coordinate_system_orientation)", - "", - "// rocket nose", - "pm.environment.set('nose_length', rocketRequest.nose.length)", - "pm.environment.set('kind', rocketRequest.nose.kind)", - "pm.environment.set('nose_position', rocketRequest.nose.position)", - "pm.environment.set('base_radius', rocketRequest.nose.base_radius)", - "pm.environment.set('rocket_radius', rocketRequest.nose.rocket_radius)", - "", - "// rocket fins", - "pm.environment.set('n', rocketRequest.fins.n)", - "pm.environment.set('root_chord', rocketRequest.fins.root_chord)", - "pm.environment.set('tip_chord', rocketRequest.fins.tip_chord)", - "pm.environment.set('span', rocketRequest.fins.span)", - "pm.environment.set('fin_position', rocketRequest.fins.position)", - "pm.environment.set('cant_angle', rocketRequest.fins.cant_angle)", - "pm.environment.set('fin_radius', rocketRequest.fins.radius)", - "pm.environment.set('airfoil', rocketRequest.fins.airfoil)", - "", - "// rocket tail", - "pm.environment.set('top_radius', rocketRequest.tail.top_radius)", - "pm.environment.set('bottom_radius', rocketRequest.tail.bottom_radius)", - "pm.environment.set('tail_length', rocketRequest.tail.length)", - "pm.environment.set('tail_position', rocketRequest.tail.position)", - "pm.environment.set('tail_radius', rocketRequest.tail.radius)", - "", - "// rocket parachute", - "pm.environment.set('parachutes_names', rocketRequest.parachutes.name)", - "pm.environment.set('parachutes_cds', rocketRequest.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', rocketRequest.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', rocketRequest.parachutes.lag)", - "pm.environment.set('parachutes_noises', rocketRequest.parachutes.noise)", - "pm.environment.set('parachutes_triggers', rocketRequest.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Rocket POST request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Rocket successfully created\");", - " });", - " pm.test(bdd + \" then response must contain a valid rocket_id\", function () {", - " pm.expect(apiRspn.rocket_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "POST", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"rail_buttons\": {\n \"angular_position\": 45,\n \"lower_button_position\": 0.2,\n \"upper_button_position\": -0.5\n },\n \"motor\": {\n \"burn_time\": 3.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"center_of_mass_without_motor\": 0,\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"motor_position\": -1.255,\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"coordinate_system_orientation\": \"tail_to_nose\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/rockets/?rocket_option=Calisto&motor_kind=Solid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "rockets", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Solid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Read Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid Rocket GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " }); ", - " pm.test(bdd + \" then response must contain a valid rocket\", function () { ", - " pm.expect(apiRspn.radius).to.eql(pm.environment.get('radius'), \"rocket radius not matching\");", - " pm.expect(apiRspn.mass).to.eql(pm.environment.get('mass'), \"rocket mass not matching\");", - " pm.expect(apiRspn.inertia).to.eql(pm.environment.get('inertia'), \"rocket inertia not matching\");", - " pm.expect(apiRspn.power_off_drag).to.eql(pm.environment.get('power_off_drag'), \"rocket power_off_drag not matching\");", - " pm.expect(apiRspn.power_on_drag).to.eql(pm.environment.get('power_on_drag'), \"rocket power_on_drag not matching\");", - " pm.expect(apiRspn.center_of_mass_without_motor).to.eql(pm.environment.get('center_of_mass_without_motor'), \"rocket center_of_mass_without_motor not matching\");", - " pm.expect(apiRspn.coordinate_system_orientation).to.eql(pm.environment.get('rocket_coordinate_system_orientation'), \"rocket coordinate_system_orientation not matching\");", - " pm.expect(apiRspn.motor_position).to.eql(pm.environment.get('motor_position'), \"rocket motor_position not matching\");", - " pm.expect(apiRspn.rail_buttons).to.eql(pm.environment.get('rail_buttons'), \"rocket rail_buttons not matching\");", - " pm.expect(apiRspn.rail_buttons.upper_button_position).to.eql(pm.environment.get('upper_button_position'), \"rocket rail_buttons upper_button_position not matching\");", - " pm.expect(apiRspn.rail_buttons.lower_button_position).to.eql(pm.environment.get('lower_button_position'), \"rocket rail_buttons lower_button_position not matching\");", - " pm.expect(apiRspn.rail_buttons.angular_position).to.eql(pm.environment.get('angular_position'), \"rocket rail_buttons angular_position not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket motor\", function () {", - " pm.expect(apiRspn.motor.burn_time).to.eql(pm.environment.get('burn_time'), \"rocket motor burn_time not matching\");", - " pm.expect(apiRspn.motor.dry_mass).to.eql(pm.environment.get('dry_mass'), \"rocket motor dry_mass not matching\");", - " pm.expect(apiRspn.motor.dry_inertia).to.eql(pm.environment.get('dry_inertia'), \"rocket motor dry_inertia not matching\");", - " pm.expect(apiRspn.motor.center_of_dry_mass_position).to.eql(pm.environment.get('center_of_dry_mass_position'), \"rocket motor center_of_dry_mass_position not matching\");", - " pm.expect(apiRspn.motor.grain_number).to.eql(pm.environment.get('grain_number'), \"rocket motor grain_number not matching\");", - " pm.expect(apiRspn.motor.grain_density).to.eql(pm.environment.get('grain_density'), \"rocket motor grain_density not matching\");", - " pm.expect(apiRspn.motor.grain_outer_radius).to.eql(pm.environment.get('grain_outer_radius'), \"rocket motor grain_outer_radius not matching\");", - " pm.expect(apiRspn.motor.grain_initial_inner_radius).to.eql(pm.environment.get('grain_initial_inner_radius'), \"rocket motor grain_initial_inner_radius not matching\");", - " pm.expect(apiRspn.motor.grain_initial_height).to.eql(pm.environment.get('grain_initial_height'), \"rocket motor grain_initial_height not matching\");", - " pm.expect(apiRspn.motor.grains_center_of_mass_position).to.eql(pm.environment.get('grains_center_of_mass_position'), \"rocket motor grains_center_of_mass_position not matching\");", - " pm.expect(apiRspn.motor.thrust_source).to.eql(pm.environment.get('thrust_source'), \"rocket motor thrust_source not matching\");", - " pm.expect(apiRspn.motor.grain_separation).to.eql(pm.environment.get('grain_separation'), \"rocket motor grain_separation not matching\");", - " pm.expect(apiRspn.motor.nozzle_radius).to.eql(pm.environment.get('nozzle_radius'), \"rocket motor nozzle_radius not matching\");", - " pm.expect(apiRspn.motor.throat_radius).to.eql(pm.environment.get('throat_radius'), \"rocket motor throat_radius not matching\");", - " pm.expect(apiRspn.motor.interpolation_method).to.eql(pm.environment.get('interpolation_method'), \"rocket motor interpolation_method not matching\");", - " pm.expect(apiRspn.motor.coordinate_system_orientation).to.eql(pm.environment.get('motor_coordinate_system_orientation'), \"motor coordinate_system_orientation not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket nose\", function () {", - " pm.expect(apiRspn.nose.length).to.eql(pm.environment.get('nose_length'), \"rocket nose length not matching\");", - " pm.expect(apiRspn.nose.kind).to.eql(pm.environment.get('kind'), \"rocket nose kind not matching\");", - " pm.expect(apiRspn.nose.position).to.eql(pm.environment.get('nose_position'), \"rocket nose position not matching\");", - " pm.expect(apiRspn.nose.base_radius).to.eql(pm.environment.get('base_radius'), \"rocket nose base_radius not matching\");", - " pm.expect(apiRspn.nose.rocket_radius).to.eql(pm.environment.get('rocket_radius'), \"rocket nose rocket_radius not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket fins\", function () {", - " pm.expect(apiRspn.fins.n).to.eql(pm.environment.get('n'), \"rocket fins 'n' not matching\");", - " pm.expect(apiRspn.fins.root_chord).to.eql(pm.environment.get('root_chord'), \"rocket fins root_chord not matching\");", - " pm.expect(apiRspn.fins.tip_chord).to.eql(pm.environment.get('tip_chord'), \"rocket fins tip_chord not matching\");", - " pm.expect(apiRspn.fins.span).to.eql(pm.environment.get('span'), \"rocket fins span not matching\");", - " pm.expect(apiRspn.fins.position).to.eql(pm.environment.get('fin_position'), \"rocket fins position not matching\");", - " pm.expect(apiRspn.fins.cant_angle).to.eql(pm.environment.get('cant_angle'), \"rocket fins cant_angle not matching\");", - " pm.expect(apiRspn.fins.radius).to.eql(pm.environment.get('fin_radius'), \"rocket fins radius not matching\");", - " pm.expect(apiRspn.fins.airfoil).to.eql(pm.environment.get('airfoil'), \"rocket fins airfoil not matching\");", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket tail\", function () {", - " pm.expect(apiRspn.tail.top_radius).to.eql(pm.environment.get('top_radius'), \"rocket tail top_radius not matching\"); ", - " pm.expect(apiRspn.tail.bottom_radius).to.eql(pm.environment.get('bottom_radius'), \"rocket tail bottom_radius not matching\"); ", - " pm.expect(apiRspn.tail.length).to.eql(pm.environment.get('tail_length'), \"rocket tail length not matching\"); ", - " pm.expect(apiRspn.tail.position).to.eql(pm.environment.get('tail_position'), \"rocket tail position not matching\"); ", - " pm.expect(apiRspn.tail.radius).to.eql(pm.environment.get('tail_radius'), \"rocket tail radius not matching\"); ", - " });", - " pm.test(bdd + \" then response must contain a valid flight rocket parachutes\", function () {", - " pm.expect(apiRspn.parachutes.name).to.eql(pm.environment.get('parachutes_names'), \"rocket parachutes names not matching\"); ", - " pm.expect(apiRspn.parachutes.cd_s).to.eql(pm.environment.get('parachutes_cds'), \"rocket parachutes cd_s not matching\"); ", - " pm.expect(apiRspn.parachutes.sampling_rate).to.eql(pm.environment.get('parachutes_sampling_rate'), \"rocket parachutes sampling_rate not matching\"); ", - " pm.expect(apiRspn.parachutes.lag).to.eql(pm.environment.get('parachutes_lags'), \"rocket parachutes lags not matching\"); ", - " pm.expect(apiRspn.parachutes.noise).to.eql(pm.environment.get('parachutes_noises'), \"rocket parachutes noises not matching\");", - " pm.expect(apiRspn.parachutes.triggers).to.eql(pm.environment.get('parachutes_triggers'), \"rocket parachutes triggers not matching\");", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/rockets/{{rocket_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "rockets", - "{{rocket_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Read rocketpy Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "", - "//TEST", - "bdd = \"Given a valid rocketpy Rocket GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.jsonpickle_rocketpy_rocket).to.exist; ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/rockets/rocketpy/{{rocket_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "rockets", - "rocketpy", - "{{rocket_id}}" - ] - } - }, - "response": [] - }, - { - "name": "Simulate Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid rocketpy Rocket simulate GET request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.rocket_data).to.exist;", - " pm.expect(apiRspn.rocket_data.inertia_details).to.exist;", - " pm.expect(apiRspn.rocket_data.inertia_details.rocket_mass_without_propellant).to.exist;", - " pm.expect(apiRspn.rocket_data.inertia_details.rocket_mass_with_propellant).to.exist;", - " pm.expect(apiRspn.rocket_data.inertia_details.rocket_inertia_with_motor_without_propellant).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_geometrical_parameters).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_geometrical_parameters.rocket_maximum_radius).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_geometrical_parameters.rocket_frontal_area).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_geometrical_parameters.rocket_codm_nozzle_exit_distance).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_geometrical_parameters.rocket_codm_center_of_propellant_mass).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_geometrical_parameters.rocket_codm_loaded_center_of_mass).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_aerodynamics_quantities).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_aerodynamics_quantities.aerodynamics_lift_coefficient_derivatives).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_aerodynamics_quantities.aerodynamics_center_of_pressure).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_aerodynamics_quantities.distance_cop_to_codm).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_aerodynamics_quantities.initial_static_margin).to.exist;", - " pm.expect(apiRspn.rocket_data.rocket_aerodynamics_quantities.final_static_margin).to.exist;", - " pm.expect(apiRspn.rocket_data.parachute_data).to.exist;", - " pm.expect(apiRspn.rocket_data.parachute_data.parachute_details).to.exist;", - " pm.expect(apiRspn.rocket_data.parachute_data.parachute_ejection_system_refresh_rate).to.exist;", - " pm.expect(apiRspn.rocket_data.parachute_data.parachute_lag).to.exist;", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "{{endpoint}}/rockets/{{rocket_id}}/simulate", - "host": [ - "{{endpoint}}" - ], - "path": [ - "rockets", - "{{rocket_id}}", - "simulate" - ] - } - }, - "response": [] - }, - { - "name": "Update Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "var rocketRequest = JSON.parse(pm.request.body.raw);", - "", - "// save rocket parameters", - "pm.environment.set('rocket_id', apiRspn.new_rocket_id)", - "pm.environment.set('radius', rocketRequest.radius)", - "pm.environment.set('mass', rocketRequest.mass)", - "pm.environment.set('inertia', rocketRequest.inertia)", - "pm.environment.set('power_off_drag', rocketRequest.power_off_drag)", - "pm.environment.set('power_on_drag', rocketRequest.power_on_drag)", - "pm.environment.set('center_of_mass_without_motor', rocketRequest.center_of_mass_without_motor)", - "pm.environment.set('motor_position', rocketRequest.motor_position)", - "pm.environment.set('rail_buttons', rocketRequest.rail_buttons)", - "pm.environment.set('upper_button_position', rocketRequest.rail_buttons.upper_button_position)", - "pm.environment.set('lower_button_position', rocketRequest.rail_buttons.lower_button_position)", - "pm.environment.set('angular_position', rocketRequest.rail_buttons.angular_position)", - "pm.environment.set('rocket_coordinate_system_orientation', rocketRequest.coordinate_system_orientation)", - "", - "// rocket motor", - "pm.environment.set('burn_time', rocketRequest.motor.burn_time)", - "pm.environment.set('dry_mass', rocketRequest.motor.dry_mass)", - "pm.environment.set('dry_inertia', rocketRequest.motor.dry_inertia)", - "pm.environment.set('center_of_dry_mass_position', rocketRequest.motor.center_of_dry_mass_position)", - "pm.environment.set('grain_number', rocketRequest.motor.grain_number)", - "pm.environment.set('grain_density', rocketRequest.motor.grain_density)", - "pm.environment.set('grain_outer_radius', rocketRequest.motor.grain_outer_radius)", - "pm.environment.set('grain_initial_inner_radius', rocketRequest.motor.grain_initial_inner_radius)", - "pm.environment.set('grain_initial_height', rocketRequest.motor.grain_initial_height)", - "pm.environment.set('grains_center_of_mass_position', rocketRequest.motor.grains_center_of_mass_position)", - "pm.environment.set('grain_separation', rocketRequest.motor.grain_separation)", - "pm.environment.set('thrust_source', rocketRequest.motor.thrust_source)", - "pm.environment.set('nozzle_radius', rocketRequest.motor.nozzle_radius)", - "pm.environment.set('throat_radius', rocketRequest.motor.throat_radius)", - "pm.environment.set('interpolation_method', rocketRequest.motor.interpolation_method)", - "pm.environment.set('motor_coordinate_system_orientation', rocketRequest.motor.coordinate_system_orientation)", - "", - "// rocket nose", - "pm.environment.set('nose_length', rocketRequest.nose.length)", - "pm.environment.set('kind', rocketRequest.nose.kind)", - "pm.environment.set('nose_position', rocketRequest.nose.position)", - "pm.environment.set('base_radius', rocketRequest.nose.base_radius)", - "pm.environment.set('rocket_radius', rocketRequest.nose.rocket_radius)", - "", - "// rocket fins", - "pm.environment.set('n', rocketRequest.fins.n)", - "pm.environment.set('root_chord', rocketRequest.fins.root_chord)", - "pm.environment.set('tip_chord', rocketRequest.fins.tip_chord)", - "pm.environment.set('span', rocketRequest.fins.span)", - "pm.environment.set('fin_position', rocketRequest.fins.position)", - "pm.environment.set('cant_angle', rocketRequest.fins.cant_angle)", - "pm.environment.set('fin_radius', rocketRequest.fins.radius)", - "pm.environment.set('airfoil', rocketRequest.fins.airfoil)", - "", - "// rocket tail", - "pm.environment.set('top_radius', rocketRequest.tail.top_radius)", - "pm.environment.set('bottom_radius', rocketRequest.tail.bottom_radius)", - "pm.environment.set('tail_length', rocketRequest.tail.length)", - "pm.environment.set('tail_position', rocketRequest.tail.position)", - "pm.environment.set('tail_radius', rocketRequest.tail.radius)", - "", - "// rocket parachute", - "pm.environment.set('parachutes_names', rocketRequest.parachutes.name)", - "pm.environment.set('parachutes_cds', rocketRequest.parachutes.cd_s)", - "pm.environment.set('parachutes_sampling_rate', rocketRequest.parachutes.sampling_rate)", - "pm.environment.set('parachutes_lags', rocketRequest.parachutes.lag)", - "pm.environment.set('parachutes_noises', rocketRequest.parachutes.noise)", - "pm.environment.set('parachutes_triggers', rocketRequest.parachutes.triggers)", - "", - "//TEST", - "bdd = \"Given a valid Rocket PUT request is made to the API\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Rocket successfully updated\");", - " });", - " pm.test(bdd + \" then response must contain a valid rocket_id\", function () {", - " pm.expect(apiRspn.new_rocket_id).to.exist; ", - " });" - ], - "type": "text/javascript" - } - }, - { - "listen": "prerequest", - "script": { - "exec": [ - "" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "PUT", - "header": [], - "body": { - "mode": "raw", - "raw": "{\n \"rail_buttons\": {\n \"angular_position\": 47,\n \"lower_button_position\": 0.1,\n \"upper_button_position\": -0.2\n },\n \"motor\": {\n \"burn_time\": 5.9,\n \"center_of_dry_mass_position\": 0.317,\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\",\n \"dry_inertia\": [\n 0.125,\n 0.125,\n 0.002\n ],\n \"dry_mass\": 1.815,\n \"grain_density\": 1815,\n \"grain_initial_height\": 0.12,\n \"grain_initial_inner_radius\": 0.015,\n \"grain_number\": 5,\n \"grain_outer_radius\": 0.033,\n \"grain_separation\": 0.005,\n \"grains_center_of_mass_position\": -0.85704,\n \"interpolation_method\": \"linear\",\n \"nozzle_radius\": 0.033,\n \"tanks\": [\n {\n \"discretize\": 100,\n \"flux_time\": [\n 0,\n 8\n ],\n \"gas\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"gas_mass\": 0.1,\n \"gas_mass_flow_rate_in\": 0.1,\n \"gas_mass_flow_rate_out\": 0.1,\n \"geometry\": [\n [\n [\n 0,\n 5\n ],\n 1\n ],\n [\n [\n 5,\n 10\n ],\n 2\n ]\n ],\n \"initial_gas_mass\": 0.1,\n \"initial_liquid_mass\": 5,\n \"liquid\": {\n \"density\": 100,\n \"name\": \"FluidName\"\n },\n \"liquid_height\": 0.5,\n \"liquid_mass\": 5,\n \"liquid_mass_flow_rate_in\": 0.1,\n \"liquid_mass_flow_rate_out\": 0.1,\n \"name\": \"Tank\",\n \"position\": 1,\n \"tank_kind\": \"MassFlow\",\n \"ullage\": 0.1\n }\n ],\n \"throat_radius\": 0.011,\n \"thrust_source\": \"Cesaroni_M1670\"\n },\n \"nose\": {\n \"base_radius\": 0.0635,\n \"kind\": \"vonKarman\",\n \"length\": 0.55829,\n \"position\": 1.278,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"airfoil\": \"\",\n \"cant_angle\": 0,\n \"n\": 4,\n \"position\": -1.04956,\n \"radius\": 0.0635,\n \"root_chord\": 0.12,\n \"span\": 0.1,\n \"tip_chord\": 0.04\n },\n \"tail\": {\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635,\n \"top_radius\": 0.0635\n },\n \"parachutes\": {\n \"cd_s\": [\n 10,\n 1\n ],\n \"lag\": [\n 1.5,\n 1.5\n ],\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"noise\": [\n [\n 0,\n 8.3,\n 0.5\n ],\n [\n 0,\n 8.3,\n 0.5\n ]\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n },\n \"inertia\": [\n 6.321,\n 6.321,\n 0.0346\n ],\n \"center_of_mass_without_motor\": 0,\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"motor_position\": -1.255,\n \"power_off_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"power_on_drag\": [\n [\n 0.01,\n 0.333865758\n ],\n [\n 0.02,\n 0.394981721\n ],\n [\n 0.03,\n 0.407756063\n ]\n ],\n \"coordinate_system_orientation\": \"tail_to_nose\"\n}", - "options": { - "raw": { - "language": "json" - } - } - }, - "url": { - "raw": "{{endpoint}}/rockets/{{rocket_id}}/?rocket_option=Calisto&motor_kind=Hybrid", - "host": [ - "{{endpoint}}" - ], - "path": [ - "rockets", - "{{rocket_id}}", - "" - ], - "query": [ - { - "key": "rocket_option", - "value": "Calisto" - }, - { - "key": "motor_kind", - "value": "Hybrid" - } - ] - }, - "description": "This returns a `token` that you can use to retrieve information later on.\n\nWe have included a test to confirm if a token is returned. We have also added test scripts to copy the token to the `token` collection variable. This makes it easy for us to reuse this token in other requests in the collection." - }, - "response": [] - }, - { - "name": "Delete Rocket", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "//Fixes the issue of breaking the collection runner whenever an http 500 is received", - "if (responseCode.code == 500) {", - " pm.test(\"Given a request is made then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " return", - "}", - "", - "var apiRspn = pm.response.json();", - "//TEST", - "bdd = \"Given a valid Rocket DELETE request is made\";", - " pm.test(bdd + \" then response must return a 200 status code\", function () {", - " pm.expect(responseCode.code).to.eql(200);", - " });", - " pm.test(bdd + \" then response must contain a valid message\", function () {", - " pm.expect(apiRspn.message).to.eql(\"Rocket successfully deleted\", \"message not matching\");", - " pm.expect(apiRspn.deleted_rocket_id).to.eql(pm.environment.get('rocket_id'), \"rocket_id not matching\"); ", - " });" - ], - "type": "text/javascript" - } - } - ], - "request": { - "method": "DELETE", - "header": [], - "url": { - "raw": "{{endpoint}}/rockets/{{rocket_id}}", - "host": [ - "{{endpoint}}" - ], - "path": [ - "rockets", - "{{rocket_id}}" - ] - } - }, - "response": [] - } - ] - } - ], - "event": [ - { - "listen": "prerequest", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - }, - { - "listen": "test", - "script": { - "type": "text/javascript", - "exec": [ - "" - ] - } - } - ], - "variable": [ - { - "key": "env_id", - "value": "" - }, - { - "key": "latitude", - "value": "" - }, - { - "key": "longitude", - "value": "" - }, - { - "key": "elevation", - "value": "" - }, - { - "key": "standard_atmosphere", - "value": "" - }, - { - "key": "atmospheric_model_type", - "value": "" - }, - { - "key": "atmospheric_model_file", - "value": "" - }, - { - "key": "date", - "value": "" - }, - { - "key": "rail_length", - "value": "" - }, - { - "key": "inclination", - "value": "" - }, - { - "key": "heading", - "value": "" - }, - { - "key": "flight_id", - "value": "" - }, - { - "key": "radius", - "value": "" - }, - { - "key": "mass", - "value": "" - }, - { - "key": "inertia", - "value": "" - }, - { - "key": "power_off_drag", - "value": "" - }, - { - "key": "power_on_drag", - "value": "" - }, - { - "key": "center_of_mass_without_motor", - "value": "" - }, - { - "key": "motor_position", - "value": "" - }, - { - "key": "rail_buttons", - "value": "" - }, - { - "key": "upper_button_position", - "value": "" - }, - { - "key": "lower_button_position", - "value": "" - }, - { - "key": "angular_position", - "value": "" - }, - { - "key": "burn_time", - "value": "" - }, - { - "key": "dry_mass", - "value": "" - }, - { - "key": "dry_inertia", - "value": "" - }, - { - "key": "center_of_dry_mass_position", - "value": "" - }, - { - "key": "grain_number", - "value": "" - }, - { - "key": "grain_density", - "value": "" - }, - { - "key": "grain_outer_radius", - "value": "" - }, - { - "key": "grain_initial_inner_radius", - "value": "" - }, - { - "key": "grain_initial_height", - "value": "" - }, - { - "key": "grains_center_of_mass_position", - "value": "" - }, - { - "key": "grain_separation", - "value": "" - }, - { - "key": "thrust_source", - "value": "" - }, - { - "key": "nozzle_radius", - "value": "" - }, - { - "key": "throat_radius", - "value": "" - }, - { - "key": "interpolation_method", - "value": "" - }, - { - "key": "coordinate_system_orientation", - "value": "" - }, - { - "key": "length", - "value": "" - }, - { - "key": "kind", - "value": "" - }, - { - "key": "position", - "value": "" - }, - { - "key": "base_radius", - "value": "" - }, - { - "key": "rocket_radius", - "value": "" - }, - { - "key": "n", - "value": "" - }, - { - "key": "root_chord", - "value": "" - }, - { - "key": "tip_chord", - "value": "" - }, - { - "key": "span", - "value": "" - }, - { - "key": "cant_angle", - "value": "" - }, - { - "key": "airfoil", - "value": "" - }, - { - "key": "top_radius", - "value": "" - }, - { - "key": "bottom_radius", - "value": "" - }, - { - "key": "parachutes_names", - "value": "" - }, - { - "key": "parachutes_cds", - "value": "" - }, - { - "key": "parachutes_sampling_rate", - "value": "" - }, - { - "key": "parachutes_lags", - "value": "" - }, - { - "key": "parachutes_noises", - "value": "" - }, - { - "key": "parachutes_triggers", - "value": "" - }, - { - "key": "nose_length", - "value": "" - }, - { - "key": "nose_position", - "value": "" - }, - { - "key": "fin_position", - "value": "" - }, - { - "key": "fin_radius", - "value": "" - }, - { - "key": "tail_length", - "value": "" - }, - { - "key": "tail_position", - "value": "" - }, - { - "key": "tail_radius", - "value": "" - }, - { - "key": "rocket_coordinate_system_orientation", - "value": "" - }, - { - "key": "motor_coordinate_system_orientation", - "value": "" - }, - { - "key": "motor_id", - "value": "" - }, - { - "key": "rocket_id", - "value": "" - } - ] -} \ No newline at end of file