mainWindow.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. import time
  2. import queue
  3. import tkinter as tk
  4. import numpy as np
  5. from gui.popup import CalibrationPopUp
  6. from gui.graph import Graph
  7. from gui.logScreen import LogScreen
  8. import logHandler
  9. class MainWindow(tk.Frame):
  10. def __init__(self, root, conf, ac_sensor, opt_sensor, mag_sensor):
  11. self.root = root
  12. self.conf = conf
  13. self.ac_sensor = ac_sensor
  14. self.opt_sensor = opt_sensor
  15. self.mag_sensor = mag_sensor
  16. self.log_handler = logHandler.get_log_handler()
  17. self.popup_window = None
  18. self.log_window = None
  19. self.mainWindow = None
  20. tk.Frame.__init__(self, root)
  21. # data plot at left side
  22. self.graph = Graph(self)
  23. self.graph.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)
  24. # frame at right side
  25. self.controls = tk.Frame(self, borderwidth=4)
  26. self.controls.pack(fill=tk.BOTH, side=tk.RIGHT)
  27. self.controlsUpdateTime = 0
  28. self.ac_dro_val_sums = np.ndarray((4), dtype=np.float)
  29. self.ac_dro_val_count = 0
  30. self.ac_dro_x = tk.StringVar()
  31. self.ac_dro_y = tk.StringVar()
  32. self.ac_dro_t1 = tk.StringVar()
  33. self.ac_dro_t2 = tk.StringVar()
  34. self.ac_label = tk.Label(self.controls, text="Acoustic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  35. self.ac_label.pack(side="top", fill="both", expand=False)
  36. tk.Label(self.controls, textvariable=self.ac_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
  37. tk.Label(self.controls, textvariable=self.ac_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
  38. tk.Label(self.controls, textvariable=self.ac_dro_t1, anchor="nw").pack(side="top", fill="both", expand=False)
  39. tk.Label(self.controls, textvariable=self.ac_dro_t2, anchor="nw").pack(side="top", fill="both", expand=False)
  40. self.opt_dro_val_sums = np.ndarray((4), dtype=np.float)
  41. self.opt_dro_val_count = 0
  42. self.opt_dro_x = tk.StringVar()
  43. self.opt_dro_y = tk.StringVar()
  44. self.opt_dro_offset = tk.StringVar()
  45. self.opt_dro_size = tk.StringVar()
  46. self.opt_label = tk.Label(self.controls, text="Optical Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  47. self.opt_label.pack(side="top", fill="both", expand=False)
  48. tk.Label(self.controls, textvariable=self.opt_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
  49. tk.Label(self.controls, textvariable=self.opt_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
  50. tk.Label(self.controls, textvariable=self.opt_dro_offset, anchor="nw").pack(side="top", fill="both", expand=False)
  51. tk.Label(self.controls, textvariable=self.opt_dro_size, anchor="nw").pack(side="top", fill="both", expand=False)
  52. self.mag_dro_val_sums = np.ndarray((4), dtype=np.float)
  53. self.mag_dro_val_count = 0
  54. self.mag_label = tk.Label(self.controls, text="Magnetic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  55. self.mag_label.pack(side="top", fill="both", expand=False)
  56. self.mag_dro_x = tk.StringVar()
  57. self.mag_dro_y = tk.StringVar()
  58. self.mag_dro_offset_x = tk.StringVar()
  59. self.mag_dro_offset_y = tk.StringVar()
  60. tk.Label(self.controls, textvariable=self.mag_dro_x, anchor = "nw").pack(side = "top", fill = "both", expand = False)
  61. tk.Label(self.controls, textvariable=self.mag_dro_y, anchor = "nw").pack(side = "top", fill = "both", expand = False)
  62. tk.Label(self.controls, textvariable=self.mag_dro_x, anchor = "nw").pack(side = "top", fill = "both", expand = False)
  63. tk.Label(self.controls, textvariable=self.mag_dro_y, anchor = "nw").pack(side = "top", fill = "both", expand = False)
  64. self.quit_button = tk.Button(self.controls, text="Quit", command=self.root.destroy, height=2, foreground="red")
  65. self.quit_button.pack(side="bottom", fill="both")
  66. self.calibrate_submenu_button = tk.Button(self.controls, text="Calibrate", command=self.calibrate_submenu, height=2)
  67. self.calibrate_submenu_button.pack_forget()
  68. self.calibrate_all_button = tk.Button(self.controls, text="Calibrate All", command=self.calibrate_all, height=2)
  69. self.calibrate_all_button.pack_forget()
  70. self.calibrateac_button = tk.Button(self.controls, text="Calibrate AC", command=self.calibrate_ac, height=2)
  71. self.calibrateac_button.pack_forget()
  72. self.calibrateopt_button = tk.Button(self.controls, text = "Calibrate OPT", command = self.calibrate_opt,height = 2)
  73. self.calibrateopt_button.pack_forget()
  74. self.calibratemag_button = tk.Button(self.controls, text = "Calibrate MAG", command = self.calibrate_mag,height = 2)
  75. self.calibratemag_button.pack_forget()
  76. self.clear_button = tk.Button(self.controls, text="Clear graph", command=self.graph.clear, height=2)
  77. self.clear_button.pack_forget()
  78. self.logscreen_button = tk.Button(self.controls, text="Log", command=self.open_log, height=2)
  79. self.logscreen_button.pack_forget()
  80. self.menu_button = tk.Button(self.controls, text="Menu", command=self.menu, height=2)
  81. self.menu_button.pack(side="bottom", fill="both")
  82. self.menu_back_button = tk.Button(self.controls, text="Back", command=self.back, height=2)
  83. self.menu_back_button.pack_forget()
  84. def update(self):
  85. if not self.root.winfo_exists():
  86. return
  87. ac_positions = []
  88. # aggregate measurements
  89. while self.ac_sensor.queue.qsize() > 0:
  90. name, data = self.ac_sensor.queue.get()
  91. if name == "data":
  92. ac_positions.append(data[0:2])
  93. self.ac_dro_val_sums += data
  94. self.ac_dro_val_count += 1
  95. opt_positions = []
  96. while self.opt_sensor.queue.qsize() > 0:
  97. name, data = self.opt_sensor.queue.get()
  98. if name == "data":
  99. opt_positions.append(data[0:2])
  100. self.opt_dro_val_sums += data
  101. self.opt_dro_val_count += 1
  102. mag_positions = []
  103. while self.mag_sensor.queue.qsize() > 0:
  104. name, data = self.mag_sensor.queue.get()
  105. if name == "data":
  106. mag_positions.append(data[0:2])
  107. self.mag_dro_val_sums += data
  108. self.mag_dro_val_count += 1
  109. # graph shows all values as a line
  110. self.graph.update([ac_positions, opt_positions, mag_positions])
  111. # update status color
  112. if self.ac_sensor.dummyActive:
  113. self.ac_label.config(fg="white", bg="red")
  114. elif len(ac_positions) > 0:
  115. self.ac_label.config(fg="white", bg="green")
  116. else:
  117. self.ac_label.config(fg="black", bg="yellow")
  118. if not self.opt_sensor.success:
  119. self.opt_label.config(fg="white", bg="red")
  120. elif len(opt_positions) > 0:
  121. self.opt_label.config(fg="white", bg="green")
  122. else:
  123. self.opt_label.config(fg="black", bg="yellow")
  124. if not self.mag_sensor.success:
  125. self.mag_label.config(fg="white", bg="red")
  126. elif len(mag_positions) > 0:
  127. self.mag_label.config(fg="white", bg="green")
  128. else:
  129. self.mag_label.config(fg="black", bg="yellow")
  130. # readouts will only be updated so often
  131. if self.controlsUpdateTime + 0.4 < time.time():
  132. self.controlsUpdateTime = time.time()
  133. # they display the average of all values
  134. if self.ac_dro_val_count > 0:
  135. self.ac_dro_val_sums /= self.ac_dro_val_count
  136. else:
  137. self.ac_dro_val_sums.fill(0)
  138. self.ac_dro_x.set("X: {:.1f} mm".format(self.ac_dro_val_sums[0]))
  139. self.ac_dro_y.set("Y: {:.1f} mm".format(self.ac_dro_val_sums[1]))
  140. self.ac_dro_t1.set("t1: {:.3f} ms".format(self.ac_dro_val_sums[2]/1000))
  141. self.ac_dro_t2.set("t2: {:.3f} ms".format(self.ac_dro_val_sums[3]/1000))
  142. self.ac_dro_val_sums.fill(0)
  143. self.ac_dro_val_count = 0
  144. if self.opt_dro_val_count > 0:
  145. self.opt_dro_val_sums /= self.opt_dro_val_count
  146. else:
  147. self.opt_dro_val_sums.fill(0)
  148. self.opt_dro_x.set("X: {:.1f} mm".format(self.opt_dro_val_sums[0]))
  149. self.opt_dro_y.set("Y: {:.1f} mm".format(self.opt_dro_val_sums[1]))
  150. self.opt_dro_offset.set("X Offset: {:.1f} %".format(self.opt_dro_val_sums[2]*100))
  151. self.opt_dro_size.set("Y Offset: {:.1f} %".format(self.opt_dro_val_sums[3]*100))
  152. self.opt_dro_val_sums.fill(0)
  153. self.opt_dro_val_count = 0
  154. if self.mag_dro_val_count > 0:
  155. self.mag_dro_val_sums /= self.mag_dro_val_count
  156. else:
  157. self.mag_dro_val_sums.fill(0)
  158. self.mag_dro_x.set("X: {:.1f} mT".format(self.mag_dro_val_sums[0]))
  159. self.mag_dro_y.set("Y: {:.1f} mT".format(self.mag_dro_val_sums[1]))
  160. self.mag_dro_offset_x.set("X Offset: {:.1f} %".format(self.mag_dro_val_sums[2]*100))
  161. self.mag_dro_offset_y.set("Y: {:.1f} %".format(self.mag_dro_val_sums[3]*100))
  162. if self.popup_window:
  163. self.popup_window.update()
  164. if self.log_window:
  165. self.log_window.update()
  166. self.root.after(30, self.update)
  167. def calibrate_submenu(self):
  168. self.calibrate_submenu_button.pack_forget()
  169. self.menu_button.pack_forget()
  170. self.clear_button.pack_forget()
  171. self.logscreen_button.pack_forget()
  172. self.menu_back_button.pack(side="bottom", fill="both")
  173. self.calibratemag_button.pack(side="bottom", fill="both")
  174. self.calibrateopt_button.pack(side="bottom", fill="both")
  175. self.calibrateac_button.pack(side="bottom", fill="both")
  176. self.calibrat_all_button.pack(side="bottom", fill="both")
  177. def calibrate_all(self):
  178. pass
  179. def calibrate_ac(self):
  180. self.ac_sensor.start_calibration()
  181. if not self.popup_window or not self.pu_root.winfo_exists():
  182. # create new window
  183. self.pu_root = tk.Toplevel(self.root)
  184. self.pu_root.wm_transient(self.root)
  185. self.pu_root.wm_title("Acoustic Sensor Calibration")
  186. # make it centered
  187. x = (self.pu_root.winfo_screenwidth() - 500) / 2
  188. y = (self.pu_root.winfo_screenheight() - 200) / 2
  189. self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
  190. # deactivate mainWindow
  191. self.pu_root.grab_set()
  192. self.popup_window = CalibrationPopUp(self.pu_root, self.ac_sensor.calibration_state, self.conf)
  193. self.popup_window.pack(side="top", fill="both", expand=True)
  194. def calibrate_opt(self):
  195. pass
  196. def calibrate_mag(self): ###
  197. self.mag_sensor.start_calibration()
  198. if not self.popup_window or not self.pu_root.winfo_exists():
  199. # create new window
  200. self.pu_root = tk.Toplevel(self.root)
  201. self.pu_root.wm_transient(self.root)
  202. self.pu_root.wm_title("Magnetic Sensor Calibration")
  203. # make it centered
  204. x = (self.pu_root.winfo_screenwidth() - 500) / 2
  205. y = (self.pu_root.winfo_screenheight() - 200) / 2
  206. self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
  207. # deactivate mainWindow
  208. self.pu_root.grab_set()
  209. self.popup_window = CalibrationPopUp(self.pu_root, self.mag_sensor.calibration_state, self.conf)
  210. self.popup_window.pack(side="top", fill="both", expand=True)
  211. def open_log(self):
  212. #create new window
  213. self.log_root = tk.Toplevel(self.root)
  214. self.log_root.wm_transient(self.root)
  215. self.log_root.wm_title("Logs")
  216. #center
  217. x = (self.log_root.winfo_screenwidth() - 780) / 2
  218. y = (self.log_root.winfo_screenheight() - 400) / 2
  219. self.log_root.geometry(f'780x400+{int(x)}+{int(y)}')
  220. # deactivate mainWindow
  221. self.log_root.grab_set()
  222. self.log_window = LogScreen(self.log_root)
  223. self.log_window.pack(side="top", fill="both", expand=True)
  224. # Menu Button
  225. def menu(self):
  226. self.menu_back_button.pack(side="bottom", fill="both")
  227. self.calibrate_submenu_button.pack(side="bottom", fill="both")
  228. self.clear_button.pack(side="bottom", fill="both")
  229. self.logscreen_button.pack(side="bottom", fill="both")
  230. self.menu_button.pack_forget()
  231. #Back Button
  232. def back(self):
  233. self.calibratemag_button.pack_forget()
  234. self.calibrateopt_button.pack_forget()
  235. self.calibrateac_button.pack_forget()
  236. self.clear_button.pack_forget()
  237. self.logscreen_button.pack_forget()
  238. self.calibrate_submenu_button.pack_forget()
  239. self.menu_button.pack(side="bottom", fill="both")
  240. self.menu_back_button.pack_forget()