创建界面,包括画布和按钮,分别输入P、I、D值,可以模拟pid调节。包括清除和重新绘制波形。
直接上代码和结果
import matplotlib matplotlib.use("Qt5Agg") # 声明使用QT5 from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PID3_figure import MyFigure from Ui_Dialog import Ui_Dialog from Ui_Dialog1 import Ui_Dialog1 from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from PyQt5 import QtWidgets from scipy.interpolate import make_interp_spline import time from PID3_pid import PID import matplotlib.pyplot as plt import numpy as np from shapely.geometry import Point import geopandas as gp class MainDialogImgBW(QDialog,Ui_Dialog): def __init__(self): super(MainDialogImgBW,self).__init__() self.setupUi(self) self.setWindowTitle("PID仿真工具") self.setMinimumSize(0,0) #第五步:定义MyFigure类的一个实例 self.F = MyFigure(width=300, height=300, dpi=100) #第六步:创建UI界面 self.myWidget() def myWidget(self): # set the layout 创建widget和layout V是垂直 H是水平 self.mlayout = QtWidgets.QVBoxLayout() #添加工具控件 self.addtoolWidget() #添加画布控件 self.addcanvasWidget() #添加按钮控件 self.addbuttonWidget() # 最外层窗口添加工具窗口 self.mlayout.addWidget(self.qwtool) # 最外层窗口添加一个画布的组合窗口 self.mlayout.addWidget(self.qwcanvas) # 最外层窗口添加一个按钮的组合窗口 self.mlayout.addWidget(self.qwbutton) # 显示最外层窗口 self.setLayout(self.mlayout) # 创建工具栏,并加入窗口中 #创建lauout和widget,把工具栏加入layout,再把layout加入widget def addtoolWidget(self): self.toolbar = NavigationToolbar(self.F.canvas, self) self.tollayout = QtWidgets.QVBoxLayout() self.tollayout.addWidget(self.toolbar) self.qwtool = QtWidgets.QWidget(self) self.qwtool.setLayout(self.tollayout) # 创建画布栏,并加入窗口中 #创建画布layout和widget,把画布加入layout,再把layout加入widget def addcanvasWidget(self): self.canlayout = QtWidgets.QHBoxLayout() self.canlayout.addWidget(self.F.canvas) self.qwcanvas = QtWidgets.QWidget(self) self.qwcanvas.setLayout(self.canlayout) #创建画布layout和widget,把画布加入layout,再把layout加入widget def addbuttonWidget(self): self.label2 = QtWidgets.QLabel('P') self.lineEdit2 = QtWidgets.QLineEdit('1.2') self.label3 = QtWidgets.QLabel('I') self.lineEdit3 = QtWidgets.QLineEdit('1') self.label4 = QtWidgets.QLabel('D') self.lineEdit4 = QtWidgets.QLineEdit('0.001') self.button5 = QtWidgets.QPushButton('绘制曲线') self.button6 = QtWidgets.QPushButton('清除曲线') self.btnlayout = QtWidgets.QHBoxLayout() self.btnlayout.addWidget(self.label2) self.btnlayout.addWidget(self.lineEdit2) self.btnlayout.addWidget(self.label3) self.btnlayout.addWidget(self.lineEdit3) self.btnlayout.addWidget(self.label4) self.btnlayout.addWidget(self.lineEdit4) self.btnlayout.addWidget(self.button5) self.btnlayout.addWidget(self.button6) self.btnlayout.addStretch() self.qwbutton = QtWidgets.QWidget(self) self.qwbutton.setLayout(self.btnlayout) #按钮点击事件 self.button5.clicked.connect(self.test_pid_new) self.button6.clicked.connect(self.abrasectl_new) # self.test_pid(1.2, 1, 0.001, L=80) #中间层封装 def test_pid_new(self): self.test_pid(1.2, 1, 0.001, L=80) # 中间层封装 def abrasectl_new(self): self.abrasectl() #PID算法及显示 def test_pid(self,P=1.2, I=1, D=0.001, L=80): Ptext = self.lineEdit2.text() P = float(Ptext) Itext = self.lineEdit3.text() I = float(Itext) Dtext = self.lineEdit4.text() D = float(Dtext) pid = PID(P, I, D) pid.SetPoint = 1 pid.setSampleTime(0.01) END = L feedback = 0 feedback_list = [] time_list = [] setpoint_list = [] for i in range(1, END): pid.update(feedback) output = pid.output if pid.SetPoint > 0: feedback += output # (output - (1/i))控制系统的函数 if i > 9: pid.SetPoint = 1 time.sleep(0.01) feedback_list.append(feedback) setpoint_list.append(pid.SetPoint) time_list.append(i) time_sm = np.array(time_list) time_smooth = np.linspace(time_sm.min(), time_sm.max(), 300) # print(time_smooth) feedback_smooth = make_interp_spline(time_list, feedback_list)(time_smooth) # print(feedback_smooth) plt.figure(0) self.F.axes.plot(time_smooth, feedback_smooth) self.F.axes.plot(time_list, setpoint_list) self.F.canvas.draw() # self.pts = gp.GeoSeries([Point(x, y) for x, y in zip(time_smooth, feedback_smooth)]) # self.pts.plot(ax=self.F.axes, marker='o', color='black', markersize=0.1) # self.pts1 = gp.GeoSeries([Point(x, y) for x, y in zip(time_smooth, setpoint_list)]) # self.pts1.plot(ax=self.F.axes, marker='o', color='black', markersize=0.1) # a = plt.plot(time_smooth, feedback_smooth) # plt.plot(time_list, setpoint_list) # #plt.xlim((0, L)) # #plt.ylim((min(feedback_list) - 0.5, max(feedback_list) + 0.5)) # plt.xlabel('time (s)') # plt.ylabel('PID (PV)') # plt.title('TEST PID') # #plt.ylim((1 - 0.5, 1 + 0.5)) # # plt.grid(True) # plt.show() #清除轨迹 def abrasectl(self): self.F.axes.clear() print("清除轨迹") self.F.canvas.draw()