Skip to main content

Unmanned Aerial Vehicle Design EXploration - A Python package for multidisciplinary analysis and optimization of electric group 1-2 UAVs.

Project description

UAV DEsign eXploration

Sammy N. Nassau, RPI DBF 2021-2026

IN PROGRESS: April 2026 is the target for public release

UAVDEX Repo

UAVDEX enables rapid determination of electric aircraft propulsion quantities (i.e. thrust or efficiency) across the entire flight envelope. It is intended primarily for students competing in design competitions such as AIAA Design/Build/Fly or SAE Aero.

The tools to thoughtfully design aircraft should be accessible to all.

Example analyses using UAVDEX

Installation

Anaconda is recommended. In anaconda prompt with a desired environment (not base) activated, simply run:

pip install uavdex

PointDesign

This object allows for calculation of electric aircraft propulsion with specified components across the entire flight envelope.

Key inputs that define a single flight condition:

  • Uinf: freestream velocity over the propeller
  • h: altitude
    • OR rho: density
  • dT: throttle setting (0-100%)
  • SOC: battery state of charge (0-100%)
    • OR Voc: cell voltage (~3.5-4.15 for LiPo)
    • OR t: runtime

Runtime assumes constant current. This is valid when designing an aircraft that spends most of its flight time in a single condition (i.e. cruise).

Component initialization

import uavdex as ud

design = ud.PointDesign() 			                    # initialize PointDesign object
design.Motor('C-4130/20', nmot = 2)                     # add a motor, and specify the # of motors (nmot = 1 by default)
design.Battery('Gaoneng_8S_3300', discharge = 85)     # add a battery, and specify the maximum discharge (default is 80%)
design.Prop('16x10E')                                   # add a propeller

To view and edit the databases use

design.OpenMotorData()      # opens an editable csv
design.OpenBatteryData()    # opens an editable csv
design.OpenPropellerData()  # opens a folder containing .dat files from https://www.apcprop.com/technical-information/performance-data/?v=7516fd43adaa

Alternatively, for a list of options printed to the console:

design.MotorOptions()
design.BatteryOptions()
design.PropellerOptions()

All values required are typically provided by the manufacturer, meaning users can add whatever components they desire.

PointResult

A simple function to get propulsion quantities (called 'propQ' in the code) at a specified flight condition.

PointResult example

import uavdex as ud

# Component Initialization
design = ud.PointDesign() 			   # initialize PointDesign object
design.Motor('C-4130/20', nmot = 2)    # add a motor, and specify the # of motors
design.Battery('Gaoneng_8S_3300')      # add a battery 
design.Prop('16x10E')                  # add a propeller

# PointResult
# Uinf_mps:	velocity in m/s   (alternatively use Uinf_fps, Uinf_mph, Uinf_kmh, Uinf_kt)
# dT: 	throttle (0-100%)
# h_m: 	altitude in m         (alternatively use h_ft, rho_kgm3, rho_slugft3, rho_lbft3)
# t_s: 	runtime in s          (alternatively use t_m, t_hr, SOC, Voc)
propQs = design.PointResult(Uinf_mps = 15, dT = 70, h_m = 50, t_s = 30, 
                            verbose = True) # this returns propQs as an array and also prints to console. To stop printing, set verbose = False.

which prints the following to the console:

At Uinf = 15.00 m/s, Throttle = 70%, Density = 1.219 kg/m³, Runtime = 30.0 s
Total Thrust (N)               = 49.204
Total Thrust (lbf)             = 11.062
Total Thrust (g)               = 5017.426
Total Thrust (oz)              = 176.984
Total Torque (N-m)             = 1.746
Total Torque (lbf-ft)          = 1.288
RPM                            = 6202.703
Drive Efficiency               = 38.587
Propeller Efficiency           = 65.074
Gearing Efficiency             = 100.000
Motor Efficiency               = 91.527
ESC Efficiency                 = 65.100
Battery Efficiency             = 99.519
Mech. Power Out of 1 Motor (W) = 567.097
Elec. Power Into 1 Motor (W)   = 619.593
Elec. Power Into 1 ESC (W)     = 951.756
Waste Power in 1 Motor (W)     = 52.497
Waste Power in 1 ESC (W)       = 332.163
Waste Power in 1 Battery (W)   = 9.193
Current in 1 Motor (A)         = 28.198
Current in 1 ESC (A)           = 30.321
Current in Battery (A)         = 60.641
Voltage in 1 Motor (V)         = 21.973
Voltage in 1 ESC (V)           = 31.390
Battery Voltage (V)            = 31.390
Voltage Per Cell (V)           = 3.943
State of Charge                = 84.687

