sensors.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. from connection import ArduinoSlave
  2. import markerDetection
  3. import time
  4. import statistics
  5. import math
  6. import threading
  7. import noise
  8. import random
  9. import traceback
  10. import cv2
  11. conn = ArduinoSlave()
  12. class AcusticSensor:
  13. def __init__(self,conf,up_queue,down_queue,calibration_state):
  14. self.up_queue = up_queue
  15. self.down_queue = down_queue
  16. self.calibration_state = calibration_state
  17. self.conf = conf
  18. self.ac_conf = conf["ac_sensor"]
  19. def start(self):
  20. self.running = True
  21. if not conn.isConnected():
  22. conn.open()
  23. conn.addRecvCallback(self._readCb)
  24. thread = threading.Thread(target=self._readCb_dummy)
  25. thread.start()
  26. while True:
  27. action = self.down_queue.get()
  28. print("action",action)
  29. if action == "calibrate":
  30. calibration_thread = threading.Thread(target= self.calibrate)
  31. calibration_thread.start()
  32. elif action == "stop":
  33. print("exit Sensor")
  34. self.running = False
  35. thread.join()
  36. calibration_thread.join()
  37. break
  38. conn.close()
  39. def _readCb_dummy(self):
  40. while self.running:
  41. value = (900+random.randint(0,300),900+random.randint(0,300))
  42. #print("dummy acc: ", value)
  43. if self.calibration_state.return_state() == 2: #first range of calibration values
  44. value = (1541+random.randint(-50,50),2076+random.randint(-50,50))
  45. self.time_vals[0].append(value[0])
  46. self.time_vals[1].append(value[1])
  47. self.calibration_state.add_value()
  48. elif self.calibration_state.return_state() == 5: #second range of calibration values
  49. value = (2076+random.randint(-50,50),1541+random.randint(-50,50))
  50. self.time_vals[0].append(value[0])
  51. self.time_vals[1].append(value[1])
  52. self.calibration_state.add_value()
  53. else:
  54. self.pass_to_gui(self.calculate_position(value))
  55. time.sleep(0.01)
  56. def _readCb(self, raw):
  57. value = conn.getAcusticRTTs()
  58. print("acc: ", value)
  59. if self.calibration_state.return_state() == 2: #first range of calibration values
  60. self.time_vals[0].append(value[0])
  61. self.time_vals[1].append(value[1])
  62. self.calibration_state.add_value()
  63. elif self.calibration_state.return_state() == 5: #second range of calibration values
  64. self.time_vals[0].append(value[0])
  65. self.time_vals[1].append(value[1])
  66. self.calibration_state.add_value()
  67. else:
  68. self.pass_to_gui(self.calculate_position(value))
  69. def calibrate(self):
  70. if not self.calibration_state.return_state() == 1:
  71. print("current calibration state:",self.calibration_state.return_state(),"need to be 1 to start calibration!")
  72. return
  73. else:
  74. print("start calibration")
  75. self.time_vals = [[],[]]
  76. self.calibration_state.next_state()
  77. while self.calibration_state.return_value_count() < 100:
  78. print("value count",self.calibration_state.return_value_count())
  79. time.sleep(1) # wait until 100 values are gathered
  80. #todo add timeout
  81. if not self.running:
  82. self.calibration_state.reset_state()
  83. return
  84. left_time_1 = statistics.mean(self.time_vals[0])
  85. right_time_2 = statistics.mean(self.time_vals[1])
  86. self.calibration_state.next_state() # signal gui to get next position
  87. while self.calibration_state.return_state() != 4:
  88. time.sleep(1) # wait till ui is ready for second position
  89. #todo add timeout
  90. if not self.running:
  91. self.calibration_state.reset_state()
  92. return
  93. self.time_vals = [[],[]]
  94. self.calibration_state.reset_value_count()
  95. self.calibration_state.next_state()
  96. while self.calibration_state.return_value_count() < 100:
  97. print("value count",self.calibration_state.return_value_count())
  98. time.sleep(1) # wait until 100 values are gathered
  99. #todo add timeout
  100. if not self.running:
  101. self.calibration_state.reset_state()
  102. return
  103. left_time_2 = statistics.mean(self.time_vals[0])
  104. right_time_1 = statistics.mean(self.time_vals[1])
  105. self.calibration_state.next_state() # signal gui start of calculation
  106. timedif = left_time_2 - left_time_1
  107. distance_1 = math.sqrt(float(self.ac_conf["left_x_offset"])**2 + (float(self.ac_conf["y_offset"]) + float(self.conf["field"]["y"]))**2 )
  108. distance_2 = math.sqrt((float(self.ac_conf["left_x_offset"]) + float(self.conf["field"]["x"])**2 + (float(self.ac_conf["y_offset"]) + float(self.conf["field"]["y"])))**2 )
  109. distancedif = distance_2 - distance_1
  110. sonicspeed_1 = distancedif / timedif
  111. overhead_1 = statistics.mean((left_time_1 - distance_1/sonicspeed_1,left_time_2 - distance_2/sonicspeed_1))
  112. print(left_time_1,distance_1,sonicspeed_1,left_time_2,distance_2,sonicspeed_1)
  113. timedif = right_time_2 - right_time_1
  114. distance_1 = math.sqrt(float(self.ac_conf["right_x_offset"])**2 + (float(self.ac_conf["y_offset"]) + float(self.conf["field"]["y"]))**2 )
  115. distance_2 = math.sqrt((float(self.ac_conf["right_x_offset"]) + float(self.conf["field"]["x"])**2 + (float(self.ac_conf["y_offset"]) + float(self.conf["field"]["y"])))**2 )
  116. distancedif = distance_2 - distance_1
  117. sonicspeed_2 = distancedif / timedif
  118. overhead_2 = statistics.mean((right_time_1 - distance_1/sonicspeed_2,right_time_2 - distance_2/sonicspeed_2))
  119. self.ac_conf["sonicspeed"] = str(statistics.mean((sonicspeed_1,sonicspeed_2)))
  120. self.ac_conf["overhead"] = str(statistics.mean((overhead_1,overhead_2)))
  121. print("calibration result",float(self.ac_conf["sonicspeed"]),float(self.ac_conf["overhead"]))
  122. self.calibration_state.next_state()
  123. def read(self):
  124. value = conn.getAcusticRTTs()
  125. return value
  126. def calculate_position(self,values):
  127. try:
  128. val1, val2 = values
  129. val1 -= float(self.ac_conf["overhead"])
  130. val2 -= float(self.ac_conf["overhead"])
  131. distance_left = val1 * float(self.ac_conf["sonicspeed"]) # millisecond -> mikrosecond value of distance is in mm
  132. distance_right = val2 * float(self.ac_conf["sonicspeed"])
  133. x = (float(self.ac_conf["sensor_distance"])**2 - distance_right**2 + distance_left**2) / (2*float(self.ac_conf["sensor_distance"])) + float(self.ac_conf["left_x_offset"])
  134. y = math.sqrt(abs(distance_left**2 - x**2)) + float(self.ac_conf["y_offset"])
  135. return(x,y)
  136. except Exception as e:
  137. print(values)
  138. traceback.print_exc()
  139. def pass_to_gui(self,data):
  140. self.up_queue.put(data)
  141. class MagneticSensor:
  142. def __init__(self):
  143. pass
  144. def start(self):
  145. if not conn.isConnected():
  146. conn.open()
  147. conn.addRecvCallback(self._readCb)
  148. def _readCb(self, raw):
  149. print("mag: ", conn.getMagneticField())
  150. def calibrate(self, x, y):
  151. pass
  152. def read(self):
  153. return conn.getMagneticField()
  154. class OpticalSensor():
  155. def __init__(self):
  156. self.cap = cv2.VideoCapture(0)
  157. self._t = None
  158. self.values = None
  159. def start(self):
  160. if not self._t:
  161. self._t = threading.Thread(target=self._getFrames, args=())
  162. self._t.daemon = True # thread dies when main thread (only non-daemon thread) exits.
  163. self._t.start()
  164. def _getFrames(self):
  165. while True:
  166. success, image = self.cap.read()
  167. if success:
  168. self.values = markerDetection.measureDistances(image)
  169. print("opt:", self.values)
  170. def calibrate(self, x, y):
  171. pass
  172. def read(self):
  173. return self.values
  174. if __name__ == "__main__":
  175. acc = AcusticSensor()
  176. acc.start()
  177. mag = MagneticSensor()
  178. mag.start()
  179. opt = OpticalSensor()
  180. opt.start()
  181. while True:
  182. time.sleep(1)