https://badge.fury.io/py/ADRpy.svg https://travis-ci.com/sobester/ADRpy.svg?branch=master

Aircraft Design Recipes in Python – User’s Guide

by Andras Sobester

Welcome to ADRpy, a free library of aircraft design and performance analysis tools suitable for rapid sizing calculations. The models implemented in ADRpy are largely analytical, enabling fast explorations of large design spaces. Most of the methods can already be used in the earliest phases of the design process, even before a geometry model is built. In fact, ADRpy can serve as the basis of sensitivity analyses and uncertainty quantification (UQ) exercises as part of the analysis of the feasibility of the design requirements.

The classes, methods and functions of the library fall into these broad categories:

1. Models of the operating environment. These live in the Atmospheres module and include virtual atmospheres (ISA, MIL-HDBK-310, etc.), runway models (suitable for take-off and landing performance modelling using a ‘real world’ runway database) and models of propulsion performance response to variations in ambient conditions.

2. Sizing and performance analysis methods for fixed wing aircraft. They can be found in the Constraint Analysis Module.

3. Airworthiness. Tools to assist in analysing the airworthiness of a design from a certification standpoint. See the Airworthiness module.

4. Utilities, including a module for Unit Conversions and a set of Miscellaneous Utilities.

This document contains numerous usage examples and details on the inputs and outputs of each class, method and function. You can copy and paste these into .py files and execute those in a development environment or from Python’s command prompt, you can copy and paste them line by line into a Python terminal or (perhaps most usefully) into a Jupyter notebook. Any problems, issues, questions, please raise an issue on GitHub. Happy designing!

Installing and running ADRpy

ADRpy is written in Python 3 and tested in Python 3.5, 3.6, 3.7 and 3.8. It is not available for Python 2.

First and foremost, you will need to have Python installed - you can get the latest version here or as part of a number of alternative packages.

Once you have Python, on most systems you should be able to simply open an operating system terminal and at the command prompt type python -m pip install ADRpy or just pip install ADRpy (pip is a Python package; in the unlikely event that it is not available on your system, download get-pip.py and run it by entering python get-pip.py at the operating system prompt).

For the ADRpy source code, license conditions (GPLv3), and alternative installation instructions see the ADRpy GitHub repository.

Notebooks

ADRpy includes a library of examples recorded in Jupyter notebooks.

You can view these on GitHub in the ADRpy notebooks library.

Alternatively, hit the green ‘Code’ button on ADRpy’s top level page and ‘Download ZIP’ to get your own copy, along with the rest of the repository.

ADRpy Modules

Atmospheres

This module contains tools for defining the environment in which aircraft performance analyses, trade-off studies, conceptual sizing and other aircraft engineering calculations can be carried out.

The module contains the following class definitions:

Runway

Definition of a runway object, including the capability to instantiate a runway from a ‘real world’ database of the world’s airports.

Atmosphere

Definition of a virtual atmosphere object. This includes a number of methods that allow the user to query parameters of the atmosphere.

Obsprofile

Definition of an atmospheric observation (sounding) object. This allows the user to create bespoke atmospheres and any other atmospheres derived from specified temperature, pressure, etc. profiles (such as the MIL HDBK 310 atmospheres).

See, in what follows, detailed descriptions of these classes, their methods, functions, as well as usage examples.

class atmospheres.Atmosphere(offset_deg=0, profile=None)

Standard or off-standard/custom atmospheres.

Available atmosphere types

1. The International Standard Atmosphere (ISA) model. Based on ESDU Data Item 77022, “Equations for calculation of International Standard Atmosphere and associated off-standard atmospheres”, published in 1977, amended in 2008. It covers the first 50km of the atmosphere.

  1. Off-standard, temperature offset versions of the above.

3. Extremely warm/cold, and low/high density atmospheres from US MIL HDBK 310

  1. User-defined atmospheres based on interpolated data.

Example

from ADRpy import atmospheres as at
from ADRpy import unitconversions as co

# Instantiate an atmosphere object: an off-standard ISA
# with a -10C offset
isa_minus10 = at.Atmosphere(offset_deg=-10)

# Query altitude
altitude_ft = 38000
altitude_m = co.feet2m(altitude_ft)

# Query the ambient density in this model at the specified altitude
print("ISA-10C density at", str(altitude_ft), "feet (geopotential):",
    isa_minus10.airdens_kgpm3(altitude_m), "kg/m^3")

# Query the speed of sound in this model at the specified altitude
print("ISA-10C speed of sound at", str(altitude_ft), "feet (geopotential):",
    isa_minus10.vsound_mps(altitude_m), "m/s")

Output:

ISA-10C density at 38000 feet (geopotential): 0.348049478999 kg/m^3
ISA-10C speed of sound at 38000 feet (geopotential): 288.1792251702055 m/s

Note

The unit tests (found in tests/t_atmospheres.py in the GitHub repository) compare the atmosphere outputs against data from the 1976 US Standard Atmosphere, NASA-TM-X-74335. ESDU 77022 describes its ISA model as being identical for all practical purposes with the US Standard Atmospheres.

Methods

airdens_kgpm3(altitudes_m=0)

Ambient density in the current atmosphere in \(\mathrm{kg/m}^3\).

airpress_mbar(altitudes_m=0)

Air pressure in mbar.

airpress_pa(altitudes_m=0)

Pressures in the selected atmosphere, in Pa.

airtemp_c(altitudes_m=0)

Air temperature in Celsius.

airtemp_k(altitudes_m=0)

Temperatures in the selected atmosphere, in K.

Parameter:

altitudes_m

altitudes at which the temperature is to be interrogated (float or array of floats)

Output:

Ambient temperature (Static Air Temperature) in Kelvin.

Example

from ADRpy import atmospheres as at

isa = at.Atmosphere()

print("ISA temperatures at SL, 5km, 10km (geopotential):",
    isa.airtemp_k([0, 5000, 10000]), "K")

Output:

ISA temperatures at SL, 5km, 10km (geopotential): [ 288.15  255.65  223.15] K
dynamicpressure_pa(airspeed_mps=0, altitudes_m=0)

Dynamic pressure in the current atmosphere at a given true airspeed and altitude

Parameters

airspeed_mps

float, true airspeed in m/s (MPSTAS)

altitudes_m

float array, altitudes in m where the dynamic pressure is to be computed

Returns

float or array of floats, dynamic pressure values

Example

from ADRpy import atmospheres as at
from ADRpy import unitconversions as co

ISA = at.Atmosphere()

altitudelist_m = [0, 500, 1000, 1500]

MPSTAS = 20

q_Pa = ISA.dynamicpressure_pa(MPSTAS, altitudelist_m)

q_mbar = co.pa2mbar(q_Pa)

print(q_mbar)

Output:

[ 2.44999974  2.33453737  2.22328473  2.11613426]
eas2tas(eas, altitude_m)

Converts EAS to TAS at a given altitude.

The method first calculates the density ratio \(\sigma\) (as the ratio of the ambient density at altitude_m and at the ambient density at sea level); the true airspeed is then calculated as:

\[\mathrm{TAS}=\frac{\mathrm{EAS}}{\sqrt{\sigma}}\]

Parameters

eas

