From d00bb6d29ceae9d2ee958b57549af335e977edc6 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Thu, 18 Nov 2021 19:07:03 +0100 Subject: Partially implement xor correlator (untested) --- src/gr-fadingui/build.sh | 8 ---- src/gr-fadingui/install.sh | 8 ++++ src/gr-fadingui/python/datasource.py | 3 +- src/gr-fadingui/python/xor_frame_sync.py | 70 ++++++++++++++++++++------------ 4 files changed, 55 insertions(+), 34 deletions(-) delete mode 100755 src/gr-fadingui/build.sh create mode 100755 src/gr-fadingui/install.sh (limited to 'src/gr-fadingui') diff --git a/src/gr-fadingui/build.sh b/src/gr-fadingui/build.sh deleted file mode 100755 index 29697af..0000000 --- a/src/gr-fadingui/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -mkdir -p build -cmake -DGR_PYTHON_DIR=/usr/lib/python3/dist-packages/ -GNinja -Bbuild -ninja -C build - -# install to system -sudo ninja -C build install diff --git a/src/gr-fadingui/install.sh b/src/gr-fadingui/install.sh new file mode 100755 index 0000000..29697af --- /dev/null +++ b/src/gr-fadingui/install.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +mkdir -p build +cmake -DGR_PYTHON_DIR=/usr/lib/python3/dist-packages/ -GNinja -Bbuild +ninja -C build + +# install to system +sudo ninja -C build install diff --git a/src/gr-fadingui/python/datasource.py b/src/gr-fadingui/python/datasource.py index ab2f441..c7d68f1 100644 --- a/src/gr-fadingui/python/datasource.py +++ b/src/gr-fadingui/python/datasource.py @@ -8,6 +8,7 @@ import io import numpy as np from gnuradio import gr + class datasource(gr.sync_block): """ Loads data from a file choosen in the graphical user interface, splits into @@ -51,7 +52,7 @@ class datasource(gr.sync_block): def make_header(self, data_size): # TODO: check that data_size is not too big - pilot = 0x1248 + pilot = 0xbeef # TODO: implement hamming code for header header = f"p{pilot:04x}s{data_size:04x}d".encode("ascii") diff --git a/src/gr-fadingui/python/xor_frame_sync.py b/src/gr-fadingui/python/xor_frame_sync.py index 735a031..af7aa85 100644 --- a/src/gr-fadingui/python/xor_frame_sync.py +++ b/src/gr-fadingui/python/xor_frame_sync.py @@ -12,36 +12,48 @@ from gnuradio import gr class xor_frame_sync(gr.sync_block): """ - docstring for block xor_frame_sync + Performs a frame synchronization by XOR matching a preamble bit sequence """ def __init__(self, sync_pattern, buffer_size): + # TODO: buffer size should be in packets gr.sync_block.__init__(self, name="xor_frame_sync", in_sig=[np.byte], out_sig=[np.byte]) # binary pattern to match - self.pattern = np.array(sync_pattern, dtype=np.dtype("uint8")) - self.nbits = len(sync_pattern) + self.pattern = np.unpackbits(np.array(sync_pattern, dtype=np.uint8))[::-1] + self.nbytes = len(sync_pattern) + self.nbits = len(self.pattern) - # buffer to delay the data - self.delay_fifo = RingBuffer(buffer_size, dtype=np.byte) + assert(self.nbits % 8 == 0) - # buffers to store cross correlation data - self.xcorr = RingBuffer(buffer_size, dtype=np.dtype("uint8")) + # packed buffer to delay the data + self.delaybuf = RingBuffer(buffer_size, dtype=np.uint8) + self.delay = 0 + + # unpacked buffer to compute correlation values, initially filled with zeros + self.corrbuf = RingBuffer(self.nbits) + self.corrbuf.extend(np.zeros(self.nbits)) + + # buffer to store correlation values + self.xcorrs = RingBuffer(buffer_size) # synchronization state self.synchronized = False - self.delay = 0 - def xcorrelation(self): + def xcorrelation(self, v): """ - Compute the binary correlation between the stream and the stored - pattern. Binary correlation between two bit vectors is just size of the + Compute the binary correlations between the stored pattern and + correlation buffer, while shifting v into the buffer. + + Binary correlation between two bit vectors is just size of the vector(s) minus the number of bits that differ. """ - unpacked = np.unpackbits(self.delay_fifo[0]) - return self.nbits - sum(np.logical_xor(unpacked, self.pattern)) + v_arr = np.array(v, dtype=np.uint8) + for b in np.unpackbits(v_arr): + self.corrbuf.appendleft(b) + yield self.nbits - np.sum(np.logical_xor(self.corrbuf, self.pattern)) def work(self, input_items, output_items): """ @@ -51,29 +63,37 @@ class xor_frame_sync(gr.sync_block): pattern appears every k bits, where k is the size of the packet. - If the buffer is not synchronized, compute a binary cross - correlation to find how by much the stream should be delayed. + correlation to find how much the stream should be delayed. + + Notes: + + - Even though the block input is of type np.byte, inp is an array + of 255 bytes, probably for performance reasons. + TODO: block processing """ inp = input_items[0] out = output_items[0] - # Add data to delay buffer - self.delay_fifo.appendleft(inp) - - # TODO: check for synchronization, else compute - - # Compute correlation if not self.synchronized: - self.xcorr.append(self.xcorrelation()) + for v in inp: + # compute the cross correlation + xcs = self.xcorrelation(v) - peak = np.argmax(self.xcorr) - if self.xcorr[peak] != self.nbits: - print(f"Warning! XOR correlation is not perfect (peak value = {self.xcorr[peak]})") + # add cross correlations to buffer and save value + self.xcorrs.extend(list(xcs)) + self.delaybuf.appendleft(v) + peak = np.argmax(self.xcorrs) self.delay = peak self.synchronized = True + if self.xcorrs[peak] != self.nbits: + self.synchronized = False + print(f"Warning! XOR correlation is not perfect (peak value = {self.xcorrs[peak]})") + + # return data with delay - out[:] = self.delay_fifo[self.delay] + out[:] = self.delaybuf[self.delay] return len(output_items[0]) -- cgit v1.2.1