aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <np@0hm.ch>2021-12-04 16:46:23 +0100
committerNao Pross <np@0hm.ch>2021-12-04 16:46:23 +0100
commit30012258948049da894e260d78551d1de44c2f50 (patch)
tree746ee8911972cc02112438861e175dc6189a4f33
parentGNUR Radio Test Sockets (diff)
downloadFading-30012258948049da894e260d78551d1de44c2f50.tar.gz
Fading-30012258948049da894e260d78551d1de44c2f50.zip
Update net.py to decode UDP data stream
-rwxr-xr-xsrc/gui/gui.py7
-rw-r--r--src/gui/net.py67
-rw-r--r--tests/sockets/Socket_test.grc24
-rwxr-xr-xtests/sockets/Test_Bit_Errorrate.py83
4 files changed, 71 insertions, 110 deletions
diff --git a/src/gui/gui.py b/src/gui/gui.py
index b2cbebb..d817f63 100755
--- a/src/gui/gui.py
+++ b/src/gui/gui.py
@@ -98,7 +98,8 @@ with window(label="RX DSP Flow Graph", width=800, height=400, pos=(25,25), tag="
#================================================
# Network plots Window
-recv_plot = net.network_plot(url="udp://localhost:31415", nsamples=100, label="Test", height=300, width=800)
+recv_plot = net.network_plot(url="udp://localhost:31415", dtype=float, nsamples=100, \
+ label="Test", height=300, width=800)
plots = {
recv_plot: "plt_ampl"
@@ -107,9 +108,9 @@ plots = {
with window(label="Time domain plots", width=800, height=400, pos=(850,25)):
with recv_plot:
add_plot_axis(mvXAxis, label="Time")
- add_plot_axis(mvYAxis, label="Amplitude", tag="plt_ampl")
+ add_plot_axis(mvYAxis, label="Amplitude", tag="axis")
- add_line_series(recv_plot.x_data, recv_plot.y_data, parent="plt_ampl")
+ add_line_series(recv_plot.xdata, recv_plot.ydata, parent="axis", tag="plt_ampl")
#================================================
# Start GUI and main loop
diff --git a/src/gui/net.py b/src/gui/net.py
index 2c91bb8..c7008cd 100644
--- a/src/gui/net.py
+++ b/src/gui/net.py
@@ -1,6 +1,7 @@
import select
import socket
from urllib.parse import urlparse
+import re
import numpy as np
from numpy_ringbuffer import RingBuffer
@@ -11,9 +12,10 @@ class udpsource:
"""
Creates an UDP listening socket
"""
- def __init__(self, url):
+ def __init__(self, url, dtype):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.url = urlparse(url)
+ self.dtype = dtype
def __del__(self):
self.sock.close()
@@ -23,32 +25,46 @@ class udpsource:
self.sock.bind((self.url.hostname, self.url.port))
# self.sock.listen()
- def read(self, nbytes):
- ready_to_read, ready_to_write, in_err = \
- select.select([self.sock], [], [], 1)
-
- if ready_to_read:
- data = sock.recv(nbytes)
- print(data)
- else:
+ def read(self, nblocks):
+ ready, _, _ = select.select([self.sock], [], [])
+ if not ready:
return None
+ # read from socket
+ blocksize = 1024 * 4
+ string = ready[0].recv(nblocks * blocksize).decode("ascii")
+
+ # decode string, remove empty values
+ chunks = filter(None, re.split(r"\[(.+?)\]", string))
+
+ def chunk_to_samples(chunk):
+ samples = chunk.split(",")
+ if samples:
+ return list(map(self.dtype, samples))
+
+ # convert each chunk into a list of samples
+ chunk_values = map(chunk_to_samples, chunks)
+
+ # flatten list of lists into a single list
+ values = sum(chunk_values, [])
+
+ return values
class network_plot(udpsource):
- def __init__(self, url, nsamples, **kwargs):
- udpsource.__init__(self, url)
+ def __init__(self, url, dtype, nsamples, **kwargs):
+ udpsource.__init__(self, url, dtype)
+ # create buffers for x and y values
self.nsamples = nsamples
- self.plot = dpg.plot(**kwargs)
-
- # create buffer and fill with zeroes
- self.buffer = RingBuffer(capacity=nsamples, dtype=(float, 2))
- for i in range(nsamples):
- # TODO: remove random data used for testing
- self.buffer.append(np.array([i, 1 + np.random.rand() / 5]))
+ self.xvalues = np.arange(0, self.nsamples)
+ self.yvalues = RingBuffer(capacity=self.nsamples, dtype=np.dtype(dtype))
+ self.yvalues.extend(np.zeros(self.nsamples))
+ # create a plot
+ self.plot = dpg.plot(**kwargs)
self.bind()
+ # Map `with' expressions to the underlying plot
def __enter__(self):
return self.plot.__enter__()
@@ -56,13 +72,16 @@ class network_plot(udpsource):
self.plot.__exit__(t, val, tb)
@property
- def x_data(self):
- return np.array(self.buffer[:,0])
+ def xdata(self):
+ return self.xvalues
@property
- def y_data(self):
- return np.array(self.buffer[:,1])
+ def ydata(self):
+ return np.array(self.yvalues)
def refresh_series(self, tag):
- dpg.set_value(tag, [self.x_data, self.y_data])
- pass
+ new_values = self.read(1)
+
+ if new_values:
+ self.yvalues.extendleft(new_values)
+ dpg.set_value(tag, [self.xdata, self.ydata])
diff --git a/tests/sockets/Socket_test.grc b/tests/sockets/Socket_test.grc
index 41c7f0a..fbc3cdf 100644
--- a/tests/sockets/Socket_test.grc
+++ b/tests/sockets/Socket_test.grc
@@ -8,7 +8,7 @@ options:
description: ''
gen_cmake: 'On'
gen_linking: dynamic
- generate_options: qt_gui
+ generate_options: no_gui
hier_block_src_path: '.:'
id: Test_Bit_Errorrate
max_nouts: '0'
@@ -18,7 +18,7 @@ options:
realtime_scheduling: ''
run: 'True'
run_command: '{python} -u {filename}'
- run_options: prompt
+ run_options: run
sizing_mode: fixed
thread_safe_setters: ''
title: 'Bit Error Rate test '
@@ -41,7 +41,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [184, 12]
+ coordinate: [216, 20.0]
rotation: 0
state: enabled
- name: analog_noise_source_x_0
@@ -60,9 +60,9 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [528, 108.0]
+ coordinate: [32, 148.0]
rotation: 0
- state: disabled
+ state: enabled
- name: blocks_null_source_0
id: blocks_null_source
parameters:
@@ -73,15 +73,15 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
num_outputs: '1'
- type: byte
+ type: complex
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [552, 224.0]
+ coordinate: [64, 264.0]
rotation: 0
- state: true
+ state: disabled
- name: blocks_throttle_1
id: blocks_throttle
parameters:
@@ -92,13 +92,13 @@ blocks:
maxoutbuf: '0'
minoutbuf: '0'
samples_per_second: samp_rate
- type: byte
+ type: float
vlen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [800, 156.0]
+ coordinate: [280, 164.0]
rotation: 0
state: true
- name: fadingui_netsink_0
@@ -108,13 +108,13 @@ blocks:
affinity: ''
alias: ''
comment: ''
- type: byte
+ type: float
veclen: '1'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [1016, 156.0]
+ coordinate: [504, 164.0]
rotation: 0
state: true
- name: import_0
diff --git a/tests/sockets/Test_Bit_Errorrate.py b/tests/sockets/Test_Bit_Errorrate.py
index b545104..6a989df 100755
--- a/tests/sockets/Test_Bit_Errorrate.py
+++ b/tests/sockets/Test_Bit_Errorrate.py
@@ -9,64 +9,23 @@
# Author: Sara Halter
# GNU Radio version: 3.8.2.0
-from distutils.version import StrictVersion
-
-if __name__ == '__main__':
- import ctypes
- import sys
- if sys.platform.startswith('linux'):
- try:
- x11 = ctypes.cdll.LoadLibrary('libX11.so')
- x11.XInitThreads()
- except:
- print("Warning: failed to XInitThreads()")
-
+from gnuradio import analog
from gnuradio import blocks
from gnuradio import gr
from gnuradio.filter import firdes
import sys
import signal
-from PyQt5 import Qt
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
import fadingui
import numpy as np
-from gnuradio import qtgui
-class Test_Bit_Errorrate(gr.top_block, Qt.QWidget):
+class Test_Bit_Errorrate(gr.top_block):
def __init__(self):
gr.top_block.__init__(self, "Bit Error Rate test ")
- Qt.QWidget.__init__(self)
- self.setWindowTitle("Bit Error Rate test ")
- qtgui.util.check_set_qss()
- try:
- self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
- except:
- pass
- self.top_scroll_layout = Qt.QVBoxLayout()
- self.setLayout(self.top_scroll_layout)
- self.top_scroll = Qt.QScrollArea()
- self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
- self.top_scroll_layout.addWidget(self.top_scroll)
- self.top_scroll.setWidgetResizable(True)
- self.top_widget = Qt.QWidget()
- self.top_scroll.setWidget(self.top_widget)
- self.top_layout = Qt.QVBoxLayout(self.top_widget)
- self.top_grid_layout = Qt.QGridLayout()
- self.top_layout.addLayout(self.top_grid_layout)
-
- self.settings = Qt.QSettings("GNU Radio", "Test_Bit_Errorrate")
-
- try:
- if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
- self.restoreGeometry(self.settings.value("geometry").toByteArray())
- else:
- self.restoreGeometry(self.settings.value("geometry"))
- except:
- pass
##################################################
# Variables
@@ -76,24 +35,19 @@ class Test_Bit_Errorrate(gr.top_block, Qt.QWidget):
##################################################
# Blocks
##################################################
- self.fadingui_netsink_0 = fadingui.netsink(address='udp://localhost:31415', dtype="byte", vlen=1)
- self.blocks_throttle_1 = blocks.throttle(gr.sizeof_char*1, samp_rate,True)
- self.blocks_null_source_0 = blocks.null_source(gr.sizeof_char*1)
+ self.fadingui_netsink_0 = fadingui.netsink(address='udp://localhost:31415', dtype="float", vlen=1)
+ self.blocks_throttle_1 = blocks.throttle(gr.sizeof_float*1, samp_rate,True)
+ self.analog_noise_source_x_0 = analog.noise_source_f(analog.GR_GAUSSIAN, 1, 0)
##################################################
# Connections
##################################################
- self.connect((self.blocks_null_source_0, 0), (self.blocks_throttle_1, 0))
+ self.connect((self.analog_noise_source_x_0, 0), (self.blocks_throttle_1, 0))
self.connect((self.blocks_throttle_1, 0), (self.fadingui_netsink_0, 0))
- def closeEvent(self, event):
- self.settings = Qt.QSettings("GNU Radio", "Test_Bit_Errorrate")
- self.settings.setValue("geometry", self.saveGeometry())
- event.accept()
-
def get_samp_rate(self):
return self.samp_rate
@@ -106,34 +60,21 @@ class Test_Bit_Errorrate(gr.top_block, Qt.QWidget):
def main(top_block_cls=Test_Bit_Errorrate, options=None):
-
- if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
- style = gr.prefs().get_string('qtgui', 'style', 'raster')
- Qt.QApplication.setGraphicsSystem(style)
- qapp = Qt.QApplication(sys.argv)
-
tb = top_block_cls()
- tb.start()
-
- tb.show()
-
def sig_handler(sig=None, frame=None):
- Qt.QApplication.quit()
+ tb.stop()
+ tb.wait()
+
+ sys.exit(0)
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
- timer = Qt.QTimer()
- timer.start(500)
- timer.timeout.connect(lambda: None)
+ tb.start()
- def quitting():
- tb.stop()
- tb.wait()
+ tb.wait()
- qapp.aboutToQuit.connect(quitting)
- qapp.exec_()
if __name__ == '__main__':
main()