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.

https://raw.githubusercontent.com/SizingLab/sizing_course/main/laboratories/Lab-multirotor/assets/images/LipoBattery.jpeg

Fig. 7 LiPo Battery#

Exercise 9

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

# 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.

https://raw.githubusercontent.com/SizingLab/sizing_course/main/laboratories/Lab-multirotor/assets/images/BrushlessMotor.jpg

Fig. 8 Brushless motor#

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()
../../_images/4b493d072a5d2884a4f81e4e8a444987ff49f3199fd1d3364801976620d61e68.png

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()
../../_images/fa1236411515f2ccca80f426cba744dc82114f10b49c9bf22cc402b9694bcc1f.png

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.

https://raw.githubusercontent.com/SizingLab/sizing_course/main/laboratories/Lab-multirotor/assets/images//ESC.jpeg

Fig. 9 Electronic Speed Controller (ESC)#

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()
../../_images/19844fc44d80147e759ffda8d6e20e004a2ffed6d5cbdf5433d299bd5be8ff8b.png

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()
../../_images/c002302030a9f9d98c7099f1db65a75059401797c03227a107d02698704fd96f.png
# 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_)
../../_images/9bb5fa92ef55d460146298a7d5b5af551006a63ec002130926edf7bb67d50e72.png
Mass / Power coefficient : 2.88e-02 [g/W] or 2.88e-05 [kg/W] with R2=0.738

Exercise 10

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^*\)