Estimation models with scaling laws#
Written by Marc Budinger (INSA Toulouse), Scott Delbecq (ISAE-SUPAERO) and Félix Pollet (ISAE-SUPAERO), Toulouse, France.
Electrical components#
The application chosen for this notebook are UAV electrical components. The estimation models calculate the component characteristics requested for their selection without requiring a detailed design. Scaling laws are particularly suitable for this purpose. This notebook illustrates the approach with electrical drone components characteristics. Validation of the obtained scaling laws is realized thanks catalog data.
The following article gives more details for components of electromechanical actuators:
Budinger, M., Liscouët, J., Hospital, F., & Maré, J. C. (2012). Estimation models for the preliminary design of electromechanical actuators. Proceedings of the Institution of Mechanical Engineers, Part G: Journal of Aerospace Engineering, 226(3), 243-259.
Notation: The x* scaling ratio of a given parameter is calculated as \(x^*=\frac{x}{x_{ref}}\) where \(x_{ref}\) is the parameter taken as the reference and \(x\) the parameter under study.
Lipo battery#
A lithium-ion polymer battery (abbreviated as LiPo) is a assembly of elementary cells. The more the cells are provided, the bigger is the power and stored energy. The following figure gives an example of a Lipo battery with the following characteristics:
Voltage / Cell Count (“S”): A LiPo cell has a nominal voltage of 3.7V (3V min, 4.2V max) . For the 7.4V battery above, this means that there are two cells in series (which means the voltage gets added together). This is sometimes why you will hear people talk about a “2S” battery pack - it means that there are 2 cells in Series.
Capacity (“C”): The capacity of a battery is basically a measure of the energy the battery can hold. The unit of measure here is milliamp hours (mAh). This is saying how much drain can be put on the battery to discharge it in one hour. The stored energy is given by the the product of voltage and thus here: Capacity (in Amps)36007.4= 0.133 MJ
Discharge Rating (“C” Rating): The C Rating is simply a measure of how fast the battery can be discharged safely and without harming the battery. The maximum safe continuous amp draw is here: 50C = 50 x Capacity (in Amps) = 250 A.
Propose a scaling law which links battery characteristics, as mass or max discharge current, to capacity \(C_{bat}\) and voltage \(U_{bat}\). Estimate the mass and max discharge current for a 3300 mAh - 4S battery knowing the following reference component:
Characteristic |
Value |
---|---|
Capacity |
5000mAh |
Continuous discharge rate |
50C |
Burst rate |
100C |
Voltage |
7.4V |
Cells |
2S |
Size (LxWxH) |
155x48x16mm |
Weight |
273g |
Solution to
\(I_{max,bat}^*=C_{bat}^*\)
\(M_{bat}^*=U_{bat}^*C_{bat}^*\)
# Reference battery 5000mAh 2S 50C
C_bat_ref = 5 # [Ah] Capacity
I_bat_max_ref = 50 * C_bat_ref # [A] max discharge current
U_bat_ref = 7.4 # [V] nominal voltage
M_bat_ref = 0.273 # [kg] mass
# New battery 3300 mA.h 4S
U_bat = 4 * 7.4 / 2
C_bat = 3300 / 1000
I_bat_max = I_bat_max_ref * (C_bat / C_bat_ref)
M_bat = M_bat_ref * (C_bat / C_bat_ref) * (U_bat / U_bat_ref)
print(f"Battery mass: {M_bat:.3f} kg")
print(f"Max discharge current: {I_bat_max:.0f} A")
Battery mass: 0.360 kg
Max discharge current: 165 A
Brushless motor#
Multi-rotor drones use out runner brushless motors which are permanent magnet synchronous motors. The following article explains how set up the scaling laws for this technology of component.
Scaling laws#
The following table summarize the scaling laws which can be used for the brushless motors.
Scaling laws |
References |
|
---|---|---|
AXI 2217/20 |
||
Nominal torque |
\(T_{nom}^*\) |
\(0.151\) N.m |
Torque constant |
\(K_T^*\) |
\(1.14.10^{-2}\) N.m/A |
Max torque |
\(T_{max}^*=T_{nom}^*\) |
\(0.198\) N.m |
Friction torque |
\(T_{fr}^*=T_{nom}^{*3/3.5}\) |
\(6.25.10^{-3}\) N.m |
Mass |
\(M^*=T_{nom}^{*3/3.5}\) |
\(69.5\) g |
Resistance |
\(R^*=K^{*2}T_{nom}^{*-5/3.5}\) |
\(0.185\) ohm |
Inertia |
\(J^*=T_{nom}^{*-5/3.5}\) |
\(2.5.10^{-5}\) kg.m² |
# Motor reference data: AXI 2217/20 GOLD LINE
T_mot_ref = 0.15 # [N.m] motor nominal torque
M_mot_ref = 69.5e-3 # [kg] motor mass
R_mot_ref = 0.185 # [Ohm] motor resistance
K_T_ref = 1.14e-2 # [N.m/A] Torque or fem constant
Validation with a data plot#
We will compare the scaling law with a plot on catalog data.
Import data#
The first step is to import catalog data stored in a excel file. We use for that functions from Panda package (with here an introduction to panda).
# Panda package Importation
import pandas as pd
# Read the .csv file with bearing data
path = "https://raw.githubusercontent.com/SizingLab/sizing_course/main/laboratories/Lab-multirotor/assets/data/"
df = pd.read_excel(path + "AXI_mot_db_student.xlsx", engine="openpyxl")
# Print the head (first lines of the file)
df.head()
Name | Kv (rpm/v) | Pole (number) | Io (A) | r (omn) | weight (g) | Imax (A) | No s | Voltage | Inom_max (A) | Eta_max (%) | Kt (N.m/A) | Tnom (N.m) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | AXI 2203/40VPP GOLD LINE | 2000 | 14 | 0.50 | 0.245 | 17.5 | 9.0 | 2 | 7.4 | 7.5 | 75 | 0.004775 | 0.033423 |
1 | AXI 2203/46 GOLD LINE | 1720 | 14 | 0.50 | 0.285 | 18.5 | 8.5 | 2 | 7.4 | 7.0 | 75 | 0.005552 | 0.036087 |
2 | AXI 2203/52 GOLD LINE | 1525 | 14 | 0.40 | 0.390 | 18.5 | 7.0 | 2 | 7.4 | 5.5 | 74 | 0.006262 | 0.031935 |
3 | AXI 2203/RACE GOLD LINE | 2300 | 14 | 0.55 | 0.220 | 18.5 | 9.0 | 3 | 11.1 | 7.5 | 74 | 0.004152 | 0.028855 |
4 | AXI 2204/54 GOLD LINE | 1400 | 14 | 0.35 | 0.320 | 25.9 | 7.5 | 3 | 11.1 | 6.0 | 77 | 0.006821 | 0.038538 |
Plot data: Mass#
import numpy as np
import matplotlib.pyplot as plt
T_mot = np.logspace(np.log10(0.01), np.log10(5), num=50)
# Scaling law
M_mot = M_mot_ref * (T_mot / T_mot_ref) ** (3 / 3.5)
# plot
h, ax = plt.subplots(1, 1, sharex=True)
ax.plot(df["Tnom (N.m)"], df["weight (g)"], ".b")
ax.plot(
T_mot,
M_mot * 1000,
"--r",
df["Tnom (N.m)"],
df["weight (g)"],
".b",
T_mot_ref,
M_mot_ref * 1000,
".g",
)
ax.set_ylabel("Motor Mass [g]")
ax.set_xlabel("Nominal torque [N.m]")
ax.grid()
Plot data: Resistance#
We want now to compare graphically the catalog data with scaling law calculations for the resistance value:
blue points, catalog data
red point, the estimated data
Exercice: Implement the corresponding python code.
# Resistance plot
# Scaling law
T_mot = df["Tnom (N.m)"].values
K_T = df["Kt (N.m/A)"].values
R_mot_data = df["r (omn)"].values
# ...
R_mot_sl = R_mot_ref * (K_T / K_T_ref) ** 2 * (T_mot / T_mot_ref) ** (-5 / 3.5)
# plot
h, ax = plt.subplots(1, 1, sharex=True)
ax.loglog(T_mot, R_mot_data / K_T**2, ".b", T_mot, R_mot_sl / K_T**2, ".r")
ax.set_ylabel("Resistance/Torque constant^2 [Ohm/(N.m/A)²]")
ax.set_xlabel("Nominal torque [N.m]")
ax.grid()
Power electronic converter#
ESC (electronic speed controllers) motor controllers are mainly DC/AC converter (inverter) composed of power electronic switchs (Mosfet transistors). We will use here a simple linear regression in order to set up a model for mass estimation.
The first step is to import catalog data stored in a .csv file. We use for that functions from Panda package (with here an introduction to panda).
The data base gives informations about mass, voltage & current (DC side) and power of the converter.
# Panda package Importation
import pandas as pd
# Read the .csv file with bearing data
path = "https://raw.githubusercontent.com/SizingLab/sizing_course/main/laboratories/Lab-multirotor/assets/data/"
df = pd.read_csv(path + "ESC_data.csv", sep=";")
# Print the head (first lines of the file) of the following columns
df.head()
Model | Imax.in[A] | m[g] | Vmax.in[V] | Pmax.in[W] | |
---|---|---|---|---|---|
0 | Jive 80+ LV | 80 | 84.0 | 22.2 | 1776 |
1 | Jive 100+ LV | 100 | 92.0 | 22.2 | 2220 |
2 | FAI Jive 150+ LV | 150 | 140.0 | 18.5 | 2775 |
3 | Jive 60+ HV | 60 | 84.0 | 44.4 | 2664 |
4 | Jive 80+ HV | 80 | 84.0 | 44.4 | 3552 |
Here we recover the information of power, mass and voltage and we render them on a scatter plot.
# Get values from panda data
x = df["Pmax.in[W]"].values
y = df["m[g]"].values
v = df["Vmax.in[V]"].values
# plot the data : scatter plot
plt.scatter(x, y, c=v, cmap="viridis")
cbar = plt.colorbar()
# show color scale
plt.xlabel("ESC Power [W]")
plt.ylabel("ESC Mass [g]")
cbar.set_label("Voltage [V]")
plt.title("Mass vs Power for ESC (Voltage in color)")
plt.grid()
plt.show()
The voltage increases with the power in order to maintain reasonable current values.
# plot the data : Voltage vs Power
plt.plot(x, v, "o")
plt.xlabel("ESC Power [W]")
plt.ylabel("ESC Voltage [V]")
plt.grid()
plt.show()
# Determination of the least squares estimator with the OLS function
from sklearn import linear_model
from sklearn.metrics import r2_score
# Matrix X and Y
# X=np.transpose(np.array((np.ones(np.size(x)), x)))
X = x.reshape(-1, 1)
Y = y.reshape(-1, 1)
reg = linear_model.LinearRegression(fit_intercept=False)
reg.fit(X, Y)
y_est = reg.predict(X)
coef = float(reg.coef_)
intercept = float(reg.intercept_)
r2 = r2_score(Y, y_est)
# plot the data
plt.plot(x, y, "o", x, y_est, "-g")
plt.xlabel("ESC Power [W]")
plt.ylabel("ESC Mass [g]")
plt.title("Comparison of original data (circles) and regression (green)")
plt.grid()
plt.show()
print(
f"Mass / Power coefficient : {coef:.2e} [g/W] or {coef/1000:.2e} [kg/W] with R2={r2:.3f}"
)
/tmp/ipykernel_2259/1007377888.py:18: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.)
coef = float(reg.coef_)
Mass / Power coefficient : 2.88e-02 [g/W] or 2.88e-05 [kg/W] with R2=0.738
Explain how the following code gives a power law which can represent the evolution of voltage with power. Complete the code with a print of the relationship.
# Matrix X and Y
# ...
# plot the data
plt.plot(x, v, "o", x, yV_est, "og")
plt.xlabel("ESC Power [W]")
plt.ylabel("ESC Voltage [V]")
plt.title("Comparison of original data (blue circles) and regression (green circles)")
plt.grid()
plt.show()
# Final part to be completed
print(f"Voltage estimation : V_esc= with R2={r2:.3f}")
print("with Power P_esc [W] and Voltage V_esc [V] of ESC controller")
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[10], line 6
1 # Matrix X and Y
2
3 # ...
4
5 # plot the data
----> 6 plt.plot(x, v, "o", x, yV_est, "og")
7 plt.xlabel("ESC Power [W]")
8 plt.ylabel("ESC Voltage [V]")
NameError: name 'yV_est' is not defined
Note
Note on the mass evolution of ESC
The conduction losses occurring in a MOS switch are given by the following expression:
\(P_{loss,MOS}=R_{ds,on}.I^2\)
In case of a MOS, the resistance \(R_{ds,on}\) which defines the conduction losses decreases inversely proportionally to the current calibration. We have thus with the scaling law notation:
\(P_{loss,MOS}^*=I^*\)
Which gives if the voltage is approximated by \(V^*\approx P*^{1/3}\):
\(P_{loss,MOS}^* \approx P^{*2/3}\)
with \(P\) the converter power.
The heat exchange of the converter shall ensure a constant temperature for the entire power range of a given line of converters. It is assumed that the dissipation is fixed here by forced convection (due to propeller air flow) which can be expressed finally with converter dimension \(d^*\) by:
\(P_{conv}^* = h^* S^* \Delta \theta^*= d^{*2} \)
and as \(P_{conv}^*=P_{loss,MOS}^*\), we have \(d^*=P^{*1/3}\) and thus a mass evolution express by the following linear trend can be deduced:
\(M^*=d^{*3}=P^*\)