Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .coverage
Binary file not shown.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,20 @@ The following is the format you'll have to use in your `.json` input files:
```json
{
"Engine" : {
"Specific Impulse (s)" : 318,
"Thrust (N)" : 500
"Type" : "Liquid",
"Specific impulse (s)" : 318,
"Thrust (N)" : 500
},
"Fuel" : {
"Oxidizer/Fuel Mixture Ratio" : 15,
"Fuel Reserve (%)" : 5
"Oxidizer/fuel mixture ratio" : 15,
"Fuel reserve (%)" : 5
},
"Mass" : {
"Dry Mass (kg)" : 10
"Dry Mass (kg)" : 10
},
"Aerodynamics" : {
"Drag Coefficient" : 0.0556,
"Cross-section (m2)" : 0.0255364
"Drag coefficient" : 0.0556,
"Cross-section (m2)" : 0.0255364
},
"Environment" : {
"Elevation (m)" : 113,
Expand All @@ -83,11 +84,11 @@ The following is the format you'll have to use in your `.json` input files:
"Air molar mass (kg/mol)" : 0.02896968,
"Gas constant (J/(K.mol))" : 8.314462618,
"Air heat capacity ratio" : 1.4,
"Standard Atmospheric pressure @SL (Pa)" : 101325
"Standard atmospheric pressure @SL (Pa)" : 101325
},
"Output" : {
"Log File Path" : "path/to/Flight.log",
"CSV File Path" : "path/to/Flight.csv"
".log file" : "Flight.log",
".csv file" : "Flight.csv"
}
}
```
Expand Down
1 change: 1 addition & 0 deletions REQUIREMENTS.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
matplotlib
numpy
coverage
pytest
pytest-cov
Expand Down
2 changes: 1 addition & 1 deletion preflightpy/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Environment:

