基于python的模糊pid算法

模糊PID控制算法的python实现

今天就来讲讲模糊PID的python实现方法。先来看一下整体的框架:

 

解释下上面框图的意思,模糊PID其实是在普通PID的基础之上,通过输入的两个变量:误差和误差的变化率的情况来动态的调整PID控制器的三个重要的参数Kp,Ki,Kd。从而使得控制器的性能达到最优。这里的PID参数的整定,使用的是增量的方式,这样可以避免过大的误差,提高整定的精度。 所使用的模糊控制器的设计方法与普通的模糊控制器设计是一样的,具体为:首先,确定模糊控制器的输入为二维输入,即把误差和误差的变化率作为模糊控制器的输入,实际设计时也可以设计成三维或者是其他的输入形式;模糊控制器的输出为PID参数的增量值,分别为kp’, ki’, kd’; 则PID的参数为: Kp(n)=Kp(n-1)+kp’; Ki(n)=Ki(n-1)+Ki’; Kd(n)=Kd(n-1)+kd’; 然后对模糊控制器的输入变量和输出变量划分模糊区间,这里为了模糊控制器设计的简单起见将它们都映射到[-3,3]区间上,统一划分的区间为{-3,-2,-1,0,1,2,3}即为{NB,NM,NS,ZO,PS,PM,PB};确定隶属度函数的形式,常用的隶属度函数类型有三角形隶属度函数,梯形隶属度函数,钟形隶属度函数,正态分布隶属度函数,根据控制对象的需要选择适当的隶属度函数;这里选择的是三角型隶属度函数,因为它形式简单,计算量小,便于在微控制器上实现。隶属度函数下图所示:

接下来是设计模糊控制器的关键,确定模糊规则,根据前人的大量研究,模糊PID的模糊控制规则一般采用如下的形式,这也是我看过的论文中普遍选择的方式。可能有的控制对象比较特殊需要做一些调整。模糊规则如下:

有了这些规则就完成了模糊控制器的核心设计,然后就需要确定去模糊的方法,还是使用老的办法,加权平均法计算输出值,公式如下:

该公式的解释任意一篇关于模糊控制的论文都可以找到,不在赘述。 由以上的描述可以,模糊PID只是使用模糊控制方法来调整PID的参数,从而实现简单的自适应控制,与普通的模糊控制原理并无不同。 需要注意的是:模糊PID一般需要一个比较接近理想控制效果的PID参数初始值,否则,效果并不理想。 了解了模糊PID的控制原理,然后开始编写C++代码,并不是什么难事。这里采用的是C++面向对象的编程思想,设计一个fuzzy_pid类,需要使用时,只需要实例化这个类即可得到一个fuzzy_pid对象,然后调用它的方法就可以实现模糊PID控制,是不是感觉很酷炫;不多说了,直接看代码:

fuzzy_PID.py

# python实现pid模糊算法代码
import math

N = 7


class Fuzzy_PID(object):
    def __init__(self):
        pass

    def FuzzyPID8(self, e_max, de_max, kp_max, ki_max, kd_max, Kp0, Ki0, Kd0):
        # 初始化
        self.target = 0
        self.actual = 0
        self.emax = e_max
        self.demax = de_max
        self.delta_Kp_max = kp_max
        self.delta_Ki_max = ki_max
        self.delta_Kd_max = kd_max
        self.e_mf_paras = None
        self.de_mf_paras = None
        self.Kp_mf_paras = None
        self.Ki_mf_paras = None
        self.Kd_mf_paras = None
        # 主要功能
        self.e = self.target - self.actual
        self.e_pre_1 = 0
        self.e_pre_2 = 0
        self.de = self.e - self.e_pre_1
        fenzi= int(N/2)
        self.Ke = fenzi / self.emax
        self.Kde = fenzi / self.demax
        self.Ku_p = self.delta_Kp_max / fenzi
        self.Ku_i = self.delta_Ki_max / fenzi
        self.Ku_d = self.delta_Kd_max / fenzi
        self.Kp_rule_matrix=[[None for _ in range(7)] for _ in range(7)]
        self.Ki_rule_matrix=[[None for _ in range(7)] for _ in range(7)]
        self.Kd_rule_matrix=[[None for _ in range(7)] for _ in range(7)]
        self.mf_t_e = "No type"
        self.mf_t_de = "No type"
        self.mf_t_Kp = "No type"
        self.mf_t_Ki = "No type"
        self.mf_t_Kd = "No type"
        self.Kp = Kp0
        self.Ki = Ki0
        self.Kd = Kd0
        self.A = self.Kp + self.Ki + self.Kd
        self.B = -2 * self.Kd - self.Kp
        self.C = self.Kd

    def FuzzyPID2(self, fuzzyLimit, pidInitVal):
        self.target = 0
        self.actual = 0
        self.e = 0
        self.e_pre_1 = 0
        self.e_pre_2 = 0
        self.de = self.e - self.e_pre_1
        self.emax = fuzzyLimit[0]
        self.demax = fuzzyLimit[1]
        self.delta_Kp_max = fuzzyLimit[2]
        self.delta_Ki_max = fuzzyLimit[3]
        self.delta_Kd_max = fuzzyLimit[4]
        fenzi= int(N/2)
        self.Ke = fenzi / self.emax
        self.Kde = fenzi / self.demax
        self.Ku_p = self.delta_Kp_max / fenzi
        self.Ku_i = self.delta_Ki_max / fenzi
        self.Ku_d = self.delta_Kd_max / fenzi
        self.mf_t_e = "No type"
        self.mf_t_de = "No type"
        self.mf_t_Kp = "No type"
        self.mf_t_Ki = "No type"
        self.mf_t_Kd = "No type"
        self.e_mf_paras = [None for _ in range(21)]
        self.de_mf_paras = [None for _ in range(21)]
        self.Kp_mf_paras = [None for _ in range(21)]
        self.Ki_mf_paras = [None for _ in range(21)]
        self.Kd_mf_paras = [None for _ in range(21)]
        self.Kp = pidInitVal[0]
        self.Ki = pidInitVal[1]
        self.Kd = pidInitVal[2]
        self.A = self.Kp + self.Ki + self.Kd
        self.B = -2 * self.Kd - self.Kp
        self.C = self.Kd


    # 三角隶属度函数
    def trimf(self, x, a, b, c):
        if x >&
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值