前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PID巡线机器小车

PID巡线机器小车

作者头像
用户1594945
发布2018-07-20 14:26:15
3.9K2
发布2018-07-20 14:26:15
举报
文章被收录于专栏:AI启蒙研究院AI启蒙研究院

上一篇《简单的巡线机器小车》,我们看到的一个偏随机巡线小车,但是效果并不理想。这一次我们讲一下PID巡线小车。相比之前的随机摇摆小车效果要好很多。

视频内容

当今的闭环自动控制技术都是基于反馈的概念以减少不确定性。反馈理论的要素包括三个部分:测量、比较和执行。测量关键的是被控变量的实际值,与期望值相比较,用这个偏差来纠正系统的响应,执行调节控制。在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。

PID控制器由比例单元(P)、积分单元(I)和微分单元(D)组成。其输入e(t)与输出u(t)的关系为:

巡线小车中的比例单元P

我们知道小车转向的依据,主要是根据光感传感器获得的参考值进行判断的。下方的图形是一个比例控制的巡线机器人,在两个极限点之间的转向变化很平滑。如果光电传感器读取的光值表明机器人离线很近,机器人就做小的转弯;如果读取的光值表明机器人离线很远,机器人就做较大的转弯。比例是一个重要的概念。比例的意思就是在两个变量之间存在线性关系,简单的说,就是变量之间的关系呈现为一条直线(如下图形所示)。

直线的表达式为:y= mx 我们将光电传感器读值线段(X轴)的中心点定为0,因为我们的光电传感器读值范围是40到50,我们把所有光电传感器读数都减掉45(这是40和50的平均值,(40+50)/2),得到的结果称为“error(误差)”。当光电传感器读数为47时,可得到error=47-45=2。这个error(误差)表明了机器人的光电传感器离线的边缘有多远。当光电传感器正好在线的边缘上,“error(误差)”为0(因为此时光电传感器的读值为45,而我们要从光电传感器读值中减掉45)。如果光电传感器全部处在白色的地方,“error(误差)”为 +5,如果光电传感器全部处在黑色的地方,“error(误差)”为 -5。

现在我们确定转向的范围是从-1(最大左转)到+1(最大右转),0转向的意思就是直行。上面图形中直线的斜率就可以用标为红色的两个点计算出来(其实直线上任意两点均可使用)。斜率= m = (y值的变化量)/(x值的变化量) = ( 1- (-1)) / (-5- 5 ) = -2/10 = -0.2 斜率是一个比例常量,用它乘以(x值)就可得到“(转向)”(y值)。

在各种PID文献中,斜率(也叫做比例常数、直线表达式中的m)被称作"K"。各式各样的Ks出现在PID文献中。你可以把K(或m,或斜率,或比例常数)看做是一个换算系数,用K把一个数字(光电传感器读值或我们例子中的error(误差))转换成另外一个数字(如Turn(转向))。这就是K的作用,非常简单也非常强大。

那么在我们的直线表达式中使用这些新的变量名字:Turn= K*(error)

用语言表达就是:将误差值error乘以比例常数K得到所需的转向值Turn。这个Turn 值就是P控制器的输出结果,因为它只涉及比例控制,被称为“比例控制部分”。

做转向的一个方法是:定义一个“目标功率”,我称之为"Tp"。Tp是当error(误差)=0时,机器人做直行得两个马达功率值。当error(误差)不为0时,我们用表达式Turn = K*(error)来计算如何改变两个马达的功率,一个马达的功率为Tp+Turn,另一个马达的功率为Tp-Turn。注意,因为我们的error(误差)范围是-5 到 +5,Turn(转向)的值也会有正值和负值,相当于做不同方向的转向。这正是我们所需要的,它能自动地正确设置马达功率值,确定哪一个马达速度快,哪一个马达速度慢。我们假定左侧的马达接入端口A,其功率值为Tp+Turn 的值;右侧马达接入端口C,其功率值为Tp-Turn 的值。当error 为正时,Turn值为正,Tp+Turn的值比Tp大,左侧的马达速度加快,右侧的马达速度减慢。当error 改变符号变为负值时(这就意味着机器人已经越过线的边缘,看到“黑色”了),此时Tp+Turn的值比Tp小,左侧的马达速度减慢,Tp-Turn的值比Tp大,右侧的马达速度加快。简单吧~

小结:P控制器能够处理很多控制问题,不仅仅是用在乐高机器人巡线上。一般来说,在满足条件的情况下,P控制器都能良好工作。 1. 传感器需要有足够宽的动态范围(不幸的是,我们的巡线机器人却不是这样)