propQs is an array containing the following propulsion quantities,

Index Symbol Description Units
0 T_N Total Thrust N
1 T_lbf Total Thrust lbf
2 T_g Total Thrust g
3 T_oz Total Thrust oz
4 Q_Nm Total Torque N·m
5 Q_lbfft Total Torque lbf·ft
6 RPM Propeller Speed RPM
7 eta_drive Drive Efficiency %
8 eta_p Propeller Efficiency %
9 eta_g Gearing Efficiency %
10 eta_m Motor Efficiency %
11 eta_c ESC Efficiency %
12 eta_b Battery Efficiency %
13 Pout Mechanical Power Out of 1 Motor W
14 Pin_m Electrical Power Into 1 Motor W
15 Pin_c Electrical Power Into 1 ESC W
16 Pw_m Waste Power in 1 Motor W
17 Pw_c Waste Power in 1 ESC W
18 Pw_b Waste Power in 1 Battery W
19 Im Current in 1 Motor A
20 Ic Current in 1 ESC A
21 Ib Current in Battery A
22 Vm Voltage in 1 Motor V
23 Vc Voltage in 1 ESC V
24 Vb Battery Voltage V
25 Voc Voltage Per Cell V
26 SOC State of Charge %

LinePlot

To plot a sweep of any one of the 4 inputs (Uinf, dT, h/rho, Voc/SOC/t) with the others fixed, use a LinePlot. The output variable plotted on the y-axis will be a selected propQ from the list above.

To select a propQ output, input a single variable or a list of variables as shown below

propQ = 'T_lbf'                       # for a single plot
# OR
propQ = ['T_lbf', 'eta_drive', 'Ib']  # to create multiple plots of propQs for the same sweep

LinePlot example

import uavdex as ud
import numpy as np

# Component Initialization
design = ud.PointDesign() 				# initialize PointDesign object
design.Motor('C-4130/20', nmot = 2)		# add a motor, and specify the # of motors
design.Battery('Gaoneng_8S_3300') 		# add a battery 
design.Prop('16x10E') 					# add a propeller

# LinePlot usage
design.LinePlot(propQ = ['T_lbf','eta_drive','Ib'], Uinf_mps = np.linspace(0, 50), dT = 100, h_m = 100, t_s = 30)
~5s runtime, n = 200 --> ~15s runtime)

n = 120

ContourPlot (sweeps of velocity and runtime)

design.ContourPlot(propQ = ['T_lbf', 'eta_drive', 'Ib'], Uinf_mps = np.linspace(0, 45, n), t_s = np.linspace(0, 300, n), dT = 100, h_m = 100)

<!-- the following is incredibly cooked, but it gets the plots to be large and pretty -->
<!--TODO update plots!!!!!>
<table>
  <tr>
    <td align="center" valign="top">
      Thrust for Uinf vs t<br>
      <img src="./Examples/ContourPlot_V_t_T.png" width="600"><br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      Propulsion Efficiency for Uinf vs t<br>
      <img src="./Examples/ContourPlot_V_t_eta.png" width="600"><br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
    <td align="center" valign="top">
      Battery Current for Uinf vs t<br>
      <img src="./Examples/ContourPlot_V_t_Ib.png" width="600"><br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
</table>
At some constant velocity, the right side bound of the contour plot indicates the runtime of the propulsion system in seconds. This is determined by where SOC = (1 - discharge). Additional bounds can originate when the propulsion system cannot generate thrust at some combination of Uinf, dT, Voc, and h. 
                                          