Float or numpy array of floats. Equivalent airspeed (any unit, returned TAS value will be in the same unit).

altitude_m

Float. Flight altitude in metres.

Returns

True airspeed in the same units as the EAS input.

keas2kcas(keas, altitude_m)

Converts equivalent airspeed into calibrated airspeed.

The relationship between the two depends on the Mach number \(M\) and the ratio \(\delta\) of the pressure at the current altitude \(P_\mathrm{alt}\) and the sea level pressure \(P_\mathrm{0}\). We approximate this relationship with the expression:

\[\mathrm{CAS}\approx\mathrm{EAS}\left[1 + \frac{1}{8}(1-\delta)M^2 + \frac{3}{640}\left(1-10\delta+9\delta^2 \right)M^4 \right]\]

Parameters

keas

float or numpy array, equivalent airspeed in knots.

altitude_m

float, altitude in metres.

Returns

kcas

float or numpy array, calibrated airspeed in knots.

mach

float, Mach number.

See also mpseas2mpscas

Notes

The reverse conversion is slightly more complicated, as their relationship depends on the Mach number. This, in turn, requires the computation of the true airspeed and that can only be computed from EAS, not CAS. The unit- specific nature of the function is also the result of the need for computing the Mach number.

Example

import numpy as np
from ADRpy import atmospheres as at
from ADRpy import unitconversions as co

isa = at.Atmosphere()

keas = np.array([100, 200, 300])
altitude_m = co.feet2m(40000)

kcas, mach = isa.keas2kcas(keas, altitude_m)

print(kcas)

Output:

[ 101.25392563  209.93839073  333.01861569]
mach(airspeed_mps, altitude_m=0)

Mach number at a given speed (m/s) and altitude (m)

mpseas2mpscas(mpseas, altitude_m)

Convert EAS (m/s) to CAS (m/s) at a given altitude (m)

tas2eas(tas, altitude_m)

Convert TAS to EAS at a given altitude

vsound_kts(altitudes_m=0)

Speed of sound in knots.

vsound_mps(altitudes_m=0)

Speed of sound in m/s at an altitude given in m.

class atmospheres.Obsprofile(alt_m=None, temp_k=None, rho_kgpm3=None, p_pa=None)

Observed atmosphere profile data.

hialt()

The maximum valid altitude (in m) of the interpolators.

loalt()

The minimum valid altitude (in m) of the interpolators.

class atmospheres.Runway(icao_code=None, rwyno=0, elevation_ft=0, heading=0, surf='ASP', length_ft=10000, width_ft=100)

Runway model to be used for take-off/landing performance calculations.

Parameters (all optional):

icao_code

String. International Civil Aviation Organisation code of the airport. Required if the user wishes to equip this object with the attributes of a specific, existing runway, e.g., ‘EGLL’ (London Heathrow airport). Runway data is obtained from an off-line image of the ourairports.com database.

rwyno

Integer. Specifies which of the runways at the airport specified by the ICAO code above we want to associate with the runway object. A ValueError will be thrown if rwyno exceeds the number of runways at the airport specified by the icao_code. The number of runways can be found in the nrways attribute of the runway object:

runway = at.Runway('KDEN')
runway.nrways

Output:

6
elevation_ft, heading, surf, length_ft, width_ft

Parameters of bespoke, user-defined runways. The recommended use of these is as indicated by their names, though the user may wish to adopt their own definitions to suit particular applications (for example, surf can be any string describing the runway surface).

Example - creating and querying a Runway class object:

from ADRpy import atmospheres as at

runway = at.Runway('EGLL', 0)

print('Runway: ', runway.le_ident, '/', runway.he_ident)

print('True headings: ',
    runway.le_heading_degt, '/',
    runway.he_heading_degt, 'degrees')

print('Elevation (low end): ', runway.le_elevation_ft, 'ft')

print('Length: ', runway.length_ft, 'ft')

Outputs:

Runway:  09L / 27R
True headings:  89.6 / 269.6 degrees
Elevation (low end):  79.0 ft
Length:  12799.0 ft
windcomponents(wind_dirs_deg, wind_speeds)

Resolves list of wind speeds and directions into runway/cross components on the current runway.

Parameters:

wind_dirs_deg

List of floats. Wind directions expressed in degrees true (e.g., directions specified in a METAR).

wind_speeds

List of floats. Wind_speeds (in the units in which the output is desired).

Outputs:

runway_component

Scalar or numpy array. The runway direction component of the wind (sign convention: headwinds are positive).

crosswind_component

Scalar or numpy array. The cross component of the wind (sign convention: winds from the right are positive).

Example

# Given a METAR, calculate the wind components on Rwy 09 at Yeovilton

from ADRpy import atmospheres as at
from metar import Metar

runway = at.Runway('EGDY', 1)

egdywx = Metar.Metar('EGDY 211350Z 30017G25KT 9999 FEW028 BKN038 08/01 Q1031')

direction_deg = egdywx.wind_dir.value()
windspeed_kts = egdywx.wind_speed.value()

rwy_knots, cross_knots = runway.windcomponents(direction_deg, windspeed_kts)

print("Runway component:", rwy_knots)
print("Cross component:", cross_knots)

Output:

Runway component: -13.5946391943
Cross component: -10.2071438305
atmospheres.geom2geop45m(altitude_m)

Converts geometric height to geopotential (m) assuming 45deg lat

atmospheres.geop2geom45m(altitude_m)

Converts geopotential height to geometric (m) assuming 45deg lat

atmospheres.idealgasdens_kgm3(p_pa, temp_k)

Density from pressure and temperature, on ideal gas assumption

atmospheres.idealgaspress_pa(rho_kgpm3, temp_k)

Pressure from density and temperature, on ideal gas assumption

atmospheres.mil_hdbk_310(high_or_low, temp_or_dens, alt_km)

Load an atmospheric data set from US Military Handbook 310

atmospheres.pistonpowerfactor(density_kgpm3)

Gagg-Ferrar model. Multiply by this to get power at given density.

atmospheres.pressratio(pressure_pa, mach)

Ratio of total pressure and the standard SL pressure

atmospheres.reciprocalhdg(heading_deg)

The reciprocal of a heading in degrees

atmospheres.tatbysat(mach, recfac=1.0)

Ratio of total and static air temperature at a given Mach no

atmospheres.tempratio(temp_c, mach)

Ratio of total temperature and the standard SL temperature

atmospheres.turbofanthrustfactor(temp_c, pressure_pa, mach, throttleratio=1, ptype='highbpr')

Multiply SL static thrust by this to get thrust at specified conditions

atmospheres.turbojetthrustfactor(temp_c, pressure_pa, mach, throttleratio=1, afterburner=False)

Multiply SL static thrust by this to get thrust at specified conditions

atmospheres.turbopropthrustfactor(dens_ratio, mach)

Multiply SL static thrust by this to get thrust at specified dens. ratio and Mach no.

atmospheres.turbopropthrustfactor_matt(temp_c, pressure_pa, mach, throttleratio=1)

Multiply SL static thrust by this to get thrust at specified conditions

Constraint Analysis Module

This module contains tools for the constraint analysis of fixed wing aircraft.

class constraintanalysis.AircraftConcept(brief=None, design=None, performance=None, designatm=None, propulsion=None)

