sensors.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. from connection import ArduinoSlave
  2. import markerDetection
  3. import time
  4. import statistics
  5. import math
  6. import threading
  7. import random
  8. import traceback
  9. import cv2
  10. conn = ArduinoSlave()
  11. class AcusticSensor:
  12. def __init__(self,conf,up_queue,down_queue,calibration_state):
  13. self.up_queue = up_queue
  14. self.down_queue = down_queue
  15. self.calibration_state = calibration_state
  16. self.field_height = float(conf["field"]["y"])
  17. self.field_length = float(conf["field"]["x"])
  18. self.sensor_distance = float(conf["ac_sensor"]["sensor_distance"])
  19. self.sensor_y_offset = float(conf["ac_sensor"]["y_offset"])
  20. self.left_sensor_x_offset = float(conf["ac_sensor"]["left_x_offset"])
  21. self.right_sensor_x_offset = float(conf["ac_sensor"]["right_x_offset"])
  22. self.sonic_speed = float(conf["ac_sensor"]["sonicspeed"])
  23. self.overhead_left = float(conf["ac_sensor"]["overhead_left"])
  24. self.overhead_right = float(conf["ac_sensor"]["overhead_right"])
  25. self.time_vals = [[],[]]
  26. self.cal_values = {
  27. "left": [0, 0],
  28. "right": [0, 0]
  29. }
  30. self.n = 0
  31. def start(self):
  32. self.dummyActive = True
  33. if not conn.isConnected():
  34. conn.open()
  35. conn.addRecvCallback(self._readCb)
  36. dummyThread = threading.Thread(target=self._readCb_dummy)
  37. dummyThread.start()
  38. while True:
  39. action = self.down_queue.get()
  40. print("action",action)
  41. if action == "calibrate":
  42. self.calibration_state.reset_state()
  43. self.time_vals = [[],[]]
  44. self.calibration_state.next_state()
  45. elif action == "stop":
  46. print("exit Sensor")
  47. self.dummyActive = False
  48. dummyThread.join()
  49. break
  50. conn.close()
  51. def _readCb_dummy(self):
  52. while self.dummyActive:
  53. value = (900+random.randint(0,300),900+random.randint(0,300))
  54. value = ((math.sin(self.n)+1)*400+900, (math.cos(self.n)+1)*400+900)
  55. self.n += 0.02
  56. #print("dummy acc: ", value)
  57. if self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_1:
  58. value = (1541+random.randint(-50,50),2076+random.randint(-50,50))
  59. elif self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_2:
  60. value = (2076+random.randint(-50,50),1541+random.randint(-50,50))
  61. self.calibrate(value)
  62. self.pass_to_gui(self.calculate_position(value))
  63. time.sleep(0.01)
  64. def _readCb(self, raw):
  65. value = conn.getAcusticRTTs()
  66. print("acc: ", value)
  67. if self.dummyActive:
  68. self.dummyActive = False
  69. if value[0] >= 0 and value[1] >= 0:
  70. self.calibrate(value)
  71. self.pass_to_gui(self.calculate_position(value))
  72. def calibrate(self, value):
  73. if self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_1:
  74. self.time_vals[0].append(value[0])
  75. self.time_vals[1].append(value[1])
  76. if len(self.time_vals[0]) >= 100:
  77. self.cal_values["left"][0] = statistics.mean(self.time_vals[0])
  78. self.cal_values["right"][1] = statistics.mean(self.time_vals[1])
  79. self.time_vals = [[],[]]
  80. self.calibration_state.next_state() # signal gui to get next position
  81. elif self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_2:
  82. self.time_vals[0].append(value[0])
  83. self.time_vals[1].append(value[1])
  84. if len(self.time_vals[0]) >= 100:
  85. self.cal_values["left"][1] = statistics.mean(self.time_vals[0])
  86. self.cal_values["right"][0] = statistics.mean(self.time_vals[1])
  87. # all values have been captured
  88. print(self.cal_values)
  89. # calculate calibration results
  90. timedif = self.cal_values["left"][1] - self.cal_values["left"][0]
  91. distance_1 = math.sqrt(self.left_sensor_x_offset**2 + (self.sensor_y_offset + self.field_height)**2 )
  92. distance_2 = math.sqrt((self.left_sensor_x_offset + self.field_length)**2 + (self.sensor_y_offset + self.field_height)**2 )
  93. distancedif = distance_2 - distance_1
  94. sonicspeed_1 = distancedif / timedif
  95. overhead_1 = statistics.mean((self.cal_values["left"][1] - distance_1/sonicspeed_1, self.cal_values["left"][0] - distance_2/sonicspeed_1))
  96. timedif = self.cal_values["right"][1] - self.cal_values["right"][0]
  97. distance_1 = math.sqrt(self.right_sensor_x_offset**2 + (self.sensor_y_offset + self.field_height)**2 )
  98. distance_2 = math.sqrt((self.right_sensor_x_offset + self.field_length)**2 + (self.sensor_y_offset + self.field_height)**2 )
  99. distancedif = distance_2 - distance_1
  100. sonicspeed_2 = distancedif / timedif
  101. overhead_2 = statistics.mean((self.cal_values["right"][0] - distance_1/sonicspeed_2, self.cal_values["right"][1] - distance_2/sonicspeed_2))
  102. print(distance_1,sonicspeed_1,distance_2,sonicspeed_2)
  103. self.sonic_speed = statistics.mean((sonicspeed_1,sonicspeed_2))
  104. self.overhead_left = overhead_1
  105. self.overhead_right = overhead_2
  106. print("calibration result", self.sonic_speed, self.overhead_left, self.overhead_right)
  107. self.calibration_state.next_state()
  108. def read(self):
  109. value = conn.getAcusticRTTs()
  110. return value
  111. def calculate_position(self,values):
  112. try:
  113. val1, val2 = values
  114. val1 -= self.overhead_left
  115. val2 -= self.overhead_right
  116. distance_left = val1 * self.sonic_speed
  117. distance_right = val2 * self.sonic_speed
  118. x = (self.sensor_distance**2 - distance_right**2 + distance_left**2) / (2*self.sensor_distance) + self.left_sensor_x_offset
  119. y = math.sqrt(max(distance_left**2 - x**2, 0)) - self.sensor_y_offset
  120. return(x,y)
  121. except Exception as e:
  122. print(values)
  123. traceback.print_exc()
  124. def pass_to_gui(self,data):
  125. self.up_queue.put(("ac_data", data))
  126. class MagneticSensor:
  127. def __init__(self):
  128. pass
  129. def start(self):
  130. if not conn.isConnected():
  131. conn.open()
  132. conn.addRecvCallback(self._readCb)
  133. def _readCb(self, raw):
  134. print("mag: ", conn.getMagneticField())
  135. def calibrate(self, x, y):
  136. pass
  137. def read(self):
  138. return conn.getMagneticField()
  139. class OpticalSensor():
  140. def __init__(self):
  141. self.cap = cv2.VideoCapture(0)
  142. self._t = None
  143. self.values = None
  144. def start(self):
  145. if not self._t:
  146. self._t = threading.Thread(target=self._getFrames, args=())
  147. self._t.daemon = True # thread dies when main thread (only non-daemon thread) exits.
  148. self._t.start()
  149. def _getFrames(self):
  150. while True:
  151. success, image = self.cap.read()
  152. if success:
  153. self.values = markerDetection.measureDistances(image)
  154. print("opt:", self.values)
  155. def calibrate(self, x, y):
  156. pass
  157. def read(self):
  158. return self.values
  159. if __name__ == "__main__":
  160. acc = AcusticSensor()
  161. acc.start()
  162. mag = MagneticSensor()
  163. mag.start()
  164. opt = OpticalSensor()
  165. opt.start()
  166. while True:
  167. time.sleep(1)