引子
本文将分析《手把手教你看懂并理解Arduino PID控制库》中:调节方向的问题
问题定义
一个完善的PID控制器的调节方式,应该有两种:
1、正向调节,也就是输出增大,那么被控量也会增大
2、反向调节,与正向调节相对应,输出增大,被控量却减小
上述两种方式很容易理解,举个例子,例如在温度控制的加热控制中,加热输出增大,那么温度随之上升(正向调节),而在对应的制冷控制中,如果制冷输出增大,那么温度应该是随之下降的(方向调节)。
解决方案
这个问题很容易解决,在代码中,仅需要将Kp、Ki、Kd设定为负的即可,在代码中,提供了一个函数SetControllerDirection和两个宏DIRECT和REVERSE用于控制输出的方向,如果需要正向输出,在构造PID之后,调用SetControllerDirection(DIRECT)即可将输出设为正向(正向是默认的,构造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
#define DIRECT 0
#define REVERSE 1
int controllerDirection = DIRECT;
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)
{
if (Kp<0 || Ki<0|| Kd<0) return;
double SampleTimeInSec = ((double)SampleTime)/1000;
kp = Kp;
ki = Ki * SampleTimeInSec;
kd = Kd / SampleTimeInSec;
if(controllerDirection ==REVERSE)
{
kp = (0 - kp);
ki = (0 - ki);
kd = (0 - kd);
}
}
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;
}
void SetControllerDirection(int Direction)
{
controllerDirection = Direction;
}
结语
至此,PID控制器的介绍已经完毕,这仅仅是一个很普通的PID控制器,具备了PID控制的基本要素,并且考虑了一切特殊的情况,大大增加了环境适应性。
然后PID控制的一个大大大大问题,就是如何选取合适的Kp、Ki、Kd参数用于满足千变万化的应用场景,目前调节PID参数主要还是靠经验和不断地试凑,人们也不断地在寻求如何选取合适的PID参数的方法。针对上述问题,应运而生了一个命题“自动调谐PID”控制器,即我们在做PID控制的时候,不需要给出非常精确的PID参数,系统会自动帮助我们找到一组“较为”合适的PID控制参数,这样既可大大减小了对经验和试凑的要求。
在后续的文章中,将介绍以下几个命题:
1、如何进行自动调参,目前主流的自动调参方式有哪些?
2、介绍RELAY METHOD方式的自动调参库是如何实现的
3、整合了PID及自动调参的PID控制库
NOTE:如有不足之处请告知。^.^
NEXT
PS:转载请注明出处:欧阳天华