mainWindow.py 8.6 KB

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