【电机控制】FOC无刷电机控制(FOC算法篇-不带电流环)

本文详细解析了FOC无刷电机控制中的算法,包括三闭环控制结构、Park和Clark变换的应用、PID控制策略以及SVPWM的实施过程,重点介绍了SimpleFOC控制方法的简化版。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【电机控制】FOC无刷电机控制(FOC算法篇)


前言

【电机控制】SimpleFOC-无刷电机控制(硬件篇)

【电机控制】SimpleFOC-无刷电机控制(软件篇)

【电机控制】SimpleFOC-无刷电机控制(SimpleFOC_studio上位机篇)

【电机控制】FOC无刷电机控制(FOC算法篇)

B站视频展示:

【电机控制】SimpleFOC无刷电机速度环位置环

提示:以下是本篇文章正文内容,下面案例可供参考

一、FOC整体框架

FOC整体框架

请添加图片描述

二、工程控制论——三闭环控制系统

三闭环嵌套,电流环在内,然后依次为速度、位置环
请添加图片描述

三、FOC解耦——SimpleFOC控制框图

关于BLCD的FOC控制,先看电流环,最内环
关于FOC解耦部分,主要根据SimpleFOC代码进行解释
原本的电流环-FOC控制框图是这样的:
请添加图片描述
三项逆变电路
请添加图片描述

步骤是这样的:
1.对电机三相电流进行采样得到 Ia,Ib,Ic。
2.将 Ia,Ib,Ic 经过Clark变换得到 I_alpha I_beta。
3.将 I_alpha I_beta 经过Park变换得到 Id,Iq。
4.计算 Id,Iq 和其设定值 Id_ref 和Iq_ref 的误差
5.将上述误差输入两个PID(只用到PI)控制器,得到输出的控制电压Ud、Uq。
6.将 Ud、Uq 进行反Park变换得到 U_alpha U_beta。
7.用 U_alpha U_beta 合成电压空间矢量,输入SVPWM模块进行调制,输出该时刻三个半桥的状态编码值(前文有提到)
8.按照前面输出的编码值控制三相逆变器的MOS管开关,驱动电机
循环上述步骤

但是!
SimpleFOC没有用使用电流采集,仅有电压,所以我们舍弃了电流采集反馈部分,为了驱动电路,我们需要转子的位置,因此在有感方案里,需要位置传感器,例如磁编码器或者霍尔传感器;而在无感方案里,需要滑膜观测器或者磁链观测器。
控制框图简化如下:
在这里插入图片描述
SimpleFOC步骤如下:
1.将 Ud、Uq 进行反Park变换得到 U_alpha U_beta。
2.用 U_alpha U_beta 合成电压空间矢量,输入SVPWM模块进行调制,输出该时刻三个半桥的状态编码值(前文有提到)
3.按照前面输出的编码值控制三相逆变器的MOS管开关,驱动电机
循环上述步骤

1、clark变换——KCL(SimpleFOC不用)

但是我们实际电路设计时不会使用三个采样器,只需要两个就够了。因为由基尔霍夫电流定律(KCL),在任一时刻,流入节点的电流之和等于流出节点的电流之和,也就是说

请添加图片描述
在这里插入图片描述
请添加图片描述
其矩阵形式:
请添加图片描述

2、park变换——三角函数(SimpleFOC不用)

请添加图片描述
请添加图片描述
其矩阵形式:
请添加图片描述

3、PID控制算法

请添加图片描述

a.电流环:

表贴式PMSM时,ID=0,只作用IQ、UQ,且不需要clark变换和park变换,此时不需要PID算法

case Type_torque:
			if(torque_controller==Type_voltage)voltage.q = new_target;  // if voltage torque control
		  else
				current_sp = new_target; // if current/foc_current torque control
			break;

b.速度环+电流环

首先,设定值给到速度设定,那么输出值就需要经过PID算法,
输出值在这里即为设定速度-实际测量速度,然后经过PID算法给到电流环
在这里,由于我们没有用电流采集,因此将输出值给到电压Uq

