foc进阶篇3——对比PLL测速,为M法加低通正名

foc进阶篇3------对比PLL测速,为M法加低通正名

相信大部分人在刚开始接触编码器时,对电机的转速获取基本都是使用M法测速加低通滤波的方式。但随着工作学习的不断深入,会逐渐听到有人说PLL测速更好,诸如什么"pll是观测器"、"pll的积分环节会让数据更平滑"等理由。于是自己也开始使用pll测速,似乎是比M法低通更好,但具体好在哪里又说不清楚。

不过今天我就直接告诉大家,有些结构的PLL测速是可以和M法加IIR低通完全等效的,而有些还不如M法加低通。破除迷信,为M法测速加低通滤波正名。

注:本文所述的PLL仅针对有感的编码器测速,并不涉及电角度滤波更不涉及无感的电角度获取。

1.经典结构的PLL测速


结论:由于这种结构的pll传递函数并不是标准的二阶弹簧阻尼的形式,因此即使阻尼比设置为1也仍然会过冲。不建议将它用到速度环的反馈中。

2. 纯P环节的PLL测速

结论:不难发现,纯P环节的PLL测速其实就相当于一阶低通滤波,时间常数为(1/kp)。

3. 仅引出积分项的PLL测速

结论:这种结构的PLL测速就相当于二阶低通滤波,可以通过设置kp、ki来修改ωn和ζ。而对于ζ=1的特例,也可以将两个一阶低通串联达到相同的效果。

4.纯p环节PLL和引出积分项PLL对比

(1)阶跃响应对比

(2)噪声抑制对比

结论:不难发现,在ωn一样的情况下,引出积分项的pll更加平滑但也更加滞后(其实就是二阶低通对比一阶低通)。

注:以上全部实验都是基于连续模型,只是为了给大家一个感性认识。实际跑在单片机上是离散的,对于ωn等参数不可以直接等效而是需要换算。

5.代码实测

(1)三种PLL的对比

首先定义三种pll及函数(注意,这些pll测的速度是电角速度,单位rad/s。实际使用将其转化为机械转速,单位RPM)

c 复制代码
#define		DT					0.00005f
#define		PI_F				3.14159265359f

#define		WN					1000.0f
#define		ZETA				1.0f

struct PLL_TYPE
{
	float32_t kp, ki;
	float32_t I;	
	float32_t angle, speed;	
};

/*经典结构PLL*/
struct PLL_TYPE pll = {
    .kp = 2.0f * WN * ZETA,
    .ki = WN * WN
};
/*纯P环节PLL*/
struct PLL_TYPE pll_p = {
    .kp = 2.0f * WN * ZETA,
};
/*引出积分项PLL*/
struct PLL_TYPE pll_i = {
    .kp = 2.0f * WN * ZETA,
    .ki = WN * WN
};

/*经典结构PLL*/
void PLL_Get(struct PLL_TYPE *pll, float32_t angleIn)
{
	float32_t error = angleIn - pll->angle;
	
	if(error > PI_F)
		error -= PI_F * 2.0f;
	else if(error < -PI_F)
		error += PI_F * 2.0f;	
	
	pll->I += pll->ki * error * DT;
    pll->speed = pll->kp * error + I;
    
	pll->angle += pll->speed * DT;	
	
	if(pll->angle > PI_F * 2.0f)
		pll->angle -= PI_F * 2.0f;
	else if(pll->angle < 0.0f)
		pll->angle += PI_F * 2.0f;
}
/*纯P环节PLL*/
void PLL_P_Get(struct PLL_TYPE *pll, float32_t angleIn)
{
	float32_t error = angleIn - pll->angle;
	
	if(error > PI_F)
		error -= PI_F * 2.0f;
	else if(error < -PI_F)
		error += PI_F * 2.0f;	
	
    pll->speed = pll->kp * error;
    
	pll->angle += pll->speed * DT;	
	
	if(pll->angle > PI_F * 2.0f)
		pll->angle -= PI_F * 2.0f;
	else if(pll->angle < 0.0f)
		pll->angle += PI_F * 2.0f;
}
/*引出积分项PLL*/
void PLL_I_Get(struct PLL_TYPE *pll, float32_t angleIn)
{
	float32_t error = angleIn - pll->angle;
	
	if(error > PI_F)
		error -= PI_F * 2.0f;
	else if(error < -PI_F)
		error += PI_F * 2.0f;	
	
	pll->speed += pll->ki * error * DT;
	
	pll->angle += (pll->speed + pll->kp * error) * DT;	
	
	if(pll->angle > PI_F * 2.0f)
		pll->angle -= PI_F * 2.0f;
	else if(pll->angle < 0.0f)
		pll->angle += PI_F * 2.0f;
}

可以看到,经典pll虽然相位上比较超前,但出现了过冲(由前面仿真得知这个过冲很可能比真实速度更高);纯P环节pll在相位滞后以及毛刺抑制上属于中间水平;引出积分项的pll测速最平滑但也最滞后。

(这里我使用电流环给iq指令让电机加速。三种pll的执行频率都为20kHz,上位机的打印频率为10kHz。)

(2)纯P环节PLL和M法加一阶低通对比

