class AnimationWidget(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) vbox = QtGui.QVBoxLayout() self.canvas = MyMplCanvas(self, width=5, height=4, dpi=100) vbox.addWidget(self.canvas) hbox = QtGui.QHBoxLayout() self.start_button = QtGui.QPushButton("start", self) self.stop_button = QtGui.QPushButton("stop", self) self.start_button.clicked.connect(self.on_start) self.stop_button.clicked.connect(self.on_stop) hbox.addWidget(self.start_button) hbox.addWidget(self.stop_button) vbox.addLayout(hbox) self.setLayout(vbox) self.x = np.linspace(0, 5*np.pi, 400) self.p = 0.0 self.y = np.sin(self.x + self.p) self.line, = self.canvas.axes.plot(self.x, self.y, animated=True, lw=2) def update_line(self, i): self.p += 0.1 y = np.sin(self.x + self.p) self.line.set_ydata(y) return [self.line] def on_start(self): self.ani = FuncAnimation(self.canvas.figure, self.update_line, blit=True, interval=25) def on_stop(self): self.ani._stop()
class ApplicationWindow(QtWidgets.QMainWindow): def __init__(self): QtWidgets.QMainWindow.__init__(self) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("application main window") self.main_widget = QtWidgets.QWidget(self) vbox = QtWidgets.QVBoxLayout(self.main_widget) self.canvas = MyMplCanvas(self.main_widget, width=5, height=4, dpi=100) ###attention### vbox.addWidget(self.canvas) hbox = QtWidgets.QHBoxLayout(self.main_widget) self.start_button = QPushButton("start", self) self.stop_button = QPushButton("stop", self) self.exit_button = QPushButton("exit", self) self.start_button.clicked.connect(self.on_start) self.stop_button.clicked.connect(self.on_stop) self.exit_button.clicked.connect(self.on_exit) hbox.addWidget(self.start_button) hbox.addWidget(self.stop_button) hbox.addWidget(self.exit_button) vbox.addLayout(hbox) self.setLayout(vbox) self.main_widget.setFocus() self.setCentralWidget(self.main_widget) global n_drops global scat global rain_drops rain_drops = np.zeros(n_drops, dtype=[('position', float, 2)]) self.scat = self.canvas.axes.scatter(rain_drops['position'][:, 0], rain_drops['position'][:, 1], s=10, lw=0.5) def update_line(self, i): global n_drops global scat global rain_drops rain_drops['position'] = np.random.uniform(0, 100, (n_drops, 2)) self.scat.set_offsets(rain_drops['position']) return self.scat, def on_start(self): self.ani = FuncAnimation(self.canvas.figure, self.update_line, blit=True, interval=25) def on_stop(self): self.ani._stop() def on_exit(self): self.close()
class AnimationGui(HasTraits): figure = Instance(Figure, ()) system = Instance(Catenary, ()) view = View(Group(Group( Item("object.system.g"), Item("object.system.length"), Item("object.system.k"), Item("object.system.dump"), ), Item("figure", editor=MPLFigureEditor(toolbar=True)), show_labels=False, orientation='horizontal'), width=800, height=600, resizable=True) def __init__(self, **kw): super(AnimationGui, self).__init__(**kw) self.axe = self.figure.add_subplot(111) def start_timer(self): self.system.ode_init() self.line, = self.axe.plot(self.system.x, -self.system.y, "-o", animated=True) self.axe.set_xlim(-0.1, 1.1) self.axe.set_ylim(-1, 0.1) self.ani = FuncAnimation(self.figure, self.update_figure, blit=True, interval=20) def stop_timer(self): self.ani._stop() def update_figure(self, frame): self.system.ode_step(0.2) self.line.set_data(self.system.x, -self.system.y) return self.line,
class AnimationGui(HasTraits): figure = Instance(Figure, ()) system = Instance(Catenary, ()) view = View( Group( Group( Item("object.system.g"), Item("object.system.length"), Item("object.system.k"), Item("object.system.dump"), ), Item("figure", editor=MPLFigureEditor(toolbar=True)), show_labels = False, orientation = 'horizontal' ), width = 800, height = 600, resizable = True) def __init__(self, **kw): super(AnimationGui, self).__init__(**kw) self.axe = self.figure.add_subplot(111) def start_timer(self): self.system.ode_init() self.line, = self.axe.plot(self.system.x, -self.system.y, "-o", animated=True) self.axe.set_xlim(-0.1, 1.1) self.axe.set_ylim(-1, 0.1) self.ani = FuncAnimation(self.figure, self.update_figure, blit=True, interval=20) def stop_timer(self): self.ani._stop() def update_figure(self, frame): self.system.ode_step(0.2) self.line.set_data(self.system.x, -self.system.y) return self.line,
class AnimationWidget(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) vbox = QtGui.QVBoxLayout() self.canvas = MyMplCanvas(self, width=5, height=4, dpi=100) vbox.addWidget(self.canvas) hbox = QtGui.QHBoxLayout() self.start_button = QtGui.QPushButton("start", self) self.stop_button = QtGui.QPushButton("stop", self) self.start_button.clicked.connect(self.on_start) self.stop_button.clicked.connect(self.on_stop) hbox.addWidget(self.start_button) hbox.addWidget(self.stop_button) vbox.addLayout(hbox) self.setLayout(vbox) self.x = np.linspace(0, 5 * np.pi, 400) self.p = 0.0 self.y = np.sin(self.x + self.p) self.line, = self.canvas.axes.plot(self.x, self.y, animated=True, lw=2) def update_line(self, i): self.p += 0.1 y = np.sin(self.x + self.p) self.line.set_ydata(y) return [self.line] def on_start(self): self.ani = FuncAnimation(self.canvas.figure, self.update_line, blit=True, interval=25) def on_stop(self): self.ani._stop()
class AnimationWindow(wx.Frame): def __init__(self, parent, data_list, config=None, yvals=None, mode="1D", pks=None, pksmode="mz", *args, **kwargs): """ A simple window for animating mulitple 1D or 2D plots in a sequence. :param parent: Parent window. Passed to wx.Frame. :param data_list: List of data to be plotted :param config: UniDecConfig object :param yvals: Titles for the plots. :param mode: 1 = 1D plots, 2 = 2D plots :param args: :param kwargs: :return: None """ wx.Frame.__init__(self, parent, title="Plot Animations", size=(-1, -1)) # Initialize parameters if mode == "2D": self.mode = 2 else: self.mode = 1 if config is None: self.config = unidecstructure.UniDecConfig() self.config.initialize() else: self.config = config self.datalist = data_list self.pks = pks self.pksmode = pksmode if self.pksmode == "mz": self.xlabel = "m/z (Th)" self.testkda = False elif self.pksmode == "CCS": self.xlabel = "CCS" self.testkda = False else: self.xlabel = "Mass (Da)" self.testkda = True self.yvals = yvals if self.yvals is None: self.yvals = list(range(0, len(data_list))) self.dim = 1 self.pos = -1 self.play = False self.animation = None # Create GUI # Make the menu filemenu = wx.Menu() menu_save_fig = filemenu.Append(wx.ID_ANY, "Save Figures", "Save all figures at selected path") self.Bind(wx.EVT_MENU, self.on_save_fig, menu_save_fig) menu_bar = wx.MenuBar() menu_bar.Append(filemenu, "&File") self.SetMenuBar(menu_bar) self.CreateStatusBar(2) panel = wx.Panel(self) sizer = wx.BoxSizer(wx.VERTICAL) if self.mode == 1: self.plot = plot1d.Plot1d(panel) else: self.plot = plot2d.Plot2d(panel) sizer.Add(self.plot, 0, wx.EXPAND) controlsizer = wx.BoxSizer(wx.HORIZONTAL) sb = wx.StaticBox(panel, label='Frame Rate (ms/frame)') sbs = wx.StaticBoxSizer(sb, orient=wx.VERTICAL) frmax = 2000 frmin = 1 self.frslider = wx.Slider( panel, wx.ID_ANY, 500, frmin, frmax, (30, 60), (250, -1), wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS) self.frslider.SetTickFreq(100) sbs.Add(self.frslider, 0, wx.EXPAND) self.Bind(wx.EVT_COMMAND_SCROLL_THUMBRELEASE, self.update_framerate, self.frslider) controlsizer.Add(sbs, 0, wx.EXPAND) self.playbutton = wx.ToggleButton(panel, label="Play") self.nextbutton = wx.Button(panel, label="Next") self.backbutton = wx.Button(panel, label="Back") controlsizer.Add(self.backbutton, 0, wx.EXPAND) controlsizer.Add(self.playbutton, 0, wx.EXPAND) controlsizer.Add(self.nextbutton, 0, wx.EXPAND) self.Bind(wx.EVT_TOGGLEBUTTON, self.on_play, self.playbutton) self.Bind(wx.EVT_BUTTON, self.on_next, self.nextbutton) self.Bind(wx.EVT_BUTTON, self.on_back, self.backbutton) self.ctlautoscale = wx.CheckBox(panel, label="Autoscale") controlsizer.Add(self.ctlautoscale, 0, wx.EXPAND) if self.mode == 2: self.ctlautoscale.SetValue(True) sizer.Add(controlsizer, 0, wx.EXPAND) panel.SetSizer(sizer) sizer.Fit(self) self.Bind(wx.EVT_CLOSE, self.on_close, self) self.init() self.Centre() self.Show(True) def on_close(self, e): """ Stop the animation and close the window. :param e: Unused event :return: None """ print("Closing") try: self.animation._stop() except: pass self.Destroy() def update(self, frame_number): """ Continues to increment the plot to the next value in the data_list. Will stop if self.play is False. :param frame_number: Required but unused. Filled by FuncAnimation. :return: 0 """ if self.play: self.pos += 1 self.update_plot() return 0 else: return 0 def update_plot(self): """ Increment to the next data set and update the plot with the new data. Tries to keep some of the old plotting parameters like the zoom the same. Stops the animation if an error occurs. :return: None """ try: if self.pks is not None: self.refresh_plot() self.add_peaks() return self.pos %= len(self.datalist) newdata = self.datalist[self.pos] title = str(self.yvals[self.pos]) if self.mode == 1: # 1D Plot line = self.plot.subplot1.lines[0] xlim = self.plot.subplot1.get_xlim() ylim = self.plot.subplot1.get_ylim() line.set_data(newdata[:, 0], newdata[:, 1]) self.plot.subplot1.set_title(title) autoflag = self.ctlautoscale.GetValue() if autoflag: self.plot.subplot1.set_autoscale_on(True) self.plot.subplot1.relim() self.plot.subplot1.autoscale_view(True, True, True) else: self.plot.subplot1.set_xlim(xlim) self.plot.subplot1.set_ylim(ylim) self.plot.repaint() else: # 2D plot xlim = self.plot.subplot1.get_xlim() ylim = self.plot.subplot1.get_ylim() self.plot.contourplot(newdata, self.config, xlab=self.xlabel, title=title, repaint=False) autoflag = self.ctlautoscale.GetValue() if not autoflag: self.plot.subplot1.set_xlim(xlim) self.plot.subplot1.set_ylim(ylim) self.plot.add_title(title) self.plot.repaint() except Exception as e: self.animation._stop() print(e) def init(self): """ Create a fresh plot and start the animation. :return: None """ self.pos = 0 self.refresh_plot() self.animation = FuncAnimation(self.plot.figure, self.update, interval=500) self.animation._start() def on_play(self, e): """ Toggles self.play on or off. Will break the while loop in self.update if self.play = False. :param e: Unused event :return: None """ tog = self.playbutton.GetValue() if tog: self.play = True else: self.play = False pass def refresh_plot(self): """ Create a fresh plot from the top. :return: None """ self.pos %= len(self.datalist) newdata = self.datalist[self.pos] title = str(self.yvals[self.pos]) if self.mode == 1: self.plot.plotrefreshtop(newdata[:, 0], newdata[:, 1], title, self.xlabel, "Intensity", "", self.config, test_kda=self.testkda) self.plot.add_title(title) if self.pks is not None: self.add_peaks() else: self.plot.contourplot(newdata, self.config, xlab=self.xlabel, title=title) self.plot.add_title(title) def on_next(self, e): """ Plot the next data set in data_list. :param e: Unused event :return: None """ self.pos += 1 self.update_plot() pass def on_back(self, e): """ Plot the previous data set in data_list. :param e: Unused event :return: None """ self.pos -= 1 self.update_plot() pass def update_framerate(self, e): """ Change the frame rate. Restart the animation with fresh frame rate. :param e: Unused event :return: None """ framerate = self.frslider.GetValue() # print "Updated framerate to:", framerate # self.animation._interval=framerate # self.animation.new_frame_seq() self.animation._stop() self.animation = FuncAnimation(self.plot.figure, self.update, interval=framerate) self.animation._start() def add_peaks(self, e=None): if self.pksmode == "mz": self.add_peaks_mz() else: self.add_peaks_mass() def add_peaks_mz(self, e=None): for p in self.pks.peaks: if p.ignore == 0: list1 = [] list2 = [] mztab = p.mztab[self.pos] mztab2 = p.mztab2[self.pos] if (not ud.isempty(mztab)) and (not ud.isempty(mztab2)): mztab = np.array(mztab) mztab2 = np.array(mztab2) maxval = np.amax(p.mztab[:, :, 1]) for k in range(0, len(mztab)): if mztab[k, 1] > self.config.peakplotthresh * maxval: list1.append(mztab2[k, 0]) list2.append(mztab2[k, 1]) # print mztab[k] self.plot.plotadddot(np.array(list1), np.array(list2), p.color, p.marker) self.plot.repaint() def add_peaks_mass(self, e=None): for p in self.pks.peaks: if p.ignore == 0: pos = ud.nearest(self.datalist[self.pos][:, 0], p.mass) data = self.datalist[self.pos][pos] if data[1] > self.config.peakplotthresh * np.amax( self.datalist[self.pos][:, 1]): self.plot.plotadddot(data[0], data[1], p.color, p.marker) self.plot.repaint() def on_save_fig(self, e=None): path = FileDialogs.save_file_dialog() base, ext = os.path.splitext(path) #self.init() #self.save_fig(base,ext) for i in range(0, len(self.datalist)): self.on_next(None) self.save_fig(base, ext) def save_fig(self, base, ext): path = base + str(self.pos) + ext print(self.pos, path) self.plot.save_figure(path)
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(980, 460) self.time = time.time() self.started = False self.x = [0] self.y = [1] # 布局 self.canvas = MyCanvas(self, width=5, height=4, dpi=100) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") # 小部件布局 self.label = QtWidgets.QLabel(self.centralwidget) self.label.setGeometry(QtCore.QRect(260, 20, 60, 20)) self.label.setObjectName("label") self.QLineEdit = QtWidgets.QLineEdit(self.centralwidget) self.QLineEdit.setGeometry(QtCore.QRect(260, 50, 140, 18)) self.QLineEdit.setObjectName("QLineEdit") self.QLineEdit.setReadOnly(True) self.label_1 = QtWidgets.QLabel(self.centralwidget) self.label_1.setGeometry(QtCore.QRect(260, 90, 60, 20)) self.label_1.setObjectName("label_1") self.QLineEdit_1 = QtWidgets.QLineEdit(self.centralwidget) self.QLineEdit_1.setGeometry(QtCore.QRect(260, 120, 140, 18)) self.QLineEdit_1.setObjectName("QLineEdit_1") self.QLineEdit_1.setReadOnly(True) self.label_2 = QtWidgets.QLabel(self.centralwidget) self.label_2.setGeometry(QtCore.QRect(260, 165, 60, 20)) self.label_2.setObjectName("label_2") self.QLineEdit_2 = QtWidgets.QLineEdit(self.centralwidget) self.QLineEdit_2.setGeometry(QtCore.QRect(260, 195, 140, 18)) self.QLineEdit_2.setObjectName("QLineEdit_2") self.QLineEdit_2.setReadOnly(True) # 大部件布局 self.listWidget = QtWidgets.QListWidget(self.centralwidget) self.listWidget.setGeometry(QtCore.QRect(10, 20, 220, 192)) self.listWidget.setObjectName("listWidget") self.listWidget.addItem("%2s%13s%15s"%('编号','进入时间','服务时间')) self.textList = QtWidgets.QTextEdit(self.centralwidget) self.textList.setGeometry(QtCore.QRect(10, 230, 400, 200)) self.textList.setObjectName("textList") self.groupBox = QtWidgets.QGroupBox(self.centralwidget) self.groupBox.setGeometry(QtCore.QRect(420, 20, 550, 420)) self.groupBox.setObjectName("groupBox") # self.textList.setStyleSheet("background-color:black") # self.textList.setTextColor(QtGui.QColor(255, 255, 255)) self.textList.setReadOnly(True) self.gridlayout = QtWidgets.QGridLayout(self.groupBox) # 继承容器groupBox self.gridlayout.addWidget(self.canvas) # 多余布局 # self.pushButton = QtWidgets.QPushButton(self.centralwidget) # self.pushButton.setGeometry(QtCore.QRect(330, 370, 75, 23)) # self.pushButton.setObjectName("pushButton") # self.pushButton0 = QtWidgets.QPushButton(self.centralwidget) # self.pushButton0.setGeometry(QtCore.QRect(420, 370, 75, 23)) # self.pushButton0.setObjectName("pushButton0") # self.pushButton.setVisible(False) # self.pushButton0.setVisible(False) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 660, 23)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) # 事件 self.listWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) #参数QtCore.Qt.CustomContextMenu self.contextMenu = QtWidgets.QMenu() self.outContextMenu = QtWidgets.QMenu() self.actionIns = self.outContextMenu.addAction(QtGui.QIcon("./resource/+.png"), u'| 添加') self.listWidget.customContextMenuRequested[QtCore.QPoint].connect(self.showMenu) self.actionIns.triggered.connect(self.insertItem) self.line, = self.canvas.axes.plot(self.x, self.y, animated=True, lw=2) # self.canvas.axes.set_xlim([0, 100]) # self.canvas.axes.set_ylim([0, 10]) self.canvas.axes.set_xbound(0,100) self.canvas.axes.set_ybound(0,10) # self.canvas.axes.set_xlabel(u'时间') # self.canvas.axes.set_ylabel(u'线程id') # self.pushButton.clicked.connect(self.on_start) # self.pushButton0.clicked.connect(self.on_stop) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "多级轮转抢占式")) # self.pushButton.setText(_translate("MainWindow", "开始")) # self.pushButton0.setText(_translate("MainWindow", "暂停")) self.label.setText(_translate("MainWindow", "队列一:")) self.label_1.setText(_translate("MainWindow", "队列二:")) self.label_2.setText(_translate("MainWindow", "队列三:")) # 添加方法 def insertItem(self): self.getText() global NUM NUM += 1 # 输入对话框 def getText(self): server, okPressed = QtWidgets.QInputDialog.getText(self.centralwidget, "服务时间", "请输入该线程的服务时间:", QtWidgets.QLineEdit.Normal, "") if okPressed and server.isdigit(): if self.listWidget.count() == 1: # self.pushButton.setVisible(True) # self.pushButton0.setVisible(True) global startTime startTime = time.time() first = NUM second = int(time.time() - startTime) thrid = int(server) Process = process.process(NUM, second, int(server)) # 线程处理数据 self.apply = multiply.applyRound(True, 0,self) self.apply.dictP[NUM] = Process self.apply.start() # 启动画图 self.on_start() else: first = NUM second = self.apply.allTime thrid = int(server) print('新的线程加入队列...') Process = process.process(NUM, second, int(server)) self.apply.hasSomeProcessCome = True self.apply.dictP[NUM] = Process s = (f' {str(first)}\t{str(second)}\t {str(thrid)}') self.listWidget.addItem(s) # 显示列表菜单 def showMenu(self,point): item = self.listWidget.itemAt(point) if item: pass else: self.outContextMenu.show() self.outContextMenu.exec_(QtGui.QCursor.pos()) # 暂停 def stopThread(self): pass # 开始 def awaitThread(self): pass # 以下均为画图 # 更新 def update_line(self, i): # i = time.time() - self.time # self.canvas.axes.cla() # self.x.append(i) # self.y.append(i * random.randint(0, 2)) # print(self.x) # print(self.y) # 更新方法一 # self.canvas.axes.set_xlim([0, max(self.x) + 1]) # self.canvas.axes.set_ylim([0, max(self.y) + 1]) # self.canvas.axes.update_datalim([[0, max(self.x) + 1],[0, max(self.y) + 1]]) # 更新方法二 # self.canvas.axes.cla() # self.canvas.axes.set_xbound(0, max(self.x) + 1) # self.canvas.axes.set_ybound(0, max(self.y) + 1) # 更新方法三 # self.canvas.axes.set_xticks([0, max(self.x) + 1]) # self.canvas.axes.set_yticks([0, max(self.y) + 1]) # self.canvas.axes.set_axis_on() # 以上方法都没有什么用 self.line.set_xdata(self.x) self.line.set_ydata(self.y) return [self.line] # 开始暂停(开始) def on_start(self): if self.started: pass else: self.ani = FuncAnimation(self.canvas.figure, self.update_line, blit=True, interval=1050) self.started = True # 开始暂停(暂停) def on_stop(self): if self.started: self.ani._stop() self.started = False else: self.ani._stop()
class ConcreteSimulation(AbstractSimulation, ObserverClient): def __init__(self): super().__init__() plt.ioff() self.DPI = MainConfiguration().DPI self.ani = None self.fig = plt.figure(figsize=(self.width / self.DPI, self.height / self.DPI), dpi=self.DPI) self.fig.subplots_adjust(left=0, bottom=0.05, right=0.95, top=1, wspace=0, hspace=0) self.fig.patch.set_facecolor(Theme().default_bg) self.ax = self.fig.add_subplot() for spine in self.ax.spines.values(): spine.set_visible(False) self.days = 0 self.ax.set_facecolor(Theme().plot_bg) self.fig.set_edgecolor(Theme().plot_bg) self.ax.set_xticks([]) self.ax.set_yticks([]) self.last_core_radius = MainConfiguration().SUBJECT_SIZE * 2 self.last_infection_radius = ( MainConfiguration().SUBJECT_INFECTION_RADIUS + MainConfiguration().SUBJECT_SIZE) * 2 self.ax.plot() self.draw_standby_pattern() def get_init_func(self): self.days = 0 if MainConfiguration().QUARANTINE_MODE.get(): ConcreteSimulation.draw_quarantine_boundaries(self.ax) if MainConfiguration().COMMUNITY_MODE.get(): ConcreteSimulation.draw_community_boundaries_on_ax(self.ax) else: ConcreteSimulation.draw_main_simulation_canvas_movement_bounds( self.ax) self.ax.set_xticks([]) self.ax.set_yticks([]) self.ax.set_xlim(0, self.width) self.ax.set_ylim(0, self.height) #self.ax.axis('off') self._box_of_particles.count_them() self.previous_infected = len( self._box_of_particles.counts["INFECTED"]) + len( self._box_of_particles.counts["ASYMPTOMATIC"]) self.previous_r = 1 self.notify(self._box_of_particles.counts) self.notify({ "DAY": 0, "R_RATE": "{:.2f}".format(self.previous_r), "R_GROWTH": "0.0%" }) self.ax.plot([], marker=".", fillstyle="full", linestyle="", color=Theme().immune, markersize=self.last_core_radius) self.ax.plot([], marker=".", fillstyle="none", linestyle="", color=Theme().immune, markersize=self.last_infection_radius) # susceptible self.ax.plot([], marker=".", fillstyle="full", linestyle="", color=Theme().susceptible, markersize=self.last_core_radius) self.ax.plot([], marker=".", fillstyle="none", color=Theme().susceptible, linestyle="", markersize=self.last_infection_radius) # asymptomatic self.ax.plot([], marker=".", fillstyle="full", linestyle="", color=Theme().asymptomatic, markersize=self.last_core_radius) self.ax.plot([], marker=".", fillstyle="none", color=Theme().asymptomatic, linestyle="", markersize=self.last_infection_radius) # infected self.ax.plot([], marker=".", fillstyle="full", linestyle="", color=Theme().infected, markersize=self.last_core_radius) self.ax.plot([], marker=".", fillstyle="none", color=Theme().infected, linestyle="", markersize=self.last_infection_radius) def func(): return self.ax.lines return func def get_animation_function(self): def func(i): frames_per_day = MainConfiguration().get_frames_per_day() self.move_guys(i) if i % frames_per_day == 0 and i != 0: self.days += 1 r_rate = self._box_of_particles.r_rate try: r_growth = (r_rate - self.previous_r) / self.previous_r except ZeroDivisionError: r_growth = 0 self.previous_r = r_rate r_rate = "{0:.2f}".format(r_rate) r_growth = "{0:.2f}%".format(r_growth * 100) self.notify({ "DAY": int(self.days), "R_RATE": r_rate, "R_GROWTH": r_growth }) self.notify(self._box_of_particles.counts) infected_coords = self.get_current_coordinates_by_key("INFECTED") immune_coords = self.get_current_coordinates_by_key("IMMUNE") susceptible_coords = self.get_current_coordinates_by_key( "SUSCEPTIBLE") asymptomatic_coords = self.get_current_coordinates_by_key( "ASYMPTOMATIC") self.ax.lines[0].set_data(*immune_coords) self.ax.lines[1].set_data(*immune_coords) self.ax.lines[2].set_data(*susceptible_coords) self.ax.lines[3].set_data(*susceptible_coords) self.ax.lines[4].set_data(*asymptomatic_coords) self.ax.lines[5].set_data(*asymptomatic_coords) self.ax.lines[6].set_data(*infected_coords) self.ax.lines[7].set_data(*infected_coords) core_radius = MainConfiguration().SUBJECT_SIZE * 2 infection_radius = (MainConfiguration().SUBJECT_INFECTION_RADIUS + MainConfiguration().SUBJECT_SIZE) * 2 if core_radius != self.last_core_radius or infection_radius != self.last_infection_radius: self.last_core_radius = core_radius self.last_infection_radius = infection_radius self.ax.lines[0].set_markersize(core_radius) self.ax.lines[1].set_markersize(infection_radius) self.ax.lines[0].set_markersize(core_radius) self.ax.lines[1].set_markersize(infection_radius) self.ax.lines[2].set_markersize(core_radius) self.ax.lines[3].set_markersize(infection_radius) self.ax.lines[4].set_markersize(core_radius) self.ax.lines[5].set_markersize(infection_radius) self.ax.lines[6].set_markersize(core_radius) self.ax.lines[7].set_markersize(infection_radius) # self._box_of_particles .print_counts()""" return self.ax.lines return func def start(self): for x in self.fig.axes: x.clear() init_func = self.get_init_func() animation_function = self.get_animation_function() self.ani = FuncAnimation(self.fig, animation_function, init_func=init_func, interval=1000 / MainConfiguration().FRAMES_PER_SECOND, blit=True) return self.ani def reset(self): self._marker_radius = MainConfiguration().SUBJECT_SIZE self._infection_zone_radius = MainConfiguration( ).SUBJECT_INFECTION_RADIUS + MainConfiguration().SUBJECT_SIZE self.pause() if self.ani is not None: self.ani._stop() self.ani = None del self._box_of_particles #self.ani = None self._box_of_particles = DefaultContainer() if MainConfiguration().COMMUNITY_MODE.get() is not True\ else CommunitiesContainer() for x in self.fig.axes: x.clear() self.ax.set_xticks([]) self.ax.set_yticks([]) #self.start() self.notify(None) self.draw_standby_pattern() self.ax.plot() self.fig.canvas.draw() def resume(self): if self.ani is not None: self.ani.event_source.start() def pause(self): if self.ani is not None: self.ani.event_source.stop() @staticmethod def draw_community_boundaries_on_ax(ax): cells = MainConfiguration().get_community_cells_border_bounds() for cell in cells: x = cell[0][0] y = cell[1][0] width = cell[0][1] - x height = cell[1][1] - y ax.add_patch( patches.Rectangle((x, y), width, height, facecolor="none", linewidth=1, edgecolor=Theme().infected, linestyle="--")) @staticmethod def draw_quarantine_boundaries(ax): if MainConfiguration().QUARANTINE_MODE.get(): q_dims = MainConfiguration().get_quarantine_dimensions() inner_padding = MainConfiguration().INNER_PADDING ax.text(q_dims["x"] + inner_padding, q_dims["y"] + inner_padding, "QUARANTINE", color=Theme().infected, fontsize="large", rotation=90) ax.add_patch( patches.Rectangle((q_dims["x"], q_dims["y"]), q_dims["width"], q_dims["height"], facecolor="none", linewidth=1, edgecolor=Theme().infected, linestyle="--")) @staticmethod def draw_main_simulation_canvas_movement_bounds(ax): q_dims = MainConfiguration().get_particle_movement_border_bounds() ax.add_patch( patches.Rectangle((q_dims[0, 0], q_dims[1, 0]), q_dims[0, 1] - q_dims[0, 0], q_dims[1, 1] - q_dims[1, 0], facecolor="none", linewidth=1, edgecolor=Theme().infected, linestyle="--")) def draw_standby_pattern(self): self.ax.set_xticks([]) self.ax.set_yticks([]) self.ax.set_xlim(0, self.width) self.ax.set_ylim(0, self.height) q_dims = MainConfiguration().get_simulation_canvas_total_bounds() self.ax.add_patch( patches.Rectangle( (q_dims[0, 0] + MainConfiguration().INNER_PADDING, q_dims[1, 0] + MainConfiguration().INNER_PADDING), q_dims[0, 1] - q_dims[0, 0] - 2 * MainConfiguration().INNER_PADDING, q_dims[1, 1] - q_dims[1, 0] - 2 * MainConfiguration().INNER_PADDING, facecolor="none", linewidth=1, edgecolor=Theme().infected, linestyle="--")) width = MainConfiguration().get_simulation_canvas_total_bounds()[0][1] self.ax.text(width - 330, 2 * MainConfiguration().INNER_PADDING, "Simulation area - standby".upper(), color=Theme().infected, fontsize="x-large", rotation=0)
class RunAnalysisInput(QDialog): def __init__(self, project, analysis_ID, analysis_type_label, *args, **kwargs): super().__init__(*args, **kwargs) uic.loadUi('data/user_input/ui/Analysis/runAnalysisInput.ui', self) icons_path = 'data\\icons\\' self.icon = QIcon(icons_path + 'pulse.png') self.setWindowIcon(self.icon) self.setWindowFlags(Qt.WindowStaysOnTopHint) # self.setWindowModality(Qt.WindowModal) self.label_title = self.findChild(QLabel, 'label_title') self.label_message = self.findChild(QLabel, 'label_message') self.label_message.setWordWrap(True) self.config_title_font() self.config_message_font() self.project = project self.solve = None self.analysis_ID = analysis_ID self.analysis_type_label = analysis_type_label self.frequencies = self.project.frequencies self.damping = self.project.global_damping self.modes = self.project.modes self.solution_acoustic = None self.solution_structural = None self.convergence_dataLog = None self.natural_frequencies_acoustic = [] self.natural_frequencies_structural = [] self.complete = False LoadingScreen('SOLUTION IN PROGRESS', 'Processing the cross-sections', target=self.process_cross_sections, project=project) if self.project.preprocessor.stop_processing: self.project.preprocessor.stop_processing = False return LoadingScreen('SOLUTION IN PROGRESS', 'Preparing the model to solve', target=self.preparing_mathematical_model_to_solve) self.pre_non_linear_convergence_plot() LoadingScreen('SOLUTION IN PROGRESS', 'Solving the analysis', target=self.process_analysis, project=project) self.post_non_linear_convergence_plot() if self.project.preprocessor.stop_processing: self.reset_all_results() self.project.preprocessor.stop_processing = False else: LoadingScreen('SOLUTION IN PROGRESS', 'Post-processing the obtained results', target=self.post_process_results) self.exec() self.check_warnings() def pre_non_linear_convergence_plot(self): if isinstance(self.solve, SolutionAcoustic): if self.analysis_ID in [3,5,6]: if self.solve.non_linear: fig = plt.figure(figsize=[8,6]) ax = fig.add_subplot(1,1,1) self.anime = FuncAnimation(fig, self.solve.graph_callback, fargs=(fig,ax), interval=2000) self.anime._start() plt.ion() plt.show() def post_non_linear_convergence_plot(self): if isinstance(self.solve, SolutionAcoustic): if self.analysis_ID in [3,5,6]: if self.solve.non_linear: self.anime._stop() def process_cross_sections(self): t0i = time() self.complete = False self.project.process_cross_sections_mapping() self.project.time_to_process_cross_sections = time() - t0i def preparing_mathematical_model_to_solve(self): t0 = time() if self.analysis_ID in [0,1,3,5,6]: if self.frequencies is None: return if len(self.frequencies) == 0: return if self.project.preprocessor._process_beam_nodes_and_indexes(): if self.analysis_ID not in [0,1,2]: title = "INCORRECT ANALYSIS TYPE" message = "There are only BEAM_1 elements in the model, therefore, \nonly structural analysis are allowable." info_text = [title, message, window_title_2] PrintMessageInput(info_text) return if self.analysis_ID == 2: self.project.preprocessor.enable_fluid_mass_adding_effect(reset=True) self.solve = self.project.get_structural_solve() elif self.analysis_ID == 4: self.solve = self.project.get_acoustic_solve() elif self.analysis_ID == 3: self.solve = self.project.get_acoustic_solve() elif self.analysis_ID in [5,6]: self.project.preprocessor.enable_fluid_mass_adding_effect() self.solve = self.project.get_acoustic_solve() else: self.project.preprocessor.enable_fluid_mass_adding_effect(reset=True) self.solve = self.project.get_structural_solve() self.project.time_to_preprocess_model = time() - t0 def process_analysis(self): t0 = time() if self.analysis_ID == 0: self.solution_structural = self.solve.direct_method(self.damping) # Structural Harmonic Analysis - Direct Method elif self.analysis_ID == 1: # Structural Harmonic Analysis - Mode Superposition Method self.solution_structural = self.solve.mode_superposition(self.modes, self.damping) elif self.analysis_ID == 3: # Acoustic Harmonic Analysis - Direct Method self.solution_acoustic, self.convergence_dataLog = self.solve.direct_method() elif self.analysis_ID == 5: # Coupled Harmonic Analysis - Direct Method t0_acoustic = time() self.solution_acoustic, self.convergence_dataLog = self.solve.direct_method() #Acoustic Harmonic Analysis - Direct Method self.project.time_to_solve_acoustic_model = time() - t0_acoustic self.project.set_acoustic_solution(self.solution_acoustic) self.solve = self.project.get_structural_solve() t0_structural = time() self.solution_structural = self.solve.direct_method(self.damping) #Coupled Harmonic Analysis - Direct Method self.project.time_to_solve_structural_model = time() - t0_structural elif self.analysis_ID == 6: # Coupled Harmonic Analysis - Mode Superposition Method t0_acoustic = time() self.solution_acoustic, self.convergence_dataLog = self.solve.direct_method() #Acoustic Harmonic Analysis - Direct Method self.project.time_to_solve_acoustic_model = time() - t0_acoustic self.project.set_acoustic_solution(self.solution_acoustic) self.solve = self.project.get_structural_solve() t0_structural = time() self.solution_structural = self.solve.mode_superposition(self.modes, self.damping) self.project.time_to_solve_structural_model = time() - t0_structural elif self.analysis_ID == 2: # Structural Modal Analysis self.natural_frequencies_structural, self.solution_structural = self.solve.modal_analysis(modes = self.modes, sigma=self.project.sigma) elif self.analysis_ID == 4: # Acoustic Modal Analysis self.natural_frequencies_acoustic, self.solution_acoustic = self.solve.modal_analysis(modes = self.modes, sigma=self.project.sigma) self.project.time_to_solve_model = time() - t0 if isinstance(self.solve, SolutionAcoustic): if self.analysis_ID in [3,5,6]: if self.solve.non_linear: sleep(2) def post_process_results(self): t0 = time() self.project.set_perforated_plate_convergence_dataLog(self.convergence_dataLog) if self.analysis_ID == 2: if self.solution_structural is None: return self.project.set_structural_solution(self.solution_structural) self.project.set_structural_natural_frequencies(self.natural_frequencies_structural.tolist()) elif self.analysis_ID == 4: if self.solution_acoustic is None: return self.project.set_acoustic_solution(self.solution_acoustic) self.project.set_acoustic_natural_frequencies(self.natural_frequencies_acoustic.tolist()) elif self.analysis_ID == 3: if self.solution_acoustic is None: return self.project.set_acoustic_solution(self.solution_acoustic) elif self.analysis_ID in [0,1,5,6]: if self.solution_structural is None: return self.project.set_structural_solve(self.solve) self.project.set_structural_solution(self.solution_structural) self.dict_reactions_at_constrained_dofs = self.solve.get_reactions_at_fixed_nodes(self.damping) self.dict_reactions_at_springs, self.dict_reactions_at_dampers = self.solve.get_reactions_at_springs_and_dampers() self.project.set_structural_reactions([ self.dict_reactions_at_constrained_dofs, self.dict_reactions_at_springs, self.dict_reactions_at_dampers ]) self.project.time_to_postprocess = time() - t0 _times = [self.project.time_to_process_cross_sections, self.project.time_to_preprocess_model, self.project.time_to_solve_model, self.project.time_to_postprocess] self.project.total_time = sum(_times) self.print_final_log() self.complete = True def check_warnings(self): # WARNINGS REACHED DURING SOLUTION title = self.analysis_type_label message = "" if self.analysis_type_label == "Harmonic Analysis - Structural": if self.solve.flag_ModeSup_prescribed_NonNull_DOFs: message = self.solve.warning_ModeSup_prescribedDOFs if self.solve.flag_Clump and self.analysis_ID==1: message = self.solve.warning_Clump[0] if self.analysis_type_label == "Modal Analysis - Structural": if self.solve.flag_Modal_prescribed_NonNull_DOFs: message = self.solve.warning_Modal_prescribedDOFs[0] if message != "": PrintMessageInput([title, message, window_title_2]) def reset_all_results(self): self.solution_structural = None self.solution_acoustic = None if self.analysis_ID == 2: self.project.set_structural_solution(None) self.project.set_structural_natural_frequencies(None) elif self.analysis_ID == 4: self.project.set_acoustic_solution(None) self.project.set_acoustic_natural_frequencies(None) elif self.analysis_ID == 3: self.project.set_acoustic_solution(None) elif self.analysis_ID in [0,1,5,6]: self.project.set_acoustic_solution(None) self.project.set_structural_solution(None) self.project.set_structural_reactions([ {}, {}, {} ]) def config_title_font(self): font = QFont() font.setPointSize(19) font.setBold(True) font.setItalic(True) font.setFamily("Arial") # font.setWeight(60) self.label_title.setFont(font) self.label_title.setStyleSheet("color:black") def config_message_font(self): font = QFont() font.setPointSize(17) font.setBold(True) # font.setItalic(True) font.setFamily("Arial") # font.setWeight(60) self.label_message.setFont(font) self.label_message.setStyleSheet("color:blue") def print_final_log(self): text = "Solution finished!\n\n" # text += "Time to check all entries: {} [s]\n".format(round(self.project.time_to_checking_entries, 6)) text += "Time to load/create the project: {} [s]\n".format(round(self.project.time_to_load_or_create_project, 4)) text += "Time to process cross-sections: {} [s]\n".format(round(self.project.time_to_process_cross_sections, 4)) text += "Time elapsed in pre-processing: {} [s]\n".format(round(self.project.time_to_preprocess_model, 4)) if self.analysis_ID in [5,6]: text += "Time to solve the acoustic model: {} [s]\n".format(round(self.project.time_to_solve_acoustic_model, 4)) text += "Time to solve the structural model: {} [s]\n".format(round(self.project.time_to_solve_structural_model, 4)) else: text += "Time to solve the model: {} [s]\n".format(round(self.project.time_to_solve_model, 4)) text += "Time elapsed in post-processing: {} [s]\n\n".format(round(self.project.time_to_postprocess, 4)) text += "Total time elapsed: {} [s]\n\n\n".format(round(self.project.total_time, 4)) text += "Press ESC to continue..." self.label_message.setText(text)
class CalibrationUI(): def __init__(self, SharedVariables_class, calculator_class): self.SV = SharedVariables_class self.CALCULATOR = calculator_class self.calibration_MainWindow = QtWidgets.QMainWindow() self.calibration_gui = C_GUI.Ui_MainWindow() self.calibration_gui.setupUi(self.calibration_MainWindow) self.temp_calibrate_x = self.SV.calibrate_x self.temp_calibrate_y = self.SV.calibrate_y self.temp_calibrate_angle = self.SV.calibrate_angle self.temp_calibrate_x_multi = self.SV.calibrate_x_multi self.temp_calibrate_y_multi = self.SV.calibrate_y_multi self.temp_calibrate_angle_multi = self.SV.calibrate_angle_multi self.calibration_gui.XCalibration_constant_spinBox.valueChanged.connect( self.x_spin) self.calibration_gui.YCalibration_constant_spinBox.valueChanged.connect( self.y_spin) self.calibration_gui.AngleCalibration_constant_spinBox.valueChanged.connect( self.angle_spin) self.calibration_gui.XCalibration_spinBox.valueChanged.connect( self.x_spin_multi) self.calibration_gui.YCalibration_spinBox.valueChanged.connect( self.y_spin_multi) self.calibration_gui.AngleCalibration_spinBox.valueChanged.connect( self.angle_spin_multi) self.calibration_gui.XCalibration_constant_slider.valueChanged.connect( self.x_slider) self.calibration_gui.YCalibration_constant_slider.valueChanged.connect( self.y_slider) self.calibration_gui.AngleCalibration_constant_slider.valueChanged.connect( self.angle_slider) self.calibration_gui.XCalibration_slider.valueChanged.connect( self.x_slider_multi) self.calibration_gui.YCalibration_slider.valueChanged.connect( self.y_slider_multi) self.calibration_gui.AngleCalibration_slider.valueChanged.connect( self.angle_slider_multi) self.calibration_MainWindow.closeEvent = self.closeEvent self.calibration_gui.ExitBtn.clicked.connect( self.calibration_MainWindow.close) self.calibration_gui.ConfirmBtn.clicked.connect(self.ConfirmBtn_click) self.calibration_gui.ResetBtn.clicked.connect(self.ResetBtn_click) self.calibration_gui.ExportBtn.clicked.connect(self.ExportBtn_click) self.calibration_gui.ImportBtn.clicked.connect(self.ImportBtn_click) self.initial_line, = self.calibration_gui.Calibration.calibration_map_axes.plot( self.SV.local_obstacle_x, self.SV.local_obstacle_y, 'g.') self.current_line, = self.calibration_gui.Calibration.calibration_map_axes.plot( self.SV.local_obstacle_x, self.SV.local_obstacle_y, 'b.') self.calibrate_line, = self.calibration_gui.Calibration.calibration_map_axes.plot( self.SV.local_obstacle_x, self.SV.local_obstacle_y, 'r.') self.position_line, = self.calibration_gui.Calibration.calibration_map_axes.plot( self.SV.vision_data[0], self.SV.vision_data[1], 'bo') self.calibrate_position_line, = self.calibration_gui.Calibration.calibration_map_axes.plot( self.SV.vision_data[0], self.SV.vision_data[1], 'ro') def show_window(self): self.calibration_MainWindow.show() self.calibration_animation = FuncAnimation( self.calibration_gui.Calibration.figure, self.animation, blit=True, interval=50) def close_window(self): self.calibration_MainWindow.close() def x_spin(self): self.temp_calibrate_x = self.calibration_gui.XCalibration_constant_spinBox.value( ) self.calibration_gui.XCalibration_constant_label.setText( "X Calibration : {}".format(self.temp_calibrate_x)) self.calibration_gui.XCalibration_constant_slider.setValue( self.temp_calibrate_x) def x_spin_multi(self): self.temp_calibrate_x_multi = self.calibration_gui.XCalibration_spinBox.value( ) / 100 self.calibration_gui.XCalibration_label.setText( "X Calibration multiply: {} %".format( self.calibration_gui.XCalibration_spinBox.value())) self.calibration_gui.XCalibration_slider.setValue( self.calibration_gui.XCalibration_spinBox.value()) def x_slider(self): self.temp_calibrate_x = self.calibration_gui.XCalibration_constant_slider.value( ) self.calibration_gui.XCalibration_constant_label.setText( "X Calibration : {}".format(self.temp_calibrate_x)) self.calibration_gui.XCalibration_constant_spinBox.setValue( self.temp_calibrate_x) def x_slider_multi(self): self.temp_calibrate_x_multi = self.calibration_gui.XCalibration_slider.value( ) / 100 self.calibration_gui.XCalibration_label.setText( "X Calibration multiply: {} %".format( self.calibration_gui.XCalibration_slider.value())) self.calibration_gui.XCalibration_spinBox.setValue( self.calibration_gui.XCalibration_slider.value()) def y_spin(self): self.temp_calibrate_y = self.calibration_gui.YCalibration_constant_spinBox.value( ) self.calibration_gui.YCalibration_constant_label.setText( "Y Calibration : {}".format(self.temp_calibrate_y)) self.calibration_gui.YCalibration_constant_slider.setValue( self.temp_calibrate_y) def y_spin_multi(self): self.temp_calibrate_y_multi = self.calibration_gui.YCalibration_spinBox.value( ) / 100 self.calibration_gui.YCalibration_label.setText( "Y Calibration multiply : {} %".format( self.calibration_gui.YCalibration_spinBox.value())) self.calibration_gui.YCalibration_slider.setValue( self.calibration_gui.YCalibration_spinBox.value()) def y_slider(self): self.temp_calibrate_y = self.calibration_gui.YCalibration_constant_slider.value( ) self.calibration_gui.YCalibration_constant_label.setText( "Y Calibration : {}".format(self.temp_calibrate_y)) self.calibration_gui.YCalibration_constant_spinBox.setValue( self.temp_calibrate_y) def y_slider_multi(self): self.temp_calibrate_y_multi = self.calibration_gui.YCalibration_slider.value( ) / 100 self.calibration_gui.YCalibration_label.setText( "Y Calibration multiply: {} %".format( self.calibration_gui.YCalibration_slider.value())) self.calibration_gui.YCalibration_spinBox.setValue( self.calibration_gui.YCalibration_slider.value()) def angle_spin(self): self.temp_calibrate_angle = self.calibration_gui.AngleCalibration_constant_spinBox.value( ) self.calibration_gui.AngleCalibration_constant_label.setText( "Angle Calibration : {}".format(self.temp_calibrate_angle)) self.calibration_gui.AngleCalibration_constant_slider.setValue( self.temp_calibrate_angle) def angle_spin_multi(self): self.temp_calibrate_angle_multi = self.calibration_gui.AngleCalibration_spinBox.value( ) / 100 self.calibration_gui.AngleCalibration_label.setText( "Angle Calibration multiply : {} %".format( self.calibration_gui.AngleCalibration_spinBox.value())) self.calibration_gui.AngleCalibration_slider.setValue( self.calibration_gui.AngleCalibration_spinBox.value()) def angle_slider(self): self.temp_calibrate_angle = self.calibration_gui.AngleCalibration_constant_slider.value( ) self.calibration_gui.AngleCalibration_constant_label.setText( "Angle Calibration : {}".format(self.temp_calibrate_angle)) self.calibration_gui.AngleCalibration_constant_spinBox.setValue( self.temp_calibrate_angle) def angle_slider_multi(self): self.temp_calibrate_angle_multi = self.calibration_gui.AngleCalibration_slider.value( ) / 100 self.calibration_gui.AngleCalibration_label.setText( "Angle Calibration multiply: {} %".format( self.calibration_gui.AngleCalibration_slider.value())) self.calibration_gui.AngleCalibration_spinBox.setValue( self.calibration_gui.AngleCalibration_slider.value()) def ConfirmBtn_click(self): self.SV.calibrate_x = self.temp_calibrate_x self.SV.calibrate_y = self.temp_calibrate_y self.SV.calibrate_angle = self.temp_calibrate_angle self.SV.calibrate_x_multi = self.temp_calibrate_x_multi self.SV.calibrate_y_multi = self.temp_calibrate_y_multi self.SV.calibrate_angle_multi = self.temp_calibrate_angle_multi self.CALCULATOR.show_message("Confirm calibration : x : {} , y : {} , angle : {} \ x multi : {} , y multi : {} , angle multi : {}" \ .format(self.SV.calibrate_x, self.SV.calibrate_y, self.SV.calibrate_angle, \ self.SV.calibrate_x_multi, self.SV.calibrate_y_multi, self.SV.calibrate_angle_multi)) def ResetBtn_click(self): self.initial_line.set_data(self.SV.local_obstacle_x, self.SV.local_obstacle_y) def closeEvent(self, event): self.CALCULATOR.show_message("Calibration stop") self.calibration_animation._stop() self.SV.calibration_run = False event.accept() def animation(self, i): self.calibration_gui.VisionData_label.setText(str(self.SV.vision_data)) temp_vision_x, temp_vision_y, temp_vision_angle_radian = self.CALCULATOR.get_calibrate_temp_vision_xy_angle( self.temp_calibrate_x, self.temp_calibrate_y, self.temp_calibrate_x_multi, self.temp_calibrate_y_multi, self.temp_calibrate_angle, self.temp_calibrate_angle_multi) temp_local_obstacle_x, temp_local_obstacle_y = self.CALCULATOR.get_calibrate_temp_local_obstacle( temp_vision_x, temp_vision_y, temp_vision_angle_radian, self.SV.lidar_radius, self.SV.lidar_angle) self.current_line.set_data(self.SV.local_obstacle_x, self.SV.local_obstacle_y) self.calibrate_line.set_data(temp_local_obstacle_x, temp_local_obstacle_y) self.position_line.set_data(self.SV.vision_data[0], self.SV.vision_data[1]) self.calibrate_position_line.set_data(temp_vision_x, temp_vision_y) self.calibration_gui.Calibration.calibration_map_axes.autoscale(True) return self.current_line, self.calibrate_line, self.position_line, self.calibrate_position_line, self.initial_line, def ExportBtn_click(self): try: name = QtWidgets.QFileDialog.getSaveFileName(self.calibration_MainWindow, \ 'Save File', "", "Rover Calibration Files (*.calibration);;Text Files (*.txt);;All Files (*)") if name != ("", ""): file = open(name[0], 'w') text = "x{}xm{}y{}ym{}a{}am{}".format(self.SV.calibrate_x, self.SV.calibrate_x_multi, \ self.SV.calibrate_y, self.SV.calibrate_y_multi, self.SV.calibrate_angle, self.SV.calibrate_angle_multi) file.write(text) file.close() except TypeError: traceback.print_exc() def ImportBtn_click(self): name = QtWidgets.QFileDialog.getOpenFileName(self.calibration_MainWindow, \ 'Open File', "", "Rover Calibration Files (*.calibration);;Text Files (*.txt);;All Files (*)") if name != ("", ""): file = open(name[0], 'r') text = file.read() self.temp_calibrate_x = int(text[text.index("x") + 1:text.index("xm")]) self.temp_calibrate_x_multi = float(text[text.index("xm") + 2:text.index("y")]) self.temp_calibrate_y = int(text[text.index("y") + 1:text.index("ym")]) self.temp_calibrate_y_multi = float(text[text.index("ym") + 2:text.index("a")]) self.temp_calibrate_angle = int(text[text.index("a") + 1:text.index("am")]) self.temp_calibrate_angle_multi = float(text[text.index("am") + 2:len(text)]) self.calibration_gui.XCalibration_constant_slider.setValue( self.temp_calibrate_x) self.calibration_gui.YCalibration_constant_slider.setValue( self.temp_calibrate_y) self.calibration_gui.AngleCalibration_constant_slider.setValue( self.temp_calibrate_angle) self.calibration_gui.XCalibration_slider.setValue( self.temp_calibrate_x_multi * 100) self.calibration_gui.YCalibration_slider.setValue( self.temp_calibrate_y_multi * 100) self.calibration_gui.AngleCalibration_slider.setValue( self.temp_calibrate_angle_multi * 100) # print( # self.temp_calibrate_x, self.temp_calibrate_x_multi, # self.temp_calibrate_y, self.temp_calibrate_y_multi, # self.temp_calibrate_angle, self.temp_calibrate_angle_multi # ) file.close()
class ROVER_gui(): def __init__(self): os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" app = QtWidgets.QApplication(sys.argv) app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) MainWindow = QtWidgets.QMainWindow() self.gui = GUI.Ui_MainWindow() self.gui.setupUi(MainWindow) self.SV = SharedVariables() self.SV.gui = self.gui self.CALCULATOR = Calculator(self.SV) self.current_speed = 0 self.show_vision_status_dict = { 0: "Booting", 1: "Waiting for command", 2: "Loading data", 3: ":Locating, please move around", 4: ":Working normally", 5: ":Lost current position" } self.rover_run, self.lidar_server_run, self.vision_server_run, \ self.animation_run, self.vision_build_map_mode, self.vision_use_map_mode, \ self.SV.calibration_run, self.keyboard_control_run, self.vision_idle \ = False, False, False, False, False, False, False, False, False self.check_status_rover_run_list = [ self.rover_run, self.vision_server_run, self.lidar_server_run ] self.check_status_rover_Btn_list = [ self.gui.RoverMainOnOffBtn, self.gui.VisionOnOffBtn, self.gui.LidarOnOffBtn ] self.check_status_func_run_list = [ self.animation_run, self.vision_build_map_mode, self.vision_use_map_mode, self.SV.calibration_run, self.keyboard_control_run ] self.check_status_func_Btn_list = [ self.gui.ShowMapBtn, self.gui.VisionBuildMapBtn, self.gui.VisionUseMapBtn, self.gui.CalibrationBtn, self.gui.KeyboardControlBtn ] self.gui.StopAllBtn.clicked.connect(self.StopAllBtn_click) self.gui.KeyboardControlBtn.clicked.connect( self.KeyboardControlBtn_click) self.gui.VisionBuildMapBtn.clicked.connect( self.VisionBuildMapBtn_click) self.gui.VisionBuildMapStopBtn.clicked.connect( self.VisionBuildMapStopBtn_click) self.gui.VisionUseMapBtn.clicked.connect(self.VisionUseMapBtn_click) self.gui.VisionUseMapStopBtn.clicked.connect( self.VisionUseMapStopBtn_click) self.gui.ShowMapBtn.clicked.connect(self.show_map) self.gui.ShowMap_AddBtn.clicked.connect(self.ShowMap_AddBtn_click) self.gui.KeyboardControl_SetSpeedBtn.clicked.connect( self.KeyboardControl_SetSpeedBtn_click) self.gui.KeyBoardControl_speed.valueChanged.connect( self.KeyBoardControl_speed_value_change) self.gui.CalibrationBtn.clicked.connect(self.calibration) self.gui_get_lidar_vision_client = rover_socket.UDP_client( 50010, 0, '192.168.5.2') self.gui_get_rover_status_client = rover_socket.UDP_client( 50012, 0, '192.168.5.2') self.gui_rover_command_client = rover_socket.UDP_client( 50013, 0, '192.168.5.2') self.get_data_retry = 0 self.get_data_timer = QtCore.QTimer() self.get_data_timer.timeout.connect(self.get_data_from_rover) self.get_data_timer.start(40) self.get_rover_status_retry = 0 self.get_rover_status_timer = QtCore.QTimer() self.get_rover_status_timer.timeout.connect(self.get_rover_status) self.get_rover_status_timer.start(40) self.check_status_timer = QtCore.QTimer() self.check_status_timer.timeout.connect(self.check_status) self.check_status_timer.start(100) self.show_map() self.gui.tabWidget.setCurrentIndex(0) # self.gui.tabWidget.currentChanged.connect(self.show_map) MainWindow.show() sys.exit(app.exec_()) def check_status(self): for i, j in zip( [self.rover_run, self.vision_server_run, self.lidar_server_run], range(len(self.check_status_rover_run_list))): if i: self.check_status_rover_Btn_list[j].setStyleSheet( "background-color: rgb(0, 255, 0);") else: self.check_status_rover_Btn_list[j].setStyleSheet( "background-color: rgb(255, 0, 0);") for i, j in zip([ self.animation_run, self.vision_build_map_mode, self.vision_use_map_mode, self.SV.calibration_run, self.keyboard_control_run ], range(len(self.check_status_func_run_list))): if i: self.check_status_func_Btn_list[j].setStyleSheet( "background-color: rgb(0, 255, 93);") else: self.check_status_func_Btn_list[j].setStyleSheet( "background-color: rgb(112, 155, 255);") def get_rover_status(self): '''Specialize for getting rover status''' def show_vision_status(): '''Explain vision status meanning''' if self.SV.vision_status in self.show_vision_status_dict: self.gui.VisionStatus_text.setText("{} : {}".format( self.SV.vision_status, self.show_vision_status_dict[self.SV.vision_status])) else: self.gui.VisionStatus_text.setText("{} : unknown".format( self.SV.vision_status)) self.gui_get_rover_status_client.send_list([1]) temp_rover_status_receive = self.gui_get_rover_status_client.recv_list( ) if temp_rover_status_receive is not None: self.gui.LidarUSB_text.setText("USB Port: " + str(temp_rover_status_receive[0]) \ + "\n Status: " + str(temp_rover_status_receive[1])) self.lidar_server_run, self.SV.vision_status, self.vision_server_run, \ self.vision_idle, self.rover_run, self.current_speed, \ self.vision_build_map_mode, self.vision_use_map_mode = \ temp_rover_status_receive[2:10] self.get_rover_status_retry = 0 show_vision_status() self.gui.CurrentSpeed_text.setText(str(self.current_speed)) else: self.get_rover_status_retry += 1 if self.get_rover_status_retry > 50: self.lidar_server_run, self.rover_run, self.vision_server_run = \ False, False, False self.gui.CurrentSpeed_text.setText("No connection") self.gui.LidarUSB_text.setText("No connection") self.gui.VisionStatus_text.setText("No connection") def get_data_from_rover(self): '''Get data from rover and turn into map''' self.gui_get_lidar_vision_client.send_list( [1]) # Send anything to make sure connection always open temp_lidar_vision_receive = self.gui_get_lidar_vision_client.recv_list( 32768) if temp_lidar_vision_receive is not None: self.SV.lidar_data = numpy.asarray(temp_lidar_vision_receive[0]) self.SV.lidar_angle = self.SV.lidar_data[:, 1] * (-1) + 0.0 * math.pi self.SV.lidar_radius = self.SV.lidar_data[:, 2] self.SV.vision_data = temp_lidar_vision_receive[1] if self.SV.vision_data[3] == 4: self.CALCULATOR.calculate_vision_xy_angle() self.CALCULATOR.calculate_local_obstacle() self.CALCULATOR.calculate_arrow() def calibration(self): if not hasattr(self, "CAL_GUI"): self.CAL_GUI = CalibrationUI(self.SV, self.CALCULATOR) if not self.vision_idle and self.vision_server_run and self.lidar_server_run: if not self.SV.calibration_run and not self.CAL_GUI.calibration_MainWindow.isVisible( ): self.CAL_GUI.show_window() self.SV.calibration_run = True else: self.CAL_GUI.close_window() self.SV.calibration_run = False else: self.CALCULATOR.show_message( "For calibration, lidar, vision should be 'On' and \ vision should be either build map mode or use map mode") def show_map(self): def plot_lidar_map(i): self.lidar_plot.set_xdata(self.SV.lidar_angle) self.lidar_plot.set_ydata(self.SV.lidar_radius) return self.lidar_plot, def plot_global_map(i): self.gui.GlobalMap.global_map_axes.set_xlim( self.CALCULATOR.get_x_axis_limit()) self.gui.GlobalMap.global_map_axes.set_ylim( self.CALCULATOR.get_y_axis_limit()) self.global_map_plot_vision.set_data(self.SV.vision_x, self.SV.vision_y) self.global_map_plot_local_obstacle.set_data( self.SV.local_obstacle_x, self.SV.local_obstacle_y) self.global_map_plot_arrow.set_data(self.SV.arrow_x, self.SV.arrow_y) self.global_map_plot_global_obstacle.set_data( self.SV.global_obstacle_x, self.SV.global_obstacle_y) return self.global_map_plot_local_obstacle, self.global_map_plot_vision, self.global_map_plot_arrow, self.global_map_plot_global_obstacle, # print("show map") if not self.animation_run: self.lidar_plot, = self.gui.LidarMap.lidar_axes.plot(0, 0, 'b.') self.global_map_plot_arrow, = self.gui.GlobalMap.global_map_axes.plot( [], [], 'g', linewidth=3) self.global_map_plot_vision, = self.gui.GlobalMap.global_map_axes.plot( [], [], 'ro', linewidth=200) self.global_map_plot_local_obstacle, = self.gui.GlobalMap.global_map_axes.plot( [], [], 'b.') self.global_map_plot_global_obstacle, = self.gui.GlobalMap.global_map_axes.plot( [], [], 'k.') self.lidar_animation = FuncAnimation(self.gui.LidarMap.figure, plot_lidar_map, blit=True, interval=50) self.global_animation = FuncAnimation(self.gui.GlobalMap.fig, plot_global_map, blit=True, interval=50) self.CALCULATOR.show_message("Show Map Start") self.animation_run = True else: self.lidar_animation._stop() self.global_animation._stop() self.CALCULATOR.show_message("Show Map Stop") self.animation_run = False def ShowMap_AddBtn_click(self): self.CALCULATOR.get_global_obstacle() def StopAllBtn_click(self): self.CALCULATOR.show_message("Stop ALL") if self.animation_run: self.lidar_animation._stop() self.global_animation._stop() self.gui.GlobalMap.global_map_axes.clear() self.animation_run = False if self.keyboard_control_run: self.KeyboardControlTimer.stop() self.gui_keyboard_control_client.close() def KeyboardControlBtn_click(self): def controller(): if keyboard.is_pressed('w') and not keyboard.is_pressed( 'a') and not keyboard.is_pressed('d'): self.gui_keyboard_control_client.send_list(['w']) elif keyboard.is_pressed('w') and keyboard.is_pressed( 'a') and not keyboard.is_pressed('d'): self.gui_keyboard_control_client.send_list(['wa']) elif keyboard.is_pressed('w') and not keyboard.is_pressed( 'a') and keyboard.is_pressed('d'): self.gui_keyboard_control_client.send_list(['wd']) elif keyboard.is_pressed('s') and not keyboard.is_pressed( 'a') and not keyboard.is_pressed('d'): self.gui_keyboard_control_client.send_list(['s']) elif keyboard.is_pressed('s') and keyboard.is_pressed( 'a') and not keyboard.is_pressed('d'): self.gui_keyboard_control_client.send_list(['sa']) elif keyboard.is_pressed('s') and not keyboard.is_pressed( 'a') and keyboard.is_pressed('d'): self.gui_keyboard_control_client.send_list(['sd']) elif keyboard.is_pressed('d') and not keyboard.is_pressed( 'w') and not keyboard.is_pressed('s'): self.gui_keyboard_control_client.send_list(['d']) elif keyboard.is_pressed('a') and not keyboard.is_pressed( 'w') and not keyboard.is_pressed('s'): self.gui_keyboard_control_client.send_list(['a']) self.gui.KeyUp.setStyleSheet("background-color: rgb(0, 255, 0);") \ if keyboard.is_pressed('w') else \ self.gui.KeyUp.setStyleSheet("background-color: rgb(255, 255, 255);") self.gui.KeyDown.setStyleSheet("background-color: rgb(0, 255, 0);") \ if keyboard.is_pressed('s') else \ self.gui.KeyDown.setStyleSheet("background-color: rgb(255, 255, 255);") self.gui.KeyRight.setStyleSheet("background-color: rgb(0, 255, 0);") \ if keyboard.is_pressed('d') else \ self.gui.KeyRight.setStyleSheet("background-color: rgb(255, 255, 255);") self.gui.KeyLeft.setStyleSheet("background-color: rgb(0 255, 0);") \ if keyboard.is_pressed('a') else \ self.gui.KeyLeft.setStyleSheet("background-color: rgb(255, 255, 255);") self.gui_keyboard_control_client = rover_socket.UDP_client( 50011, 0, '192.168.5.2') self.KeyboardControlTimer = QtCore.QTimer() self.KeyboardControlTimer.timeout.connect(controller) if not self.keyboard_control_run: self.CALCULATOR.show_message('Keyboard Control Start') self.KeyboardControlTimer.start(50) self.keyboard_control_run = True else: self.KeyboardControlTimer.stop() self.gui_keyboard_control_client.close() self.CALCULATOR.show_message('Keyboard Control Stop') self.keyboard_control_run = False def KeyboardControl_SetSpeedBtn_click(self): if self.rover_run: self.gui_rover_command_client.send_list( ["gss", self.gui.KeyBoardControl_speed.value()]) self.CALCULATOR.show_message( "Set Car Speed " + str(self.gui.KeyBoardControl_speed.value())) else: self.CALCULATOR.show_message("Warring : ROVER is not running") def KeyBoardControl_speed_value_change(self): self.gui.SetSpeed_label.setText( str(self.gui.KeyBoardControl_speed.value())) def WayPointBtn_click(self): self.CALCULATOR.show_message("Way Point mode start !") def VisionUseMapBtn_click(self): if self.vision_idle: self.gui_rover_command_client.send_list( ['gum', self.gui.UseMapID.value()]) self.CALCULATOR.show_message('Vision start use map') else: if self.vision_server_run: self.CALCULATOR.show_message('Vision module is busy') else: self.CALCULATOR.show_message('Vision is not working') def VisionBuildMapBtn_click(self): if self.vision_idle: self.gui_rover_command_client.send_list( ['gbm', self.gui.BuildMapID.value()]) self.CALCULATOR.show_message("Vision start building map") else: if self.vision_server_run: self.CALCULATOR.show_message('Vision module is busy') else: self.CALCULATOR.show_message('Vision is not working') def VisionBuildMapStopBtn_click(self): if not self.vision_idle and self.vision_build_map_mode: self.gui_rover_command_client.send_list(['gbms']) self.CALCULATOR.show_message( "Vision module is reseting please wait until ROVER reseting") else: self.CALCULATOR.show_message( "Vision is either idling or in use map mode") def VisionUseMapStopBtn_click(self): if not self.vision_idle and self.vision_use_map_mode: self.gui_rover_command_client.send_list(['gums']) self.CALCULATOR.show_message( "Vision module is reseting please wait until ROVER reseting") else: self.CALCULATOR.show_message( "Vision is either idling or in build map mode")
class Simulation(object): def __init__(self, fig=None, figsize=(6,6), period=10, xlim=(-2, 2), ylim=(-2, 2)): ''' Constructor for the base model. Must be called explicitly from the constructor of the derived class Arguments: figsize [inches]: Sets the size of the window containing the simulation. period_ms [ms]: Sets the time between each update of the simulation. xlim [m]: Sets the size of the x-axis in simulation distance units, typically meters ylim [m]: Sets the size of the y-axis in simulation distance units, typically meters ''' self.period_ms = period self.period_s = self.period_ms/1000.0 self.state = [] self.input = [] self.time = 0.0 self.iteration = 0 self.state_posterior = [] if fig : self.figure = figure else: self.figure = figure(num=None, figsize=figsize, dpi=80, facecolor='w', edgecolor='k') self.axes = self.figure.add_subplot(111, autoscale_on=False, xlim=xlim, ylim=ylim) self.event_source = self.figure.canvas.new_timer() self.event_source.interval = self.period_ms self.controller = None self.controllers_arr = [None]*3 def startAnimation(self, iterations=0): ''' This method must be called to begin the simulation and will block until the simulation is finished. Arguments: iterations []: Number of times the update method will be called. ''' if iterations == 0 : frames=None else : frames=range(iterations) self.reset(self.controller.reset_ar()) self.ani = FuncAnimation(self.figure, self.update, frames=frames, interval=self.period_ms, repeat=False, event_source=self.event_source) self.figure.show() return self.state_posterior def reset(self, reset_arr): ''' This methods sets the initial condition of state and time and is called prior to each simulation. Example: self.time = 0.0 self.state = [0.0 , 0.0] ''' raise NotImplementedError("This method is just an interface. Implement in inheriting class") def update(self, iteration_number): ''' This method runs the simulation steps by calling: - The control method to generate control input - The model method for updating the state - The draw method to update the figure - The upkeep method to record data and control the simulation Arguments: iteration_number [] : The iteration number. ''' self.iteration = iteration_number self.time = self.time + self.period_s self.control() self.model() self.draw() self.upkeep() def control(self): ''' This method handles the control algorithm. Must return input vector for model ''' pass def model(self): ''' This method calculates the new state of the system. Must return new state. ''' raise NotImplementedError("This method is just an interface. Implement in inheriting class") def draw(self): ''' This method handles updating or redrawing the figure ''' raise NotImplementedError("This method is just an interface. Implement in inheriting class") def upkeep(self): ''' This method handles saving data for later plotting or analysis ''' pass def stop(self): ''' This method stops the animation ''' self.ani._stop()