1. PID三个环节的作用
PID三个环节各自的主要作用和效应:
- 比例环节:起主要控制作用,使控制量向目标值靠拢,但可能导致振荡
- 积分环节:消除稳态误差,但会增加超调量
- 微分环节:产生阻尼效果,抑制振荡和超调,但会降低响应速度
2. 比例系数与积分时间的大小对曲线的影响关系
1. 比例环节
成比例地反映控制系统的偏差信号e(t),偏差一旦产生,控制器立即产生控制作用,以减小偏差。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。
P参数越大比例作用越强,动态响应越快,消除误差的能力越强。但实际系统是有惯性的,控制输出变化后,实际y(t)值变化还需等待一段时间才会缓慢变化。由于实际系统是有惯性的,比例作用不宜太强,比例作用太强会引起系统振荡不稳定。P参数的大小应在以上定量计算的基础上根据系统响应情况,现场调试决定,通常将P参数由大向小调,以能达到最快响应又无超调(或无大的超调)为最佳参数。
优点:调整系统的开环比例系数,提高系统的稳态精度,减低系统的惰性,加快响应速度。
缺点:仅用P控制器,过大的开环比例系数不仅会使系统的超调量增大,而且会使系统稳定裕度变小,甚至不稳定。
2. 积分环节
控制器的输出与输入误差信号的积分成正比关系。主要用于消除静差,提高系统的无差度。积分作用的强弱取决于积分时间常数T,T越大,积分作用越弱,反之则越强。
对一个自动控制系统,如果在进入稳态后存在稳态误差,则称这个控制系统是有稳态误差的或简称有差系统(System with Steady-state Error)。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。这样,即便误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减小,直到等于零。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。PI控制器不但保持了积分控制器消除稳态误差的“记忆功能”,而且克服了单独使用积分控制消除误差时反应不灵敏的缺点。
优点:消除稳态误差。
缺点:积分控制器的加入会影响系统的稳定性,使系统的稳定裕度减小。
3. 微分环节
反映偏差信号的变化趋势,并能在偏差信号变得太大之前,在系统中引入一个有效的早期修正信号,从而加快系统的动作速度,减少调节时间。在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。
自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入“比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势。这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。PD控制只在动态过程中才起作用,对恒定稳态情况起阻断作用。因此,微分控制在任何情况下都不能单独使用。
优点:使系统的响应速度变快,超调减小,振荡减轻,对动态过程有“预测”作用。
在低频段,主要是PI控制规律起作用,提高系统型别,消除或减少稳态误差;在中高频段主要是PD规律起作用,增大截止频率和相角裕度,提高响应速度。因此,控制器可以全面地提高系统的控制性能。
3.代码程序
//定义PID结构体用于存放一个PID的数据
typedef struct{
float kp,ki,kd;//三个系数
float error,lastError;//误差、上次误差
float integral,maxIntegral;//积分值、积分限幅值
float output,maxOutput;//PWM输出值、PWM输出限幅值
}PID;
//初始化pid参数
void PID_Init(PID *pid,float p,float i,float d,float maxI,float maxOut){
pid.kp=p;
pid.ki=i;
pid.kd=d;
pid.maxIntegral=maxI;
pid.maxOutput=maxOut;
}
//进行一次pid计算(每次调用间隔一段时间)
//参数为(pid结构体,目标值,反馈值),计算结果放在pid结构体的output成员中
void PID_Calc(PID *pid,float reference,float feedback){
//更新数据
pid.lastError = pid.error; //保存上次误差
pid.error = reference-feedback; //计算新误差
//计算比例
float pout = pid.error * pid.kp;
//计算微分
float dout = (pid.error - pid.lastError) * pid.kd;
//计算积分
pid.integral += pid.error * pid.ki;
//积分限幅(大于限幅值,则赋值限幅值)(小于负的限幅值,则赋值负的积分限幅值)
if(pid.integral > pid.maxIntegral) pid.integral = pid.maxIntegral;
else if(pid.integral < -pid.maxIntegral) pid.integral = -pid.maxIntegral;
//计算PWM输出值
pid.output = pout + dout + pid.integral;
//输出PWM限幅(大于限幅值,则赋值PWM输出限幅值)(小于负的限幅值,则赋值负的PWM输出限幅值)
if(pid.output > pid.maxOutput) pid.output = pid.maxOutput;
else if(pid.output < -pid.maxOutput) pid.output = -pid.maxOutput;
}
PID mypid;//创建一个PID结构体变量
main(){
//...初始化其它代码(PWM等)
PID_Init(&mypid,10,1,5,800,1000);//初始化PID参数
while(1){//进入循环运行
float feedbackValue=...; //获取到被控对象的反馈值
float targetValue =...; //设置的目标值
//进行PID计算,结果保存在output变量中
PID_Calc(&mypid,targetValue,feedbackValue);
//设定执行器输出(mypid.output)值
.... = mypid.output;
delay(10);//等待一定时间再开始下一次循环
}
}
4. 调节PID各环节的方式
参考链接1:http://t.csdn.cn/mpgm7
参考链接2:http://t.csdn.cn/ltjZu