改善初学者的PID(一)—简介
一、简介
结合新的Arduino PID库的发布,我决定发布此系列文章。 最后一个库虽然可靠,但实际上并没有任何代码说明。 这次围绕该计划详细解释代码为何如此。 我希望这对两类人有用:
-
直接对Arduino PID库中发生的事情感兴趣的人将获得详细说明。
-
任何编写自己的PID算法的人都可以看看我的工作方式,并借用他们喜欢的任何东西。
这将是一个艰难的口号,但我认为我发现了一种不太痛苦的方式来解释我的代码。 我将从所谓的“初学者的PID”开始。然后逐步进行改进,直到获得具有高效,鲁棒性的pid算法。
初学者的PID
这是每个人首先学习的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控制器类似的代码,则必须解决一些问题:
- 采样时间 - 如果定期对PID算法进行评估,则其效果最佳。如果算法知道此间隔,我们还可以简化一些内部数学运算。
- 微分冲击 - 这不是最大的问题,但是很容易解决,因此我们将这样做。
- 动态调整参数 - 一种好的PID算法可以在不影响内部工作的情况下更改调整参数。
- 缓解积分饱和 - 我们将介绍什么是缓解积分饱和,并实施具有附带好处的解决方案。
- 开/关(自动/手动)- 在大多数应用中,有时需要关闭PID控制器并手动调节输出,而不会干扰控制器。
- 初始化 - 控制器首次开启时,我们希望进行”无扰动的传输“,也就是说,我们不希望输出突然变为某个新值。
- 控制方向 - 最后一个不是鲁棒性本身名称的更改,它旨在确保用户输入具有正确符号的调优参数。
- 新增 测量比例(Proportional on Measurement) - 添加这个特性使得它更加容易控制特定类型的过程。
测量比例(Proportional on Measurement)** - 添加这个特性使得它更加容易控制特定类型的过程。
解决所有问题后,我们将获得一个可靠的PID算法。我们也会(并非偶然)拥有最新版本的Arduino PID 库中使用的代码。因此,无论你在尝试编写自己的算法,还是试图了解PID库正在发生的事情,希望对你有所帮助。让我们开始吧。