基于测量的 SDPM 参数化
本例展示了如何根据实验测量结果对永磁同步电机 (PMSM) 进行参数化。
为了确定永磁同步电机的参数,我们将进行三次实验。我们事先已知所需的电机参数,并将其与实验所得值进行比较。
电机文件中的数据:
nPolespairs = 2; # Количество пар полюсов
iRated = 2.5; # Ток при номинальной скорости и нагрузке (А)
rpmRated = 7500; # Номинальная скорость (об/мин)
torqueRated = 0.07; # Крутящий момент при номинальной скорости (Н·м)
torqueStall = 0.28; # Заданный крутящий момент (Н·м)
iStall = 8.5; # Пиковый ток (А)
inertia = 5e-6; # Момент инерции (кг·м2)
viscousDamping = 1.13e-6; # Коэффициент вязкого трения
staticFriction = 7e-4; # Коэффициент сухого трения
coulombFriction = 0.8*staticFriction; # Коэффициент кулоновского трения
R = 3.43; # Сопротивление (Ом)
L = 0.53e-3; # Индуктивность (Гн)
# Параметры блока PMSM (СДПМ)
torqueConstant = 2/3*torqueStall/iStall; # Постоянная момента (Нм/А)
emfConstant = torqueConstant; # Постоянная противо-ЭДС (В∙с/рад)
PM = torqueConstant/nPolespairs; # Потокосцепление постоянного магнита (Вб)
# Параметры и флаги контроллера
rpmDemand = rpmRated; # Заданная скорость (об/мин)
enableDrive = 1; # Включение управления
dt = 1e-4; # Период дискретизации контроллера (с)
测试 1:转子静止时 R 和 L 的测定
第一个试验在转子锁定的电机上进行。在两相间施加一个阶跃电压,研究瞬态响应。由此产生的时间常数 τ 由定子电阻和电感值决定:

设置转子的初始旋转角度:
rotorangle = -90/(nPolespairs);
运行模型:
if "PMSMFromMeasurement1" in [m.name for m in engee.get_all_models()]
m = engee.open( "PMSMFromMeasurement1" ) # загрузка модели
else
m = engee.load( "PMSMFromMeasurement1.engee" )
end
results1 = engee.run(m, verbose=true)
从模型中读取数据
t = results1["uab"].time; # Время
uab_1 = results1["uab"].value; # Напряжение между фазами a и b
ia = results1["ia"].value; # Ток на фазе a
根据数值、稳态电压和电流计算电阻。
实验中的绕组 a 和 b 是串联连接的,因此我们将得出的电阻除以 2:
R_e = uab_1[end] / ia[end] / 2;
让我们来计算电路的时间常数,即电流达到稳态电流值 的时间:
idx = findfirst(x -> x >= (0.63 * ia[end]), ia);
tau = t[idx];
根据公式 表达并计算电感 L:
L_e = R_e * tau;
预期瞬态:
iEstimated = uab_1[end] / (2 * R_e) * (1 .- exp.(-t .* R_e ./ L_e));
在下图中,您可以比较模型测得的电流和计算得出的电流图。
using Plots
plotlyjs();
plot(t, ia, xlabel="Время, c", ylabel="Ток, А", w = 2, label="Измеренный ток", linecolor =:blue)
plot!(t, iEstimated, xlabel="Время, c", ylabel="Ток, А", w = 2, label="Ожидаемый ток", linecolor =:green)
plot!([tau, tau], [0, ia[end]], linecolor =:red, line =:dashdot, label="τ" )
xlims!(0, 10*tau) # Установка пределов оси x
ylims!(0, ia[end]) # Установка пределов оси y
annotate!(0.0008, 4.5, text(string("R эталонное = ", R, " Ом"), :left, 10))
annotate!(0.0008, 4, text(string("R измеренное = ", round(R_e, digits=2), " Ом"), :left, 10))
annotate!(0.0008, 3.5, text(string("L эталонная = ", L*1000, " мГн"), :left, 10))
annotate!(0.0008, 3, text(string("L измеренная = ", round(L_e*1000, digits=2), " мГн"), :left, 10))
annotate!(tau, 1, text(string("Измеренная постоянная времени = ", round(1000*tau, digits=3), " мc"), :left, 10))
测试 2.确定恒定反电磁场
在第二次试验中,电机在无电力负载的情况下旋转。这样就可以估算出反向电磁场常数。
请注意,以 SI 单位表示的反 EMF 常数等于电机扭矩常数,因此本例中只计算一个常数。

运行模型:
if "PMSMFromMeasurement2" in [m.name for m in engee.get_all_models()]
m = engee.open( "PMSMFromMeasurement2" ) # загрузка модели
else
m = engee.load( "PMSMFromMeasurement2.engee" )
end
results2 = engee.run(m, verbose=true)
从模型中读取数据
t = results2["uab"].time; # Время
uab_2 = results2["uab"].value; # Напряжение a-b
确定反 EMF 常数
反 EMF 常数 可用公式计算:
其中 是电机 a 相上的压降、
- 电机轴的角速度。
扭矩常数等于以 SI 单位表示的反 EMF 常数。
wRef = rpmRated*2*pi/60; # Угловая скорость ротора (рад/с)
vPeakLL = maximum(abs.(uab_2)); # Пиковое линейное напряжение (В)
vPeakLN = vPeakLL/sqrt(3); # Пиковое напряжение фаза-нейтраль (В)
emfConstantE = vPeakLN/wRef; # wq константы противо-ЭДС
下图显示了实验电机以额定转速运行时产生的反向电磁场。
可以通过计算转子每转一圈的电流变化周期数来确定极对数。
plot(t, uab_2, xlabel="Время, c", ylabel="Противо-ЭДС", label="Противо-ЭДС экспериментального двигателя", w = 2)
annotate!(0.0013, -20, text(string("Константа противо-ЭДС эталонная = ", round(emfConstant,digits=4), " В∙с/рад"), :left, 10))
annotate!(0.0013, -25, text(string("Константа противо-ЭДС измеренная = ", round(emfConstantE,digits=4), " В∙с/рад"), :left, 10))
3 摩擦系数和转动惯量的确定
在第三次实验中,控制器控制空载电机。
在之前的实验中,已经获得了扭矩常数。通过转换定子电流,可以计算出摩擦系数。

