sensors.py 6.7 KB

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