mainWindow.py 8.9 KB

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