程式模擬的系統結構如下 軟體界面如下 第一張圖為執行機構的輸出u的變化曲線(第一個水箱的進水量) 第二張圖為第一個水箱(上水箱)的水位變化曲線 第三張圖為第二個水箱(下水箱)的水位變化曲線 控制面板如下 設定值預設為10 預設為自動控制,點擊手動控制按鈕後,控制對象的輸入u不會自動變化。 手動控制切 ...
程式模擬的系統結構如下
軟體界面如下
第一張圖為執行機構的輸出u的變化曲線(第一個水箱的進水量)
第二張圖為第一個水箱(上水箱)的水位變化曲線
第三張圖為第二個水箱(下水箱)的水位變化曲線
控制面板如下
設定值預設為10
預設為自動控制,點擊手動控制按鈕後,控制對象的輸入u不會自動變化。
手動控制切換自動控制未作無擾切換處理
輸入有限幅0~20,有抗積分飽和處理
python版本3.4.3,matplotlib版本1.5.1,numpy版本1.11.0
import matplotlib.pyplot as plt import numpy as np import time import threading import tkinter method=1 #method為1時自動控制,為其他值時手動控制 sp=10 #設定值 T1=10 #第一個水箱的參數 T2=20 #第二個水箱的參數 k1=1.5 #第一個水箱的參數 k2=1.2 #第二個水箱的參數 deltat=0.05 #模擬的步距 showt=0.5 #顯示的步距 #pid控制參數 kp=2 ki=0.05 kd=0 #輸出限幅 umax=20 umin=0 #初始化 y1=0 #第一個水箱的初始水位 y2=0 #第二個水箱的初始水位 t=0 #運行的時間 i=0 u=1 #第一個水箱的進水量 #三個顯示視窗的設置 p1=plt.subplot(3,1,1) p1.set_title('inflow u') p2=plt.subplot(3,1,2) p2.set_title('water level y1') p3=plt.subplot(3,1,3) p3.set_title('water level y2') plt.plot(0,0) def loop(): global y1,y2,t,i,u,sp Y1=[y1] Y2=[y2] T=[t] U=[u] xi=0 e0=0 while True: i=i+1 t=t+deltat #輸出限幅 if u<umin: u=umin if u>umax: u=umax #控制對象模擬 y1=(k1*u-y1)/T1*deltat+y1 y2=(k2*y1-y2)/T2*deltat+y2 T+=[t] Y1+=[y1] #記錄下第一個水箱的歷史水位 Y2+=[y2] #記錄下第二個水箱的歷史水位 U+=[u] #記錄下歷史輸入 if showt/deltat<=i : i=0 if method==1: #pid控制演算法 e=sp-y2 xp=kp*e xi=xi+ki*e xd=(e-e0)*kd/showt e0=e u=xp+xi+xd #抗積分飽和 if xp+xi>umax: xi=umax-xp if xp+xi<umin: xi=umin-xp p1.plot(T,U) p2.plot(T,Y1) p3.plot(T,Y2) p3.set_xlabel('y2=%.2f' %y2) plt.draw() time.sleep(showt) def gui(): global entrysp,entryu root=tkinter.Tk() framesp=tkinter.Frame(root) frameu=tkinter.Frame(root) frameam=tkinter.Frame(root) labelsp=tkinter.Label(framesp,text='設定值') labelu=tkinter.Label(frameu,text='輸入u ') entrysp=tkinter.Entry(framesp) entryu=tkinter.Entry(frameu) buttonsp=tkinter.Button(framesp,text='更改',command=gui_sp) buttonu=tkinter.Button(frameu,text='更改',command=gui_u) buttonm2a=tkinter.Button(frameam,text='自動控制',command=gui_m2a) buttona2m=tkinter.Button(frameam,text='手動控制',command=gui_a2m) framesp.pack() frameu.pack() frameam.pack() labelsp.pack(side='left') entrysp.pack(side='left') buttonsp.pack(side='left') labelu.pack(side='left') entryu.pack(side='left') buttonu.pack(side='left') buttonm2a.pack(side='left') buttona2m.pack(side='left') root.mainloop() def gui_sp(): global sp strsp=entrysp.get() sp=float(strsp) def gui_u(): global u stru=entryu.get() u=float(stru) def gui_m2a(): global method method=1 def gui_a2m(): global method method=0 threading.Thread(target=loop,args=()).start() threading.Thread(target=gui,args=()).start() plt.show()