Skip to content

Commit

Permalink
Moved aircraft type data to external files.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanwatsonforster committed Sep 25, 2023
1 parent 1888e23 commit fc9e0bc
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 91 deletions.
44 changes: 25 additions & 19 deletions airpower/aircraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,24 +443,30 @@ def startmove(self, flighttype, powerap, actions):
raise ValueError("invalid flight type %s." % flighttype)

# TODO: Don't assume CL.
powerchart = self._aircrafttype.powerchart("CL")
powerapMIL = self._aircrafttype.power("CL", "MIL")
powerapAB = self._aircrafttype.power("CL", "AB")
if powerap == "IDLE":
powersetting = "IDLE"
powerap = 0
elif powerap == "NOR" or powerap == 0:
powersetting = "NOR"
powerap = 0
elif powerap == "MIL" or (powerap == "AB" and "AB" in powerchart):
powersetting = powerap
powerap = powerchart[powersetting]
powerap = 0
elif powerap == "MIL":
powersetting = "MIL"
powerap = powerapMIL
elif powerap == "AB" and powerapAB == None:
raise ValueError("aircraft does not have AB.")
elif powerap == "AB":
powersetting = "AB"
powerap = powerapAB
elif not isinstance(powerap, (int, float)) or powerap < 0 or powerap % 0.5 != 0:
raise ValueError("invalid power AP %s" % powerap)
elif powerap <= powerchart["MIL"]:
raise ValueError("invalid power %s" % powerap)
elif powerap <= powerapMIL:
powersetting = "MIL"
elif "AB" in powerchart and powerap <= powerchart["AB"]:
elif powerapAB != None and powerap <= powerapAB:
powersetting = "AB"
else:
raise ValueError("requested power %s APs exceeds aircraft capability.")
raise ValueError("requested power of %s APs exceeds aircraft capability.")

self._restore(apturn.turn() - 1)

Expand Down Expand Up @@ -512,12 +518,11 @@ def startmove(self, flighttype, powerap, actions):

# See rule 6.1.
if powersetting == "IDLE":
self._log("reducing speed by 0.5 as the power setting is IDLE.")
self._speed -= 0.5

# See rule 6.2.
if self._speed <= 0:
self._speed = 0
idlefp = self._aircrafttype.power("CL", "IDLE")
# This keeps the speed non-negative. See rule 6.2.
idlefp = min(idlefp, self._speed)
self._log("reducing speed by %.1f as the power setting is IDLE." % idlefp)
self._speed -= idlefp

# See rule 6.1.
if self._lastpowersetting == "IDLE" and self._powersetting == "AB" and not self._aircrafttype.hasproperty("RPR"):
Expand All @@ -528,13 +533,14 @@ def startmove(self, flighttype, powerap, actions):
self._log("insufficient power above cruise speed.")
self._powerap -= 1.0

# See rule 6.6.
m1 = self._m1()
if self._speed >= m1:
speed = "%.1f (SSS)" % self._speed
speed = "%.1f (SS)" % self._speed
elif self._speed == m1 - 0.5:
speed = "%.1f (HTS)" % self._speed
speed = "%.1f (HT)" % self._speed
elif self._speed == m1 - 1.0:
speed = "%.1f (LTS)" % self._speed
speed = "%.1f (LT)" % self._speed
else:
speed = "%.1f" % self._speed
self._log("speed is %s and %.1f FPs are available." % (speed, self._fp))
Expand Down Expand Up @@ -591,7 +597,7 @@ def _endmove(self):
else:
# TODO: Don't assume CL.
# TODO: Calculate this at the moment of the maximum turn, since it depends on the configuration.
turnap = -self._aircrafttype.turndragchart("CL")[self._maxturnrate]
turnap = -self._aircrafttype.turndrag("CL", self._maxturnrate)

self._log("power APs = %+.1f." % self._powerap)
self._log("turn APs = %+.1f and %+.1f." % (turnap, self._sustainedturnap))
Expand Down
120 changes: 48 additions & 72 deletions airpower/aircrafttype.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,74 @@
import json

class aircrafttype:

def __init__(self, name):
self._name = name
# TODO: Look for the file using a relative path.
filename = "/content/src/airpower/aircrafttypes/%s.json" % name
# TODO: Handle errors.
self._data = json.load(open(filename, "r", encoding="utf-8"))
assert name == self._data["name"]

def power(self, configuration, setting):
if not setting in self._data["powertable"][configuration]:
return None
else:
return self._data["powertable"][configuration][setting]

def powerchart(self, configuration):
if self._name == "F-80C":
return {
"CL" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, },
"1/2" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, },
"DT" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, },
"FUEL": { "IDLE": 0.0, "NOR": 0.5, "MIL": 1.0, }
}[configuration]
elif self._name == "F-84E":
return {
"CL" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5, },
"1/2" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 0.5, "SPBR": 0.5, },
"DT" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 0.5, "SPBR": 1.0, },
"FUEL": { "IDLE": 0.0, "NOR": 0.5, "MIL": 1.0, }
}[configuration]
def SPBR(self, configuration):
return self._data["powertable"][configuration]["SPBR"]

