这是每一个人最初学到的PID等式:
然后每个人都可以写下这样的PID控制器:
/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double errSum, lastErr;
double kp, ki, kd;
void Compute()
{
/*How long since we last calculated*/
unsigned long now = millis();
double timeChange = (double)(now - lastTime);
/*Compute all the working error variables*/
double error = Setpoint - Input;
errSum += (error * timeChange);
double dErr = (error - lastErr) / timeChange;
/*Compute PID Output*/
Output = kp * error + ki * errSum + kd * dErr;
/*Remember some variables for next time*/
lastErr = error;
lastTime = now;
}
void SetTunings(double Kp, double Ki, double Kd)
{
kp = Kp;
ki = Ki;
kd = Kd;
}
Compute()被规律或无序的调用,并很好的工作。如果我们将这段代码变成标准工业PID控制器,还需要明确和解决下面这些事情:
- Sample Time 样本时间- PID算法最好是能评定规律的间隔。如果算法在意这个间隔,我们可以简化内部的计算。
- Derivative Kick - 不是什么大问题,很容易解决,因此我们准备解决它。
- On-The-Fly Tuning Changes 在运调试- 一个好的PID算法是在参数调优时不打乱内部工作。
- Reset Windup Mitigation - 我们将跟进什么是重置终结,然后实现一个可以带来好处的方案。
- On/Off (Auto/Manual) 开/关(自动/手动) - 有很多程序,有时希望关闭PID控制,然后通过手动输出,没有控制器的干扰。
- Initialization 初始化 - 当控制器第一次启动时,我们需要优雅的转换。也就是说不希望一下突然输出一些修正值。
- Controller Direction 控制方向- 最后一种,不是鲁棒性名称上的修改。它设计来确保用户使用正确的信号进行参数调优。
当我们解决了这些问题,我们将拥有一个坚实的PID算法。