PID控制器就是根据系统的误差,利用比例、积分、微分计算出控制量进行控制的。
1.比例系数 Kp 的作用是加快系统的响应速度,提高系统的调节精度。Kp
越大,系统的响应速度越快,系统的调节精度越高,但是容易产生超调,甚至会
使系统不稳定。Kp 取值过小,则会降低调节精度,使响应速度缓慢,从而延长
调节时间,是系统静态、动态特性变差;
2.积分作用系数 Ki 的作用是消除系统的稳态误差。Ki 越大,系统的静态
误差消除的越快,但是 Ki 过大,在响应过程的初期会产生积分饱和的现象,从
而引起响应过程的较大超调。若 Ki 过小,将使系统静态误差难以消除,影响系
统的调节精度;
3.微分系数 Kd 的作用是改善系统的动态特性,其作用主要是在响应过程中
抑制偏差向任何方向的变化,对偏差变化进行提前预报。但是 kd 过大,会使响
应过程提前制动,从而延长调节时间,而且会降低系统的抗干扰性。
/****************************所谓PID即为P(比例)+I(积分)+D(微分**************************/
**(1)P控制(比例控制): e(t) = SP - y(t); SP--设定值 e(t)--误差值(设定的值和当前的误差) y(t)--反馈值(当前值)
**适用于滞后性不大的系统 u(t) = e(t) * P; u(t)--输出值(需要输出的) P--比例系数
**
**(2)PI控制(比例+积分): u(t) = Kp*e(t) + Ki∑e(t) + u0
**可使系统进入稳态无稳态误差u(t)--输出 Kp--比例放大系数 ki--积分放大系数 e(t)--误差 u0--控制量基准值(基础偏差)
**
**(3)PD控制(微分控制):
**微分项解决响应速度问题 积分项解决稳定性
**(4)PID控制(比例积分微分控制):
**微分项解决响应速度问题 u(t) = Kp*e(t) + Ki∑e(t)+ Kd[e(t) – e(t-1)] + u0
**采样周期(即反馈值的采样周期)
**控制周期(就是每隔多长时间进行一次PID运算,并将结果输出)
****************************小结:P(比例)--即时性 I(积分)--响应速度 D(微分)--稳定性************************************
*/
#include<stdio.h>
#include<string.h>
#include"StandardPID.h"
//#include<stdib.h>
//对变量的声明
typedef struct PID{
double SetPoint; //设定值
double Kp; //比例系数
double Ki; //积分系数
double Kd; //微分系数
double LastError; //最后一次误差数Er[-1]
double PrevError; //最后第二次误差数er[-2]
double SumError; //误差积分
}PID;
/*
**PID计算部分
*/
double PIDCalc(PID *pp, double NextPoint)
{
double dError, //当前微分
Error; //偏差
Error = pp->SetPoint - NextPoint; //偏差值=设定值-输入值(当前值)
pp->SumError += Error; //积分=积分+偏差 --偏差的累加
dError = pp->LastError - pp->PrevError; //当前微分 = 最后误差 - 之前误差
pp->PrevError = pp->LastError; //更新“之前误差”
pp->LastError = Error; //更新“最后误差”
return (pp->Kp * Error //比例项 = 比例常数 * 偏差
+ pp->Ki * pp->SumError //积分项 = 积分常数 * 误差积分
+ pp->Kd * dError //微分项 = 微分常数 * 当前微分
);
}
//为PID变量申请内存,范围指向pp的指针
void PIDInit (PID *pp)
{
//memset是计算机中C / C++语言函数。将s所指向的某一块内存中的前n个
memset(pp, 0, sizeof(PID)); //字节的内容全部设置为ch指定的ASCII值,块的大小由第三个参数指定,
} //这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。
double sensor(void) //输入
{
double shuru;
scanf("%lf", &shuru);
return shuru;
}
void actuator(double rDelta) //输出
{
printf("%lf\n", rDelta);
}
int main()
{
PID sPID; //PID结构体
double rOut; //输出变量
double rIn; //输入变量
PIDInit(&sPID); //初始化结构体
sPID.Kp = 0.4;
sPID.Ki = 0.15;
sPID.Kd = 0.4;
sPID.SetPoint = 100.0;
for (;;){
rIn = sensor(); //取输入值
rOut = PIDCalc(&sPID, rIn); //PID运算
actuator(rOut); //输出
}
}