zoukankan      html  css  js  c++  java
  • 水箱水位控制程序

    程序仿真的系统结构如下

    软件界面如下

    第一张图为执行机构的输出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()
    
    
    
            
  • 相关阅读:
    边框的作用之产生相对margin
    css3 实现切换显示隐藏效果
    Vue 获取数据、事件对象、todolist
    Vue 双向数据绑定、事件介绍以及ref获取dom节点
    Vue 目录结构分析 数据绑定 绑定属性 循环渲染数据 数据渲染
    Vue 安装环境创建项目
    进程&线程
    生成Excel
    JQuery input file 上传图片
    0908期 HTML 样式表属性
  • 原文地址:https://www.cnblogs.com/Arago/p/5447492.html
Copyright © 2011-2022 走看看