2. 被控制的东西(在我们的例子里是马达)也需要有足够宽的动态范围。每个马达在功率值上的宽动态范围应该很接近。

3. 传感器和被控制的东西必须响应迅速。“迅速”的意思是“比系统内发生的任何变化都快”。控制马达时,通常不太可能获得马达的“迅速”响应,因为马达需要一定的时间来改变功率。就是说机器人的动作要比P控制器的命令滞后,这对P控制器的精确控制,会产生一定的困难。

巡线小车中的积分单元I

为了提高P控制器的响应速度,我们在表达式中加入一个新的部分——积分,PID中的“I”。积分用于计算误差的动态求和。每次我们读取光电传感器的值,并计算error(误差)时,我们将error(误差)加到一个变量中,这个变量我们称之为integral(积分)。 integral(积分)= integral(积分)+ error(误差) 这个“=”是计算机里赋值的意思,意味着将它右边的计算结果赋值给左边的那个变量名,就是计算机把原有的integral的值加上error的值,将结果赋值给integral。接下来,同P的部分一样,我们对integral乘以一个比例常数,这是另一个K。因为这个比例常数与积分部分有关,所以我们称其为Ki。与P比例控制部分相同,我们把integral(积分)乘以一个常量,会得到一个修正值。我们要把这个修正值加到Turn变量中去。

Turn= Kp*(error) + Ki*(integral)

上面就是PI控制器的基本表达式。Turn是对马达的修正,Kp*(error) 是比例控制部分, Ki*(integral)是积分控制部分。 积分控制部分有什么作用呢?如果误差在几次循环中都保持同样的值,积分部分就会越来越大。例如,如果我们读取光电传感器值,计算出error为1,很短时间后,我们再次读取光电传感器值,这一次error为2,第三次的error还是为2,那么此时的integral将是1+2+2=5。Integral为5,但这一步的error只为2。在修正量中,积分部分能产生很大的影响,但通常来说,它需要比较长的时间才能发挥作用。 积分控制的另一个作用是能去除小的误差。在巡线过程中,如果光电传感器非常接近线的边缘,但又不是正好在线的边缘上,那么error会很小,只能产生一个很小的修正量。你可以通过改变比例控制中的 Kp来修正这个小的error,但经常会产生机器人的振荡(来回摇摆)。积分控制部分就可以完美地修正小的误差,因为integral(积分)是对errors(误差)的累加,几个连续的小误差可以使integral(积分)大到足以发生作用。 我们可以把积分控制理解为控制器的"memory"(存储器)。Integral(积分)表现的是error(误差)累积的过程,可以持续向控制器提供修正误差的方法。

巡线小车中的微分单元D

我们的控制器里有了比例控制部分,用于纠正当前的误差;有了积分控制部分,用于纠正过去的误差。有没有一种办法能让我们及时预测未来,对还没发生的误差进行纠正呢?就是PID中的"D"。

假定误差的下一个变化与当前最后一个变化是相同的,我们据此来预测将来。 这个意思是说,下一个误差的期望值是:当前误差+前两次传感器采样误差的变化量。在两个连续点之间的误差变化量就叫做导数。导数是一条直线的斜率。

看上去,计算起来有些复杂。用数据举例能帮助我们说明这个问题。让我们假设当前误差是2,前一个误差是5,那么我们预测的下一个误差会是多少呢?误差的变化,也就是导数,是:

(当前误差)-(前一个误差)

按照我们的数值就是 2 - 5 = -3 。因此,当前的导数就是-3 。我们使用导数预测下一个误差就是

(下一个误差) = (当前误差)+ (当前导数)

按照我们假定的数值就是2 + (-3) = -1 。因此,我们预测下一个误差会是-1 。在实践中,我们实际上并不是要完全一致地预测下一个误差。相反地,我们只是在控制器的公式中直接使用导数。导数控制部分,与积分控制部分一样,实际上也包含时间因素,正式的导数控制部分是:

Kd(导数)/(dT)

与比例控制和微分控制一样,我们需要对导数乘上一个常量。因为这个常量是与导数相关的,因此被称之为Kd。注意,在导数控制部分,我们是除以dT,而在积分控制部分,我们是乘以dT。我们会和在积分控制部分一样,采用同样的技巧从导数控制部分去掉这个dT。如果在每一个循环中dT的值相同,分数Kd/dT就是一个常量。我们可以用另外一个Kd来代替Kd/dT。同先前的Ks一样,这个K值是未知的,需要通过反复试验来确定,因此它是Kd/dT 或是一个新的 Kd,都没有关系。

