文档章节

手把手教你看懂并理解Arduino PID控制库——初始化

欧阳天华
 欧阳天华
发布于 2017/01/19 09:26
字数 848
阅读 730
收藏 1

引子

本文将分析《手把手教你看懂并理解Arduino PID控制库》中:初始化的问题

问题定义

先看问题的图示:

上一节,讨论的是PID控制由开转关的过程中存在的问题,那么紧接着上一节,如果在关闭后,突然再次开启,那么会产生什么问题呢?直观来看,对于被控量会出现图中,绿色线的一个bump,这个bump是由于由关转开的一瞬间,输出突然放大,那么对于灵敏度高的系统,则会出现,滞后大的系统可能不会如此明显,但不管怎么说,为了杜绝一切不利因素,我们都应该想办法消除这个bump。由于这个bump的根因是由于输出的突变而造成的,所以需要想办法控制这个输出的突变。

解决方案

想一想,所有此类问题都是发生在时间轴上的,那么PID控制中时间轴会影响的项只有积分项和微分项(可以想象,比例向为Kp * (设定值 - 被控量),这是一个连续量,不存在突变的可能(除非是采样时间特别长,在改变输出前,被控量飞上天了),所以只需要从这两项上想办法,控制住这两项的突变,即可控制住输出的突变。首先问题发生在PID关闭转开启的过程中,由于PID开启关闭控制的函数是SetMode,所以在此函数中,增加一个initial函数用于控制积分项和微分项即可。具体做法是:

1、更新微分项上一次采样值为PID开启一瞬间的采样值,这样可以保持微分项维持在上一次开启结束的状态不变。

2、将积分项设置为当前的输出,为什么要这么做呢?积分项由于PID关闭长时间维持关闭前的状态,一旦开启,如果不改变积分项,输出会瞬间被拉回到上一次开启结束的状态,突变就这样产生了

代码

/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double ITerm, lastInput;
double kp, ki, kd;
int SampleTime = 1000; //1 sec
double outMin, outMax;
bool inAuto = false;
 
#define MANUAL 0
#define AUTOMATIC 1
 
void Compute()
{
   if(!inAuto) return;
   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;
}
 
void SetMode(int Mode)
{
    bool newAuto = (Mode == AUTOMATIC);
    if(newAuto && !inAuto)
    {  /*we just went from manual to auto*/
        Initialize();
    }
    inAuto = newAuto;
}
 
void Initialize()
{
   lastInput = Input;
   ITerm = Output;
   if(ITerm> outMax) ITerm= outMax;
   else if(ITerm< outMin) ITerm= outMin;
}

结论

图片说明一切。。。。。

NOTE:如有不足之处请告知。^.^

下一章将介绍如果在系统运行过程中,控制方向对系统的影响

NEXT

PS:转载请注明出处:欧阳天华

© 著作权归作者所有

欧阳天华
粉丝 11
博文 9
码字总数 9812
作品 0
松江
程序员
私信 提问
手把手教你看懂并理解Arduino PID控制库——引子

介绍 本文主要依托于Brett Beauregard大神针对Arduino平台撰写的PID控制库Arduino PID Library及其对应的帮助博客Improving the Beginner’s PID。在没有Brett Beauregard帮助之前,也尝试过...

欧阳天华
2016/12/21
9.2K
3
手把手教你看懂并理解Arduino PID控制库——采样时间

引子 在《手把手教你看懂并理解Arduino PID控制库》中已经简单介绍过Brett Beauregard大神所提供的ArduinoPID控制库,此库不仅仅可以在Arduino使用,稍作简单的修改即可移植到别的平台。那么...

欧阳天华
2016/12/21
3.2K
1
手把手教你看懂并理解Arduino PID控制库——微分冲击

引子 本文将分析《手把手教你看懂并理解Arduino PID控制库》中第二个问题:设定值改变对微分项的影响。语文不好,原文中叫做Derivative Kick,实在是想不出好的名字,暂且称为微分冲击。 问题...

欧阳天华
2016/12/21
1K
1
手把手教你做智能LED灯(二) 硬件端的开发

第2节 硬件端的开发 现在,我们开始实现智能LED灯硬件相关部分的设计。 2.1 硬件连接 选择了Arduino MEGA 、HC-06蓝牙模块、LED灯模块和三引脚按钮开关以后,我们就需要把它们组合起来,为我...

anddlecn
2016/09/13
0
0
手把手教你智能硬件开发(三) 控制LED灯

第3节 控制LED灯 现在我们开始尝试用代码控制一个真正的直观的硬件设备。 第一个例子:让Arduino开发板上的一个LED小灯周期性的打开、关闭。 第二个例子:让LED灯亮度逐渐的变亮变暗。 3.1 ...

anddlecn
2016/09/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
53分钟前
4
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
6
0
从零基础到拿到网易Java实习offer,我做对了哪些事

作为一个非科班小白,我在读研期间基本是自学Java,从一开始几乎零基础,只有一点点数据结构和Java方面的基础,到最终获得网易游戏的Java实习offer,我大概用了半年左右的时间。本文将会讲到...

Java技术江湖
昨天
5
0
程序性能checklist

程序性能checklist

Moks角木
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部