You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

localization.py 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import numpy as np
  2. import os
  3. from copy import deepcopy
  4. class Localization:
  5. def __init__(self):
  6. self.scale_factor = 0.003
  7. self.k_nearest = 15
  8. #self.table = np.load('fingerprinting_tables/Julian_1cm_precision_corrected_antenas.npy') # corrected table made by Ihm (No ferrite)
  9. #self.table = np.load('fingerprinting_tables/SmallManualFingerprint_Ferrite.npy') # manual fingerprinting table (Ferrite) [A bit off]
  10. #self.table = np.load('fingerprinting_tables/Julian_BThesis_table2_switchedAnt5&6 and 7&8.npy') # Switched Ant5<->6 and 7<->8 in Excel (No Ferrite) [Does not work!]
  11. self.table = np.load('fingerprinting_tables/Julian_THIS_ONE_IS_IT.npy') # 2cm precision this definetly worked for (No ferrite)
  12. self.normalized_table = deepcopy(self.table)
  13. self.data = np.load('recorded_data/current_recording.npy')
  14. def localize(self, fv, exclude_frames=False):
  15. """ Input: - fv [type = numpy array (mb list) [15, 1]]:
  16. A feature vector contains the antenna voltages of one sample in following order:
  17. frame1, frame2, ... frame 8, main1, main2, ... main8
  18. - scale_factor [type = float]:
  19. This is multiplied with the fv to adjust the difference in constants between the real world
  20. and the measurements. Things like resistance, coil windings, amplification factors
  21. - k_nearest [type = int]:
  22. This tells the localization method k-nearest how many neighbours it should take into account
  23. to average the position in the end
  24. Output: - position [type = np.array[3]]:
  25. The estimated position of the object in this sample x,y,z
  26. """
  27. feature_vector = fv * self.scale_factor
  28. if exclude_frames:
  29. table_copy = deepcopy(self.table) # make a copy of the fingerprinting table
  30. table_copy[:, 17:25] = 0 # set all mains in the copy to 0
  31. max_idx = np.argmax(abs(feature_vector[:8])) # find highest Frame
  32. print("Feature_vector BEFORE taking highest frame out:\n", feature_vector)
  33. print("Highest Frame:", max_idx+1)
  34. feature_vector[max_idx] = 0
  35. print("Feature_vector AFTER taking highest frame out:\n", feature_vector)
  36. table_copy[:, max_idx+9] = 0 # set the row of highest Frame in fingerprinting to 0
  37. print("First row of table", table_copy[0])
  38. # print("feature vector =", feature_vector)
  39. # print("max_idx=", max_idx)
  40. # print("tablecopy= ", table_copy[0, :])
  41. repeated_feature_vector = np.square(table_copy[:, 9:] - feature_vector)
  42. else:
  43. repeated_feature_vector = np.square(self.table[:, 9:] - feature_vector) # Before changing anything on this function
  44. euclidean_distances = np.sum(repeated_feature_vector, 1)
  45. order = np.argsort(euclidean_distances)
  46. minDist = np.sqrt(euclidean_distances[order[0]])
  47. maxDist = np.sqrt(euclidean_distances[order[self.k_nearest - 1]])
  48. dsum = 0.0
  49. position = np.array([0.0, 0.0, 0.0])
  50. for idx in order[:self.k_nearest]:
  51. d = (maxDist - np.sqrt(euclidean_distances[idx])) / (maxDist - minDist)
  52. dsum += d
  53. position += self.table[idx][:3] * d
  54. position /= dsum
  55. #print(position)
  56. return position*1000 # conversion from metre to mm
  57. def localize_all_samples(self, input_path, output_path):
  58. # Load data
  59. data = np.load('recorded_data/' + input_path + ".npy")
  60. # Just User Feedback
  61. print("Start calculating positions from: recorded_data/" + input_path + ".npy")
  62. print("With: scale_factor=", self.scale_factor, ", k_nearest=", self.k_nearest, ", every 10th sample")
  63. data = data[::10, :] # taking only every 10th sample
  64. positions = np.empty((np.shape(data)[0], 3), dtype=np.float)
  65. #Normal Localization
  66. positions = np.empty((np.shape(data)[0], 3), dtype=np.float)
  67. for i in range(np.shape(data)[0]):
  68. fv = data[i, 3:]
  69. positions[i, :] = self.localize(fv)
  70. #print("loc progress=", i)
  71. # Save result
  72. np.save('calculated_positions/' + output_path, positions)
  73. print("Saved result in: calculated_positions/" + output_path + ".npy")
  74. def localize_all_samples_direct(self, data, output_path):
  75. """ same as localize all samples, but takes input_data directly and doesnt load it"""
  76. # Just User Feedback
  77. # print("Start calculating positions from data with shape:", np.shape(data))
  78. # print("With: scale_factor=", self.scale_factor, ", k_nearest=", self.k_nearest, ", every 10th sample")
  79. #data = data[::10, :] # taking only every 10th sample
  80. positions = np.empty((np.shape(data)[0], 3), dtype=np.float)
  81. #Normal Localization
  82. positions = np.empty((np.shape(data)[0], 3), dtype=np.float)
  83. for i in range(np.shape(data)[0]):
  84. fv = data[i, 3:]
  85. #print("fv=", fv)
  86. positions[i, :] = self.localize(fv)
  87. #print("loc progress=", i)
  88. # Save result
  89. np.save('calculated_positions/' + output_path, positions)
  90. #print("Saved result in: calculated_positions/" + output_path + ".npy")
  91. return positions
  92. def localize_averaged_samples(self, input_path, output_path):
  93. # Load data
  94. data = np.load('recorded_data/' + input_path + ".npy")
  95. # Just User Feedback
  96. print("Start calculating positions from: recorded_data/" + input_path + ".npy")
  97. print("With: scale_factor=", self.scale_factor, ", k_nearest=", self.k_nearest)
  98. # Average the recorded samples before localization
  99. positions = np.empty((np.shape(data)[0], 3), dtype=np.float)
  100. mean_data = np.zeros(np.shape(data))
  101. mean_data[:, :] = np.mean(data, axis=0) # average all recorded samples
  102. fv = mean_data[0, 3:] # as now all of mean_data is the same in every entry, just take any entry (at pos 0)
  103. positions = self.localize(fv) # we get a single position out
  104. print("Averaged position: x=", positions[0], ", y=", positions[1], ", z=", positions[2])
  105. # Save result
  106. np.save('calculated_positions/'+output_path, positions)
  107. print("Saved result in: calculated_positions/"+output_path+".npy")