我有两个模糊逻辑控制器输入;一个是位置误差和错误率。
我知道我的问题可能是由于不太了解每个参数的影响。
问题是我在建立模糊规则时感到困惑。什么时候需要对Kp,Kd和Ki使用高值和低值来实现最佳调整?当误差几乎为零时,Kp是否必须非常低(因此,机器人处于所需位置)?同一问题适用于所有三个参数。
#1 楼
E. Abbasi,M. J. Mahjoob在论文中使用模糊系统在悬停模式下调整PID增益使用模糊系统控制四旋翼无人机,解释了如何使用模糊逻辑调整PID增益。您可以找到许多有关单例调整的论文,但本文显示了完全模糊控制使用齐格勒-尼古尔斯(或其他技术)查找PID增益具有输入错误(e)和错误更改(de)
定义输入和输出的模糊化图。定义限制(也可以更改形状),如
name [min,peak,max]
very small [-1,-1,-0.6], small [-1,-0.6,0], medium [-0.6,0,0.6], big [0,0.6,1], very big [0.6,1,1]
创建规则如
/>
if **e** and/or **de** *fuzzyname* (small,big etc.) than KI is fuzzyname (small,big etc.)
对结果进行模糊处理。 -PID只需将质量更改为e,将服务更改为de,最后您可以将小费输出更改为KP / KI / KD
(有关于小费问题的示例:python scikit Fuzzy-模糊控制系统:小费问题) />
注1:错误范围应明确定义,因此必须记录错误并更改错误。限制必须在这些值的最大值和最小值中。
注2:输出值范围在-1和1之间。
Fuzzy-PID的示例代码python中的代码在这里:
# -*- coding: utf-8 -*-
"""
@author: acs
"""
import skfuzzy as fuzz
from skfuzzy import control as ctrl
import acspid
import numpy as np
from matplotlib import pyplot as plt
plt.ion()
fig=plt.figure()
ferr = ctrl.Antecedent(np.arange(-150, 150, 1), 'ferr')
fder = ctrl.Antecedent(np.arange(-150, 150, 1), 'fder')
fout = ctrl.Consequent(np.arange(-1, 1, 0.01), 'fout')
ferr.automf(5)
fder.automf(5)
fout.automf(5)
fout['poor'] = fuzz.trimf(fout.universe, [-1, -1, -0.5])
fout['mediocre'] = fuzz.trimf(fout.universe, [-1, -0.5, 0])
fout['average'] = fuzz.trimf(fout.universe, [-0.1, 0, 0.1])
fout['decent'] = fuzz.trimf(fout.universe, [0, 0.5, 2])
fout['good'] = fuzz.trimf(fout.universe, [0.5, 1, 1])
fout.view()
ferr.view()
fder.view()
plt.show()
plt.pause(0.0001)
#'poor'; 'mediocre'; 'average'; 'decent', or 'good'
rules=[]
rules.append(ctrl.Rule(ferr['average'] | fder['average'] , fout['average']))
rules.append(ctrl.Rule(ferr['decent'] | fder['decent'] , fout['decent']))
rules.append(ctrl.Rule(ferr['good'] | fder['good'] , fout['good']))
rules.append(ctrl.Rule(ferr['mediocre'] | fder['mediocre'] , fout['mediocre']))
rules.append(ctrl.Rule(ferr['poor'] | fder['poor'] , fout['poor']))
fctrl = ctrl.ControlSystem(rules)
fpid = ctrl.ControlSystemSimulation(fctrl)
pid=acspid.pidcont(1.2,0.02,0.01,5,-5)
pid2=acspid.pidcont(1.2,0.02,0.01,5,-5)
d=np.zeros(10)
for i in range(10):
d=np.append(d,np.ones(10)*np.random.uniform(-100,100,1))
print len(d)
m=[]
m.append(0.0)
m2=[]
m2.append(0.0)
e=[]
de=[]
e2=[]
de2=[]
kp=pid.kp
kd=pid.kd
ki=pid.ki
for i in range(len(d)):
pid.setDesired(d[i])
print "e:",pid.error ,"\t de:", pid.ed
fpid.input['ferr'] = pid.error
fpid.input['fder'] = pid.ed
fpid.compute()
newpid=np.abs(fpid.output['fout'])
print "PID:", newpid*pid.kp,"\t",newpid*pid.ki,"\t",newpid*pid.kd
pid.setGains(newpid*kp,newpid*ki,newpid*kd)
newm=pid.update(m[-1])
newm=m[-1]+newm
print i,m[-1],newm
m.append(newm)
e.append(pid.error)
de.append(pid.ed)
pid2.setDesired(d[i])
newm2=pid2.update(m2[-1])
newm2=m2[-1]+newm2
m2.append(newm2)
e2.append(pid2.error)
de2.append(pid2.ed)
ax1 =plt.subplot(2,1,1)
ax1.set_xlim([0, len(d)])
ax1.set_ylim([-200, 200])
plt.grid()
plt.plot(range(len(m)),m,linewidth=5.0)
plt.plot(range(len(m2)),m2,linewidth=2.0)
plt.plot(range(len(d)),d,'g--')
plt.title('Status')
ax2=plt.subplot(2,1,2)
ax2.set_xlim([0, 50])
ax2.set_ylim([-100, 100])
plt.plot(range(len(e)),e,'r-',range(len(de)),de,'g-')
plt.grid()
plt.title('e and ed')
#plt.draw()
plt.show()
plt.pause(0.0001)
模糊输入成员函数:
模糊输出成员函数:
状态:在状态图中,虚线是目标值,红色线是PID,绿色线是Fuzzy-PID
此处为acspid类
class pidcont():
def __init__(self,P,I,D,pmax,pmin):
self.kp=P
self.kd=D
self.ki=I
self.pidmax=pmax
self.pidmin=pmin
self.desired=0.0
self.error=0.0
self.elast=0.0
self.esum=0.0
self.eder=0.0
def update(self,current):
self.error=self.desired-current
self.eder=self.error-self.elast
self.elast=self.error
self.esum=self.esum+self.error
if self.esum>self.pidmax:
self.esum=self.pidmax
elif self.esum<self.pidmin:
self.esum=self.pidmin
self.P=self.kp*self.error
self.D=self.kd*self.eder
self.I=self.ki*self.esum
pid=self.P+self.I+self.D
return pid
def setDesired(self,d):
self.desired=d
def setGains(self,P,I,D):
self.kp=P
self.kd=D
self.ki=I
def setLimits(self,pmax,pmin):
self.pidmax=pmax
self.pidmin=pmin
评论
$ \ begingroup $
仅链接的答案无法提供对该方法的任何了解。如果您可以总结文章,将会很有帮助。
$ \ endgroup $
– Paul
16-11-28在19:28
$ \ begingroup $
@Paul,够了吗?
$ \ endgroup $
–acs
16-11-28在20:26
$ \ begingroup $
感谢@acs的全面答复。但是,在链接时,请尽量避免使用本文或类似的链接文本。链接容易腐烂,如果发生这种情况,则链接文本不会帮助任何人找到该页面。通常丢失的页面没有被删除,它们只是被移到了另一个位置。如果您将页面标题(以及论文的作者)作为链接文本给出,则对该文本的搜索通常会找到新的位置。
$ \ endgroup $
– Mark Booth♦
16年11月29日在11:16
$ \ begingroup $
@acs在上面的python代码(Fuzzy-PID)中,有一个名为(acspid)的导入库,没有它,代码无法实现。您能证明还是请展示一下,谢谢。
$ \ endgroup $
–艾哈迈德·费萨尔(Ahmed Faisal)
19年1月20日在22:36
$ \ begingroup $
@AhmedFaisal很抱歉未能及时回答。我添加了acspid类。
$ \ endgroup $
–acs
19年1月24日在20:24
评论
很抱歉这个问题,但是如果您使用的是模糊逻辑,为什么不只使用它来制作模糊逻辑控制器呢?它比PID具有更强大的功能,并且可以处理非线性。您能画出一个图表来显示如何连接传感器,执行器,PID和模糊逻辑系统吗?为什么PID不够好,无法控制机器人的位置?
您能提供参考的acspid源代码吗?