mainWindow.py 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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_label = tk.Label(self.controls, text="Magnetic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  54. self.mag_label.pack(side="top", fill="both", expand=False)
  55. self.mag_dro_x = tk.StringVar()
  56. self.mag_dro_y = tk.StringVar()
  57. self.mag_dro_val_sums = tk.StringVar()
  58. self.mag_dro_val_count = tk.StringVar()
  59. tk.Label(self.controls, textvariable=self.mag_dro_x, anchor = "nw").pack(side = "top", fill = "both", expand = False)
  60. tk.Label(self.controls, textvariable=self.mag_dro_y, anchor = "nw").pack(side = "top", fill = "both", expand = False)
  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. self.quit_button = tk.Button(self.controls, text="Quit", command=self.root.destroy, height=2, foreground="red")
  64. self.quit_button.pack(side="bottom", fill="both")
  65. self.calibrateac_button = tk.Button(self.controls, text="Calibrate AC", command=self.calibrate_ac, height=4)
  66. self.calibrateac_button.pack_forget()
  67. self.calibratemc_button = tk.Button(self.controls, text = "Calibrate MC", command = self.calibrate_mc,height = 4)
  68. self.calibratemc_button.pack_forget()
  69. self.clear_button = tk.Button(self.controls, text="Clear graph", command=self.graph.clear, height=4)
  70. self.clear_button.pack_forget()
  71. self.logscreen_button = tk.Button(self.controls, text="Log", command=self.open_log, height=4)
  72. self.logscreen_button.pack_forget()
  73. self.menu_button = tk.Button(self.controls, text="Menu", command=self.menu, height=4)
  74. self.menu_button.pack(side="bottom", fill="both")
  75. self.menu_back_button = tk.Button(self.controls, text="Back", command=self.back, height=4)
  76. self.menu_back_button.pack_forget()
  77. def update(self):
  78. if not self.root.winfo_exists():
  79. return
  80. ac_positions = []
  81. # aggregate measurements
  82. while self.ac_sensor.queue.qsize() > 0:
  83. name, data = self.ac_sensor.queue.get()
  84. if name == "data":
  85. ac_positions.append(data[0:2])
  86. self.ac_dro_val_sums += data
  87. self.ac_dro_val_count += 1
  88. opt_positions = []
  89. while self.opt_sensor.queue.qsize() > 0:
  90. name, data = self.opt_sensor.queue.get()
  91. if name == "data":
  92. opt_positions.append(data[0:2])
  93. self.opt_dro_val_sums += data
  94. self.opt_dro_val_count += 1
  95. mag_positions = []
  96. while self.mag_sensor.queue.qsize() > 0:
  97. name, data = self.mag_sensor.queue.get()
  98. if name == "data":
  99. mag_positions.append(data[0:2])
  100. self.mag_dro_val_sums += data
  101. self.mag_dro_val_count += 1
  102. # graph shows all values as a line
  103. self.graph.update([ac_positions, opt_positions, mag_positions])
  104. # update status color
  105. if self.ac_sensor.dummyActive:
  106. self.ac_label.config(fg="white", bg="red")
  107. elif len(ac_positions) > 0:
  108. self.ac_label.config(fg="white", bg="green")
  109. else:
  110. self.ac_label.config(fg="black", bg="yellow")
  111. if not self.opt_sensor.success:
  112. self.opt_label.config(fg="white", bg="red")
  113. elif len(opt_positions) > 0:
  114. self.opt_label.config(fg="white", bg="green")
  115. else:
  116. self.opt_label.config(fg="black", bg="yellow")
  117. if not self.mag_sensor.:
  118. self.mag_label.config(fg="white", bg="red")
  119. elif len(mag_positions) > 0:
  120. self.mag_label.config(fg="white", bg="green")
  121. else:
  122. self.mag_label.config(fg="black", bg="yellow")
  123. # readouts will only be updated so often
  124. if self.controlsUpdateTime + 0.4 < time.time():
  125. self.controlsUpdateTime = time.time()
  126. # they display the average of all values
  127. if self.ac_dro_val_count > 0:
  128. self.ac_dro_val_sums /= self.ac_dro_val_count
  129. else:
  130. self.ac_dro_val_sums.fill(0)
  131. self.ac_dro_x.set("X: {:.1f} mm".format(self.ac_dro_val_sums[0]))
  132. self.ac_dro_y.set("Y: {:.1f} mm".format(self.ac_dro_val_sums[1]))
  133. self.ac_dro_t1.set("t1: {:.3f} ms".format(self.ac_dro_val_sums[2]/1000))
  134. self.ac_dro_t2.set("t2: {:.3f} ms".format(self.ac_dro_val_sums[3]/1000))
  135. self.ac_dro_val_sums.fill(0)
  136. self.ac_dro_val_count = 0
  137. if self.opt_dro_val_count > 0:
  138. self.opt_dro_val_sums /= self.opt_dro_val_count
  139. else:
  140. self.opt_dro_val_sums.fill(0)
  141. self.opt_dro_x.set("X: {:.1f} mm".format(self.opt_dro_val_sums[0]))
  142. self.opt_dro_y.set("Y: {:.1f} mm".format(self.opt_dro_val_sums[1]))
  143. self.opt_dro_offset.set("offset: {:.1f} %".format(self.opt_dro_val_sums[2]*100))
  144. self.opt_dro_size.set("size: {:.1f} %".format(self.opt_dro_val_sums[3]*100))
  145. self.opt_dro_val_sums.fill(0)
  146. self.opt_dro_val_count = 0
  147. if self.popup_window:
  148. self.popup_window.update()
  149. if self.log_window:
  150. self.log_window.update()
  151. self.root.after(30, self.update)
  152. def calibrate_ac(self):
  153. self.ac_sensor.start_calibration()
  154. if not self.popup_window or not self.pu_root.winfo_exists():
  155. # create new window
  156. self.pu_root = tk.Toplevel(self.root)
  157. self.pu_root.wm_transient(self.root)
  158. self.pu_root.wm_title("Acoustic Sensor Calibration")
  159. # make it centered
  160. x = (self.pu_root.winfo_screenwidth() - 500) / 2
  161. y = (self.pu_root.winfo_screenheight() - 200) / 2
  162. self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
  163. # deactivate mainWindow
  164. self.pu_root.grab_set()
  165. self.popup_window = CalibrationPopUp(self.pu_root, self.ac_sensor.calibration_state, self.conf)
  166. self.popup_window.pack(side="top", fill="both", expand=True)
  167. def calibrate_mc(self):
  168. pass
  169. def open_log(self):
  170. #create new window
  171. self.log_root = tk.Toplevel(self.root)
  172. self.log_root.wm_transient(self.root)
  173. self.log_root.wm_title("Logs")
  174. #center
  175. x = (self.log_root.winfo_screenwidth() - 780) / 2
  176. y = (self.log_root.winfo_screenheight() - 400) / 2
  177. self.log_root.geometry(f'780x400+{int(x)}+{int(y)}')
  178. # deactivate mainWindow
  179. self.log_root.grab_set()
  180. self.log_window = LogScreen(self.log_root)
  181. self.log_window.pack(side="top", fill="both", expand=True)
  182. # Menu Button
  183. def menu(self):
  184. self.menu_back_button.pack(side="bottom", fill="both")
  185. self.calibrateac_button.pack(side="bottom", fill="both")
  186. self.calibratemc_button.pack(side="bottom", fill="both")
  187. self.clear_button.pack(side="bottom", fill="both")
  188. self.logscreen_button.pack(side="bottom", fill="both")
  189. self.menu_button.pack_forget()
  190. #Back Button
  191. def back(self):
  192. self.calibrateac_button.pack_forget()
  193. self.calibratemc_button.pack_forget()
  194. self.clear_button.pack_forget()
  195. self.logscreen_button.pack_forget()
  196. self.menu_button.pack(side="bottom", fill="both")
  197. self.menu_back_button.pack_forget()