Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
junzis
GitHub Repository: junzis/openap
Path: blob/master/openap/kinematic.py
592 views
1
"""OpenAP kinematic model.
2
3
This module implements functions to access the WRAP kinematic model.
4
5
Examples:
6
WRAP model can be accessed as follows::
7
8
from openap import WRAP
9
wrap = WRAP(ac='A320')
10
wrap.cruise_mach()
11
12
with result::
13
14
{
15
'default': 0.78,
16
'minimum': 0.75,
17
'maximum': 0.8,
18
'statmodel': 'beta',
19
'statmodel_params': [17.82, 5.05, 0.62, 0.2]
20
}
21
22
"""
23
24
import glob
25
import os
26
27
import pandas as pd
28
29
curr_path = os.path.dirname(os.path.realpath(__file__))
30
dir_wrap = os.path.join(curr_path, "data/wrap/")
31
file_synonym = os.path.join(curr_path, "data/wrap/_synonym.csv")
32
33
wrap_synonym = pd.read_csv(file_synonym)
34
35
36
class WRAP:
37
"""Construct the kinematic model of the aircraft."""
38
39
def __init__(self, ac: str, **kwargs):
40
"""Initialize WRAP object.
41
42
Args:
43
ac: ICAO aircraft type (for example: A320).
44
45
"""
46
self.ac = ac.lower()
47
48
self.use_synonym = kwargs.get("use_synonym", True)
49
50
wrap_files = glob.glob(dir_wrap + "*.txt")
51
ac_wrap_available = [s[-8:-4].lower() for s in wrap_files]
52
53
if self.ac not in ac_wrap_available and not self.use_synonym:
54
raise ValueError((f"Kinematic model for {self.ac} not available."))
55
56
if self.ac not in ac_wrap_available and self.use_synonym:
57
syno = wrap_synonym.query("[email protected]")
58
if syno.shape[0] > 0:
59
self.ac = syno.new.iloc[0]
60
else:
61
raise ValueError(f"Kinematic model for {self.ac} not available.")
62
63
self.df = pd.read_fwf(os.path.join(dir_wrap, self.ac + ".txt"))
64
65
def _get_var(self, var):
66
r = self.df[self.df["variable"] == var]
67
68
if r.shape[0] == 0:
69
raise ValueError(f"Variable {var} not found")
70
71
v = r.values[0]
72
73
res = {
74
"default": v[3],
75
"minimum": v[4],
76
"maximum": v[5],
77
"statmodel": v[6],
78
"statmodel_params": [float(i) for i in v[7].split("|")],
79
}
80
return res
81
82
def takeoff_speed(self):
83
"""Get takeoff speed."""
84
return self._get_var("to_v_lof")
85
86
def takeoff_distance(self):
87
"""Get takeoff distance."""
88
return self._get_var("to_d_tof")
89
90
def takeoff_acceleration(self):
91
"""Get takeoff acceleration."""
92
return self._get_var("to_acc_tof")
93
94
def initclimb_vcas(self):
95
"""Get initial climb CAS."""
96
return self._get_var("ic_va_avg")
97
98
def initclimb_vs(self):
99
"""Get initial climb vertical rate."""
100
return self._get_var("ic_vs_avg")
101
102
def climb_range(self):
103
"""Get climb range distance (in km)."""
104
return self._get_var("cl_d_range")
105
106
def climb_const_vcas(self):
107
"""Get speed for constant CAS climb."""
108
return self._get_var("cl_v_cas_const")
109
110
def climb_const_mach(self):
111
"""Get speed during constant Mach climb."""
112
return self._get_var("cl_v_mach_const")
113
114
def climb_cross_alt_concas(self):
115
"""Get cross over altitude when constant CAS climb starts."""
116
return self._get_var("cl_h_cas_const")
117
118
def climb_cross_alt_conmach(self):
119
"""Get cross over altitude from constant CAS to Mach climb."""
120
return self._get_var("cl_h_mach_const")
121
122
def climb_vs_pre_concas(self):
123
"""Get vertical rate before constant CAS climb."""
124
return self._get_var("cl_vs_avg_pre_cas")
125
126
def climb_vs_concas(self):
127
"""Get vertical rate during constant CAS climb."""
128
return self._get_var("cl_vs_avg_cas_const")
129
130
def climb_vs_conmach(self):
131
"""Get vertical rate during constant Mach climb."""
132
return self._get_var("cl_vs_avg_mach_const")
133
134
def cruise_range(self):
135
"""Get cruise range."""
136
return self._get_var("cr_d_range")
137
138
def cruise_alt(self):
139
"""Get average cruise altitude."""
140
return self._get_var("cr_h_mean")
141
142
def cruise_init_alt(self):
143
"""Get initial cruise altitude."""
144
return self._get_var("cr_h_init")
145
146
def cruise_max_alt(self):
147
return self._get_var("cr_h_max")
148
149
def cruise_mach(self):
150
"""Get average cruise Mach number."""
151
return self._get_var("cr_v_mach_mean")
152
153
def cruise_max_mach(self):
154
return self._get_var("cr_v_mach_max")
155
156
def cruise_mean_vcas(self):
157
return self._get_var("cr_v_cas_mean")
158
159
def descent_range(self):
160
"""Get descent range."""
161
return self._get_var("de_d_range")
162
163
def descent_const_mach(self):
164
"""Get speed during the constant Mach descent."""
165
return self._get_var("de_v_mach_const")
166
167
def descent_const_vcas(self):
168
"""Get speed during the constant CAS descent."""
169
return self._get_var("de_v_cas_const")
170
171
def descent_cross_alt_conmach(self):
172
"""Get crossover altitude from constant Mach to CAS descent."""
173
return self._get_var("de_h_mach_const")
174
175
def descent_cross_alt_concas(self):
176
"""Get crossover altitude from constant Mach to CAS descent."""
177
return self._get_var("de_h_cas_const")
178
179
def descent_vs_conmach(self):
180
"""Get vertical rate during constant Mach descent."""
181
return self._get_var("de_vs_avg_mach_const")
182
183
def descent_vs_concas(self):
184
"""Get vertical rate during constant CAS descent."""
185
return self._get_var("de_vs_avg_cas_const")
186
187
def descent_vs_post_concas(self):
188
"""Get vertical rate after constant CAS descent."""
189
return self._get_var("de_vs_avg_after_cas")
190
191
def finalapp_vcas(self):
192
"""Get CAS for final approach."""
193
return self._get_var("fa_va_avg")
194
195
def finalapp_vs(self):
196
"""Get vertical speed for final approach."""
197
return self._get_var("fa_vs_avg")
198
199
def landing_speed(self):
200
"""Get landing speed."""
201
return self._get_var("ld_v_app")
202
203
def landing_distance(self):
204
"""Get breaking distance for landing."""
205
return self._get_var("ld_d_brk")
206
207
def landing_acceleration(self):
208
"""Get landing deceleration."""
209
return self._get_var("ld_acc_brk")
210
211