韩国网站的风格,云南网站建设优化企业,移动医护网站建设利弊,个人网站推广费用Arduino PID库 #xff08;2#xff09; – Derivative Kick
参考#xff1a;手把手教你看懂并理解Arduino PID控制库——微分冲击 pid内容索引-CSDN博客 Arduino PID库 #xff08;1#xff09;– 简介
问题
此修改将稍微调整derivative term。目标是消除一种称为“…Arduino PID库 2 – Derivative Kick
参考手把手教你看懂并理解Arduino PID控制库——微分冲击 pid内容索引-CSDN博客 Arduino PID库 1– 简介
问题
此修改将稍微调整derivative term。目标是消除一种称为“Derivative Kick”的现象。 spikes :尖峰 从第一张图看出当设定值产生一个阶跃后被控量 Input 随着时间慢慢向设定值靠近第二张图反应的是设定值产生阶跃后控制量 Output 的变化可以发现Output 会突然产生一个较大的阶跃具体原因可以参考 “万恶” 的 PID 经典控制方程。第三张图描述的是 Output 的梯度也就是变化率值变化时间变化同样可以发现一个阶跃并且这个脉冲可能会非常的大dt 非常小远远超过 Output 变化量。同理图中描述了当设定值突然减小Output 及其对应的梯度变化情况。对于一般的系统来说我们不希望这样的突变发生可以想象如果采样周期很长那么这个冲击会持续很长时间系统估计就飞起来了。当然如果你的系统需要这个冲击那么这个问题就可以忽略 上图说明了问题。由于errorSetpoint-Input因此Setpoint的任何更改都会导致误差的瞬时变化。这种变化的导数是无穷大在实践中由于 dt 不是 0它最终是一个非常大的数字。该数字被反馈入pid方程从而导致输出中出现尖峰。幸运的是有一种简单的方法可以摆脱这种情况。
解决方案 Setpoint 这一项就会产生一个巨大的冲击而且仅会产生一次在下一个计算周期就会消失。处理的方法很多最简单的就是将 Serpoint 这一项移除也就是认为对于微分项来说不存在设定值的改变。如果这么处理系统会不会失控呢这种玩法已经和我们根深蒂固的经典 PID 理论不一样了啊这怎么整
上述问题的答案是不会失控我们将上述过程写成数学表达式 事实证明误差的导数等于输入的负导数除非设定值发生变化。这最终是一个完美的解决方案。我们不是加Kd * 误差的导数而是减去输入的 Kd * 导数。这称为使用“测量导数”
代码
/*working variables*/
unsigned long lastTime;
double Input, Output, Setpoint;
double errSum, lastInput;
double kp, ki, kd;
int SampleTime 1000; //1 sec
void Compute()
{unsigned long now millis();int timeChange (now - lastTime);if(timeChangeSampleTime){/*Compute all the working error variables*/double error Setpoint - Input;errSum error;double dInput (Input - lastInput);/*Compute PID Output*/Output kp * error ki * errSum - kd * dInput;/*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;}
}这里的修改非常简单。我们将 dError 替换为 -dInput。我们现在不再记住最后一个错误而是记住最后一个输入
结果 Output 梯度尖峰被去除控制量原来存在一个尖峰被消除被控量的微分变得较为平坦 这些修改给我们带来的结果。请注意输入看起来仍然大致相同。因此我们获得了相同的性能但我们不会在每次设定值更改时都发出巨大的输出峰值。
这可能是也可能不是什么大问题。这完全取决于您的应用程序对输出峰值的敏感程度。不过在我看来不突变就不需要做更多的工作所以为什么不把事情做好呢