case Type_velocity:
			// velocity set point
      shaft_velocity_sp = new_target;
      // calculate the torque command
      current_sp = PID_velocity(shaft_velocity_sp - shaft_velocity); // if current/foc_current torque control
      // if torque controlled through voltage control 
      if(torque_controller == Type_voltage)
			{
        voltage.q = current_sp;  // use voltage if phase-resistance not provided
        voltage.d = 0;
      }
			break;

c.位置环+速度环+电流环

首先,设定值给到位置设定,那么位置环输出值需要PID算法,
位置环输出值在这里即为设定位置-实际测量位置,然后经过PID算法给到速度环
其次,输出给到速度设定,那么速度环输出值也需要PID算法,
速度环输出值在这里即为速度设定-实际测量速度,然后经过PID算法给到电流环,
最后,由于我们没有用电流采集,因此将输出值给到电压Uq

case Type_angle:
		// angle set point
      shaft_angle_sp = new_target;
      // calculate velocity set point
      shaft_velocity_sp = PID_angle( shaft_angle_sp - shaft_angle );
      // calculate the torque command
      current_sp = PID_velocity(shaft_velocity_sp - shaft_velocity); // if voltage torque control
      // if torque controlled through voltage  
      if(torque_controller == Type_voltage)
			{
				voltage.q = current_sp;
        voltage.d = 0;
      }
			break;

4、park逆变换

将park变换逆变换即可:
请添加图片描述

5、SVPWM

FOC最终的执行部分,接收FOC传来的Uα 和Uβ,然后通过上面的过程转换成开关管的控制信号,控制定子绕组产生旋转磁场。

a.三项电压表达(SimpleFOC不用)

请添加图片描述
从上图可知,我们可以通过互差120度,大小随着时间按正弦规律变化的3个分矢量来合成一个大小不变旋转的总矢量。于是问题又变成了:如何得到大小随着时间按正弦规律变化的3个分矢量呢?我们先回到电机上,其实这3个分矢量就对应了电机的3个绕组,3个绕组就是互差120度的,只要再控制绕组上的电压大小按照正弦规律变化,是不是就可以得到大小不变旋转的总矢量呢?看下面电机定子的坐标系图:
请添加图片描述
我们用公式来表示一下:定义这三个电压空间矢量为UA(t)、UB(t)、UC(t),他们方向始终在各自的轴线上,而大小随时间按正弦规律变化,时间相位上互差120度。假设Um为相电压的有效值(相电压呈正弦变化),f为电源频率,则有:
请添加图片描述

请添加图片描述
K为常数,可取不同值,在这里取2/3

请添加图片描述
当开关Sa=1时,UA(t)=Udc(A相相线通过上桥臂直通母线Udc);当开关Sb=1时,UB(t)=Udc;当开关Sc=1时,UC(t)=Udc。

当开关Sa=0时,UA(t)=0(A相相线通过下桥臂直通GND);当开关Sb=0时,UB(t)=0;当开关Sc=0时,UC(t)=0。

这样,合成矢量的关系式就变成了桥臂的开关函数,因此上式可以写成:

请添加图片描述
这里是三项电压,可是输入给我们的只有两项电压,因此,需要转换。

b.两项电压表达

请添加图片描述
请添加图片描述
请添加图片描述
同理可求得Uref在其它扇区中各矢量的作用时间,结果如表2-4所示。表中两个非零矢量作用时间的比例系数为K =√3Ts/Udc 。
请添加图片描述

当两个零电压矢量作用时间为0时,一个PWM周期内非零电压矢量的作用时间最长,此时的合成空间电压矢量幅值最大,由下图2-12可知其幅值最大不会超过图中所示的正六边形边界。而当合成矢量落在该边界之外时,将发生过调制,逆变器输出电压波形将发生失真。
在SVPWM调制模式下,逆变器能够输出的最大不失真圆形旋转电压矢量为图2-12所示虚线正六边形的内切圆,
其幅值为:

 (3/ 2)x(2Udc/ 3) =3Udc/3

即逆变器输出的不失真最大正弦相电压幅值为√3Udc /3 ,
因此voltage_limit的设置即为12*1.7/3=6.9,最大值需要小于6.9

	voltage_limit=4;           //V,最大值需小于12/1.732=6.9

