Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a custom QT GUI sink in Gnuradio

I am working on an SDR project in GNURadio. My project requires a special kind of plot, that I can't get with the inbuild QT GUI Sinks. However, after much searching, I can't find any API documentation or Tutorial that explains how I can make my own QT Gui Widgets (preferably in Python), so that gnuradio displays them like the inbuild blocks.

I so far have implemented a class, that works as a standalone QT application, i.e, with:

 import pmt
 import time
 import pyqtgraph as pg
 from gnuradio import gr
 from collections import namedtuple
 from PyQt5 import QtWidgets, QtCore


class event_plot(gr.sync_block):

 def __init__(self, gui_hint: str):
        gr.sync_block.__init__(self,
                               name="event_plot",
                               in_sig=None,
                               out_sig=None)
        self._create_gui_widget()

    def _create_gui_widget(self):
        """ Generate the Widget for the GUI and update timer.
        """
        # GUI setup
        self.widget = pg.PlotWidget(title="Tracer Detections")
        self.widget.setLabel('bottom', 'Time', 's')
        self.plot_item = self.widget.getPlotItem()
        self.stem_items = []

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self._update_plot)
        self.timer.start(1000)  # Update every 200ms

    ...

    def _update_plot(self):
       ...

    def get_widget(self):
        return self.widget

    def work(self, input_items, output_items):
        return len(output_items[0])


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    plot = event_plot("").get_widget()
    plot.show()
    app.exec_()

I assume I must make some setting in the block's yaml file, so that gnuradio knows that it is a GUI block, and how to receive the Widget. Is there some documentation explaining this?

like image 218
PeterO Avatar asked Oct 16 '25 16:10

PeterO


1 Answers

You'll need to learn how to write a GNU Radio block first, then you'll need to understand how to get data across the GNU Radio block thread / Qt GUI thread boundary, and then you can write your visualization.

The first part is, I'd argue, the easiest: https://tutorials.gnuradio.org is should explain that. You seem to have already generated a stub for such a block, so that's a good sign, but the io signature is wrong, so you will need to be sure to fully understand what you want that block to do: actually have a sample stream input.

Then comes the harder part of heaving data from the GNU Radio side to the Qt side. That's a bit dangerous, because both sides are running their own, independent, execution threads, so it's hard to coordinate who gets to access which samples without the other party still reading it, or equally bad, while the other side is still writing it.

Luckily, we already have GNU Radio Qt visualizations. I'd recommend that after you've worked through the official GNU Radio tutorial (not before, because our qt-gui code is not exactly easy to understand and will be very frustrating to you), you look at e.g. the Qt GUI Time Sink's source code (see the time_sink_f_impl.cc linked there).

  • See how they use the qAppplication's postEvent method to throw copied data "over the fence"
  • See how the visualization widget itself is a separate class from the block

You will have to make a judgement call on whether the stream-driven minimum update time approach is right for you. This is a hard call to make – I'd even argue GNU Radio's approach here isn't the right one for most cases. If you decide that instead of triggering a visual update if new data is available AND the minimum update time has elapsed, you want a timer to regularly update your visual display, you will need some FIFO logic inside your visualization that deals with the situation when between update times, no new data has arrived.

This all is, in theory, possible in Python, but I've yet to see being it done very successfully. Python adds yet another layer of separate threading and blocking issues atop of it. There used to be approaches to work around that (once upon a time, pyqtgraph-based visualizations existed in the wild), but the hard part is really coming up with a strategy on

  1. when (under which conditions?) the visualization needs to be updated and
  2. how to get the data out of GNU Radio into Qt's framework, without data races and use-after-frees.
like image 158
Marcus Müller Avatar answered Oct 18 '25 17:10

Marcus Müller