PID笔记

Improving the Beginner’s PID

参考资料

Improving the Beginner’s PID – Introduction

The Beginner’s PID

以下是每个人第一次学习的PID方程:

在这里插入图片描述
这导致几乎每个人都编写了以下PID控制器:

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double errSum, lastErr;
double kp, ki, kd;
void Compute()
{
   /*How long since we last calculated*/
   unsigned long now = millis();
   double timeChange = (double)(now - lastTime);
  
   /*Compute all the working error variables*/
   double error = Setpoint - Input;
   errSum += (error * timeChange);
   double dErr = (error - lastErr) / timeChange;
  
   /*Compute PID Output*/
   Output = kp * error + ki * errSum + kd * dErr;
  
   /*Remember some variables for next time*/
   lastErr = error;
   lastTime = now;
}
  
void SetTunings(double Kp, double Ki, double Kd)
{
   kp = Kp;
   ki = Ki;
   kd = Kd;
}

Compute()可以定期调用,也可以不定期调用,而且它运行得很好。不过,这个系列并不是关于“效果很好”的。如果我们要将此代码转化为与工业PID控制器相当的代码,我们必须解决以下几点:

  1. Sample Time
    如果以规则的间隔对PID算法进行评估,则PID算法的功能最佳。如果算法知道这个区间,我们也可以简化一些内部数学。

  2. Derivative Kick
    这不是最大的交易,但很容易摆脱,所以我们将这么做。

  3. On-The-Fly Tuning Changes
    一个好的PID算法是可以在不影响内部工作的情况下更改调整参数的算法。

  4. Reset Windup Mitigation
    我们将深入了解什么是Reset Windup,并实施一个具有副作用的解决方案

  5. On/Off (Auto/Manual)
    在大多数应用中,有时需要关闭PID控制器并手动调整输出,而不会受到控制器的干扰.

  6. Initialization
    当控制器第一次打开时,我们想要一个“无颠簸的传输”。也就是说,我们不希望输出突然急动到某个新值。

  7. Controller Direction
    最后一个并不是健壮性本身的名称的改变。它旨在确保用户输入的调整参数具有正确的符号。

  8. NEW: Proportional on Measurement
    添加此功能可以更容易地控制某些类型的进程。

Improving the Beginner’s PID – Sample Time

初学者PID被设计为不规则调用。这导致2个问题:

  • 您无法从PID获得一致的行为,因为有时它被频繁调用,有时它不被调用。
  • 你需要做额外的数学计算导数和积分,因为它们都取决于时间的变化。

确保定期调用PID。我决定这样做的方式是指定在每个周期调用计算函数。PID根据预先确定的采样时间决定是否应该立即计算或返回。

一旦我们知道PID以恒定的间隔进行评估,导数和积分计算也可以简化。

在这里插入图片描述

在第10行和第11行,算法现在自行决定是否该进行计算。此外,因为我们现在知道样本之间的时间是相同的,所以我们不需要不断地乘以时间变化。我们只能适当地调整Ki和Kd(第31和32行),结果在数学上是等效的,但更有效。

不过,这样做有点麻烦。如果用户决定在操作期间更改采样时间,则Ki和Kd将需要重新调整以反映这一新变化。这就是第39-42行的全部内容。

另外请注意,我在第29行将采样时间转换为秒。严格来说,这是不必要的,但允许用户以1秒和s为单位输入Ki和Kd,而不是以1/mS和mS为单位。

上面的变化为我们做了3件事

  1. 无论调用Compute()的频率有多高,PID算法都将以一定的间隔进行评估[第11行]
  2. 由于时间相减[第10行],当millis()返回到0时不会出现问题。这种情况每55天才会发生一次
  3. 我们再也不需要用时间变化来乘和除了。由于它是一个常数,我们可以将其从计算代码中移出[第15+16]行],并将其与调整常数[第31+32]行]合并。从数学上讲,它的结果是一样的,但每次评估PID时都会节省一次乘法和除法.

关于中断的旁注:如果这个PID进入微控制器,那么可以为使用中断提供一个很好的论据。SetSampleTime设置中断频率,然后在该时间调用Compute。在这种情况下,不需要第9-12、23和24行。如果你打算用你的PID实现来做这件事,那就去做吧!请继续阅读本系列。希望您仍能从接下来的修改中获得一些好处。

Improving the Beginner’s PID – Derivative Kick

在这里插入图片描述

上图说明了这个问题。由于误差=设定点-输入,设定点的任何变化都会导致误差的瞬时变化。这种变化的导数是无穷大的(在实践中,由于dt不是0,它最终会成为一个非常大的数字。)这个数字被输入到pid方程中,这会导致输出出现不希望的峰值。幸运的是,有一种简单的方法可以消除这种情况。

在这里插入图片描述
事实证明,误差的导数等于输入的负导数,除非设定值发生变化。这最终成为一个完美的解决方案。我们不加(Kd误差导数),而是减去(KdInput导数)。这被称为使用“测量导数”.

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double errSum, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
void Compute()
{
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
      /*Compute all the working error variables*/
      double error = Setpoint - Input;
      errSum += error;
      double dInput = (Input - lastInput);
 
      /*Compute PID Output*/
      Output = kp * error + ki * errSum - kd * dInput;
 
      /*Remember some variables for next time*/
      lastInput = Input;
      lastTime = now;
   }
}
 
void SetTunings(double Kp, double Ki, double Kd)
{
  double SampleTimeInSec = ((double)SampleTime)/1000;
   kp = Kp;
   ki = Ki * SampleTimeInSec;
   kd = Kd / SampleTimeInSec;
}
 
void SetSampleTime(int NewSampleTime)
{
   if (NewSampleTime > 0)
   {
      double ratio  = (double)NewSampleTime
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}

在这里插入图片描述

这里的修改非常容易。我们将+dError替换为-dInput。我们现在记住的不是lastError,而是lastInput.
在这里插入图片描述

以下是这些修改给我们带来的结果。请注意,输入看起来仍然大致相同。因此,我们获得了相同的性能,但并不是每次设定值发生变化时都会发出巨大的输出峰值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值