最近研究了一下PID,用C#实现了一下,搞的差不多明白了,和大家分享一下,感谢大家的关注。
项目源码见文末。
下图是测试效果:
前面只有P调节,后面加入I调节消除稳态误差。
下面说一下测试过程,首先模拟一个被调节的设备。大家先可以假设这是一个水罐,我们通过Input口的注水和抽水调节液位Level,罐子本身有个Output口,排出水来干扰我们的控制。
class Device
{
public Device()
{
Task.Run(Running);
}
public double Input { get; set; }
public double Output { get; set; }
public double Level { get; set; }
public double MaxLevel { get; set; } = double.MaxValue;
public double MixLevel { get; set; } = 0d;
private void Running()
{
while (true)
{
Thread.Sleep(200);
if (Level < MaxLevel)
Level += Input*3;
if (Level > Output)
Level -= Output;
else
Level = 0;
LevelChange?.Invoke();
}
}
public event Action LevelChange;
}
然后就是PID控制的水泵
class PID
{
public double err; //偏差值
public double err_last; //上一个偏差值
public double err_last_last; //上上一个偏差值
public double Target; //调节目标
public double Output; //输出
public double Maxout { get; set; } = 10000d;
public double Mixout { get; set; } = -10000d;
public double PID_realize(double target, double nowvalue, double Kp = 0.4, double Ki = 0.3, double Kd = 0.1)
{
if (target != Target) {
Output = Kp * err;
Target = target;
}
err = target - nowvalue;
Output += Kp * (err - err_last + Ki * err + Kd * (err - 2 * err_last + err_last_last)); //这是增量PID算法的公式
err_last_last = err_last;
err_last = err;
if (Output > Maxout) Output = Maxout;
if (Output < Mixout) Output = Mixout;
return Output;
}
}
其它就是一些界面的实现了,就不贴了,可以到我们码云下载我的开源项目。
https://gitee.com/tfarcraw/wpfnotes.git
是我平时学习wpf 的一个练手小项目集,这个示例在PrismMain项目中,不过我会经常更新,有时候就把这个项目整合掉了,这个我打包发到CSDN上吧。
https://download.csdn.net/download/tfarcraw/12584796