PID参数自整定库之一:继电反馈整定算法
时间:2022-11-29 14:30:00
??在上述章节中,我们实现了PID控制器并在后续进行了改进。但作为经典PID控制器仍然存在PID参数整定问题。一般来说,我们可以采用人工整定的方法,但人工整定涉及到更专业的知识,找到合适的参数本身并不容易,所以人们探索了一系列适合不同情况的方法PID参数自动整定算法。本文将讨论基于继电反馈的内容PID参数自整定算法。
1、基本原理
??如果测量了系统的一阶模型,或者得到了系统的临界比例增益Kc和振荡周期Tc,设计起来很容易PID调节器。
1.1.继电反馈自整定过程
??继电反馈自整定的基本思想是在控制系统中设置两种模式:整定模式和调整模式。显然,调整模式是指我们正常使用的模式PID控制器,整定模式是我们用来整定的PID参数过程。
??在整定模式下,我们将系统的操作转换为开关模式,即输出值在最大值和最小值之间的周期性转换。具体来说,当测量值小于设定值时,我们将控制器的输出最大,当测量值大于设定值时,我们将输出值设定为最小。这样,被控制系统聚会产生振动。经过至少三次过零检测,我们将得到一个周期的振荡波形。从这个振荡波形中,我们可以提取系统的特征参数,以获得我们想要的PID参数。
??在调整模式下,首先得出系统的特征参数PID控制器的参数,然后使用此PID控制器调整系统。PID参数继电反馈自整定结构图如下:
??我们可以从上图中知道,当需要时PID当参数固定时,开关放置在继电环节中。系统根据继电反馈建立稳定的极限环振荡后,可根据系统响应特性确定PID参数。当自整定计算完成后,我们可以控制开关PID调节器环节,使系统正常进入PID控制过程。
1.2.继电反馈自整定原理
??为什么我们采用这一方式就可以确定PID控制器的参数是什么?这是因为振荡波形的特性是由被控对象的特性决定的。在整定模式下,整个控制系统的框图等效如下:
??当我们根据测量值与设定值的比较给出最大或最小输出时,根据被控对象的特性会产生一定频率和振幅的振荡波,从而确定系统的振荡频率ωc与临界增益Kc。确定系统的振荡频率更为常用ωc与增益Kc描述函数法是一种方法。描述函数法实际上是一种有效的方法,基于非线性链接输入信号与输出信号之间的基波分量关系。
??描述非线性特征的函数N(A)当输入是正弦信号时Asin(ωt)输出的基波分量Ysin(ωt φ)对输入正弦量的复数比,即:
??其中A1、B1是输出Y(t)傅立叶级数的一次项系数。
??具有回环节点非线性环节特性的实际描述函数可以表示为:
??A公式为正弦波幅值,d回环幅值,ε回环宽度的一半。当我们在这里建立继电环节时,我们可以认为它是一个理想的继电环节,即没有回环,即ε=所以有:
??在这里,我们将被控对象的传输函数设置为以下形式:
??以K为对象的增益,T对象的时间常数,τ对象的滞后时间。
??根据前继电回路结构框图,在这个简单的反馈系统中,闭环特征方程振荡的条件可以写为:
1 N(A)G(s)=0 (s=jωc),即G(jωc)=-1/N(A)。
??振荡频率可以得到ωc与增益Kc为:
??系统振荡周期Tc可通过测量输出曲线相邻峰值的时间获得。到目前为止,我们已经获得了临界频率ωc相应的临界增益和临界振荡周期。
??在获得被控对象的临界增益和临界振荡周期后,可以根据Ziegle-Nichols算法确定PID参数。如表所示:
??这样,就用继电反馈的方法整定出了PID调节器参数。PID参数继电自整定法是一种简单的自适应控制方法,数据量小,实现简单,调节效果好,特别适用于内存小的调节器,应用广泛。
2、算法设计
??我们已经明白了PID参数继电反馈自整定的基本原理,那么如何实现呢?接下来,我们将基于继电反馈进行设计PID具体实现算法的参数自整定。
??采用继电反馈方法整定PID参数主要涉及两个方面。一是通过人工操作使系统产生临界振荡,测量临界比例Kc和临界周期Tc的根本所在。第二是根据得到的数据计算PID参数值。因此,我们从这两个方面考虑继电反馈PID参数整定算法。
2.1.产生振荡
??首先,让我们分析一下如何产生振荡波形。在继电反馈中,振荡是通过控制执行单元以一定的输出比来回转换的,而测量值随之振荡。因此,在我们在系统中给出设定值后,我们根据设定值和测量值之间的偏差来决定输出值是正的还是反的。
??在这里,我考虑了执行单元的积极作用。一般来说,当设定值大于测量值时,我们将执行单元的输出切换到相应的高输出,然后测量值就会上升。当测量值上升到大于设定值时,我们将执行单元的输出切换到相应的低输出,然后测量值就会下降。这样,我们就可以得到测量值的振荡曲线。
??每次切换执行单元时,我们记录一次转换次数。同时,观察测量值和设定值的相对大小。每个测量值被称为一次过零,从大于设定值到小于设定值,或者从小于设定值到大于设定值。如果我们检测到4次过零或5次切换执行单元,我们可以认为系统振荡。
??进一步考虑,我们发现测量值和设定值的相对位置对我们的判断有关键影响。如果初始测量值大于设定值,则最大值将出现在两次过零后,如下图所示的区域3。最小值将出现在3次过零后,如下图所示的区域4。
??如果初始测量值小于设定值,则最小值将在两次过零后出现,如下图所示。最大值将在3次过零后出现,如下图所示。
??通过以上图例,我们可以知道四次检测可以有两个波形,可以确认系统已经振荡。此外,我们还可以获得由图中区域3和区域4组成的完整稳定的波形周期。通过这些数据,我们可以得到振荡波形周期Tc振荡波形的振幅值。这些数据是我们计算所需要的。
2.2、参数计算
??在上述振荡波型的测量中,我们得到了最大值和最小值,而波形的振幅值是最大差的一半,因此我们得到了振幅值A。我们将最大值几位PVmax,最小值几位PVmin就可以得到Kc计算公式如下:
K_c=4d/πA=8d/(π*(PV_max-PV_min))
??在测量过程中,我们在2次过零后记录了周期的开始时间。我们在4次过零后记录了周期的结束时间,因此我们可以利用结束时间与开始时间的间隔和采样周期来获得振荡周期。
T_c=(T_end-T_start )*T_s
??在上述两个公式中,Ts对于整个过程中的采样周期,d是我们输出切换的差值,是我们已知的数据。这可以基于Ziegle-Nichols公式计算对应PID参数了。
实现算法的实现
??基于继电反馈于继电反馈的基础PID我们将根据上述算法分析实现参数自整定的基本算法。根据上述算法分析,我们了解到,在产生振荡和测量数据时,由于初始偏差的正负不同,需要区分不同状态下的处理。此外,整合成功和整合失败也将有不同的操作。
3.1.定义相关变量
??通过前面的分析,我们知道实现整个过程需要大量的变量控制和记录。为了便于管理这些变量,我们使用结构来统一处理这些变量。经过分析,我们定义了控制变量结构的整个过程如下:
/*定义整个过程中变量结构的类型*/ typedef struct TuneObject { uint8_t tuneEnable:2; //整定与PID控制开关,0:PID控制;1:参数整定;2:整定失败; uint8_t preEnable:2; ///预处理使能,前置位置开始整定 uint8_t initialStatus:1; ///记录开始确定前偏差的初始状态 uint8_t outputStatus:1; //记录输出的初始状态,0允许上升过零计数;1允许下降过零计数; uint8_t controllerType:2; //控制器类型:0,P控制器;1,PI控制器;2,PID控制器 uint8_t zeroAcrossCounter; //过零点计数器,每次输出变化加1,比实际过零次数多1次 uint8_t riseLagCounter; ///上升迟滞时间计数器 uint8_t fallLagCounter; // uint16_t tunePeriod; //整定采样周期 uint32_t tuneTimer; ///整定计时器 uint32_t startTime; ///记录波形周期的开始时间 uint32_t endTime; ///记录波形周期的结束时间 float outputStep; ///输出阶跃d float maxPV; //振荡波形中测量值的最大值 float minPV; ////振荡波形中测量值的最小值 }TuneObjectType;
3.2、整定前期处理
??正如我们前面所说,设定值和测量值的相对位置对于判断过程非常重要,所以我们应该在整个过程开始前识别它。此外,一些控制变量也需要在整个开始前设置,所以我设计一个预处理的过程来完成这些前期的工作。
/*整定开始前的预处理,判断状态及初始化变量*/
static void TunePretreatment(CLASSICPID *vPID,TuneObjectType *tune)
{
tune->maxPV=vPID->minimum;
tune->minPV=vPID->maximum;
tune->tuneTimer=0;
tune->startTime=0;
tune->endTime=0;
tune->outputStep=100;
if(*vPID->pSV>=*vPID->pPV)
{
tune->initialStatus=1;
tune->outputStatus=0;
}
else
{
tune->initialStatus=0;
tune->outputStatus=1;
}
tune->preEnable=0;
tune->zeroAcrossCounter=0;
tune->riseLagCounter=0;
tune->fallLagCounter=0;
}
3.3、整定过程的控制
整定过程的控制就是实现整个整定过程的各种操作。包括对输出高低转换的控制、对形成振荡后对第二个波形的数据记录、整定成功后的相关处理以及整定失败后的相关处理等。
void RelayFeedbackAutoTuning(CLASSICPID *vPID,TuneObjectType *tune)
{
/*整定开始前的预处理,只执行一次*/
if(tune->preEnable==1)
{
TunePretreatment(vPID,tune);
}
uint32_t tuneDuration=0;
tune->tuneTimer++;
tuneDuration=(tune->tuneTimer*tune->tunePeriod)/1000;
if(tuneDuration>3600) //整定过程持续超过1小时,未能形成有效振荡,整定失败
{
tune->tuneEnable=2;
tune->preEnable=1;
return;
}
if(*vPID->pSV>=*vPID->pPV) //设定值大于测量值,则开执行单元
{
tune->riseLagCounter++;
tune->fallLagCounter=0;
if(tune->riseLagCounter>LAG_PHASE)
{
*vPID->pMV=100;
if(tune->outputStatus==0)
{
tune->outputStatus=1;
tune->zeroAcrossCounter++;
if(tune->zeroAcrossCounter==3)
{
tune->startTime=tune->tuneTimer;
}
}
}
}
else //设定值小于测量值,则关执行单元
{
tune->riseLagCounter=0;
tune->fallLagCounter++;
if(tune->fallLagCounter>LAG_PHASE)
{
*vPID->pMV=0;
if(tune->outputStatus==1)
{
tune->outputStatus=0;
tune->zeroAcrossCounter++;
if(tune->zeroAcrossCounter==3)
{
tune->startTime=tune->tuneTimer;
}
}
}
}
if(tune->zeroAcrossCounter==3) //已经两次过零,可以记录波形数据
{
if(tune->initialStatus==1) //初始设定值大于测量值,则区域3出现最小值
{
if(*vPID->pPVminPV)
{
tune->minPV=*vPID->pPV;
}
}
else if(tune->initialStatus==0) //初始设定值小于测量值,则区域3出现最大值
{
if(*vPID->pPV>tune->maxPV)
{
tune->maxPV=*vPID->pPV;
}
}
}
else if(tune->zeroAcrossCounter==4) //已经三次过零,记录另半波的数据
{
if(tune->initialStatus==1) //初始设定值大于测量值,则区域4出现最大值
{
if(*vPID->pPV>tune->maxPV)
{
tune->maxPV=*vPID->pPV;
}
}
else if(tune->initialStatus==0) //初始设定值小于测量值,则区域4出现最小值
{
if(*vPID->pPVminPV)
{
tune->minPV=*vPID->pPV;
}
}
}
else if(tune->zeroAcrossCounter==5) //已经四次过零,振荡已形成可以整定参数
{
CalculationParameters(vPID,tune);
tune->tuneEnable=0;
tune->preEnable=1;
}
}
3.4、参数的计算
当整定过程实现4次过零后,说明整定成功能,这时我们需要根据我们测量到的数据计算PID参数。具体的计算公式在前面已经详细描述过了。根据公式可以实现编码如下:
/*计算PID参数值*/
static void CalculationParameters(CLASSICPID *vPID,TuneObjectType *tune)
{
float kc=0.0;
float tc=0.0;
float zn[3][3]={
{0.5,100000.0,0.0},{0.45,0.8,0.0},{0.6,0.5,0.125}};
tc=(tune->endTime-tune->startTime)*tune->tunePeriod/1000.0;
kc=(8.0*tune->outputStep)/(PI*(tune->maxPV-tune->minPV));
#if PID_PARAMETER_STYLE > (0)
*vPID->pKp=zn[tune->controllerType][0]*kc; //比例系数
*vPID->pKi=*vPID->pKp*tune->tunePeriod/(zn[tune->controllerType][1]*tc); //积分系数
*vPID->pKd=*vPID->pKp*zn[tune->controllerType][2]*tc/tune->tunePeriod; //微分系数
#else
*vPID->pPb=100/(zn[tune->controllerType][0]*kc); //比例带
*vPID->pTi=zn[tune->controllerType][1]*tc; //积分时间
*vPID->pTd=zn[tune->controllerType][2]*tc; //微分时间
#endif
}
4、应用与结论
本篇中我们设计并实现了基于一种继电反馈方法的PID参数自整定的过程。在使用中,我们需要基于整定结构体声明一个变量用于整个过程的控制。该变量定义后,成员变量tuneEnable、preEnable和controllerType需要提前赋值。tuneEnable变量值为0时是使用PID控制器,而tuneEnable变量值为1时是开启整定过程,当tuneEnable变量值为2时是指示整定失败。preEnable变量在整定前赋值为1,表示先做预处理。而controllerType则根据所整定的控制器的类型来定,主要用于参数的计算。
使用此方法时需要注意,对于那些不允许产生波动的控制对象采用此法是不合适的。特别是一些工业现场,大幅度的波动本身就是不被允许的。但对于一些如嵌入式的小系统,简单回路的PID控制系统此法是可行的。
此方法适用于自平衡系统对象,对于非自平衡对象将不能达到相应的效果。更多的时候不会引起有小的振荡,没有办法通过此方法得到PID参数。