Definition of a basic aircraft concept. An object of this class defines an aircraft design in terms of the brief it is aiming to meet, high level design variables that specify it, key parameters that describe its performance, as well as the atmosphere it operates in. These are the four arguments that define an object of the AircraftConcept class. The first three are dictionaries, as described below, the last is an object of Atmosphere class.

Parameters:

brief

Dictionary. Definition of the design brief, that is, the requirements the design seeks to meet. Contains the following key names:

climbalt_m

Float. The altitude (in metres) where the climb rate requirement is specified. Optional, defaults to zero (sea level).

climbspeed_kias

Float. The airspeed (in knots, indicated) at which the required climb rate has to be achieved.

climbrate_fpm

Float. Required climb rate (in feet per minute) at the altitude specified in the climbalt_m entry (above).

cruisealt_m

Float. The altitude at which the cruise speed requirement will be defined.

cruisespeed_ktas

Float. The required cruise speed (in knots, true airspeed) at the altitude specified in the cruisealt_m entry (above).

cruisethrustfact

Float. The fraction (nondimensional) of the maximum available thrust at which the cruise speed requirement must be achieved.

servceil_m

Float. The required service ceiling in meters (that is, the altitude at which the maximum rate of climb drops to 100 feet per minute).

secclimbspd_kias

Float. The speed (knots indicated airspeed) at which the service ceiling must be reached. This should be an estimate of the best rate of climb speed.

vstallclean_kcas

Float. The maximum acceptable stall speed (in knots, indicated/calibrated).

groundrun_m

Float. Length (in metres) of take-off ground run in meters at the elevation defined by the rwyelevation_m entry of the dictionary. This is a basic, 100% N1, no wind, zero runway gradient ground run.

rwyelevation_m

Float. The elevation (in metres) of the runway againts which the take-off constraint is defined. Optional, defaults to zero (sea level).

to_headwind_kts

Float. The speed of the take-off headwind (in knots), parallel to the runway. Optional, defaults to zero.

to_slope_perc

Float. The percent gradient of the runway in the direction of travel. Optional, defaults to zero.

stloadfactor

Float. Load factor to be sustained by the aircraft in a steady, level turn.

turnalt_m

Float. Altitude (in metres) where the turn requirement is defined. Optional, defaults to zero (sea level).

turnspeed_ktas

Float. True airspeed (in knots) at which the turn requirement (above) has to be met. Since the dynamics of turning flight is dominated by inertia, which depends on ground speed, the turn speed is specified here as TAS (on the zero wind assumption). If you’d rather specify this as IAS/CAS/EAS, use eas2tas first to obtain the TAS value.

Example design brief:

brief = {'rwyelevation_m':0, 'groundrun_m':313,
         'stloadfactor': 1.5, 'turnalt_m': 1000, 'turnspeed_ktas': 100,
         'climbalt_m': 0, 'climbspeed_kias': 101, 'climbrate_fpm': 1398,
         'cruisealt_m': 3048, 'cruisespeed_ktas': 182, 'cruisethrustfact': 1.0,
         'servceil_m': 6580, 'secclimbspd_kias': 92,
         'vstallclean_kcas': 69}
design

Dictionary. Definition of key, high level design variables that define the future design.

aspectratio

Float. Wing aspect ratio. Optional, defaults to 8.

sweep_le_deg

Float. Main wing leading edge sweep angle (in degrees). Optional, defaults to zero (no sweep).

sweep_mt_deg

Float. Main wing sweep angle measured at the maximum thickness point. Optional, defaults to value of ‘sweep_le_deg’.

sweep_25_deg

Float. Main wing sweep angle measured at the quarter chord point. Optional, defaults to ~29% sweep_le_deg, ~71% sweep_mt_deg.

roottaperratio

Float. Standard definition of wing tip chord to root chord ratio, zero for sharp, pointed wing-tip delta wings. Optional, defaults to the theoretical optimal value as a function of the quarter-chord sweep angle.

wingarea_m2

Float. Total reference area of the wing (in metres squared).

wingheightratio

Float. The ratio of altitude h to wingspan b, used for the calculation of ground effect. Optional, defaults to 100 (produces a ground effect factor of near unity).

bpr

Float. Specifies the propulsion system type. For jet engines (powered by axial gas turbines) this should be the bypass ratio (hence ‘bpr’).

*Deprecated: Set to -1 for piston engines, -2 for turboprops and -3 if no power/thrust corrections are needed (e.g., for electric motors).

spooluptime_s

Float. Time in seconds for the engine to reach take-off thrust. Optional, defaults to 5.

totalstaticthrust_n

Float. Maximum thrust achievable at zero airspeed.

tr

Float. Throttle ratio for gas turbine engines. tr = 1 means that the Turbine Entry Temperature will reach its maximum allowable value in sea level standard day conditions, so higher ambient temperatures will result in power loss. Higher tr values mean thrust decay starting at higher altitudes.

weight_n

Float. Specifies the maximum take-off weight of the aircraft.

weightfractions

Dictionary. Specifies at what fraction of the maximum take-off weight do various constraints have to be met. It should contain the following keys: take-off, climb, cruise, turn, servceil. Optional, each defaults to 1.0 if not specified.

runwayalpha_deg

Float. Angle of attack the main wing encounters during take-off roll. Optional, defaults to 0.

runwayalpha_max_deg

Float. Maximum permitted angle of attack before lift-off.

performance

Dictionary. Definition of key, high level design performance estimates.

CD0TO

Float. Zero-lift drag coefficient in the take-off configuration

CDTO

Float. Take-off drag coefficient. Optional, defaults to 0.09.

CDminclean

Float. Zero lift drag coefficient in clean configuration. Optional, defaults to 0.03.

mu_R

Float. Coefficient of rolling resistance on the wheels. Optional, defaults to 0.03.

CL0TO

Float. Zero-alpha lift coefficient.

CLTO

Float. Take-off lift coefficient. Optional, defaults to 0.95.

CLmaxTO

Float. Maximum lift coefficient in take-off conditions. Optional, defaults to 1.5.

CLmaxclean

Float. Maximum lift coefficient in flight, in clean configuration.

CLminclean

Float. Minimum lift coefficient in flight, in clean configuration. Typically negative.

CLslope

Float. Lift-curve slope gradient, or Cl/alpha of a design aerofoil (or wing that may be considered 2D) in incompressible flow. Optional, defaults to the flat plate theory maximum of 2*Pi.

etaprop

Dictionary. Propeller efficiency in various phases of the mission. It should contain the following keys: take-off, climb, cruise, turn, servceil. Optional, unspecified entries in the dictionary default to the following values:

code

etap = {‘take-off’: 0.45, ‘climb’: 0.75, ‘cruise’: 0.85, ‘turn’: 0.85, ‘servceil’: 0.65}

designatm

Atmosphere class object. Specifies the virtual atmosphere in which all the design calculations within the AircraftConcept class will be performed. Optional, defaults to the International Standard Atmosphere.

propulsion

Tuple. Contains at maximum two objects of the ADRpy propulsion module, specifying the nature of the aircraft propulsion system. The first item of the tuple should be an ADRpy propulsion EngineDeck class object, followed by an optional ADRpy PropellerDeck class object.