voltage_power_supply的设置,驱动供电,驱动芯片我的设置12V
Udc值设置为:

voltage_power_supply=12;   //V

代码Uout的设置,,前文提到,我们只用Uq,因此就看else后面的就可以了,

	if(Ud) // only if Ud and Uq set 
	{// _sqrt is an approx of sqrt (3-4% error)
		Uout = _sqrt(Ud*Ud + Uq*Uq) / voltage_power_supply;
		// angle normalisation in between 0 and 2pi
		// only necessary if using _sin and _cos - approximation functions
		angle_el = _normalizeAngle(angle_el + atan2(Uq, Ud));
	}
	else
	{// only Uq available - no need for atan2 and sqrt
		Uout = Uq / voltage_power_supply;
		// angle normalisation in between 0 and 2pi
		// only necessary if using _sin and _cos - approximation functions
		angle_el = _normalizeAngle(angle_el + _PI_2);
	}

c.找扇区

空间矢量调制的第一步是判断由Uα 和Uβ所决定的空间电压矢量所处的扇区。
假定合成的电压矢量落在第 I 扇区,
可知其等价条件如下:

   0<arctan(/) <60

落在第 I 扇区的充分必要条件为:

> 0 ,Uβ  > 0 且Uβ/<3

同理可得到合成的电压矢量落在其它扇区的等价条件,得出:

Uref落在第Ⅱ扇区的充要条件为:Uβ>0 且Uβ/ Ua>3;
Uref落在第Ⅲ扇区的充要条件为:Ua<0 ,Uβ> 0-/Ua  <3;
Uref落在第Ⅳ扇区的充要条件为:Ua<0 ,Uβ  < 0 且Uβ/Ua  <3;
Uref落在第Ⅴ扇区的充要条件为:Uβ<0-/Ua>3;
Uref落在第Ⅵ扇区的充要条件为:Ua>0 ,Uβ<0-/Ua  <3

请添加图片描述
再定义,

若U1 > 0 ,则 A=1,否则 A=0; 
若U2 > 0 ,则B=1,否则 B=0;
若U3 > 0 ,则 C=1,否则 C=0

可以看出 A,B,C 之间共有八种组合,但由判断扇区的公式可知 A,B,C 不会同时为 1 或同时为 0,所以实际的组合是六种,A,B,C 组合取不同的值对应着不同的扇区,并且是一一对应的,因此完全可以由 A,B,C 的组合判断所在的扇区。为区别六种状态,令

  N=4*C+2*B+A,

代码:通过角度计算当前扇区:

sector = (angle_el / _PI_3) + 1;

则可以通过下表计算参考电压矢量Uref所在的扇区。
请添加图片描述

d.套公式(任意矢量)

请添加图片描述
请添加图片描述
对照矢量图,可总结

请添加图片描述
Udc表示电源电压(在代码中是voltage_limit),Uref表示设置的力矩大小(在代码中是target_voltage),Ts表示PWM周期(代码中没有把Ts体现出来,代码中的T1、T2是周期的百分比)。
代码Udc的设置

代码:将T1(Tx)、T2(Ty)、T0的值表示出来

	T1 = _SQRT3*_sin(sector*_PI_3 - angle_el) * Uout;
	T2 = _SQRT3*_sin(angle_el - (sector-1.0)*_PI_3) * Uout;
	T0 = 1 - T1 - T2;

至此,PWM波周期的百分比就找出来了
————————————————————————————————

如图当合成电压矢量端点落在正六边形与外接圆之间时,已发生过调制,输出电压将发生失真,必须采取过调制处理,这里采用一种比例缩小算法。
在每一个扇区,选择相邻两个电压矢量以及零矢量,按照伏秒平衡原则来合成每个扇区内的任意电压矢量,即:

