无感 FOC:滑模观测器(SMO)
系列:电机控制系列 - 第 11 篇 难度:⭐⭐⭐⭐ 阅读时间:40 分钟
前言
编码器成本高、体积大、可靠性差。
无感 FOC 的优势:
- ✅ 无编码器 → 降低成本
- ✅ 减少体积
- ✅ 提高可靠性
本篇目标:
- ✅ 理解滑模观测器原理
- ✅ 掌握反电动势提取
- ✅ 实现完整的 SMO 代码
一、滑模观测器原理
1.1 核心思想
观测器:根据可测量,估计不可测量
可测量:ia, ib, ua, ub
不可测量:θe(电角度)
观测器:利用电机数学模型,从电流误差估计反电动势 → 提取角度1.2 数学模型
αβ 坐标系电压方程:
uα = Rs·iα + L·(diα/dt) + eα
uβ = Rs·iβ + L·(diβ/dt) + eβ
其中:
- eα, eβ:反电动势
- eα = -ωe·ψf·sin(θe)
- eβ = ωe·ψf·cos(θe)关键:反电动势包含角度信息!
θe = atan2(-eα, eβ)1.3 滑模观测器方程
电流观测器:
îα_dot = (uα - Rs·iα - zα) / L
îβ_dot = (uβ - Rs·iβ - zβ) / L
其中:
- îα, îβ:估计电流
- zα, zβ:滑模控制项滑模控制项:
zα = k·sign(iα - îα)
zβ = k·sign(iβ - îβ)
其中:
- k:滑模增益(需大于反电动势最大值)
- sign(x):符号函数反电动势提取(低通滤波):
êα = LPF(zα)
êβ = LPF(zβ)二、SMO 实现
2.1 数据结构
/**
* @brief 滑模观测器
*/
typedef struct {
// 估计值
float i_alpha_est;
float i_beta_est;
float e_alpha;
float e_beta;
// 观测器参数
float k_slide; // 滑模增益
float lpf_coeff; // 低通滤波系数
// 输出
float theta_est; // 估计角度
float omega_est; // 估计角速度
} SMO_t;2.2 SMO 更新函数
/**
* @brief SMO 更新
*/
void SMO_Update(SMO_t *smo,
float u_alpha, float u_beta,
float i_alpha, float i_beta,
float dt,
Motor_Params_t *motor) {
// 1. 电流误差
float err_alpha = i_alpha - smo->i_alpha_est;
float err_beta = i_beta - smo->i_beta_est;
// 2. 滑模函数(平滑 sign 函数)
float z_alpha = smo->k_slide * tanhf(err_alpha * 10.0f);
float z_beta = smo->k_slide * tanhf(err_beta * 10.0f);
// 3. 电流观测器
float i_alpha_dot = (u_alpha - motor->Rs * i_alpha - z_alpha) / motor->Ld;
float i_beta_dot = (u_beta - motor->Rs * i_beta - z_beta) / motor->Ld;
smo->i_alpha_est += i_alpha_dot * dt;
smo->i_beta_est += i_beta_dot * dt;
// 4. 反电动势提取(低通滤波)
smo->e_alpha = smo->e_alpha * (1.0f - smo->lpf_coeff) + z_alpha * smo->lpf_coeff;
smo->e_beta = smo->e_beta * (1.0f - smo->lpf_coeff) + z_beta * smo->lpf_coeff;
// 5. 角度计算
float theta_new = atan2f(-smo->e_alpha, smo->e_beta);
// 6. 角度归一化
if (theta_new < 0) theta_new += 2.0f * M_PI;
// 7. 角速度计算(PLL 或简单差分)
float delta_theta = theta_new - smo->theta_est;
// 处理角度跳变
if (delta_theta > M_PI) delta_theta -= 2.0f * M_PI;
if (delta_theta < -M_PI) delta_theta += 2.0f * M_PI;
smo->omega_est = delta_theta / dt;
smo->theta_est = theta_new;
}2.3 参数整定
/**
* @brief SMO 参数初始化
*/
void SMO_Init(SMO_t *smo, Motor_Params_t *motor) {
// 滑模增益:需大于反电动势峰值
// e_max = ω_max · ψf
float omega_max = 1000.0f; // rad/s
float e_max = omega_max * motor->Psi_f;
smo->k_slide = e_max * 1.5f; // 1.5 倍安全裕量
// 低通滤波系数:权衡噪声 vs 延迟
// 建议值:0.01 - 0.1
smo->lpf_coeff = 0.05f;
// 初始化
smo->i_alpha_est = 0;
smo->i_beta_est = 0;
smo->e_alpha = 0;
smo->e_beta = 0;
smo->theta_est = 0;
smo->omega_est = 0;
}三、无感 FOC 集成
/**
* @brief 无感 FOC 控制
*/
void FOC_Sensorless_Update(FOC_t *foc) {
// 1. 电流采样
ADC_Read_Current(&foc->ia, &foc->ib, &foc->ic);
// 2. Clarke 变换
Clarke_Transform(foc->ia, foc->ib, foc->ic,
&foc->i_alpha, &foc->i_beta);
// 3. SMO 估计角度
SMO_Update(&foc->smo,
foc->v_alpha, foc->v_beta, // 上一周期电压
foc->i_alpha, foc->i_beta,
foc->pid_id.Ts,
&foc->motor);
foc->theta_e = foc->smo.theta_est;
foc->omega_m = foc->smo.omega_est / foc->motor.P;
// 4. Park 变换
Park_Transform(foc->i_alpha, foc->i_beta, foc->theta_e,
&foc->id, &foc->iq);
// 5. 电流环 PID
foc->vd = PID_Position(&foc->pid_id, foc->id_ref - foc->id);
foc->vq = PID_Position(&foc->pid_iq, foc->iq_ref - foc->iq);
// 6. 逆 Park 变换
Inv_Park_Transform(foc->vd, foc->vq, foc->theta_e,
&foc->v_alpha, &foc->v_beta);
// 7. SVPWM
SVPWM_Control(foc->v_alpha, foc->v_beta, VDC);
}四、SMO 局限性
4.1 低速性能差
原因:
- 低速 → 反电动势小 → 信噪比低
- 观测器难以区分反电动势和噪声
解决方法:
- 高频注入法(第 12 篇)
- 开环强拖启动(低速)
4.2 参数敏感性
原因:
- 观测器依赖 Rs, L
- 参数变化 → 性能下降
解决方法:
- 在线参数辨识(第 17 篇)
五、总结
SMO 核心要点:
- 电流观测器 + 滑模函数
- 反电动势提取(低通滤波)
- 角度 = atan2(-eα, eβ)
- 适用于中高速场景
下一篇:无感 FOC:高频注入法