智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 20845|回复: 28
打印 上一主题 下一主题

抗积分饱和的PID控制算法及其C语言实现

  [复制链接]

184

主题

1972

帖子

0

精华

功勋会员

E=mc^2.0

Rank: 10Rank: 10Rank: 10

积分
15110

论坛骨干奖章活跃会员奖章优秀会员奖章资源大师奖章论坛元老奖章

威望
5404
贡献
8060
兑换币
1555
注册时间
2010-12-8
在线时间
823 小时
跳转到指定楼层
1#
发表于 2012-5-17 14:12:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 znfc2 于 2012-5-17 14:14 编辑

    继续伪学术啊,高手勿喷,初学者可以看看{:soso_e113:}
    经典PID算法,适合单输入单输出系统,对于相对复杂的非线性系统可能需要进行补偿{:soso_e113:}
    所谓的积分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制量超出了正常运行范围而进入饱和区。一旦系统出现反向偏差,u(k)逐渐从饱和区退出。进入饱和区越深则退出饱和区时间越长。在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应的改变,这时系统就像失控一样,造成控制性能恶化,这种现象称为积分饱和现象或积分失控现象。
    防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在计算u(k)时,首先判断上一时刻的控制量u(k-1)是否已经超出了极限范围: 如果u(k-1)>umax,则只累加负偏差; 如果u(k-1)<umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。直接贴出代码
以下代码为位置式PID算法
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("ID_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.umax){
        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;
}

2

主题

16

帖子

0

精华

高级会员

Rank: 4

积分
508
威望
301
贡献
127
兑换币
9
注册时间
2012-3-14
在线时间
40 小时
毕业学校
中国石油大学
2#
发表于 2012-5-17 14:59:04 | 只看该作者
LZ,弱弱的问一句,float PID_realize(float speed)的参数speed是要设定的速度么??
PID不大懂,见笑见笑。。
回复 支持 反对

使用道具 举报

184

主题

1972

帖子

0

精华

功勋会员

E=mc^2.0

Rank: 10Rank: 10Rank: 10

积分
15110

论坛骨干奖章活跃会员奖章优秀会员奖章资源大师奖章论坛元老奖章

威望
5404
贡献
8060
兑换币
1555
注册时间
2010-12-8
在线时间
823 小时
3#
 楼主| 发表于 2012-5-17 15:16:59 | 只看该作者
bidai541 发表于 2012-5-17 14:59
LZ,弱弱的问一句,float PID_realize(float speed)的参数speed是要设定的速度么??
PID不大懂,见笑见笑 ...

pid.SetSpeed=speed;
设定速度啊
回复 支持 反对

使用道具 举报

2

主题

36

帖子

0

精华

高级会员

Rank: 4

积分
997
QQ
威望
558
贡献
187
兑换币
0
注册时间
2011-7-8
在线时间
126 小时
4#
发表于 2012-5-17 15:35:58 | 只看该作者
学习了
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

高级会员

Rank: 4

积分
508
威望
301
贡献
127
兑换币
9
注册时间
2012-3-14
在线时间
40 小时
毕业学校
中国石油大学
5#
发表于 2012-5-17 16:53:35 | 只看该作者
znfc2 发表于 2012-5-17 15:16
pid.SetSpeed=speed;
设定速度啊

pid.SetSpeed=speed;
设定速度与输出速度是啥关系?用赛道信息给出电机速度,是不是对应pid.SetSpeed?
我们想尝试下用PID,还请多多指点,谢谢~
回复 支持 反对

使用道具 举报

4

主题

487

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2981

活跃会员奖章优秀会员奖章

QQ
威望
2216
贡献
489
兑换币
53
注册时间
2010-11-10
在线时间
138 小时
6#
发表于 2012-5-17 18:16:12 | 只看该作者
学习一下 呵呵 平时只看增量式的了
回复 支持 反对

使用道具 举报

184

主题

1972

帖子

0

精华

功勋会员

E=mc^2.0

Rank: 10Rank: 10Rank: 10

积分
15110

论坛骨干奖章活跃会员奖章优秀会员奖章资源大师奖章论坛元老奖章

威望
5404
贡献
8060
兑换币
1555
注册时间
2010-12-8
在线时间
823 小时
7#
 楼主| 发表于 2012-5-17 19:32:52 | 只看该作者
bidai541 发表于 2012-5-17 16:53
pid.SetSpeed=speed;
设定速度与输出速度是啥关系?用赛道信息给出电机速度,是不是对应pid.SetSpeed?
...

pid.voltage为输出量
pid.err为设置速度与实际速度的偏差
回复 支持 反对

使用道具 举报

489

主题

1691

帖子

1

精华

管理员

网站创始人&站长

Rank: 11Rank: 11Rank: 11Rank: 11

积分
85927

特殊贡献奖章资源大师奖章论坛骨干奖章推广达人奖章优秀版主奖章热心会员奖章论坛元老奖章在线王奖章活跃会员奖章优秀会员奖章

QQ
威望
56985
贡献
17372
兑换币
13142
注册时间
2007-6-8
在线时间
5785 小时
8#
发表于 2012-5-18 00:26:04 | 只看该作者
支持原创
回复 支持 反对

使用道具 举报

2

主题

16

帖子

0

精华

高级会员

Rank: 4

积分
508
威望
301
贡献
127
兑换币
9
注册时间
2012-3-14
在线时间
40 小时
毕业学校
中国石油大学
9#
发表于 2012-5-18 08:38:19 | 只看该作者
znfc2 发表于 2012-5-17 19:32
pid.voltage为输出量
pid.err为设置速度与实际速度的偏差

欧了!谢谢楼主~
回复 支持 反对

使用道具 举报

184

主题

1972

帖子

0

精华

功勋会员

E=mc^2.0

Rank: 10Rank: 10Rank: 10

积分
15110

论坛骨干奖章活跃会员奖章优秀会员奖章资源大师奖章论坛元老奖章

威望
5404
贡献
8060
兑换币
1555
注册时间
2010-12-8
在线时间
823 小时
10#
 楼主| 发表于 2012-5-18 09:03:30 | 只看该作者
demon 发表于 2012-5-18 00:26
支持原创

其实也不是原创.老外在就发明了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-12-25 14:33 , Processed in 0.175709 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表