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. break
  49. conn.close()
  50. def _readCb_dummy(self):
  51. while self.dummyActive:
  52. value = (900+random.randint(0,300),900+random.randint(0,300))
  53. value = ((math.sin(self.n)+1)*400+900, (math.cos(self.n)+1)*400+900)
  54. self.n += 0.02
  55. if self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_1:
  56. value = (1541+random.randint(-50,50),2076+random.randint(-50,50))
  57. elif self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_2:
  58. value = (2076+random.randint(-50,50),1541+random.randint(-50,50))
  59. self.calibrate(value)
  60. self.pass_to_gui(self.calculate_position(value))
  61. time.sleep(0.01)
  62. def _readCb(self, raw):
  63. value = conn.getAcusticRTTs()
  64. if self.dummyActive:
  65. self.dummyActive = False
  66. if value[0] >= 0 and value[1] >= 0:
  67. self.calibrate(value)
  68. self.pass_to_gui(self.calculate_position(value))
  69. def calibrate(self, value):
  70. if self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_1:
  71. self.time_vals[0].append(value[0])
  72. self.time_vals[1].append(value[1])
  73. if len(self.time_vals[0]) >= 100:
  74. self.cal_values["left"][0] = statistics.mean(self.time_vals[0])
  75. self.cal_values["right"][1] = statistics.mean(self.time_vals[1])
  76. self.time_vals = [[],[]]
  77. self.calibration_state.next_state() # signal gui to get next position
  78. elif self.calibration_state.get_state() == self.calibration_state.ACCUMULATING_2:
  79. self.time_vals[0].append(value[0])
  80. self.time_vals[1].append(value[1])
  81. if len(self.time_vals[0]) >= 100:
  82. self.cal_values["left"][1] = statistics.mean(self.time_vals[0])
  83. self.cal_values["right"][0] = statistics.mean(self.time_vals[1])
  84. # all values have been captured
  85. print(self.cal_values)
  86. # calculate calibration results
  87. timedif = self.cal_values["left"][1] - self.cal_values["left"][0]
  88. distance_1 = math.sqrt(self.left_sensor_x_offset**2 + (self.sensor_y_offset + self.field_height)**2 )
  89. distance_2 = math.sqrt((self.left_sensor_x_offset + self.field_length)**2 + (self.sensor_y_offset + self.field_height)**2 )
  90. distancedif = distance_2 - distance_1
  91. sonicspeed_1 = distancedif / timedif
  92. overhead_1 = statistics.mean((self.cal_values["left"][1] - distance_1/sonicspeed_1, self.cal_values["left"][0] - distance_2/sonicspeed_1))
  93. timedif = self.cal_values["right"][1] - self.cal_values["right"][0]
  94. distance_1 = math.sqrt(self.right_sensor_x_offset**2 + (self.sensor_y_offset + self.field_height)**2 )
  95. distance_2 = math.sqrt((self.right_sensor_x_offset + self.field_length)**2 + (self.sensor_y_offset + self.field_height)**2 )
  96. distancedif = distance_2 - distance_1
  97. sonicspeed_2 = distancedif / timedif
  98. overhead_2 = statistics.mean((self.cal_values["right"][0] - distance_1/sonicspeed_2, self.cal_values["right"][1] - distance_2/sonicspeed_2))
  99. self.sonic_speed = statistics.mean((sonicspeed_1,sonicspeed_2))
  100. self.overhead_left = overhead_1
  101. self.overhead_right = overhead_2
  102. print("calibration results:")
  103. print(" sonicspeed: {:8.6f} mm/us".format(self.sonic_speed))
  104. print(" overhead_left: {:8.3f} us".format(self.overhead_left))
  105. print(" overhead_right: {:8.3f} us".format(self.overhead_right))
  106. self.calibration_state.next_state()
  107. def read(self):
  108. value = conn.getAcusticRTTs()
  109. return value
  110. def calculate_position(self,values):
  111. try:
  112. val1, val2 = values
  113. val1 -= self.overhead_left
  114. val2 -= self.overhead_right
  115. distance_left = val1 * self.sonic_speed
  116. distance_right = val2 * self.sonic_speed
  117. x = (self.sensor_distance**2 - distance_right**2 + distance_left**2) / (2*self.sensor_distance) + self.left_sensor_x_offset
  118. y = math.sqrt(max(distance_left**2 - x**2, 0)) - self.sensor_y_offset
  119. return(x,y)
  120. except Exception as e:
  121. print(values)
  122. traceback.print_exc()
  123. def pass_to_gui(self,data):
  124. self.up_queue.put(("ac_data", data))
  125. class MagneticSensor:
  126. def __init__(self):
  127. pass
  128. def start(self):
  129. if not conn.isConnected():
  130. conn.open()
  131. conn.addRecvCallback(self._readCb)
  132. def _readCb(self, raw):
  133. print("mag: ", conn.getMagneticField())
  134. def calibrate(self, x, y):
  135. pass
  136. def read(self):
  137. return conn.getMagneticField()
  138. class OpticalSensor():
  139. def __init__(self):
  140. self.cap = cv2.VideoCapture(0)
  141. self._t = None
  142. self.values = None
  143. def start(self):
  144. if not self._t:
  145. self._t = threading.Thread(target=self._getFrames, args=())
  146. self._t.daemon = True # thread dies when main thread (only non-daemon thread) exits.
  147. self._t.start()
  148. def _getFrames(self):
  149. while True:
  150. success, image = self.cap.read()
  151. if success:
  152. self.values = markerDetection.measureDistances(image)
  153. print("opt:", self.values)
  154. def calibrate(self, x, y):
  155. pass
  156. def read(self):
  157. return self.values
  158. if __name__ == "__main__":
  159. acc = AcusticSensor()
  160. acc.start()
  161. mag = MagneticSensor()
  162. mag.start()
  163. opt = OpticalSensor()
  164. opt.start()
  165. while True:
  166. time.sleep(1)