4. 无感FOC的滑模观测器实现
任务目标
本案例实现用于无感FOC的滑模观测器(SMO),从电机相电流和母线电压估算反电动势,进而得到转子位置与速度,替代位置传感器完成闭环控制。
核心原理
在αβ静止坐标系下,表贴式PMSM的电压方程为:
v_α = R·i_α + L·(di_α/dt) − ω_e·ψ_f·sin(θ_e)
v_β = R·i_β + L·(di_β/dt) + ω_e·ψ_f·cos(θ_e)
其中反电动势项 e_α = −ω_e·ψ_f·sin(θ_e),e_β = ω_e·ψ_f·cos(θ_e)。滑模观测器通过电流误差构造滑模面,经滑模控制律提取反电动势,再用反正切或锁相环(PLL)解算转子位置与速度。
实现代码
以下为完整的滑模观测器C实现,包含电流观测、滑模控制律、反电动势滤波及PLL位置速度估算,可直接嵌入FOC控制循环(10kHz中断调用):
// smo.h
typedef struct {
float Rs, Ls; // 定子电阻、电感
float Ts; // 采样周期(s)
float k_slide; // 滑模增益
float lp_fc; // 低通滤波截止频率(Hz)
float pll_kp, pll_ki; // PLL带宽参数
// 内部状态
float i_alpha_est, i_beta_est;
float e_alpha_raw, e_beta_raw;
float e_alpha_f, e_beta_f;
float theta_pll, omega_pll;
float pll_integral;
} SMO;
void smo_init(SMO *smo, float Rs, float Ls, float Ts,
float k_slide, float lp_fc, float pll_kp, float pll_ki) {
smo->Rs = Rs; smo->Ls = Ls; smo->Ts = Ts;
smo->k_slide = k_slide; smo->lp_fc = lp_fc;
smo->pll_kp = pll_kp; smo->pll_ki = pll_ki;
smo->i_alpha_est = smo->i_beta_est = 0;
smo->e_alpha_raw = smo->e_beta_raw = 0;
smo->e_alpha_f = smo->e_beta_f = 0;
smo->theta_pll = smo->omega_pll = 0;
smo->pll_integral = 0;
}
// 符号函数
static float sign(float x) { return (x > 0) ? 1.0f : ((x < 0) ? -1.0f : 0.0f); }
// 主更新函数:输入v_alpha/v_beta(电压V),i_alpha/i_beta(电流A)
// 输出:smo->theta_pll(电角度rad),smo->omega_pll(电角速度rad/s)
void smo_update(SMO *smo, float v_alpha, float v_beta,
float i_alpha, float i_beta) {
float L = smo->Ls, R = smo->Rs, Ts = smo->Ts;
float k = smo->k_slide;
// 1. 电流观测器(欧拉离散)
float di_alpha = (1.0f/L) * (v_alpha - R*smo->i_alpha_est
- smo->e_alpha_raw);
float di_beta = (1.0f/L) * (v_beta - R*smo->i_beta_est
- smo->e_beta_raw);
smo->i_alpha_est += di_alpha * Ts;
smo->i_beta_est += di_beta * Ts;
// 2. 电流误差
float err_alpha = smo->i_alpha_est - i_alpha;
float err_beta = smo->i_beta_est - i_beta;
// 3. 滑模控制律(等效反电动势)
smo->e_alpha_raw = k * sign(err_alpha);
smo->e_beta_raw = k * sign(err_beta);
// 4. 低通滤波(一阶惯性)
float w_lp = 2.0f * 3.14159265f * smo->lp_fc;
float alpha = w_lp * Ts / (1.0f + w_lp * Ts);
smo->e_alpha_f += alpha * (smo->e_alpha_raw - smo->e_alpha_f);
smo->e_beta_f += alpha * (smo->e_beta_raw - smo->e_beta_f);
// 5. PLL估算位置与速度
// 误差:e_cross = e_alpha_f*cos(θ) + e_beta_f*sin(θ) → 0
float err_pll = smo->e_alpha_f * cosf(smo->theta_pll)
+ smo->e_beta_f * sinf(smo->theta_pll);
// 归一化(反电动势幅值近似为k)
err_pll = err_pll / (k + 1e-6f);
smo->pll_integral += smo->pll_ki * err_pll * Ts;
smo->omega_pll = smo->pll_kp * err_pll + smo->pll_integral;
smo->theta_pll += smo->omega_pll * Ts;
// 角度归一化到(-π, π]
if (smo->theta_pll > 3.14159265f)
smo->theta_pll -= 2.0f * 3.14159265f;
else if (smo->theta_pll < -3.14159265f)
smo->theta_pll += 2.0f * 3.14159265f;
}
参数整定与使用
- 滑模增益
k_slide:需大于反电动势峰值,通常取k = 1.2~1.5 × ω_e·ψ_f,实际调试时从小到大增加直至电流误差收敛。 - 低通截止频率
lp_fc:滤除滑模抖振,一般设为电频率的5~10倍,过高则滤波不净,过低则相位延迟大。 - PLL带宽:
pll_kp决定动态响应,pll_ki消除稳态误差。建议初始pll_kp = 200~500,pll_ki = 0.1×pll_kp,再根据实际速度波动微调。
运行与验证
离线仿真验证步骤:
- 准备一组电机运行数据:给定恒定电频率
f_e = 50Hz(电角速度ω_e = 314 rad/s),反电动势幅值E = 5V,用理想电压方程生成v_α, v_β和i_α, i_β波形(采样率10kHz,时长0.1s)。 - 调用
smo_init()初始化,参数:Rs=1.0Ω, Ls=0.005H, Ts=1e-4s, k_slide=8.0, lp_fc=500Hz, pll_kp=300, pll_ki=30。 - 循环调用
smo_update(),记录每次输出的theta_pll和omega_pll。
通过条件:
- 稳态后(约20ms后)估算电角速度
omega_pll收敛至314 rad/s附近,误差小于5%。 - 估算角度
theta_pll与实际角度θ_e = ω_e·t的差值(减去固定相位偏移后)波动小于±0.1rad。 - 若用于实际电机控制,需在电机中速运转(额定转速10%以上)时切入观测器,切换瞬间电流无明显冲击。
常见问题
- 启动失败:零速/低速时反电动势幅值过小,SMO无法收敛。需使用I/F或V/F开环启动,达到一定转速后再切换至SMO闭环。
- 角度滞后:低通滤波器引入相位延迟,可在估算角度上补偿
atan(ω_e/ω_lp)的角度,或改用滑模观测器+自适应滤波器。 - 抖振过大:增大低通滤波深度或改用饱和函数替代符号函数,但会降低带宽,需权衡。