This repository is being developed to advance the state of the art of drone performance predictions under a wide range of weather and battery conditions with mission planning in mind. An interactive GUI is available at http://droneecon.com. This README will explain general usage as well as the underlying theory for the models used, as currently implemented. Note that Drone-AWE is a work in progress (see Future Work). This document will explain general usage for the latter, as well as the engineering theory at work behind the scenes.
Drone-AWE may be used in two ways: using the GUI available at http://droneecon.com, or by using the source code directly. To use the source code directly, install using
pip install drone_awe
Base functionality is achieved by running the following:
import drone_awe
m = drone_awe.model(args)
m.simulate()
where args
is a dictionary containing simulation parameters. Note that for every parameter not specified in args
, a default value is used. It is possible to run the default simulation by passing an empty dictionary into the drone_awe.model()
method:
import drone_awe
m = drone_awe.model({})
m.simulate()
Settable dictionary keys with example values for args
include the following:
{
"validation":False,
"validationcase":"DiFranco2016",
"dronename":"dji-Mavic2",
"batterytechnology":"near-future",
"stateofhealth":90.0,
"startstateofcharge":100.0,
"rain":False,
"dropsize":1.0,
"liquidwatercontent":1.0,
"temperature":15.0,
"wind":False,
"windspeed":10.0,
"winddirection":0.0,
"relativehumidity":0.0,
"mission": {
"missionspeed": 10.0,
"altitude":100.0,
"heading":0.0,
"payload:0.0
},
"timestep":1,
"plot":True,
"xlabel":"missionspeed",
"ylabel":"power",
"title":"First_test",
"simulationtype":"simple",
"model":"abdilla",
"xvals":[0,1,2,3,4,5],
"weathereffect":"temperature",
"weathervals":[10,20,30,40]
}
These are explained further in Settings. After a drone_awe.model
object is instantiated, settings can be changed by modifying the input
class variable as:
m.input['xlabel'] = 'payload'
m.input['validationcase'] = 'Stolaroff2018'
The simulation must then be re-run using:
m.simulate()
An optional boolean may be set to produce a plot on runtime by running:
m = drone_awe.model({},plot=True)
when a drone_awe.model
is instantiated. Alternatively, the drone_awe.model
's plot
variable may be set at any time:
m.plot = True
The following subsections explain the use of various settings of a drone_awe.model
object.
'dronename'
must be set to a string that is defined in the drone database. To access a dictionary containing all supported drones, use the following methods:
droneDictionary = drone_awe.drones
If a drone or validation case does not exist in the drone database, it may still be used by setting a custom dictionary:
m.drone = droneDictionary
where droneDictionary
is a dictionary with the same keys as the following:
{
'id': 'dji-Mavic2',
'wingtype': 'rotary',
'diagonal': 0.354,
'takeoffweight': 0.907,
'speedmax': 20,
'altitudemax': 6000,
'endurancemax': 31,
'endurancemaxspeed': 6.944,
'endurancemaxhover': 29,
'rangemax': 18000,
'rangemaxspeed': 13.889,
'temperaturemin': -10,
'chargerpowerrating': 60,
'batterytype': 'LiPo',
'batterycapacity': 3850,
'batteryvoltage': 15.4,
'batterycells': 4,
'batteryenergy': 59.29,
'batterymass': 0.297,
'waterproof': 'no',
'windspeedmax': 10.8,
'batteryrechargetime': 90,
'rotorquantity': 4,
'rotordiameter': 0.2,
'cruisespeed': 6.94,
'payload': 0.0,
'length': 0.322,
'width': 0.242,
'height': 0.084
}
Note that not all parameters need be specified, but if a simulation is run that requires unspecified parameters, the model will not run.
To view validation cases for drone_awe
models, set 'validation'=True
and 'validationcase'
to a string contained in the validation case database. To access a dictionary containing all supported validation cases, run the following:
validationDictionary = drone_awe.validationdata()
Additionally, validationCaseDictionary
is a dictionary with the following format:
{
'id': 'Stolaroff2018',
'xvalid': [1.358974359,1.7179487179,1.6923076923,1.7692307692,1.7692307692,1.8205128205,1.8717948718,1.8974358974,1.9230769231,1.9743589744,2.0512820513,2.1025641026,2.1025641026,2.1794871795,2.2820512821,2.3076923077,2.3333333333,2.4358974359,2.5384615385,2.5384615385,2.6666666667,2.7948717949,2.9487179487,3.1025641026,3.2564102564,3.358974359,3.4615384615,3.641025641,3.7435897436,3.8717948718,4.0512820513,4.2564102564,4.358974359,4.641025641,4.8974358974,5.8461538462,6,6.2820512821,6.5384615385,7.1538461538,7.4871794872,7.8205128205,8.4871794872,9.1794871795,9.7692307692,10.2564102564,10.6923076923,11.1282051282,11.5897435897],
'yvalid': [133.7510729614,149.2375075128,142.6477385276,144.5897859156,140.9450186657,141.7583868756,142.3874173587,140.4340604922,139.3656195241,139.5335348046,140.2321151941,139.9589946754,136.1689649626,138.3618186589,141.3711557508,139.4001574523,136.7492021569,136.5131929807,137.712167001,133.136399421,135.7755034665,136.58240428,141.8694500174,143.7278953027,145.8751386173,144.4503136349,143.5492800366,144.4966689523,140.8944307591,139.7885398414,140.0842115956,140.6905892611,140.7593265104,140.4412051028,148.3297356325,161.0751453894,160.7738527567,158.8079335653,157.0439596719,161.2248774665,165.1381601781,164.7032531681,177.1408013138,175.6982333173,190.095233258,197.4485952036,209.0736216573,203.7684942987,215.7551870381],
'drone': {
'validationcase':'Stolaroff2018',
'wingtype': 'rotary',
'rotorquantity': 4,
'takeoffweight': 1.3,
'batterytype': 'LiPo',
'batteryvoltage': 11.1,
'batterymass': 0.262,
'props': '10x4.7',
'endurancemaxhover': 16,
'payloadmax': 0.4,
'batterycapacity': 5500,
'payload': 0.0,
'rotordiameter': 0.254,
'batterycells': 3,
'length': 0.280,
'width': 0.140,
'height': 0.100,
'waterproof': 'no'
},
'settings': {
'dronename': 'drone',
'stateofhealth': 100.0,
'startstateofcharge': 100.0,
'altitude': 100.0,
'temperaturesealevel': 15.0,
'rain': False,
'dropsize': 0.0,
'liquidwatercontent': 1.0,
'temperature': 15.0,
'wind': False,
'windspeed': 0.0,
'winddirection': 0.0,
'relativehumidity': 85.0,
'icing': False,
"mission": {
"missionspeed": 10.0
},
'timestep': 1,
'xlabel': 'missionspeed',
'ylabel': 'alpha',
'title': 'Stolaroff',
'simulationtype': 'simple',
'model': 'abdilla',
'xvals': [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0],
'validation': False,
'validationcase': 'Stolaroff2018',
'batterytechnology': 'current'
}
}
Data used for validation cases can be found in [2,6-10].
Some specifications are not explicitly available, or require some adaptation at runtime. Note that the 'altitude'
setting of validation cases is not always known and is set by default to '0'
. 'length'
, 'width'
, and 'height'
parameters are not necessarily set to geometrically accurate values; rather, they are set so that 'length'
times 'width'
results in the top area and that 'width'
times 'height'
results in the drone's frontal area.
When simulating a fixed-wing drone, the current model requires input parameters for the lift-to-drag ratio ('L/D'
) and the efficiency of the propulsive system ('propulsiveefficiency'
). Ballpark estimates for small UAVs are on the order of 10 and 30%, respectively, although these values heavily depend on the specific geometries and propulsive systems of the drones.
These parameters need to be edited for each specific fixed-wing drone in drones.py.
'batterytechnology'
must be set to one of the following options: 'current'
, 'near-future'
, or 'far-future'
. 'current'
will use the current battery capacity as specified in drone.params
. 'near-future'
projects a future capacity in five years based on an increase of 3.5% of battery capacity each year. 'far-future'
projects battery capacity for lithium-air batteries, about ten times the capacity of current LiPo batteries.
'stateofhealth'
refers to the amount of capacity contained within the battery relative to its initial capacity at first use. 100% would be a new battery. LiPo batteries (most commonly used battery for drones) are typically retired when their state of health falls to 80-85%. At lower states of health, the battery capacity is decreased and cycles through a full charge more quickly.
'stateofcharge'
refers to the current capacity level of the battery, where 100% is fully charged (regardless of how much the battery has been used before), and 0% is a dead battery.
These parameters specifiy rain characteristics. If there is no rain in the simulation, set these to 0.0.
'dropsize'
refers to the diameter of a raindrop (assuming a spherical shape), with units of meters. 'liquidwatercontent'
refers to the amount of water in a given volume of air, with units of kg/m^3. 'rainfallrate'
is the rate of rainfall in units of mm/hr, which translates to litres per cubic meter per hour.
Only one of 'liquidatercontent'
and 'rainfallrate'
needs to be specified.
Units of temperature are given in degrees Celcius.
'relativehumidity'
refers to water content in the air, ranging from 0% to 100%.
'mission'
is a dictionary with the following keys:
-
'missionspeed'
— the cruise velocity of the drone, with units of m/s. -
'altitude'
— in units of meters. -
'heading'
— the heading angle of the drone, in units of ___________. -
'payload'
— the mass of any exra payload attached to the drone (e.g., camera), in units of kg.
'xlabel'
and 'ylabel'
not only specify axis labels of the plot, but also tell the simulation what to solve for ('ylabel'
) and what parameter to loop through ('xlabel'
). 'ylabel'
can be range
, endurance
, or power
. 'xlabel'
can be any variable from the following list:
"startstateofcharge",
"altitude",
"temperature",
"dropsize",
"liquidwatercontent",
"newtemperature",
"windspeed",
"winddirection",
"relativehumidity",
"payload",
"missionspeed"
'xvals'
is a list containing all the values of x the simulation will loop through and produce a single data point for.
'zlabel'
can be specified to any of the variables used for the 'xlabel'
parameter (see list above) to loop through. This will produce a curve for each of the values in 'zvals'
and plot them on the same figure. This is useful for looping through a weather effect, such as temperature or relative humidity, to see their effects on a plot of range vs payload.
'title'
is the title displayed on the top of the plot, followed by the current date. Currently, the title needs to be one word. A title of multiple words can have each word separated by an underscore en lieu of a space.
Drone AWE
is intended to predict performance parameters of rotary and fixed-wing drones based on readily-available specifications. To accomplish this, the power requirements for a given flight maneuver is calculated and used to predict battery drain behavior. Then, parameters such as range and endurance can be calculated. Comprehensive state data is collected at each step of a simulation, providing a versatile data set as output for study.
For rotary drones, power consumption is predicted in two steps. First, model parameters are calibrated based on known specifications, like maximum hover time and rotor diameter. Then, momentum theory is used to predict the power consumption.
According to rotor momentum theory, five equations govern the flight of a rotorcraft:
$T = \sqrt{W^2 + D^2}$ $tan(\alpha) = \frac{D}{W}$ $D = \frac{1}{2} \rho V_\infty^2 C_D A_{\bot}$ $v_i = \frac{T}{2 A_{rotor} N_{rotor} \rho \sqrt{V_\infty^2 cos^2(\alpha) + (V_\infty sin(\alpha) + v_i^2)}}$ $A_{\bot} = A_{front} cos(\alpha) + A_{top} sin(\alpha)$
A modified set of these equations were applied to rotary drones by Stolaroff, Samaras, O'Neill et. al. in [1]. Drone AWE
predicts the power consumption of a rotary drone by solving this system. GEKKO, a software package introduced in [2], is used to solve for:
-
$T$ - thrust per rotor -
$\alpha$ - angle of attack -
$D$ - drag -
$v_i$ - rotor induced velocity -
$A_{\bot}$ - planform area of the drone perpendicular to its velocity
given the following:
-
$W$ - effective weight -
$V_\infty$ - drone speed -
$C_D$ - drag coefficient -
$A_{rotor}$ - rotor area -
$N_{rotor}$ - number of rotors -
$\rho$ - air density -
$A_{front}$ - frontal drone area -
$A_{top}$ - drone top area
Note that the model currently assumes that the drag coefficient does not change with velocity and/or angle of attack.
The power requirement for the hover case is calculated according to another equation from [1]:
$P_{hover} = \frac{W^{3/2}}{\eta \sqrt{2N_{rotor} A_{rotor} \rho}}$
where
- $\eta = \frac{P_{hover}}{P_{hover, actual}}
where
$P_{hover, actual} = \frac{CV_{battery}}{E_{hover}}$
where
$P = \eta T(V_\infty sin(\alpha) + v_i)$
The power requirement for fixed-wing drones is found in [11] and is as follows:
where
Spanwise efficiency and the no-lift drag coefficient are assumed parameters, so this model has much room for improvement. It is also difficult to update from rain effects other than momentum, as the model is not easily manipulated by editing a lift-to-drag ratio.
Endurance is defined as the length of time a drone can remain airborne. Range is the physical distance traveled by the drone. Endurance is calculated by dividing the battery energy (capacity multiplied by voltage) by the power required:
where
where
From the ideal gas law,
In this model the increase or decrease in temperature is taken from 15 °C, and is used to calculate an associated change in air density. In turn, density directly influences power required for drones.
Humidity also has a direct impact on air density, which directly affects power requirements for drones. This model uses empirical data obtained from [3], where the effects of varying levels of humidity and temperature on air density were recorded.
Rain has many effects on the flight performance of drones; however, there is little to no information or validation experiments that test the effects of rain on rotary-wing drones. Thus, for rotary drones in this model, only the effects of downward momentum imparted by the rain to the drone is considered. It is not meant to be comprehensive and, with the aid of more empirical data, could be refined and/or altered significantly to better represent the effects of rain.
For fixed-wing drones, in addition to the momentum exchange, rain has been shown to both decrease lift and increase drag at all practical angles of attack. In this model, a slight reduction in the lift-to-drag ratio is performed, based on averages taken from plots from [4] and [5] (the lift coefficient is reduced by 6% and the drag coefficient increases by 0.01).
Force from downward momentum was calculated from the droplet size and liquid water content, as specified by the user. If a rainfall rate was instead given, the following conversion is performed taken from [4]:
where
The force from a single droplet is found by multiplying the droplet mass by the change in velocity of the droplet upon impact ('dropsize'
, the terminal velocity can be calculated as:
where
where
The result of the drop's impact is assumed to be:
The number of raindrops incident on the drone per second (
Putting all of this together, the force imparted by all incident raindrops per second on a drone is the number of incident drops multiplied by the change in momentum, the average droplet mass multiplied by the average change in velocity:
This force acts in the opposite direction of lift, which requires more power to overcome. It effectively increases the "weight" of the drone as far as power generation is concerned.
Ice accretion has many adverse effects on a drone's flight performance, including significant losses in lift and increases in drag. In addition, ice adds more weight to the system, which is especially significant for drones, whose weights are small to begin with. Icing effects can even lead to premature stall conditions. Despite these dangerous risks, icing is also very difficult to predict without using computational fluid dynamics (CFD), which is outside the current scope of this project.
In this model, we do not attempt to predict the effects of icing; however, at certain conditions we do issue a warning to the user that icing could occur at those operating conditions, specifically when temperature is low and humidity is high. We encourage users to refer to the icing sections in our literature reviews of weather effects on drone flight performance for more information.
Properties and their respective units are converted within the simulation to SI units, and then converted back. Those units are:
- Capacity: milliamp-hours [mAh]
- Voltage: volts [V]
- Current: amperes [A]
- Resistance: ohms [Ω]
-
Velocity/Speed: meters per second [m/s]
-
Power: watts [W]
-
Endurance or Flight time: minutes [min]
-
Altitude: meters [m]
-
mass: kilograms [kg]
- note that "takeoff weight" is measured in mass units
-
Temperature: degrees Celcius [°C]
-
Wind Resistance: meters per second [m/s]
*refers to the maximum wind speed rating for the drone
-
Battery re-charge time: minutes [min]
getparams
reads in a .txt or .csv file and outputs a dictionary with keys from a specified list and values from the specified parameter file.getXandY()
reads in data from a validation case and saves the contents to lists for x and y. This function assumes the first row contains labels and ignores them.interpolate()
does a simple linear interpolation with inputs of 2 x-values, 2 y-values, and the x-value of the interpolated value.
- test_power.py
- test_drone.py
- test_plotter.py
This section is to be used to record ideas for future development that cannot be immediately implemented due to time constraints.
- calculate propulsive efficiency at max range and max endurance and interpolate between the two
- go weather by weather and determine the appropriate model to be used
- validate the fixed-wing power model
- implement a more comprehensive model for power that could include lifting line theory
- Re-visit after having recorded wind tunnel data
This section contains a detailed description of each class, all contained in Classes.py.
-
the
Drone
class-
class variables contain:
-
data sheet specifications of specific drone models (e.g., the Mavic 2 Pro), including
- battery size
- battery type
- range under specified conditions
- fixed wing or rotary wing
- etc.
-
-
methods calculate certain characteristics based on available information
-
-
the
Battery
class-
class variables describe:
-
properties of specific batteries used to model their discharge characteristics, including
- battery type
- number of cells
- low, nominal, and charged cell voltages
-
Real-time discharge characteristics for simulation, including
- instantaneous voltage
- instantaneous current
- instantaneous state of charge
- current state of health
-
-
methods are used to update class variables using information from the
params/
directory
-
-
the
Power
class-
class variables describe
- baseline power consumption
- an array of 'correction' objects used to modify the power consumption class variable due to weather or other effects (these could be the weather effect classes, actually)
- total power consumption
-
methods are used to
- update the total power consumption class variable
- append
PowerCorrection
objects toPower
objects using theaddCorrection
method - throw an error if
addCorrection
attempts to append a time-variantPowerCorrection
object to a time-invariantPower
object - the
PowerCorrection
method- adjustments to the baseline power requirements of the drone
- whether the simulation is time-variant or time-invariant
- methods perform miscellaneous book-keeping functions
-
-
the
Weather
class-
class variables describe
- an instance of each weather effect to be modeled
- droplet size (rain)
- Liquid Water Content (LWC) (rain)
- rainfall rate (rain)
-
the
__updateRain
method- For all drone types, this calculates the momentum imparted to the drone from falling rain droplets based on their size and liquid water content.
-
the
__getWebernumber
method- Calculates weber number based on rain density, velocity, diameter, and frequency. This is used to obtain momentum in the __updateRain method.
-
the
updateLD
method- Refers to a pre-determined value for loss in lift and increase in drag based on validation data as noted in the theory section. Only for fixed-wing drones.
-
the
__getSurfaceTension
method- empirically interpolates surfaces tension based on current temperature
-
the
updateDensityTemperature
method -
the
updateDensityHumidity
class -
the
Wind
class -
class variables describe
* wind speed * wind direction * amount of turbulence? * variation in speed and/or direction?
-
the
Gust
class-
class variables describe
- frequency
- amplitude
-
-
the
Ice
class- Because of modeling difficulty, this class does not attempt yet to model icing effects. It may in the future be used to identify if icing conditions are present.
-
-
the
Mission
class-
class variables describe
- mission speed
-
-
the
Simulation
class- class variables describe
- start time
- end time
- timestep
- current timestep index
- current time
- methods are used to run and store simulation information, including procedures to get range and endurance
- class variables describe
NOTE: the model is based on power consumption to accomodate future development. The Power
class is designed to receive an indefinite number of modifications based on weather effects
-
the
Plotter
class- plots results according to labels and titles specified by the user in the
settings.txt
file. Methods can plot a line or scatter plots. The validation method plots results on top of specified validation data.
- plots results according to labels and titles specified by the user in the
- Beal, L.D.R., Hill, D., Martin, R.A., and Hedengren, J. D., GEKKO Optimization Suite, Processes, Volume 6, Number 8, 2018, doi: 10.3390/pr6080106.
- Stolaroff, J. K., Samaras, C., O’Neill, E. R., Lubers, A., Mitchell, A. S., & Ceperley, D. (2018). Energy use and life cycle greenhouse gas emissions of drones for commercial package delivery. Nature Communications, 9(1), 1–13. https://doi.org/10.1038/s41467-017-02411-5
- Yue, W., Xue, Y., & Liu, Y. (2017). High Humidity Aerodynamic Effects Study on Offshore Wind Turbine Airfoil/Blade Performance through CFD Analysis. International Journal of Rotating Machinery, 2017, 1–15. https://doi.org/10.1155/2017/7570519
- Cao, Y., Wu, Z., & Xu, Z. (2014). Effects of rainfall on aircraft aerodynamics. Progress in Aerospace Sciences, 71, 85–127. https://doi.org/10.1016/j.paerosci.2014.07.003
- Ismail, M., Yihua, C., Wu, Z., & Sohail, M. A. (2014). Numerical Study of Aerodynamic Efficiency of a Wing in Simulated Rain Environment. Journal of Aircraft, 51(6), 2015–2023. https://doi.org/10.2514/1.c032594
- Abdilla, A., Richards, A., & Burrow, S. (2015). Power and endurance modelling of battery-powered rotorcraft. In 2015 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS) (pp. 675–680). IEEE. https://doi.org/10.1109/IROS.2015.7353445
- Chang, K., Rammos, P., Wilkerson, S. A., Bundy, M., & Gadsden, S. A. (2016). LiPo battery energy studies for improved flight performance of unmanned aerial systems. In R. E. Karlsen, D. W. Gage, C. M. Shoemaker, & G. R. Gerhart (Eds.) (Vol. 9837, p. 98370W). International Society for Optics and Photonics. https://doi.org/10.1117/12.2223352
- Di Franco, C., & Buttazzo, G. (2016). Coverage Path Planning for UAVs Photogrammetry with Energy and Resolution Constraints. Journal of Intelligent and Robotic Systems: Theory and Applications, 83(3–4), 445–462. https://doi.org/10.1007/s10846-016-0348-x
- Dorling, K., Heinrichs, J., Messier, G. G., & Magierowski, S. (2017). Vehicle Routing Problems for Drone Delivery. IEEE Transactions on Systems, Man, and Cybernetics: Systems, 47(1), 70–85. https://doi.org/10.1109/TSMC.2016.2582745
- Ostler, J. N., Bowman, W. J., Snyder, D. O., & Mclain, T. W. (2009). Performance Flight Testing of Small, Electric Powered Unmanned Aerial Vehicles (Vol. 1). Retrieved from https://journals.sagepub.com/doi/pdf/10.1260/175682909789996177
- Traub, L. W. (2011). Range and Endurance Estimates for Battery-Powered Aircraft. Journal of Aircraft, 48(2), 703–707. https://doi.org/10.2514/1.c031027