FOC-滑膜控制器SMC/滑膜观测器SMO

目录

前面

滑膜速度控制器

控制器所处位置

理论设计

模型搭建

滑膜观测器

基本原理

反正切函数

锁相环

滑膜观测器模型(反正切)

滑膜观测器C代码实现

SMO.c

SMO.h


前面

滑膜常见用处有两个:

1、作为滑膜控制器SMC,对速度进行直接控制

2、作为滑膜观测器SMO,获取电机角度与转速信息

滑膜速度控制器

SMC叫滑膜控制(Sliding Mode Contral)

三相PMSM是一个非线性、强耦合的多变量控制系统,对于外界的扰动或者电机自身的参数发生变化时,传统的PI控制并不能满足实际的要求。因此可以引入滑模控制SMC,它对扰动和参数不敏感,响应速度也够快。

控制器所处位置

该模型在整个控制系统中的位置:

输入是:参考转速实际转速的误差。

输出是:Iq轴PI调节的输入。

理论设计

滑模控制其设计如下:

重点关注最后一个公式就可以。

模型搭建

公式可以转换为模型:

其中这三个属于滑模控制器关键参数:

转速:0.2秒时加载,可快速恢复到参考转速值1000。

电磁转矩

滑膜观测器

SMO叫滑膜观测器(Sliding Mode Observer),用于获取转子位置信息与转速信息。

在整个控制系统中所处的位置:

基本原理

该方法基于给定电流反馈电流之间的误差来设计滑膜观测器,并通过该误差重构电机的反电动势估算转子位置

简单来说就是,滑膜观测器就是通过采样与坐标变换得到的Ualpha,Ubeta,Ialpha,Ibeta四个参数值,获取扩展反电动势Ealpha、Ebeta的值。

之后则是需要想办法通过反电动势值,来获取转子的位置角θ:常见办法有反正切函数、PLL锁相环。同理也可同时获得转速估计值

反正切函数

转子的位置角:

转速估计值:

锁相环

滑膜观测器模型(反正切)

整体模型:

滑膜观测器总模型:

滑膜观测器获取反电动势模型:

反正切函数模型获取转子位置与速度信息:

转子位置 实际值与估计值:

转子速度 实际值与估计值:

滑膜观测器C代码实现

SMO.c

#include "Sensorless_SMO.h"
#include "IQ_math.h"
#define PI 3.14159265358979

extern  Angle_SMO   Angle_SMOPare ;
extern  Speed_est   Speed_estPare ;
extern  SMO_Motor   SMO_MotorPare ;
extern  IQAtan     IQAtan_Pare; 

//这段代码实现了角度估计的计算过程,其中包括滑模位置观测器的更新、电流误差的计算、滑动控制量的计算和反电势的估计
void  Angle_Cale(p_Angle_SMO  pV)
{
    /*	Sliding mode current observer	*/
    pV->EstIalpha = _IQmpy(pV->Fsmopos,pV->EstIalpha) + _IQmpy(pV->Gsmopos,(pV->Valpha-pV->Ealpha-pV->Zalpha));
    pV->EstIbeta  = _IQmpy(pV->Fsmopos,pV->EstIbeta)  + _IQmpy(pV->Gsmopos,(pV->Vbeta -pV->Ebeta -pV->Zbeta ));

	/*	Current errors	*/
    pV->IalphaError = pV->EstIalpha - pV->Ialpha;
    pV->IbetaError  = pV->EstIbeta  - pV->Ibeta;

	/*  Sliding control calculator	*/
	/* pV->Zalpha=pV->IalphaError*pV->Kslide/pV->E0) where E0=0.5 here*/
	 pV->Zalpha = _IQmpy(IQsat(pV->IalphaError,pV->E0,-pV->E0),_IQmpy2(pV->Kslide));
	 pV->Zbeta  = _IQmpy(IQsat(pV->IbetaError ,pV->E0,-pV->E0),_IQmpy2(pV->Kslide));

	/*	Sliding control filter -> back EMF calculator	*/
    pV->Ealpha = pV->Ealpha + _IQmpy(pV->Kslf,(pV->Zalpha-pV->Ealpha));
    pV->Ebeta  = pV->Ebeta  + _IQmpy(pV->Kslf,(pV->Zbeta -pV->Ebeta));
 
}

