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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 70630|回复: 51

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

  [复制链接]
发表于 2013-12-31 12:47 | 显示全部楼层 |阅读模式
本帖最后由 syl312 于 2014-1-23 13:57 编辑

        几十年来,PID控制器已被证明是一个非常有用的工具,在工业自动化领域。其应用范围涵盖机械,化工,食品等行业,采矿业,汽车和航空航天业和许多其他地方等。由于它的简单,它允许手动调协,成功地处理甚至很多非线性部分未知的过程,它成为一个标准的工具,它通常被看作是通用实现反馈控制的实际目标。
       PID控制包含有比例(P),积分(I),微分(D)三种控制规律。它们都是线性控制器,其作用是按偏差的比例,或比例加积分,或比例加积分和微分形成控制量,去控制被控对象,使被控对象输出趋于稳定。这里的偏差就是系统的给定值:Setpoint,与被控对象的实际输出就是控制器的输入值:Input之差;error = Setpoint - Input。
    原文地址传送:http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/ 希望通过对本文的翻译,帮助大家更加好的理解和认识PID控制。
对于学习PID,我们第一次会接触到以下公式:
         
        上面公式为离散化的位置式PID,因为实际中很多都是模拟量,而计算机只能处理数字量,只能将连续的离散化。位置式的PID是指控制器输出直接去控制执行机构(如阀门)和执行机构(阀门开度一一对应)。
    上面公式为离散化的位置式PID,因为实际中很多都是模拟量,而计算机只能处理数字量,只能将连续的离散化。位置式的PID是指控制器输出直接去控制执行机构(如阀门)和执行机构(阀门开度一一对应)。
根据以上公式写出下面的PID程序:

[mw_shl_code=c,true]/*定义变量*/
unsigned long lastTime;
doubleInput, Output, Setpoint;
doubleerrSum, lastErr;
doublekp, ki, kd;
void Compute()
{
   /*上次计算时间*/
   unsigned long now = millis();
   doubletimeChange = (double)(now - lastTime);
   /*按公式写出如下的式子*/
   doubleerror = Setpoint - Input;
   errSum += (error * timeChange);
   doubledErr = (error - lastErr) / timeChange;
   /*计算 PID的输出*/
   Output = kp * error + ki * errSum + kd * dErr;
   /*记录下一个采样时间PID参数的值*/
   lastErr = error;
   lastTime = now;
}
void SetTunings(doubleKp,doubleKi,doubleKd)
{
   kp = Kp;
   ki = Ki;
   kd = Kd;
}[/mw_shl_code]
   Compute()函数会被定时或不定时的调用,他能工作的很好。虽然这个系列并没有做到很好,如果我们想通过上的代码设计出工业级别PID驱动器,我们最好解决一下问题:
   Sample Time(采样时间):如果PID能有规律的被调用,那么PID将实现很好的控制,同时我们也能简化一些内部的数学计算。
   Derivative Kick(微分失控):问题不大,也很好解决,我们会在后面解决这个问题。
   On-The-Fly Tuning Changes(快速调整参数变化):好的PID算法在改变参数的时候,并不会影响内部的工作。
   Reset Windup Mitigation(缓解积分饱和):了解什么是积分饱和,并且在有利的方面进行方案实施。
   On/Off (Auto/Manual)(开关-自动或手动):在很多应用里,我们有时候需要关闭PID控制器,然后通过手动调节输出,避免控制器的干扰。
   Initialization(初始化):
   Controller Direction(控制器的方向):最后一个章节会有详细介绍。

注:所有的程序中都是采用double双精度,在arduino中,双精度是采用float精度处理的。所以,我建议改变所有double变成float


    采样时间:
     PID如果不规则的调用,会产生以下2个问题:
1.有时候定时调用,有时候又停止调用,将得不到PID的持续稳定特性。
2.需要额外对积分和微分进行数学计算,因为他们都是和时间息息相关的。

