"""OpenAP kinematic model.
This module implements functions to access the WRAP kinematic model.
Examples:
WRAP model can be accessed as follows::
from openap import WRAP
wrap = WRAP(ac='A320')
wrap.cruise_mach()
with result::
{
'default': 0.78,
'minimum': 0.75,
'maximum': 0.8,
'statmodel': 'beta',
'statmodel_params': [17.82, 5.05, 0.62, 0.2]
}
"""
import glob
import os
import pandas as pd
curr_path = os.path.dirname(os.path.realpath(__file__))
dir_wrap = os.path.join(curr_path, "data/wrap/")
file_synonym = os.path.join(curr_path, "data/wrap/_synonym.csv")
wrap_synonym = pd.read_csv(file_synonym)
class WRAP:
"""Construct the kinematic model of the aircraft."""
def __init__(self, ac: str, **kwargs):
"""Initialize WRAP object.
Args:
ac: ICAO aircraft type (for example: A320).
"""
self.ac = ac.lower()
self.use_synonym = kwargs.get("use_synonym", True)
wrap_files = glob.glob(dir_wrap + "*.txt")
ac_wrap_available = [s[-8:-4].lower() for s in wrap_files]
if self.ac not in ac_wrap_available and not self.use_synonym:
raise ValueError((f"Kinematic model for {self.ac} not available."))
if self.ac not in ac_wrap_available and self.use_synonym:
syno = wrap_synonym.query("[email protected]")
if syno.shape[0] > 0:
self.ac = syno.new.iloc[0]
else:
raise ValueError(f"Kinematic model for {self.ac} not available.")
self.df = pd.read_fwf(os.path.join(dir_wrap, self.ac + ".txt"))
def _get_var(self, var):
r = self.df[self.df["variable"] == var]
if r.shape[0] == 0:
raise ValueError(f"Variable {var} not found")
v = r.values[0]
res = {
"default": v[3],
"minimum": v[4],
"maximum": v[5],
"statmodel": v[6],
"statmodel_params": [float(i) for i in v[7].split("|")],
}
return res
def takeoff_speed(self):
"""Get takeoff speed."""
return self._get_var("to_v_lof")
def takeoff_distance(self):
"""Get takeoff distance."""
return self._get_var("to_d_tof")
def takeoff_acceleration(self):
"""Get takeoff acceleration."""
return self._get_var("to_acc_tof")
def initclimb_vcas(self):
"""Get initial climb CAS."""
return self._get_var("ic_va_avg")
def initclimb_vs(self):
"""Get initial climb vertical rate."""
return self._get_var("ic_vs_avg")
def climb_range(self):
"""Get climb range distance (in km)."""
return self._get_var("cl_d_range")
def climb_const_vcas(self):
"""Get speed for constant CAS climb."""
return self._get_var("cl_v_cas_const")
def climb_const_mach(self):
"""Get speed during constant Mach climb."""
return self._get_var("cl_v_mach_const")
def climb_cross_alt_concas(self):
"""Get cross over altitude when constant CAS climb starts."""
return self._get_var("cl_h_cas_const")
def climb_cross_alt_conmach(self):
"""Get cross over altitude from constant CAS to Mach climb."""
return self._get_var("cl_h_mach_const")
def climb_vs_pre_concas(self):
"""Get vertical rate before constant CAS climb."""
return self._get_var("cl_vs_avg_pre_cas")
def climb_vs_concas(self):
"""Get vertical rate during constant CAS climb."""
return self._get_var("cl_vs_avg_cas_const")
def climb_vs_conmach(self):
"""Get vertical rate during constant Mach climb."""
return self._get_var("cl_vs_avg_mach_const")
def cruise_range(self):
"""Get cruise range."""
return self._get_var("cr_d_range")
def cruise_alt(self):
"""Get average cruise altitude."""
return self._get_var("cr_h_mean")
def cruise_init_alt(self):
"""Get initial cruise altitude."""
return self._get_var("cr_h_init")
def cruise_max_alt(self):
return self._get_var("cr_h_max")
def cruise_mach(self):
"""Get average cruise Mach number."""
return self._get_var("cr_v_mach_mean")
def cruise_max_mach(self):
return self._get_var("cr_v_mach_max")
def cruise_mean_vcas(self):
return self._get_var("cr_v_cas_mean")
def descent_range(self):
"""Get descent range."""
return self._get_var("de_d_range")
def descent_const_mach(self):
"""Get speed during the constant Mach descent."""
return self._get_var("de_v_mach_const")
def descent_const_vcas(self):
"""Get speed during the constant CAS descent."""
return self._get_var("de_v_cas_const")
def descent_cross_alt_conmach(self):
"""Get crossover altitude from constant Mach to CAS descent."""
return self._get_var("de_h_mach_const")
def descent_cross_alt_concas(self):
"""Get crossover altitude from constant Mach to CAS descent."""
return self._get_var("de_h_cas_const")
def descent_vs_conmach(self):
"""Get vertical rate during constant Mach descent."""
return self._get_var("de_vs_avg_mach_const")
def descent_vs_concas(self):
"""Get vertical rate during constant CAS descent."""
return self._get_var("de_vs_avg_cas_const")
def descent_vs_post_concas(self):
"""Get vertical rate after constant CAS descent."""
return self._get_var("de_vs_avg_after_cas")
def finalapp_vcas(self):
"""Get CAS for final approach."""
return self._get_var("fa_va_avg")
def finalapp_vs(self):
"""Get vertical speed for final approach."""
return self._get_var("fa_vs_avg")
def landing_speed(self):
"""Get landing speed."""
return self._get_var("ld_v_app")
def landing_distance(self):
"""Get breaking distance for landing."""
return self._get_var("ld_d_brk")
def landing_acceleration(self):
"""Get landing deceleration."""
return self._get_var("ld_acc_brk")