智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 16320|回复: 19
打印 上一主题 下一主题

PID控制算法的个人理解,分享给和我一样的新手

    [复制链接]

17

主题

80

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1497
威望
753
贡献
436
兑换币
471
注册时间
2013-10-27
在线时间
154 小时
跳转到指定楼层
1#
发表于 2013-11-1 13:03:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
PID控制算法,当时看了感觉很迷糊,不知道为什么,总感觉不靠谱,但是有没有实际的办法验证,看了很多例子,用了比较容易理解的例子,但是自己还是不相信。想了想,就自己构建了一个模型,在电脑上有验证了下,用的是vc6.0软件,可以清楚的看到输入和输出的次数,接近程度,需要的下载看看吧,也许有用,如果发现错误,还是希望能给个回复,指出来,让大家共同进步下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

17

主题

80

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1497
威望
753
贡献
436
兑换币
471
注册时间
2013-10-27
在线时间
154 小时
2#
 楼主| 发表于 2013-11-1 13:37:24 | 只看该作者
PID调节分为位置式和增量式,小车里面应该用的是位置式。看似很复杂的公式其实也没有那么令人捉摸不透,假设现在就是一个控制小车的车速度的问题,在任何一个时刻,一个环境,要想让小车的速度按照一个速度输出。必然存在着一个输入。这个输入值不能确定,确切说不能用数学公式准确的刻画,而且环境时刻在改变,即使知道了输入值和输出速度的关系,环境一旦改变对应关系自然也就变了,为了解决这个复杂问题,所以才引入了PID调节。
需要明白的是小车的速度和输入之间的关系不是线性的,肯定不存在v=k*in这种表达式。如果真的是这样的话,只需要一个k就可以调节了,假如现在的速度是3m/s,输入电压是3v,要想达到4m/s仅仅需要使得输入增大1v就搞定了,存在着数学关系in=in+(v1-v)*k0;v1是想要达到的速度,v是现在的速度,这个k0是可以确定的也就是k的倒数。但是这么做不切实际。
当初存在很多疑惑,认为通过这个k0调节足够,当初我认为即使只有k0输出也会在目标输出值上下进行震荡,但是会慢慢的靠近,一直可以成功达到标准的输出。没有必要用积分和微分,后来就用C语言编写一个程序简单的验证下自己的猜想。
已经知道了v和i之间的不存在线性关系。所以自己假设在一切条件不变的情况下存在着一个固定的数学关系式,当然不是线性的,为了方便起见,我们假设v=in*in;这个是存在的,但是假设我们还不知道,所以不能直接用这个公式控制速度。
假设现在in=1;v自然等于1,现在目标是要求v输出4,应该怎么办呢。
假设只有比例项控制C语言程序如下所示:
double y=16,x=4;,y1=100;//y=x*x,然后取得系数k=0.1
        //double  err=0;
        //double  err_array[100]={0};
        int i,t;
       
        while(1)
        {
        for(i=1;i<100;i++)
        {
                x=x+(y1-y)*0.1;//+(err_array[i]-err_array[i-1])*0.001;
                //err_array[i]=(64-y);
                y=x*x;
                printf("%d:  %lf  %lf\n",i,x,y);
               
        }
通过更改x和y的初始值和目标值运行可以观测程序运行结果,现在目标值是y1=100;系数目前是0.1
我把目标值改了。改成了81,x=9的时候才是理想控制,看一下运行结果。

果然和我想的一样开始x的值在应该输出的值上下震荡,逐渐接近于9,在第68次x=9.0000;这只是一个,貌似看着这样也可以控制,不需要积分和微分,
但是把x和y的值改变了,目标值改变下就不那么乐观了,比如说我现在把y1改成100,那么x输出应该是10才对,或者是一个非常非常接近与10的数,

这就是事实,执行10000次任然是一个10.07误差还是非常非常大的,说明系统存在某些不可消除的误差,仅仅靠比例项是不可行,很自然,比例项越大,达到目标值越快,但是也不是越大越好,过大震荡就很难消除,时间变长。要求控制速度是快,准,狠。时间长了自然是不行啊。电脑上不能随便设定系数,否则就没有结果了。上面这个次数当然是越少越好了。下面是引入了积分,其实这个积分就是求和,这个不像数学表达式是连续的,是间断的。采样周期也就是1ms吧。
下面是引入了积分的程序:

        double y=16,x=4; //y=x*x,然后取得系数k=0.1
        double  err=0;
        double  err_array[200]={0};
        int i,t;
        while(1)
        {
        for(i=1;i<100;i++)
        {
                x=x+(100-y)*0.1+(err_array[i-1]-err_array[i])*0.001;
                err_array[i]=(64-y);
                y=x*x;
                printf("%d:  %lf  %lf\n",i,x,y);
        }
在没有引入积分前100次后的结果是这个

引入积分后则是:


10.100和10.656,发现积分确实可以减少误差,一定存在着积分系数使得x更逼近或者能够达到目标值,只不过我没有仔细一个个实验,调节系数。系数一个个调,第一个确定了才能继续调节第二个,先调的是比例项,然后是积分项。这里只是一个简单的比方,没有过多的实际用处,也就是帮助理解下关系。实际用的时候恐怕要复杂点。
还有一个是微分系数,微分是就是求两次误差差值的差,反应了误差的变化趋势,有预测的意味。
下面是使用了微分后的代码
double y=16,x=4; //y=x*x,然后取得系数k=0.1
        double  err=0;
        double  err_array[200]={0};
        double  err_array1[200]={0};
        int i,t;
        while(1)
        {
        for(i=1;i<100;i++)
        {
                x=x+(100-y)*0.1+(err_array[i-1]-err_array[i])*0.001+(err_array1[i]-err_array1[i-1])*0.001;
                err_array1[i]=err_array[i-1]-err_array[i];
                err_array[i]=(64-y);
                y=x*x;
                printf("%d:  %lf  %lf\n",i,x,y);
        }
结果是:

更精准了一步,这就是一个简单的PID吧。
这是文本内容,图片内容见下载的文档
回复 支持 1 反对 0

使用道具 举报

38

主题

1651

帖子

0

精华

功勋会员

Rank: 10Rank: 10Rank: 10

积分
8770
威望
4444
贡献
2638
兑换币
1818
注册时间
2010-12-29
在线时间
844 小时
3#
发表于 2013-11-1 15:27:23 | 只看该作者
用excel或者origin或者matlab来仿真就方便多了。
回复 支持 反对

使用道具 举报

17

主题

80

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1497
威望
753
贡献
436
兑换币
471
注册时间
2013-10-27
在线时间
154 小时
4#
 楼主| 发表于 2013-11-1 16:28:28 | 只看该作者
yukunlinykl 发表于 2013-11-1 15:27
用excel或者origin或者matlab来仿真就方便多了。

哦,谢谢哈 matlab还没有学,excel确实方便,可以直接看到图,更直观。
回复 支持 反对

使用道具 举报

6

主题

673

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2357

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

QQ
威望
1073
贡献
634
兑换币
740
注册时间
2013-7-5
在线时间
325 小时
5#
发表于 2013-11-1 19:17:34 | 只看该作者
受教啦 !:lol
回复 支持 反对

使用道具 举报

16

主题

590

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2987
威望
1599
贡献
34
兑换币
939
注册时间
2012-11-17
在线时间
677 小时
6#
发表于 2013-11-1 21:12:26 | 只看该作者
这个学了自动控制原理   就都理解了
回复 支持 反对

使用道具 举报

6

主题

300

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
5366
威望
3935
贡献
1101
兑换币
461
注册时间
2012-11-21
在线时间
165 小时
7#
发表于 2013-11-2 10:08:24 | 只看该作者
:)
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
威望
124
贡献
82
兑换币
83
注册时间
2013-10-3
在线时间
36 小时
毕业学校
南昌大学
8#
发表于 2013-11-6 09:15:19 | 只看该作者
搞不懂这个式子到底是增量式还是位置式? x=x+(y1-y)*0.1; 看y1-y这个是本次误差,应该是位置式,但是为什么要加x,不是增量式才需要再加上前一次的值么。
回复 支持 反对

使用道具 举报

2

主题

38

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
415
威望
228
贡献
107
兑换币
139
注册时间
2013-9-11
在线时间
40 小时
毕业学校
辽工大
9#
发表于 2013-11-8 20:44:22 | 只看该作者
回复 支持 反对

使用道具 举报

3

主题

563

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3808

优秀会员奖章活跃会员奖章论坛元老奖章在线王奖章

QQ
威望
1710
贡献
906
兑换币
1148
注册时间
2013-8-24
在线时间
596 小时
10#
发表于 2013-11-11 19:10:32 | 只看该作者
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-5 14:41 , Processed in 0.458852 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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