mainWindow.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. tk.Frame.__init__(self, root)
  20. # data plot at left side
  21. self.graph = Graph(self)
  22. self.graph.pack(fill=tk.BOTH, side=tk.LEFT, expand=True)
  23. # frame at right side
  24. self.controls = tk.Frame(self, borderwidth=4)
  25. self.controls.pack(fill=tk.BOTH, side=tk.RIGHT)
  26. self.controlsUpdateTime = 0
  27. self.ac_dro_val_sums = np.ndarray((4), dtype=np.float)
  28. self.ac_dro_val_count = 0
  29. self.ac_dro_x = tk.StringVar()
  30. self.ac_dro_y = tk.StringVar()
  31. self.ac_dro_t1 = tk.StringVar()
  32. self.ac_dro_t2 = tk.StringVar()
  33. self.ac_label = tk.Label(self.controls, text="Acoustic Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  34. self.ac_label.pack(side="top", fill="both", expand=False)
  35. tk.Label(self.controls, textvariable=self.ac_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
  36. tk.Label(self.controls, textvariable=self.ac_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
  37. tk.Label(self.controls, textvariable=self.ac_dro_t1, anchor="nw").pack(side="top", fill="both", expand=False)
  38. tk.Label(self.controls, textvariable=self.ac_dro_t2, anchor="nw").pack(side="top", fill="both", expand=False)
  39. self.opt_dro_val_sums = np.ndarray((4), dtype=np.float)
  40. self.opt_dro_val_count = 0
  41. self.opt_dro_x = tk.StringVar()
  42. self.opt_dro_y = tk.StringVar()
  43. self.opt_dro_offset = tk.StringVar()
  44. self.opt_dro_size = tk.StringVar()
  45. self.opt_label = tk.Label(self.controls, text="Optical Sensor", anchor="c", font=("Helvatica", 10, 'bold'))
  46. self.opt_label.pack(side="top", fill="both", expand=False)
  47. tk.Label(self.controls, textvariable=self.opt_dro_x, anchor="nw").pack(side="top", fill="both", expand=False)
  48. tk.Label(self.controls, textvariable=self.opt_dro_y, anchor="nw").pack(side="top", fill="both", expand=False)
  49. tk.Label(self.controls, textvariable=self.opt_dro_offset, anchor="nw").pack(side="top", fill="both", expand=False)
  50. tk.Label(self.controls, textvariable=self.opt_dro_size, anchor="nw").pack(side="top", fill="both", expand=False)
  51. menu_button = tk.Button(self.controls, text="Menu", command=self.menu, height=4)
  52. menu_button.pack(side="bottom", fill="both")
  53. quit_button = tk.Button(self.controls, text="Quit", command=self.root.destroy, height=2, foreground="red")
  54. quit_button.pack(side="bottom", fill="both")
  55. quit_button.forget_pack()
  56. calibrate_button = tk.Button(self.controls, text="Calibrate AC", command=self.calibrate_ac, height=4)
  57. calibrate_button.pack(side="bottom", fill="both")
  58. calibrate_button.foreget_pack()
  59. clear_button = tk.Button(self.controls, text="Clear graph", command=self.graph.clear, height=4)
  60. clear_button.pack(side="bottom", fill="both")
  61. clear_button.forget_pack()
  62. logscreen_button = tk.Button(self.controls, text="Log", command=self.open_log, height=4)
  63. logscreen_button.pack(side="bottom", fill="both")
  64. logscren_button.forget_pack()
  65. def update(self):
  66. if not self.root.winfo_exists():
  67. return
  68. ac_positions = []
  69. # aggregate measurements
  70. while self.ac_sensor.queue.qsize() > 0:
  71. name, data = self.ac_sensor.queue.get()
  72. if name == "data":
  73. ac_positions.append(data[0:2])
  74. self.ac_dro_val_sums += data
  75. self.ac_dro_val_count += 1
  76. opt_positions = []
  77. while self.opt_sensor.queue.qsize() > 0:
  78. name, data = self.opt_sensor.queue.get()
  79. if name == "data":
  80. opt_positions.append(data[0:2])
  81. self.opt_dro_val_sums += data
  82. self.opt_dro_val_count += 1
  83. # graph shows all values as a line
  84. self.graph.update([ac_positions, opt_positions])
  85. # update status color
  86. if self.ac_sensor.dummyActive:
  87. self.ac_label.config(fg="white", bg="red")
  88. elif len(ac_positions) > 0:
  89. self.ac_label.config(fg="white", bg="green")
  90. else:
  91. self.ac_label.config(fg="black", bg="yellow")
  92. if not self.opt_sensor.success:
  93. self.opt_label.config(fg="white", bg="red")
  94. elif len(opt_positions) > 0:
  95. self.opt_label.config(fg="white", bg="green")
  96. else:
  97. self.opt_label.config(fg="black", bg="yellow")
  98. # readouts will only be updated so often
  99. if self.controlsUpdateTime + 0.4 < time.time():
  100. self.controlsUpdateTime = time.time()
  101. # they display the average of all values
  102. if self.ac_dro_val_count > 0:
  103. self.ac_dro_val_sums /= self.ac_dro_val_count
  104. else:
  105. self.ac_dro_val_sums.fill(0)
  106. self.ac_dro_x.set("X: {:.1f} mm".format(self.ac_dro_val_sums[0]))
  107. self.ac_dro_y.set("Y: {:.1f} mm".format(self.ac_dro_val_sums[1]))
  108. self.ac_dro_t1.set("t1: {:.3f} ms".format(self.ac_dro_val_sums[2]/1000))
  109. self.ac_dro_t2.set("t2: {:.3f} ms".format(self.ac_dro_val_sums[3]/1000))
  110. self.ac_dro_val_sums.fill(0)
  111. self.ac_dro_val_count = 0
  112. if self.opt_dro_val_count > 0:
  113. self.opt_dro_val_sums /= self.opt_dro_val_count
  114. else:
  115. self.opt_dro_val_sums.fill(0)
  116. self.opt_dro_x.set("X: {:.1f} mm".format(self.opt_dro_val_sums[0]))
  117. self.opt_dro_y.set("Y: {:.1f} mm".format(self.opt_dro_val_sums[1]))
  118. self.opt_dro_offset.set("offset: {:.1f} %".format(self.opt_dro_val_sums[2]*100))
  119. self.opt_dro_size.set("size: {:.1f} %".format(self.opt_dro_val_sums[3]*100))
  120. self.opt_dro_val_sums.fill(0)
  121. self.opt_dro_val_count = 0
  122. if self.popup_window:
  123. self.popup_window.update()
  124. if self.log_window:
  125. self.log_window.update()
  126. self.root.after(30, self.update)
  127. def calibrate_ac(self):
  128. self.ac_sensor.start_calibration()
  129. if not self.popup_window or not self.pu_root.winfo_exists():
  130. # create new window
  131. self.pu_root = tk.Toplevel(self.root)
  132. self.pu_root.wm_transient(self.root)
  133. self.pu_root.wm_title("Acoustic Sensor Calibration")
  134. # make it centered
  135. x = (self.pu_root.winfo_screenwidth() - 500) / 2
  136. y = (self.pu_root.winfo_screenheight() - 200) / 2
  137. self.pu_root.geometry(f'500x200+{int(x)}+{int(y)}')
  138. # deactivate mainWindow
  139. self.pu_root.grab_set()
  140. self.popup_window = CalibrationPopUp(self.pu_root, self.ac_sensor.calibration_state, self.conf)
  141. self.popup_window.pack(side="top", fill="both", expand=True)
  142. def open_log(self):
  143. #create new window
  144. self.log_root = tk.Toplevel(self.root)
  145. self.log_root.wm_transient(self.root)
  146. self.log_root.wm_title("Logs")
  147. #center
  148. x = (self.log_root.winfo_screenwidth() - 780) / 2
  149. y = (self.log_root.winfo_screenheight() - 400) / 2
  150. self.log_root.geometry(f'780x400+{int(x)}+{int(y)}')
  151. # deactivate mainWindow
  152. self.log_root.grab_set()
  153. self.log_window = LogScreen(self.log_root)
  154. self.log_window.pack(side="top", fill="both", expand=True)
  155. def menu(self):
  156. self.menu_button.pack_forget()
  157. self.quit_button.pack(side="bottom", fill="both")
  158. self.calibrate_button.pack(side="bottom", fill="both")
  159. self.clear_button.pack(side="bottom", fill="both")
  160. self.logScreen_button.pack(side="bottom", fill="both")
  161. self.goback_button=tk.Button(self.controls, text="Go Back", command="goback", height=4)
  162. self.goback_button.pack(side="bottom", fill="both")
  163. def goback(self):
  164. self.menu_button.pack(side="bottom", fill="both")
  165. self.quit_button.forget_pack()
  166. self.calibrate_button.forget_pack()
  167. self.clear_button.forget_pack()
  168. self.logScreen_button.forget_pack()
  169. self.goback_button.forget_pack()