You are on page 1of 8

Generating Out-of-tree module in GNU Radio using

Python
Abhishek Bhatta

June 19, 2017

1 Aim
Introduction to generating an out-of-tree module in GNU Radio and linking it with gnuradio−
companion.

2 Out-Of-Tree Module
GNU Radio is a framework built to enable design, simulation and implementation of real
world radio systems. It contains a modular “flowgraph” oriented system that contains built
in libraries which can be combined to operate as complex system and implement various
signal processing applications. It even allows the users to define their own processing
modules that can be incorporated with the pre-built libraries to perform the user defined
processing. These user defined modules are known as “Out-Of-Tree (OOT)” modules within
the GNU Radio framework. The OOT’s can be built using two different languages c++ and
python.
In this practical you will learn how to built these OOT modules using python.

3 GNU Radio with Python

3.1 Investigating the help command

In this section an introduction to generating GNU Radio blocks with specific functionality
is provided. A very useful tool available for the purpose is gr modtool. Type the command
after the $ symbol in the terminal
$ gr_modtool help
Usage:
gr_modtool <command> [options] -- Run <command> with the given options.
gr_modtool help -- Show a list of commands.
gr_modtool help <command> -- Shows the help for a given command.

1
List of possible commands:

Name Aliases Description


=====================================================================
disable dis Disable block (comments out CMake entries for files)
info getinfo,inf Return information about a given module
remove rm,del Remove block (delete files and remove Makefile entries)
makexml mx Make XML file for GRC block bindings
add insert Add block to the out-of-tree module.
newmod nm,create Create a new out-of-tree module
rename insert Add block to the out-of-tree module.

Immediately the command prints out the commands available to gr modtool. The next
step is to check for more options under the command. Type the following in terminal:
$ gr_modtool help newmod
Usage: gr_modtool nm [options].
Call gr_modtool without any options to run it interactively.

Options:
General options:
-h, --help Displays this help message.
-d DIRECTORY, --directory=DIRECTORY
Base directory of the module. Defaults to the cwd.
-n MODULE_NAME, --module-name=MODULE_NAME
Use this to override the current module’s name (is
normally autodetected).
-N BLOCK_NAME, --block-name=BLOCK_NAME
Name of the block, where applicable.
--skip-lib Don’t do anything in the lib/ subdirectory.
--skip-swig Don’t do anything in the swig/ subdirectory.
--skip-python Don’t do anything in the python/ subdirectory.
--skip-grc Don’t do anything in the grc/ subdirectory.
--scm-mode=SCM_MODE
Use source control management (yes, no or auto).
-y, --yes Answer all questions with ’yes’. This can overwrite
and delete your files, so be careful.

New out-of-tree module options:


--srcdir=SRCDIR Source directory for the module template.

This command gives more details about the options available for the command newmod.
Now that the help feature is investigated it would be easier to move forward. At any point
if there is a doubt type the help command and get the information.

2
3.2 Setting up a new block

Typing the following command in the terminal will generate a new block with the desired
name; in this case tutorial is used.
$ gr_modtool newmod tutorial

The above command will generate a new folder called gr-tutorial in the current directory.
Type the following commands in to navigate into the folder and list the files in it as shown.
$ cd gr-tutorial/
gr-tutorial$ ls
apps CMakeLists.txt examples include MANIFEST.md swig
cmake docs grc lib python

Since in this part of the tutorial python is being used then the only folders of interest
are python and grc. It is time to add a new block into the folder, there are different types of
blocks available but for this tutorial the synchronous 1:1 input to output block will be used
to make explaining things easier. Other details can be found in the GNU Radio website in
Section 4.
gr-tutorial$ gr_modtool add -t sync -l python
GNU Radio module name identified: tutorial
Language: Python
Enter name of block/code (without module name prefix): multiply_py_ff
Block/code identifier: multiply_py_ff
Enter valid argument list, including default arguments: multiple
Add Python QA code? [Y/n] y
Adding file ’python/multiply_py_ff.py’...
Adding file ’python/qa_multiply_py_ff.py’...
Editing python/CMakeLists.txt...
Adding file ’grc/tutorial_multiply_py_ff.xml’...
Editing grc/CMakeLists.txt...

Follow the instructions in the above command set, insert the names as mentioned and
generate the block. The ff at the end of the file name is to create a naming convention here
are the suffixes and their meanings.

Suffix Meaning
ff float in, float out
cc complex in, complex out
f sink with no output or source with no input that uses float

Table 1: Parameters used to simulate CRLB.

Now navigate into the python folder and open the newly generated file using the
following commands (use your favorite editor, here gedit is used).

3
gr-tutorial$ cd python
gr-tutorial/python$ gedit multiply_py_ff.py

The above command opens the python file and the contents are as follows:
import numpy
from gnuradio import gr

class multiply_py_ff(gr.sync_block):
"""
docstring for block multiply_py_ff
"""
def __init__(self, multiple):
gr.sync_block.__init__(self,
name="multiply_py_ff",
in_sig=[<+numpy.float+>],
out_sig=[<+numpy.float+>])

def work(self, input_items, output_items):


in0 = input_items[0]
out = output_items[0]
# <+signal processing here+>
out[:] = in0
return len(output_items[0])

