-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathaddons.qmd
More file actions
197 lines (131 loc) · 4.95 KB
/
addons.qmd
File metadata and controls
197 lines (131 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# Add-ons
OpenAP can interface with EUROCONTROL's BADA (Base of Aircraft Data) performance models. Both BADA3 and BADA4 are supported, providing alternative drag, thrust, and fuel flow calculations.
:::{.callout-important}
To use these modules, you must first obtain a license and BADA data from EUROCONTROL.
:::
## BADA3
BADA3 uses a coefficient-based model with different parameters for various flight phases. The data is stored in OPF (Operations Performance File) format.
### Setup
```python
from openap.addon import bada3
bada_path = "path/to/bada_3.x"
```
### Drag
Calculate drag force in clean and non-clean configurations:
```python
drag = bada3.Drag("A320", bada_path)
# Clean configuration (cruise)
drag.clean(mass=60000, tas=300, alt=35_000) # kg, kts, ft -> N
# Non-clean configuration (approach or landing)
drag.nonclean(mass=60000, tas=150, alt=3_000, phase="AP") # approach
drag.nonclean(mass=60000, tas=140, alt=1_000, phase="LD", landing_gear=True) # landing
```
The `phase` parameter accepts:
- `"AP"` - Approach configuration
- `"LD"` - Landing configuration
### Thrust
BADA3 provides thrust calculations for different flight phases:
```python
thrust = bada3.Thrust("A320", bada_path)
# Maximum climb thrust
thrust.climb(tas=280, alt=20_000) # kts, ft -> N
# Maximum cruise thrust (95% of climb thrust)
thrust.cruise(tas=450, alt=35_000)
# Takeoff thrust
thrust.takeoff(tas=150, alt=0)
# Idle (descent) thrust - requires configuration
thrust.idle(tas=300, alt=25_000, config="CR") # cruise descent
thrust.idle(tas=200, alt=5_000, config="AP") # approach
thrust.idle(tas=150, alt=1_000, config="LD") # landing
```
The `config` parameter for idle thrust:
- `"CR"` - Cruise/clean configuration
- `"AP"` - Approach configuration
- `"LD"` - Landing configuration
### Fuel Flow
```python
fuel = bada3.FuelFlow("A320", bada_path)
# Enroute fuel flow (cruise, corrected)
fuel.enroute(mass=60000, tas=450, alt=35_000) # kg, kts, ft -> kg/s
# Nominal fuel flow (before cruise correction)
fuel.nominal(mass=60000, tas=450, alt=35_000, vs=0)
# Idle fuel flow
fuel.idle(mass=60000, tas=300, alt=25_000)
# Approach/landing fuel flow
fuel.approach(mass=60000, tas=150, alt=3_000)
```
### ISA Temperature Deviation
All thrust and fuel calculations support ISA temperature deviation using the `dT` parameter:
```python
# Hot day scenario (+15K above ISA)
thrust.climb(tas=280, alt=20_000, dT=15)
fuel.enroute(mass=60000, tas=450, alt=35_000, vs=500, dT=15)
```
## BADA4
BADA4 uses a more sophisticated polynomial model with higher fidelity, especially for modern aircraft. The data is stored in XML format.
### Setup
```python
from openap.addon import bada4
bada_path = "path/to/bada_4.x/tables"
```
### Drag
```python
drag = bada4.Drag("A320", bada_path)
drag.clean(mass=60000, tas=300, alt=35_000) # kg, kts, ft -> N
```
The aircraft type can be ICAO typecode like `A320` or with subtypes like `A320-231`.
### Thrust
```python
thrust = bada4.Thrust("A320", bada_path)
# Maximum climb thrust (MCMB rating)
thrust.climb(tas=280, alt=20_000)
# Maximum cruise thrust (MCRZ rating)
thrust.cruise(tas=450, alt=35_000)
# Takeoff thrust
thrust.takeoff(tas=150, alt=0)
# Idle thrust (LIDL rating)
thrust.idle(tas=300, alt=25_000)
```
### Fuel Flow
```python
fuel = bada4.FuelFlow("A320", bada_path)
# Enroute fuel flow
fuel.enroute(mass=60000, tas=450, alt=35_000) # kg, kts, ft -> kg/s
# Idle fuel flow
fuel.idle(mass=60000, tas=300, alt=25_000)
```
The enroute method automatically switches to idle fuel flow when vertical speed is below -250 ft/min.
## Vectorized Calculations
:::{.callout-tip}
All BADA models support vectorized calculations. Input parameters can be provided as lists or numpy arrays for fast batch processing.
:::
In the following example, we show how to calculate the fuel flow from a flight data file obtained from opensky state vectors. First, we read the data file and calculate the time step between each row.
```python
import pandas as pd
import openap
from openap.addon import bada4
typecode = "A319"
fuel_bada = bada4.FuelFlow(typecode, bada_path)
df = pd.read_csv("path/to/your/fightdata.csv")
dt = df.timestamp.diff().bfill().dt.total_seconds() # time step in seconds
# assume 85% of MTOW as initial mass
mass0 = openap.prop.aircraft(typecode)["mtow"] * 0.85
```
Then we calculate the fuel flow at each time step and sum the total fuel consumed.
```python
# first pass to get an initial guess with reference mass
fuel_flow_initial_guess = fuel_bada.enroute(
mass=mass0,
tas=df.groundspeed,
alt=df.altitude,
vs=df.vertical_rate,
).flatten()
# correct the mass at each time step
mass = mass0 - (fuel_flow_initial_guess * dt).cumsum()
# second pass with corrected mass
fuel_flow = fuel_bada.enroute(
mass=mass, tas=df.groundspeed, alt=df.altitude, vs=df.vertical_rate
).flatten()
total_fuel = sum(fuel_flow * dt)
```
The cacluation takes approximately `4.6 ms ± 33.7 μs` for a flight dataframe with ~ 7,000 rows on a` Ryzen 7 7840HS` CPU.