基于扩展卡尔曼滤波的滑模观测器,反电动势波形近乎正弦波形,观测器估算转子电角度与实际电角度相差...
基于扩展卡尔曼滤波的滑模观测器,反电动势波形近乎正弦波形,观测器估算转子电角度与实际电角度相差0.3弧度左右,转速跟随效果不错。
电机控制的老司机们肯定对转子位置观测不陌生。今天咱们来唠唠一个实战中挺有意思的组合——把扩展卡尔曼滤波(EKF)和滑模观测器(SMO)揉在一起玩的观测方案。实测效果挺有意思:反电动势波形接近标准正弦,角度跟踪误差控制在0.3rad内,转速响应跟得比外卖小哥还紧。

先甩个核心代码片段镇楼:
class SMO_EKF:
def __init__(self):
self.theta_hat = 0.0
self.omega_hat = 0.0
self.P = np.eye(2) * 0.1 # 协方差矩阵初始化
self.Q = np.diag([0.01, 0.1]) # 过程噪声
self.R = 0.1 # 测量噪声
def update(self, i_alpha, i_beta, v_alpha, v_beta, dt):
s_alpha = self.L * (i_alpha - self.i_alpha_hat)
s_beta = self.L * (i_beta - self.i_beta_hat)
# 滑模切换项
z_alpha = self.k * np.sign(s_alpha)
z_beta = self.k * np.sign(s_beta)
# EKF预测步骤
F = np.array([[1, -dt],
[0, 1]]) # 状态转移矩阵
self.theta_hat += self.omega_hat * dt
x_pred = F @ np.array([self.theta_hat, self.omega_hat])
self.P = F @ self.P @ F.T + self.Q
# 雅可比矩阵计算
H = np.array([[-np.sin(x_pred[0]), 0],
[np.cos(x_pred[0]), 0]])
# 卡尔曼增益
K = self.P @ H.T @ np.linalg.inv(H @ self.P @ H.T + self.R)
# 观测更新
back_emf = np.array([z_alpha, z_beta])
residual = back_emf - np.array([self.ke * np.sin(x_pred[0]),
self.ke * np.cos(x_pred[0])])
x_update = x_pred + K @ residual
self.theta_hat, self.omega_hat = x_update[0] % (2*np.pi), x_update[1]
这段代码有几个精妙之处。首先是滑模的切换项zalpha/zbeta,那个np.sign()函数看着简单,实则是整个观测器的抗扰动核心。不过直接硬切换会引发抖振,所以后边用EKF来做状态估计的平滑处理,相当于给暴脾气的滑模观测器套了个缓冲垫。
有趣的是反电动势的处理方式。这里直接把滑模输出的高频分量zalpha/zbeta当作等效反电动势来用,通过self.ke(反电动势系数)换算成正弦形式。实测波形接近标准正弦的关键就在这——滑模的强鲁棒性保证了反电动势提取的完整性,而EKF的非线性处理能力则把波形中的毛刺给熨平了。

角度跟踪误差0.3rad这个数据,在实际调试中发现主要来自两个方面:一是滑模切换增益k的选择需要与转速范围匹配,二是EKF中过程噪声矩阵Q的设置。当电机转速超过1500rpm时,适当提高Q矩阵中角速度对应的噪声项,能让角度误差稳定在0.25~0.35rad区间。
转速跟随效果好的秘诀藏在状态转移矩阵里:
F = np.array([[1, -dt],
[0, 1]])
这个看似简单的离散化处理,实际上把角度和转速的耦合关系处理得很干净。特别是在加速过程中,omega_hat的更新会通过残差修正产生滞后补偿,实测在阶跃转速指令下,跟随延迟可以控制在20ms以内。

最后给个实测波形对比图(想象一下):
左边是传统滑模观测器的角度跟踪,像喝醉的蛇一样各种抖动;

右边是本方案的效果,虽然还有约0.3rad的相位差,但整个波形平滑得跟德芙巧克力似的,转速曲线更是几乎和设定值重合。这种程度的性能,在无位置传感器的洗衣机电机控制里已经足够让转子跳起华尔兹了。
更多推荐
所有评论(0)