AFPT -- Basic Usage

  1. Define a bird description using the Bird() constructor.
  2. Compute flight performance using computeFlightPerformance().

Bird description

A bird can be defined using the Bird() construction function. This function ensures that the generated object contains all required parameters that describe the bird.

myBird <- Bird(
  massTotal = 0.215, #  weight in kg
  wingSpan = 0.67,  #  wingspan in m
  wingArea = 0.0652, #  wing area in m2
  name = 'Jackdaw',
  name.scientific = 'Corvus monedula',
  type = 'passerine',
  source = 'KleinHeerenbrink M, Warfvinge K and Hedenstrom A (2016) J.Exp.Biol. 219: 10, 1572--1581'

Any parameters that are not specified, but that are required by any of the flight performance calculations will be filled in with either defaults or estimated with allometric scaling relationships. For instance, the body frontal area, that is used for computing body drag, is in this case calculated based on the specified massTotal from an allometric relationship for type='passerine':


It is possible to modify the bird description simply by reassigning the variables in the list, i.e.

myBird$wingbeatFrequency <- 5

However, it should be noted that some of the variables are related to others (e.g. massTotal is the sum of massEmpty, massFat and massLoad), so that manual changes can lead to unexpected results.

Compute flight performance

Flight performance can be computed using computeFlightPerformance(). It calculates maximum available mechanical power from the muscles, aerodynamic (mechanical) power for flapping flight as a function of airspeed and the corresponding chemical power.

flightperf <- computeFlightPerformance(myBird)

This is the simplest call to computeFlightPerformance(). The print() of the flightperf shows a summary of the computed powercurve. The function computeFlightPerformance() has calculated several characteristic airspeeds:

[^1]: At the minimum speed, the assumption of fast forward flight may be invalid. See also the section about validity flags.

These characteristic speeds are stored as a data.frame named table, which contains several more advanced variables not shown in the print, as explained in the following sections.

The function computeFlightPerformance() also estimates the best climb performance, i.e. the maximum climb rate that can be achieved given the power available from the muscles. This data point is stored in the data.frame named maxClimb. It contains the same variables as table, plus an additional one: climbRate.

Finally, computeFlightPerformance() also computes a powercurve for a range of speeds. The length of this curve can be specified by providing a length.out argument, but the default produces 10 points. This curve can be used to visualize the speed dependency of the various variables.

powercurve <- flightperf$powercurve

mtext(side = 1, line = 2, 'Airspeed (m/s)')
mtext(side = 2, line = 2, 'Peak amplitude (deg)')

Wingbeat kinematics

In the current example, the strokeplane is optimized. The model also implicitly optimizes the wingbeat amplitude for minimum induced power, so essentially the returned powercurve represents the optimal wingbeat for a given wingbeat frequency.


By default, computeFlightPerformance() will try to optimize the strokeplane angle for minimum power at any given speed. This optimization is performed many times, which results in a high computational load. The optimization can be avoided by explicitly specifying a strokeplane angle, e.g. computeFlightPerformance(myBird,strokeplane=0).

Validity flags

table contains flags that indicate whether the data point is outside the validity range of the model:


In this case the flags indicate the the minimum speed is outside the model's validity range, indicating too high reduced frequency and too high thrust requirement. The model was obtained for reduced frequencies $1 \leq k_f \leq 6$ and thrust requirements (thrust to lift ratio) $0 \leq \frac{T}{L} \leq 0.3$. The flag flags.speedLo indicates that the data point is below the low speed limit of the model ($U<2w_\mathrm{i,h}$; airspeed is lower than twice the induced downwash in hover[^2]). Data points with flags may be reasonable extrapolations of the model, but it is safer to assume flagged data points are invalid.

[^2]:see @KleinHeerenbrink2015 p. 13.

Non-flapping drag components

Stored in the table are also the drag components. Only the non-flapping (Dnf) components are stored:


These are the induced drag, zero lift profile drag, lift dependent profile drag and parasitic drag, respectively. The latter includes the body drag, but also any other additional drag (e.g. the drag component of weight during climb).

with(powercurve , plot( speed, Dnf.ind, type='b', col='red3', 
                        xlab=NA, ylab=NA, xlim=c(0,20), ylim=c(0.0,0.20)))
with(powercurve , lines( speed, Dnf.pro0, type='b', col='green3'))
with(powercurve , lines( speed, Dnf.pro2, type='b', col='blue3'))
with(powercurve , lines( speed, Dnf.par, type='b', col='yellow3'))
mtext(side = 1, line = 2,'Airspeed (m/s)')
mtext(side = 2, line = 2,'Drag (N)')

The above figure shows the magnitude of the non-flapping drag components for different speeds. The lift dependent components are very large at low speeds and they decrease rapidly with increasing speed. The parasitic drag shows the classic quadratic behaviour with speed. The zero-lift profile drag is near zero at low speeds, and increases more linearly with speed. This is due to the strong dependence of the friction coefficient on the Reynolds number. As non-flapping effectively means gliding, these drag components can be used to construct a drag polar for gliding flight. However, this ignores the wing flex that typically occurs at higher speeds.

Drag factors and power factors

Flapping the wings alters the drag experienced by the wings: $D = k_D D^\prime$ (using $D^\prime$ for non-flapping drag) [^3]. The factors $k_D$ depend on the wingbeat kinematics and are returned in table:


These factors are for induced drag, zero lift profile drag and lift dependent profile drag respectively.

[^3]: flapping flight factors as per @KleinHeerenbrink2015.

The aerodynamic power components for flapping flight can be computed in a similar way: $P = k_P D^\prime U$. The factors $k_P$ depend on the wingbeat kinematics and are also stored in table:

with(powercurve , plot( speed, kD.ind, type='b', col='red3', 
                        xlab=NA, ylab=NA, xlim=c(0,20), ylim=c(0.5,2.5)))
with(powercurve , lines( speed, kD.pro0, type='b', col='green3'))
with(powercurve , lines( speed, kD.pro2, type='b', col='blue3'))
mtext(side = 1, line = 2,'Airspeed (m/s)')
mtext(side = 2, line = 2,'Drag factors (-)')

with(powercurve , plot( speed, kP.ind, type='b', col='red3', 
                        xlab=NA, ylab=NA, xlim=c(0,20), ylim=c(0.5,2.5)))
with(powercurve , lines( speed, kP.pro0, type='b', col='green3'))
with(powercurve , lines( speed, kP.pro2, type='b', col='blue3'))
mtext(side = 1, line = 2,'Airspeed (m/s)')
mtext(side = 2, line = 2,'Power factors (-)')

The above figure shows the speed dependency of the drag factors and power factors. At low speeds the lift-dependent drag factors have a low value. There is even a tendency for the factors to drop below 1. The zero-lift profile drag instead takes very large values. At these low speeds the velocity of the wings starts to become more dominant than the flight speed.


Several other variables are also stored in table:


These are respectively the wingbeat frequency (in this case as specified in myBird), the lift force (in this case just equal to weight), the mean chord Reynolds number, and the zero lift profile drag coefficient (dependent on mean chord Reynolds number).

Flight condition

All models by default use the internal FLIGHTCONDITION, which describes the standard atmosphere, with air density $\rho=1.225$ kg m^3^, gravitational acceleration $g=9.81$ m s^-2^ and kinematic viscosity $\nu=14.61\times 10^{-6}$ m^2^ s^-1^. It is possible to define an alternative flight condition:

myFlightCondition <- list(
  density = 0.9093, # [kg/m3] 3 km altitude
  gravity = 9.81, # [m/s2]
  viscosity = 18.63E-6, # [m2/s] 3 km altitude
  windSpeed = 0,# [m/s]
  windDir = 0 # [degrees] 0 degrees means wind is along the track direction

Air density decreases with altitude, and a density of $\rho=0.909$ kg m^3^ corresponds to a flight altitude of 3 km above sea level in the international standard atmosphere. At this altitude the kinematic viscosity has increased to $\nu=18.63\times 10^{-6}$ m^2^ s^-1^. This alternative flight condition can be used in the performance calculation as:

flightperf.ISA3 <- computeFlightPerformance(myBird,flightcondition=myFlightCondition)

Note how the power requirements have increased (this is only apparent from the minimumPower and maximumRange, as the maximum available power is unchanged), but the characteristic speeds also increased. Looking at the energetic cost per traveled distance:

COT.ISA0 <- with(flightperf$table,power.chem/speed); 
COT.ISA3 <-with(flightperf.ISA3$table,power.chem/speed); 
list(ISA0 = COT.ISA0, ISA3 = COT.ISA3)

it appears that flying at the maximum range speed at a higher altitude will actually reduce the maximum range (which can be attributed to the increase in kinematic viscosity, increasing the profile drag coefficient). However, the 1% increase in flight cost does pay back as a 15% reduction in flight time. In fact, if the bird cares about time minimization, flying at altitude is highly advantageous, increasing the maximum flight speed while reducing the associated cost of transport.


Try the afpt package in your browser

Any scripts or data that you put into this service are public.

afpt documentation built on Sept. 2, 2017, 1:06 a.m.