现在我们可以写出PID控制器的完整公式了:

Turn (转向)= Kp*error(误差) + Ki*integral(积分)+ Kd*derivative(导数)

显然,我们可以“预测将来”了,但是这么做有什么帮助?预测又能准确到什么程度呢?如果当前误差比前一个误差更糟糕,导数控制部分就会纠正这一误差。如果当前误差比前一误差要好一些,导数控制控制部分就会停止控制器去纠正这个误差。第二个非常有用的作用是,误差越接近于0,我们就越接近想正确停下的那个点。但是系统可能需要一段时间来响应马达功率的变化,因此我们在误差趋近于0之前,就要开始降低马达的功率,以防止过冲。不用担心导数控制部分的方程式很复杂,你所要做的只有一件事,就是按照正确的顺序做减法运算。所谓正确的顺序,就是用“当前”减去“前一个”。因此在计算导数时,我们要用“当前误差”减去“前一个误差”。

总结

我使用了其他人总结出来的PID控制器调整的方法,测量几个系统参数就可以让你非常好地计算出 Kp,Ki 和 Kd的值。有几种技术可用于计算Ks,其中之一就叫做 "Ziegler–Nichols方法" 。通过谷歌搜索可以找到很多讲述这种技术的网页。我所使用的版本几乎是直接使用了维基网页——PID控制器中的内容(在很多其他的地方也可以找到相同的内容),我只做了一点小小的改动,包括下表中所示计算过程中的循环时间。

按以下步骤调整PID控制器:

1. 将 Ki 和 Kd 的值置为0,即关闭控制器中的这些部分,将控制器作为一个简单的比例控制器。

2. 把Tp(目标功率值)设置的小一点。对于我们使用的马达来说,可以设为25.

3. 将 Kp 设置为一个“合理”的值,什么是合理的?

1)用我们想让马达功率达到的最大值(100)除以能使用的最大误差值。对于我们的巡线机器人,我们假定这个最大误差是5,所以推测出Kp值为 100/5=20。当误差为+5,马达的功率将达到100。当误差为0,马达的功率会在 Tp (目标功率值)上。

2)或者,将Kp 值设为 1 (或100),看看会发生什么。

3)如果你要把 K's的值乘以100,在这里,1就要记成100,20记成2000,100记成10000.

4. 运行机器人,观察运行状态。如果它不能巡线,从线上脱离开,就提高Kp值;如果它剧烈摆动,就降低Kp 值。调整Kp值,直到机器人能够巡线,并且没有明显的摆动为止。我们称这时的Kp 值为"Kc" (在PID文献中,被称为临界值)

5. 使用Kc值作为Kp,运行机器人,试着找出机器人运行时的“振荡周期”是多少。这个测试不需要非常准确。振荡周期(Pc)是指机器人从线的一侧开始,摆动到另一侧,再回到开始点的时间长短。对于典型的乐高机器人来说,Pc 大约是在0.5秒到1或2秒之间。

6.你还需要知道,机器人控制系统的循环周期是多少。我将循环设置为一个固定的次数(如10,000),测量机器人完成全部循环次数的总时间(从开始到结束的时间,或机器人显示出结果的时间),每个循环的周期是测量时间除以循环次数。对于一个完整的PID控制器来说,使用NXT-G编程(在程序中不要使用发声、显示等模块,这些模块的使用会占用程序运行时间,影响测试结果),dT值应该在每个循环0.015秒到0.020秒之间。

7. 使用下表计算 Kp, Ki, 和 Kc 的值。如果你只想要一个P控制器,使用表中标注了P的那一行来计算Kp (Ki' 和 Kd' 均为0)。如果你想要一个PI控制器,就使用第二行来计算。如果你想要一个完整的PID控制器,就使用最后一行来计算。

8. 在实际操作时,那些K值都要用100乘以它们实际的值,但是在计算中你不需要考虑这个问题。这个因数100 ,在确定Kp = Kc 临界值时,就已经考虑在内了。

9. 运行机器人,看看它的表现。

10. 你可以调整Kp, Ki 和 Kd 的值直到获得最佳的性能。你可以从相当大的调整开始,如30%,然后尝试较小的调整,以获得最佳的(或者至少是可以接受的)效果。

11. 一旦你确定了一组好的K值,提高TP值,提高机器人的直线速度。

12. 对于新的TP值,要重新的调整K值,也许甚至要回到第1步,重复整个过程,

13. 不断地重复,直到机器人的表现是可以接受的。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI启蒙研究院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档