improve singal process efficiency

This commit is contained in:
Junzi Sun 2019-08-22 16:59:12 +02:00
parent fdc34497c0
commit 785584aff5

View File

@ -1,24 +1,25 @@
import sys
import numpy as np import numpy as np
import pyModeS as pms import pyModeS as pms
from rtlsdr import RtlSdr from rtlsdr import RtlSdr
from threading import Thread from threading import Thread
import time import time
amplitude_threshold = 0.2
modes_sample_rate = 2e6 modes_sample_rate = 2e6
modes_frequency = 1090e6 modes_frequency = 1090e6
buffer_size = 1024 * 100 buffer_size = 1024 * 100
read_size = 1024 * 8 read_size = 1024 * 20
pbits = 8 pbits = 8
fbits = 112 fbits = 112
preamble = "1010000101000000" 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_diff = 0.8 # signal amplitude threshold difference between 0 and 1 bit
class RtlReader(Thread): class RtlReader(Thread):
def __init__(self, debug=False): def __init__(self, debug=False):
super(RtlReader, self).__init__() super(RtlReader, self).__init__()
self.signal_buffer = np.array([]) self.signal_buffer = []
self.debug = debug self.debug = debug
self.sdr = RtlSdr() self.sdr = RtlSdr()
self.sdr.sample_rate = modes_sample_rate self.sdr.sample_rate = modes_sample_rate
@ -29,37 +30,36 @@ class RtlReader(Thread):
def _process_buffer(self): def _process_buffer(self):
messages = [] messages = []
pulses_array = np.where(self.signal_buffer < amplitude_threshold, 0, 1) # signal_array = np.array(self.signal_buffer)
pulses = "".join(str(x) for x in pulses_array) # 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 i = 0
while i < len(pulses): while i < buffer_length:
if pulses[i] == 0: if self.signal_buffer[i] < th_amp:
i += 1 i += 1
continue continue
if pulses[i : i + pbits * 2] == preamble: # if pulses[i : i + pbits * 2] == preamble:
if self._check_preamble(self.signal_buffer[i : i + pbits * 2]):
frame_start = i + pbits * 2 frame_start = i + pbits * 2
frame_end = i + pbits * 2 + (fbits + 1) * 2 frame_end = i + pbits * 2 + (fbits + 1) * 2
frame_pulses = pulses[frame_start:frame_end] frame_length = (fbits + 1) * 2
frame_pulses = self.signal_buffer[frame_start:frame_end]
msgbin = "" msgbin = ""
for j in range(0, len(frame_pulses), 2): for j in range(0, frame_length, 2):
p2 = frame_pulses[j : j + 2] p2 = frame_pulses[j : j + 2]
if p2 == "10": if len(p2) < 2:
c = "1"
elif p2 == "01":
c = "0"
elif p2 == "11":
a2 = self.signal_buffer[
frame_start + j : frame_start + j + 2
]
if a2[0] > a2[1]:
c = "1"
else:
c = "0"
elif p2 == "00":
break break
if p2[0] < th_amp and p2[1] < th_amp:
break
elif p2[0] >= p2[1]:
c = "1"
elif p2[0] < p2[1]:
c = "0"
else: else:
msgbin = "" msgbin = ""
break break
@ -75,7 +75,8 @@ class RtlReader(Thread):
if self.debug: if self.debug:
self._debug_msg(msghex) self._debug_msg(msghex)
elif i > len(self.signal_buffer) - pbits * 2 - fbits * 2: elif i > buffer_length - 500:
# save some for next process
break break
else: else:
i += 1 i += 1
@ -84,6 +85,16 @@ class RtlReader(Thread):
self.signal_buffer = self.signal_buffer[i:] self.signal_buffer = self.signal_buffer[i:]
return messages return messages
def _check_preamble(self, pulses):
if len(pulses) != 16:
return False
for i in range(16):
if abs(pulses[i] - preamble[i]) > th_amp_diff:
return False
return True
def _check_msg(self, msg): def _check_msg(self, msg):
df = pms.df(msg) df = pms.df(msg)
msglen = len(msg) msglen = len(msg)
@ -105,30 +116,34 @@ class RtlReader(Thread):
elif df in [4, 5, 11] and msglen == 14: elif df in [4, 5, 11] and msglen == 14:
print(msg, pms.icao(msg)) print(msg, pms.icao(msg))
else: else:
print("[*]", msg) # print("[*]", msg)
pass pass
def _read_callback(self, data, rtlsdr_obj): def _read_callback(self, data, rtlsdr_obj):
self.signal_buffer = np.concatenate( # scaling signal (imporatant)
(self.signal_buffer, np.absolute(data)) amp = np.absolute(data)
) amp_norm = np.interp(amp, (amp.min(), amp.max()), (0, 1))
self.signal_buffer.extend(amp_norm.tolist())
if len(self.signal_buffer) >= buffer_size: if len(self.signal_buffer) >= buffer_size:
try:
messages = self._process_buffer() messages = self._process_buffer()
self.handle_messages(messages) self.handle_messages(messages)
except KeyboardInterrupt:
sys.exit(1)
def handle_messages(self, messages): def handle_messages(self, messages):
"""re-implement this method to handle the messages""" """re-implement this method to handle the messages"""
for msg, t in messages: for msg, t in messages:
pass
# print("%15.9f %s" % (t, msg)) # print("%15.9f %s" % (t, msg))
pass
def stop(self):
self.sdr.cancel_read_async()
def run(self): def run(self):
self.sdr.read_samples_async(self._read_callback, read_size) self.sdr.read_samples_async(self._read_callback, read_size)
# while True:
# count = 1
# while count < 1000:
# count += 1
# data = self.sdr.read_samples(read_size) # data = self.sdr.read_samples(read_size)
# self._read_callback(data, None) # self._read_callback(data, None)
@ -136,5 +151,5 @@ class RtlReader(Thread):
if __name__ == "__main__": if __name__ == "__main__":
rtl = RtlReader() rtl = RtlReader()
rtl.debug = True rtl.debug = True
# rtl.daemon = True
rtl.start() rtl.start()
rtl.join()