PID控制算法5: On/Off(开关PID控制)

PID控制器为什么需要一个开关

在调试PID算法的过程中,有时需要手动的让系统输出某个值。怎么办?可以简单的办,不管你PID控制器计算出来的值的多少,我都强制的让系统输出特定的值。这么做其实也不违法,感觉就是有点渣,既然不爱了为什么还去招惹她。就像下面的图,你让PID控制器辛辛苦苦的计算,计算出来的结果你又不要,非得自己去设置个值,这种人挺那个啥的。

就像下面的的代码,让PID计算完之后,又强制让输出为0.

void loop()
{
    Compute();
    Output=0;
}

这样无论PID的怎么说,都可以覆盖他的值。但是,这在实践中是一个可怕的想法。PID会变得非常疑惑:“我一直在改变输出值,什么也没发生,出了什么事情?!让我改变一个更大的输出值。”结果,当你停止覆写输出并切换回PID时,输出值可能会立刻发生巨大的改变。

解决方案

解决此问题的方法是有一种方法可以打开和关闭PID。 这些状态的常用术语是“手动”(我将手动调节值)和“自动”(PID将自动调节输出)。 让我们看看如何通过代码完成此操作:

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
double outMin, outMax;
bool inAuto = false;

#define MANUAL 0
#define AUTOMATIC 1

void Compute()
{
   if(!inAuto) return;
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
      /*Compute all the working error variables*/
      double error = Setpoint - Input;
      ITerm+= (ki * error);
      if(ITerm> outMax) ITerm= outMax;
      else if(ITerm< outMin) ITerm= outMin;
      double dInput = (Input - lastInput);

      /*Compute PID Output*/
      Output = kp * error + ITerm- kd * dInput;
      if(Output > outMax) Output = outMax;
      else if(Output < outMin) Output = outMin;

      /*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;
   }
}

void SetOutputLimits(double Min, double Max)
{
   if(Min > Max) return;
   outMin = Min;
   outMax = Max;

   if(Output > outMax) Output = outMax;
   else if(Output < outMin) Output = outMin;

   if(ITerm> outMax) ITerm= outMax;
   else if(ITerm< outMin) ITerm= outMin;
}

void SetMode(int Mode)
{
  inAuto = (Mode == AUTOMATIC);
}

一个相当简单的解决方案。 如果未处于自动模式,请立即退出计算函数,而无需调整输出或任何内部变量。

的确,可以通过不从调用例程中调用Compute来达到类似的效果,但是这种解决方案可以保留PID的工作原理,这正是我们所需要的。 通过将内容保持在内部,我们可以跟踪所处的模式,更重要的是,它使我们知道何时更改模式。 这就引出了下一个问题……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值