1位置式PID算法
公式
积分环节替换为累计的形式实现
数据结构
typedef struct
{
float target_val; //目标值
float actual_val; //实际值
float err; //定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float integral; //定义积分值
}_pid;
/**
* @brief PID算法实现
* @param actual_val:实际值
* @note 无
* @retval 通过PID计算后的输出
*/
float PID_realize(float actual_val)
{
/*计算目标值与实际值的误差*/
pid.err=pid.target_val-actual_val;
/*误差累积*/
pid.integral+=pid.err;
/*PID算法实现*/
pid.actual_val=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
/*误差传递*/
pid.err_last=pid.err;
/*返回当前实际值*/
return pid.actual_val;
}
2增量式PID算法
公式
增量式 PID 的输出与近三次的偏差有很大关系;
代码实现
数据结构
typedef struct
{
float target_val; //目标值
float actual_val; //实际值
float err; //定义当前偏差值
float err_next; //定义下一个偏差值
float err_last; //定义最后一个偏差值
float Kp, Ki, Kd; //定义比例、积分、微分系数
}_pid;
/**
* @brief PID算法实现
* @param actual_val:实际值
* @note 无
* @retval 通过PID计算后的输出
*/
float PID_realize(float actual_val)
{
/*计算目标值与实际值的误差*/
pid.err=pid.target_val-actual_val;
/*PID算法实现*/
pid.actual_val += pid.Kp*(pid.err - pid.err_next)
+ pid.Ki*pid.err
+ pid.Kd*(pid.err - 2 * pid.err_next + pid.err_last);
/*传递误差*/
pid.err_last = pid.err_next;
pid.err_next = pid.err;
/*返回当前实际值*/
return pid.actual_val;
}
3 算法对比
对比区别
-
增量式算法不需要对积分项累加,控制量增量只与近几次的误差有关,计算误差对控制量
计算的影响较小。而 位置式算法要对近几次的偏差的进行积分累加,容易产生较大的累加
误差; -
增量式算法得出的是控制量的增量,例如在阀门控制中,只输出阀门开度的变化部分,误
动作影响小,必要时还可通过逻辑判断限制或禁止本次输出,不会严重影响系统的工作;而
位置式的输出直接对应对象的输出,因此对系统影响较大; -
增量式算法控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分
部件的对象,如步进电机等,而 位置式算法适用于执行机构不带积分部件的对象,如电液
伺服阀;
• 在进行 PID 控制时,位置式 PID 需要有积分限幅和输出限幅,而 增量式 PID 只需输出限
幅
位置式 PID 优缺点:
优点:: 位置式 PID 是一种非递推式算法,可直接控制执行机构(如平衡小车),u(k) 的值和执行
机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以
很好应用;
缺点:: 每次输出均与过去的状态有关,计算时要对 e(k) 进行累加,运算工作量大。
增量式 PID 优缺点:
优点::
- 误动作时影响小,必要时可用逻辑判断的方法去掉出错数据。
- 手动/自动切换时冲击小,便于实现无扰动切换。
- 算式中不需要累加。控制增量 Δu(k) 的确定仅与最近 3 次的采样值有关。在速度闭环控制
中有很好的实时性。
缺点:
- 积分截断效应大,有稳态误差;
- 溢出的影响大。有的被控对象用增量式则不太好;