String. An alternative to specifying propulsion objects, specify a generic type of propulsion from either :code: “turboprop”, :code: “piston”, :code: “electric”, or :code: “jet”.

bank2turnradius(bankangle_deg)

Calculates the turn radius in m, given the turn TAS and the bank angle

bestclimbspeedprop(wingloading_pa, altitude_m)

The best rate of climb speed for a propeller aircraft

findchordsweep_rad(xc_findsweep)

Calculates the sweep angle at a given chord fraction, for a constant taper wing

Parameters:

xc_findsweep

float, the fraction of chord along which the function is being asked to determine the sweep angle of. Inputs are bounded as 0 <= xc_findsweep <= 1 (0% to 100% chord), where x/c = 0 is defined as the leading edge.

Outputs:

sweep_rad

float, this is the sweep angle of the given chord fraction, for a constant taper wing.

induceddragfact(whichoswald=None, mach_inf=None)
Lift induced drag factor k estimate (Cd = Cd0 + K.Cl^2) based on the relationship

(k = 1 / pi * AR * e_0).

Parameters:

whichoswald

integer, used to specify the method(s) to estimate e_0 from. Specifying a single digit integer selects a single associated method, however a concatenated string of integers can be used to specify that e_0 should be calculated from the average of several. Optional, defaults to methods 2 and 4.

mach_inf

float, the free-stream flight mach number. Optional, defaults to 0.3 (incompressible flow prediction).

Outputs:

induceddragfactor

float, an estimate for the coefficient of Cl^2 in the drag polar (Cd = Cd0 + K.Cl^2) based on various estimates of the oswald efficiency factor.

Note This method does not contain provisions for ‘wing-in-ground-effect’ factors.

induceddragfact_lesm(wingloading_pa=None, cl_real=None, mach_inf=None)

Lift induced drag factor k estimate (Cd = Cd0 + k.Cl^2), from LE suction theory, for aircraft capable of supersonic flight.

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa. Optional, provided that an aircraft weight and wing area are specified in the design definitions dictionary.

cl_real

float or array, the coefficient of lift demanded to perform a maneuver. Optional, defaults to cl at cruise.

mach_inf

float, Mach number at which the Oswald efficiency factor is to be estimated, required to evaluate compressibility effects. Optional, defaults to 0.3 (incompressible flow).

Outputs:

k

float, predicted lift-induced drag factor K, as used in (Cd = Cd0 + k.Cl^2)

Note

This method does not contain provisions for ‘wing-in-ground-effect’ factors.

liftslope_prad(mach_inf=None)

Method for estimating the lift-curve slope from aircraft geometry; Methods from http://naca.central.cranfield.ac.uk/reports/arc/rm/2935.pdf (Eqn. 80), by D. Kuchemann; DATCOM 1978;

Several methods for calculating supersonic and subsonic lift-slopes are aggregated to produce a model for the lift curve with changing free-stream Mach number.

Parameters:

mach_inf

float, the free-stream flight mach number. Optional, defaults to 0.3 (incompressible flow prediction).

Outputs:

liftslope_prad

float, the predicted lift slope as an average of several methods of computing it, for a ‘thin’ aerofoil (t/c < 5%) - assuming the aircraft is designed with supersonic flight in mind. Units of rad^-1.

Note

Care must be used when interpreting this function in the transonic flight regime. This function departs from theoretical models for 0.6 <= Mach_free-stream <= 1.4, and instead uses a weighted average of estimated curve-fits and theory to predict transonic behaviour.

map2static()

Maps the average take-off thrust to static thrust. If a bypass ratio is not specified, it returns a value of 1.

oswaldspaneff1()

Raymer’s Oswald span efficiency estimate, sweep < 30, moderate AR

oswaldspaneff2()

Oswald span efficiency estimate due to Brandt et al.

oswaldspaneff3()

Raymer’s Oswald span efficiency estimate, swept wings

oswaldspaneff4(mach_inf=None)

Method for estimating the oswald factor from basic aircraft geometrical parameters; Original method by Mihaela Nita and Dieter Scholz, Hamburg University of Applied Sciences https://www.dglr.de/publikationen/2012/281424.pdf

The method returns an estimate for the Oswald efficiency factor of a planar wing. The mach correction factor was fitted around subsonic transport aircraft, and therefore this method is recommended only for use in subsonic analysis with free-stream Mach < 0.69.

Parameters:

mach_inf

float, Mach number at which the Oswald efficiency factor is to be estimated, required to evaluate compressibility effects. Optional, defaults to 0.3 (incompressible flow).

Outputs:

e

float, predicted Oswald efficiency factor for subsonic transport aircraft.

powerrequired(wingloading_pa, tow_kg, feasibleonly=True, map2sl=True)

Calculate the power (in HP) required for t/o, trn, clm, crs, sec.

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

tow_kg

float, maximum take-off weight of the aircraft.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

preq_hp

dictionary, power (in horsepower) required for the given wing loadings.

propulsionsensitivity_monothetic(wingloading_pa, y_var='tw', y_lim=None, x_var='ws_pa', customlabels=None, show=True, maskbool=False, textsize=None, figsize_in=None)

Constraint analysis in the wing loading (or wing area) - T/W ratio (or power) space. The method generates a plot of the combined constraint diagram, with optional sensitivity diagrams for individual constraints. These are based on a One-Factor-at-a-Time analysis of the local sensitivities of the constraints (required T/W or power values) with respect to the variables that define the aircraft concept. The sensitivity charts show the relative proportions of these local sensitivities, referred to as ‘relative sensitivities’. Sensitivities are computed for those inputs that are specified as a range (a [min, max] list) instead of a single scalar value and the sensitivity is estimated across this range, with the midpoint taken as the nominal value (see more details in this notebook).

Sensitivities can be computed with respect to components of the design brief, as well as aerodynamic parameter estimates or geometrical parameters.

The example below can serve as a template for setting up a sensitivity study; further examples can be found in the notebook.

This is a higher level wrapper of twrequired - please consult its documentation entry for details on the individual constraints and their required inputs.

Parameters:

wingloading_pa

array, list of wing loading values in Pa.

y_var

string, specifies the quantity to be plotted along the y-axis of the combined constraint diagram. Set to ‘tw’ for dimensionless thrust-to-weight required, or ‘p_hp’ for the power required (in horsepower); sea level standard day values in both cases. Optional, defaults to ‘tw’.

y_lim

float, used to define the plot y-limit. Optional, defaults to 105% of the maximum value across all constraint curves.

x_var

string, specifies the quantity to be plotted along the x-axis of the combined constraint diagram. Set to ‘ws_pa’ for wing loading in Pa, or ‘s_m2’ for wing area in metres squared. Optional, defaults to ‘ws_pa’.

customlabels

dictionary, used to remap design definition parameter keys to labels better suited for plot labelling. Optional, defaults to None. See example below for usage.

show

boolean/string, used to indicate the type of plot required. Available arguments: True, False, ‘combined’, ‘climb’, ‘cruise’, ‘servceil’, ‘take-off’, and ‘turn’. Optional, defaults to True. ‘combined’ will generate the classic combined constraint diagram on its own.