定义每个扇区中先发生的矢量用为Tx,后发生的矢量为 Ty。
当 Tx+Ty≤TS时,矢量端点在正六边形之内,不发生过调制;当Tx+Ty>TS时,矢量端点超出正六边形,发生过调制。输出的波形会出现严重的失真,需采取以下措施:
设将电压矢量端点轨迹端点拉回至正六边形内切圆内时两非零矢量作用时间分别为 Tx’,Ty’,则有比例关系:
请添加图片描述
使用上面的简单比例关系,把两个非零矢量作用时间矫正好。请添加图片描述

代码:找到扇区后,再代入到每个扇区的公式:

	switch(sector)
	{
		case 1:
			Ta = T1 + T2 + T0/2;
			Tb = T2 + T0/2;
			Tc = T0/2;
			break;
		case 2:
			Ta = T1 +  T0/2;
			Tb = T1 + T2 + T0/2;
			Tc = T0/2;
			break;
		case 3:
			Ta = T0/2;
			Tb = T1 + T2 + T0/2;
			Tc = T2 + T0/2;
			break;
		case 4:
			Ta = T0/2;
			Tb = T1+ T0/2;
			Tc = T1 + T2 + T0/2;
			break;
		case 5:
			Ta = T2 + T0/2;
			Tb = T0/2;
			Tc = T1 + T2 + T0/2;
			break;
		case 6:
			Ta = T1 + T2 + T0/2;
			Tb = T0/2;
			Tc = T1 + T0/2;
			break;
		default:  // possible error state
			Ta = 0;
			Tb = 0;
			Tc = 0;
	}

e.输出至寄存器

	TIM_SetCompare1(TIM2,Ta*PWM_Period);
	TIM_SetCompare2(TIM2,Tb*PWM_Period);
	TIM_SetCompare3(TIM2,Tc*PWM_Period);

四、参考资料

FOC之SVPWM学习笔记-优快云博客
深入浅出讲解FOC算法与SVPWM技术-稚晖君
SVPWM分析、各个扇区详细计算以及Matlab仿真-优快云博客
SimpleFOC(八)—— 理论+实践 深度分析SVPWM
SVPWM算法原理及详解

总结

本文仅仅简单介绍了FOC无刷电机控制(FOC算法篇)方面,评论区欢迎讨论。

### 永磁同步电机(PMSM)磁场定向控制(FOC) 控制框图 磁场定向控制(Field-Oriented Control, FOC),也称为矢量控制,是一种用于优化永磁同步电机性能的技术。通过调整定子电流的幅度和相位,使产生的磁场与转子磁场保持正交关系,从而实现最大化的扭矩输出[^1]。 #### FOC控制系统的主要组成部分 1. **坐标变换模块** - 将三相静止坐标系下的电流转换到两相同步旋转坐标系下(即d-q轴)。这一步骤通常采用Clarke变换和Park变换来完成。 2. **速度控制器** - 接收实际转速反馈信号并与设定的目标转速比较后计算出所需的电磁转矩指令值。 3. **电流调节器** - 对应于d轴和q轴分别设置独立的比例积分(PI)控制器,用来精确地跟踪期望的直流分量id* 和iq* ,进而得到逆变器所需施加给电机绕组上的电压命令vdref 及vqref 。 4. **反向坐标变换模块** - 把经过处理后的直流量重新映射回原始的ABC三相交流系统中去驱动功率器件工作。 5. **位置传感器/无感估算单元** - 提供实时的位置信息以便准确执行上述各项操作;对于某些应用场合也可以利用软件算法代替硬件传感装置来进行估计。 6. **PWM调制环节** - 根据最终获得的参考电压波形产生合适的脉宽调制信号以控制开关元件的动作频率及时序安排。 ```python # Python伪代码表示部分功能逻辑 def fock_control_system(): # 坐标变换过程简化示意 i_alpha_beta = clarke_transform(i_a, i_b) id_iq = park_transform(i_alpha_beta) # PI调节器示例 (仅展示概念) v_d_ref = pi_controller(id_setpoint, id_measured) v_q_ref = pi_controller(iq_setpoint, iq_measured) # 返回至原坐标系并生成PWM信号 pwm_signals = generate_pwm(inverse_park(v_d_ref, v_q_ref)) return pwm_signals ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kisorge

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值