Python Files Generated by GRC
April 25, 2024About 3 min
A Simple GNU Radio System Architecture
Python Files Generated by GRC
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: Not titled yet
# Author: jyw
# GNU Radio version: 3.10.1.1
from packaging.version import Version as 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 PyQt5 import Qt
from gnuradio import qtgui
from gnuradio.filter import firdes
import sip
from gnuradio import analog
from gnuradio import blocks
from gnuradio import gr
from gnuradio.fft import window
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
from gnuradio import qtgui
class basic(gr.top_block, Qt.QWidget):
def __init__(self):
gr.top_block.__init__(self, "Not titled yet", catch_exceptions=True)
Qt.QWidget.__init__(self)
self.setWindowTitle("Not titled yet")
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", "basic")
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
##################################################
self.samp_rate = samp_rate = 32000
##################################################
# Blocks
##################################################
self.qtgui_freq_sink_x_0 = qtgui.freq_sink_c(
1024, #size
window.WIN_BLACKMAN_hARRIS, #wintype
0, #fc
samp_rate, #bw
"", #name
1,
None # parent
)
self.qtgui_freq_sink_x_0.set_update_time(0.10)
self.qtgui_freq_sink_x_0.set_y_axis(-140, 10)
self.qtgui_freq_sink_x_0.set_y_label('Relative Gain', 'dB')
self.qtgui_freq_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, 0.0, 0, "")
self.qtgui_freq_sink_x_0.enable_autoscale(False)
self.qtgui_freq_sink_x_0.enable_grid(False)
self.qtgui_freq_sink_x_0.set_fft_average(1.0)
self.qtgui_freq_sink_x_0.enable_axis_labels(True)
self.qtgui_freq_sink_x_0.enable_control_panel(False)
self.qtgui_freq_sink_x_0.set_fft_window_normalized(False)
labels = ['', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ["blue", "red", "green", "black", "cyan",
"magenta", "yellow", "dark red", "dark green", "dark blue"]
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
for i in range(1):
if len(labels[i]) == 0:
self.qtgui_freq_sink_x_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_freq_sink_x_0.set_line_label(i, labels[i])
self.qtgui_freq_sink_x_0.set_line_width(i, widths[i])
self.qtgui_freq_sink_x_0.set_line_color(i, colors[i])
self.qtgui_freq_sink_x_0.set_line_alpha(i, alphas[i])
self._qtgui_freq_sink_x_0_win = sip.wrapinstance(self.qtgui_freq_sink_x_0.qwidget(), Qt.QWidget)
self.top_layout.addWidget(self._qtgui_freq_sink_x_0_win)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
self.analog_sig_source_x_0 = analog.sig_source_c(samp_rate, analog.GR_COS_WAVE, 1000, 1, 0, 0)
##################################################
# Connections
##################################################
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.blocks_throttle_0, 0), (self.qtgui_freq_sink_x_0, 0))
def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "basic")
self.settings.setValue("geometry", self.saveGeometry())
self.stop()
self.wait()
event.accept()
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate)
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
self.qtgui_freq_sink_x_0.set_frequency_range(0, self.samp_rate)
def main(top_block_cls=basic, 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):
tb.stop()
tb.wait()
Qt.QApplication.quit()
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
timer = Qt.QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)
qapp.exec_()
if __name__ == '__main__':
main()
Program Architecture
The above program is a Python program constructed using GNU Radio and PyQt5. It is mainly used to create a simple system that can generate a sine wave signal and analyze its frequency. The table below outlines the main blocks of the program and their descriptions:
Block | Description |
---|---|
Import Dependencies | Import necessary packages such as PyQt5 for GUI and gnuradio for signal processing |
Environment Setup | Check and set up the runtime environment, check if loading X11 library is required; set the system signal handling method |
Class Definition | Define the basic class, which is the main class of the system integrating GUI interface and signal processing flow |
Signal Processing Modules | Include signal source, throttle block, and frequency display |
Signal Connections | Connect the signal source to the throttle block, then output to the frequency display to show the signal frequency distribution |
GUI Configuration | Set window attributes, layout, and parameters of signal processing modules |
Main Function | Initialize an instance of the basic class, start signal processing and GUI interface |
Execution | Entry point of the program to ensure the program runs in the main mode |
Detailed Explanation
Import Dependencies: The program starts by importing multiple packages, such as
PyQt5
for GUI andgnuradio
modules for signal processing.Environment Setup:
- Check if the platform is Linux, and if so, invoke the
libX11.so
library to ensure the X11 graphical interface can run correctly. - Set up the system signal handling to close the program when interrupt or termination signals are received.
- Check if the platform is Linux, and if so, invoke the
Class Definition:
- Define a class named
basic
, inheriting fromgr.top_block
andQt.QWidget
. This class is used to set up the application's GUI interface and signal processing flow. - In the class's initialization method, set window attributes, layout, and signal processing modules including signal source
analog_sig_source_x_0
, throttle blockblocks_throttle_0
, and frequency displayqtgui_freq_sink_x_0
.
- Define a class named
Signal Processing Modules:
analog_sig_source_x_0
: Generates a cosine wave signal with a fixed frequency.blocks_throttle_0
: Controls the rate of signal flow to prevent excessive CPU resource consumption.qtgui_freq_sink_x_0
: Displays the frequency distribution of the signal.
Signal Connections:
- Connect the signal source to the throttle block, then output to the frequency display to show the signal's frequency distribution.
GUI Configuration:
- Set parameters of the signal source, such as sampling rate and frequency.
- Manage the layout of the application window and user interface settings.
Main Function:
- Check the Qt version, set the graphics system.
- Create an instance of the
basic
class, set up system signal processing, and display the application. - Handle system signals and timer events to properly close and start the program.
Execution:
- The bottom part of the program serves as the entry point to ensure the program runs the
main
function.
- The bottom part of the program serves as the entry point to ensure the program runs the
Exercise 1
Try running the generated Python program file in the GNU Radio Python environment, and you should obtain the same results as in GRC.