maskbool

boolean, used to indicate whether or not constraints that do not affect the combined minimum propulsion sizing requirement should be obscured. Optional, defaults to False.

textsize

integer, sets a representative reference fontsize for the text on the plots. Optional, defaults to 10 for multi-subplot figures, and to 14 for singles.

figsize_in

list, used to specify custom dimensions of the output plot in inches. Image width must be specified as a float in the first entry of a two-item list, with height as the second item. Optional, defaults to 14.1 inches wide by 10 inches tall.

See also twrequired

Notes

1. This is a plotting routine that wraps the various constraint models implemented in ADRpy. If specific constraint data is required, use twrequired.

2. Investigating sensitivities of design parameters embedded within the aircraft concept definition dictionaries, such as weight fractions or propeller efficiencies for various constraints, is not currently supported. Similarly, it uses the atmosphere provided in the class argument ‘designatm’; the computation of sensitivities with respect to atmosphere choice is not supported.

  1. The sensitivities are computed numerically.

Example

import numpy as np

from ADRpy import atmospheres as at
from ADRpy import constraintanalysis as ca

designbrief = {'rwyelevation_m': 0, 'groundrun_m': 313,
                'stloadfactor': [1.5, 1.65], 'turnalt_m': [1000, 1075], 'turnspeed_ktas': [100, 110],
                'climbalt_m': 0, 'climbspeed_kias': 101, 'climbrate_fpm': 1398,
                'cruisealt_m': [2900, 3200], 'cruisespeed_ktas': [170, 175], 'cruisethrustfact': 1.0,
                'servceil_m': [6500, 6650], 'secclimbspd_kias': 92,
                'vstallclean_kcas': 69}
designdefinition = {'aspectratio': [10, 11], 'sweep_le_deg': 2, 'sweep_25_deg': 0, 'bpr': -1,
                    'wingarea_m2': 13.46, 'weight_n': 15000,
                    'weightfractions': {'turn': 1.0, 'climb': 1.0, 'cruise': 0.853, 'servceil': 1.0}}
designperformance = {'CDTO': 0.0414, 'CLTO': 0.59, 'CLmaxTO': 1.69, 'CLmaxclean': 1.45, 'mu_R': 0.02,
                     'CDminclean': [0.0254, 0.026], 'etaprop': {'take-off': 0.65, 'climb': 0.8,
                                                                'cruise': 0.85, 'turn': 0.85,
                                                                'servceil': 0.8}}

wingloadinglist_pa = np.arange(700, 2500, 5)
customlabelling = {'aspectratio': 'AR',
                   'sweep_le_deg': '$\Lambda_{LE}$',
                   'sweep_mt_deg': '$\Lambda_{MT}$'}

atm = at.Atmosphere()
concept = ca.AircraftConcept(designbrief, designdefinition, designperformance, atm)

concept.propulsionsensitivity_monothetic(wingloading_pa=wingloadinglist_pa, y_var='p_hp', x_var='s_m2',
                                     customlabels=customlabelling)
smincleanstall_m2(weight_kg)

Minimum wing area defined by the clean stall CLmax and the weight

thrusttoweight_sustainedturn(wingloading_pa)

Baseline T/W req’d for sustaining a given load factor at a certain altitude

thrusttoweight_takeoff(wingloading_pa)

The thrust to weight ratio required for take-off. This function is an implementation of the following simple, analytical model:

\[\frac{\overline{T}}{W} = 1.21\frac{W/S}{\rho C_\mathrm{Lmax}^\mathrm{TO}gd_ \mathrm{G}}+\frac{1}{2}\frac{C_\mathrm{D}^\mathrm{TO}}{C_\mathrm{L}^\mathrm{TO}} +\frac{1}{2}\mu_\mathrm{R}\]

where \(\overline{T}\) is the average thrust during the take-off run, \(W/S\) is the wing loading, \(d_\mathrm{G}\) is the required ground roll, \(C_\mathrm{D}^\mathrm{TO}\) and \(C_\mathrm{L}^\mathrm{TO}\) are the ‘all wheels on the runway’ drag and lift coefficient respectively in the take-off configuration, \(C_\mathrm{Lmax}^\mathrm{TO}\) is the maximum lift coefficient achieved during the take-off run (during rotation), \(\rho\) is the ambient density and \(\mu_\mathrm{R}\) is the coefficient of rolling resistance on the wheels.

This is a function exposed to the user for clarity and added flexibility. If you need to calculate the thrust to weight ratio required for take-off, use twrequired_to. This corrects the output of this function to account for the environmental conditions (including their impact on engine performance) and includes a mapping to static thrust. thrusttoweight_takeoff should only be used if you would like to perform these corrections in a different way than implemented in twrequired_to.

If a full constraint analysis is required, twrequired should be used. A similar ‘full constraint set’ function is available for calculating the power demanded of the engine or electric motor of a propeller-driven aircraft (to satisfy the constraint set) - this is called powerrequired.

twrequired(wingloading_pa, feasibleonly=True, map2sl=True)

Calculate the T/W required for t/o, trn, clm, crs, sec.

This method integrates the full set of constraints and it gives the user a compact way of performing a full constraint analysis. If a specific constraint is required only, the individual methods can be called separately: twrequired_to (take-off), twrequired_trn (turn), twrequired_clm (climb), twrequired_trn (turn), twrequired_crs (cruise), twrequired_sec (service ceiling).

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

twreq

dictionary variable, wherein each entry contains vectors related to one of the constraints: twreq['take-off'] (T/W required for take-off), twreq['liftoffspeed_mps'] (liftoff speed in m/s), twreq['avspeed_mps'] (average speed of the take-off run, in m/s), twreq['turn'] (T/W required for the turn), twreq['turnfeasible'] (same as twreq['turn'], but with NaN where the maximum lift coefficient is exceeded), twreq['turncl'] (lift coefficient required in the turn), twreq['climb'] (T/W required for climb), twreq['cruise'] (T/W required for cruise), twreq['servceil'] (T/W required for the service ceiling constraint), twreq['combined'] (the T/W required to meet all of the above).

twrequired_clm(wingloading_pa, map2sl=True)

Calculates the T/W required for climbing for a range of wing loadings.

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

twratio

array, thrust to weight ratio required for the given wing loadings.

See also twrequired

Notes

1. Use twrequired if a full constraint analysis is desired, as this integrates the take-off, turn, climb, cruise, and service ceiling constraints, as well as computing the combined constraint boundary.

2. The calculation currently approximates climb performance on the constant TAS assumption (though note that the design brief dictionary variable must specify the climb speed as IAS, which is the operationally relevant figure) - a future version of the code will remove this approximation and assume constant IAS.

Example

Given a climb rate (in feet per minute) and a climb speed (KIAS), as well as an altitude (in a given atmosphere) where these must be achieved, as well as a set of basic geometrical and aerodynamic performance parameters, compute the necessary T/W ratio to hold the specified climb rate.

from ADRpy import atmospheres as at
from ADRpy import constraintanalysis as ca

designbrief = {'climbalt_m': 0, 'climbspeed_kias': 101,
            'climbrate_fpm': 1398}

etap = {'climb': 0.8}