纯P环节pll和M法加低通测速完全重合了,第二张图加了一点Y轴偏置才得以看出。(这里pll的kp=2000,执行频率为20kHz;M法的采样频率和滤波频率也为20kHz,滤波系数为0.1。不知道有没有人发现了什么。)

看到这里,可能会有人疑惑。为什么我的M法测速加低通滤波不是这个效果?其实是采样频率的问题。

6.M法加低通不如PLL的原因

相信大家在学习速度环的时候,大概都听过这样一句话:"由于电机的机械时间常数远大于电气时间常数,所以速度环的执行频率一般是电流环的十分之一"。这里先不评价这句话,但相信大概率会因为听了这句话,选择把M法测速的采样频率也拉到电流环执行频率的十分之一。

这里将M法测速及滤波的频率降低到2kHz,对比20kHz执行频率的纯P环节pll。(这里为了保证低通滤波的截止频率与之前接近,因此滤波系数改为0.526,pll的参数不变。)

发现没有,M法加低通测速的波形变成了阶梯状,并且整体相对pll更滞后一些。(大家也可以尝试使用2kHz采样的M法配合20kHz的滤波,滤波系数为0.1,去对比pll测速。我这里已经试过了,虽然阶梯状没有了,但相比pll还是滞后了。)

还有,这里2kHz采样的M法相比前面20kHz采样的噪声低了很多,并且最左边的点连起来的相位相比pll超前,可不可以用它来做速度反馈?如果你的速度环执行频率也是2k的话,那么确实可以。但请注意,它的数据更新频率也只有2k,如果你后面打算将速度环的执行频率提高到4k、5k甚至10k,那么当中有几次的反馈值都是之前的、不变的。这里我更加建议使用20kHz采样的M法测速加十次滑动平均滤波来代替2kHz采样的M法测速,这样既可以达到相同的噪声水平,又能保证数据的更新频率,而且滞后程度也是一样的(对比2k采样M法最左边的点连起来的线)。

结论:为什么你感觉M法加低通效果不如pll好,就是因为采样频率的问题。你的M法采样频率只有电流环执行频率的十分之一,而pll一般和电流环同频,正是因为这一点导致M法丢失了一些信息。

7.总结

1.经典结构的pll测速在面对阶跃信号或斜率较高的信号会产生虚假过冲,如果将它作为速度环的反馈可能会引起更大的过冲以及振荡,不建议使用。

2.纯p结构的pll测速基本可以等效为M法测速加一阶IIR低通滤波。但是要注意,这种方法不可以用于角度跟踪滤波,因为存在稳态误差(角度滞后)。还有,使用的时候kp要比较大(或者说ωn不能太低),否则电机加速度大会出现失锁的可能,这点与低通滤波不同。

3.仅引出积分项的pll测速基本可以等效为M法测速加二阶IIR低通滤波。

4.M法的采样频率要尽可能的高,不用担心低速时两次采样采不到脉冲增量,只要配合低通滤波即可。但要注意,编码器分辨率越低,低速时的毛刺就越大,如果加大滤波则会引入更多延迟和滞后(这一点PLL也是一样的)。既想要毛刺小又想要延迟滞后少,那就要使用更高分辨率的编码器配合较小的滤波(或者速度观测器,不过这玩意也有局限性)。

5.虽然pll测速可以等效为M法加低通的形式,并且相比M法加低通,pll更容易出现失锁的情况(如果ωn设置过低),但有几个地方是M法加低通不可比拟的。首先它可以在测速的同时给电角度滤波。其次它可以稍加改造变成速度观测器和扰动观测器,这一点后面有机会再说。

参考资料

https://zhuanlan.zhihu.com/p/665627084

https://zhuanlan.zhihu.com/p/366750470

https://github.com/odriverobotics/ODrive

相关推荐
Wallace Zhang2 天前
SimpleFOC源码学习02(v2.3.2) - 低通滤波器lowpass_filter.cpp与lowpass_filter.h
foc
Wallace Zhang2 天前
SimpleFOC源码学习04(v2.3.2) - 数学基础层foc_utils.cpp与foc_utils.h
foc
Wallace Zhang3 天前
SimpleFOC源码学习00(v2.3.2) - 源码版本说明
foc
Wallace Zhang3 天前
SimpleFOC源码学习01(v2.3.2) - PID控制器PID.cpp与PID.h
foc
jdhfusk14 天前
foc进阶篇1——可能比强拖更好的磁编非线性校准
foc·无刷电机控制
沉沙丶21 天前
关于matlab分析电流THD的一些探究和记录
开发语言·matlab·电机控制·foc·永磁同步电机·模型预测·预测控制
沉沙丶23 天前
模型预测控制专题(十二)—— 基于高阶扩展状态观测器HESO的MPFCC
simulink·电机控制·foc·永磁同步电机·pmsm·无模型预测·电流预测控制
沉沙丶23 天前
模型预测控制专题(十一)—— 基于改进型扩张状态观测器MESO的MPFCC
电机控制·foc·永磁同步电机·模型预测·预测控制·pmsm·无模型预测
沉沙丶24 天前
模型预测控制专题(十)—— 现有观测器限制分析
电机控制·foc·永磁同步电机·模型预测·预测控制·pmsm·无模型预测