sensors.py 6.7 KB

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