AFPT Multiple Birds

Marco Klein Heerenbrink

2017-09-01

library(afpt)

In this example we will look at how to compute flight performance for a set of birds. We will use the birds described in Hedenström and Alerstam (1992). The pacakge has limited capabilities for handling multiple birds in a data.frame. We first load the data set in the workspace. This prepared data set already has a format recognized by the bird constructor, and can therefore be used directly as Bird(climbing_birds).

data(climbing_birds) #  Load climbing bird data set

climbing_birds <- climbing_birds#[seq(1,15,3),]
myBirds <- Bird(climbing_birds)

myBirds$coef.profileDragLiftFactor[myBirds$name=='Mute swan'] = 0 
# we have to assume that swans has specialized aerofoil, as it otherwise won't be able to fly
# this may be true for other birds too, and should be investigated further...

myBirds[c('name','massTotal','wingSpan','wingArea','wingbeatFrequency')]
##                  name massTotal wingSpan    wingArea wingbeatFrequency
## 1           Mute swan  10.56000     2.23 0.540532609               3.5
## 2       Greylag goose   3.57500     1.64 0.316423529               3.8
## 3               Eider   1.79300     0.94 0.105190476               7.0
## 4  Red-throated diver   1.36400     1.11 0.100991803               5.5
## 5         Brent goose   1.36400     1.15 0.123598131               5.0
## 6              Curlew   0.79200     0.90 0.120895522               5.5
## 7              Wigeon   0.71500     0.80 0.078048780               6.5
## 8         Wood pigeon   0.53900     0.78 0.093600000               5.8
## 9       Oystercatcher   0.52800     0.83 0.079183908               5.7
## 10        Arctic tern   0.12100     0.80 0.057142857               4.1
## 11        Song thrush   0.06588     0.34 0.019266667              10.1
## 12             Dunlin   0.04998     0.40 0.014545455               8.1
## 13              Swift   0.04070     0.45 0.015340909               6.8
## 14          Chaffinch   0.02204     0.26 0.012754717               9.8
## 15             Siskin   0.01140     0.21 0.007474576              11.2

As this data set was used in relation to climb performance, we will use the function findMaximumClimbRate():

myBirds$powerAvailable <- computeAvailablePower(myBirds)
climbperf <- findMaximumClimbRate(myBirds,maximumPower = myBirds$powerAvailable,strokeplane=20)
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio

## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...):
## Power required to descend at this speed is higher than the power available.
## Warning in .findMaximumClimbRate.function(fun, maximumPower, speed, ...): 1 model validity flags raised:
##  High Thrust Ratio
climbperf[c('speed','climbRate','frequency','amplitude')]
##        speed  climbRate frequency amplitude
## 1  17.437234 0.27598741       3.5  28.95810
## 2  16.085625 0.07381682       3.8  33.26917
## 3  17.923576 0.27167314       7.0  41.48678
## 4  15.314955 0.41368742       5.5  39.44518
## 5  14.640349 0.40712680       5.0  39.08424
## 6  13.151185 0.64786121       5.5  43.73877
## 7  14.122421 0.68897362       6.5  45.47488
## 8  12.467322 0.74436634       5.8  46.58590
## 9  12.320401 0.76769487       5.7  45.44499
## 10  7.033862 0.89175445       4.1  48.30411
## 11  9.882467 1.77672285      10.1  65.18206
## 12  8.455751 1.40921938       8.1  59.83829
## 13  7.277247 1.46502960       6.8  60.39518
## 14  7.546147 1.76797674       9.8  71.69574
## 15  5.013951 2.30762726      11.2  83.54983

Without prescribing an airspeed, this function searches for the airspeed that maximizes climbrate. Climbrate is computed by adding a component of the weight, \(W\sin\gamma\), to the drag (here \(W\) is the weight, and \(\gamma\) is the climb angle), and then finding the climb angle at which the aerodynamic power requirement matches the available power. This gives a slightly different result than the traditional method of converting the power margin at minimum power speed directly, because the propulsive efficiency depends on the thrust requirement. For comparison:

minpower <- findMinimumPowerSpeed(myBirds,strokeplane=20)
climbperf.trad <- data.frame( # compute traditional climb performance
  speed = minpower$speed,
  climbRate = (myBirds$powerAvailable-minpower$power)/myBirds$massTotal/9.81
)

