//PID算法
//简介: 比例、积分、微分结合三个环节于一体的闭环控制算法
//本质:根据输入的偏差,按照P\I\D函数关系进行计算从而调整输出。
//比例环节:u = Kpe; //Kp越大,系统稳定时间越短,但是会存在超调现象,容易导致系统损毁或者震荡,存在静态误差(系统控制过程接近稳定状态///时,目标值和实测值之间的偏差)。
//积分环节:u = Kpe + KiΣe;
//对输入偏差不断进行积分,主要用于消除静态误差;
//Ki越大,消除静态误差时间越短,但容易产生超调震荡,稳定性变差。
//微分环节:u = Kpe + KiΣe + Kd(e(k) - e(k-1));
//提前稳定输出,避免超调,但系数过大容易抑制过大,容易产生高频噪声
//位置式PID:u = Kpe + KiΣe + Kd*(e(k) - e(k-1));
//特点:直接控制输出
//缺点:产生累计误差,累计量较大,计算量大
//增量式PID:Δu = Kp*(e(k)- e(k-1)) + Kie(k) + Kd(e(k)- 2e(k-1) + e(k-2));
//特点:计算相对值,不直接控制输出
//优点:计算量少,计算偏差,没有累计误差;
可扫码了解相关职位
/*PID types select*/
#define PID_TYPE 1 //1:position-based PID 0:incremental PID
/*
*@brief Parameters required by the PID algorithm
*/
typedef struct{
float Kp; //比例系数
float Ki; //积分系数
float Kd; //微分系数
float DestValue; //设定目标值
float ActionValue; //控制输出值
float CumulativeError; //累计误差
float Error; //当前误差
float LastError; //上一次误差
float PrevError; //上两次误差
}PID_Param_TypeDef;
/*
*Function:GKHY_PID_Init
*Describe: PID parameters init.
*Parameter: PID_Param: which pid defined yourself need to be inited.
Kp: the parameter of proportion.
Ki: the parameter of integration.
Kd: the parameter of differentiation.
*Return: none
*/
void GKHY_PID_Init(PID_Param_TypeDef *PID_Param, float Kp, float Ki, float Kd)
{
PID_Param->Kp = Kp;
PID_Param->Ki = Ki;
PID_Param->Kd = Kd;
PID_Param->DestValue = 0.0;
PID_Param->ActionValue = 0.0;
PID_Param->CumulativeError = 0.0;
PID_Param->Error = 0.0;
PID_Param->LastError = 0.0;
PID_Param->PrevError = 0.0;
}
/*
*Function:GKHY_PID_Init
*Describe: PID calculation is performed according to the current acquisition value
*Parameter: PID_Param: which pid defined yourself need to be calculate.
CurrentValue: the current value which need to be calculate.
*Return: ActionValue
*/
float GKHY_PID_Calculate(PID_Param_TypeDef *PID_Param, float CurrentValue)
{
PID_Param->Error = PID_Param->DestValue - CurrentValue;
#if PID_TYPE //位置式PID u = Kp*e + Ki*Σe + Kd*(e(k) - e(k-1));
PID_Param->CumulativeError += PID_Param.Error;
PID_Param->ActionValue = PID_Param->Kp * PID_Param->Error + \
PID_Param->Ki * PID_Param->CumulativeError + \
PID_Param->Ki * (PID_Param->Error - PID_Param->LastError);
PID_Param->LastError = PID_Param->Error;
#else //增量式PID Δu = Kp*(e(k)- e(k-1)) + Ki*e(k) + Kd*(e(k)- 2e(k-1) + e(k-2));
PID_Param->ActionValue += PID_Param->Kp * (PID_Param->Error - PID_Param->LastError) + \
PID_Param->Ki * PID_Param->Error + \
PID_Param->Ki * (PID_Param->Error - 2 * PID_Param->LastError + PID_Param->PrevError);
PID_Param->PrevError = PID_Param->LastError;
PID_Param->LastError = PID_Param->Error;
#endif
return PID_Param.ActionValue;
}
```使用清注明出处