Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
junzis
GitHub Repository: junzis/openap
Path: blob/master/scripts/test_acropole.py
592 views
1
# %%
2
3
import matplotlib
4
import matplotlib.pyplot as plt
5
import seaborn as sns
6
from acropole import FuelEstimator
7
from scipy.optimize import curve_fit
8
from tqdm.autonotebook import tqdm
9
10
import numpy as np
11
import openap
12
import pandas as pd
13
14
pd.options.display.max_columns = 100
15
16
# matplotlib.use("WebAgg")
17
18
# %%
19
fe = FuelEstimator()
20
21
# %%
22
typecode = "A320"
23
24
alt = np.arange(1000, 40000, 500)
25
tas = np.arange(0, 500, 10)
26
vs = np.arange(-3000, 3000, 500)
27
28
altitude, speed, vertical_rate = np.meshgrid(alt, tas, vs)
29
30
flight = pd.DataFrame(
31
{
32
"groundspeed": speed.flatten(),
33
"altitude": altitude.flatten(),
34
"vertical_rate": vertical_rate.flatten(),
35
}
36
).assign(typecode="A320")
37
38
# %%
39
flight_fuel = fe.estimate(flight)
40
41
42
# %%
43
# sns.lineplot(
44
# data=flight_fuel.query("vertical_rate == 0"),
45
# x="groundspeed",
46
# y="fuel_flow",
47
# hue="altitude",
48
# )
49
# %%
50
51
flight_ = flight_fuel.query("vertical_rate == 0")
52
speed_, altitude_ = np.meshgrid(tas, alt)
53
fig, ax = plt.subplots(subplot_kw=dict(projection="3d"))
54
surf = ax.plot_surface(
55
altitude_,
56
speed_,
57
flight_.fuel_flow.values.reshape(len(alt), len(tas)),
58
cmap="viridis",
59
)
60
plt.show()
61
62
63
# %%
64
65
ac = openap.prop.aircraft("A320")
66
ac
67
68
eng = openap.prop.engine(ac["engine"]["default"])
69
eng
70
71
# %%
72
73
alt = np.arange(1000, 40000, 100)
74
tas = np.arange(0, 500, 10)
75
76
altitude, speed = np.meshgrid(alt, tas)
77
78
mass = 70000
79
80
drag = openap.Drag("A320")
81
thrust = openap.Thrust("A320")
82
D = drag.clean(mass=mass, tas=speed, alt=altitude, vs=0)
83
T = D
84
thrust_max = thrust.takeoff(tas=speed, alt=altitude)
85
86
CL = (
87
mass
88
* 9.81
89
/ (
90
0.5
91
* openap.aero.density(altitude * openap.aero.ft)
92
* (speed * openap.aero.kts) ** 2
93
* ac["wing"]["area"]
94
)
95
)
96
97
flight = pd.DataFrame(
98
{
99
"groundspeed": speed.flatten(),
100
"altitude": altitude.flatten(),
101
"drag": D.flatten(),
102
"CL": CL.flatten(),
103
"thrust": T.flatten(),
104
"thrust_max": thrust_max.flatten(),
105
}
106
).assign(typecode="A320", vertical_rate=0)
107
108
flight = flight.query("thrust<thrust_max*2 and CL<1.3")
109
110
flight
111
112
# %%
113
flight_fuel = fe.estimate(flight).query("fuel_flow==fuel_flow")
114
flight_fuel
115
# %%
116
117
flight = pd.read_csv("../test/data/flight_a320.csv").query("ALTI_STD_FT>500")
118
flight.head()
119
120
# %%
121
mass = flight.MASS_KG
122
speed = flight.TRUE_AIR_SPD_KT
123
altitude = flight.ALTI_STD_FT
124
vertical_rate = flight.VERT_SPD_FTMN
125
fuelflow = flight.FUEL_FLOW_KGH * 2 / 3600
126
127
drag = openap.Drag("A320")
128
thrust = openap.Thrust("A320")
129
ff = openap.FuelFlow("A320")
130
131
D = drag.clean(mass=mass, tas=speed, alt=altitude, vs=vertical_rate)
132
T = D + mass * 9.81 * np.sin(
133
np.arctan2(vertical_rate * openap.aero.fpm, speed * openap.aero.kts)
134
)
135
136
T_idle = thrust.descent_idle(tas=speed, alt=altitude)
137
T[T < T_idle] = T_idle
138
139
thrust_max = thrust.takeoff(tas=speed, alt=altitude)
140
ff_estimate = ff.enroute(mass=mass, tas=speed, alt=altitude, vs=vertical_rate)
141
142
plt.plot(
143
flight.FLIGHT_TIME,
144
flight.FUEL_FLOW_KGH * 2,
145
lw=1,
146
label="actual (kg/h)",
147
)
148
plt.plot(
149
flight.FLIGHT_TIME,
150
ff_estimate * 3600,
151
alpha=0.8,
152
lw=1,
153
label="estimate (kg/h)",
154
)
155
plt.legend()
156
157
# %%
158
159
160
def func(ratio, a, b):
161
return -a * (ratio - b) ** 2 + a * b**2
162
163
164
ratio = T / (eng["max_thrust"] * ac["engine"]["number"])
165
166
popt, pcov = curve_fit(func, ratio, fuelflow, bounds=((0, 1), (np.inf, np.inf)))
167
print(popt)
168
169
plt.plot(ratio, fuelflow, "b.")
170
171
x = np.linspace(0, 1, 100)
172
plt.plot(x, func(x, *popt), "r-")
173
174
ff2 = eng["fuel_c3"] * x**3 + eng["fuel_c2"] * x**2 + eng["fuel_c1"] * x
175
plt.plot(x, ff2, "g-")
176
177
plt.show()
178
179
# %%
180
181
182
plt.plot(
183
flight.FLIGHT_TIME,
184
flight.FUEL_FLOW_KGH * 2,
185
lw=1,
186
label="actual (kg/h)",
187
)
188
plt.plot(
189
flight.FLIGHT_TIME,
190
func(ratio, *popt) * 3600,
191
alpha=0.8,
192
lw=1,
193
label="estimate (kg/h)",
194
)
195
plt.legend()
196
plt.show()
197
198