designperformance = {'CDminclean': 0.0254, 'etaprop' :etap}

designdef = {'aspectratio': 10.12, 'sweep_le_deg': 2,
            'sweep_mt_deg': 0, 'bpr': -1}

TOW_kg = 1542.0

designatm = at.Atmosphere()

concept = ca.AircraftConcept(designbrief, designdef,
                            designperformance, designatm)

wingloadinglist_pa = [1250, 1500, 1750]

twratio = concept.twrequired_clm(wingloadinglist_pa)

print('T/W: ', twratio)

Output:

T/W:  [ 0.20249491  0.2033384   0.20578177]
twrequired_crs(wingloading_pa, map2sl=True)

Calculate the T/W required for cruise for a range of wing loadings

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

twratio

array, thrust to weight ratio required for the given wing loadings.

See also twrequired

twrequired_sec(wingloading_pa, map2sl=True)

T/W required for a service ceiling for a range of wing loadings

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

twratio

array, thrust to weight ratio required for the given wing loadings.

See also twrequired

twrequired_to(wingloading_pa, map2sl=True)

Calculate the T/W required for take-off for a range of wing loadings

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

twratio

array, thrust to weight ratio required for the given wing loadings.

liftoffspeed_mpstas

array, liftoff speeds (TAS - true airspeed) in m/s.

avspeed_mps

average speed (TAS) during the take-off run, in m/s.

See also twrequired

Notes

1. The calculations here assume a ‘no wind’ take-off, conflating ground speed (GS) and true airspeed (TAS).

2. Use twrequired if a full constraint analysis is desired, as this integrates the take-off, turn, climb, cruise, and service ceiling constraints, as well as computing the combined constraint boundary.

Example

from ADRpy import atmospheres as at
from ADRpy import constraintanalysis as ca

designbrief = {'rwyelevation_m':1000, 'groundrun_m':1200}
designdefinition = {'aspectratio':7.3, 'bpr':3.9, 'tr':1.05}
designperformance = {'CDTO':0.04, 'CLTO':0.9, 'CLmaxTO':1.6, 'mu_R':0.02}

wingloadinglist_pa = [2000, 3000, 4000, 5000]

atm = at.Atmosphere()
concept = ca.AircraftConcept(designbrief, designdefinition,
                            designperformance, atm)

tw_sl, liftoffspeed_mpstas, _ = concept.twrequired_to(wingloadinglist_pa)

print(tw_sl)
print(liftoffspeed_mpstas)

Output:

[ 0.19397876  0.26758006  0.33994772  0.41110154]
[ 52.16511207  63.88895348  73.77260898  82.48028428]
twrequired_trn(wingloading_pa, map2sl=True)

Calculates the T/W required for turning for a range of wing loadings

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

map2sl

boolean, specifies if the result in the conditions specified, should be mapped to sea level equivalents. Optional, defaults to True.

Outputs:

twratio

array, thrust to weight ratio required for the given wing loadings.

clrequired

array, lift coefficient values required for the turn (see notes).

feasibletw

as twratio, but contains NaNs in lieu of unachievable (CLmax exceeded) values.

See also twrequired

Notes

1. Use twrequired if a full constraint analysis is desired, as this integrates the take-off, turn, climb, cruise, and service ceiling constraints, as well as computing the combined constraint boundary.

2. At the higher end of the wing loading range (low wing area values) the CL required to achieve the required turn rate may exceed the maximum clean CL (as specified in the CLmaxclean entry in the performance dictionary argument of the AircraftConcept class object being used). This means that, whatever the T/W ratio, the wings will stall at this point. The basic T/W value will still be returned in twratio, but there is another output, feasibletw, which is an array of the same T/W values, with those values blanked out (replaced with NaN) that cannot be achieved due to CL exceeding the maximum clean lift coefficient.

Example

Given a load factor, an altitude (in a given atmosphere) and a true airspeed, as well as a set of basic geometrical and aerodynamic performance parameters, compute the necessary T/W ratio to hold that load factor in the turn.

from ADRpy import atmospheres as at
from ADRpy import constraintanalysis as ca
from ADRpy import unitconversions as co

designbrief = {'stloadfactor': 2, 'turnalt_m': co.feet2m(10000),
            'turnspeed_ktas': 140}

etap = {'turn': 0.85}

designperformance = {'CLmaxclean': 1.45, 'CDminclean':0.02541,
                    'etaprop': etap}

designdef = {'aspectratio': 10.12, 'sweep_le_deg': 2,
            'sweep_mt_deg': 0, 'bpr': -1}

designatm = at.Atmosphere()

concept = ca.AircraftConcept(designbrief, designdef,
designperformance, designatm)

wingloadinglist_pa = [1250, 1500, 1750]

twratio, clrequired, feasibletw = concept.twrequired_trn(wingloadinglist_pa)

print('T/W:               ', twratio)
print('Only feasible T/Ws:', feasibletw)
print('CL required:       ', clrequired)
print('CLmax clean:       ', designperformance['CLmaxclean'])

Output:

T/W:                [ 0.19920641  0.21420513  0.23243016]
Only feasible T/Ws: [ 0.19920641  0.21420513         nan]
CL required:        [ 1.06552292  1.2786275   1.49173209]
CLmax clean:        1.45
vstall_kias(wingloading_pa, clmax)

Calculates the stall speed (indicated) for a given wing loading in a specified cofiguration.

Parameters:

wingloading_pa

float or array, list of wing-loading values in Pa.

clmax

maximum lift coefficient (float) or the name of a standard configuration (string) for which a maximum lift coefficient was specified in the performance dictionary (currently implemented: ‘take-off’).

Outputs:

vs_keas

float or array, stall speed in knots.

Note

The calculation is performed assuming standard day ISA sea level conditions (not in the conditions specified in the atmosphere used when instantiating the AircraftConcept object!) so the speed returned is an indicated (IAS) / calibrated (CAS) value.

Example:

from ADRpy import constraintanalysis as ca

designperformance = {'CLmaxTO':1.6}

concept = ca.AircraftConcept({}, {}, designperformance, {})

wingloading_pa = 3500

print("VS_to:", concept.vstall_kias(wingloading_pa, 'take-off'))
wigfactor()

Wing-in-ground-effect factor to account for the change in induced drag as a result of the wing being in close proximity of the ground. Specify the entry wingheightratio in the design dictionary variable you instantiated the AircraftConcept object with in order to compute this - if unspecified, a call to this method will result in a value practically equal to 1 being returned.

The factor, following McCormick (“Aerodynamics, Aeronautics, and Flight Mechanics”, Wiley, 1979) and Gudmundsson (2013) is calculated as:

\[\Phi = \frac{(16\,h/b)^2}{1+(16\,h/b)^2}\]

where \(h/b\) is design[‘wingheightratio’]: the ratio of the height of the wing above the ground (when the aircraft is on the runway) and the span of the main wing.

The induced drag coefficient adjusted for ground effect thus becomes:

\[C_\mathrm{Di} = \Phi C_\mathrm{Di}^\mathrm{oge},\]

where the ‘oge’ superscript denotes the ‘out of ground effect’ value.

Example

import math
from ADRpy import constraintanalysis as co

