Aircraft Design Recipes in Python – User’s Guide¶
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.
Off-standard, temperature offset versions of the above.
3. Extremely warm/cold, and low/high density atmospheres from US MIL HDBK 310
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.
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 intwrequired_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 calledpowerrequired
.
- 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 astwreq['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
inconstraintanalysis.py
.- design
Dictionary. See
AircraftConcept
inconstraintanalysis.py
.- performance
Dictionary. See
AircraftConcept
inconstraintanalysis.py
.- designatm
Atmosphere class object. See
AircraftConcept
inconstraintanalysis.py
.- propulsion
Tuple or String. See
AircraftConcept
inconstraintanalysis.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 indocs/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
throughG
, 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.
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.
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.