void  SMO_Pare_init(void )  // 电机参数初始化
{
	SMO_MotorPare.Rs = 0.821;    
	SMO_MotorPare.Ls = 0.00758; 
	SMO_MotorPare.Ib = 6 ;   
	SMO_MotorPare.Vb = 14 ;
	SMO_MotorPare.Ts = 0.00008;
	SMO_MotorPare.POLES=4;
	SMO_MotorPare.BASE_FREQ=135;  
	SMO_MotorPare.Fsmopos = exp((-SMO_MotorPare.Rs/SMO_MotorPare.Ls)*(SMO_MotorPare.Ts));
	SMO_MotorPare.Gsmopos = (SMO_MotorPare.Vb/SMO_MotorPare.Ib)*(1/SMO_MotorPare.Rs)*(1-SMO_MotorPare.Fsmopos);

	Angle_SMOPare.Fsmopos = (int32_t)( SMO_MotorPare.Fsmopos*32768);
	Angle_SMOPare.Gsmopos = (int32_t)( SMO_MotorPare.Gsmopos*32768);
	Angle_SMOPare.Kslide = 4500 ;  //     
	Angle_SMOPare.Kslf =1000;      //      
	Angle_SMOPare.E0= 32670 ;      //    
	Speed_estPare.SpeedK1=355;
	Speed_estPare.SpeedK2=669;
	Speed_estPare.speed_coeff=(500*60)/(SMO_MotorPare.POLES ); // 2毫秒计算一次角度差值 1000/2ms=500   =7500	
}

 // 电机在2ms时间计算角度变化量。即是公式:
 // Speed_estPare.Speed_ele_angleIQ =Speed_estPare.ele_angleIQ -Speed_estPare.old_ele_angleIQ  
 // 防止超过65535和小于0,把差值一阶滤波,插值变化量乘系数就可以得到速度。
 // 速度信号的计算可以简单根据转位置的步进角计算或者直接根据角度在一定周期内的变化量计算
 // 其中移位16是把角度变化量归1的一个系数,变化角度/360度,在乘一个系数得到速度,
 // 可以通过示波器测量一个霍尔周期时间来计算。
 // 假设一个霍尔周期时间15ms,电机极对数为4,速度RPM=1/T*60/p=1000/15*60/4=1000rpm 
 // 然后看在线看角度变化量(或者通讯发出来),速度RPM=变化量/65535*K=1000,求得系数K。 
 // 系数 :Speed_estPare.speed_coeff

void SMO_Speedcale(void)  // 2ms执行一次
{
   Speed_estPare.ele_angleIQ= IQAtan_Pare.IQAngle; 
 	 Speed_estPare.Speed_ele_angleIQ =Speed_estPare.ele_angleIQ- Speed_estPare.old_ele_angleIQ ;

	//如果速度估计值为负数,则加上一个周期的角度(65536)来获得正数表示的速度值
   if( Speed_estPare.Speed_ele_angleIQ <0)
   Speed_estPare.Speed_ele_angleIQ+=65536; 	
   
   //通过速度滤波器计算平滑的速度估计值
 	Speed_estPare.Speed_ele_angleIQFitter= _IQ10mpy(Speed_estPare.SpeedK2, Speed_estPare.Speed_ele_angleIQFitter)+_IQ10mpy(Speed_estPare.SpeedK1,  Speed_estPare.Speed_ele_angleIQ);
   
   //转换成电机的旋转速度值Speed_RPM 这个是系数角度计算系数speed_coeff
   Speed_estPare.Speed_RPM = (Speed_estPare.Speed_ele_angleIQ*Speed_estPare.speed_coeff)>>16; // 最大角度 2pi是一圈 65536
	
   //对转速值进行限制。如果转速值超过3000 RPM,则将转速值设为0
	 if( Speed_estPare.Speed_RPM>=3000)
	  Speed_estPare.Speed_RPM=0;
	 Speed_estPare.old_ele_angleIQ = Speed_estPare.ele_angleIQ ;
}
 

//===========================================================================
// No more.
//===========================================================================

SMO.h

#ifndef  Sensorless_SMO_H
#define  Sensorless_SMO_H

#include "IQ_math.h"
#include "stm32f10x.h" 
#include "math.h"
 