### Additional ContourPlot examples
<!--TODO update plots!!!!!>
<table>
	<tr>
		<td width="33%" valign="top">
			<p align="center">
				<a>Efficiency for velocity vs throttle
          <pre>design.ContourPlot(propQ = 'eta_drive',
                  Uinf_mps = np.linspace(0, 45, 200), 
                  dT = np.linspace(20, 100, 200), 
                  h_m = 50, 
                  t_s = 20)</pre>
        </a>
			</p>
			<img src="./Examples/ContourPlot_V_dT_eta.png">
		</td>
		<td width="33%" valign="top">
			<p align="center">
				<a>Efficiency for velocity vs cell voltage
          <pre>design.ContourPlot(propQ = 'eta_drive',
                  Uinf_mps = np.linspace(0, 45, 200), 
                  dT = 100,
                  h_m = 50, 
                  Voc = np.linspace(3.5, 4.2, 200))</pre>
        </a>
			</p>
      <img src="./Examples/ContourPlot_V_Voc_eta.png">
		</td>
		<td width="33%" valign="top">
			<p align="center">
				<a>Efficiency for cell voltage vs throttle
           <pre>design.ContourPlot(propQ = 'eta_drive',
                  Uinf_mps = 30.0,
                  dT = np.linspace(20, 100, 200),
                  h_m = 50, 
                  Voc = np.linspace(3.5, 4.2, 200))</pre>
        </a>
			</p>
			<img src="./Examples/ContourPlot_Voc_dT_eta.png">
		</td>
	</tr>
</table>
The bounds on these plots occur when the throttle setting and battery voltage are low, meaning the propulsion drive cannot produce thrust at the given velocity. Therefore, efficiency goes to zero.


## Future updates
1. Automatic boundary selection (no input array needed, just specify which variable is the sweep)
2. Battery resistance near low SOC modeled
3. Manual limit lines based on component values (i.e. ESC waste power < 500 W)
4. Expansion of database features
5. Functions for the best Uinf, dT, h for maximum efficiency

Have any requests? Submit a ticket on the google form below or open a github issue thread.
#### TODO: GOOGLE FORM

Want a propulsion component added to the default package CSV sheets? Request here:
#### TODO: GOOGLE FORM

<!--
### Primary Objects:

#### PointDesign
PointDesign is the primary method for electric


#### DesignStudy
#### ClassicalSizing

# Propulsion Models 
--> 

[1]: https://rincon-mora.gatech.edu/publicat/jrnls/tec05_batt_mdl.pdf
[2]: https://www.researchgate.net/profile/Andrew-Gong-2/publication/326263042_Performance_Testing_and_Modeling_of_a_Brushless_DC_Motor_Electronic_Speed_Controller_and_Propeller_for_a_Small_UAV_Application/links/5b52a5c545851507a7b6f581/Performance-Testing-and-Modeling-of-a-Brushless-DC-Motor-Electronic-Speed-Controller-and-Propeller-for-a-Small-UAV-Application.pdf
[3]: https://web.mit.edu/drela/Public/web/qprop/motor1_theory.pdf
[4]: https://www.mdpi.com/2226-4310/11/1/16



Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uavdex-0.1.9.tar.gz (14.5 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uavdex-0.1.9-py3-none-any.whl (14.4 MB view details)

Uploaded Python 3

File details

Details for the file uavdex-0.1.9.tar.gz.

File metadata

  • Download URL: uavdex-0.1.9.tar.gz
  • Upload date:
  • Size: 14.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for uavdex-0.1.9.tar.gz
Algorithm Hash digest
SHA256 8a0962f26512b080c96bab3a38da6a28bcafed7ea95fb1b9f4eef3a3d9ae8fa9
MD5 b91d2bb67e42d143847e973a84f55a4b
BLAKE2b-256 6671ed0e4bfe4f84ce5e176c1de3b8a415ad608a36fe929ded1120c86ca91b84

See more details on using hashes here.

File details

Details for the file uavdex-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: uavdex-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 14.4 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for uavdex-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 7f2d63bb029b36460c7155daf1fdeaec5a17365d5618adc224a4f4181f8351e7
MD5 125802ccca9ccaa29421ce2a42e85ac4
BLAKE2b-256 83f1862aad0a3d8b4936c18255c1efe04cca649a194e5671de38812b7ca03534

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page