前言

【控制】三种PID形式(3)_位置式PID即:Proportional(比例)、Integral(积分)、Differential(微分)的缩写。

顾名思义,【控制】三种PID形式(3)_位置式PID控制算法是结合比例、积分和微分三种环节于一体的控制算法,它是连续系统中技术最为成熟、应用最为广泛的一种控制算法,该控制算法出现于20世纪30至40年代,适用于对被控对象模型了解不清的场合。

实际运行的经验和理论的分析都表明,运用这种控制规律对许多工业过程进行控制时,都能得到比较满意的效果。PID控制的实质就是根据输入的偏差值,按照比例、积分、微分的函数关系进行运算,运算结果用以控制输出。

【控制】三种PID形式(3)_增量式PID_03

【控制】三种PID形式(3)_增量式PID_04

PID公式:

【控制】三种PID形式(3)_专家PID_05,其中

【控制】三种PID形式(3)_位置式PID_06:控制器输出的控制量

【控制】三种PID形式(3)_专家PID_07:偏差信号,它等于给定量与输出量之差

【控制】三种PID形式(3)_位置式PID_08:比例系数

【控制】三种PID形式(3)_位置式PID_09:积分时间系数

【控制】三种PID形式(3)_位置式PID_10:微分时间常数​

1 位置式PID

位置式pid公式

【控制】三种PID形式(3)_位置式PID_11

【控制】三种PID形式(3)_增量式PID_12

【控制】三种PID形式(3)_专家PID_13用户设定的目标值 - 控制对象当前状态值 ,即偏差量

比例【控制】三种PID形式(3)_专家PID_14【控制】三种PID形式(3)_专家PID_15

积分【控制】三种PID形式(3)_位置式PID_16

微分【控制】三种PID形式(3)_位置式PID_17,即此次偏差【控制】三种PID形式(3)_专家PID_18上次偏差

因为有偏差积分【控制】三种PID形式(3)_位置式PID_19,一直累加,也就是说当前的控制【控制】三种PID形式(3)_位置式PID_20与过去的所有状态都有关系,输出【控制】三种PID形式(3)_位置式PID_20对应的是执行机构实际的位置,也就是说,一旦控制输出出错,【控制】三种PID形式(3)_位置式PID_20的变化会引起系统的大幅变化。

并且位置式【控制】三种PID形式(3)_位置式PID在积分项逐渐饱和的过程中,偏差依然会在积分作用下累加,一旦偏差开始反向变化(偏差量【控制】三种PID形式(3)_专家PID_13取反),系统则需要一定时间从饱和区退出,所以要有积分限幅(设定积分项的上限和下限)和输出限幅(设定输出量【控制】三种PID形式(3)_位置式PID_20的上限和下限)

PID调节的具体过程

不同参数下的pid实现过程:

【控制】三种PID形式(3)_位置式PID_26

【控制】三种PID形式(3)_专家PID_27

代码实现

//PID算法的实现

int32 PID_Realize(PID *sptr, float *PID, int32 NowData, int32 Point)
{
//当前误差,定义为寄存器变量,只能用于整型和字符型变量,提高运算速度
int32 iError; // 当前误差
float Realize; // 最后得出的实际增量
iError = Point - NowData; // 计算当前误差 设定减当前
sptr->SumError += PID[KI] * iError; // 误差积分
sptr->SumError = limit(sptr->SumError, PID[KT]);//积分限幅
Realize = PID[KP] * iError
+ sptr->SumError
+ PID[KD] * (iError - sptr->LastError);//P项 I项 D项 相加
sptr->PrevError = sptr->LastError; // 更新前次误差
sptr->LastError = iError; // 更新上次误差
sptr->LastData = NowData; // 更新上次数据
return Realize; // 返回实际值
}

2 增量式PID

 增量式PID控制,数字PID控制算法的一种基本形式,是通过对控制量的增量(本次控制量和上次控制量的差值)进行PID控制的一种控制算法。和位置式PID控制不同,增量式PID控制将当前时刻的控制量和上一时刻的控制量做差,以差值为新的控制量,是一种递推式的算法。

增量式pid公式

【控制】三种PID形式(3)_位置式PID_28

【控制】三种PID形式(3)_增量式PID_29

上面公式有位置式PID公式推导而来。

输出【控制】三种PID形式(3)_位置式PID_20:表示输出位置增量

比例项【控制】三种PID形式(3)_专家PID_14【控制】三种PID形式(3)_位置式PID_32,表示此次偏差减去上次偏差,即偏差的变化量,比例系数为【控制】三种PID形式(3)_位置式PID_08

积分项【控制】三种PID形式(3)_增量式PID_34【控制】三种PID形式(3)_专家PID_13表示此次的偏差量,积分系数为【控制】三种PID形式(3)_位置式PID_36

