PID巡线算法在三光电巡线小车上的运用

  • PID巡线算法是一种非常适合用于巡线的算法,使用PID巡线算法可以使小车的巡线稳定性大大增强,并且小车速度可以得到明显的提升。但是学习PID算法是一个漫长的过程,并且一个失误可以导致整个小车出现问题和故障,所以在这里记录一下PID算法的学习经验以便我以后再次掌握。
这里主要是记录PID算法在小车上的运用

一.PID算法是什么

PID算法是一种广泛应用于工业控制系统的反馈控制策略,它通过比例(P)、积分(I)和微分(D)三个基本环节的组合来调节控制系统的输出,以达到期望的控制效果。PID算法的核心在于根据当前的误差和过去的误差累积,以及未来误差的预测,来计算控制输出。

二.PID算法怎么在小车上使用

PID算法有三个核心值,比例(P)、积分(I)、微分(D)。

PID算法还需要有三个关键数据:现在的值、预期的值、误差的值。

  • 现在的值:指的是当前的一种状态值,在小车上体现的就是小车各个光电传感器的值。
  • 误差的值:指的就是现在的值和目标的值的差值,在小车上一般都是线的左右两个光电的差值。
  • 预期的值:指的就是目标值哦,小车上的目标值是什么?是左右光电的差值是0,即两个光电识别到的值近似相同,这代表了小车中心已经沿着线前进。如果以左光电-右光电的值作为误差值,寻黑线为例子,如果差值>0,说明小车左偏,反而反之。

在读取小车的光电值时,我们需要的不是0和1,因为他只能代表光电传感器的光值是否达到设定的阈值,我们需要的是光电的模拟光值,只有这样误差值才是一个有效值。

但是我们不同的光电传感器,所能读取到的数据并不一样,有些光电传感器可以读取模拟光值(0-?),有一些又只能读取模拟颜色值(0-255),并且在不同的环境,光照、场地地图的平整度或者地图材料都会影响误差值的计算,这样我们PID的值在同一车上却不能在不同环境和器材上使用,此时我们需要使用数据归一化算法。

数据归一化算法

使用不同的数据归一化算法可以实现不同的误差消除效果,例如消除掉光线、传感器的影响,或者放大误差、缩小误差甚至规范误差的作用。

现在我普遍使用的归一化算法是:误差值=(s2-s4)/[(s2+s3+s4)+0.001]*2

使用这个归一化算法,可以让误差值在[-2,2]的范围之内,-2和2分别代表了极右偏和极左偏,+0.001的目的是防止除0,x2的目的是放大误差。

至于如果对这个归一化算法不理解,可以进行如下假设:

数据归一化在实际运算中的假设

假设现在在室内或者一个光线较为正常的环境下:你的小车s2=1000,s3=3000,s4=1200

不使用归一化算法:error=s2-s4error得到-200,你的车左偏。

使用归一化算法:error=(s2-s4)/(s2+s3+s4+0.001)*2这时误差值得到-0.7,你的车依旧可以得到左偏的结果。

但是如果新的光电传感器只能读0-255呢?或者换了一个环境等情况,第一种算法得到的error值就会出现相同偏角但是误差不同,而归一化算法后就不会出现这种情况。并且第一种算法在更换器械之后必须要调整PID的值,并且你的PID值需要根据光电传感器读值返回写。如果光电传感器的值范围大,你的PID值普遍都要写成小数,或者反过来,你的PID值就需要写的很大,对于这些情况可能你会觉得没有什么,但是对于小车控制器,会有计算精度问题,导致你的PID算法不够稳定、好用。

PID算法的具体变量意义

通过读取光电值并经过数据归一化处理之后,我们的误差值稳定在了一个固定的范围。

这时候就要调试PID的值去使小车稳定巡线,但在此之前需要知道P、I、D值的各个意义。

  • 比例P:通过直接与误差相乘获取小车应该变化的速度值。
  • 积分I:通过与误差的持续累积值相乘,来进行微小修正。
  • 微分D:通过与上次误差-这次误差的值进行抵抗比例算法带来的震荡。

比例P算法会造成一种震荡,具体表现在小车在线左右不断抽搐抖动,这是由于比例P直接与误差相乘带来的问题,使用微分D算法可以进行对比例P的震荡消除效果,在这之后,小车会处于一种误差一直趋于0但无法结接近的状态,这时候通过积分I算法,通过对误差的无限累加至一个变量内,然后乘以积分指数进行系统性的微调,此时小车完全达到稳定状态。

如果难以理解,这里有一段伪代码:

func line():
    kp = 4
    ki = 1
    kd = 2

    error = (s2-s4)/(s2+s3+s4+0.001)*2
    differ = error - last_error
    inter += error
    
    base_speed = 80
    change_speed = error * kp + inter * ki + differ * kd
    spl = base_speed - change_speed
    spr = base_speed + change_speed

    setMotor(spl,spr)
    sleep(0.001) // s
end

总的来说,P是对实时误差的控制,I是对历史误差的控制,D是对未来误差的预测控制,通过此算法可以有效的对小车巡线的控制。

这里之所以我们是计算变化值而不是输出值,是因为PID算法输出的值实际上属于一种加速度类的变化值,而不是最终的结果值。

线程等待0.001s的目的是降低持续高强度的信息获取和计算造成的系统耦合,即抽风。

三.PID算法的调试方法

第一步:p值的调试方法

总体估算大概p值,并在调试中不断修改。

  • 出现脱线或者转弯修正非常不及时的情况:p值太小
  • 出现在线的左右两侧震荡:如果震荡过大说明p值太大,如果处于一种震荡不大但是可以走的状态说明就是可以了。如果不清楚到底是什么情况可以增加或者减小p值以后再调试观察。

第二步:d值调试方法

在调试之前强调:d值一定不可以大于p值!

还是大概调试d值,根据小车情况去修改d值。

  • 震荡依旧存在:如果d不大于p下,增加d值。
  • 震荡几乎没有:已经ok了!

第三步:可选的i值调试方法

当小车巡线一直存在倾斜情况或者歪歪扭扭的情况,就可以考虑选用i值。

在调试i值需要我们根据控制器实际运算频率去调试。

注意:inter的值虽说是无限累加,但是仍然要设置范围。如[-100,100]

根据具体情况调试,小车总会趋于稳定的。当然i值不宜过小和过大,但是一般情况下i值几乎可以不使用,直接设置为0。

四.PID巡线算法附加算法

脱线处理

脱线之后可以根据具体的光电传感器位置,当某个角落的传感器检测到值可以直接设置误差值为一个超大的值去直接拉回小车。

当然普遍是使用上一次误差,即转向记忆。并且可以选择每一次增加一点点,这样会缩小小车归线的时间。

分层PID

在一些特别的地图里面,存在非常直的线和非常弯的线,在这种情况下,我们可以根据误差的范围来设置不同的PID值进行对不同程度的线来正常行驶。

© 版权声明
THE END
喜欢就支持一下吧
点赞1赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容