With elementary background in python it should be clear that the import numpy and
from gnuradio import gr commands in the above code is used to initialize the required
libraries. The command def __init__(self, multiple): initializes the constructor of python
with a input variable named “multiple”. The second “def” command defines a function that
performs a certain task and can be called at a later stage. There are a few places in the code
that contains “<...>”, these are placeholders created by “gr_modtool” and these are the
locations where modifications needs to be made.
Now it is time to make some modifications to the code.

• gr.sync_block.init takes 4 inputs: self, name and size/type of the input and output.
To make the inputs 32 bit float replace:

– in_sig=[<+numpy.float+>] by in_sig=[numpy.float32]
– out_sig=[<+numpy.float+>] by out_sig=[numpy.float32]

• def work(self, input_items, output_items) function contains the next placeholder


and since here all the actual processing happens. Making some changes to this
function by multiplying the input with the variable multiple, replace:

– out[:] = in0 by out[:] = in0*self.multiple

4
Now save the file and it is time to move to the next step.

3.3 QA Tests

Now since the above code is modified it needs to be tested in order to make sure it will run
correctly when it is installed in GNU Radio. This is a very important step and should not be
skipped at any time, otherwise it may corrupt the entire installation of GNU Radio. Open
the file named “qa multiply py ff.py” by typing the following commands:
gr-tutorial/python$ gedit multiply_py_ff.py

That should open up the file with the following contents:


from gnuradio import gr, gr_unittest
from gnuradio import blocks
from multiply_py_ff import multiply_py_ff

class qa_multiply_py_ff (gr_unittest.TestCase):

def setUp (self):


self.tb = gr.top_block ()

def tearDown (self):


self.tb = None

def test_001_t (self):


# set up fg
self.tb.run ()
# check data

if __name__ == ’__main__’:
gr_unittest.run(qa_multiply_py_ff, "qa_multiply_py_ff.xml")

“gr unittest” aids in checking the approximate equality of tuples of float and complex
numbers. The next thing to worry about is the “def test 001 t” function. The task at hand
is to input data so create a data in the form of a vector to check multiple values at once as:
src\_data = (0, 1, -2, 5.5, -0.5)

An expected output also needs to be added so that the actual output can be compared
to it as:
expected\_result = (0, 2, -4, 11, -1)

Now create the source (src), sink (snk) and mult (mult) blocks and connect them to
each other as:

5
src = blocks.vector_source_f (src_data)
mult = multiply_py_ff (2)
snk = blocks.vector_sink_f ()
self.tb.connect (src, mult)
self.tb.connect (mult, snk)

Next step is to run the graph and store the data from sink as:
self.tb.run ()
result_data = snk.data ()

Lastly add a comparison function to check if the output is equal to the expected output
upto 6 decimal places as:
self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)

Finally the “test 001 t” function should look like:


src_data = (0, 1, -2, 5.5, -0.5)
expected_result = (0, 2, -4, 11, -1)
src = blocks.vector_source_f (src_data)
mult = multiply_py_ff (2)
snk = blocks.vector_sink_f ()
self.tb.connect (src, mult)
self.tb.connect (mult, snk)
self.tb.run ()
result_data = snk.data ()
self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6)

Next step is to run the test and check if the code is working correctly. Go to the python
directory in the terminal and enter:
gr-tutorial/python$ python qa_multiply_py_ff.py

Observe the output of the test, change one of the input numbers and see if the output
changes to make sure it is actually working properly.

3.4 XML Files

By now the python files and the QA test files are already prepared. The next thing to do is
to edit the XML file in the grc folder so that a graphical block corresponding to the designed
block is created to be used in gnuradio-companion.
The next step is to get out of the python folder and get into the grc folder (use the
“cd” command available to do so). Open the “tutorial multiply py ff.xml” file (by now
you should know how to do it, if not then refer to the commands above and figure it out
yourself). Make the changes in the XML file until it looks like:
<?xml version="1.0"?>
<block>

6
<name>multiply_py_ff</name>
<key>tutorial_multiply_py_ff</key>
<category>tutorial</category>
<import>import tutorial</import>
<make>tutorial.multiply_py_ff($multiple)</make>
<!-- Make one ’param’ node for every Parameter you
want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Multiple</name>
<key>multiple</key>
<type>float</type>
</param>

<!-- Make one ’sink’ node per input. Sub-nodes:


* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...-->
</type>
</sink>

<!-- Make one ’source’ node per output. Sub-nodes:


* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>out</name>
<type><!-- e.g. int, float, complex, byte, short, xxx_vector, ...-->
</type>
</source>
</block>

Now creating the blocks are complete. Next step is to install the newly created block in
gnuradio and use it in the graphical interface. Navigate to the build directory using the
terminal and run the following (one line at a time):
cmake ../
make
sudo make install
sudo ldconfig

7
Figure 1: Create this flow-graph to test the block you just created.

If everything goes smoothly you should be able to open gnuradio-companion and look
for the block under the tab “[tutorial]” with the name “multiply py ff”

3.5 Final Testing

Open “gnuradio-companion” and create the flow graph as shown in Figure 1. Check out the
website in Section 4, you can find more detailed explanations on this practical.

4 Useful Websites

Tutorial website : https://wiki.gnuradio.org/index.php/Guided_


Tutorial_GNU_Radio_in_Python

You might also like