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.

frequency_sweep.py 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import numpy as np
  2. import multiprocessing
  3. from modules.reader_interface import ReaderInterface
  4. import ast
  5. import os
  6. import time
  7. FREQ_SWITCH_TIME = 0.05
  8. LEN_COLLECTED_SAMPLES = 10
  9. class FrequencySweep(multiprocessing.Process):
  10. def __init__(self, pipe=None, consumers_pipes=None):
  11. multiprocessing.Process.__init__(self)
  12. self.pipe = pipe
  13. self.consumers_pipes = consumers_pipes
  14. self.config = None
  15. self.current_amp = None
  16. self.reader = None
  17. self.request = None
  18. self.freq_sweep_channel = None
  19. self.samples_block_size = None
  20. self.sweeping = False
  21. self.calibrated = False
  22. self.command = None
  23. self.swept_array = None
  24. self.frequency_list = None
  25. self.collected_samples = None
  26. self.offsets = None
  27. self.phis = None
  28. self.magnitude_offsets = None
  29. self.current_feedback = None
  30. self.percentage = 0
  31. self.sweep_index = 0
  32. def read_config(self):
  33. config_file = open(os.path.join(os.getcwd(), "frequency_sweep_config.txt"), "r")
  34. contents = config_file.read()
  35. self.config = ast.literal_eval(contents)
  36. config_file.close()
  37. self.current_amp = self.config["current_amp"]
  38. self.freq_sweep_channel = self.config["freq_sweep_channel"]
  39. self.samples_block_size = self.config["samples_block_size"]
  40. def process_sample(self, samples):
  41. sum_samples = np.zeros(np.shape(samples[0].getRawData()[self.freq_sweep_channel]), dtype=np.complex)
  42. for sample in samples:
  43. sum_samples += sample.getRawData()[self.freq_sweep_channel]
  44. self.collected_samples = sum_samples / len(samples)
  45. self.collected_samples = self.collected_samples.flatten()
  46. def configure_reader(self):
  47. self.reader = ReaderInterface(resistance=self.config["resistance"],
  48. inductance=self.config["inductance"],
  49. load_factor=self.config["loadFactor"],
  50. num_antennas=self.config["numAntennas"],
  51. channel_permutation=self.config["channelPermutation"])
  52. for idx, c in enumerate(self.config["channels"]):
  53. self.reader.setFrequency(idx, c[0])
  54. if c[1] > 0:
  55. self.reader.setExciterCurrent(idx, self.current_amp)
  56. self.reader.setExciterEnabled(idx, True)
  57. self.reader.setChannel20Switch(3) # Set channel 20 to current feedback
  58. self.reader.enableConfiguration()
  59. self.request = self.reader.requestData(self.process_sample, blockSize=self.samples_block_size, blocks=-1)
  60. def run(self):
  61. self.read_config()
  62. self.configure_reader()
  63. while True:
  64. if self.pipe.poll():
  65. self.command = self.pipe.recv()
  66. self.reset_sweep()
  67. if self.command[0] != 'stop':
  68. self.initiate_sweep()
  69. if self.sweeping:
  70. self.set_reader()
  71. time.sleep(FREQ_SWITCH_TIME)
  72. self.update_arrays()
  73. self.percentage = int((self.sweep_index / (len(self.frequency_list) - 1)) * 100)
  74. self.send()
  75. if self.sweep_index < len(self.frequency_list) - 1:
  76. self.sweep_index += 1
  77. else:
  78. if self.command[0] == 'continuous_sweep':
  79. self.sweep_index = 0
  80. else:
  81. self.reset_sweep()
  82. def send(self):
  83. if self.command[0] == 'recalibrate':
  84. self.pipe.send([self.percentage, self.offsets[self.sweep_index, 1:], self.offsets])
  85. elif self.command[0] == 'sweep':
  86. self.pipe.send([self.percentage, self.swept_array[self.sweep_index, 1:], self.swept_array])
  87. if self.consumers_pipes is not None:
  88. for pipe in self.consumers_pipes:
  89. pipe.send([self.percentage, self.swept_array[self.sweep_index, 1:], self.swept_array])
  90. elif self.command[0] == 'continuous_sweep':
  91. self.pipe.send([self.percentage, self.swept_array[self.sweep_index, 1:], self.swept_array])
  92. if self.consumers_pipes is not None:
  93. for pipe in self.consumers_pipes:
  94. pipe.send([self.percentage, self.swept_array[self.sweep_index, 1:], self.swept_array])
  95. def initiate_sweep(self):
  96. self.frequency_list = self.command[1]
  97. self.swept_array = np.ones((len(self.frequency_list), 22), dtype=np.complex)
  98. self.swept_array[:, 0] = self.frequency_list
  99. if self.command[0] == 'recalibrate':
  100. self.offsets = np.ones((len(self.frequency_list), 22), dtype=np.complex)
  101. self.calibrated = False
  102. self.sweeping = True
  103. def reset_sweep(self):
  104. self.sweeping = False
  105. self.sweep_index = 0
  106. def set_reader(self):
  107. self.reader.setFrequency(self.freq_sweep_channel, float(self.frequency_list[self.sweep_index]))
  108. self.reader.setExciterCurrent(self.freq_sweep_channel, self.current_amp)
  109. #self.reader.setExciterEnabled(self.freq_sweep_channel, True)
  110. def update_arrays(self):
  111. if self.command[0] == 'recalibrate':
  112. self.offsets[self.sweep_index, 1:] = self.collected_samples
  113. if self.sweep_index == len(self.frequency_list) - 1:
  114. self.phis = np.angle(self.offsets[:, 1:21], deg=False)
  115. self.magnitude_offsets = np.abs(self.offsets[:, 1:21])
  116. self.current_feedback = self.offsets[:, 21]
  117. self.calibrated = True
  118. else:
  119. if self.calibrated:
  120. self.swept_array[self.sweep_index, 1:] = (self.collected_samples - self.offsets[self.sweep_index, 1:])
  121. s_rotated = self.collected_samples[0:20] * np.exp(-1j * self.phis[self.sweep_index, :])
  122. current_feedback_calibrated = self.collected_samples[20] / self.current_feedback[self.sweep_index]
  123. self.swept_array[self.sweep_index, 1:21] = s_rotated - \
  124. (current_feedback_calibrated * self.magnitude_offsets[self.sweep_index, :])
  125. self.swept_array[self.sweep_index, 21] = current_feedback_calibrated