微分项【控制】三种PID形式(3)_增量式PID_37【控制】三种PID形式(3)_位置式PID_38表示当前【控制】三种PID形式(3)_增量式PID_39偏差减去前一刻【控制】三种PID形式(3)_增量式PID_40偏差再加上前前一刻【控制】三种PID形式(3)_增量式PID_41次偏差,即偏差变化量的变化量,微分系数为【控制】三种PID形式(3)_增量式PID_42

     增量式【控制】三种PID形式(3)_位置式PID根据公式可以很好地看出,一旦确定了三个系数【控制】三种PID形式(3)_位置式PID_44,只要使用近三次测量值与实际目标值的偏差,即可由上面的公式求出最终的控制增量。而得出的控制增量【控制】三种PID形式(3)_位置式PID_20没有偏差的累加作用,控制增量【控制】三种PID形式(3)_位置式PID_20仅与近几次偏差的测量值有关,容易通过加权处理得到较好的控制效果,在系统出现问题时,增量式【控制】三种PID形式(3)_位置式PID不会严重影响系统的工作。

优缺点

优点:

1.出错时影响较小,必要时可以通过逻辑判断的方法去掉出错数据

2.算式中不需要累加,控制增量u(k)仅与近三次偏差测量值有关

缺点:

 积分截断效应大,控制时存在稳态误差。(尚待诠释)

代码实现

实践出真知,纸上得来终觉浅,任何公式没有实践也没有意义,最重要的还是要根据公式把代码写出来。

typedef struct                     
{
float Kp; //比例系数Proportional
float Ki; //积分系数Integral
float Kd; //微分系数Derivative
float Ek; //当前误差
float Ek1; //上一次误差 e(k-1)
float Ek2; //上上一次误差 e(k-2)
}PID_IncTypeDef;

/************************************************
函数名称 :PID_Inc
功 能 :PID增量(Increment)计算
参 数 :SetValue ------ 设置值(期望值)
ActualValue --- 实际值(反馈值)
PID ----------- PID结构体指针
返 回 值 :PIDInc -------- 本次PID增量(+/-)
*************************************************/
float PID_Inc(float SetValue, float ActualValue, PID_IncTypeDef *PID)
{
float PIDInc; //增量
PID->Ek = SetValue - ActualValue;
float PID_P; //P项
float PID_I; //I项
float PID_D; //D项
PID_P = PID->Kp*(PID->Ek - PID->Ek1);
PID_I = PID->Ki*PID->Ek;
PID_D = PID->Kd*(PID->Ek -2*PID->Ek1 + PID->Ek2);
PIDInc= PID_P+PID_I+PID_D; //三项相加
PID->Ek2 = PID->Ek1; //更新上上次偏差
PID->Ek1 = PID->Ek; //更新上次偏差
return PIDInc;
}

3 专家PID

实际生活中,存在许多无法用数学模型或计算解决的问题,专家一般根据自己丰富的知识和经验进行推理从而解决问题。而专家PID控制正是模仿这一特点设计的。

实现过程

【控制】三种PID形式(3)_专家PID_48

Ⅰ、Ⅲ、Ⅴ、 Ⅶ,...区域:误差向绝对值减小的方向变化。此时,可采取保持等待措施,相当于实施开环控制;

Ⅱ、Ⅳ、Ⅵ、Ⅷ,...区域:误差绝对值朝增大的方向变化。此时,可根据误差的大小分别实施较强或一般的控制作用,以抑制动态误差。

【控制】三种PID形式(3)_专家PID_13表示离散化的当前采样时刻的误差值,【控制】三种PID形式(3)_位置式PID_50分别表示前一个和前两个采样时刻的误差值,则有:

根据误差及其变化,可设计专家PID控制器,该控制器可分为以下五种情况进行设计:

(1)当【控制】三种PID形式(3)_增量式PID_51时,说明误差的绝对值已经很大。不论误差变化趋势如何,都应考虑控制器的输出应按最大(或最小)输出,以达到迅速调整误差,使误差绝对值以最大速度减小。此时,它相当于实施开环控制。

(2)当【控制】三种PID形式(3)_位置式PID_52时,说明误差在朝误差绝对值增大方向变化,或误差为某一常值,未发生变化。

此时,如果【控制】三种PID形式(3)_增量式PID_53,说明误差也较大,可考虑由控制器实施较强的控制作用,以达到扭转误差绝对值朝减小方向变化,并迅速减小误差的绝对值,控制器输出为:

【控制】三种PID形式(3)_专家PID_54

如果【控制】三种PID形式(3)_专家PID_55,说明尽管误差朝绝对值增大方向变化,但误差绝对值本身并不很大,可考虑控制器实施一般的控制作用,只要扭转误差的变化趋势,使其朝误差绝对值减小方向变化,控制器输出为

【控制】三种PID形式(3)_专家PID_56

(3)当【控制】三种PID形式(3)_位置式PID_57时,说明误差的绝对值朝减小的方向变化,或者已经达到平衡状态。此时,可考虑采取保持控制器输出不变。

(4)当【控制】三种PID形式(3)_专家PID_58时,说明误差处于极值状态。如果此时误差的绝对值较大,即【控制】三种PID形式(3)_增量式PID_53 ,可考虑实施较强的控制作用。

【控制】三种PID形式(3)_位置式PID_60

