sensors.py 7.4 KB

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