typedef struct {
	     int32_t  Valpha;       //二相静止坐标系alpha-轴电压	
	     int32_t  Ealpha;       //二相静止坐标系alpha-轴反电动势
	     int32_t  Zalpha;       //alfa轴滑膜观测器的z平面
	     int32_t  Gsmopos;      //滑膜常数1
	     int32_t  EstIalpha;    //滑膜估算alpha-轴电流
	     int32_t  Fsmopos;      //滑膜常数2
	     int32_t  Vbeta;        //二相静止坐标系beta-轴电压	 
	     int32_t  Ebeta;  	    //二相静止坐标系beta-轴反电动势
	     int32_t  Zbeta;        //beta轴滑膜观测器的z平面	 
	     int32_t  EstIbeta;     //滑膜估算beta-轴电流 
	     int32_t  Ialpha;  	    //二相静止坐标系alpha-轴电流
	     int32_t  IalphaError;  //二相静止坐标系beta-轴电流误差
	     int32_t  Kslide;       //滤波器系数	 
	     int32_t  Ibeta;  	    //二相静止坐标系beta-轴电流 
	     int32_t  IbetaError;   //二相静止坐标系beta-轴电流误差
	     int32_t  Kslf;         //滤波器系数
	     int32_t  E0;	          //滑膜的电流误差的限幅值 0.5
	   } Angle_SMO, *p_Angle_SMO;

#define Angle_SMO_DEFAULTS {0,0,0,0,0,0,0,0,0,0,0,0} // 初始化参数

typedef struct {
	    int32_t  Speed_ele_angleIQ;  //速度电角度值(计算速度)  
	    int32_t  old_ele_angleIQ;   // 电机历史电角度
	    int32_t  ele_angleIQ;      // 电机电角度
	    int32_t  Speed_ele_angleIQFitter;  //速度电角度值(计算速度)    	 
	    uint16_t Speed_RPM;       	 //电机旋转速度 	 
	    uint32_t speed_coeff;       //计算速度的系数
    	uint16_t SpeedK1;           // 速度滤波系数K1
	    uint16_t SpeedK2;         // 速度滤波系数K2
	   }Speed_est;

#define Speed_est_DEFAULTS {0,0,0,0,0,0,0,0} // 初始化参数

typedef struct{
	float  Rs; 			//电机的相电阻	 
	float  Ls;			//电机的相电感	  
    float  Ib; 			//电机控制器的基本相电流 	  
	float  Vb;			//电机控制器的基本相电压	 
    float  Ts;			 //采样周期	 
    uint32_t   POLES; // 电机的极对数
    uint32_t   BASE_FREQ; // 电机控制器的基本频率
	float  Fsmopos;		   //滑膜常数1
    float  Gsmopos;			 //滑膜常数2
  }SMO_Motor;

#define SMO_Motor_DEFAULTS {0.0,0.0,0.0,0.0,0.0,0,0,0.0,0.0} // 初始化参数

void  Angle_Cale(p_Angle_SMO  pV); //滑膜电机位置电角度计算
void  SMO_Pare_init (void );   // 滑膜观测器的参数初始化
void SMO_Speedcale(void) ;    //  滑膜的角度计算速度函数
#endif /* Sensorless_SMO*/

