1.位置式PID
typedef struct { float Kp; //比例系数Proportional float Ki; //积分系数Integral float Kd; //微分系数Derivative float Ek; //当前误差 float Ek1; //前一次误差 e(k-1) float Ek2; //再前一次误差 e(k-2) float LocSum; //累计积分位置 }PID_LocTypeDef; /************************************************ 函数名称 : PID_Loc 功 能 : PID位置(Location)计算 参 数 : SetValue ------ 设置值(期望值) ActualValue --- 实际值(反馈值) PID ----------- PID数据结构 返 回 值 : PIDLoc -------- PID位置 作 者 : strongerHuang *************************************************/ float PID_Loc(float SetValue, float ActualValue, PID_LocTypeDef *PID) { float PIDLoc; //位置 PID->Ek = SetValue - ActualValue; PID->LocSum += PID->Ek; //累计误差 PIDLoc = PID->Kp * PID->Ek + (PID->Ki * PID->LocSum) + PID->Kd * (PID->Ek1 - PID->Ek); PID->Ek1 = PID->Ek; return PIDLoc; }
2.增量式PID
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增量(+/-) 作 者 : strongerHuang *************************************************/ float PID_Inc(float SetValue, float ActualValue, PID_IncTypeDef *PID) { float PIDInc; //增量 PID->Ek = SetValue - ActualValue; PIDInc = (PID->Kp * PID->Ek) - (PID->Ki * PID->Ek1) + (PID->Kd * PID->Ek2); PID->Ek2 = PID->Ek1; PID->Ek1 = PID->Ek; return PIDInc; }
两者的区别:
(1)位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大;
(2)增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。
(3)由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。