library('afpt')
Bird()
constructor.computeFlightPerformance()
.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'
:
myBird$bodyFrontalArea
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.
The default bird settings mostly follow the suggestions in @Pennycuick2008.
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) flightperf
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:
minimumSpeed
: the required aerodynamic power equals the maximum available muscle power[^1].minimumPower
: the required aerodynamic/chemical power is minimal, i.e. this is the speed for maximum endurance.maximumRange
: the cost of transport is minimal, i.e this is the speed for maximum range.maximumSpeed
: required aerodynamic power equals the maximum available muscle power.[^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
. Similarly, the function also produces a data.frame
named minTime
, which holds the flight performance for time minimizing migratory flight. At this airspeed, which will be slightly higher than the maximum range speed, the bird balances flight time with the time it takes to (re)gain the energy lost during flight.
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 plot(flightperf,symbol.speed="U") plot(powercurve$speed,powercurve$amplitude,xlab=NA,ylab=NA,type='b',xlim=c(0,20),ylim=c(20,60)) mtext(side = 1, line = 2, 'Airspeed (m/s)') mtext(side = 2, line = 2, 'Peak amplitude (deg)')
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.
flightperf$table[c('speed','frequency','strokeplane','amplitude')]
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)
.
table
contains flags that indicate whether the data point is outside the validity range of the model:
flightperf$table[,grep('^flags.',names(flightperf$table))]
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.
Stored in the table
are also the drag components. Only the non-flapping (Dnf
) components are stored:
flightperf$table[,grep('^Dnf.',names(flightperf$table))]
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).
par(mar=c(3.1,3.1,0.4,1.1),mgp=c(1.9,.7,0),cex=0.75) 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.
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
:
flightperf$table[,grep('^kD.',names(flightperf$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
:
flightperf$table[,grep('^kP.',names(flightperf$table))]
par(mar=c(3.1,3.1,0.4,1.1),mgp=c(1.9,.7,0),cex=0.75) 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
:
flightperf$table[c('frequency','L','ReynoldsNumber','CDpro0')]
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).
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) flightperf.ISA3
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) COT.ISA3/COT.ISA0
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.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.