def turndragchart(self, configuration):
if self._name == "F-80C":
return {
"CL" : { "TT": 0.0, "HT": 1.0, "BT": 1.0, },
"1/2": { "TT": 0.0, "HT": 1.0, "BT": 1.0, },
"DT" : { "TT": 0.0, "HT": 1.0, "BT": 2.0, },
}[configuration]
elif self._name == "F-84E":
return {
"CL" : { "TT": 0.0, "HT": 1.0, "BT": 2.0, },
"1/2": { "TT": 1.0, "HT": 2.0, "BT": 2.0, },
"DT" : { "TT": 1.0, "HT": 2.0, "BT": 2.0, },
}[configuration]
def fuelrate(self, setting):
if not setting in self._data["powertable"]["FUEL"]:
return None
else:
return self._data["powertable"]["FUEL"][setting]

def turndrag(self, configuration, turnrate):
if not turnrate in self._data["turndragtable"][configuration]:
return None
else:
return self._data["turndragtable"][configuration][turnrate]

def minspeed(self, configuration, altitudeband):
if altitudeband == "UH":
altitudeband = "EH"
if self._name == "F-80C":
return {
"CL" : { "LO": 1.5, "ML": 1.5, "MH": 2.0, "HI": 2.0, "VH": 2.5, "EH": 0.0, },
"1/2": { "LO": 1.5, "ML": 2.0, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0, },
"DT" : { "LO": 2.0, "ML": 2.0, "MH": 2.5, "HI": 2.5, "VH": 0.0, "EH": 0.0, },
}[configuration][altitudeband]
elif self._name == "F-84E":
return {
"CL" : { "LO": 1.5, "ML": 1.5, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0, },
"1/2": { "LO": 1.5, "ML": 2.0, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0, },
"DT" : { "LO": 2.0, "ML": 2.0, "MH": 2.5, "HI": 0.0, "VH": 0.0, "EH": 0.0, },
}[configuration][altitudeband]
if not altitudeband in self._data["minspeedtable"][configuration]:
return None
else:
return self._data["minspeedtable"][configuration][altitudeband]

def maxspeed(self, configuration, altitudeband):
if altitudeband == "UH":
altitudeband = "EH"
if self._name == "F-80C":
return {
"CL" : { "LO": 5.5, "ML": 5.5, "MH": 5.0, "HI": 4.5, "VH": 4.0, "EH": 0.0, },
"1/2": { "LO": 5.5, "ML": 5.0, "MH": 4.5, "HI": 4.5, "VH": 4.0, "EH": 0.0, },
"DT" : { "LO": 5.0, "ML": 4.5, "MH": 4.5, "HI": 4.0, "VH": 0.0, "EH": 0.0, },
}[configuration][altitudeband]
elif self._name == "F-84E":
return {
"CL" : { "LO": 6.0, "ML": 6.0, "MH": 5.5, "HI": 5.5, "VH": 5.5, "EH": 0.0, },
"1/2": { "LO": 5.5, "ML": 5.5, "MH": 5.5, "HI": 5.0, "VH": 5.0, "EH": 0.0, },
"DT" : { "LO": 5.5, "ML": 5.0, "MH": 5.5, "HI": 0.0, "VH": 0.0, "EH": 0.0, },
}[configuration][altitudeband]
return self._data["maxspeedtable"][configuration][altitudeband]

def cruisespeed(self):
if self._name == "F-80C":
return 4.0
elif self._name == "F-84E":
return 4.5
return self._data["cruisespeed"]

def climbspeed(self):
if self._name == "F-80C":
return 3.0
elif self._name == "F-84E":
return 3.5
return self._data["climbspeed"]

def divespeed(self, altitudeband):
if altitudeband == "UH":
altitudeband = "EH"
if self._name == "F-80C":
return { "LO": 6.5, "ML": 6.5, "MH": 6.5, "HI": 6.5, "VH": 6.0, "EH": 0.0, }[altitudeband]
elif self._name == "F-84E":
return { "LO": 7.0, "ML": 7.0, "MH": 6.5, "HI": 6.5, "VH": 6.0, "EH": 0.0, }[altitudeband]
if not altitudeband in self._data["divespeedtable"]:
return None
else:
return self._data["divespeedtable"][altitudeband]

def ceiling(self, configuration):
if self._name == "F-80C":
return { "CL": 45, "1/2": 40, "DT": 35, }[configuration]
elif self._name == "F-84E":
return { "CL": 41, "1/2": 36, "DT": 30, }[configuration]
return self._data["ceilingtable"][configuration]

