mainWindow.py 7.6 KB

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