内容概要:本文详细介绍了无感FOC(Field Oriented Control)电机控制系统的实现,特别是采用滑膜观测器(Sliding Mode Observer, SMO)进行转子磁场观测的方法。文章首先解释了为何选择无感FOC及其优势,接着深入探讨了滑膜观测器相较于传统卡尔曼滤波器的优点,如鲁棒性强、计算简单和实时性好。文中展示了从启动阶段的V/f控制到稳定运行阶段的FOC控制的具体代码实现,包括启动阶段的V/f控制、运行阶段的FOC控制以及滑膜观测器的实现。此外,还特别强调了代码实现中的注意事项,如采样时间的选择、观测器增益的整定和坐标变换的精度。最后,文章总结了整个项目的开发历程,并指出代码已完全开源,旨在帮助初学者更好地理解和掌握无感FOC控制。 适合人群:对电机控制尤其是无感FOC感兴趣的工程师和技术爱好者,具备一定的C语言编程基础和嵌入式开发经验。 使用场景及目标:适用于高精度工业控制、伺服系统等领域,目标是提高电机的动态响应和控制精度。通过学习本文提供的代码实现和实战经验,读者可以更好地理解无感FOC的工作原理并应用于实际项目中。 其他说明:本文不仅提供了详细的代码实现,还分享了许多实用的调试技巧和优化建议,如滑膜观测器的参数调整、V/f启动的频率斜坡设置等。这些内容对于初学者来说非常有价值,可以帮助他们少走弯路,更快地上手无感FOC控制。
### 使用Simulink设计小车跟随滑模控制系统的教程 #### 项目背景 在现代控制系统的设计中,滑模控制(Sliding Mode Control, SMC)因其鲁棒性和对不确定性的容忍度而在许多应用领域得到广泛应用。对于移动机器人或自动车辆而言,SMC能有效应对环境变化带来的不确定性,确保路径跟踪精度。 #### 控制目标设定 针对本案例中的小车系统,主要目的是使小车沿预定轨迹行驶并保持稳定姿态。为此需构建一个基于状态反馈的非线性控制器,在存在外界干扰情况下仍可维持良好性能[^1]。 #### 系统建模与分析 建立精确的动力学模型是实施任何先进控制策略的前提条件之一。考虑到实际应用场景复杂多变的特点,这里采用简化版二自由度单轨汽车模型作为研究对象: - 质量 \( m \) - 惯性矩 \( I_z \) - 前轮转角 \( δ_f(t) \) 其运动方程组如下所示: \[ \begin{aligned} &\dot{x}(t)=v(t)\cos(\theta (t)) \\ &\dot{y}(t)=v(t)\sin (\theta (t))\\ &\dot{\psi }(t)=\frac{{a}\cdot {u}_f(t)-b\cdot u_r(t)}{I_{zz}}\\ &\ddot{\upsilon }=\left[\mu _c-\beta v^{2}+\gamma |\delta |^p sign(v)\right]\times F_x /m -g sin(\alpha )+w_\nu (t), p>0. \end{aligned} \] 其中\( w_v(t) \)表示过程噪声;其余变量定义见表1. | 符号 | 含义 | |------------|-------------------------------| | \( x,y,\theta\) | 小车位姿坐标 | | \( a,b \) | 主轴到前后桥中心距离 | | \( μ_c \) | 阻尼系数 | | \( β ,γ,p \) | 参数 | 此部分具体推导细节参阅文献[^4]. #### 设计滑模面及其切换函数 根据上述动力学特性,选取合适的状态向量组合形成期望趋近律: \[ s=e+C_1e'+...+C_ne^{(n)}, e=r-y \] 此处\( r \)代表参考指令序列; \( y \)为当前输出测量值. 并据此构造相应的切换逻辑表达式以驱动误差收敛至零平面附近区域运行. #### 构造Lyapunov候选泛函验证稳定性 引入正定能量型指标V(s),证明当时间趋于无穷大时,V'(s)<0恒成立,则说明所提算法具备全局渐近稳定的性质. #### MATLAB/Simulink实现流程概览 利用MathWorks官方提供的工具箱快速搭建虚拟实验平台,完成整个闭环回路联调测试工作流: 1. 新建空白工程文件夹; 2. 编辑`plant.m`, 定义受控体动态行为特征; 3. 修改`ctrl.m`, 实现自定义SMC算法核心功能模块 ; 4. 设置初始参数集于`parameter.m`; 5. 运行脚本`demo_plot.m`查看最终效果展示图表; 特别注意的是,在处理含有高频成分较多的实际物理信号过程中可能会遇到抖振现象影响整体表现质量的问题,此时建议尝试加入低通滤波器环节抑制不必要的高频分量或者考虑其他改进措施如边界层法等来缓解此类状况的发生概率[^3]. ```matlab % plant.m: 物理方程描述 function dxdt = plant(t,x,u,param) dxdt=[x(2);... -(param.b*x(2)+param.k*(x(1)-r))/param.m]; end % ctrl.m: 控制律描述 function u=ctrl(x,param) if abs(s)>eps u=-sign(s)*(lambda*abs(s)^rho+kappa); else u=-k*s; end end % parameter.m: 常数值设置 param.a=1; param.b=0.5; param.k=8; param.m=70; param.lambda=10; param.rho=0.9; param.kappa=2; eps=0.01;k=5; % demo_plot.m: 结果可视化绘制 figure(); plot(time,response,'LineWidth',2); xlabel('Time[s]'); ylabel('Position[m]'); title('Response Curve'); grid on; ```
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值