PID--抗积分饱和法--004

Posted 郭志凯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PID--抗积分饱和法--004相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/***********************************************************************
    所谓的积分饱和现象是指如果系统存在一个方向的偏差, PID 控制器的输
    出由于积分作用的不断累加而加大, 从而导致执行机构达到极限位置, 若控制器
    输出 U(k)继续增大, 执行器开度不可能再增大, 此时计算机输出控制量超出了
    正常运行范围而进入饱和区。 一旦系统出现反向偏差, u(k)逐渐从饱和区退出。
    进入饱和区越深则退出饱和区时间越长。 在这段时间里, 执行机构仍然停留在极
    限位置而不随偏差反向而立即做出相应的改变, 这时系统就像失控一样, 造成控
    制性能恶化, 这种现象称为积分饱和现象或积分失控现象。
    防止积分饱和的方法之一就是抗积分饱和法, 该方法的思路是在计算
    u(k)时, 首先判断上一时刻的控制量 u(k-1)是否已经超出了极限范围: 如果
    u(k-1)>umax, 则只累加负偏差;
    如果 u(k-1)<umin, 则只累加正偏差。 从而避
    免控制量长时间停留在饱和区。 直接贴出代码, 不懂的看看前面几节的介绍。
****************************************************************************/
struct _pid
{
    float SetSpeed; //定义设定值
    float ActualSpeed; //定义实际值
    float err; //定义偏差值
    float err_last; //定义上一个偏差值
    float Kp,Ki,Kd; //定义比例、 积分、 微分系数
    float voltage; //定义电压值( 控制执行器的变量)
    float integral; //定义积分值
    float umax;
    float umin;
} pid;

void PID_init()
{
    printf("PID_init begin \n");
    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.2;
    pid.Ki=0.1; //注意, 和上几次相比, 这里加大了积分环节的值
    pid.Kd=0.2;
    pid.umax=400;
    pid.umin=-200;
    printf("PID_init end \n");
}

float PID_realize(float speed)
{
    int index;
    pid.SetSpeed=speed;
    pid.err=pid.SetSpeed-pid.ActualSpeed;
    if(pid.ActualSpeed>pid.umax) //灰色底色表示抗积分饱和的实现
    {
        if(abs(pid.err)>200) //蓝色标注为积分分离过程
        {
            index=0;
        }
        else
        {
            index=1;
            if(pid.err<0)
            {
                pid.integral+=pid.err;
            }
        }
    }
    else if(pid.ActualSpeed<pid.umin)
    {
        if(abs(pid.err)>200) //积分分离过程
        {
            index=0;
        }
        else
        {
            index=1;
            if(pid.err>0)
            {
                pid.integral+=pid.err;
            }
        }
    }
    else
    {
        if(abs(pid.err)>200)
        //积分分离过程
        {
            index=0;
        }
        else
        {
            index=1;
            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;
}


int main()
{
    PID_init();
    int count=0;
    while(count<1000)
    {
        float speed=PID_realize(200.0);
        printf("%f\n",speed);
        count++;
    }
    return 0;
}

 

以上是关于PID--抗积分饱和法--004的主要内容,如果未能解决你的问题,请参考以下文章

增量式pid如何能防止积分饱和

Unity 3D 游戏通用系统设置页面,自定义按键设置,背景虚化,图像设置,亮度对比度饱和度音量调节,分辨率窗口化,帧率垂直同步,抗锯齿,阴影质量,纹理质量设置

数值分析实验之数值积分法(java 代码)

数值分析实验之数值积分法(java 代码)

数值分析实验之数值积分法(Python 代码)

数值分析实验之数值积分法(Python 代码)