mainWindow.py 12 KB

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