def __init__(self, vars):
# Environmental Constants
self.elev, self.t, self.g, self.M_air, self.R, self.gamma, self.Pstatic = vars # noqa
self.elev, self.t, self.g, self.M_air, self.R, self.gamma, self.P_zero = vars # noqa
self.g_zero = self.g
self.Re = 6356766
self.hb = [ # Layer base altitudes
Expand Down
4 changes: 0 additions & 4 deletions preflightpy/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,3 @@ def cast(self, x):
return float(x)
except Exception:
return str(x)

# TEMP: for testing purposes
# p = Params()
# print(p.package, len(str(p.package)), type(p.package[0][1]))
157 changes: 98 additions & 59 deletions preflightpy/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,46 +29,73 @@ def __init__(self, params, env, burn_time: float):
p = params
# Environment
self.env = env

# Burn time
self.num_steps = int(burn_time/self.env.t)
self.num_steps = int(burn_time // self.env.t)
self.burn_time = self.num_steps * self.env.t

# Engine specs
self.isp, self.Fthrust = p.package[0]
self.etype = p.package[0][0]
p.package[0].pop(0)
if self.etype == "Liquid":
self.isp, self.thrust = p.package[0]
elif self.etype == "Solid":
self.isp, self.avg_thrust, path = p.package[0] # noqa
with(open(path)) as f:
csv_reader = csv.reader(f)
self.thrust_curve = {}
for row in csv_reader:
self.thrust_curve.update({
float(row[0]): float(row[1])
})
f.close()

# Fuel Specs
self.OFratio, self.Reserve = p.package[1]
if self.etype == "Liquid":
self.OFratio, self.Reserve = p.package[1]
elif self.etype == "Solid":
self.OFratio = 0
self.Reserve = p.package[1][0]
# Flow Rate
self.w = (self.Fthrust/self.env.g_zero)/self.isp
self.dF = self.w * (1/(self.OFratio+1))
if self.etype == "Liquid":
self.w = (self.thrust/self.env.g_zero)/self.isp
elif self.etype == "Solid":
self.w = (self.avg_thrust/self.env.g_zero)/self.isp
self.dF = self.w * (1 / (self.OFratio + 1))
self.dOx = (self.w - self.dF)

# Fuel & Oxidizer
self.F = (self.dF * self.burn_time)/(1 - self.Reserve/100)
self.Ox = (self.dOx * self.burn_time)/(1 - self.Reserve/100)

# Mass
self.frameM = p.package[2][0]
self.dry_mass = p.package[2][0]

# Aerodynamics
self.Cd, self.Aproj = p.package[3]
self.Cd, self.cross_section = p.package[3]

# Output
self.logout, self.csvout = p.package[4]

open(self.logout, "w").close()

self.field_names = [
"t",
"Fthrust",
"Fdrag",
"thrust",
"drag",
"m",
"v",
"Mach",
"mach",
"a",
"altitude",
"asl",
"twr",
"maxV",
"maxMach",
"maxAcc",
"minAcc",
"maxG",
"minG"
"max_v",
"max_mach",
"max_acc",
"min_acc",
"max_g",
"min_g"
]
with open(self.csvout, "w", newline="") as f:
csv_writer = csv.writer(f)
Expand All @@ -78,25 +105,26 @@ def __init__(self, params, env, burn_time: float):
# Flight
def launch(self):
"""Runs a simulation within the given parameters."""
# Variable setup
# Variables setup
self.t = 0
self.altitude = 0
self.asl = self.altitude + self.env.elev
self.calc_mass()
self.env.get_status(self.asl)
self.calc_thrust()
self.calc_twr()
self.Fdrag = 0
self.drag = 0
self.v = 0
self.maxV = 0
self.Mach = 0
self.maxMach = 0
self.maxAcc = 0
self.maxG = 0
self.minAcc = 0
self.minG = 0
self.max_v = 0
self.mach = 0
self.max_mach = 0
self.max_acc = 0
self.max_g = 0
self.min_acc = 0
self.min_g = 0
self.a = 0
self.j = 0
self.s = 0
self.t = 0

# Used by matplotlib
self.plot_data = [
Expand All @@ -119,6 +147,8 @@ def launch(self):
self.add_data()
# Environment-related
self.update_env()
# Thrust-related
self.calc_thrust()
# Accelaration/derivative-related
self.calc_acc()
self.calc_additional_derivatives()
Expand All @@ -130,23 +160,20 @@ def launch(self):
self.calc_drag()
self.calc_twr()
# Mass-related
self.remove_fuel()
self.calc_propellant()
self.calc_mass()
# Time-related
self.t += self.env.t

if self.twr < 1:
raise RuntimeError("TWR below 1 : {}".format(self.twr))
if self.a > self.max_acc:
self.max_acc = self.a
self.max_g = self.max_acc/self.env.g

if self.a > self.maxAcc:
self.maxAcc = self.a
self.maxG = self.maxAcc/self.env.g
if self.v > self.max_v:
self.max_v = self.v
self.max_mach = self.mach

if self.v > self.maxV:
self.maxV = self.v
self.maxMach = self.Mach

self.Fthrust = 0
self.thrust = 0

# Deceleration phase
while self.v > 0:
Expand All @@ -169,29 +196,35 @@ def launch(self):
# Time-related
self.t += self.env.t

if self.a < self.minAcc:
self.minAcc = self.a
self.minG = self.minAcc/self.env.g
if self.a < self.min_acc:
self.min_acc = self.a
self.min_g = self.min_acc/self.env.g

self.output(
"maxV",
"maxMach",
"maxAcc",
"minAcc",
"maxG",
"minG"
"max_v",
"max_mach",
"max_acc",
"min_acc",
"max_g",
"min_g"
)

def suicide_burn(self):
"""Run a suicide burn simulation, will affct ascent simulation."""
self.Vt = math.sqrt((2 * self.m * self.env.g) / (self.env.Rho * self.Aproj * self.Cd)) # noqa
self.Vt = math.sqrt((2 * self.m * self.env.g) / (self.env.Rho * self.cross_section * self.Cd)) # noqa

# Mass
def calc_mass(self):
self.fuelM = (self.Ox + self.F)
self.m = self.fuelM + self.frameM

def remove_fuel(self):
self.propellant_mass = (self.Ox + self.F)
self.m = self.propellant_mass + self.dry_mass

def calc_propellant(self):
if self.etype == "Liquid":
self.w = (self.thrust/self.env.g_zero)/self.isp
elif self.etype == "Solid":
self.w = (self.avg_thrust/self.env.g_zero)/self.isp
self.dF = self.w * (1/(self.OFratio+1))
self.dOx = (self.w - self.dF)
self.Ox -= self.dOx * self.env.t
self.F -= self.dF * self.env.t

Expand All @@ -203,21 +236,27 @@ def set_altitude(self):
# Derivatives of position
def calc_velocity(self):
self.v += self.a * self.env.t
self.Mach = self.v/self.env.c
self.mach = self.v/self.env.c

def calc_acc(self):
self.a = (self.Fthrust - (self.m * self.env.g + self.Fdrag)) / self.m
self.a = (self.thrust - (self.m * self.env.g + self.drag)) / self.m

def calc_additional_derivatives(self):
self.j = (self.a - self.plot_data[4][-1]) / self.env.t
self.s = (self.j - self.plot_data[5][-1]) / self.env.t

# Forces
def calc_thrust(self):
if self.etype == "Liquid":
pass
elif self.etype == "Solid":
self.thrust = self.thrust_curve[round(self.t, 3)]

def calc_drag(self):
self.Fdrag = 0.5 * (self.env.Rho * self.v**2 * self.Cd * self.Aproj)
self.drag = 0.5 * (self.env.Rho * self.v**2 * self.Cd * self.cross_section) # noqa

def calc_twr(self):
self.twr = self.Fthrust / (self.m * self.env.g)
self.twr = self.thrust / (self.m * self.env.g)

# Environment
def update_env(self):
Expand Down Expand Up @@ -250,14 +289,14 @@ def add_data(self):
self.plot_data[4].append(self.a)
self.plot_data[5].append(self.j)
self.plot_data[6].append(self.s)
self.plot_data[7].append(self.Fdrag)
self.plot_data[7].append(self.drag)
self.output(
"t",
"Fthrust",
"Fdrag",
"thrust",
"drag",
"m",
"v",
"Mach",
"mach",
"a",
"altitude",
"asl",
Expand Down
15 changes: 8 additions & 7 deletions tests/input/case.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
{
"Engine" : {
"Specific Impulse (s)" : 318,
"Type" : "Liquid",
"Specific impulse (s)" : 318,
"Thrust (N)" : 500
},
"Fuel" : {
"Oxidizer/Fuel Mixture Ratio" : 15,
"Fuel Reserve (%)" : 5
"Oxidizer/fuel mixture ratio" : 15,
"Fuel reserve (%)" : 5
},
"Mass" : {
"Dry Mass (kg)" : 10
},
"Aerodynamics" : {
"Drag Coefficient" : 0.0556,
"Drag coefficient" : 0.0556,
"Cross-section (m2)" : 0.0255364
},
"Environment" : {
Expand All @@ -21,10 +22,10 @@
"Air molar mass (kg/mol)" : 0.02896968,
"Gas constant (J/(K.mol))" : 8.314462618,
"Air heat capacity ratio" : 1.4,
"Standard Atmospheric pressure @SL (Pa)" : 101325
"Standard atmospheric pressure @SL (Pa)" : 101325
},
"Output" : {
"Log File Path" : "Flight.log",
"CSV File Path" : "Flight.csv"
".log file" : "Flight.log",
".csv file" : "Flight.csv"
}
}
5 changes: 3 additions & 2 deletions tests/input/case.params
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Type : Solid
Specific impulse (s) : 318
Thrust (N) : 500
Average thrust (N) : 500
Thrust curve file path : tests/input/thrust.csv
================== ▲ Engine ▲ =================
Oxidizer/Fuel mixture ratio : 15
Fuel reserve (%) : 5
=================== ▲ Fuel ▲ ==================
Dry mass (kg) : 10
Expand Down
Loading