def rollhfp(self):
return self._data["maneuvertable"]["LR/DR"]["HFP"]

def rolldrag(self, rolltype):
assert rolltype in [ "VR", "LR", "DR" ]
if rolltype != "VR":
rolltype == "LR/DR"
return self._data["maneuvertable"][rolltype]["DP"]

def hasproperty(self, p):
if self._name == "F-80C":
return p in ["HTD"]
elif self._name == "F-84E":
return p in ["HTD"]
return p in self._data["properties"]
34 changes: 34 additions & 0 deletions airpower/aircrafttypes/F-80C.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "F-80C",
"origin": "TSOH",
"powertable": {
"CL" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5 },
"1/2" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5 },
"DT" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5 },
"FUEL": { "IDLE": 0.0, "NOR": 0.5, "MIL": 1.0 }
},
"maneuvertable": {
"LR/DR": { "HFP": 1.0, "DP": 1.5 },
"VR": { "DP": 0.5 }
},
"turndragtable": {
"CL" : { "TT": 0.0, "HT": 1.0, "BT": 1.0 },
"1/2": { "TT": 0.0, "HT": 1.0, "BT": 1.0 },
"DT" : { "TT": 0.0, "HT": 1.0, "BT": 2.0 }
},
"minspeedtable": {
"CL" : { "LO": 1.5, "ML": 1.5, "MH": 2.0, "HI": 2.0, "VH": 2.5, "EH": 0.0 },
"1/2": { "LO": 1.5, "ML": 2.0, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0 },
"DT" : { "LO": 2.0, "ML": 2.0, "MH": 2.5, "HI": 2.5, "VH": 0.0, "EH": 0.0 }
},
"maxspeedtable": {
"CL" : { "LO": 5.5, "ML": 5.5, "MH": 5.0, "HI": 4.5, "VH": 4.0, "EH": 0.0 },
"1/2": { "LO": 5.5, "ML": 5.0, "MH": 4.5, "HI": 4.5, "VH": 4.0, "EH": 0.0 },
"DT" : { "LO": 5.0, "ML": 4.5, "MH": 4.5, "HI": 4.0, "VH": 0.0, "EH": 0.0 }
},
"cruisespeed": 4.0,
"climbspeed": 3.0,
"divespeedtable": { "LO": 6.5, "ML": 6.5, "MH": 6.5, "HI": 6.5, "VH": 6.0, "EH": 0.0 },
"ceilingtable": { "CL": 45, "1/2": 40, "DT": 35 },
"properties": [ "HTD" ]
}
34 changes: 34 additions & 0 deletions airpower/aircrafttypes/F-84E.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "F-84E",
"origin": "TSOH",
"powertable": {
"CL" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 1.0, "SPBR": 0.5 },
"1/2" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 0.5, "SPBR": 0.5 },
"DT" : { "IDLE": 0.5, "NOR": 0.0, "MIL": 0.5, "SPBR": 1.0 },
"FUEL": { "IDLE": 0.0, "NOR": 0.5, "MIL": 1.0 }
},
"maneuvertable": {
"LR/DR": { "HFP": 1.0, "DP": 1.5 },
"VR": { "DP": 0.5 }
},
"turndragtable": {
"CL" : { "TT": 0.0, "HT": 1.0, "BT": 2.0 },
"1/2": { "TT": 1.0, "HT": 2.0, "BT": 2.0 },
"DT" : { "TT": 1.0, "HT": 2.0, "BT": 2.0 }
},
"minspeedtable": {
"CL" : { "LO": 1.5, "ML": 1.5, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0 },
"1/2": { "LO": 1.5, "ML": 2.0, "MH": 2.0, "HI": 2.5, "VH": 2.5, "EH": 0.0 },
"DT" : { "LO": 2.0, "ML": 2.0, "MH": 2.5, "HI": 0.0, "VH": 0.0, "EH": 0.0 }
},
"maxspeedtable": {
"CL" : { "LO": 6.0, "ML": 6.0, "MH": 5.5, "HI": 5.5, "VH": 5.5, "EH": 0.0 },
"1/2": { "LO": 5.5, "ML": 5.5, "MH": 5.5, "HI": 5.0, "VH": 5.0, "EH": 0.0 },
"DT" : { "LO": 5.5, "ML": 5.0, "MH": 5.5, "HI": 0.0, "VH": 0.0, "EH": 0.0 }
},
"cruisespeed": 4.5,
"climbspeed": 3.5,
"divespeedtable": { "LO": 7.0, "ML": 7.0, "MH": 6.5, "HI": 6.5, "VH": 6.0, "EH": 0.0 },
"ceilingtable": { "CL": 41, "1/2": 36, "DT": 30 },
"properties": [ "HTD" ]
}

0 comments on commit fc9e0bc

Please sign in to comment.