解决方法:保证PID在一个固定的的时间间隔内被调用,我通过每个周期内事先设置好的采样时间调用compute函数,PID再决定是计算还是立即返回数值。一旦我们知道PID在固定时间间隔内被调用,积分和微分的计算就能被简化。
程序:
        [mw_shl_code=c,true]unsigned long lastTime;
doubleInput, Output, Setpoint;
doubleerrSum, lastErr;
doublekp, ki, kd;
int SampleTime =1000; //1sec
void Compute()
{
   unsigned long now = millis();
   int timeChange = (now - lastTime);//第10行
   if(timeChange>=SampleTime)
   {
   
      doubleerror = Setpoint - Input;
      errSum += error;
      doubledErr = (error - lastErr);
      Output = kp * error + ki * errSum + kd * dErr;
      lastErr = error;
      lastTime = now;
   }
}

void SetTunings(doubleKp,doubleKi,doubleKd)
{
  doubleSampleTimeInSec = ((double)SampleTime)/1000;// millis()函数的时间是ms所以/1000可以转化成秒
   kp = Kp;
   ki = Ki * SampleTimeInSec;//31行
   kd = Kd / SampleTimeInSec;
}

void SetSampleTime(int NewSampleTime)
{
   if (NewSampleTime >0)
   {
      doubleratio  = (double)NewSampleTime //39行
                      / (double)SampleTime;
      ki *= ratio;
      kd /= ratio;
      SampleTime = (unsigned long)NewSampleTime;
   }
}[/mw_shl_code]
       注:910行就是PID决定是否进行计算,同时我们也简化了积分和微分的计算。在3031,我们知道采样时间是一定的,我们可以通过这个等式等效,就不需要KIKD不断的与时间变化做乘积。3942行函数可以改变采样时间,时间是以秒为单位。

      附录:             常用被控参数的经验采样周期
被控参数
采样周期/s
备注
被控参数
采样周期/s
流量
1~5
优先选1~2s
温度
15~20s
压力
3~10
优先选6~8s
直流电机
100ms
液位
6~8



















我们第一次会接触到以下公式.png
发表于 2014-9-3 10:28 | 显示全部楼层
节奏 发表于 2014-8-19 13:00
下载还要2金币?  我这里有个1金币的!

这个看起来好牛逼啊。。。还有这种神器
发表于 2014-8-19 13:00 | 显示全部楼层
下载还要2金币?  我这里有个1金币的!

PID算法演示程1序.rar

194.03 KB, 下载次数: 981

 楼主| 发表于 2013-12-31 13:02 | 显示全部楼层
本帖最后由 syl312 于 2013-12-31 13:36 编辑

帖子不好贴图,我把翻译的word贴在一楼,未翻译完。

提高PID翻译教程.rar

103.82 KB, 下载次数: 420

售价: 2 金币  [记录]

word格式

发表于 2014-1-4 18:15 | 显示全部楼层
顶起。。。。。。。。好东西。。。。
发表于 2014-1-5 08:41 | 显示全部楼层
技术贴,太实用了!
 楼主| 发表于 2014-1-5 09:47 | 显示全部楼层
popopupa 发表于 2014-1-5 08:41
技术贴,太实用了!

这个翻译教程是结合PID库的,可以直接调用库,原理是这个。
发表于 2014-1-5 14:36 | 显示全部楼层
syl312 发表于 2014-1-5 09:47
这个翻译教程是结合PID库的,可以直接调用库,原理是这个。

正好我前几天刚下载了PID库还没看 及时雨啊 多谢多谢!
发表于 2014-2-22 20:30 | 显示全部楼层
好帖子!支持一下!!!!!!!!!!
发表于 2014-3-30 08:39 | 显示全部楼层
PID库?还有库吗?
发表于 2014-4-27 20:30 | 显示全部楼层
我想请教一下,我也做过PID的,是用来控温,感觉理论讲得很好,但是一到实际工作中去就全完了。我控温的精度希望达到±0.1℃,但是结果总是在2摄氏度的范围内震荡,不知道大家有什么建议么?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-28 01:35 , Processed in 0.100261 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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