climbperf[c('speed','climbRate')]/climbperf.trad # compare
##        speed climbRate
## 1  1.0187631 0.8421719
## 2  1.0050750 0.7932620
## 3  1.0154745 0.7406871
## 4  1.0263884 0.7817314
## 5  1.0282111 0.7873369
## 6  1.0512358 0.7836472
## 7  1.0493672 0.7673626
## 8  1.0623172 0.7776499
## 9  1.0618622 0.7891940
## 10 1.1104072 0.8354703
## 11 1.1556532 0.7702182
## 12 1.1405148 0.7948562
## 13 1.1547435 0.8160012
## 14 1.1989975 0.7780880
## 15 0.9010589 0.8540825

The climb performance of these birds was observed by radar tracking. The model can predict the maximum climbrate for these observed speeds:

myBirds$climbSpeed <- climbing_birds$climbSpeed # attach observed climb speeds to the bird data
climbperf2 <- findMaximumClimbRate(
  myBirds,computeAvailablePower(myBirds),
  speed=myBirds$climbSpeed, # specify observed climb speeds
  strokeplane=20
)
                    
climbperf2[c('speed','climbRate','frequency','amplitude','strokeplane')]
##    speed  climbRate frequency amplitude strokeplane
## 1   16.7 0.27277198       3.5  28.95211          20
## 2   15.9 0.07353519       3.8  33.26125          20
## 3   16.9 0.26065227       7.0  41.39131          20
## 4   17.9 0.34735164       5.5  39.51922          20
## 5   16.4 0.37621073       5.0  39.13836          20
## 6   14.9 0.61239513       5.5  43.78936          20
## 7   20.3 0.25871426       6.5  45.51540          20
## 8   15.5 0.62966622       5.8  46.62685          20
## 9   13.6 0.74683532       5.7  45.47474          20
## 10   9.9 0.74390078       4.1  47.88441          20
## 11  12.4 1.63959372      10.1  64.96896          20
## 12  13.9 0.80656514       8.1  59.09936          20
## 13  10.0 1.29593370       6.8  59.79491          20
## 14  11.2 1.39915854       9.8  70.73258          20
## 15  13.4 0.77087587      11.2  75.39675          20

Climb performance predicted and observed – Black markers indicate observed climb performance; Red markers indicate predicted performance. Climb rate predicted and observed – Black markers indicate observed climb performance; Green markers indicate predicted climb performance at observed climb speedClimb performance predicted and observed – Black markers indicate observed climb performance; Red markers indicate predicted performance. Climb rate predicted and observed – Black markers indicate observed climb performance; Green markers indicate predicted climb performance at observed climb speed

Climb performance predicted and observed – Birds in the top-left quadrant are predicted at nearly the observed flight speed, but were observed climbing faster than alowed by the model, indicating their drag is estimated too high. The birds in the top-right quadrant are flying at a higher flight speed than predicted and their climbrate is also higher, suggesting most likely body drag is estimated too high. The birds in the lower-right quadrant may just have been observed performing a sub-optimal climb. Alternatively particularly their lift dependent drag may be under predicted in the model. The arrows indicate the climb rate predicted by the model for the observed flight speed. In this case all positive values indicate the drag in the model is too high.

Climb performance predicted and observed – Birds in the top-left quadrant are predicted at nearly the observed flight speed, but were observed climbing faster than alowed by the model, indicating their drag is estimated too high. The birds in the top-right quadrant are flying at a higher flight speed than predicted and their climbrate is also higher, suggesting most likely body drag is estimated too high. The birds in the lower-right quadrant may just have been observed performing a sub-optimal climb. Alternatively particularly their lift dependent drag may be under predicted in the model. The arrows indicate the climb rate predicted by the model for the observed flight speed. In this case all positive values indicate the drag in the model is too high.

References

Hedenström, Anders, and Thomas Alerstam. 1992. “Climbing performance of migrating birds as a basis for estimating limits for fuel-carrying capacity and muscle work.” J. Exp. Biol. 164 (MARCH 1992): 19–38. http://jeb.biologists.org/content/164/1/19.short.