PID控制算法的C++实现
七 变积分的PID控制算法C++实现
变积分PID可以看成是积分分离的PID算法的更一般的形式。在普通的PID控制算法中,由于积分系数ki是常数,所以在整个控制过程中,积分增量是不变的。但是,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。因此,根据系统的偏差大小改变积分速度是有必要的。
变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。
这里给积分系数前加上一个比例值index:
当abs(err)<180时,index=1;
当180<abs(err)<200时,index=(200-abs(err))/20;
当abs(err)>200时,index=0;
最终的比例环节的比例系数值为ki*index;
具体PID实现代码如下:
pid.h:
#ifndef _PID_H_
#define _PID_H_
typedef struct _pid{
float SetSpeed;
float ActualSpeed;
float err;
float err_last;
float Kp, Ki, Kd;
float voltage;
float integral;
float umax;
float umin;
}Pid;
class Pid_control
{
public:
void PID_init();
float PID_realize(float speed);
private:
int index;
Pid pid;
};
#endif
pid.cpp:#include <iostream>
#include "pid.h"
using namespace std;
void Pid_control::PID_init()
{
pid.SetSpeed = 0.0;
pid.ActualSpeed = 0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.voltage = 0.0;
pid.integral = 0.0;
pid.Kp = 0.4;
pid.Ki = 0.2;
pid.Kd = 0.2;
pid.umax = 400;
pid.umin = -200;
}
float Pid_control::PID_realize(float speed){
float index;
pid.SetSpeed = speed;
pid.err = pid.SetSpeed - pid.ActualSpeed;
if (abs(pid.err)>200)
{
index = 0.0;
}
else if (abs(pid.err)<180){
index = 1.0;
pid.integral += pid.err;
}
else{
index = (200 - abs(pid.err)) / 20;
pid.integral += pid.err;
}
pid.voltage = pid.Kp*pid.err + index*pid.Ki*pid.integral + pid.Kd*(pid.err - pid.err_last);
pid.err_last = pid.err;
pid.ActualSpeed = pid.voltage*1.0;
return pid.ActualSpeed;
}
main.cpp:
#include "pid.h"
#include <iostream>
using namespace std;
int main()
{
Pid_control Pid;
Pid.PID_init();
int count = 0;
while (count<1000)
{
float speed = Pid.PID_realize(200.0);
cout << speed << ";" << " ";
count++;
}
cout << endl;
system("pause");
return 0;
}
最终结果可以看出,系统的稳定速度非常快(测试程序参见本系列教程3):
![](https://img-blog.csdn.net/20170410163539245?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3poQ0FsZXg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)