控制器建模所需的变量:
rpm2rad = 2*pi/60;
rad2rpm = 60/(2*pi);
powermax = torqueRated*rpmRated*2*pi/60;
Kp = 0.01;
Ki = 2.0;
ts = 0.0001;
t2eq_Iq = 2/(3*nPolespairs*PM);
测量在四种不同速度下保持恒速所需的机械扭矩。
低速时所需的扭矩主要用于克服干摩擦,高速时则用于克服粘性摩擦。
图中显示了四种速度下测得的扭矩。通过这些点画出一条直线。零速交叉点表示干摩擦系数,斜率表示粘摩擦系数。
function trapz(x, y)
n = length(x)
integral = 0.0
for i in 1:n-1
integral += (x[i+1] - x[i]) * (y[i+1] + y[i]) / 2
end
return integral
end
rpmVec = [0.25, 0.5, 0.75, 1.0]*rpmRated;
trqVec = zeros(size(rpmVec));
for i=1:length(rpmVec)
if "PMSMFromMeasurement3" in [m.name for m in engee.get_all_models()]
m = engee.open( "PMSMFromMeasurement3" ) # загрузка модели
else
m = engee.load( "PMSMFromMeasurement3.engee" )
end
rpmDemand = rpmVec[i];
engee.set_param!("PMSMFromMeasurement3", "StopTime" => 2*60/rpmDemand)
results3 = engee.run(m, verbose=true)
t = results3["ia"].time; # Время из модели
ia_3 = results3["ia"].value; # ток фазы-a из модели
idx = findfirst(x -> x >= (60/rpmDemand), t);
temp = trapz(t[idx:end],(ia_3[idx:end]).^2)
iaRms = sqrt(temp/(t[end]-t[idx]));
trqVec[i] = 3*torqueConstant*iaRms;
end
rpmDemand = rpmRated;
scatter(rpmVec, 1000*trqVec, title="Механические потери крутящего момента", xlabel="Скорость, м/c", ylabel="Момент, мН*м", w = 2, label="Измеренные значения", legend=:bottomright )
using Polynomials
coef = coeffs(fit(2*pi/60*rpmVec, trqVec,1));
estimatedStaticFriction = coef[1];
estimatedViscousDamping = coef[2];
rpmVec0 = [0; rpmVec];
plot!(rpmVec0, 1000*(estimatedStaticFriction.+rpmVec0*2*pi/60*estimatedViscousDamping), label="Линейная аппроксимация")
annotate!(trqVec[end], 2.1, text(string("Коэффициент сухого трения эталонный = ", staticFriction), :left, 10))
annotate!(trqVec[end], 2.0, text(string("Коэффициент сухого трения измеренный = ", round(estimatedStaticFriction,digits=6)), :left, 10))
annotate!(trqVec[end], 1.9, text(string("Коэффициент вязкого трения эталонный = ", viscousDamping), :left, 10))
annotate!(trqVec[end], 1.8, text(string("Коэффициент вязкого трения измеренный = ", round(estimatedViscousDamping, digits=9)), :left, 10))
第二张图显示的是电机减速测试。在该测试中,所需的扭矩设为零或关闭电机。
利用测得的减速度以及设定的摩擦扭矩和阻尼扭矩,可以确定电机转子的转动惯量。
enableDrive = 0;
engee.set_param!("PMSMFromMeasurement3", "StopTime" => 2*60/rpmDemand)
if "PMSMFromMeasurement3" in [m.name for m in engee.get_all_models()]
m = engee.open( "PMSMFromMeasurement3" ) # загрузка модели
else
m = engee.load( "PMSMFromMeasurement3.engee" )
end
results4 = engee.run(m, verbose=true)
enableDrive = 1;
t = results4["rpm"].time; # Время из модели
rpm = results4["rpm"].value; # скорость ротора
plot(t, rpm, xlabel="Время, c", ylabel="Скорость (об/мин)", label="Тест замедления", w = 2)
initialTorque = -staticFriction - rpmRated*2*pi/60*viscousDamping;
initialAccel = 2*pi/60*(rpm[end]-rpm[1])/(2*60/rpmDemand);
estimatedInertia = initialTorque/initialAccel;
annotate!(0, 7465, text(string("Момент инерции эталонный = ", inertia, " кг∙м^2"), :left, 10))
annotate!(0, 7460, text(string("Момент инерции измеренный = ", round(estimatedInertia,digits=6), " кг∙м^2"), :left, 10))
结论
在本例中,我们根据实验测量结果确定了永磁同步电机的参数。
为此,我们进行了三次测试。在第一次测试中,我们确定了电机绕组的电阻和电感;在第二次测试中,我们确定了反电磁场常数;在第三次测试中,我们确定了摩擦系数和惯性矩。
实验得出的数值与文件中的电机参数相当。