Làm cách nào để điều chỉnh các tham số PID bằng Logic Mờ?


7

Trước đây tôi đã sử dụng phương pháp Ziegler để điều chỉnh các tham số của bộ điều khiển PID để điều khiển vị trí robot của tôi. Sau đó tôi đã triển khai logic mờ để tự điều chỉnh các tham số. Tôi có hai đầu vào cho bộ điều khiển logic mờ; một là lỗi vị trí và tỷ lệ lỗi.

Tôi biết rằng vấn đề của tôi có thể là do không hiểu rõ về ảnh hưởng của từng tham số.

Vấn đề là tôi bối rối trong việc thiết lập các quy tắc mờ. Khi nào tôi cần sử dụng các giá trị cao và thấp cho Kp, Kd và Ki để đạt được điều chỉnh tốt nhất? Có phải Kp phải rất thấp khi sai số gần như bằng không (do đó, robot ở vị trí mong muốn)? Câu hỏi tương tự áp dụng cho cả ba tham số.


Xin lỗi vì câu hỏi nhưng nếu bạn đang làm việc với logic mờ tại sao bạn không sử dụng nó để tạo bộ điều khiển logic mờ? Nó có khả năng hơn nhiều so với một PID và nó có thể xử lý các phi tuyến tính.
goncalo luis

1
Bạn có thể vẽ sơ đồ cho thấy các cảm biến, bộ truyền động, bộ điều khiển và hệ thống logic mờ của bạn sẽ được kết nối như thế nào không? Tại sao PID không đủ tốt để kiểm soát vị trí robot của bạn?
Ian

bạn có thể cung cấp mã nguồn acspid cho tài liệu tham khảo không, cảm ơn trước.
David

Câu trả lời:


9

Bài viết Điều khiển UAV Quadrotor sử dụng hệ thống mờ để điều chỉnh mức tăng của PID trong chế độ di chuột của E. Abbasi, MJ Mahjoob giải thích cách điều chỉnh mức tăng của PID bằng logic mờ. Bạn có thể tìm thấy nhiều bài viết về điều chỉnh singleton nhưng bài báo này cho thấy sự kiểm soát hoàn toàn mờ nhạt

  1. tìm mức tăng PID với ziegler-nichols (hoặc kỹ thuật khác)
  2. Tạo một bộ thay đổi khuếch đại PID mờ có lỗi đầu vào (e) và thay đổi lỗi (de)
  3. Xác định đồ thị độ mờ cho đầu vào và đầu ra. Xác định giới hạn (bạn cũng có thể thay đổi hình dạng) như

    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]

  4. tạo quy tắc như

    if **e** and/or **de** *fuzzyname* (small,big etc.) than KI is fuzzyname (small,big etc.)

  5. Chắc chắn kết quả.

Bạn có thể sử dụng các công cụ như hộp công cụ mờ matlab hoặc python skfuzzy

Vấn đề tới hạn có thể được sử dụng như Fuzzy-PID chỉ cần thay đổi Qualtiy thành e và dịch vụ như de và cuối cùng bạn có thể thay đổi đầu ra là KP / KI / KD (có ví dụ về vấn đề tới hạn: python scikit fuzzy - Hệ thống điều khiển mờ: Tipping Vấn đề )

Lưu ý 1: Phạm vi lỗi phải được xác định rõ để bạn phải ghi lại lỗi và thay đổi lỗi. Các giới hạn phải ở giá trị tối đa và tối thiểu của các giá trị này

Lưu ý 2: Phạm vi giá trị đầu ra là tốt giữa -1 và 1.

Một mã ví dụ cho Fuzzy-PID trong python có ở đây:

# -*- 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)

Chức năng thành viên đầu vào mờ: nhập mô tả hình ảnh ở đây

Chức năng thành viên đầu ra mờ: nhập mô tả hình ảnh ở đây

Trạng thái: Trong biểu đồ đường đứt nét là giá trị đích, đường màu đỏ là PID và đường màu xanh lá cây là Fuzzy-PID

Ở đây lớp học 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

nhập mô tả hình ảnh ở đây


Câu trả lời chỉ liên kết không cung cấp bất kỳ cái nhìn sâu sắc về phương pháp. Nó sẽ hữu ích nếu bạn có thể tóm tắt bài viết thay thế.
Paul

2
@Paul, thế này đã đủ chưa?
ac

2
Cảm ơn câu trả lời toàn diện @acs. Khi liên kết mặc dù, vui lòng cố gắng tránh sử dụng Giấy này hoặc tương tự như văn bản liên kết. Liên kết có xu hướng bị thối và nếu điều này xảy ra, văn bản liên kết không giúp ai tìm thấy trang. Các trang bị thiếu thường không được gỡ bỏ, chúng vừa được chuyển đến một vị trí khác. Nếu bạn đặt tiêu đề trang (và tác giả cho một bài báo) làm văn bản liên kết thì việc tìm kiếm văn bản đó thường sẽ tìm thấy vị trí mới.
Gian hàng Mark

1
@acs trong mã python ở trên (Fuzzy-PID) có thư viện nhập tên là (acspid), mã không được thực hiện mà không có nó. bạn có thể chứng minh nó hoặc hiển thị nó xin vui lòng, với cảm ơn.
Ahmed Faisal

@AhmedFaisal xin lỗi vì trả lời trễ. Tôi đã thêm lớp acspid.
acs
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.