mainWindow.py 9.1 KB

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