designdef = {'aspectratio':8}
wingarea_m2 = 10
wingspan_m = math.sqrt(designdef['aspectratio'] * wingarea_m2)

for wingheight_m in [0.6, 0.8, 1.0]:

    designdef['wingheightratio'] = wingheight_m / wingspan_m

    aircraft = co.AircraftConcept({}, designdef, {}, {})

    print('h/b: ', designdef['wingheightratio'],
          'Phi: ', aircraft.wigfactor())

Output:

h/b:  0.06708203932499368  Phi:  0.5353159851301115
h/b:  0.08944271909999159  Phi:  0.6719160104986877
h/b:  0.11180339887498948  Phi:  0.761904761904762
wsmaxcleanstall_pa()

Maximum wing loading defined by the clean stall Clmax

constraintanalysis.tw2pw(thrusttoweight, speed, etap)

Converts thrust to weight to power to weight (propeller-driven aircraft)

Parameters:

thrusttoweight

thrust to weight ratio (non-dimensional)

speed

ground speed (in m/s if output in Watts / Newton is required)

etap

propeller efficiency (non-dimensional), float

Outputs:

power to weight ratio (in W/N if speed is in m/s)

See also powerrequired

Notes

1. A note on units. If the input speed is in m/s, the other two inputs being non-dimensional, the output product is also in m/s, which is equal to W/N (W / N = (J/s) / N = (Nm/s) / N = m/s).

2. The speed input is a kinematic quantity, not an airspeed, so it is generally a ground speed (GS) or a true airspeed (TAS) if we are assuming zero wind.

3. The inputs to the function are scalars or a mix of scalars and numpy arrays.

Example:

from ADRpy import constraintanalysis as ca
from ADRpy import atmospheres as at
from ADRpy import unitconversions as co

designbrief = {'stloadfactor': 2, 'turnalt_m': 3050, 'turnspeed_ktas': 140}

etap = {'turn': 0.85}

designperformance = {'CLmaxclean': 1.45, 'CDminclean': 0.02541,
                        'etaprop': etap}

designdef = {'aspectratio': 10, 'sweep_le_deg': 2,
                'sweep_mt_deg': 0, 'bpr': -1}

TOW_kg = 1500

designatm = at.Atmosphere()
concept = ca.AircraftConcept(designbrief, designdef,
                                designperformance, designatm)

wingloading_pa = 1000

twreq, _, _ = concept.twrequired_trn(wingloading_pa)

turnspeed_mpstas = co.kts2mps(designbrief['turnspeed_ktas'])

pw_trn_wpn = ca.tw2pw(twreq, turnspeed_mpstas, etap['turn'])
pw_trn_hpkg = co.wn2hpkg(pw_trn_wpn)
p_trn_hp = pw_trn_hpkg * TOW_kg

print(p_trn_hp)

Output:

318.691213406

Airworthiness module

This module contains tools for the analysis of an aircraft design from the point of view of meeting initial airworthiness requirements.

class airworthiness.CertificationSpecifications(brief=None, design=None, performance=None, designatm=None, propulsion=None, csbrief=None)

Aircraft concept class designed for capturing those elements of the definition of a design that are required for the preparation of some of the analyses needed for determining the initial airworthiness of an aircraft concept. Currently ADRpy facilitates one such type of analysis - the construction of the V-n diagram of an aircraft concept, as prescribed by Part 23 (as detailed, e.g., by EASA’s CS-23).

Parameters:

brief

Dictionary. See AircraftConcept in constraintanalysis.py.

design

Dictionary. See AircraftConcept in constraintanalysis.py.

performance

Dictionary. See AircraftConcept in constraintanalysis.py.

designatm

Atmosphere class object. See AircraftConcept in constraintanalysis.py.

propulsion

Tuple or String. See AircraftConcept in constraintanalysis.py.

csbrief

Dictionary. Definition of key parameters relating to establishing the initial airworthiness of an aircraft. It contains the following key names:

certcat

String. Used to specify the intended certification category of the aircraft, as per Part 23. Acceptable values are: 'norm' (normal), 'util' (utility), 'comm' (commuter), or 'aero' (aerobatic). Optional, defaults to 'norm'.

altitude_m

Float. The altitude (in metres) at which the calculations are to be performed. Optional, defaults to 0.

cruisespeed_keas

Float. The design cruise speed (in knots, equivalent airspeed). Commonly denoted V_C.

divespeed_keas

Float. The design dive speed (in knots, equivalent airspeed). Commonly denoted V_D.

maxlevelspeed_keas

Float. The design maximum level flight speed at sea level (in knots, equivalent airspeed). Commonly denoted V_H.

weightfraction

Float. The fraction (nondimensional) of the maximum take-off weight at which the calculations are to be performed. Optional, defaults to 1.

flightenvelope(textsize=None, figsize_in=None, show=True)

Construction of the flight envelope, as per CS-23.333(d), see also 14 CFR 23.333. Calling this method will plot the flight envelope at a single wing-loading. For examples, see below and in the Jupyter notebook Constructing V-n diagrams.ipynb included in docs/ADRpy/notebooks.

Note that this V-n diagram should only be seen as indicative. When preparing the documentation for establishing the airworthiness of an aircraft, the engineer responsible for the structural aspects of the airworthiness must conduct his/her own calculations in establishing the flight envelope.

Parameters:

textsize

integer, sets a representative reference fontsize that text in the output plot scale themselves in accordance to. Optional, defaults to 10.

figsize_in

list, used to specify custom dimensions of the output plot in inches. Image width must be specified as a float in the first entry of a two-item list, with height as the remaining item. Optional, defaults to 12 inches wide by 7.5 inches tall.

show

boolean, used to specify if the plot should be displayed. Optional, defaults to True.

Outputs:

coords_poi

dictionary, containing keys A through G, with values of coordinate tuples. These are “points of interest”, the speed [KEAS] at which they occur, and the load factor they are attributed to.

Example

from ADRpy import airworthiness as aw
from ADRpy import unitconversions as co
from ADRpy import atmospheres as at

designbrief = {}

designdef = {'aspectratio': 11.1, 'wingarea_m2': 12.1, 'weight_n': 5872}

designperf = {'CLmaxclean': 1.45, 'CLminclean': -1, 'CLslope': 6.28}

designpropulsion = "piston" # not specifically needed for the V-n diagram here, required simply for 
                            # consistency with other classes and to support features included in later releases 

designatm = at.Atmosphere() # set the design atmosphere to a zero-offset ISA

csbrief={'cruisespeed_keas': 107, 'divespeed_keas': 150,
'altitude_m': 0,
'weightfraction': 1, 'certcat': 'norm'}

concept = aw.CertificationSpecifications(designbrief, designdef, designperf, designatm, designpropulsion, csbrief)
vs_keas(loadfactor)

Equivalent air speed in knots for stall at design weight, for some loadfactor

Unit Conversions

This module contains tools for converting between units commonly used in aircraft design.

unitconversions.c2f(temp_c)

Convert temperature value from Celsius to Fahrenheit

unitconversions.c2k(temp_c)

Convert temperature value from Celsius to Kelvin

unitconversions.c2r(temp_c)

Convert temperature value from Celsius to Rankine

unitconversions.eas2tas(eas, localairdensity_kgm3)

