3. SMO增益参数整定与鲁棒性分析
任务目标
本案例针对永磁同步电机(PMSM)无位置传感器控制中的滑模观测器(SMO),完成以下闭环任务:
- 建立包含参数摄动的PMSM反电动势模型与滑模观测器;
- 实现滑模增益
k的整定规则,并分析其对观测误差与抖振的影响; - 在电机电阻、电感发生摄动时,测试观测器的鲁棒性。
核心原理与整定规则
滑模观测器采用饱和函数替代符号函数以抑制抖振,边界层厚度为ε。增益k需满足存在性条件:
k > max(|e_α|, |e_β|) + δ,其中e_α, e_β为反电动势估计误差,δ为裕量。
整定规则:
- 下限:
k_min = 1.2 × max(|E_α|, |E_β|),保证滑模可达; - 上限:
k_max = 2.0 × max(|E_α|, |E_β|),超过后抖振显著增大且观测精度不再提升; - 推荐初值:
k = 1.5 × E_peak,ε = 0.1 × E_peak,其中E_peak为额定转速下反电动势幅值。
仿真模型与代码
以下Python代码实现完整闭环:包含PMSM模型、滑模观测器、参数摄动注入与增益扫描分析。依赖numpy与matplotlib。
import numpy as np
import matplotlib.pyplot as plt
# ---------- PMSM参数 ----------
Rs = 2.0 # 定子电阻(Ω)
Ld = Lq = 0.01 # 电感(H)
flux = 0.1 # 永磁体磁链(Wb)
pp = 4 # 极对数
J = 0.002 # 转动惯量(kg·m²)
B = 0.001 # 阻尼系数
# 额定工况
speed_ref = 1500 # rpm
omega_e = speed_ref * pp * np.pi / 30 # 电角速度(rad/s)
Vdc = 300.0
# 反电动势幅值(额定)
E_peak = flux * omega_e
# ---------- 参数摄动注入 ----------
def perturb_params(Rs_nom, L_nom, pct):
"""返回摄动后的参数, pct为百分比(如0.2表示+20%)"""
Rs_p = Rs_nom * (1 + pct)
L_p = L_nom * (1 + pct)
return Rs_p, L_p
# ---------- 滑模观测器 ----------
def smo_observer(i_alpha, i_beta, v_alpha, v_beta,
Rs_hat, L_hat, k, epsilon, dt,
i_alpha_hat, i_beta_hat, e_alpha_hat, e_beta_hat):
"""
基于电流模型的滑模观测器
返回: 更新后的电流估计、反电动势估计
"""
# 电流误差
err_alpha = i_alpha_hat - i_alpha
err_beta = i_beta_hat - i_beta
# 饱和函数
def sat(x):
return np.clip(x / epsilon, -1.0, 1.0)
# 滑模控制律
u_alpha = -k * sat(err_alpha)
u_beta = -k * sat(err_beta)
# 电流估计更新
di_alpha_hat = (-Rs_hat * i_alpha_hat + v_alpha - e_alpha_hat + u_alpha) / L_hat
di_beta_hat = (-Rs_hat * i_beta_hat + v_beta - e_beta_hat + u_beta) / L_hat
i_alpha_hat += di_alpha_hat * dt
i_beta_hat += di_beta_hat * dt
# 反电动势估计(通过低通滤波)
cutoff = 100.0 # 截止频率(rad/s)
alpha = cutoff * dt / (1 + cutoff * dt)
e_alpha_hat += alpha * (u_alpha - e_alpha_hat)
e_beta_hat += alpha * (u_beta - e_beta_hat)
return i_alpha_hat, i_beta_hat, e_alpha_hat, e_beta_hat
# ---------- 仿真主循环 ----------
def run_simulation(Rs_actual, L_actual, k, epsilon, sim_time=0.5):
dt = 1e-5
steps = int(sim_time / dt)
# 状态初始化
i_alpha, i_beta = 0.0, 0.0
i_alpha_hat, i_beta_hat = 0.0, 0.0
e_alpha_hat, e_beta_hat = 0.0, 0.0
theta_e = 0.0
# 记录稳态误差与抖振
err_history = []
chattering_history = []
for step in range(steps):
t = step * dt
theta_e = omega_e * t
# 实际反电动势
e_alpha = -flux * omega_e * np.sin(theta_e)
e_beta = flux * omega_e * np.cos(theta_e)
# 施加电压(简化: 直接给定)
v_alpha = Rs_actual * i_alpha + e_alpha
v_beta = Rs_actual * i_beta + e_beta
# 实际电流(理想模型)
di_alpha = (-Rs_actual * i_alpha + v_alpha - e_alpha) / L_actual
di_beta = (-Rs_actual * i_beta + v_beta - e_beta) / L_actual
i_alpha += di_alpha * dt
i_beta += di_beta * dt
# 观测器更新(使用标称参数)
i_alpha_hat, i_beta_hat, e_alpha_hat, e_beta_hat = smo_observer(
i_alpha, i_beta, v_alpha, v_beta,
Rs, Ld, k, epsilon, dt,
i_alpha_hat, i_beta_hat, e_alpha_hat, e_beta_hat
)
# 记录稳态数据(0.3s后)
if t > 0.3:
err = np.sqrt((e_alpha - e_alpha_hat)**2 + (e_beta - e_beta_hat)**2)
err_history.append(err)
# 抖振度量: 控制量高频分量
if step > 10:
chattering = np.abs(e_alpha_hat - e_alpha_hat_prev)
chattering_history.append(chattering)
e_alpha_hat_prev = e_alpha_hat
# 返回均方根误差与抖振指标
rmse = np.sqrt(np.mean(np.square(err_history)))
chattering_level = np.mean(chattering_history) if chattering_history else 0
return rmse, chattering_level
# ---------- 增益扫描分析 ----------
k_values = np.linspace(0.5 * E_peak, 3.0 * E_peak, 10)
epsilon = 0.1 * E_peak
rmse_list = []
chatter_list = []
print("=== 增益扫描 (标称参数) ===")
for k in k_values:
rmse, chatter = run_simulation(Rs, Ld, k, epsilon)
rmse_list.append(rmse)
chatter_list.append(chatter)
print(f"k={k:.3f} ({k/E_peak:.1f}×E_peak) RMSE={rmse:.4f}V 抖振={chatter:.6f}V")
# ---------- 参数摄动鲁棒性测试 ----------
print("\n=== 参数摄动鲁棒性测试 (k=1.5×E_peak) ===")
k_fixed = 1.5 * E_peak
perturbations = [-0.3, -0.15, 0, 0.15, 0.3] # ±30%, ±15%, 0
for pct in perturbations:
Rs_p, L_p = perturb_params(Rs, Ld, pct)
rmse, chatter = run_simulation(Rs_p, L_p, k_fixed, epsilon)
print(f"摄动{pct*100:+.0f}%: Rs={Rs_p:.2f}Ω, L={L_p:.4f}H RMSE={rmse:.4f}V 抖振={chatter:.6f}V")
# ---------- 可视化 ----------
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
# 左图: 增益与误差/抖振关系
ax1_twin = ax1.twinx()
ax1.plot(k_values/E_peak, rmse_list, 'b-o', label='观测误差(RMSE)')
ax1_twin.plot(k_values/E_peak, chatter_list, 'r-s', label='抖振水平')
ax1.set_xlabel('增益 k (×E_peak)')
ax1.set_ylabel('观测误差 (V)', color='b')
ax1_twin.set_ylabel('抖振水平 (V)', color='r')
ax1.axvline(x=1.0, color='gray', linestyle='--', alpha=0.5)
ax1.axvline(x=2.0, color='gray', linestyle='--', alpha=0.5)
ax1.text(1.0, max(rmse_list)*0.9, 'k_min', ha='center')
ax1.text(2.0, max(rmse_list)*0.9, 'k_max', ha='center')
ax1.legend(loc='upper left')
ax1_twin.legend(loc='upper right')
ax1.set_title('滑模增益整定分析')
ax1.grid(True, alpha=0.3)
# 右图: 参数摄动下的鲁棒性
pct_labels = [f'{p*100:+.0f}%' for p in perturbations]
rmse_perturb = []
for pct in perturbations:
Rs_p, L_p = perturb_params(Rs, Ld, pct)
rmse, _ = run_simulation(Rs_p, L_p, k_fixed, epsilon)
rmse_perturb.append(rmse)
ax2.bar(pct_labels, rmse_perturb, color='steelblue')
ax2.set_xlabel('参数摄动比例')
ax2.set_ylabel('观测误差 RMSE (V)')
ax2.set_title('参数摄动鲁棒性 (k=1.5×E_peak)')
ax2.grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('smo_gain_analysis.png', dpi=150)
print("\n图像已保存: smo_gain_analysis.png")
运行与验证
运行方式:直接执行上述Python脚本,需安装numpy和matplotlib。
通过条件:
- 增益扫描结果应显示:当
k从0.5×E_peak增大到1.5×E_peak时,观测误差RMSE显著下降;继续增大到2.0×E_peak以上时,误差基本不变但抖振水平持续上升; - 参数摄动测试中,在±30%的电阻、电感摄动下,观测误差RMSE应保持在较小范围(相对标称值变化不超过50%),证明观测器对参数摄动具有鲁棒性;
- 生成的
smo_gain_analysis.png应清晰展示上述两个趋势。
整定规则总结
| 参数 | 整定规则 | 影响 |
|---|---|---|
增益 k | 1.2×E_peak ≤ k ≤ 2.0×E_peak,推荐1.5×E_peak | 过小导致观测误差增大;过大导致抖振加剧 |
边界层 ε | ε = 0.05~0.15×E_peak | 过小抖振大;过大降低观测精度 |
实际应用中,E_peak随转速变化,建议采用k = 1.5 × flux × |ω_e|的自适应形式,或按最高转速设计固定增益并验证低速性能。