这是根据理论实现的位置式PID的一种写法,这里和别人的写法不一样,其实实现的功能是没多大差别的,其他人的写法更加简洁而且易懂,但可能不那么容易和理论联系起来。
这里最开始本人的Kp,T,Ti,Td给的是都给的是1。根据理论,时间周期定了或小到可以忽略才能对其他参数进行调整,所以T给到了1,便于控制结果;且因为积分时间影响误差,将T给到了100便于调整其他参数;接下来就是根据程序执行的结果,将Kp和Td往小了调,使输出结果在100左右波动。这里本人的参数调的有点点差,最终输出结果为100.014784,不过已经很接近了。
#include "stdio.h"
#include "stdlib.h"
double Discretization(double aim,double act);//离散化位置式PID
struct pid//结构体变量声明PID
{
double Kp;//比例系数
double T;//调节周期
double Ti;//积分时间
double Td;//微分时间
double out;//控制输出
};
struct error//结构体变量声明误差
{
double now;//当前值
double last;//前一值
double sum;//误差
};
double P,I,D;//比例项,积分项,微分项
int main()
{
double i=Discretization(100,99);
printf("%1f",i);
system("pause");
}
/*
**作者:xwj
**时间:2023/10/26
**函数名:Discretization(double aim,double act);
**功能:通过调整Kp,T,Ti,Td来改变PID三个项的值将实际值强制转变为预期值
**使用示例:double i=Discretization(100,99);
*/
double Discretization(double aim,double act)
{
struct pid p;
p.Kp=28.24;
p.T=1;
p.Ti=100;
p.Td=0.08;//数据初始化
P = p.Kp;
I = p.Kp*p.T/p.Ti;
D = p.Kp*p.Td/p.T;//根据PID的微积分表达式离散化方程得出
struct error e;
e.now=aim-act;
e.last=0;
e.sum+=e.now;
p.out=P*(e.now+I*e.sum+D*(e.now-e.last));
e.last=e.now;
return p.out;
}
位置式PID是我在和同伴们的竞赛过程中,验证过的比较靠谱一种的控制算法,能够满足工程对实时控制的需求。这里是验证我个人对PID控制的理解程度。这里是理想化的数学模型,当有外界变化的时候,还要分不同的情况增加积分限幅的操作。
文章评论