关于增量式PID的代码(C语言)实现的详细说明--应该可以解决部分人的疑惑

关于增量式PID的代码(C语言)实现的详细说明

网上可以找到很多关于增量式PID的一些解释说明;
最终都可以得到如下的公式:

Δu=Kp·{e(n)-e(n-1)}+Ki·e(n)+Kd·{e(n)-2·e(n-1)+e(n-2)} ;

最终转换成代码有很多是

  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;
    //非本人编写
    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;
    }

有些人对代码存在一定的疑惑,其实代码是没有问题的;
公式为:

Δu=Kp·{e(n)-e(n-1)}+Ki·e(n)+Kd·{e(n)-2·e(n-1)+e(n-2)}

整理为:

Δu=(Kp+Ki)·e(n)-(Kp+2)·e(n-1)+Kd·e(n-2)

由于Pid需要整定参数、因而可以将上式三项误差前的数当作一个整体;
即表示为:

Δu=KP·e(n)-KI·e(n-1)+KD·e(n-2)

将上式对比代码、则可以得出、代码是符合公式的

当然我们也可以将代码完全按照公式来描述
typedef struct{
	float limit;		//输出限幅
	float target;		//目标输出量
	float feedback;		//实际输出量	
	float Kp;	
	float Ki;	
	float Kd;	
	float e_0;			//当前误差
	float e_1;			//上一次误差
	float e_2;			//上上次误差
}PID;
 
#define max(a, b)			(a>b? a:b)
#define min(a, b)			(a<b? a:b)
#define range(x, a, b)		(min(max(x, a), b))
#define exchange(a, b, tmp) (tmp=a, a=b, b=tmp)
#define myabs(x)			((x<0)? -x:x)
 
float pid_calc(PID *pid)
{
	float out;
	float ep, ei, ed;
	
	pid->e_0 = pid->target - pid->feedback;
	ep = pid->e_0  - pid->e_1;
	ei = pid->e_0;
	ed = pid->e_0 - 2*pid->e_1 + pid->e_2;
	out = pid->Kp*ep + pid->Ki*ei + pid->Kd*ed;
	out = range(out, -pid->limit, pid->limit);
	pid->e_2 = pid->e_1;
	pid->e_1 = pid->e_0;
	return out;
}

个人还是比较建议第二种写法!调参的时候也更加直观一点;

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ah_yl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值