Algorithm——PID控制算法理论

因为最近在做智能车,百度人工智能创意组,团队用到了PID对小车底层进行调节,所以学习并记录一下。

PID控制算法

控制流程图

在这里插入图片描述

  • E为当前值与期望值的差值,即偏差值,即E = Sv - Pv
  • Kp是指比例系数值(P)
  • OUT为经过PID计算后的输出控制信号
PID公式

在这里插入图片描述

比例(proportion)控制

比例是指将当前偏差乘以一个常数,用来将差值信号放大或放小。
比例控制是指OUT = Kp * E
比例控制主要考虑当前偏差的大小,通过当前的偏差值进行调节,如果当前误差为20,Kp为0.5,且系统存在动态的误差10,以水箱为例,即每秒漏10cm的水,而当前和满水状态相差20cm,则调节作用为OUT = 20 * 0.5 = 10,即每秒补10cm的水,此时漏水和补水的速率相同,导致系统达到动态平衡,但是和预期值始终会相差20cm,为避免静态误差的影响,可以加入一个常数out1进行调节,OUT = Kp * E + out1,在这里,如果out1为10,则可以有效对冲环境(漏水)带来的静态误差。

积分(integral)控制

积分本质就是偏差求和,积分控制是指OUT = Ki * Sk
偏差求和:Sk = E1 + E2 +E3 + ..... + Ek
积分控制主要考虑到偏差的历史情况,如果历史情况偏差大小都有,导致Sk = 0,则偏差求和为0,输出为0,系统处于失控状态。

缺点:

  • 会在第一次达到设定值时产生过冲现象,然后在设定值两端震荡达到稳定。

避免过冲现象的解决方案:

  • 积分分离:在系统的当前值达到设定值的70%或者80%时加入积分项,不让积分项过早的累计误差。

微分(differential)控制

微分的本质就是前一次偏差与当前偏差相减,微分控制是指OUT = Kd * Dk
两次偏差之差:Dk = Ek - Ek-1
微分控制主要考察偏差的最近变化趋势,比如t1时刻偏差为30,t2时刻偏差为28,t3时刻偏差为26,则t2偏差 - t1偏差 = 2,t3偏差 - t2偏差 = 2,此时两次偏差之差为0,所以当单独使用微分控制时,OUT = Kd * 0 = 0,输出为0,系统处于失控状态。

位置式PID

在这里插入图片描述误差量累计较大,所以一般在应用时将P、D值调大,P值大可以较快回到设定值,但同时会带来较大的震荡,D值大可以削减P带来的震荡,稳定调节过程;同时,使I较小,防止震荡过大。

增量式PID

在这里插入图片描述
误差量累计小,积分项只和前一时刻的量有关,所以增量一般较小,不易产生较大的震荡。所以在使用增量PID时,一般使P值较大,可以使系统较快地达到设定值,使I值较小,使得增量惯性小,减缓震荡。

基于python的PID算法


class PID_Param_init:
    def __init__(self):
        self.Kp = 0    #P
        self.Ki = 0    #I
        self.Kd = 0    #D

        self.set_val = 0    #设定值
        self.error_last = 0 #上一时刻的差值
        self.error_prev = 0 #上上一时刻的差值
        self.error_sum = 0  #所有时刻的差值总和
        self.error_In = [2]
        

# 增量计算公式:
# Pout=Kp*[e(t) - e(t-1)] + Ki*e(t) + Kd*[e(t) - 2*e(t-1) +e(t-2)]
def PID_Controller_Increa(pid,val_in): # val_in当前时刻的输入量
    error = pid.set_val - val_in
    pid.error_In.append(error)
    #系统刚开始时
    t = len(pid.error_In)
    print(t)
    if t > 2:
        pid.error_last = pid.error_In[t-1]
        pid.error_prev = pid.error_In[t-2]
    else:
        pid.error_last = 0
        pid.error_prev = 0
    Res = pid.Kp*(error-pid.error_last) + pid.Ki*error + pid.Kd*(error-2*pid.error_last+pid.error_prev)
    print(pid.error_last)
    pid.error_prev = pid.error_last
    pid.error_last = error
    return Res

#初始化参数
PID_Param = PID_Param_init()
#参数定义
PID_Param.Kp = 1
PID_Param.Ki = 2
PID_Param.Kd = 3

val_in = 0


#计算得出输出
res = PID_Controller_Increa(PID_Param, val_in)

参考视频:

参考文章:

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值