改进初学者的PID-积分饱和

最近看到了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 = 1000;//1 secdouble 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)/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;
}

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

5、最终结果

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

欢迎关注:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499400.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

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

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

改进初学者的PID-初始化

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

如何优化代码和RAM大小

如果供应商为我自己的项目提供了一个起点&#xff0c;那就太好了。工作blinky始终是一个伟大的首发。方便总是有代价&#xff0c;而且“blinky”就是夸大“切换GPIO引脚”的代码大小。对于具有少量RAM和FLASH的设备&#xff0c;这可能会引起关注&#xff1a;如果blinky占用那么…

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

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

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

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

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

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

PID:我应该何时计算积分项?

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

Arduino PID自整定库

最近看到了Brett Beauregard发表的有关PID的系列文章&#xff0c;感觉对于理解PID算法很有帮助&#xff0c;于是将系列文章翻译过来&#xff01;在自我提高的过程中&#xff0c;也希望对同道中人有所帮助。作者Brett Beauregard的原文网址&#xff1a;http&#xff1a;//brettb…

LwIP应用开发笔记之二:LwIP无操作系统UDP服务器

前面我们已经完成了LwIP协议栈基于逻辑的基本移植&#xff0c;在这一节我们将以RAW API来实现UDP服务器。 1、UDP协议简述 UDP协议全称是用户数据报协议&#xff0c;在网络中它与TCP协议一样用于处理数据包&#xff0c;是一种无连接的协议。在OSI模型中&#xff0c;处于传输层…

LwIP应用开发笔记之三:LwIP无操作系统UDP客户端

前一节我们实现了基于RAW API的UDP服务器&#xff0c;在接下来&#xff0c;我们进一步利用RAW API实现UDP客户端。 1、UDP协议简述 UDP协议全称是用户数据报协议&#xff0c;在网络中它与TCP协议一样用于处理数据包&#xff0c;是一种无连接的协议。在OSI模型中&#xff0c;处…

LwIP应用开发笔记之四:LwIP无操作系统TFTP服务器

前面我们已经实现了UDP的回环客户端和回环服务器的简单应用&#xff0c;接下来我们实现一个基于UDP的简单文件传输协议TFTP。 1、TFTP协议简介 TFTP是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议&#xff0c;提供不复杂、开销不大的文件传输服务。端…

LwIP应用开发笔记之五:LwIP无操作系统TCP服务器

前面我们实现了UDP服务器及客户端以及基于其上的TFTP应用服务器。接下来我们将实现同样广泛应用的TCP协议各类应用。 1、TCP简述 TCP&#xff08;Transmission Control Protocol 传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&#xff0c;由…

LwIP应用开发笔记之六:LwIP无操作系统TCP客户端

上一篇我们基于LwIP协议栈的RAW API实现了一个TCP服务器的简单应用&#xff0c;接下来一节我们来实现一个TCP客户端的简单应用。 1、TCP简述 TCP&#xff08;Transmission Control Protocol 传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议&a…

LwIP应用开发笔记之七:LwIP无操作系统HTTP服务器

前面我们实现了TCP服务器和客户端的简单应用&#xff0c;接下来我们实现一个基于TCP协议的应用协议&#xff0c;那就是HTTP超文本传输协议。 1、HTTP协议简介 超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;简称HTTP&#xff0c;是一种基于…

LwIP应用开发笔记之八:LwIP无操作系统HTTP客户端

前面我们实现了TCP服务器和客户端的简单应用&#xff0c;接下来我们实现一个基于TCP协议的应用协议&#xff0c;那就是HTTP超文本传输协议 1、HTTP协议简介 超文本传输协议&#xff08;Hyper Text Transfer Protocol&#xff09;&#xff0c;简称HTTP&#xff0c;是一种基于T…

LwIP应用开发笔记之九:LwIP无操作系统TELNET服务器

前面我们已经实现了基于RAW API的TCP服务器和客户端&#xff0c;也在此基础上实现了HTTP应用。接下来我们实现一个基于TCP的Telnet服务器应用。 1、Telnet协议简介 Telnet协议是TCP/IP协议族中的一员&#xff0c;是Internet远程登陆服务的标准协议和主要方式。它为用户提供了…

在ARM Cortex-M上实现FreeRTOS性能计数器

说明&#xff1a;本文翻译自Erich Styger的文章《Implementing FreeRTOS Performance Counters on ARM Cortex-M》&#xff0c;文章的权属属于原作者。 当使用像FreeRTOS这样的RTOS时&#xff0c;迟早要问一个问题&#xff1a;每个任务花费多少时间&#xff1f;基于Eclipse的M…

STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出

脉冲信号用于设备控制是非常常见的&#xff0c;但在一些情况下&#xff0c;我们希望精确的控制脉冲的数量以实现对运动的精确控制。实现的方式也许有多种多样&#xff0c;但使用计时器来实现此类操作是人们比较容易想到的。 1、原理概述 我们知道在STM32平台上&#xff0c;使…

外设驱动库开发笔记0:EPD总体设计

在产品开发过程中&#xff0c;不可避免需要使用很多外部的元件及传感器&#xff0c;这些元器件也许是板载的&#xff0c;也许是板外的&#xff0c;但不管怎样&#xff0c;为其开发驱动程序都是必须的。每次都需要为这些元器件编写驱动程序。但每次重复编写调试很麻烦&#xff0…

外设驱动库开发笔记1:AD56xx系列DAC驱动

DAC在我们的项目中经常使用到&#xff0c;而使用最多的就是AD56xx系列&#xff0c;包括有单通道的AD5662、双通道的AD5623和AD5663、以及四通道的AD5624和AD5664等。出于方便复用的原因&#xff0c;我们设计并实现AD56xx系列DAC的驱动。 1、功能概述 AD56xx系列DAC属于nanoDA…