123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- import time
- import queue
- import tkinter as tk
- import numpy as np
- from gui.popup import CalibrationPopUp
- from gui.graph import Graph
- from gui.logScreen import LogScreen
- from sensors.opticalSensor import OpticalSensor
- import logHandler
- class MainWindow(tk.Frame):
- def __init__(self, root, conf, ac_sensor, opt_sensor, mag_sensor):
- self.root = root
- self.conf = conf
- self.ac_sensor = ac_sensor
- self.opt_sensor = opt_sensor
- self.mag_sensor = mag_sensor
- self.log_handler = logHandler.get_log_handler()
- self.popup_window = None
- self.log_window = None
- self.mainWindow = None
- tk.Frame.__init__(self, root)
- # data plot at left side
- self.graph = Graph(self)
- self.graph.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)
- # frame at right side
- self.controls = tk.Frame(self, borderwidth=4)
- self.controls.pack(fill=tk.BOTH, side=tk.RIGHT)
- self.controlsUpdateTime = 0
- self.ac_dro_val_sums = np.ndarray((4), dtype=np.float)
- self.ac_dro_val_count = 0
- self.ac_dro_x = tk.StringVar()
- self.ac_dro_y = tk.StringVar()
- self.ac_dro_t1 = tk.StringVar()
- self.ac_dro_t2 = tk.StringVar()
- self.ac_label = tk.Label(self.controls, text="Acoustic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
- self.ac_label.pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.ac_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.ac_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.ac_dro_t1, anchor="nw").pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.ac_dro_t2, anchor="nw").pack(side="top", fill="both", expand=False)
- self.opt_dro_val_sums = np.ndarray((4), dtype=np.float)
- self.opt_dro_val_count = 0
- self.opt_dro_x = tk.StringVar()
- self.opt_dro_y = tk.StringVar()
- self.opt_dro_offset = tk.StringVar()
- self.opt_dro_size = tk.StringVar()
- self.opt_label = tk.Label(self.controls, text="Optical Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
- self.opt_label.pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.opt_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.opt_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.opt_dro_offset, anchor="nw").pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.opt_dro_size, anchor="nw").pack(side="top", fill="both", expand=False)
- self.mag_dro_val_sums = np.ndarray((4), dtype=np.float)
- self.mag_dro_val_count = 0
- self.mag_dro_x = tk.StringVar()
- self.mag_dro_y = tk.StringVar()
- self.mag_label = tk.Label(self.controls, text="Magnetic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
- self.mag_label.pack(side="top", fill="both", expand=False)
- tk.Label(self.controls, textvariable=self.mag_dro_x, anchor = "nw").pack(side = "top", fill = "both", expand = False)
- tk.Label(self.controls, textvariable=self.mag_dro_y, anchor = "nw").pack(side = "top", fill = "both", expand = False)
- self.quit_button = tk.Button(self.controls, text="Quit", command=self.root.destroy, height=2, foreground="red")
- self.quit_button.pack(side="bottom", fill="both")
- self.calibrate_submenu_button = tk.Button(self.controls, text="Calibrate", command=self.calibrate_submenu, height=2)
- self.calibrate_submenu_button.pack_forget()
-
- self.calibrate_all_button = tk.Button(self.controls, text="Calibrate All", command=self.calibrate_all, height=2)
- self.calibrate_all_button.pack_forget()
-
- self.calibrateac_button = tk.Button(self.controls, text="Calibrate AC", command=self.calibrate_ac, height=2)
- self.calibrateac_button.pack_forget()
- self.calibrateopt_button = tk.Button(self.controls, text = "Calibrate OPT", command = self.calibrate_opt,height = 2)
- self.calibrateopt_button.pack_forget()
-
- self.calibratemag_button = tk.Button(self.controls, text = "Calibrate MAG", command = self.calibrate_mag,height = 2)
- self.calibratemag_button.pack_forget()
- self.clear_button = tk.Button(self.controls, text="Clear graph", command=self.graph.clear, height=2)
- self.clear_button.pack_forget()
- self.logscreen_button = tk.Button(self.controls, text="Log", command=self.open_log, height=2)
- self.logscreen_button.pack_forget()
- self.menu_button = tk.Button(self.controls, text="Menu", command=self.menu, height=2)
- self.menu_button.pack(side="bottom", fill="both")
-
- self.menu_back_button = tk.Button(self.controls, text="Back", command=self.back, height=2)
- self.menu_back_button.pack_forget()
- def update(self):
- if not self.root.winfo_exists():
- return
- ac_positions = []
- # aggregate measurements
- while self.ac_sensor.queue.qsize() > 0:
- name, data = self.ac_sensor.queue.get()
- if name == "data":
- ac_positions.append(data[0:2])
- self.ac_dro_val_sums += data
- self.ac_dro_val_count += 1
- opt_positions = []
- while self.opt_sensor.queue.qsize() > 0:
- name, data = self.opt_sensor.queue.get()
- if name == "data":
- opt_positions.append(data[0:2])
- self.opt_dro_val_sums += data
- self.opt_dro_val_count += 1
-
- mag_positions = []
- while self.mag_sensor.queue.qsize() > 0:
- name, data = self.mag_sensor.queue.get()
- if name == "data":
- mag_positions.append(data[0:2])
- self.mag_dro_val_sums += data
- self.mag_dro_val_count += 1
-
- # graph shows all values as a line
- self.graph.update([ac_positions, opt_positions, mag_positions])
- # update status color
- if self.ac_sensor.dummyActive:
- self.ac_label.config(fg="white", bg="red")
- elif len(ac_positions) > 0:
- self.ac_label.config(fg="white", bg="green")
- else:
- self.ac_label.config(fg="black", bg="yellow")
- if not self.opt_sensor.success:
- self.opt_label.config(fg="white", bg="red")
- elif len(opt_positions) > 0:
- self.opt_label.config(fg="white", bg="green")
- else:
- self.opt_label.config(fg="black", bg="yellow")
- if not self.mag_sensor.success:
- self.mag_label.config(fg="white", bg="red")
- elif len(mag_positions) > 0:
- self.mag_label.config(fg="white", bg="green")
- else:
- self.mag_label.config(fg="black", bg="yellow")
- # readouts will only be updated so often
- if self.controlsUpdateTime + 0.4 < time.time():
- self.controlsUpdateTime = time.time()
- # they display the average of all values
- if self.ac_dro_val_count > 0:
- self.ac_dro_val_sums /= self.ac_dro_val_count
- else:
- self.ac_dro_val_sums.fill(0)
- self.ac_dro_x.set("X: {:.1f} mm".format(self.ac_dro_val_sums[0]))
- self.ac_dro_y.set("Y: {:.1f} mm".format(self.ac_dro_val_sums[1]))
- self.ac_dro_t1.set("t1: {:.3f} ms".format(self.ac_dro_val_sums[2]/1000))
- self.ac_dro_t2.set("t2: {:.3f} ms".format(self.ac_dro_val_sums[3]/1000))
- self.ac_dro_val_sums.fill(0)
- self.ac_dro_val_count = 0
- if self.opt_dro_val_count > 0:
- self.opt_dro_val_sums /= self.opt_dro_val_count
- else:
- self.opt_dro_val_sums.fill(0)
- self.opt_dro_x.set("X: {:.1f} mm".format(self.opt_dro_val_sums[0]))
- self.opt_dro_y.set("Y: {:.1f} mm".format(self.opt_dro_val_sums[1]))
- self.opt_dro_offset.set("X Offset: {:.1f} %".format(self.opt_dro_val_sums[2]*100))
- self.opt_dro_size.set("Y Offset: {:.1f} %".format(self.opt_dro_val_sums[3]*100))
- self.opt_dro_val_sums.fill(0)
- self.opt_dro_val_count = 0
- if self.mag_dro_val_count > 0:
- self.mag_dro_val_sums /= self.mag_dro_val_count
- else:
- self.mag_dro_val_sums.fill(0)
- self.mag_dro_x.set("X: {:.1f} mm".format(self.mag_dro_val_sums[0]))
- self.mag_dro_y.set("Y: {:.1f} mm".format(self.mag_dro_val_sums[1]))
- #self.mag_dro_offset_x.set("X Offset: {:.1f} %".format(self.mag_dro_val_sums[2]*100))
- #self.mag_dro_offset_y.set("Y Offset: {:.1f} %".format(self.mag_dro_val_sums[3]*100))
- if self.popup_window: # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!~~~~~~~+++*
- self.popup_window.update()
-
- if self.log_window:
- self.log_window.update()
- self.root.after(30, self.update)
- def calibrate_submenu(self):
-
- self.calibrate_submenu_button.pack_forget()
- self.menu_button.pack_forget()
- self.clear_button.pack_forget()
- self.logscreen_button.pack_forget()
- self.menu_back_button.pack(side="bottom", fill="both")
- self.calibratemag_button.pack(side="bottom", fill="both")
- self.calibrateopt_button.pack(side="bottom", fill="both")
- self.calibrateac_button.pack(side="bottom", fill="both")
- self.calibrate_all_button.pack(side="bottom", fill="both")
-
- def calibrate_all(self):
- pass
-
- def calibrate_ac(self):
- self.ac_sensor.start_calibration()
- if not self.popup_window or not self.pu_root.winfo_exists():
- # create new window
- self.pu_root = tk.Toplevel(self.root)
- self.pu_root.wm_transient(self.root)
- self.pu_root.wm_title("Acoustic Sensor Calibration")
- # make it centered
- x = (self.pu_root.winfo_screenwidth() - 500) / 2
- y = (self.pu_root.winfo_screenheight() - 200) / 2
- self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
- # deactivate mainWindow
- self.pu_root.grab_set()
- self.popup_window = CalibrationPopUp(self.pu_root, self.ac_sensor.calibration_state, self.conf)
- self.popup_window.pack(side="top", fill="both", expand=True)
- def calibrate_opt(self):
- pass
-
- def calibrate_mag(self): ###
- self.mag_sensor.start_calibration()
- if not self.popup_window or not self.pu_root.winfo_exists():
- # create new window
- self.pu_root = tk.Toplevel(self.root)
- self.pu_root.wm_transient(self.root)
- self.pu_root.wm_title("Magnetic Sensor Calibration")
- # make it centered
- x = (self.pu_root.winfo_screenwidth() - 500) / 2
- y = (self.pu_root.winfo_screenheight() - 200) / 2
- self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
- # deactivate mainWindow
- self.pu_root.grab_set()
- self.popup_window = CalibrationPopUp(self.pu_root, self.mag_sensor.calibration_state, self.conf)
- self.popup_window.pack(side="top", fill="both", expand=True)
- def open_log(self):
- #create new window
- self.log_root = tk.Toplevel(self.root)
- self.log_root.wm_transient(self.root)
- self.log_root.wm_title("Logs")
- #center
- x = (self.log_root.winfo_screenwidth() - 780) / 2
- y = (self.log_root.winfo_screenheight() - 400) / 2
- self.log_root.geometry(f'780x400+{int(x)}+{int(y)}')
- # deactivate mainWindow
- self.log_root.grab_set()
- self.log_window = LogScreen(self.log_root)
- self.log_window.pack(side="top", fill="both", expand=True)
-
- # Menu Button
- def menu(self):
- self.menu_back_button.pack(side="bottom", fill="both")
- self.calibrate_submenu_button.pack(side="bottom", fill="both")
- self.clear_button.pack(side="bottom", fill="both")
- self.logscreen_button.pack(side="bottom", fill="both")
- self.menu_button.pack_forget()
- #Back Button
- def back(self):
- self.calibratemag_button.pack_forget()
- self.calibrateopt_button.pack_forget()
- self.calibrateac_button.pack_forget()
- self.clear_button.pack_forget()
- self.logscreen_button.pack_forget()
- self.calibrate_submenu_button.pack_forget()
- self.menu_button.pack(side="bottom", fill="both")
- self.menu_back_button.pack_forget()
|