如果此时误差的绝对值较小,即【控制】三种PID形式(3)_专家PID_55,可考虑实施较弱的控制作用

【控制】三种PID形式(3)_专家PID_62

(5)当【控制】三种PID形式(3)_增量式PID_63时,说明误差的绝对值很小,此时加入积分,减少稳态误差。

以上各式中:

【控制】三种PID形式(3)_专家PID_64为误差【控制】三种PID形式(3)_专家PID_65的第【控制】三种PID形式(3)_专家PID_66个极值;

【控制】三种PID形式(3)_位置式PID_20为第【控制】三种PID形式(3)_专家PID_66次控制器的输出;

【控制】三种PID形式(3)_位置式PID_69为增益放大系数,【控制】三种PID形式(3)_增量式PID_70;

【控制】三种PID形式(3)_专家PID_71为抑制系数,【控制】三种PID形式(3)_专家PID_72;

【控制】三种PID形式(3)_专家PID_73为设定的误差界限,【控制】三种PID形式(3)_专家PID_74

【控制】三种PID形式(3)_专家PID_66为控制周期;

【控制】三种PID形式(3)_位置式PID_76为任意小的正实数。

代码实现

typedef struct PID               //PID结构体
{ int32 kp; //参数kp,ki,kd
int32 ki;
int32 kd;
int32 LastError; // 上次误差
int32 PrevError; // 预测误差
int32 LastData; // 上次数据
int16 errorabsmax; //设定误差绝对值最大值
int16 errorabsmid; //设定误差绝对值中值
int16 errorabsmin; //设定误差绝对值最小值
int16 maximum; //设定输出值上限
int16 minimum; //设定输出值下限
} PID;


//************************* 专家PID控制**************************
/*
函数:int32 Expert_PID_Realize(PID *sptr,int32 NowData, int32 Point)
功能:专家PID控制
参数:
PID *sprt:结构体指针
int32 NowData 当前值 (可使用结构体定义变量)
int32 Point 设定目标值 (可使用结构体定义变量)
说明:该函数参考其他程序。
返回值:int32 Realize
*/
int32 Expert_PID_Realize(PID *sptr, int32 NowData, int32 Point)
{
int32 iError,ider_Error,Lastder_Error;
int16 k1=0;
int16 K1=0;
int16 K2=0;
int32 Realize;
iError = Point - NowData;
// 计算当前误差 设定目标值减当前实际值
ider_Error=iError-sptr->LastError;
//计算当前误差变化量
Lastder_Error=sptr->LastError-sptr->PrevError;
//计算上次误差变化量
if(abs(iError)>sptr->errorabsmax)
//规则1 误差绝对值大于设定误差绝对值最大值
{
if(iError>0)
{
Realize=sptr->maximum; //最大输出
}
if(iError<0)
{
Realize=sptr->minimum;
}
}
if(abs(iError)<=sptr->errorabsmax)
{
if(iError*ider_Error>0||ider_Error==0)
//规则2 误差与误差变化量乘积大于零或者误差变化量为零 说明误差绝对值在增大或不变
{
if(abs(iError)>=sptr->errorabsmid)
{
Realize+=k1*(sptr->kp*(iError-sptr->LastError)+sptr->ki*iError+sptr->kd*(iError-2*sptr->LastError+sptr->PrevError));

}
if(abs(iError)<sptr->errorabsmid)
{
Realize+=(sptr->kp*(iError-sptr->LastError)+sptr->ki*iError+sptr->kd*(iError-2*sptr->LastError+sptr->PrevError));
}
}
if((iError*ider_Error<0&&ider_Error*Lastder_Error>0)||iError==0)
//规则3 (误差与误差变化量乘积小于零并且误差变化量与上次误差变化量大于零)或者误差为零
{
Realize=Realize; //误差绝对值在减小无需改变控制
}
if((iError*ider_Error<0&&ider_Error*Lastder_Error<0))
//规则4 误差与误差变化量乘积小于零并且误差变化量与上次误差变化量乘积小于零 说明误差处于极值
{
if(abs(iError)>sptr->errorabsmid)
{
Realize+=K1*sptr->kp*iError; //K1>1 K1为增益放大系数
}
else
Realize+=K2*sptr->kp*iError; //0<K2<1 K2为增益抑制系数
}
}
if(abs(iError)<sptr->errorabsmid)
{
Realize+=sptr->kp*ider_Error+sptr->ki*iError;
}
sptr->PrevError = sptr->LastError; // 更新前次误差
sptr->LastError = iError; // 更新上次误差
sptr->LastData = NowData; //更新上次数据
return Realize; //返回最终值
}



int32 abs(int32 x) //绝对值函数abs()
{
if(x>=0)
return x;
else
return -x;
}

4 经典控制理论—PID控制

PID控制可以说是所有懂得控制的工程师所必须要了解的了,下面链接的内容是以单自由度为对象进行PID控制,并进行分析。

这里我们所控制的对象为,一个电机通过减速比带动一个连杆。

经典控制理论—PID控制

电机的建模部分

________________END _________________