标签:作者 关注 原理 看到了 mode imei png 需要 跟踪
最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner’s-pid-onoff/
1、问题所在
有一个 PID 控制器虽然是很好的,但你并不是什么时候都需要它。
假设在程序中的某个时刻,您希望将输出强制为某个值 (例如 0),您当然可以在调用例程中执行此操作:
1 void loop() 2 { 3 Compute(); 4 Output=0; 5 }
这样,无论 PID 输出是什么,您只需覆盖其值。然而,这在实践中是一个可怕的想法。PID 会变得非常混乱:“我一直发送输出,但是什么都没有发生!到底发生了什么事? !我再发送一下。”因此,当您停止覆盖输出并切换回 PID 时,您可能会立即得到一个巨大的输出值改变。
2、解决方案
解决这个问题的办法是有办法关闭和打开 PID。这些状态的常用术语是 "手动" (我将手动调整输出值) 和 "自动" (PID 将自动调整输出)。让我们看看这是如何在代码中完成的。
3、代码
1 /*working variables*/ 2 unsigned long lastTime; 3 double Input,Output,Setpoint; 4 double ITerm,lastInput; 5 double kp,ki,kd; 6 int SampleTime = 1000; //1 sec 7 double outMin,outMax; 8 bool inAuto = false; 9 10 #define MANUAL 0 11 #define AUTOMATIC 1 12 13 void Compute() 14 { 15 if(!inAuto) return; 16 unsigned long now = millis(); 17 int timeChange = (now - lastTime); 18 if(timeChange>=SampleTime) 19 { 20 /*Compute all the working error variables*/ 21 double error = Setpoint - Input; 22 ITerm+= (ki * error); 23 if(ITerm> outMax) ITerm= outMax; 24 else if(ITerm< outMin) ITerm= outMin; 25 double dInput = (Input - lastInput); 26 27 /*Compute PID Output*/ 28 Output = kp * error + ITerm- kd * dInput; 29 if(Output > outMax) Output = outMax; 30 else if(Output < outMin) Output = outMin; 31 32 /*Remember some variables for next time*/ 33 lastInput = Input; 34 lastTime = now; 35 } 36 } 37 38 void SetTunings(double Kp,double Ki,double Kd) 39 { 40 double SampleTimeInSec = ((double)SampleTime)/1000; 41 kp = Kp; 42 ki = Ki * SampleTimeInSec; 43 kd = Kd / SampleTimeInSec; 44 } 45 46 void SetSampleTime(int NewSampleTime) 47 { 48 if (NewSampleTime > 0) 49 { 50 double ratio = (double)NewSampleTime 51 / (double)SampleTime; 52 ki *= ratio; 53 kd /= ratio; 54 SampleTime = (unsigned long)NewSampleTime; 55 } 56 } 57 58 void SetOutputLimits(double Min,double Max) 59 { 60 if(Min > Max) return; 61 outMin = Min; 62 outMax = Max; 63 64 if(Output > outMax) Output = outMax; 65 else if(Output < outMin) Output = outMin; 66 67 if(ITerm> outMax) ITerm= outMax; 68 else if(ITerm< outMin) ITerm= outMin; 69 } 70 71 void SetMode(int Mode) 72 { 73 inAuto = (Mode == AUTOMATIC); 74 }
一个相当简单的解决方案。如果您不在自动模式下,请立即离开计算函数,而不调整 "输出" 或任何内部变量。
4、最终结果
的确,您可以通过不象例程那样调用计算来实现类似的效果,但此解决方案保持PID所包含的工作原理,这是我们所需要的。通过保持事物的内部过程,我们可以跟踪处于哪种模式中,更重要的是,当我们改变模式时,它让我们知道有哪些工作需要进行。这就引出了下一期.....。
欢迎关注:
标签:作者 关注 原理 看到了 mode imei png 需要 跟踪
原文地址:https://www.cnblogs.com/foxclever/p/11371375.html