sensors.py 6.5 KB

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