8 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.
To use these modules, you must first obtain a license and BADA data from EUROCONTROL.
8.1 BADA3
BADA3 uses a coefficient-based model with different parameters for various flight phases. The data is stored in OPF (Operations Performance File) format.
8.1.1 Setup
from openap.addon import bada3
bada_path = "path/to/bada_3.x"8.1.2 Drag
Calculate drag force in clean and non-clean configurations:
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) # landingThe phase parameter accepts:
"AP"- Approach configuration"LD"- Landing configuration
8.1.3 Thrust
BADA3 provides thrust calculations for different flight phases:
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") # landingThe config parameter for idle thrust:
"CR"- Cruise/clean configuration"AP"- Approach configuration"LD"- Landing configuration
8.1.4 Fuel Flow
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)8.1.5 ISA Temperature Deviation
All thrust and fuel calculations support ISA temperature deviation using the dT parameter:
# 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)8.2 BADA4
BADA4 uses a more sophisticated polynomial model with higher fidelity, especially for modern aircraft. The data is stored in XML format.
8.2.1 Setup
from openap.addon import bada4
bada_path = "path/to/bada_4.x/tables"8.2.2 Drag
drag = bada4.Drag("A320", bada_path)
drag.clean(mass=60000, tas=300, alt=35_000) # kg, kts, ft -> NThe aircraft type can be ICAO typecode like A320 or with subtypes like A320-231.
8.2.3 Thrust
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)8.2.4 Fuel Flow
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.
8.3 Vectorized Calculations
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.
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.85Then we calculate the fuel flow at each time step and sum the total fuel consumed.
# 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 aRyzen 7 7840HS CPU.