update rtlsdr reader
This commit is contained in:
@@ -3,88 +3,105 @@ import pyModeS as pms
|
||||
from rtlsdr import RtlSdr
|
||||
import time
|
||||
|
||||
modes_sample_rate = 2e6
|
||||
sampling_rate = 2e6
|
||||
smaples_per_microsec = 2
|
||||
|
||||
modes_frequency = 1090e6
|
||||
buffer_size = 1024 * 100
|
||||
read_size = 1024 * 20
|
||||
read_size = 1024 * 10
|
||||
|
||||
pbits = 8
|
||||
fbits = 112
|
||||
preamble = [1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
|
||||
th_amp = 0.2 # signal amplitude threshold for 0 and 1 bit
|
||||
# th_amp = 0.2 # signal amplitude threshold for 0 and 1 bit
|
||||
th_amp_diff = 0.8 # signal amplitude threshold difference between 0 and 1 bit
|
||||
|
||||
|
||||
class RtlReader(object):
|
||||
def __init__(self, **kwargs):
|
||||
super(RtlReader, self).__init__()
|
||||
self.signal_buffer = []
|
||||
self.signal_buffer = [] # amplitude of the sample only
|
||||
self.sdr = RtlSdr()
|
||||
self.sdr.sample_rate = modes_sample_rate
|
||||
self.sdr.sample_rate = sampling_rate
|
||||
self.sdr.center_freq = modes_frequency
|
||||
self.sdr.gain = "auto"
|
||||
# sdr.freq_correction = 75
|
||||
|
||||
self.debug = kwargs.get("debug", False)
|
||||
self.raw_pipe_in = None
|
||||
self.stop_flag = False
|
||||
self.noise_floor = 1e6
|
||||
|
||||
def _calc_noise(self):
|
||||
"""Calculate noise floor"""
|
||||
window = smaples_per_microsec * 100
|
||||
means = np.array(self.signal_buffer).reshape(-1, window).mean(axis=1)
|
||||
return min(means)
|
||||
|
||||
def _process_buffer(self):
|
||||
"""process raw IQ data in the buffer"""
|
||||
|
||||
# update noise floor
|
||||
self.noise_floor = min(self._calc_noise(), self.noise_floor)
|
||||
|
||||
# set minimum signal amplitude
|
||||
min_sig_amp = 3.162 * self.noise_floor # 10 dB SNR
|
||||
|
||||
# Mode S messages
|
||||
messages = []
|
||||
|
||||
# signal_array = np.array(self.signal_buffer)
|
||||
# pulses_array = np.where(np.array(self.signal_buffer) < th_amp, 0, 1)
|
||||
# pulses = "".join(str(x) for x in pulses_array)
|
||||
buffer_length = len(self.signal_buffer)
|
||||
|
||||
i = 0
|
||||
while i < buffer_length:
|
||||
if self.signal_buffer[i] < th_amp:
|
||||
if self.signal_buffer[i] < min_sig_amp:
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# if pulses[i : i + pbits * 2] == preamble:
|
||||
if self._check_preamble(self.signal_buffer[i : i + pbits * 2]):
|
||||
frame_start = i + pbits * 2
|
||||
frame_end = i + pbits * 2 + (fbits + 1) * 2
|
||||
frame_length = (fbits + 1) * 2
|
||||
frame_pulses = self.signal_buffer[frame_start:frame_end]
|
||||
|
||||
msgbin = ""
|
||||
threshold = max(frame_pulses) * 0.2
|
||||
|
||||
msgbin = []
|
||||
for j in range(0, frame_length, 2):
|
||||
p2 = frame_pulses[j : j + 2]
|
||||
if len(p2) < 2:
|
||||
break
|
||||
|
||||
if p2[0] < th_amp and p2[1] < th_amp:
|
||||
if p2[0] < threshold and p2[1] < threshold:
|
||||
break
|
||||
elif p2[0] >= p2[1]:
|
||||
c = "1"
|
||||
c = 1
|
||||
elif p2[0] < p2[1]:
|
||||
c = "0"
|
||||
c = 0
|
||||
else:
|
||||
msgbin = ""
|
||||
msgbin = []
|
||||
break
|
||||
msgbin += c
|
||||
|
||||
msgbin.append(c)
|
||||
|
||||
# advance i with a jump
|
||||
i = frame_start + j
|
||||
|
||||
if len(msgbin) > 0:
|
||||
msghex = pms.bin2hex(msgbin)
|
||||
msghex = pms.bin2hex("".join([str(i) for i in msgbin]))
|
||||
if self._check_msg(msghex):
|
||||
messages.append([msghex, time.time()])
|
||||
if self.debug:
|
||||
self._debug_msg(msghex)
|
||||
|
||||
elif i > buffer_length - 500:
|
||||
# save some for next process
|
||||
break
|
||||
# elif i > buffer_length - 500:
|
||||
# # save some for next process
|
||||
# break
|
||||
else:
|
||||
i += 1
|
||||
|
||||
# keep reminder of buffer for next iteration
|
||||
# reset the buffer
|
||||
self.signal_buffer = self.signal_buffer[i:]
|
||||
|
||||
return messages
|
||||
|
||||
def _check_preamble(self, pulses):
|
||||
@@ -122,10 +139,8 @@ class RtlReader(object):
|
||||
pass
|
||||
|
||||
def _read_callback(self, data, rtlsdr_obj):
|
||||
# scaling signal (imporatant)
|
||||
amp = np.absolute(data)
|
||||
amp_norm = np.interp(amp, (amp.min(), amp.max()), (0, 1))
|
||||
self.signal_buffer.extend(amp_norm.tolist())
|
||||
self.signal_buffer.extend(amp.tolist())
|
||||
|
||||
if len(self.signal_buffer) >= buffer_size:
|
||||
messages = self._process_buffer()
|
||||
|
||||
Reference in New Issue
Block a user