diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml
index ff9d51f..d276559 100644
--- a/.github/workflows/pylint.yml
+++ b/.github/workflows/pylint.yml
@@ -21,4 +21,4 @@ jobs:
pip install -r requirements.txt
- name: Analysing the code with pylint
run: |
- pylint -d C0200,C0301,C0114,R0903,C0115,W0246,R0914,C0209,E1121,C0103,C2801,R0801,E1101,R0911,C0116 $(git ls-files '*.py')
+ pylint -d C0200,C0301,C0114,R0903,C0115,W0246,R0914,C0209,E1121,C0103,C2801,R0801,E1101,E0401,E0611,R0911,C0116,W0212,W0719,W0601,W1203,W0123 $(git ls-files '*.py')
diff --git a/README.md b/README.md
index 1517f5c..c4774c2 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,8 @@
- Stores simulation input data in mongo-db
## Docker
-- touch .env
-- docker-compose up --build -d
+- set MONGODB_CONNECTION_STRING: `touch .env && echo MONGODB_CONNECTION_STRING="$ConnectionString" > .env`
+- run docker compose: `docker-compose up --build -d`
## Setup
- [Install python3](https://www.python.org/downloads/) 3.11.5 or above
@@ -34,19 +34,25 @@
│ │ ├── motor.py
│ │ └── rocket.py
│ │
-│ ├── models
-│ │ ├── aerosurfaces.py
+│ ├── routes
│ │ ├── environment.py
│ │ ├── flight.py
│ │ ├── motor.py
-│ │ ├── parachute.py
│ │ └── rocket.py
│ │
│ ├── repositories
+│ │ ├── repo.py
│ │ ├── environment.py
│ │ ├── flight.py
│ │ ├── motor.py
-│ │ ├── repo.py
+│ │ └── rocket.py
+│ │
+│ ├── models
+│ │ ├── aerosurfaces.py
+│ │ ├── environment.py
+│ │ ├── flight.py
+│ │ ├── motor.py
+│ │ ├── parachute.py
│ │ └── rocket.py
│ │
│ └── views
diff --git a/compose.yaml b/compose.yaml
index 7293a1d..b1340e9 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -1,11 +1,12 @@
-version: '1'
+version: '2'
services:
- fastapi-app:
+ api:
build:
context: .
dockerfile: Dockerfile
image: infinity-api:latest
+ container_name: infinity-api
ports:
- "3000:3000"
env_file:
diff --git a/lib/api.py b/lib/api.py
index 595a131..a0e91cc 100644
--- a/lib/api.py
+++ b/lib/api.py
@@ -2,7 +2,6 @@
This is the main API file for the RocketPy API.
"""
import logging
-from typing import Any, Dict
from fastapi import FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
@@ -10,20 +9,14 @@
from fastapi.openapi.utils import get_openapi
from fastapi.responses import RedirectResponse, JSONResponse
-from lib.views.flight import FlightSummary, FlightCreated, FlightUpdated, FlightDeleted, FlightPickle
-from lib.views.environment import EnvSummary, EnvCreated, EnvUpdated, EnvDeleted, EnvPickle
-from lib.views.rocket import RocketSummary, RocketCreated, RocketUpdated, RocketDeleted, RocketPickle
-from lib.views.motor import MotorSummary, MotorCreated, MotorUpdated, MotorDeleted, MotorPickle
-from lib.models.environment import Env
-from lib.models.flight import Flight
-from lib.models.rocket import Rocket, RocketOptions
-from lib.models.motor import Motor, MotorKinds, MotorEngines
-from lib.controllers.flight import FlightController
-from lib.controllers.environment import EnvController
-from lib.controllers.rocket import RocketController
-from lib.controllers.motor import MotorController
+from lib.routes import flight, environment, motor, rocket
-app = FastAPI(swagger_ui_parameters={"defaultModelsExpandDepth": 0, "syntaxHighlight.theme": "obsidian"})
+app = FastAPI(
+ swagger_ui_parameters={
+ "defaultModelsExpandDepth": 0,
+ "syntaxHighlight.theme": "obsidian",
+ }
+)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
@@ -31,37 +24,44 @@
allow_methods=["*"],
allow_headers=["*"],
)
+app.include_router(flight.router)
+app.include_router(environment.router)
+app.include_router(motor.router)
+app.include_router(rocket.router)
+
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="RocketPy Infinity-API",
- version="1.0.0 ALPHA",
+ version="1.0.0 BETA",
description=(
- "
RocketPy Infinity-API is a RESTful API for RocketPy, a rocket flight simulator.
"
- " "
- ""
- "Swagger UI "
- " "
- " "
- ""
- "ReDoc "
- " "
- "Create, manage, and simulate rocket flights, environments, rockets, and motors.
"
- "Currently, the API only supports SolidMotor (calisto as power_off/on_drag and Cesaroni as thrust_source) and TrapezoidalFins. We apologize for the limitation, but we are actively working to expand its capabilities soon.
"
- "Please report any bugs at GitHub Issues
"
+ "RocketPy Infinity-API is a RESTful Open API for RocketPy, a rocket flight simulator.
"
+ " "
+ ""
+ "Swagger UI "
+ " "
+ " "
+ ""
+ "ReDoc "
+ " "
+ "Create, manage, and simulate rocket flights, environments, rockets, and motors.
"
+ "Currently, the API only supports TrapezoidalFins. We apologize for the limitation, but we are actively working to expand its capabilities soon.
"
+ "Please report any bugs at GitHub Issues
"
),
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://drive.google.com/uc?id=1xKt6u5mI8x8ZuA5IZvIFDolg2_0iQUf-"
}
- x_swagger={"visible": False} # Hide the summary in Swagger UI
app.openapi_schema = openapi_schema
return app.openapi_schema
+
+
app.openapi = custom_openapi
+
# Main
@app.get("/", include_in_schema=False)
async def main_page():
@@ -70,560 +70,19 @@ async def main_page():
"""
return RedirectResponse(url="/redoc")
-# Flight routes
-@app.post("/flights/", tags=["FLIGHT"])
-async def create_flight(flight: Flight, rocket_option: RocketOptions, motor_kind: MotorKinds) -> "FlightCreated":
- """
- Creates a new flight
-
- ## Args
-
- ``` Flight object as JSON ```
-
- ## Returns
-
- HTTP 200 { "message": "Flight created successfully.", id: flight_id_hash }
-
- ## Raises
-
- HTTP 422 Unprocessable Entity: If API is unable to parse flight data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to create flight in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await FlightController(flight, rocket_option, motor_kind).create_flight()
-
-@app.get("/flights/{flight_id}", tags=["FLIGHT"])
-async def read_flight(flight_id: int) -> "Flight":
- """
- Reads a flight
-
- ## Args
-
- ``` flight_id: Flight ID hash ```
-
- ## Returns
-
- ``` Flight object as JSON ```
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
- """
- return await FlightController.get_flight(flight_id)
-
-@app.get("/flights/rocketpy/{flight_id}", tags=["FLIGHT"])
-async def read_rocketpy_flight(flight_id: int) -> "FlightPickle":
- """
- Reads a rocketpy flight object
-
- ## Args
-
- ``` flight_id: Flight ID hash. ```
-
- ## Returns
-
- ``` RocketPy flight object as jsonpickle string ```
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
- """
- return await FlightController.get_rocketpy_flight(flight_id)
-
-@app.put("/flights/{flight_id}/env", tags=["FLIGHT"])
-async def update_flight_env(flight_id: int, env: Env) -> "FlightUpdated":
- """
- Updates flight environment
-
- ## Args
-
- ```
- flight_id: Flight ID hash
- env: env object as JSON
- ```
-
- ## Returns
-
- HTTP 200 { "message": "Flight updated successfully.", new_flight_id: new_flight_id_hash }
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
-
- HTTP 422 Unprocessable Entity: If API is unable to parse env data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to update flight in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await FlightController.update_env(flight_id, env)
-
-@app.put("/flights/{flight_id}/rocket", tags=["FLIGHT"])
-async def update_flight_rocket(flight_id: int, rocket: Rocket, rocket_option: RocketOptions, motor_kind: MotorKinds) -> "FlightUpdated":
- """
- Updates flight rocket.
-
- ## Args
-
- ```
- flight_id: Flight ID hash.
- rocket: Rocket object as JSON
- ```
-
- ## Returns
-
- HTTP 200 { "message": "Flight updated successfully.", new_flight_id: new_flight_id_hash }
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
-
- HTTP 422 Unprocessable Entity: If API is unable to parse rocket data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to update flight in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await FlightController.update_rocket(flight_id, rocket, rocket_option, motor_kind)
-
-@app.put("/flights/{flight_id}", tags=["FLIGHT"])
-async def update_flight(flight_id: int, flight: Flight, rocket_option: RocketOptions, motor_kind: MotorKinds) -> "FlightUpdated":
- """
- Updates Flight object
-
- ## Args
- ```
- flight_id: Flight ID hash.
- flight: Flight object as JSON
- ```
-
- ## Returns
-
- HTTP 200 { "message": "Flight updated successfully.", new_flight_id: new_flight_id_hash }
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
-
- HTTP 422 Unprocessable Entity: If API is unable to parse flight data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to update flight in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await FlightController(flight, rocket_option, motor_kind).update_flight(flight_id)
-
-@app.delete("/flights/{flight_id}", tags=["FLIGHT"])
-async def delete_flight(flight_id: int) -> "FlightDeleted":
- """
- Deletes a flight
-
- ## Args
-
- ``` flight_id: Flight ID hash ```
-
- ## Returns
-
- HTTP 200 { "message": "Flight deleted successfully." }
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
- """
- return await FlightController.delete_flight(flight_id)
-
-@app.get("/flights/{flight_id}/simulate", tags=["FLIGHT"])
-async def simulate_flight(flight_id: int) -> "FlightSummary":
- """
- Simulates a flight
-
- ## Args
-
- ``` flight_id: Flight ID hash ```
-
- ## Returns
-
- ``` Flight summary as JSON ```
-
- ## Raises
-
- HTTP 404 Not Found: If flight_id does not exist at database.
- """
- return await FlightController.simulate(flight_id)
-
-# Environment routes
-@app.post("/environments/", tags=["ENVIRONMENT"])
-async def create_env(env: Env) -> "EnvCreated":
- """
- Creates a new environment
-
- ## Args
-
- ``` Env object as a JSON ```
-
- ## Returns
-
- HTTP 200 { "message": "Environment created successfully.", id: env_id_hash }
-
- ## Raises
-
- HTTP 422 Unprocessable Entity: If API is unable to parse env data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to create env in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await EnvController(env).create_env()
-
-@app.get("/environments/{env_id}", tags=["ENVIRONMENT"])
-async def read_env(env_id: int) -> "Env":
- """
- Reads an environment
-
- ## Args
-
- ``` env_id: Environment ID hash ```
-
- ## Returns
-
- ``` Env object as JSON. ```
-
- ## Raises
-
- HTTP 404 Not Found: If env_id does not exist at database.
- """
- return await EnvController.get_env(env_id)
-
-@app.put("/environments/{env_id}", tags=["ENVIRONMENT"])
-async def update_env(env_id: int, env: Env) -> "EnvUpdated":
- """
- Updates an environment
-
- ## Args
-
- ```
- env_id: Environment ID hash
- env: Env object as JSON
- ```
-
- ## Returns
-
- HTTP 200 { "message": "Environment updated successfully.", new_env_id: new_env_id_hash }
-
- ## Raises
-
- HTTP 404 Not Found: If env_id does not exist at database.
-
- HTTP 422 Unprocessable Entity: If API is unable to parse env data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to update env in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await EnvController(env).update_env(env_id)
-
-@app.delete("/environments/{env_id}", tags=["ENVIRONMENT"])
-async def delete_env(env_id: int) -> "EnvDeleted":
- """
- Deletes an environment
-
- ## Args
-
- ``` env_id: Environment ID hash ```
-
- ## Returns
-
- HTTP 200 { "message": "Environment deleted successfully." }
-
- ## Raises
-
- HTTP 404 Not Found: If env_id does not exist at database.
- """
- return await EnvController.delete_env(env_id)
-
-@app.get("/environments/rocketpy/{env_id}", tags=["ENVIRONMENT"])
-async def read_rocketpy_env(env_id: int) -> "EnvPickle":
- """
- Reads a rocketpy environment
-
- ## Args
-
- ``` env_id: Environment ID hash ```
-
- ## Returns
-
- ``` Rocketpy Environment object as JSONPickle string. ```
-
- ## Raises
- HTTP 404 Not Found: If env_id does not exist at database.
- """
- return await EnvController.get_rocketpy_env(env_id)
-
-@app.get("/environments/{env_id}/simulate", tags=["ENVIRONMENT"])
-async def simulate_env(env_id: int) -> "EnvSummary":
- """
- Simulates an environment
-
- ## Args
-
- ``` env_id: Env ID hash ```
-
- ## Returns
-
- ``` Env summary object containig simulation numbers and plots as JSON ```
-
- ## Raises
-
- HTTP 404 Not Found: If env_id does not exist at database.
- """
- return await EnvController.simulate(env_id)
-
-# Motor routes
-@app.post("/motors/", tags=["MOTOR"])
-async def create_motor(motor: Motor, motor_kind: MotorKinds) -> "MotorCreated":
- """
- Creates a new motor
-
- ## Args
-
- ``` Motor object as a JSON ```
-
- ## Returns
-
- HTTP 200 { "message": "Motor created successfully.", id: motor_id_hash }
-
- ## Raises
-
- HTTP 422 Unprocessable Entity: If API is unable to parse motor data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to create motor in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await MotorController(motor, motor_kind).create_motor()
-
-@app.get("/motors/{motor_id}", tags=["MOTOR"])
-async def read_motor(motor_id: int) -> "Motor":
- """
- Reads a motor
-
- ## Args
-
- ``` motor_id: Motor ID hash ```
-
- ## Returns
-
- Motor object as JSON.
-
- ## Raises
-
- HTTP 404 Not Found: If motor_id does not exist at database.
- """
- return await MotorController.get_motor(motor_id)
-
-@app.put("/motors/{motor_id}", tags=["MOTOR"])
-async def update_motor(motor_id: int, motor: Motor, motor_kind: MotorKinds) -> "MotorUpdated":
- """
- Updates a motor
-
- ## Args
-
- ```
- motor_id: Motor ID hash
- motor: Motor object as JSON
- ```
-
- ## Returns
-
- HTTP 200 { "message": "Motor updated successfully.", new_motor_id: new_motor_id_hash }
-
- ## Raises
-
- HTTP 404 Not Found: If motor_id does not exist at database.
-
- HTTP 422 Unprocessable Entity: If API is unable to parse motor data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to update motor in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await MotorController(motor, motor_kind).update_motor(motor_id)
-
-@app.delete("/motors/{motor_id}", tags=["MOTOR"])
-async def delete_motor(motor_id: int) -> "MotorDeleted":
- """
- Deletes a motor
-
- ## Args
-
- ``` motor_id: Motor ID hash ```
-
- ## Returns
-
- HTTP 200 { "message": "Motor deleted successfully." }
-
- ## Raises
-
- HTTP 404 Not Found: If motor_id does not exist at database.
- """
- return await MotorController.delete_motor(motor_id)
-
-@app.get("/motors/rocketpy/{motor_id}", tags=["MOTOR"])
-async def read_rocketpy_motor(motor_id: int) -> "MotorPickle":
- """
- Reads a rocketpy motor
-
- ## Args
-
- ``` motor_id: Motor ID hash ```
-
- ## Returns
-
- ``` Rocketpy Motor object as JSONPickle string ```
-
- ## Raises
- HTTP 404 Not Found: If motor_id does not exist at database.
- """
- return await MotorController.get_rocketpy_motor(motor_id)
-
-@app.get("/motors/{motor_id}/simulate", tags=["MOTOR"])
-async def simulate_motor(motor_id: int) -> "MotorSummary":
- """
- Simulates a motor
-
- ## Args
-
- ``` motor_id: Motor ID hash ```
-
- ## Returns
-
- ``` Motor summary as JSON ```
-
- ## Raises
-
- HTTP 404 Not Found: If motor_id does not exist at database.
- """
- return await MotorController.simulate(motor_id)
-
-# Rocket routes
-@app.post("/rockets/", tags=["ROCKET"])
-async def create_rocket(rocket: Rocket, rocket_option: RocketOptions, motor_kind: MotorKinds) -> "RocketCreated":
- """
- Creates a new rocket
-
- ## Args
-
- ``` Rocket object as a JSON ```
-
- ## Returns
-
- HTTP 200 { "message": "Rocket created successfully.", id: rocket_id_hash }
-
- ## Raises
-
- HTTP 422 Unprocessable Entity: If API is unable to parse rocket data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to create rocket in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await RocketController(rocket, rocket_option, motor_kind).create_rocket()
-
-@app.get("/rockets/{rocket_id}", tags=["ROCKET"])
-async def read_rocket(rocket_id: int) -> Rocket:
- """
- Reads a rocket
-
- ## Args
-
- ``` rocket_id: Rocket ID hash ```
-
- ## Returns
-
- ``` Rocket object as JSON ```
-
- ## Raises
-
- HTTP 404 Not Found: If rocket_id does not exist at database.
- """
- return await RocketController.get_rocket(rocket_id)
-
-@app.put("/rockets/{rocket_id}", tags=["ROCKET"])
-async def update_rocket(rocket_id: int, rocket: Rocket, rocket_option: RocketOptions, motor_kind: MotorKinds) -> "RocketUpdated":
- """
- Updates a rocket
-
- ## Args
-
- ```
- rocket_id: Rocket ID hash
- rocket: Rocket object as JSON
- ```
-
- ## Returns
-
- HTTP 200 { "message": "Rocket updated successfully.", new_rocket_id: new_rocket_id_hash }
-
- ## Raises
-
- HTTP 404 Not Found: If rocket_id does not exist at database.
-
- HTTP 422 Unprocessable Entity: If API is unable to parse rocket data, usually happens when some parameter is invalid, please attend to API docs request specifications.
-
- HTTP 500 Internal Server Error: If API is either unable to update rocket in mongoDB or valid parameter type/structure provided but content is breaking the API.
- """
- return await RocketController(rocket, rocket_option, motor_kind).update_rocket(rocket_id)
-
-@app.delete("/rockets/{rocket_id}", tags=["ROCKET"])
-async def delete_rocket(rocket_id: int) -> "RocketDeleted":
- """
- Deletes a rocket
-
- ## Args
-
- ``` rocket_id: Rocket ID hash ```
-
- ## Returns
-
- HTTP 200 { "message": "Rocket deleted successfully." }
-
- ## Raises
-
- HTTP 404 Not Found: If rocket_id does not exist at database.
- """
- return await RocketController.delete_rocket(rocket_id)
-
-@app.get("/rockets/rocketpy/{rocket_id}", tags=["ROCKET"])
-async def read_rocketpy_rocket(rocket_id: int) -> "RocketPickle":
- """
- Reads a rocketpy rocket
-
- ## Args
-
- ``` rocket_id: Rocket ID hash ```
-
- ## Returns
-
- ``` Rocketpy Rocket object as JSONPickle string ```
-
- ## Raises
-
- HTTP 404 Not Found: If rocket_id does not exist at database.
- """
- return await RocketController.get_rocketpy_rocket(rocket_id)
-
-@app.get("/rockets/{rocket_id}/simulate", tags=["ROCKET"])
-async def simulate_rocket(rocket_id: int) -> "RocketSummary":
- """
- Simulates a rocket
-
- ## Args
-
- ``` rocket_id: Rocket ID hash ```
-
- ## Returns
-
- HTTP 200 pydantic rocket summary object containig simulation numbers and plots as JSON.
-
- ## Raises
-
- HTTP 404 Not Found: If rocket_id does not exist at database.
- """
- return await RocketController.simulate(rocket_id)
# Additional routes
@app.get("/health", status_code=status.HTTP_200_OK, include_in_schema=False)
async def __perform_healthcheck():
- return {'health': 'Everything OK!'}
+ return {"health": "Everything OK!"}
+
-# Errors
+# Errors
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
- exc_str = f'{exc}'.replace('\n', ' ').replace(' ', ' ')
- logging.error(f"{request}: {exc_str}")
- content = {'status_code': 10422, 'message': exc_str, 'data': None}
- return JSONResponse(content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)
+ exc_str = f"{exc}".replace("\n", " ").replace(" ", " ")
+ logging.error(f"{request}: {exc_str}")
+ content = {"status_code": 10422, "message": exc_str, "data": None}
+ return JSONResponse(
+ content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY
+ )
diff --git a/lib/controllers/environment.py b/lib/controllers/environment.py
index 46fc5ac..90c4c6f 100644
--- a/lib/controllers/environment.py
+++ b/lib/controllers/environment.py
@@ -1,15 +1,24 @@
-from typing import Dict, Any, Union
+from typing import Union
import jsonpickle
from rocketpy.environment.environment import Environment
-from fastapi import Response, status
+from fastapi import HTTPException, status
from lib.models.environment import Env
from lib.repositories.environment import EnvRepository
-from lib.views.environment import EnvSummary, EnvData, EnvPlots, EnvCreated, EnvDeleted, EnvUpdated, EnvPickle
-
-class EnvController():
- """
+from lib.views.environment import (
+ EnvSummary,
+ EnvData,
+ EnvPlots,
+ EnvCreated,
+ EnvDeleted,
+ EnvUpdated,
+ EnvPickle,
+)
+
+
+class EnvController:
+ """
Controller for the Environment model.
Init Attributes:
@@ -18,35 +27,39 @@ class EnvController():
Enables:
- Create a rocketpy.Environment object from an Env model object.
"""
+
def __init__(self, env: Env):
rocketpy_env = Environment(
- latitude=env.latitude,
- longitude=env.longitude,
- elevation=env.elevation,
- date=env.date
- )
+ latitude=env.latitude,
+ longitude=env.longitude,
+ elevation=env.elevation,
+ date=env.date,
+ )
rocketpy_env.set_atmospheric_model(
- type=env.atmospheric_model_type,
- file=env.atmospheric_model_file
- )
+ type=env.atmospheric_model_type, file=env.atmospheric_model_file
+ )
self.rocketpy_env = rocketpy_env
self.env = env
- async def create_env(self) -> "Union[EnvCreated, Response]":
+ async def create_env(self) -> "Union[EnvCreated, HTTPException]":
"""
Create a env in the database.
Returns:
- Dict[str, str]: Environment id.
+ EnvCreated: Environment id.
"""
env = EnvRepository(environment=self.env)
successfully_created_env = await env.create_env()
- if successfully_created_env:
- return EnvCreated(env_id=str(env.env_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ if not successfully_created_env:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to create environment",
+ )
+
+ return EnvCreated(env_id=str(env.env_id))
@staticmethod
- async def get_env(env_id: int) -> "Union[Env, Response]":
+ async def get_env(env_id: int) -> "Union[Env, HTTPException]":
"""
Get a env from the database.
@@ -59,14 +72,16 @@ async def get_env(env_id: int) -> "Union[Env, Response]":
Raises:
HTTP 404 Not Found: If the env is not found in the database.
"""
- successfully_read_env = \
- await EnvRepository(env_id=env_id).get_env()
+ successfully_read_env = await EnvRepository(env_id=env_id).get_env()
if not successfully_read_env:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Environment not found"
+ )
+
return successfully_read_env
@staticmethod
- async def get_rocketpy_env(env_id: int) -> "Union[EnvPickle, Response]":
+ async def get_rocketpy_env(env_id: int) -> "Union[EnvPickle, HTTPException]":
"""
Get a rocketpy env object encoded as jsonpickle string from the database.
@@ -79,17 +94,21 @@ async def get_rocketpy_env(env_id: int) -> "Union[EnvPickle, Response]":
Raises:
HTTP 404 Not Found: If the env is not found in the database.
"""
- successfully_read_env = \
- await EnvRepository(env_id=env_id).get_env()
+ successfully_read_env = await EnvRepository(env_id=env_id).get_env()
if not successfully_read_env:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Environment not found"
+ )
- successfully_read_rocketpy_env = \
- EnvController( successfully_read_env ).rocketpy_env
+ successfully_read_rocketpy_env = EnvController(
+ successfully_read_env
+ ).rocketpy_env
- return EnvPickle(jsonpickle_rocketpy_env=jsonpickle.encode(successfully_read_rocketpy_env))
+ return EnvPickle(
+ jsonpickle_rocketpy_env=jsonpickle.encode(successfully_read_rocketpy_env)
+ )
- async def update_env(self, env_id: int) -> "Union[EnvUpdated, Response]":
+ async def update_env(self, env_id: int) -> "Union[EnvUpdated, HTTPException]":
"""
Update a env in the database.
@@ -97,25 +116,30 @@ async def update_env(self, env_id: int) -> "Union[EnvUpdated, Response]":
env_id (int): env id.
Returns:
- Dict[str, Any]: env id and message.
+ EnvUpdated: env id and message.
Raises:
HTTP 404 Not Found: If the env is not found in the database.
"""
- successfully_read_env = \
- await EnvRepository(env_id=env_id).get_env()
+ successfully_read_env = await EnvRepository(env_id=env_id).get_env()
if not successfully_read_env:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Environment not found"
+ )
- successfully_updated_env = \
- await EnvRepository(environment=self.env, env_id=env_id).update_env()
+ successfully_updated_env = await EnvRepository(
+ environment=self.env, env_id=env_id
+ ).update_env()
+ if not successfully_updated_env:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to update environment",
+ )
- if successfully_updated_env:
- return EnvUpdated(new_env_id=str(successfully_updated_env))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return EnvUpdated(new_env_id=str(successfully_updated_env))
@staticmethod
- async def delete_env(env_id: int) -> "Union[EnvDeleted, Response]":
+ async def delete_env(env_id: int) -> "Union[EnvDeleted, HTTPException]":
"""
Delete a env from the database.
@@ -123,24 +147,28 @@ async def delete_env(env_id: int) -> "Union[EnvDeleted, Response]":
env_id (int): Environment id.
Returns:
- Dict[str, str]: Environment id and message.
+ EnvDeleted: Environment id and message.
Raises:
HTTP 404 Not Found: If the env is not found in the database.
"""
- successfully_read_env = \
- await EnvRepository(env_id=env_id).get_env()
+ successfully_read_env = await EnvRepository(env_id=env_id).get_env()
if not successfully_read_env:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Environment not found"
+ )
+
+ successfully_deleted_env = await EnvRepository(env_id=env_id).delete_env()
+ if not successfully_deleted_env:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to delete environment",
+ )
- successfully_deleted_env = \
- await EnvRepository(env_id=env_id).delete_env()
- if successfully_deleted_env:
- return EnvDeleted(deleted_env_id = str(env_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return EnvDeleted(deleted_env_id=str(env_id))
@staticmethod
- async def simulate(env_id: int) -> "Union[EnvSummary, Response]":
+ async def simulate(env_id: int) -> "Union[EnvSummary, HTTPException]":
"""
Simulate a rocket environment.
@@ -153,14 +181,22 @@ async def simulate(env_id: int) -> "Union[EnvSummary, Response]":
Raises:
HTTP 404 Not Found: If the env does not exist in the database.
"""
- successfully_read_env = \
- await EnvRepository(env_id=env_id).get_env()
+ successfully_read_env = await EnvRepository(env_id=env_id).get_env()
if not successfully_read_env:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
-
- env = EnvController(successfully_read_env).rocketpy_env
- env_simulation_numbers = EnvData.parse_obj(env.all_info_returned())
- env_simulation_plots = EnvPlots.parse_obj(env.all_plot_info_returned())
-
- env_summary = EnvSummary( env_data=env_simulation_numbers, env_plots=env_simulation_plots )
- return env_summary
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Environment not found"
+ )
+
+ try:
+ env = EnvController(successfully_read_env).rocketpy_env
+ env_simulation_numbers = EnvData.parse_obj(env.all_info_returned())
+ env_simulation_plots = EnvPlots.parse_obj(env.all_plot_info_returned())
+ env_summary = EnvSummary(
+ env_data=env_simulation_numbers, env_plots=env_simulation_plots
+ )
+ return env_summary
+ except Exception as e:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail=f"Failed to simulate environment: {e}",
+ ) from e
diff --git a/lib/controllers/flight.py b/lib/controllers/flight.py
index 5c83a5d..0fd6eba 100644
--- a/lib/controllers/flight.py
+++ b/lib/controllers/flight.py
@@ -1,25 +1,38 @@
-from typing import Dict, Any, Union
-from fastapi import Response, status
+from typing import Union
+from fastapi import HTTPException, status
from rocketpy.simulation.flight import Flight as RocketpyFlight
import jsonpickle
from lib.models.rocket import Rocket, RocketOptions
-from lib.models.motor import Motor, MotorEngines, MotorKinds
+from lib.models.motor import MotorKinds
from lib.models.flight import Flight
from lib.models.environment import Env
-from lib.views.flight import (
- FlightSummary, SurfaceWindConditions, OutOfRailConditions, BurnoutConditions, ApogeeConditions, MaximumValues,
- InitialConditions, NumericalIntegrationSettings, ImpactConditions, EventsRegistered, LaunchRailConditions, FlightData,
- FlightCreated, FlightUpdated, FlightDeleted, FlightPickle
+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
-class FlightController():
+class FlightController:
"""
Controller for the Flight model.
@@ -36,8 +49,13 @@ class FlightController():
- Read a RocketpyFlight object from the database.
"""
- def __init__(self, flight: Flight, rocket_option: RocketOptions, motor_kind: MotorKinds):
- rocketpy_rocket = RocketController(flight.rocket, rocket_option=rocket_option, motor_kind=motor_kind).rocketpy_rocket
+
+ def __init__(
+ self, flight: Flight, rocket_option: RocketOptions, motor_kind: MotorKinds
+ ):
+ rocketpy_rocket = RocketController(
+ flight.rocket, rocket_option=rocket_option, motor_kind=motor_kind
+ ).rocketpy_rocket
rocketpy_env = EnvController(flight.environment).rocketpy_env
rocketpy_flight = RocketpyFlight(
@@ -45,7 +63,7 @@ def __init__(self, flight: Flight, rocket_option: RocketOptions, motor_kind: Mot
inclination=flight.inclination,
heading=flight.heading,
environment=rocketpy_env,
- rail_length=flight.rail_length
+ rail_length=flight.rail_length,
)
self.rocket_option = rocket_option
@@ -53,26 +71,28 @@ def __init__(self, flight: Flight, rocket_option: RocketOptions, motor_kind: Mot
self.rocketpy_flight = rocketpy_flight
self.flight = flight
- async def create_flight(self) -> "Union[FlightCreated, Response]":
+ async def create_flight(self) -> "Union[FlightCreated, HTTPException]":
"""
Create a flight in the database.
Returns:
- Dict[str, str]: Flight id.
+ FlightCreated: Flight id.
"""
flight = FlightRepository(flight=self.flight)
- successfully_created_flight = \
- await flight.create_flight(
- motor_kind = self.motor_kind,
- rocket_option = self.rocket_option
- )
+ successfully_created_flight = await flight.create_flight(
+ motor_kind=self.motor_kind, rocket_option=self.rocket_option
+ )
- if successfully_created_flight:
- return FlightCreated(flight_id=str(flight.flight_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ if not successfully_created_flight:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to create flight.",
+ )
+
+ return FlightCreated(flight_id=str(flight.flight_id))
@staticmethod
- async def get_flight(flight_id: int) -> "Union[Flight, Response]":
+ async def get_flight(flight_id: int) -> "Union[Flight, HTTPException]":
"""
Get a flight from the database.
@@ -85,14 +105,20 @@ async def get_flight(flight_id: int) -> "Union[Flight, Response]":
Raises:
HTTP 404 Not Found: If the flight is not found in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
+
return successfully_read_flight
@staticmethod
- async def get_rocketpy_flight(flight_id: int) -> "Union[FlightPickle, Response]":
+ async def get_rocketpy_flight(
+ flight_id: int,
+ ) -> "Union[FlightPickle, HTTPException]":
"""
Get a rocketpy flight object encoded as jsonpickle string from the database.
@@ -105,19 +131,29 @@ async def get_rocketpy_flight(flight_id: int) -> "Union[FlightPickle, Response]"
Raises:
HTTP 404 Not Found: If the flight is not found in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
- successfully_read_rocketpy_flight = \
- FlightController(flight = successfully_read_flight,
- rocket_option = RocketOptions(successfully_read_flight.rocket._rocket_option),
- motor_kind = MotorKinds(successfully_read_flight.rocket.motor._motor_kind)).rocketpy_flight
+ successfully_read_rocketpy_flight = FlightController(
+ flight=successfully_read_flight,
+ rocket_option=RocketOptions(successfully_read_flight.rocket._rocket_option),
+ motor_kind=MotorKinds(successfully_read_flight.rocket.motor._motor_kind),
+ ).rocketpy_flight
- return FlightPickle(jsonpickle_rocketpy_flight=jsonpickle.encode(successfully_read_rocketpy_flight))
+ return FlightPickle(
+ jsonpickle_rocketpy_flight=jsonpickle.encode(
+ successfully_read_rocketpy_flight
+ )
+ )
- async def update_flight(self, flight_id: int) -> "Union[FlightUpdated, Response]":
+ async def update_flight(
+ self, flight_id: int
+ ) -> "Union[FlightUpdated, HTTPException]":
"""
Update a flight in the database.
@@ -125,28 +161,34 @@ async def update_flight(self, flight_id: int) -> "Union[FlightUpdated, Response]
flight_id (int): Flight id.
Returns:
- Dict[str, Any]: Flight id and message.
+ FlightUpdated: Flight id and message.
Raises:
HTTP 404 Not Found: If the flight is not found in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
- successfully_updated_flight = \
- await FlightRepository(flight=self.flight, flight_id=flight_id).update_flight(
- rocket_option = self.rocket_option,
- motor_kind = self.motor_kind
- )
+ successfully_updated_flight = await FlightRepository(
+ flight=self.flight, flight_id=flight_id
+ ).update_flight(rocket_option=self.rocket_option, motor_kind=self.motor_kind)
+ if not successfully_updated_flight:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to update flight.",
+ )
- if successfully_updated_flight:
- return FlightUpdated(new_flight_id=str(successfully_updated_flight))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return FlightUpdated(new_flight_id=str(successfully_updated_flight))
@staticmethod
- async def update_env(flight_id: int, env: Env) -> "Union[FlightUpdated, Response]":
+ async def update_env(
+ flight_id: int, env: Env
+ ) -> "Union[FlightUpdated, HTTPException]":
"""
Update the environment of a flight in the database.
@@ -155,28 +197,37 @@ async def update_env(flight_id: int, env: Env) -> "Union[FlightUpdated, Response
env (models.Env): Environment model object.
Returns:
- Dict[str, Any]: Flight id and message.
+ FlightUpdated: Flight id and message.
Raises:
HTTP 404 Not Found: If the flight is not found in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
- flight = successfully_read_flight.dict()
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
+ flight = successfully_read_flight.dict()
flight["environment"] = env
flight = Flight(**flight)
- successfully_updated_flight = \
- await FlightRepository(flight=flight, flight_id=flight_id).update_flight()
+ successfully_updated_flight = await FlightRepository(
+ flight=flight, flight_id=flight_id
+ ).update_flight()
+ if not successfully_updated_flight:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to update flight.",
+ )
- if successfully_updated_flight:
- return FlightUpdated(new_flight_id=str(successfully_updated_flight))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return FlightUpdated(new_flight_id=str(successfully_updated_flight))
@staticmethod
- async def update_rocket(flight_id: int, rocket: Rocket, rocket_option, motor_kind) -> "Union[FlightUpdated, Response]":
+ async def update_rocket(
+ flight_id: int, rocket: Rocket, rocket_option, motor_kind
+ ) -> "Union[FlightUpdated, HTTPException]":
"""
Update the rocket of a flight in the database.
@@ -185,32 +236,38 @@ async def update_rocket(flight_id: int, rocket: Rocket, rocket_option, motor_kin
rocket (models.Rocket): Rocket model object.
Returns:
- Dict[str, Any]: Flight id and message.
+ FlightUpdated: Flight id and message.
Raises:
HTTP 404 Not Found: If the flight is not found in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
- flight = successfully_read_flight.dict()
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
+ flight = successfully_read_flight.dict()
updated_rocket = rocket.dict()
updated_rocket["rocket_option"] = rocket_option
updated_rocket["motor"]["motor_kind"] = motor_kind
flight["rocket"] = Rocket(**updated_rocket)
-
flight = Flight(**flight)
- successfully_updated_flight = \
- await FlightRepository(flight=flight, flight_id=flight_id).update_flight()
+ successfully_updated_flight = await FlightRepository(
+ flight=flight, flight_id=flight_id
+ ).update_flight()
+ if not successfully_updated_flight:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to update flight.",
+ )
- if successfully_updated_flight:
- return FlightUpdated(new_flight_id=str(successfully_updated_flight))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return FlightUpdated(new_flight_id=str(successfully_updated_flight))
@staticmethod
- async def delete_flight(flight_id: int) -> "Union[FlightDeleted, Response]":
+ async def delete_flight(flight_id: int) -> "Union[FlightDeleted, HTTPException]":
"""
Delete a flight from the database.
@@ -218,24 +275,32 @@ async def delete_flight(flight_id: int) -> "Union[FlightDeleted, Response]":
flight_id (int): Flight id.
Returns:
- Dict[str, str]: Flight id and message.
+ FlightDeleted: Flight id and message.
Raises:
HTTP 404 Not Found: If the flight is not found in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
+
+ successfully_deleted_flight = await FlightRepository(
+ flight_id=flight_id
+ ).delete_flight()
+ if not successfully_deleted_flight:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to delete flight.",
+ )
- successfully_deleted_flight = \
- await FlightRepository(flight_id=flight_id).delete_flight()
- if successfully_deleted_flight:
- return FlightDeleted(deleted_flight_id=str(flight_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return FlightDeleted(deleted_flight_id=str(flight_id))
@staticmethod
- async def simulate(flight_id: int) -> "Union[FlightSummary, Response]":
+ async def simulate(flight_id: int) -> "Union[FlightSummary, HTTPException]":
"""
Simulate a rocket flight.
@@ -248,160 +313,247 @@ async def simulate(flight_id: int) -> "Union[FlightSummary, Response]":
Raises:
HTTP 404 Not Found: If the flight does not exist in the database.
"""
- successfully_read_flight = \
- await FlightRepository(flight_id=flight_id).get_flight()
+ successfully_read_flight = await FlightRepository(
+ flight_id=flight_id
+ ).get_flight()
if not successfully_read_flight:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
-
- flight = FlightController(flight = successfully_read_flight,
- rocket_option = RocketOptions(successfully_read_flight.rocket._rocket_option),
- motor_kind = MotorKinds(successfully_read_flight.rocket.motor._motor_kind)).rocketpy_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)
- )
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Flight not found."
+ )
- _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)
- )
+ try:
+ flight = FlightController(
+ flight=successfully_read_flight,
+ rocket_option=RocketOptions(
+ successfully_read_flight.rocket._rocket_option
+ ),
+ motor_kind=MotorKinds(
+ successfully_read_flight.rocket.motor._motor_kind
+ ),
+ ).rocketpy_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)
+ ),
+ )
- _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))
- )
+ _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)
+ ),
+ )
- _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
+ _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),
)
- ** 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)
- )
+ _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
+ ),
+ )
- _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)
- )
+ _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)
+ ),
+ )
- 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)
+ _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)
+ ),
)
- 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])
+
+ _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
+ ),
)
- if len(flight.parachute_events) == 0:
- _events_registered = EventsRegistered(
- events_trace = "No parachute event registered"
+ _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
+ ),
)
- 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
- )
+
+ 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
+ ),
)
- events[name].append(
- name
- + " Parachute Inflated at Height of: {:.3f} m (AGL)".format(
- altitude - flight.env.elevation
- )
+ 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]),
)
- _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 )
+ 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,
+ )
- return flight_summary
+ flight_summary = FlightSummary(flight_data=_flight_data)
+ return flight_summary
+ except Exception as e:
+ raise HTTPException(
+ status_code=500, detail=f"Failed to simulate flight: {e}"
+ ) from e
diff --git a/lib/controllers/motor.py b/lib/controllers/motor.py
index 24393f9..a01eafb 100644
--- a/lib/controllers/motor.py
+++ b/lib/controllers/motor.py
@@ -1,16 +1,23 @@
-from fastapi import Response, status
-from typing import Any, Dict, Union
+from typing import Union
+from fastapi import HTTPException, status
from rocketpy.motors.solid_motor import SolidMotor
from rocketpy.motors.liquid_motor import LiquidMotor
from rocketpy.motors.hybrid_motor import HybridMotor
-from rocketpy import TankGeometry, Fluid
import jsonpickle
from lib.models.motor import Motor, MotorKinds
from lib.repositories.motor import MotorRepository
-from lib.views.motor import MotorSummary, MotorData, MotorCreated, MotorUpdated, MotorDeleted, MotorPickle
+from lib.views.motor import (
+ MotorSummary,
+ MotorData,
+ MotorCreated,
+ MotorUpdated,
+ MotorDeleted,
+ MotorPickle,
+)
-class MotorController():
+
+class MotorController:
"""
Controller for the motor model.
@@ -20,6 +27,7 @@ class MotorController():
Enables:
- Create a rocketpy.Motor object from a Motor model object.
"""
+
def __init__(self, motor: Motor, motor_kind):
self.guard(motor, motor_kind)
motor_core = {
@@ -28,14 +36,15 @@ def __init__(self, motor: Motor, motor_kind):
"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
+ "center_of_dry_mass_position": motor.center_of_dry_mass_position,
}
match motor_kind:
case MotorKinds.liquid:
rocketpy_motor = LiquidMotor(**motor_core)
case MotorKinds.hybrid:
- rocketpy_motor = HybridMotor(**motor_core,
+ rocketpy_motor = HybridMotor(
+ **motor_core,
throat_radius=motor.throat_radius,
grain_number=motor.grain_number,
grain_density=motor.grain_density,
@@ -43,10 +52,11 @@ def __init__(self, motor: Motor, motor_kind):
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
+ grains_center_of_mass_position=motor.grains_center_of_mass_position,
)
case _:
- rocketpy_motor = SolidMotor(**motor_core,
+ rocketpy_motor = SolidMotor(
+ **motor_core,
grain_number=motor.grain_number,
grain_density=motor.grain_density,
grain_outer_radius=motor.grain_outer_radius,
@@ -55,36 +65,45 @@ def __init__(self, motor: Motor, motor_kind):
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
+ interpolation_method=motor.interpolation_method,
)
if motor_kind != MotorKinds.solid:
for tank in motor.tanks:
rocketpy_motor.add_tank(tank.tank, tank.position)
-
- self.motor_kind = motor_kind #tracks motor kind state
+
+ self.motor_kind = motor_kind # tracks motor kind state
self.rocketpy_motor = rocketpy_motor
self.motor = motor
-
+
def guard(self, motor: Motor, motor_kind):
if motor_kind != MotorKinds.solid and motor.tanks is None:
- return Response(status_code=status.HTTP_400_BAD_REQUEST, content="Tanks must be provided for liquid and hybrid motors.")
+ raise HTTPException(
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
+ detail="Tanks must be provided for liquid and hybrid motors.",
+ )
- async def create_motor(self) -> "Union[MotorCreated, Response]":
+ async def create_motor(self) -> "Union[MotorCreated, HTTPException]":
"""
Create a motor in the database.
Returns:
- Dict[str, str]: motor id.
+ MotorCreated: motor id.
"""
motor = MotorRepository(motor=self.motor)
- successfully_created_motor = await motor.create_motor(motor_kind = self.motor_kind)
- if successfully_created_motor:
- return MotorCreated(motor_id=str(motor.motor_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ successfully_created_motor = await motor.create_motor(
+ motor_kind=self.motor_kind
+ )
+ if not successfully_created_motor:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to create motor.",
+ )
+
+ return MotorCreated(motor_id=str(motor.motor_id))
@staticmethod
- async def get_motor(motor_id: int) -> "Union[Motor, Response]":
+ async def get_motor(motor_id: int) -> "Union[Motor, HTTPException]":
"""
Get a motor from the database.
@@ -97,14 +116,16 @@ async def get_motor(motor_id: int) -> "Union[Motor, Response]":
Raises:
HTTP 404 Not Found: If the motor is not found in the database.
"""
- successfully_read_motor = \
- await MotorRepository(motor_id=motor_id).get_motor()
+ successfully_read_motor = await MotorRepository(motor_id=motor_id).get_motor()
if not successfully_read_motor:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Motor not found."
+ )
+
return successfully_read_motor
@staticmethod
- async def get_rocketpy_motor(motor_id: int) -> "Union[MotorPickle, Response]":
+ async def get_rocketpy_motor(motor_id: int) -> "Union[MotorPickle, HTTPException]":
"""
Get a rocketpy motor object encoded as jsonpickle string from the database.
@@ -117,18 +138,24 @@ async def get_rocketpy_motor(motor_id: int) -> "Union[MotorPickle, Response]":
Raises:
HTTP 404 Not Found: If the motor is not found in the database.
"""
- successfully_read_motor = \
- await MotorRepository(motor_id=motor_id).get_motor()
+ successfully_read_motor = await MotorRepository(motor_id=motor_id).get_motor()
if not successfully_read_motor:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Motor not found."
+ )
- successfully_read_rocketpy_motor = \
- MotorController(motor = successfully_read_motor,
- motor_kind = MotorKinds(successfully_read_motor._motor_kind)).rocketpy_motor
+ successfully_read_rocketpy_motor = MotorController(
+ motor=successfully_read_motor,
+ motor_kind=MotorKinds(successfully_read_motor._motor_kind),
+ ).rocketpy_motor
- return MotorPickle(jsonpickle_rocketpy_motor=jsonpickle.encode(successfully_read_rocketpy_motor))
+ return MotorPickle(
+ jsonpickle_rocketpy_motor=jsonpickle.encode(
+ successfully_read_rocketpy_motor
+ )
+ )
- async def update_motor(self, motor_id: int) -> "Union[MotorUpdated, Response]":
+ async def update_motor(self, motor_id: int) -> "Union[MotorUpdated, HTTPException]":
"""
Update a motor in the database.
@@ -136,25 +163,30 @@ async def update_motor(self, motor_id: int) -> "Union[MotorUpdated, Response]":
motor_id (int): Motor id.
Returns:
- Dict[str, Any]: motor id and message.
+ MotorUpdated: motor id and message.
Raises:
HTTP 404 Not Found: If the motor is not found in the database.
"""
- successfully_read_motor = \
- await MotorRepository(motor_id=motor_id).get_motor()
+ successfully_read_motor = await MotorRepository(motor_id=motor_id).get_motor()
if not successfully_read_motor:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Motor not found."
+ )
- successfully_updated_motor = \
- await MotorRepository(motor=self.motor, motor_id=motor_id).update_motor(motor_kind = self.motor_kind)
+ successfully_updated_motor = await MotorRepository(
+ motor=self.motor, motor_id=motor_id
+ ).update_motor(motor_kind=self.motor_kind)
+ if not successfully_updated_motor:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to update motor.",
+ )
- if successfully_updated_motor:
- return MotorUpdated(new_motor_id=str(successfully_updated_motor))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return MotorUpdated(new_motor_id=str(successfully_updated_motor))
@staticmethod
- async def delete_motor(motor_id: int) -> "Union[MotorDeleted, Response]":
+ async def delete_motor(motor_id: int) -> "Union[MotorDeleted, HTTPException]":
"""
Delete a motor from the database.
@@ -162,24 +194,30 @@ async def delete_motor(motor_id: int) -> "Union[MotorDeleted, Response]":
motor_id (int): motor id.
Returns:
- Dict[str, str]: motor id and message.
+ MotorDeleted: motor id and message.
Raises:
HTTP 404 Not Found: If the motor is not found in the database.
"""
- successfully_read_motor = \
- await MotorRepository(motor_id=motor_id).get_motor()
+ successfully_read_motor = await MotorRepository(motor_id=motor_id).get_motor()
if not successfully_read_motor:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Motor not found."
+ )
- successfully_deleted_motor = \
- await MotorRepository(motor_id=motor_id).delete_motor()
- if successfully_deleted_motor:
- return MotorDeleted(deleted_motor_id=str(motor_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ successfully_deleted_motor = await MotorRepository(
+ motor_id=motor_id
+ ).delete_motor()
+ if not successfully_deleted_motor:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to delete motor.",
+ )
+
+ return MotorDeleted(deleted_motor_id=str(motor_id))
@staticmethod
- async def simulate(motor_id: int) -> "Union[MotorSummary, Response]":
+ async def simulate(motor_id: int) -> "Union[MotorSummary, HTTPException]":
"""
Simulate a rocketpy motor.
@@ -192,39 +230,48 @@ async def simulate(motor_id: int) -> "Union[MotorSummary, Response]":
Raises:
HTTP 404 Not Found: If the motor does not exist in the database.
"""
- successfully_read_motor = \
- await MotorRepository(motor_id=motor_id).get_motor()
+ successfully_read_motor = await MotorRepository(motor_id=motor_id).get_motor()
if not successfully_read_motor:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
-
- motor = MotorController(motor=successfully_read_motor,
- motor_kind = MotorKinds(successfully_read_motor._motor_kind)).rocketpy_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)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Motor not found."
)
- + " 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 )
- return motor_summary
+ try:
+ motor = MotorController(
+ motor=successfully_read_motor,
+ motor_kind=MotorKinds(successfully_read_motor._motor_kind),
+ ).rocketpy_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 )
+ return motor_summary
+ except Exception as e:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail=f"Failed to simulate motor: {e}",
+ ) from e
diff --git a/lib/controllers/rocket.py b/lib/controllers/rocket.py
index 04b502f..1885709 100644
--- a/lib/controllers/rocket.py
+++ b/lib/controllers/rocket.py
@@ -1,9 +1,10 @@
-from typing import Dict, Any, Union
-import jsonpickle
+from typing import Union
import ast
+import jsonpickle
+
+from fastapi import HTTPException, status
-from fastapi import Response, status
-#from inspect import getsourcelines
+# from inspect import getsourcelines
from rocketpy.rocket.parachute import Parachute as RocketpyParachute
from rocketpy.rocket.rocket import Rocket as RocketpyRocket
@@ -13,13 +14,25 @@
from lib.controllers.motor import MotorController
from lib.models.rocket import Rocket, RocketOptions
-from lib.models.motor import MotorKinds
+from lib.models.motor import MotorKinds
from lib.models.aerosurfaces import NoseCone, TrapezoidalFins, Tail
from lib.models.parachute import Parachute
from lib.repositories.rocket import RocketRepository
-from lib.views.rocket import InertiaDetails, RocketGeometricalParameters, RocketAerodynamicsQuantities, ParachuteData, RocketData, RocketSummary, RocketCreated, RocketUpdated, RocketDeleted, RocketPickle
-
-class RocketController():
+from lib.views.rocket import (
+ InertiaDetails,
+ RocketGeometricalParameters,
+ RocketAerodynamicsQuantities,
+ ParachuteData,
+ RocketData,
+ RocketSummary,
+ RocketCreated,
+ RocketUpdated,
+ RocketDeleted,
+ RocketPickle,
+)
+
+
+class RocketController:
"""
Controller for the Rocket model.
@@ -29,56 +42,65 @@ class RocketController():
Enables:
create a RocketpyRocket object from a Rocket model object.
"""
+
def __init__(self, rocket: Rocket, rocket_option, motor_kind):
rocketpy_rocket = RocketpyRocket(
- radius=rocket.radius,
- mass=rocket.mass,
- inertia=rocket.inertia,
- power_off_drag=f"lib/data/{rocket_option.value.lower()}/powerOffDragCurve.csv",
- power_on_drag=f"lib/data/{rocket_option.value.lower()}/powerOnDragCurve.csv",
- center_of_mass_without_motor=rocket.center_of_mass_without_motor,
- coordinate_system_orientation=rocket.coordinate_system_orientation
+ radius=rocket.radius,
+ mass=rocket.mass,
+ inertia=rocket.inertia,
+ power_off_drag=f"lib/data/{rocket_option.value.lower()}/powerOffDragCurve.csv",
+ power_on_drag=f"lib/data/{rocket_option.value.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(rocket.motor, motor_kind).rocketpy_motor,
- rocket.motor_position)
+ # 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(rocket.motor, motor_kind).rocketpy_motor,
+ rocket.motor_position,
+ )
- #NoseCone
+ # NoseCone
nose = self.NoseConeController(rocket.nose).rocketpy_nose
rocketpy_rocket.aerodynamic_surfaces.add(nose, nose.position)
rocketpy_rocket.evaluate_static_margin()
- #FinSet
- #TBD: re-write this to match overall fins not only TrapezoidalFins
+ # FinSet
+ # TBD: re-write this to match overall fins not only TrapezoidalFins
finset = self.TrapezoidalFinsController(rocket.fins).rocketpy_finset
rocketpy_rocket.aerodynamic_surfaces.add(finset, finset.position)
rocketpy_rocket.evaluate_static_margin()
- #Tail
+ # Tail
tail = self.TailController(rocket.tail).rocketpy_tail
rocketpy_rocket.aerodynamic_surfaces.add(tail, tail.position)
rocketpy_rocket.evaluate_static_margin()
- #Parachutes
+ # Parachutes
for p in range(len(rocket.parachutes)):
parachute_trigger = rocket.parachutes[p].triggers[0]
if self.ParachuteController.check_trigger(parachute_trigger):
- rocket.parachutes[p].triggers[0] = compile(parachute_trigger, '', 'eval')
- parachute = self.ParachuteController(rocket.parachutes, p).rocketpy_parachute
+ rocket.parachutes[p].triggers[0] = compile(
+ parachute_trigger, "", "eval"
+ )
+ parachute = self.ParachuteController(
+ rocket.parachutes, p
+ ).rocketpy_parachute
rocketpy_rocket.parachutes.append(parachute)
else:
print("Parachute trigger not valid. Skipping parachute.")
continue
- self.rocket_option = rocket_option #tracks rocket option state
+ self.rocket_option = rocket_option # tracks rocket option state
self.rocketpy_rocket = rocketpy_rocket
self.rocket = rocket
- class NoseConeController():
+ class NoseConeController:
"""
Controller for the NoseCone model.
@@ -88,18 +110,19 @@ class NoseConeController():
Enables:
- Create a rocketpy.AeroSurface.NoseCone object from a NoseCone model object.
"""
+
def __init__(self, nose: NoseCone):
rocketpy_nose = RocketpyNoseCone(
- length=nose.length,
- kind=nose.kind,
- base_radius=nose.base_radius,
- rocket_radius=nose.rocket_radius
+ length=nose.length,
+ kind=nose.kind,
+ base_radius=nose.base_radius,
+ rocket_radius=nose.rocket_radius,
)
rocketpy_nose.position = nose.position
self.rocketpy_nose = rocketpy_nose
self.nose = nose
- class TrapezoidalFinsController():
+ class TrapezoidalFinsController:
"""
Controller for the TrapezoidalFins model.
@@ -109,21 +132,22 @@ class TrapezoidalFinsController():
Enables:
- Create a rocketpy.AeroSurface.TrapezoidalFins object from a TrapezoidalFins model object.
"""
+
def __init__(self, trapezoidal_fins: TrapezoidalFins):
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
+ 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
self.rocketpy_finset = rocketpy_finset
self.trapezoidal_fins = trapezoidal_fins
- class TailController():
+ class TailController:
"""
Controller for the Tail model.
@@ -133,18 +157,19 @@ class TailController():
Enables:
- Create a rocketpy.AeroSurface.Tail object from a Tail model object.
"""
+
def __init__(self, tail: Tail):
rocketpy_tail = RocketpyTail(
- top_radius=tail.top_radius,
- bottom_radius=tail.bottom_radius,
- length=tail.length,
- rocket_radius=tail.radius
+ top_radius=tail.top_radius,
+ bottom_radius=tail.bottom_radius,
+ length=tail.length,
+ rocket_radius=tail.radius,
)
rocketpy_tail.position = tail.position
self.rocketpy_tail = rocketpy_tail
self.tail = tail
- class ParachuteController():
+ class ParachuteController:
"""
Controller for the Parachute model.
@@ -154,14 +179,15 @@ class ParachuteController():
Enables:
- Create a RocketpyParachute.Parachute object from a Parachute model object.
"""
+
def __init__(self, parachute: Parachute, p: int):
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]
+ 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],
)
self.rocketpy_parachute = rocketpy_parachute
self.parachute = parachute
@@ -180,7 +206,7 @@ def check_trigger(expression: str) -> bool:
# Parsing the expression into an AST
try:
- parsed_expression = ast.parse(expression, mode='eval')
+ parsed_expression = ast.parse(expression, mode="eval")
except SyntaxError:
print("Invalid syntax.")
return False
@@ -189,8 +215,10 @@ def check_trigger(expression: str) -> bool:
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":
+ if (
+ isinstance(parsed_expression.body, ast.Name)
+ and parsed_expression.body.id == "apogee"
+ ):
global apogee
apogee = "apogee"
return True
@@ -225,21 +253,27 @@ def check_trigger(expression: str) -> bool:
return False
return True
- async def create_rocket(self) -> "Union[RocketCreated, Response]":
+ async def create_rocket(self) -> "Union[RocketCreated, HTTPException]":
"""
Create a rocket in the database.
Returns:
- Dict[str, str]: Rocket id.
+ RocketCreated: Rocket id.
"""
rocket = RocketRepository(rocket=self.rocket)
- successfully_created_rocket = await rocket.create_rocket(rocket_option = self.rocket_option)
- if successfully_created_rocket:
- return RocketCreated(rocket_id=str(rocket.rocket_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ successfully_created_rocket = await rocket.create_rocket(
+ rocket_option=self.rocket_option
+ )
+ if not successfully_created_rocket:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to create rocket.",
+ )
+
+ return RocketCreated(rocket_id=str(rocket.rocket_id))
@staticmethod
- async def get_rocket(rocket_id: int) -> "Union[Rocket, Response]":
+ async def get_rocket(rocket_id: int) -> "Union[Rocket, HTTPException]":
"""
Get a rocket from the database.
@@ -252,14 +286,20 @@ async def get_rocket(rocket_id: int) -> "Union[Rocket, Response]":
Raises:
HTTP 404 Not Found: If the rocket is not found in the database.
"""
- successfully_read_rocket = \
- await RocketRepository(rocket_id=rocket_id).get_rocket()
+ successfully_read_rocket = await RocketRepository(
+ rocket_id=rocket_id
+ ).get_rocket()
if not successfully_read_rocket:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Rocket not found."
+ )
+
return successfully_read_rocket
@staticmethod
- async def get_rocketpy_rocket(rocket_id: int) -> "Union[RocketPickle, Response]":
+ async def get_rocketpy_rocket(
+ rocket_id: int,
+ ) -> "Union[RocketPickle, HTTPException]":
"""
Get a rocketpy rocket object encoded as jsonpickle string from the database.
@@ -272,19 +312,29 @@ async def get_rocketpy_rocket(rocket_id: int) -> "Union[RocketPickle, Response]"
Raises:
HTTP 404 Not Found: If the rocket is not found in the database.
"""
- successfully_read_rocket = \
- await RocketRepository(rocket_id=rocket_id).get_rocket()
+ successfully_read_rocket = await RocketRepository(
+ rocket_id=rocket_id
+ ).get_rocket()
if not successfully_read_rocket:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Rocket not found."
+ )
- successfully_read_rocketpy_rocket = \
- RocketController(rocket=successfully_read_rocket,
- rocket_option = RocketOptions(successfully_read_rocket._rocket_option),
- motor_kind = MotorKinds(successfully_read_rocket.motor._motor_kind)).rocketpy_rocket
+ successfully_read_rocketpy_rocket = RocketController(
+ rocket=successfully_read_rocket,
+ rocket_option=RocketOptions(successfully_read_rocket._rocket_option),
+ motor_kind=MotorKinds(successfully_read_rocket.motor._motor_kind),
+ ).rocketpy_rocket
- return RocketPickle(jsonpickle_rocketpy_rocket=jsonpickle.encode(successfully_read_rocketpy_rocket))
+ return RocketPickle(
+ jsonpickle_rocketpy_rocket=jsonpickle.encode(
+ successfully_read_rocketpy_rocket
+ )
+ )
- async def update_rocket(self, rocket_id: int) -> "Union[RocketUpdated, Response]":
+ async def update_rocket(
+ self, rocket_id: int
+ ) -> "Union[RocketUpdated, HTTPException]":
"""
Update a rocket in the database.
@@ -292,25 +342,32 @@ async def update_rocket(self, rocket_id: int) -> "Union[RocketUpdated, Response]
rocket_id (int): rocket id.
Returns:
- Dict[str, Any]: rocket id and message.
+ RocketUpdated: rocket id and message.
Raises:
HTTP 404 Not Found: If the rocket is not found in the database.
"""
- successfully_read_rocket = \
- await RocketRepository(rocket_id=rocket_id).get_rocket()
+ successfully_read_rocket = await RocketRepository(
+ rocket_id=rocket_id
+ ).get_rocket()
if not successfully_read_rocket:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Rocket not found."
+ )
- successfully_updated_rocket = \
- await RocketRepository(rocket=self.rocket, rocket_id=rocket_id).update_rocket(rocket_option = self.rocket_option)
+ successfully_updated_rocket = await RocketRepository(
+ rocket=self.rocket, rocket_id=rocket_id
+ ).update_rocket(rocket_option=self.rocket_option)
+ if not successfully_updated_rocket:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to update rocket.",
+ )
- if successfully_updated_rocket:
- return RocketUpdated(new_rocket_id=str(successfully_updated_rocket))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return RocketUpdated(new_rocket_id=str(successfully_updated_rocket))
@staticmethod
- async def delete_rocket(rocket_id: int) -> "Union[RocketDeleted, Response]":
+ async def delete_rocket(rocket_id: int) -> "Union[RocketDeleted, HTTPException]":
"""
Delete a rocket from the database.
@@ -318,24 +375,32 @@ async def delete_rocket(rocket_id: int) -> "Union[RocketDeleted, Response]":
rocket_id (int): Rocket id.
Returns:
- Dict[str, str]: Rocket id and message.
+ RocketDeleted: Rocket id and message.
Raises:
HTTP 404 Not Found: If the rocket is not found in the database.
"""
- successfully_read_rocket = \
- await RocketRepository(rocket_id=rocket_id).get_rocket()
+ successfully_read_rocket = await RocketRepository(
+ rocket_id=rocket_id
+ ).get_rocket()
if not successfully_read_rocket:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Rocket not found."
+ )
+
+ successfully_deleted_rocket = await RocketRepository(
+ rocket_id=rocket_id
+ ).delete_rocket()
+ if not successfully_deleted_rocket:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail="Failed to delete rocket.",
+ )
- successfully_deleted_rocket = \
- await RocketRepository(rocket_id=rocket_id).delete_rocket()
- if successfully_deleted_rocket:
- return RocketDeleted(deleted_rocket_id=str(rocket_id))
- return Response(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
+ return RocketDeleted(deleted_rocket_id=str(rocket_id))
@staticmethod
- async def simulate(rocket_id: int) -> "Union[RocketSummary, Response]":
+ async def simulate(rocket_id: int) -> "Union[RocketSummary, HTTPException]":
"""
Simulate a rocket rocket.
@@ -348,112 +413,148 @@ async def simulate(rocket_id: int) -> "Union[RocketSummary, Response]":
Raises:
HTTP 404 Not Found: If the rocket does not exist in the database.
"""
- successfully_read_rocket = \
- await RocketRepository(rocket_id=rocket_id).get_rocket()
+ successfully_read_rocket = await RocketRepository(
+ rocket_id=rocket_id
+ ).get_rocket()
if not successfully_read_rocket:
- return Response(status_code=status.HTTP_404_NOT_FOUND)
-
- rocket = RocketController(rocket=successfully_read_rocket,
- rocket_option = RocketOptions(successfully_read_rocket._rocket_option),
- motor_kind = MotorKinds(successfully_read_rocket.motor._motor_kind)).rocketpy_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)
- ]
- )
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND, detail="Rocket not found."
+ )
- _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",
+ try:
+ rocket = RocketController(
+ rocket=successfully_read_rocket,
+ rocket_option=RocketOptions(successfully_read_rocket._rocket_option),
+ motor_kind=MotorKinds(successfully_read_rocket.motor._motor_kind),
+ ).rocketpy_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_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_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)
+ ),
+ )
- 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
+ _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"
)
- ),
- 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_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"
)
- )
- )
- _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"
+ _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)
+ + " 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",
)
- _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"
+ _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_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) + " 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 )
+ _rocket_data = RocketData(
+ inertia_details=_inertia_details,
+ rocket_geometrical_parameters=_rocket_geometrical_parameters,
+ rocket_aerodynamics_quantities=_rocket_aerodynamics_quantities,
+ parachute_data=_parachute_data,
+ )
- return rocket_summary
+ rocket_summary = RocketSummary(rocket_data=_rocket_data)
+ return rocket_summary
+ except Exception as e:
+ raise HTTPException(
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
+ detail=f"Failed to simulate rocket: {e}",
+ ) from e
diff --git a/lib/models/aerosurfaces.py b/lib/models/aerosurfaces.py
index 490c99f..73284ea 100644
--- a/lib/models/aerosurfaces.py
+++ b/lib/models/aerosurfaces.py
@@ -1,11 +1,13 @@
from typing import Optional
from pydantic import BaseModel
+
class RailButtons(BaseModel, frozen=True):
upper_button_position: Optional[float] = -0.5
lower_button_position: Optional[float] = 0.2
angular_position: Optional[float] = 45
+
class NoseCone(BaseModel, frozen=True):
length: float = 0.55829
kind: str = "vonKarman"
@@ -13,6 +15,7 @@ class NoseCone(BaseModel, frozen=True):
base_radius: float = 0.0635
rocket_radius: float = 0.0635
+
class Fins(BaseModel, frozen=True):
n: int = 4
root_chord: float = 0.12
@@ -23,10 +26,12 @@ class Fins(BaseModel, frozen=True):
radius: float = 0.0635
airfoil: str = ""
+
class TrapezoidalFins(Fins, frozen=True):
def __init__(self):
super().__init__()
+
class Tail(BaseModel, frozen=True):
top_radius: float = 0.0635
bottom_radius: float = 0.0435
diff --git a/lib/models/environment.py b/lib/models/environment.py
index 4a1a5bc..0ce9afe 100644
--- a/lib/models/environment.py
+++ b/lib/models/environment.py
@@ -2,12 +2,15 @@
from typing import Optional
from pydantic import BaseModel
+
class Env(BaseModel, frozen=True):
latitude: float = 0
longitude: float = 0
elevation: Optional[int] = 1400
- #Opional parameters
- atmospheric_model_type: Optional[str] = 'standard_atmosphere'
- atmospheric_model_file: Optional[str] = 'GFS'
- date: Optional[datetime.datetime] = datetime.datetime.today() + datetime.timedelta(days=1)
+ # Opional parameters
+ atmospheric_model_type: Optional[str] = "standard_atmosphere"
+ atmospheric_model_file: Optional[str] = "GFS"
+ date: Optional[datetime.datetime] = datetime.datetime.today() + datetime.timedelta(
+ days=1
+ )
diff --git a/lib/models/flight.py b/lib/models/flight.py
index 20182bd..61343cc 100644
--- a/lib/models/flight.py
+++ b/lib/models/flight.py
@@ -2,6 +2,7 @@
from lib.models.rocket import Rocket
from lib.models.environment import Env
+
class Flight(BaseModel, frozen=True):
environment: Env = Env()
rocket: Rocket = Rocket()
diff --git a/lib/models/motor.py b/lib/models/motor.py
index fb57453..7a2a451 100644
--- a/lib/models/motor.py
+++ b/lib/models/motor.py
@@ -1,29 +1,40 @@
-from rocketpy import LevelBasedTank, MassBasedTank, MassFlowRateBasedTank, UllageBasedTank, SolidMotor, LiquidMotor, HybridMotor, TankGeometry, Function
-from typing import Optional, Tuple, List, Dict
from enum import Enum
+from typing import Optional, Tuple, List
+from rocketpy import (
+ LevelBasedTank,
+ MassBasedTank,
+ MassFlowRateBasedTank,
+ UllageBasedTank,
+ TankGeometry,
+)
from pydantic import BaseModel, PrivateAttr
+
class MotorKinds(str, Enum):
hybrid: str = "Hybrid"
solid: str = "Solid"
liquid: str = "Liquid"
+
class MotorEngines(str, Enum):
cesaroni: str = "Cesaroni_M1670"
custom: str = "Custom"
+
class TankKinds(str, Enum):
level: str = "Level"
mass: str = "Mass"
mass_flow: str = "MassFlow"
ullage: str = "Ullage"
+
class TankFluids(BaseModel, frozen=True):
name: str = "FluidName"
density: float = 100.0
+
class MotorTank(BaseModel, frozen=True):
- #Required parameters
+ # Required parameters
geometry: "List[Tuple[Tuple[float,float],float]]" = [((0, 5), 1), ((5, 10), 2)]
tank_kind: TankKinds = TankKinds.mass_flow
gas: TankFluids = TankFluids()
@@ -31,8 +42,8 @@ class MotorTank(BaseModel, frozen=True):
name: str = "Tank"
flux_time: "List[float]" = [0, 8]
position: float = 1.0
-
- #Optional parameters
+
+ # Optional parameters
discretize: Optional[int] = 100
liquid_height: Optional[float] = 0.5
liquid_mass: Optional[float] = 5.0
@@ -49,27 +60,29 @@ def __init__(self, **kwargs):
super().__init__(**kwargs)
tank_core = {
"name": self.name,
- "geometry": TankGeometry(geometry_dict = { t:f for t,f in self.geometry }),
+ "geometry": TankGeometry(geometry_dict=dict(self.geometry)),
"flux_time": self.flux_time,
"gas": self.gas,
"liquid": self.liquid,
- "discretize": self.discretize
+ "discretize": self.discretize,
}
match self.tank_kind:
case TankKinds.level:
tank = LevelBasedTank(**tank_core, liquid_height=self.liquid_height)
case TankKinds.mass:
- tank = MassBasedTank(**tank_core,
- liquid_mass=self.liquid_mass, gas_mass=self.gas_mass)
+ tank = MassBasedTank(
+ **tank_core, liquid_mass=self.liquid_mass, gas_mass=self.gas_mass
+ )
case TankKinds.mass_flow:
- tank = MassFlowRateBasedTank(**tank_core,
- gas_mass_flow_rate_in=self.gas_mass_flow_rate_in,
+ tank = MassFlowRateBasedTank(
+ **tank_core,
+ gas_mass_flow_rate_in=self.gas_mass_flow_rate_in,
gas_mass_flow_rate_out=self.gas_mass_flow_rate_out,
liquid_mass_flow_rate_in=self.liquid_mass_flow_rate_in,
liquid_mass_flow_rate_out=self.liquid_mass_flow_rate_out,
initial_liquid_mass=self.initial_liquid_mass,
- initial_gas_mass=self.initial_gas_mass
+ initial_gas_mass=self.initial_gas_mass,
)
case TankKinds.ullage:
tank = UllageBasedTank(**tank_core, ullage=self.ullage)
@@ -80,10 +93,11 @@ def __hash__(self):
temp = str(temp)
return hash(temp)
+
class Motor(BaseModel, frozen=True):
- #TBD: thrust_source must be the id of a previously uploaded .eng file and a list of "default" files must be provided in the api docs
+ # TBD: thrust_source must be the id of a previously uploaded .eng file and a list of "default" files must be provided in the api docs
- #Required parameters
+ # Required parameters
thrust_source: MotorEngines = MotorEngines.cesaroni
burn_time: float = 3.9
nozzle_radius: float = 0.033
@@ -92,7 +106,7 @@ class Motor(BaseModel, frozen=True):
center_of_dry_mass_position: float = 0.317
_motor_kind: MotorKinds = PrivateAttr()
- #Optional parameters
+ # Optional parameters
tanks: Optional["List[MotorTank]"] = [MotorTank()]
grain_number: Optional[int] = 5
grain_density: Optional[float] = 1815
@@ -105,7 +119,7 @@ class Motor(BaseModel, frozen=True):
interpolation_method: Optional[str] = "linear"
coordinate_system_orientation: Optional[str] = "nozzle_to_combustion_chamber"
- def __init__(self, motor_kind = MotorKinds.solid, **kwargs):
+ def __init__(self, motor_kind=MotorKinds.solid, **kwargs):
super().__init__(**kwargs)
self._motor_kind = motor_kind
diff --git a/lib/models/parachute.py b/lib/models/parachute.py
index f1106a3..12bf480 100644
--- a/lib/models/parachute.py
+++ b/lib/models/parachute.py
@@ -1,23 +1,29 @@
from typing import List, Tuple
from pydantic import BaseModel
+
class Parachute(BaseModel, frozen=True):
- name: "List[str]" = ["Main","Drogue"]
+ name: "List[str]" = ["Main", "Drogue"]
cd_s: "List[float]" = [10, 1]
lag: "List[float]" = [1.5, 1.5]
sampling_rate: "List[int]" = [105, 105]
noise: "List[Tuple[float, float, float]]" = [(0, 8.3, 0.5), (0, 8.3, 0.5)]
- triggers: "List[str]" = ["lambda p, h, y: y[5] < 0 and h < 800", "lambda p, h, y: y[5] < 0"]
+ triggers: "List[str]" = [
+ "lambda p, h, y: y[5] < 0 and h < 800",
+ "lambda p, h, y: y[5] < 0",
+ ]
def __hash__(self):
- return hash((
- tuple(self.name),
- tuple(self.cd_s),
- tuple(self.sampling_rate),
- tuple(self.lag),
- tuple(self.noise),
- tuple(self.triggers),
- ))
+ return hash(
+ (
+ tuple(self.name),
+ tuple(self.cd_s),
+ tuple(self.sampling_rate),
+ tuple(self.lag),
+ tuple(self.noise),
+ tuple(self.triggers),
+ )
+ )
def __getitem__(self, idx):
if isinstance(idx, slice):
diff --git a/lib/models/rocket.py b/lib/models/rocket.py
index c31abda..09d0172 100644
--- a/lib/models/rocket.py
+++ b/lib/models/rocket.py
@@ -1,16 +1,18 @@
+from enum import Enum
from typing import Optional, Tuple, List
from pydantic import BaseModel, PrivateAttr
-from enum import Enum
from lib.models.motor import Motor
from lib.models.aerosurfaces import Fins, NoseCone, Tail, RailButtons
from lib.models.parachute import Parachute
+
class RocketOptions(str, Enum):
calisto: str = "Calisto"
custom: str = "Custom"
+
class Rocket(BaseModel, frozen=True):
- #Required parameters
+ # Required parameters
rail_buttons: RailButtons = RailButtons()
motor: Motor = Motor()
nose: NoseCone = NoseCone()
@@ -22,23 +24,23 @@ class Rocket(BaseModel, frozen=True):
radius: float = 0.0632
mass: float = 16.235
motor_position: float = -1.255
- power_off_drag: "List[Tuple[float, float]]" = [
- (0.01,0.333865758),
- (0.02,0.394981721),
- (0.03,0.407756063)
+ power_off_drag: "List[Tuple[float, float]]" = [
+ (0.01, 0.333865758),
+ (0.02, 0.394981721),
+ (0.03, 0.407756063),
]
- power_on_drag: "List[Tuple[float, float]]" = [
- (0.01,0.333865758),
- (0.02,0.394981721),
- (0.03,0.407756063)
+ power_on_drag: "List[Tuple[float, float]]" = [
+ (0.01, 0.333865758),
+ (0.02, 0.394981721),
+ (0.03, 0.407756063),
]
_rocket_option: RocketOptions = PrivateAttr()
- #Optional parameters
- #TBD: a list of possible tailToNose values must be provided in the api docs
+ # Optional parameters
+ # TBD: a list of possible tailToNose values must be provided in the api docs
coordinate_system_orientation: Optional[str] = "tail_to_nose"
- def __init__(self, rocket_option = RocketOptions.calisto, **kwargs):
+ def __init__(self, rocket_option=RocketOptions.calisto, **kwargs):
super().__init__(**kwargs)
self._rocket_option = rocket_option
diff --git a/lib/repositories/environment.py b/lib/repositories/environment.py
index ddc9dbc..8632b65 100644
--- a/lib/repositories/environment.py
+++ b/lib/repositories/environment.py
@@ -1,8 +1,9 @@
+from typing import Union
from pymongo.results import InsertOneResult
from pymongo.results import DeleteResult
from lib.models.environment import Env
from lib.repositories.repo import Repository
-from typing import Union
+
class EnvRepository(Repository):
"""
@@ -41,9 +42,12 @@ async def create_env(self) -> "InsertOneResult":
environment_to_dict = self.environment.dict()
environment_to_dict["env_id"] = self.env_id
return await self.collection.insert_one(environment_to_dict)
- except:
- raise Exception("Error creating environment")
- return InsertOneResult( acknowledged=True, inserted_id=None )
+ except Exception as e:
+ raise Exception(f"Error creating environment: {str(e)}") from e
+ finally:
+ self.__del__()
+ else:
+ return InsertOneResult(acknowledged=True, inserted_id=None)
async def update_env(self) -> "Union[int, None]":
"""
@@ -57,29 +61,30 @@ async def update_env(self) -> "Union[int, None]":
environment_to_dict["env_id"] = self.environment.__hash__()
await self.collection.update_one(
- { "env_id": self.env_id },
- { "$set": environment_to_dict }
+ {"env_id": self.env_id}, {"$set": environment_to_dict}
)
self.env_id = environment_to_dict["env_id"]
return self.env_id
- except:
- raise Exception("Error updating environment")
+ except Exception as e:
+ raise Exception(f"Error updating environment: {str(e)}") from e
+ finally:
+ self.__del__()
async def get_env(self) -> "Union[Env, None]":
"""
Gets a environment from the database
-
+
Returns:
models.Env: Model environment object
"""
try:
- environment = await self.collection.find_one({ "env_id": self.env_id })
+ environment = await self.collection.find_one({"env_id": self.env_id})
if environment is not None:
return Env.parse_obj(environment)
return None
- except:
- raise Exception("Error getting environment")
+ except Exception as e:
+ raise Exception(f"Error getting environment: {str(e)}") from e
async def delete_env(self) -> "DeleteResult":
"""
@@ -89,6 +94,8 @@ async def delete_env(self) -> "DeleteResult":
DeleteResult: result of the delete operation
"""
try:
- return await self.collection.delete_one({ "env_id": self.env_id })
- except:
- raise Exception("Error deleting environment")
+ return await self.collection.delete_one({"env_id": self.env_id})
+ except Exception as e:
+ raise Exception(f"Error deleting environment: {str(e)}") from e
+ finally:
+ self.__del__()
diff --git a/lib/repositories/flight.py b/lib/repositories/flight.py
index eea93de..6f3f47b 100644
--- a/lib/repositories/flight.py
+++ b/lib/repositories/flight.py
@@ -4,6 +4,7 @@
from lib.models.flight import Flight
from lib.repositories.repo import Repository
+
class FlightRepository(Repository):
"""
Flight repository
@@ -26,7 +27,9 @@ def __init__(self, flight: Flight = None, flight_id: str = None):
def __del__(self):
super().__del__()
- async def create_flight(self, motor_kind: str = "Solid", rocket_option: str = "Calisto") -> "InsertOneResult":
+ async def create_flight(
+ self, motor_kind: str = "Solid", rocket_option: str = "Calisto"
+ ) -> "InsertOneResult":
"""
Creates a flight in the database
@@ -43,11 +46,16 @@ async def create_flight(self, motor_kind: str = "Solid", rocket_option: str = "C
flight_to_dict["rocket"]["rocket_option"] = rocket_option
flight_to_dict["rocket"]["motor"]["motor_kind"] = motor_kind
return await self.collection.insert_one(flight_to_dict)
- except:
- raise Exception("Error creating flight")
- return InsertOneResult( acknowledged=True, inserted_id=None )
+ except Exception as e:
+ raise Exception(f"Error creating flight: {str(e)}") from e
+ finally:
+ self.__del__()
+ else:
+ return InsertOneResult(acknowledged=True, inserted_id=None)
- async def update_flight(self, motor_kind: str = "Solid", rocket_option: str = "Calisto") -> "Union[int, None]":
+ async def update_flight(
+ self, motor_kind: str = "Solid", rocket_option: str = "Calisto"
+ ) -> "Union[int, None]":
"""
Updates a flight in the database
@@ -60,30 +68,31 @@ async def update_flight(self, motor_kind: str = "Solid", rocket_option: str = "C
flight_to_dict["rocket"]["rocket_option"] = rocket_option
flight_to_dict["rocket"]["motor"]["motor_kind"] = motor_kind
- updated_flight = await self.collection.update_one(
- { "flight_id": self.flight_id },
- { "$set": flight_to_dict }
+ await self.collection.update_one(
+ {"flight_id": self.flight_id}, {"$set": flight_to_dict}
)
self.flight_id = flight_to_dict["flight_id"]
- return self.flight_id
- except:
- raise Exception("Error updating flight")
+ return self.flight_id
+ except Exception as e:
+ raise Exception(f"Error updating flight: {str(e)}") from e
+ finally:
+ self.__del__()
async def get_flight(self) -> "Union[Flight, None]":
"""
Gets a flight from the database
-
+
Returns:
models.Flight: Model flight object
"""
try:
- flight = await self.collection.find_one({ "flight_id": self.flight_id })
+ flight = await self.collection.find_one({"flight_id": self.flight_id})
if flight is not None:
return Flight.parse_obj(flight)
return None
- except:
- raise Exception("Error getting flight")
+ except Exception as e:
+ raise Exception(f"Error getting flight: {str(e)}") from e
async def delete_flight(self) -> "DeleteResult":
"""
@@ -93,6 +102,8 @@ async def delete_flight(self) -> "DeleteResult":
DeleteResult: result of the delete operation
"""
try:
- return await self.collection.delete_one({ "flight_id": self.flight_id })
- except:
- raise Exception("Error deleting flight")
+ return await self.collection.delete_one({"flight_id": self.flight_id})
+ except Exception as e:
+ raise Exception(f"Error deleting flight: {str(e)}") from e
+ finally:
+ self.__del__()
diff --git a/lib/repositories/motor.py b/lib/repositories/motor.py
index 030bf3e..95883f1 100644
--- a/lib/repositories/motor.py
+++ b/lib/repositories/motor.py
@@ -4,6 +4,7 @@
from lib.models.motor import Motor
from lib.repositories.repo import Repository
+
class MotorRepository(Repository):
"""
Motor repository
@@ -42,9 +43,12 @@ async def create_motor(self, motor_kind: str = "solid") -> "InsertOneResult":
motor_to_dict["motor_id"] = self.motor_id
motor_to_dict["motor_kind"] = motor_kind
return await self.collection.insert_one(motor_to_dict)
- except:
- raise Exception("Error creating motor")
- return InsertOneResult( acknowledged=True, inserted_id=None )
+ except Exception as e:
+ raise Exception(f"Error creating motor: {str(e)}") from e
+ finally:
+ self.__del__()
+ else:
+ return InsertOneResult(acknowledged=True, inserted_id=None)
async def update_motor(self, motor_kind: str = "solid") -> "Union[int, None]":
"""
@@ -58,30 +62,31 @@ async def update_motor(self, motor_kind: str = "solid") -> "Union[int, None]":
motor_to_dict["motor_id"] = self.motor.__hash__()
motor_to_dict["motor_kind"] = motor_kind
- updated_motor = await self.collection.update_one(
- { "motor_id": self.motor_id },
- { "$set": motor_to_dict }
+ await self.collection.update_one(
+ {"motor_id": self.motor_id}, {"$set": motor_to_dict}
)
self.motor_id = motor_to_dict["motor_id"]
- return self.motor_id
- except:
- raise Exception("Error updating motor")
+ return self.motor_id
+ except Exception as e:
+ raise Exception(f"Error updating motor: {str(e)}") from e
+ finally:
+ self.__del__()
async def get_motor(self) -> "Union[motor, None]":
"""
Gets a motor from the database
-
+
Returns:
models.motor: Model motor object
"""
try:
- motor = await self.collection.find_one({ "motor_id": self.motor_id })
+ motor = await self.collection.find_one({"motor_id": self.motor_id})
if motor is not None:
return Motor.parse_obj(motor)
return None
- except:
- raise Exception("Error getting motor")
+ except Exception as e:
+ raise Exception(f"Error getting motor: {str(e)}") from e
async def delete_motor(self) -> "DeleteResult":
"""
@@ -91,6 +96,8 @@ async def delete_motor(self) -> "DeleteResult":
DeleteResult: result of the delete operation
"""
try:
- return await self.collection.delete_one({ "motor_id": self.motor_id })
- except:
- raise Exception("Error deleting motor")
+ return await self.collection.delete_one({"motor_id": self.motor_id})
+ except Exception as e:
+ raise Exception(f"Error deleting motor: {str(e)}") from e
+ finally:
+ self.__del__()
diff --git a/lib/repositories/repo.py b/lib/repositories/repo.py
index 26aec23..24401c4 100644
--- a/lib/repositories/repo.py
+++ b/lib/repositories/repo.py
@@ -1,12 +1,13 @@
-import asyncio
from motor.motor_asyncio import AsyncIOMotorClient
from pymongo.server_api import ServerApi
from lib.secrets import secrets_instance
+
class Repository:
"""
Base class for all repositories (singleton)
"""
+
_self = None
def __new__(cls, *args, **kwargs):
@@ -15,8 +16,12 @@ def __new__(cls, *args, **kwargs):
return cls._self
def __init__(self, collection: str):
- self.connection_string = secrets_instance.get_secret("MONGODB_CONNECTION_STRING")
- self.client = AsyncIOMotorClient(self.connection_string, server_api=ServerApi('1'))
+ self.connection_string = secrets_instance.get_secret(
+ "MONGODB_CONNECTION_STRING"
+ )
+ self.client = AsyncIOMotorClient(
+ self.connection_string, server_api=ServerApi("1")
+ )
self.db = self.client.rocketpy
self.collection = self.db[collection]
diff --git a/lib/repositories/rocket.py b/lib/repositories/rocket.py
index ab03807..2d64fce 100644
--- a/lib/repositories/rocket.py
+++ b/lib/repositories/rocket.py
@@ -4,6 +4,7 @@
from lib.models.rocket import Rocket
from lib.repositories.repo import Repository
+
class RocketRepository(Repository):
"""
Rocket repository
@@ -42,9 +43,12 @@ async def create_rocket(self, rocket_option: str = "Calisto") -> "InsertOneResul
rocket_to_dict["rocket_id"] = self.rocket_id
rocket_to_dict["rocket_option"] = rocket_option
return await self.collection.insert_one(rocket_to_dict)
- except:
- raise Exception("Error creating rocket")
- return InsertOneResult( acknowledged=True, inserted_id=None )
+ except Exception as e:
+ raise Exception(f"Error creating rocket: {str(e)}") from e
+ finally:
+ self.__del__()
+ else:
+ return InsertOneResult(acknowledged=True, inserted_id=None)
async def update_rocket(self, rocket_option: str = "Calisto") -> "Union[int, None]":
"""
@@ -58,30 +62,31 @@ async def update_rocket(self, rocket_option: str = "Calisto") -> "Union[int, Non
rocket_to_dict["rocket_id"] = self.rocket.__hash__()
rocket_to_dict["rocket_option"] = rocket_option
- updated_rocket = await self.collection.update_one(
- { "rocket_id": self.rocket_id },
- { "$set": rocket_to_dict }
+ await self.collection.update_one(
+ {"rocket_id": self.rocket_id}, {"$set": rocket_to_dict}
)
self.rocket_id = rocket_to_dict["rocket_id"]
- return self.rocket_id
- except:
- raise Exception("Error updating rocket")
+ return self.rocket_id
+ except Exception as e:
+ raise Exception(f"Error updating rocket: {str(e)}") from e
+ finally:
+ self.__del__()
async def get_rocket(self) -> "Union[Rocket, None]":
"""
Gets a rocket from the database
-
+
Returns:
models.Rocket: Model rocket object
"""
try:
- rocket = await self.collection.find_one({ "rocket_id": self.rocket_id })
+ rocket = await self.collection.find_one({"rocket_id": self.rocket_id})
if rocket is not None:
return Rocket.parse_obj(rocket)
return None
- except:
- raise Exception("Error getting rocket")
+ except Exception as e:
+ raise Exception(f"Error getting rocket: {str(e)}") from e
async def delete_rocket(self) -> "DeleteResult":
"""
@@ -91,6 +96,8 @@ async def delete_rocket(self) -> "DeleteResult":
DeleteResult: result of the delete operation
"""
try:
- return await self.collection.delete_one({ "rocket_id": self.rocket_id })
- except:
- raise Exception("Error deleting rocket")
+ return await self.collection.delete_one({"rocket_id": self.rocket_id})
+ except Exception as e:
+ raise Exception(f"Error deleting rocket: {str(e)}") from e
+ finally:
+ self.__del__()
diff --git a/lib/routes/environment.py b/lib/routes/environment.py
new file mode 100644
index 0000000..e2e8f0c
--- /dev/null
+++ b/lib/routes/environment.py
@@ -0,0 +1,93 @@
+"""
+Environment routes
+"""
+from fastapi import APIRouter
+
+from lib.views.environment import (
+ EnvSummary,
+ EnvCreated,
+ EnvUpdated,
+ EnvDeleted,
+ EnvPickle,
+)
+from lib.models.environment import Env
+from lib.controllers.environment import EnvController
+
+router = APIRouter(
+ prefix="/environments",
+ tags=["ENVIRONMENT"],
+ responses={
+ 404: {"description": "Not found"},
+ 422: {"description": "Unprocessable Entity"},
+ 500: {"description": "Internal Server Error"},
+ },
+)
+
+
+@router.post("/")
+async def create_env(env: Env) -> "EnvCreated":
+ """
+ Creates a new environment
+
+ ## Args
+ ``` Env object as a JSON ```
+ """
+ return await EnvController(env).create_env()
+
+
+@router.get("/{env_id}")
+async def read_env(env_id: int) -> "Env":
+ """
+ Reads an environment
+
+ ## Args
+ ``` env_id: Environment ID hash ```
+ """
+ return await EnvController.get_env(env_id)
+
+
+@router.put("/{env_id}")
+async def update_env(env_id: int, env: Env) -> "EnvUpdated":
+ """
+ Updates an environment
+
+ ## Args
+ ```
+ env_id: Environment ID hash
+ env: Env object as JSON
+ ```
+ """
+ return await EnvController(env).update_env(env_id)
+
+
+@router.delete("/{env_id}")
+async def delete_env(env_id: int) -> "EnvDeleted":
+ """
+ Deletes an environment
+
+ ## Args
+ ``` env_id: Environment ID hash ```
+ """
+ return await EnvController.delete_env(env_id)
+
+
+@router.get("/rocketpy/{env_id}")
+async def read_rocketpy_env(env_id: int) -> "EnvPickle":
+ """
+ Reads a rocketpy environment
+
+ ## Args
+ ``` env_id: Environment ID hash ```
+ """
+ return await EnvController.get_rocketpy_env(env_id)
+
+
+@router.get("/{env_id}/simulate")
+async def simulate_env(env_id: int) -> "EnvSummary":
+ """
+ Simulates an environment
+
+ ## Args
+ ``` env_id: Env ID hash ```
+ """
+ return await EnvController.simulate(env_id)
diff --git a/lib/routes/flight.py b/lib/routes/flight.py
new file mode 100644
index 0000000..5e2962b
--- /dev/null
+++ b/lib/routes/flight.py
@@ -0,0 +1,134 @@
+"""
+Flight routes
+"""
+from fastapi import APIRouter
+
+from lib.views.flight import (
+ FlightSummary,
+ FlightCreated,
+ FlightUpdated,
+ FlightDeleted,
+ FlightPickle,
+)
+from lib.models.environment import Env
+from lib.models.flight import Flight
+from lib.models.rocket import Rocket, RocketOptions
+from lib.models.motor import MotorKinds
+from lib.controllers.flight import FlightController
+
+router = APIRouter(
+ prefix="/flights",
+ tags=["FLIGHT"],
+ responses={
+ 404: {"description": "Not found"},
+ 422: {"description": "Unprocessable Entity"},
+ 500: {"description": "Internal Server Error"},
+ },
+)
+
+
+@router.post("/")
+async def create_flight(
+ flight: Flight, rocket_option: RocketOptions, motor_kind: MotorKinds
+) -> "FlightCreated":
+ """
+ Creates a new flight
+
+ ## Args
+ ``` Flight object as JSON ```
+ """
+ return await FlightController(flight, rocket_option, motor_kind).create_flight()
+
+
+@router.get("/{flight_id}")
+async def read_flight(flight_id: int) -> "Flight":
+ """
+ Reads a flight
+
+ ## Args
+ ``` flight_id: Flight ID hash ```
+ """
+ return await FlightController.get_flight(flight_id)
+
+
+@router.get("/rocketpy/{flight_id}")
+async def read_rocketpy_flight(flight_id: int) -> "FlightPickle":
+ """
+ Reads a rocketpy flight object
+
+ ## Args
+ ``` flight_id: Flight ID hash. ```
+ """
+ return await FlightController.get_rocketpy_flight(flight_id)
+
+
+@router.put("/{flight_id}/env")
+async def update_flight_env(flight_id: int, env: Env) -> "FlightUpdated":
+ """
+ Updates flight environment
+
+ ## Args
+ ```
+ flight_id: Flight ID hash
+ env: env object as JSON
+ ```
+ """
+ return await FlightController.update_env(flight_id, env)
+
+
+@router.put("/{flight_id}/rocket")
+async def update_flight_rocket(
+ flight_id: int, rocket: Rocket, rocket_option: RocketOptions, motor_kind: MotorKinds
+) -> "FlightUpdated":
+ """
+ Updates flight rocket.
+
+ ## Args
+ ```
+ flight_id: Flight ID hash.
+ rocket: Rocket object as JSON
+ ```
+ """
+ return await FlightController.update_rocket(
+ flight_id, rocket, rocket_option, motor_kind
+ )
+
+
+@router.put("/{flight_id}")
+async def update_flight(
+ flight_id: int, flight: Flight, rocket_option: RocketOptions, motor_kind: MotorKinds
+) -> "FlightUpdated":
+ """
+ Updates Flight object
+
+ ## Args
+ ```
+ flight_id: Flight ID hash.
+ flight: Flight object as JSON
+ ```
+ """
+ return await FlightController(flight, rocket_option, motor_kind).update_flight(
+ flight_id
+ )
+
+
+@router.delete("/{flight_id}")
+async def delete_flight(flight_id: int) -> "FlightDeleted":
+ """
+ Deletes a flight
+
+ ## Args
+ ``` flight_id: Flight ID hash ```
+ """
+ return await FlightController.delete_flight(flight_id)
+
+
+@router.get("/{flight_id}/simulate")
+async def simulate_flight(flight_id: int) -> "FlightSummary":
+ """
+ Simulates a flight
+
+ ## Args
+ ``` flight_id: Flight ID hash ```
+ """
+ return await FlightController.simulate(flight_id)
diff --git a/lib/routes/motor.py b/lib/routes/motor.py
new file mode 100644
index 0000000..c29d90b
--- /dev/null
+++ b/lib/routes/motor.py
@@ -0,0 +1,95 @@
+"""
+Motor routes
+"""
+from fastapi import APIRouter
+
+from lib.views.motor import (
+ MotorSummary,
+ MotorCreated,
+ MotorUpdated,
+ MotorDeleted,
+ MotorPickle,
+)
+from lib.models.motor import Motor, MotorKinds
+from lib.controllers.motor import MotorController
+
+router = APIRouter(
+ prefix="/motors",
+ tags=["MOTOR"],
+ responses={
+ 404: {"description": "Not found"},
+ 422: {"description": "Unprocessable Entity"},
+ 500: {"description": "Internal Server Error"},
+ },
+)
+
+
+@router.post("/")
+async def create_motor(motor: Motor, motor_kind: MotorKinds) -> "MotorCreated":
+ """
+ Creates a new motor
+
+ ## Args
+ ``` Motor object as a JSON ```
+ """
+ return await MotorController(motor, motor_kind).create_motor()
+
+
+@router.get("/{motor_id}")
+async def read_motor(motor_id: int) -> "Motor":
+ """
+ Reads a motor
+
+ ## Args
+ ``` motor_id: Motor ID hash ```
+ """
+ return await MotorController.get_motor(motor_id)
+
+
+@router.put("/{motor_id}")
+async def update_motor(
+ motor_id: int, motor: Motor, motor_kind: MotorKinds
+) -> "MotorUpdated":
+ """
+ Updates a motor
+
+ ## Args
+ ```
+ motor_id: Motor ID hash
+ motor: Motor object as JSON
+ ```
+ """
+ return await MotorController(motor, motor_kind).update_motor(motor_id)
+
+
+@router.delete("/{motor_id}")
+async def delete_motor(motor_id: int) -> "MotorDeleted":
+ """
+ Deletes a motor
+
+ ## Args
+ ``` motor_id: Motor ID hash ```
+ """
+ return await MotorController.delete_motor(motor_id)
+
+
+@router.get("/rocketpy/{motor_id}")
+async def read_rocketpy_motor(motor_id: int) -> "MotorPickle":
+ """
+ Reads a rocketpy motor
+
+ ## Args
+ ``` motor_id: Motor ID hash ```
+ """
+ return await MotorController.get_rocketpy_motor(motor_id)
+
+
+@router.get("/{motor_id}/simulate")
+async def simulate_motor(motor_id: int) -> "MotorSummary":
+ """
+ Simulates a motor
+
+ ## Args
+ ``` motor_id: Motor ID hash ```
+ """
+ return await MotorController.simulate(motor_id)
diff --git a/lib/routes/rocket.py b/lib/routes/rocket.py
new file mode 100644
index 0000000..fded8cc
--- /dev/null
+++ b/lib/routes/rocket.py
@@ -0,0 +1,100 @@
+"""
+Rocket routes
+"""
+from fastapi import APIRouter
+
+from lib.views.rocket import (
+ RocketSummary,
+ RocketCreated,
+ RocketUpdated,
+ RocketDeleted,
+ RocketPickle,
+)
+from lib.models.rocket import Rocket, RocketOptions
+from lib.models.motor import MotorKinds
+from lib.controllers.rocket import RocketController
+
+router = APIRouter(
+ prefix="/rockets",
+ tags=["ROCKET"],
+ responses={
+ 404: {"description": "Not found"},
+ 422: {"description": "Unprocessable Entity"},
+ 500: {"description": "Internal Server Error"},
+ },
+)
+
+
+@router.post("/")
+async def create_rocket(
+ rocket: Rocket, rocket_option: RocketOptions, motor_kind: MotorKinds
+) -> "RocketCreated":
+ """
+ Creates a new rocket
+
+ ## Args
+ ``` Rocket object as a JSON ```
+ """
+ return await RocketController(rocket, rocket_option, motor_kind).create_rocket()
+
+
+@router.get("/{rocket_id}")
+async def read_rocket(rocket_id: int) -> Rocket:
+ """
+ Reads a rocket
+
+ ## Args
+ ``` rocket_id: Rocket ID hash ```
+ """
+ return await RocketController.get_rocket(rocket_id)
+
+
+@router.put("/{rocket_id}")
+async def update_rocket(
+ rocket_id: int, rocket: Rocket, rocket_option: RocketOptions, motor_kind: MotorKinds
+) -> "RocketUpdated":
+ """
+ Updates a rocket
+
+ ## Args
+ ```
+ rocket_id: Rocket ID hash
+ rocket: Rocket object as JSON
+ ```
+ """
+ return await RocketController(rocket, rocket_option, motor_kind).update_rocket(
+ rocket_id
+ )
+
+
+@router.delete("/{rocket_id}")
+async def delete_rocket(rocket_id: int) -> "RocketDeleted":
+ """
+ Deletes a rocket
+
+ ## Args
+ ``` rocket_id: Rocket ID hash ```
+ """
+ return await RocketController.delete_rocket(rocket_id)
+
+
+@router.get("/rocketpy/{rocket_id}")
+async def read_rocketpy_rocket(rocket_id: int) -> "RocketPickle":
+ """
+ Reads a rocketpy rocket
+
+ ## Args
+ ``` rocket_id: Rocket ID hash ```
+ """
+ return await RocketController.get_rocketpy_rocket(rocket_id)
+
+
+@router.get("/{rocket_id}/simulate")
+async def simulate_rocket(rocket_id: int) -> "RocketSummary":
+ """
+ Simulates a rocket
+
+ ## Args
+ ``` rocket_id: Rocket ID hash ```
+ """
+ return await RocketController.simulate(rocket_id)
diff --git a/lib/secrets.py b/lib/secrets.py
index e719203..422a491 100644
--- a/lib/secrets.py
+++ b/lib/secrets.py
@@ -2,10 +2,12 @@
from dotenv import dotenv_values
from pydantic import BaseModel
+
class Secrets(BaseModel):
"""
- Secrets class to load secrets from .env file
+ Secrets class to load secrets from .env file
"""
+
secrets: dict = dotenv_values(".env")
@staticmethod
@@ -18,5 +20,6 @@ def get_secret(self, key):
return self.get_os_secret(key)
return dotenv_secret
+
# global instance
secrets_instance = Secrets()
diff --git a/lib/views/environment.py b/lib/views/environment.py
index de1ace9..51b4216 100644
--- a/lib/views/environment.py
+++ b/lib/views/environment.py
@@ -1,9 +1,10 @@
from typing import List
from pydantic import BaseModel
+
class EnvData(BaseModel):
- #TBD: review grav type
- #grav: "Any"
+ # TBD: review grav type
+ # grav: "Any"
elevation: int
model_type: str
model_type_max_expected_height: int
@@ -18,6 +19,7 @@ class EnvData(BaseModel):
lat: float
lon: float
+
class EnvPlots(BaseModel):
grid: "List[float]"
wind_speed: "List[float]"
@@ -29,21 +31,26 @@ class EnvPlots(BaseModel):
pressure: "List[float]"
temperature: "List[float]"
+
class EnvSummary(BaseModel):
env_data: EnvData
env_plots: EnvPlots
+
class EnvCreated(BaseModel):
- env_id: str
+ env_id: str
message: str = "Environment successfully created"
+
class EnvUpdated(BaseModel):
- new_env_id: str
+ new_env_id: str
message: str = "Environment successfully updated"
+
class EnvDeleted(BaseModel):
- deleted_env_id: str
+ deleted_env_id: str
message: str = "Environment successfully deleted"
+
class EnvPickle(BaseModel):
jsonpickle_rocketpy_env: str
diff --git a/lib/views/flight.py b/lib/views/flight.py
index d038bb5..3d64591 100644
--- a/lib/views/flight.py
+++ b/lib/views/flight.py
@@ -1,6 +1,7 @@
from typing import Optional, Any
from pydantic import BaseModel
+
class InitialConditions(BaseModel):
initial_position: str
initial_velocity: str
@@ -8,6 +9,7 @@ class InitialConditions(BaseModel):
initial_angular_position: str
initial_angular_velocity: str
+
class NumericalIntegrationSettings(BaseModel):
max_time: str
max_time_step: str
@@ -20,15 +22,18 @@ class NumericalIntegrationSettings(BaseModel):
function_evaluations_per_time_step: str
avg_function_evaluations_per_time_step: str
+
class SurfaceWindConditions(BaseModel):
frontal_surface_wind_speed: str
lateral_surface_wind_speed: str
+
class LaunchRailConditions(BaseModel):
rail_length: str
flight_inclination: str
flight_heading: str
+
class OutOfRailConditions(BaseModel):
out_of_rail_time: str
out_of_rail_velocity: str
@@ -37,6 +42,7 @@ class OutOfRailConditions(BaseModel):
out_of_rail_thrust_weight_ratio: str
out_of_rail_reynolds_number: str
+
class BurnoutConditions(BaseModel):
burnout_time: str
burnout_rocket_velocity: str
@@ -45,11 +51,13 @@ class BurnoutConditions(BaseModel):
burnout_mach_number: str
burnout_kinetic_energy: str
+
class ApogeeConditions(BaseModel):
apogee_time: str
apogee_altitude: str
apogee_freestream_speed: str
+
class MaximumValues(BaseModel):
maximum_speed: str
maximum_mach_number: str
@@ -64,15 +72,18 @@ class MaximumValues(BaseModel):
maximum_lower_rail_button_normal_force: str
maximum_lower_rail_button_shear_force: str
+
class ImpactConditions(BaseModel):
x_impact_position: "Optional[str]"
y_impact_position: "Optional[str]"
time_of_impact: "Optional[str]"
impact_velocity: "Optional[str]"
+
class EventsRegistered(BaseModel):
events_trace: "Optional[Any]"
+
class FlightData(BaseModel):
initial_conditions: InitialConditions
numerical_integration_settings: NumericalIntegrationSettings
@@ -85,24 +96,30 @@ class FlightData(BaseModel):
impact_conditions: ImpactConditions
events_registered: "Optional[EventsRegistered]"
+
class FlightPlots(BaseModel):
pass
+
class FlightSummary(BaseModel):
flight_data: FlightData
- #flight_plots: FlightPlots
+ # flight_plots: FlightPlots
+
class FlightCreated(BaseModel):
- flight_id: str
+ flight_id: str
message: str = "Flight successfully created"
+
class FlightUpdated(BaseModel):
- new_flight_id: str
+ new_flight_id: str
message: str = "Flight successfully updated"
+
class FlightDeleted(BaseModel):
- deleted_flight_id: str
+ deleted_flight_id: str
message: str = "Flight successfully deleted"
+
class FlightPickle(BaseModel):
jsonpickle_rocketpy_flight: str
diff --git a/lib/views/motor.py b/lib/views/motor.py
index 402477a..0be590e 100644
--- a/lib/views/motor.py
+++ b/lib/views/motor.py
@@ -1,6 +1,7 @@
from typing import List, Any
from pydantic import BaseModel
+
class MotorData(BaseModel):
total_burning_time: str
total_propellant_mass: str
@@ -9,6 +10,7 @@ class MotorData(BaseModel):
maximum_thrust: str
total_impulse: str
+
class MotorPlots(BaseModel):
thrust: List[Any]
total_mass: List[Any]
@@ -20,21 +22,26 @@ class MotorPlots(BaseModel):
i_13: List[Any]
i_23: List[Any]
+
class MotorSummary(BaseModel):
motor_data: MotorData
- #motor_plots: MotorPlots
+ # motor_plots: MotorPlots
+
class MotorCreated(BaseModel):
- motor_id: str
+ motor_id: str
message: str = "Motor successfully created"
+
class MotorUpdated(BaseModel):
- new_motor_id: str
+ new_motor_id: str
message: str = "Motor successfully updated"
+
class MotorDeleted(BaseModel):
- deleted_motor_id: str
+ deleted_motor_id: str
message: str = "Motor successfully deleted"
+
class MotorPickle(BaseModel):
jsonpickle_rocketpy_motor: str
diff --git a/lib/views/rocket.py b/lib/views/rocket.py
index f7d184f..07ee848 100644
--- a/lib/views/rocket.py
+++ b/lib/views/rocket.py
@@ -1,11 +1,13 @@
from typing import List, Any, Optional
from pydantic import BaseModel
+
class InertiaDetails(BaseModel):
rocket_mass_without_propellant: str
rocket_mass_with_propellant: str
rocket_inertia_with_motor_without_propellant: "List[str]"
+
class RocketGeometricalParameters(BaseModel):
rocket_maximum_radius: str
rocket_frontal_area: str
@@ -13,6 +15,7 @@ class RocketGeometricalParameters(BaseModel):
rocket_codm_center_of_propellant_mass: str
rocket_codm_loaded_center_of_mass: str
+
class RocketAerodynamicsQuantities(BaseModel):
aerodynamics_lift_coefficient_derivatives: "Any"
aerodynamics_center_of_pressure: "Any"
@@ -20,36 +23,44 @@ class RocketAerodynamicsQuantities(BaseModel):
initial_static_margin: str
final_static_margin: str
+
class ParachuteData(BaseModel):
parachute_details: "Any"
# parachute_ejection_signal_trigger: "Any"
parachute_ejection_system_refresh_rate: "Optional[Any]"
parachute_lag: "Any"
+
class RocketData(BaseModel):
inertia_details: InertiaDetails
rocket_geometrical_parameters: RocketGeometricalParameters
rocket_aerodynamics_quantities: RocketAerodynamicsQuantities
parachute_data: ParachuteData
+
class RocketPlots(BaseModel):
pass
+
class RocketSummary(BaseModel):
rocket_data: RocketData
- #rocket_plots: RocketPlots
+ # rocket_plots: RocketPlots
+
class RocketCreated(BaseModel):
rocket_id: str
message: str = "Rocket successfully created"
+
class RocketUpdated(BaseModel):
- new_rocket_id: str
+ new_rocket_id: str
message: str = "Rocket successfully updated"
+
class RocketDeleted(BaseModel):
- deleted_rocket_id: str
+ deleted_rocket_id: str
message: str = "Rocket successfully deleted"
+
class RocketPickle(BaseModel):
jsonpickle_rocketpy_rocket: str
diff --git a/test/Infinity-API.postman_collection.json b/test/Infinity-API.postman_collection.json
index 203e044..4ff23fc 100644
--- a/test/Infinity-API.postman_collection.json
+++ b/test/Infinity-API.postman_collection.json
@@ -2,7 +2,7 @@
"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 \n- GET `api/artifact/{{artifact_id}}` { Artifact }\n \n- GET `api/rocketpy/artifact/{{artifact_id}}` { json_pickle_string_artifact }\n \n- GET `api/simulate/artifact/{{artifact_id}}` { ArtifactSimulationSummary }\n \n- PUT `api/artifact/{{artifact_id}}` { message, new_artifact_id }\n \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## **Disclaimer**\n\nCurrently the API only supports Solid motors and TrapezoidalFins, sorry for that, we are working to expand its capabilities soon.\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/)",
+ "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"
@@ -398,849 +398,2647 @@
"name": "Flight",
"item": [
{
- "name": "Create Flight",
- "event": [
+ "name": "Hybrid",
+ "item": [
{
- "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"
- }
+ "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": []
},
{
- "listen": "prerequest",
- "script": {
- "exec": [
- ""
- ],
- "type": "text/javascript"
- }
- }
- ],
- "request": {
- "method": "POST",
- "header": [],
- "body": {
- "mode": "raw",
- "raw": "{\n \"rail_length\": 5.2,\n \"inclination\": 85,\n \"heading\": 0,\n \"environment\": {\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1405,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n },\n \"rocket\": {\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"inertia\": [\n 6.321, \n 6.321, \n 0.0346\n ],\n \"power_off_drag\": \"calisto\",\n \"power_on_drag\": \"calisto\",\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"motor_position\": -1.255,\n \"rail_buttons\": {\n \"upper_button_position\": -0.5,\n \"lower_button_position\": 0.2,\n \"angular_position\": 45\n },\n \"motor\": {\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n },\n \"nose\": {\n \"length\": 0.55829,\n \"kind\": \"vonKarman\",\n \"position\": 1.278,\n \"base_radius\": 0.0635,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"n\": 4,\n \"root_chord\": 0.12,\n \"tip_chord\": 0.04,\n \"span\": 0.1,\n \"position\": -1.04956,\n \"cant_angle\": 0,\n \"radius\": 0.0635,\n \"airfoil\": \"\"\n },\n \"tail\": {\n \"top_radius\": 0.0635,\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635\n },\n \"parachutes\": {\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"cd_s\": [\n 10,\n 1\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"lag\": [\n 1.5,\n 1.5\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 \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n }\n } \n}",
- "options": {
- "raw": {
- "language": "json"
+ "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": []
},
- "url": {
- "raw": "{{endpoint}}/flights/",
- "host": [
- "{{endpoint}}"
+ {
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- ""
- ]
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{endpoint}}/flights/rocketpy/{{flight_id}}",
+ "host": [
+ "{{endpoint}}"
+ ],
+ "path": [
+ "flights",
+ "rocketpy",
+ "{{flight_id}}"
+ ]
+ }
+ },
+ "response": []
},
- "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}}"
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "{{flight_id}}"
- ]
- }
- },
- "response": []
- },
- {
- "name": "Read rocketpy Flight",
- "event": [
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{endpoint}}/flights/{{flight_id}}/simulate",
+ "host": [
+ "{{endpoint}}"
+ ],
+ "path": [
+ "flights",
+ "{{flight_id}}",
+ "simulate"
+ ]
+ }
+ },
+ "response": []
+ },
{
- "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}}"
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "rocketpy",
- "{{flight_id}}"
- ]
- }
- },
- "response": []
- },
- {
- "name": "Simulate Flight",
- "event": [
+ "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": []
+ },
{
- "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}}"
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "{{flight_id}}",
- "simulate"
- ]
+ "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": []
}
- },
- "response": []
+ ]
},
{
- "name": "Update Flight",
- "event": [
+ "name": "Liquid",
+ "item": [
{
- "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"
- }
+ "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": []
},
{
- "listen": "prerequest",
- "script": {
- "exec": [
- ""
- ],
- "type": "text/javascript"
- }
- }
- ],
- "request": {
- "method": "PUT",
- "header": [],
- "body": {
- "mode": "raw",
- "raw": "{\n \"rail_length\": 5.2,\n \"inclination\": 85,\n \"heading\": 0,\n \"environment\": {\n \"latitude\": 0,\n \"longitude\": 0,\n \"elevation\": 1405,\n \"atmospheric_model_type\": \"standard_atmosphere\",\n \"atmospheric_model_file\": \"GFS\",\n \"date\": \"2023-05-09T16:30:50.065992\"\n },\n \"rocket\": {\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"inertia\": [\n 6.321, \n 6.321, \n 0.0346\n ],\n \"power_off_drag\": \"calisto\",\n \"power_on_drag\": \"calisto\",\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"motor_position\": -1.255,\n \"rail_buttons\": {\n \"upper_button_position\": -0.5,\n \"lower_button_position\": 0.2,\n \"angular_position\": 45\n },\n \"motor\": {\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n },\n \"nose\": {\n \"length\": 0.55829,\n \"kind\": \"vonKarman\",\n \"position\": 1.278,\n \"base_radius\": 0.0635,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"n\": 4,\n \"root_chord\": 0.12,\n \"tip_chord\": 0.04,\n \"span\": 0.1,\n \"position\": -1.04956,\n \"cant_angle\": 0,\n \"radius\": 0.0635,\n \"airfoil\": \"\"\n },\n \"tail\": {\n \"top_radius\": 0.0635,\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635\n },\n \"parachutes\": {\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"cd_s\": [\n 10,\n 1\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"lag\": [\n 1.5,\n 1.5\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 \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n }\n } \n}",
- "options": {
- "raw": {
- "language": "json"
+ "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": []
},
- "url": {
- "raw": "{{endpoint}}/flights/{{flight_id}}",
- "host": [
- "{{endpoint}}"
+ {
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "{{flight_id}}"
- ]
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{endpoint}}/flights/rocketpy/{{flight_id}}",
+ "host": [
+ "{{endpoint}}"
+ ],
+ "path": [
+ "flights",
+ "rocketpy",
+ "{{flight_id}}"
+ ]
+ }
+ },
+ "response": []
},
- "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"
- }
+ "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": []
},
{
- "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"
+ "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": []
},
- "url": {
- "raw": "{{endpoint}}/flights/{{flight_id}}/env",
- "host": [
- "{{endpoint}}"
+ {
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "{{flight_id}}",
- "env"
- ]
+ "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": []
},
- "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": "Update Flight Rocket",
- "event": [
+ "name": "Solid",
+ "item": [
{
- "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"
- }
+ "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": []
},
{
- "listen": "prerequest",
- "script": {
- "exec": [
- ""
- ],
- "type": "text/javascript"
- }
- }
- ],
- "request": {
- "method": "PUT",
- "header": [],
- "body": {
- "mode": "raw",
- "raw": "{\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"inertia\": [\n 6.321, \n 6.321, \n 0.0346\n ],\n \"power_off_drag\": \"calisto\",\n \"power_on_drag\": \"calisto\",\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"motor_position\": -1.255,\n \"rail_buttons\": {\n \"upper_button_position\": -0.5,\n \"lower_button_position\": 0.2,\n \"angular_position\": 45\n },\n \"motor\": {\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n },\n \"nose\": {\n \"length\": 0.55829,\n \"kind\": \"vonKarman\",\n \"position\": 1.278,\n \"base_radius\": 0.0635,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"n\": 4,\n \"root_chord\": 0.12,\n \"tip_chord\": 0.04,\n \"span\": 0.1,\n \"position\": -1.04956,\n \"cant_angle\": 0,\n \"radius\": 0.0635,\n \"airfoil\": \"\"\n },\n \"tail\": {\n \"top_radius\": 0.0635,\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635\n },\n \"parachutes\": {\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"cd_s\": [\n 10,\n 1\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"lag\": [\n 1.5,\n 1.5\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 \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n } \n}",
- "options": {
- "raw": {
- "language": "json"
+ "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": []
},
- "url": {
- "raw": "{{endpoint}}/flights/{{flight_id}}/rocket",
- "host": [
- "{{endpoint}}"
+ {
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "{{flight_id}}",
- "rocket"
- ]
+ "request": {
+ "method": "GET",
+ "header": [],
+ "url": {
+ "raw": "{{endpoint}}/flights/rocketpy/{{flight_id}}",
+ "host": [
+ "{{endpoint}}"
+ ],
+ "path": [
+ "flights",
+ "rocketpy",
+ "{{flight_id}}"
+ ]
+ }
+ },
+ "response": []
},
- "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}}"
+ "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"
+ }
+ }
],
- "path": [
- "flights",
- "{{flight_id}}"
- ]
+ "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": []
}
- },
- "response": []
+ ]
}
]
},
@@ -1314,7 +3112,7 @@
"header": [],
"body": {
"mode": "raw",
- "raw": "{\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n}",
+ "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"
@@ -1322,13 +3120,19 @@
}
},
"url": {
- "raw": "{{endpoint}}/motors/",
+ "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."
@@ -1562,7 +3366,7 @@
"header": [],
"body": {
"mode": "raw",
- "raw": "{\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n}",
+ "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"
@@ -1570,13 +3374,20 @@
}
},
"url": {
- "raw": "{{endpoint}}/motors/{{motor_id}}",
+ "raw": "{{endpoint}}/motors/{{motor_id}}/?motor_kind=Liquid",
"host": [
"{{endpoint}}"
],
"path": [
"motors",
- "{{motor_id}}"
+ "{{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."
@@ -1747,7 +3558,7 @@
"header": [],
"body": {
"mode": "raw",
- "raw": "{\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"inertia\": [\n 6.321, \n 6.321, \n 0.0346\n ],\n \"power_off_drag\": \"calisto\",\n \"power_on_drag\": \"calisto\",\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"motor_position\": -1.255,\n \"rail_buttons\": {\n \"upper_button_position\": -0.5,\n \"lower_button_position\": 0.2,\n \"angular_position\": 45\n },\n \"motor\": {\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n },\n \"nose\": {\n \"length\": 0.55829,\n \"kind\": \"vonKarman\",\n \"position\": 1.278,\n \"base_radius\": 0.0635,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"n\": 4,\n \"root_chord\": 0.12,\n \"tip_chord\": 0.04,\n \"span\": 0.1,\n \"position\": -1.04956,\n \"cant_angle\": 0,\n \"radius\": 0.0635,\n \"airfoil\": \"\"\n },\n \"tail\": {\n \"top_radius\": 0.0635,\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635\n },\n \"parachutes\": {\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"cd_s\": [\n 10,\n 1\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"lag\": [\n 1.5,\n 1.5\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 \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n } \n}",
+ "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"
@@ -1755,13 +3566,23 @@
}
},
"url": {
- "raw": "{{endpoint}}/rockets/",
+ "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."
@@ -2101,7 +3922,7 @@
"header": [],
"body": {
"mode": "raw",
- "raw": "{\n \"radius\": 0.0632,\n \"mass\": 16.235,\n \"inertia\": [\n 6.321, \n 6.321, \n 0.0346\n ],\n \"power_off_drag\": \"calisto\",\n \"power_on_drag\": \"calisto\",\n \"center_of_mass_without_motor\": 0,\n \"coordinate_system_orientation\": \"tail_to_nose\",\n \"motor_position\": -1.255,\n \"rail_buttons\": {\n \"upper_button_position\": -0.5,\n \"lower_button_position\": 0.2,\n \"angular_position\": 45\n },\n \"motor\": {\n \"burn_time\": 3.9,\n \"dry_mass\": 1.815,\n \"dry_inertia\": [0.125, 0.125, 0.002],\n \"center_of_dry_mass_position\": 0.317,\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 \"thrust_source\": \"Cesaroni_M1670\", \n \"nozzle_radius\": 0.033,\n \"throat_radius\": 0.011,\n \"interpolation_method\": \"linear\",\n \"coordinate_system_orientation\": \"nozzle_to_combustion_chamber\"\n },\n \"nose\": {\n \"length\": 0.55829,\n \"kind\": \"vonKarman\",\n \"position\": 1.278,\n \"base_radius\": 0.0635,\n \"rocket_radius\": 0.0635\n },\n \"fins\": {\n \"n\": 4,\n \"root_chord\": 0.12,\n \"tip_chord\": 0.04,\n \"span\": 0.1,\n \"position\": -1.04956,\n \"cant_angle\": 0,\n \"radius\": 0.0635,\n \"airfoil\": \"\"\n },\n \"tail\": {\n \"top_radius\": 0.0635,\n \"bottom_radius\": 0.0435,\n \"length\": 0.06,\n \"position\": -1.194656,\n \"radius\": 0.0635\n },\n \"parachutes\": {\n \"name\": [\n \"Main\",\n \"Drogue\"\n ],\n \"cd_s\": [\n 10,\n 1\n ],\n \"sampling_rate\": [\n 105,\n 105\n ],\n \"lag\": [\n 1.5,\n 1.5\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 \"triggers\": [\n \"lambda p, h, y: y[5] < 0 and h < 800\",\n \"lambda p, h, y: y[5] < 0\"\n ]\n } \n}",
+ "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"
@@ -2109,13 +3930,24 @@
}
},
"url": {
- "raw": "{{endpoint}}/rockets/{{rocket_id}}",
+ "raw": "{{endpoint}}/rockets/{{rocket_id}}/?rocket_option=Calisto&motor_kind=Hybrid",
"host": [
"{{endpoint}}"
],
"path": [
"rockets",
- "{{rocket_id}}"
+ "{{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."