PID入门提高翻译教程【二】-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 29620|回复: 20

PID入门提高翻译教程【二】

[复制链接]
发表于 2013-12-31 12:51 | 显示全部楼层 |阅读模式
本帖最后由 syl312 于 2014-1-23 13:57 编辑
   微分过冲:
   出现的问题:通过对微分项的弱化处理,目的是消除微分过冲的现象。

                             

[图1微分过冲]

 [图1微分过冲]
      上图说明了这个问题,因为偏差error=Setpoint-Input.任何在系统设定值得改变将立刻引起偏差的变化。所以系统设置值微小的变化将会导致出现一个极大的微分值。解决方法:

                           

【图等式1】

【图等式1】
   以上公式已经被证明,除了设置值改变的时候,偏差的微分等于输入导数的负值。这就有了一个很好的解决方法。我们用 -kd * dInput取代原来的微分。这就是微分的测量方法。
程序实现:

[mw_shl_code=c,true]unsigned long lastTime;
doubleInput, Output, Setpoint;
doubleerrSum, lastInput;
doublekp, ki, kd;
int SampleTime =1000; //1s
void Compute()
{
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
      doubleerror = Setpoint - Input;
      errSum += error;
      doubledInput = (Input - lastInput);
      Output = kp * error + ki * errSum - kd * dInput;
      lastInput = Input;
      lastTime = now;
   }
}

void SetTunings(doubleKp,doubleKi,doubleKd)
{
  doubleSampleTimeInSec = ((double)SampleTime)/1000;
   kp = Kp;
   ki = Ki * SampleTimeInSec;
   kd = Kd / SampleTimeInSec;
}
void SetSampleTime(int NewSampleTime)
{
   if (NewSampleTime >0)
   {
      doubleratio  = (double)NewSampleTime
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}[/mw_shl_code]
      结果:
                       

【图结果】

【图结果】
这就是我们修正后带来的效果。注意输入依旧是一样的。我们得到了一样的性能,并且不会因为Setpoing的变化导致输出波形有很大的纹波。
问题:对于一个正在运行的PID控制系统PID参数的改变会导致输出的变化。

                        

【图正在运行的PID控制系统PID参数的改变会导致输出的变化】

【图正在运行的PID控制系统PID参数的改变会导致输出的变化】

对于修正正在运行的控制系统的PID参数,会带来很大的变化。以下是PID参数修改前后的变化值:

                       

【表PID参数修改前后的变化值】

【表PID参数修改前后的变化值】

       通过这张可以看出,以上是因为积分突然变为原来的一半。当参数变化时,带来的变化是巨大的。为什么会是这样的呢?下面的积分公式可以解释:

                        

[公式2]

[公式2]

      这就解释了为什么KI没改变之前系统工作的一直很稳定。突然,你乘了一个新的KI值与之前的偏差累计总和。这样带来的变化不是我们所希望的,我们只想改变后能朝着我们希望的方向发展。
     解决方法:解决的方法有很多,我在最新的Arduino PID库里使用的方法是重新调整errSum(偏差总和).KI变为原来的两倍时,把errSum变为原来的一半,虽然这个方法有点笨拙,下面有更加明智的方法。这个方法要求有基础的代数基础或者计算技巧。
                     

[公式3]

[公式3]



     把KI乘到里面,虽然看起来没什么变化,但是我们将会看到这个小变化带来了很大的不同。现在我们将error和Ki相乘。并且把乘积和保存起来,当Ki变化时,这时不会有很大的变化了,因为之前的KI的乘积和值已经存储起来了。

[mw_shl_code=c,true]unsigned long lastTime;
doubleInput, Output, Setpoint;
doubleITerm, lastInput;
doublekp, ki, kd;
int SampleTime =1000; //1sec
void Compute()
{
   unsigned long now = millis();
   int timeChange = (now - lastTime);
   if(timeChange>=SampleTime)
   {
      doubleerror = Setpoint - Input;
      ITerm += (ki * error);
      doubledInput = (Input - lastInput);
      Output = kp * error + ITerm - kd * dInput;

      lastInput = Input;
      lastTime = now;
   }
}

void SetTunings(doubleKp,doubleKi,doubleKd)
{
  doubleSampleTimeInSec = ((double)SampleTime)/1000;
   kp = Kp;
   ki = Ki * SampleTimeInSec;
   kd = Kd / SampleTimeInSec;
}

void SetSampleTime(int NewSampleTime)
{
   if (NewSampleTime >0)
   {
      doubleratio  = (double)NewSampleTime
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}[/mw_shl_code]
我们用ITerm变量来替代errSum【第四行】。这样KI就包含在ITerm中,就从主要的PID计算式子中抽离出来。
结果如下:
                           

【图5】

【图5】

                        

【图6】

【图6】

当KI调整之前,控制器重新调整了全部的error的总和,每个偏差值都能看到。通过这个程序,先前的偏差值仍旧是原样的,新的KI值只是朝着我们希望的方向有作用。
 楼主| 发表于 2014-1-2 13:50 | 显示全部楼层
 楼主| 发表于 2014-1-2 13:51 | 显示全部楼层

图片不能贴在文章里吗,只能放在附件?
发表于 2014-1-2 17:22 | 显示全部楼层
syl312 发表于 2014-1-2 13:51
图片不能贴在文章里吗,只能放在附件?

可以啊,点上传图片就行了啊
 楼主| 发表于 2014-1-2 19:01 | 显示全部楼层
coloz 发表于 2014-1-2 17:22
可以啊,点上传图片就行了啊

需要先上传图片再复制才可以显示在文章里,有几张显示不出来我就放在附件里了,搞定了
 楼主| 发表于 2014-1-2 19:39 | 显示全部楼层
图又挂了,我放在附件里了。
发表于 2014-1-5 08:42 | 显示全部楼层
强烈支持,正好想用PID,多谢分享!
 楼主| 发表于 2014-1-5 09:46 | 显示全部楼层
popopupa 发表于 2014-1-5 08:42
强烈支持,正好想用PID,多谢分享!

剩下部分这个月应该会翻译好,可以去原地址看看,先学习
发表于 2014-2-22 20:31 | 显示全部楼层
好帖子!收藏研究!!!!!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 07:29 , Processed in 0.151043 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表