Convert True Air Speed to Equivalent Air Speed

unitconversions.feet22m2(area_ft2)

Converts area value from feet squared to meters squared

unitconversions.feet2m(length_feet)

Converts length value from feet to meters

unitconversions.fpm2mps(speed_fpm)

Convert speed value from feet/min to m/s

unitconversions.hp2kw(power_hp)

Convert power from HP to kW

unitconversions.inhg2mbar(press_inhg)

Convert pressure value from inHg to mbar

unitconversions.k2c(temp_k)

Convert temperature value from Kelvin to Celsius

unitconversions.k2r(temp_k)

Convert temperature value from Kelvin to Rankine

unitconversions.kg2lbs(mass_kg)

Convert mass value from kg to lbs

unitconversions.kg2n(mass_kg)

Converts mass in kg to weight in N

unitconversions.kgm22pa(pressure_kgm2)

Convert pressure value from kg/m^2 to Pa

unitconversions.kgm32sft3(density_kgm3)

Convert density from kg/m^3 to slugs/ft^3

unitconversions.km2m(length_km)

Converts length value from kilometres to metres

unitconversions.kts2mps(speed_kts)

Convert speed value knots to mps

unitconversions.kw2hp(power_kw)

Convert power from kW to HP

unitconversions.lbf2n(force_lbf)

Convert force from lbf to N

unitconversions.lbfft22mbar(press_lbfft2)

Convert pressure value from lb/ft^2 to mbar

unitconversions.lbfft22pa(pressure_lbft2)

Convert pressure from lbf(pound-force)/ft^2 to Pascal

unitconversions.lbs2kg(mass_lbs)

Convert mass value from lbs to kg

unitconversions.m22feet2(area_m2)

Converts area value from meters squared to feet squared

unitconversions.m2feet(length_m)

Convert length value from meters to feet

unitconversions.m2km(length_m)

Converts length value from meters to kilometres

unitconversions.mbar2inhg(press_mbar)

Convert pressure value from mbar to inHg

unitconversions.mbar2lbfft2(press_mbar)

Convert pressure value from mbar to lb/ft^2

unitconversions.mbar2pa(press_mbar)

Convert pressure value from mbar to Pascal

unitconversions.mps2kts(speed_mps)

Convert speed value from m/s to knots

unitconversions.n2kg(force_n)

Converts force in N to mass in kg

unitconversions.n2lbf(force_n)

Convert force from N to lbf

unitconversions.pa2kgm2(pressure_pa)

Convert pressure value from Pa to kg/m^2

unitconversions.pa2lbfft2(pressure_pa)

Convert pressure from Pascal to lbf(pound-force)/ft^2

unitconversions.pa2mbar(press_pa)

Convert pressure value from Pascal to mbar

unitconversions.r2c(temp_r)

Convert temperature value from Rankine to Celsius

unitconversions.r2k(temp_r)

Convert temperature value from Rankine to Kelvin

unitconversions.sft32kgm3(density_slft3)

Convert density from slugs/ft^3 to kg/m^3

unitconversions.tas2eas(tas, localairdensity_kgm3)

Convert True Air Speed to Equivalent Air Speed

unitconversions.wn2hpkg(powertoweight_wn)

Convert power to weight (Watt/N) to hp/kg

unitconversions.wn2kwkg(powertoweight_wn)

Convert power to weight (Watt/N) to kW/kg

unitconversions.wn2wkg(powertoweight_wn)

Convert power to weight (Watt/N) to W/kg

Miscellaneous Utilities

This module contains miscellaneous tools to support aircraft engineering calculations and data analysis.

mtools4acdc.fdrplot(timeseriescsvfile, timeline, panels, markers, figpars)

Generates a multi-panel time series plot, suitable, for example, for the analysis of flight test data.

Parameters:

timeseriescsvfile

CSV file containing the data to be visualised. It must have a header containing the names of the channels, with each corresponding signal in the column underneath its name. There should be a time column (elapsed time in seconds) and the data should be ordered according to this column.

timeline

List with four entries: the header of the time column in the CSV file (string), the label of the time (horizontal) axis (string), the time at which the plot should start (float) and the time at which the plot should end (float).

panels

List of lists of variables to be plotted. Each list represents one panel on the plot, and is of the form [panel y-label, channel1, channel2, …] (all strings), channel1, channel2, etc. should be column headings from the CSV file. They will also become the legend labels. There should be at least two lines (two panels). See example below.

markers

A list of two lists, specifying the location and color of vertical marker lines (e.g., to mark some landmark point in the flight, such as the beginning of rotation and lift-off in the example below).

figpars

A list of two lists and an integer of the form [[fig width, fig height, dpi], [axes label font size, tick font size, legend font size], colourscheme]. Set colourscheme to 1 for a clean, minimalistic look (recommended). See example below.

Outputs:

f

figure object

axes

subplot axes handles

flightdata_tf

pandas dataframe containing the plotted data (the original CSV file data trimmed as specified by the time limits).

Example - visualising a take-off:

import ADRpy
from ADRpy import mtools4acdc as adrpytools
import os

timeline = ['Time', 'Time (s)', 20, 60]

panels = [
    ['Angles (deg)', 'True AoA', 'Pitch angle'],
    ['Altitude (ft)', 'IRS Alt', 'GPS Alt', 'Press alt'],
    ['Body rotation rates (deg/s)', 'Roll rate', 'Pitch rate', 'Yaw rate'],
    ['Speed (knots)', 'IAS', 'TAS', 'GPS GS']
]

timeseriescsvfile = os.path.join(ADRpy.__path__[0], "data", "sample_takeoff_data.csv")

markers = [[40, 43.8], ['grey','grey']]

figpars = [[6, 10, 300], [8, 8, 8], 1]

figobj, axes, flightdata = adrpytools.fdrplot(
    timeseriescsvfile, timeline, panels, markers, figpars)

Output:

A four-panel time series plot of 11 channels of data.
mtools4acdc.iterable(obj)

Use to determine if object “obj” is iterable. Returns a boolean.

mtools4acdc.panelplot_with_shared_x(haxis, vaxes, hlabel, vlabels, vlines, vlinecols, figpar=[6, 10, 100], tex=False, fam='sans-serif', fontsizes=[8, 8, 8])

Multi-panel plots with a shared x-axis, e.g., for time series. For plotting flight data (e.g., as seen in accident reports), use fdrplot.

mtools4acdc.panelplot_with_shared_y(vaxis, haxes, hlimits, vlabel, hlabels, hlines, hlinecols, figpar=[10, 6, 100], tex=False, fam='sans-serif')

Multi-panel plots with a shared y-axis, e.g., for atmosphere profiles. See the Jupyter notebook Introduction_to_Modelling_the_Atmosphere… in the docs/ADRpy directory for usage examples.

mtools4acdc.polyblend(time, time_f, signal_i, signal_f)

A smooth blend between two levels of a signal. Suitable for approximating thrust variations associated with spool-up and spool-down, etc.

mtools4acdc.recastasnpfloatarray(scalarorvec)

Recasts an arbitrary argument as a numpy float array. Used internally by some of the constraint calculations to increase robustness, though the use of numpy arrays as inputs is the recommended approach in most cases.