最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助。作者Brett Beauregard的原文网址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner’s-pid-reset-windup/

1、问题所在

  积分饱和是一个陷阱,它可能比任何其他内容对初学者有更多的要求。当 PID 认为它可以做一些它做不到的事情时,就会发生这种情况。例如,Arduino 上的 PWM 输出接受0-255 之间的值。默认情况下,PID 不知道这一点。如果它认为300-400-500 会奏效,它将尝试那些期望得到它所需要的东西的值。由于在现实中,该值被限制在 255,它只会继续尝试越来越多的数字,而不会取得任何进展。

  这个问题以奇怪的滞后的形式显现出来。上面我们可以看到,输出以 "非常兴奋" 的方式超出了外部限制。当设定值下降时,输出必须在低于255的限制线之前逐步减少。

2、解决方案步骤1

  有几种方法可以缓解积分饱和,但我选择的方法如下:告诉 PID 输出限制是什么。在下面的代码中,您将看到现在有一个 SetOuputLimits函数。一旦达到任一限制,pid 停止求和 (积分)。它知道没有什么可做的; 它知道自己已经无能为力。由于输出不会积分饱和,所以当设定值下降到我们可以做一些事情的范围内时,我们会得到立即的响应。

3、解决方案步骤2

  不过,请注意,在上面的图表中,虽然我们摆脱了那个积分饱和滞后,但我们并没有完成这一步。PID认为它正在发送的东西,和刚刚发送的东西间还是存在偏差。为什么?比例项和 (在较小的程度上) 微分项的存在。

  尽管积分项已被安全地钳位,但P和D仍在增加他们两的份额,产生的结果也有可能会高于输出限制。在我看来,这依然是不可接受的。如果用户调用名为 "SetOutputLimits" 的函数,他们必须假定这意味着“输出将保留在这些值之内”。因此,对于步骤2,我们将其作为一个有效的假设。除了钳位积分项之外,我们还要钳位输出值,使其保持在预期的位置。

  (注意: 您可能会问为什么我们需要钳位这两个。如果我们要控制输出限制,为什么要单独钳位积分项呢?如果我们只是钳位输出,积分项就会不停的增长。虽然在向上的过程中,输出看起来会很好,但我们会看到在下降的过程中,会受到积分饱和的影响。

4、代码

 /*working variables*/
unsigned long lastTime;
double Input,Output,Setpoint;
double ITerm,lastInput;
double kp,ki,kd;
int SampleTime = ; //1 sec
double outMin,outMax;
void Compute()
{
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)/;
kp = Kp;
ki = Ki * SampleTimeInSec;
kd = Kd / SampleTimeInSec;
} void SetSampleTime(int NewSampleTime)
{
if (NewSampleTime > )
{
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;
}

  添加了一个新函数,允许用户指定输出限制 [52-63 行]。这些限制用于钳位积分项 [17-18] 和输出 [23-24]

5、最终结果

  正如我们所看到的,积分饱和被消除了。此外,输出将保留在我们希望的位置。这意味着无需对输出进行外部钳位。如果希望它的范围从23到 167,您可以将它们设置为输出限制。

欢迎关注:

改进初学者的PID-积分饱和的更多相关文章

  1. PID控制器开发笔记之三:抗积分饱和PID控制器的实现

    积分作用的引入是为了消除系统的静差,提高控制精度.但是如果一个系统总是存在统一个方向的偏差,就可能无限累加而进而饱和,极大影响系统性能.抗积分饱和就是用以解决这一问题的方法之一.这一节我们就来实现抗积 ...

  2. 改进初学者的PID-介绍

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  3. 改进初学者的PID-测量的比例编码

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  4. 改进初学者的PID-修改整定参数

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  5. 改进初学者的PID-采样时间

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  6. 改进初学者的PID-正反作用

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  7. 改进初学者的PID-测量的比例介绍

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  8. 改进初学者的PID-初始化

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

  9. 改进初学者的PID-手自动切换

    最近看到了Brett Beauregard发表的有关PID的系列文章,感觉对于理解PID算法很有帮助,于是将系列文章翻译过来!在自我提高的过程中,也希望对同道中人有所帮助.作者Brett Beaure ...

随机推荐

  1. python 之类、self

    类是什么 可以视为种类或者类型的同义词.所有的对象都属于某一个类,称为类的实例. 例如:鸟就是"鸟类"的实例.这就是一个有很多子类的一般(抽象)类:看到的鸟可能属于子类" ...

  2. python为什么不需要重载函数

    https://www.cnblogs.com/erbaodabao0611/p/7490439.html

  3. 一般spring配置上下文

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  4. 项目兼容ie8技术要点

    好久没有写博客了,因为最近公司项目要调ie8兼容,一直在忙这事,终于竣工了,跟大家分享下这老掉牙的浏览器是如何搞定的...本人新手一枚,欢迎大家指教 项目是使用的jeecg框架,后台使用的java,前 ...

  5. Go读写文件

    Go序列化和反序列化 package main import ( "bufio" "encoding/json" "fmt" "o ...

  6. byte[] 转 2进制字符串

    /byte[]转为二进制字符串表示byte[] bytesTest =new byte[]{16,18,33}; string strResult=string.Empty;string strTem ...

  7. 2019/7/22----tomacat配置web页面访问路径

    tomcat----conf-----Catalina----localhost----cms.xml,cms.xml文件中添加: <?xml version='1.0' encoding=&q ...

  8. Session的数据共享

    要体现出Session的数据共享,需要建立两个Servlet: 第一个:建立Session,将值设置为Tom. protected void doGet(HttpServletRequest requ ...

  9. pyy整队 线段树

    pyy整队 线段树 问题描述: 众所周知pyy当了班长,服务于民.一天体育课,趁体育老师还没来,pyy让班里n个同学先排好 队.老师不在,同学们开始玩起了手机.站在队伍前端玩手机,前面的人少了,谁都顶 ...

  10. Spring MVC国际化配置

    Spring MVC国际化配置 前言 项目开发中要考虑支持国际化,框架选用的是Spring MVC框架,那么问题来了Spring MVC如何配置并实现国际化. 实现过程(Maven项目) 对于Spri ...