Table of Contents
FIT/CorteXlab 103
In this tutorial we go one step deeper into the process of running an experiment on FIT/CorteXlab, this time starting from an empty GNU Radio project on your computer.
For practical purposes, we will use a readily available GNU Radio example instead of starting from a clean sheet, but this will introduce the same procedure you'll use when you want to run your own project on FIT/CorteXlab. We will also briefly introduce how to add custom C++ blocks to your project.
This time, the division of resources is slightly different and will be according to the table below:
Group | SSH login | Nodes to use | TCP Port |
---|---|---|---|
1 | tuto1 | node 3 | 6663 |
2 | tuto2 | node 4 | 6664 |
3 | tuto3 | node 7 | 6665 |
4 | tuto4 | node 8 | 6666 |
5 | tuto5 | node 6 | 6667 |
6 | tuto6 | node 23 | 6668 |
7 | tuto7 | node 27 | 6669 |
8 | tuto8 | node 24 | 6670 |
9 | tuto9 | node 28 | 6671 |
Henceforth you'll replace <number of group> by the number of your group read in the table above.
Setup
The purpose of this tutorial is to receive an ongoing OFDM transmission on a given USRP node. One transmitter node is set up for the whole group and each group will control a receiver node. Instead of starting from an empty project, we are going to use the GNU Radio examples for an OFDM transmitter and receiver. We are also going to change the channel estimation
block such that it produces frequency channel estimations that can be seen in the fft-web interface.
Start you virtual FIT/CorteXlab work environment
Let us start by firing up the virtual FIT/CorteXlab environment that you should've installed before, in the Prerequisites section.
Assuming you have correctly followed the steps described in that section, you can now fire up VirtualBox
Log into the virtual machine with username:cxlbusr
and with an empty password
Once the LXDE interface is fired up, open an LXTerminal
from the Start Menu > System tools
For now we'll be working only on the virtual FIT/CorteXlab environment.
Making a copy of the OFDM receiver
Copy the file rx_ofdm.grc
located in /home/cxlbusr/cortexlab/build/gnuradio.git/gr-digital/examples/ofdm/
to a new folder called tuto_ofdm
in a place of your choice, for example ˜/tasks/tuto_ofdm/
. This folder will be your local task folder.
As you can guess rx_ofdm.grc
is an OFDM receiver, but a standalone one capable to run in simulation mode under GNU Radio.
For the moment, the file tree should look like that:
... ├── tuto_ofdm │ └── rx_ofdm.grc ...
Preparing the RX python script
The .grc file we copied from the examples folder were made to work in simulation mode, i.e. without actual transmissions and through a simulated channel. You can see this by examining the reception chain with GNU Radio Companion (GRC).
Lets start by opening rx_ofdm.grc
with GRC.
cxlbusr@debian-jessie-cortexlab:~/tasks/tuto_ofdm$ gnuradio-companion rx_ofdm.grc
The flowgraph starts with blocks like Random Source
, OFDM Transmitter
and Channel Model
, as seen in the figure below. These blocks implement the whole transmitter chain as well as the simulated channel.
We will need to modify the flowgraph by replacing the transmitter and the simulated blocks by a UHD source block (UHD: USRP Source
) to stream the waveforms from the USRP through the receiver chain.
Using GNU Radio Companion we are going to open and edit the .grc file in order to use it with USRP nodes.
rx_ofdm.grc
We are now going to proceed to change the RX OFDM graph into something compatible with FIT/CorteXlab.
Initially we need to prepare the whole graph to make it run under FIT/CorteXlab. The main requirement is that the graph runs without graphical user interface (GUI) and that it stops automatically in the end without requiring user intervention. Bear in mind that the code will run on a remote host and that the user has no direct access to it. Do not forget to remove all GUI interface elements from the graph if any.
Open the Options block
(in the top left corner of the graph) and:
- Switch the
Generate Options
fromQT GUI
toNo GUI
- Change
Run Options
toRun to Completion
The next thing to do is to replace encoding and transmission parts and to put a USRP Source
block instead:
- Remove the
Random Source
,Stream to tagged stream
,OFDM Transmitter
Channel Model
andthrottle
blocks. TheThrottle
is not needed anymore since theUSRP Source
block will cadence our graph. - Place a
UHD: USRP Source
block and connect it to theSchimdl and Cox OFDM synch.
andDelay
blocks. - Place a
fft web
block and connect it to theUHD: USRP Source
block. This will be used to debug the signal into the RX chain. - Open the
tag debug
block and add the key filter “packet_num”. It is highly recommended to add a filter in theTag Debug
block in order to avoid printing a huge amount of useless data.
Next, we need to configure the USRP parameters. Open the UHD: USRP Source
block.
- In the
General
tab, verify that theSamp Rate
field containssamp_rate
, the variable that controls the sample rate throughout the graph (we will set it later), - In the
RF Options tab
, set theCh0: Center Freq (Hz)
to2.49e9
(2.49 GHz), - Set the
Ch0: Gain Type
toAbsolute (dB)
, - Set the
Ch0: Gain Value
to 20, - Set the antenna port
Ch0: Antenna
toTX/RX
(RX2
can't be used in FIT/CorteXlab at the moment) and - The
Ch0: Bandwidth (Hz)
parameter should remain at 0.
Then, we need to configure the fft web parameters. Open the fft web
block and change the following parameters:
- Set the
port
to the port value for your group, available in the above table, - Set the
sample rate
to the variablesamp_rate
,
Finally, in the Variable
block located in top of the flow graph, whose ID is samp_rate
, set the Value
field to 2000000
(2 MHz).
In the end your graph should look like this (The areas marked with a red square indicate the changed areas):
Generate the python files
The last thing we need to do within GRC is to generate the python file that will be used as the experiment executable. Press the generate flow graph
button and that's it! You now have the python filerx_ofdm.py
in the same folder as the .grc file.
Hint: the button is located in the toolbar, near the play button and looks like this →
Create the scenario
As we've seen before, the experiment description file is called scenario.yaml
and will be loaded by the experiment scheduler to figure out which nodes and what executable will be used during the experiment. It also gives the necessary startup scripts and parameters that the user provides for his experiment.
Example scenario
Here is a simple example of what our scenario.yaml
file should look like:
# Example scenario description file # # All lines starting with "#" and empty lines are ignored # Scenario textual description # simple string (a one liner) description: CorteXlab tutorial number 3 # Experiment maximum duration # Time after which the experiment is forced to stop # integer (seconds) duration: 120 # Node list # # format: # # nodes: # (machine): # command: (entry point script relative to the task root) nodes: node4: command: ./rx_ofdm.py
This file uses the yaml syntax and is self-documented.
Adapting the example scenario
We'll need to change the scenario file in order to reflect the nodes that your group is going to use. Please refer to the table at the top for the information you're going to use.
Use your preferred unix editor to edit the file and change node4
to the node that has been assigned to your group.
Launch the experiment in FIT/CorteXlab
Up to now we've been working on the virtual FIT/CorteXlab environment. If everything went well, we should have on your virtual machine a file tree that looks like this:
... ├── tuto_ofdm │ ├── rx_ofdm.py │ ├── scenario.yaml │ └── rx_ofdm.grc ...
The .grc files will not be used by CorteXlab but you can leave them in the same directory.
Upload the files on airlock
Upload the tuto_ofdm directory on Airlock. For example, on Linux, it will look like this:
cxlbusr@debian-jessie-cortexlab:~/tasks/tuto_ofdm$ cd .. cxlbusr@debian-jessie-cortexlab:~/tasks$ scp -r tuto_ofdm/ tuto<number of group>@airlock:~
Dont forget to replace <number of group> below by the number of your group!
Create the task
Connect to Airlock through ssh as described here. For example :
cxlbusr@debian-jessie-cortexlab:~/tasks$ ssh tuto<number of group>@airlock
You will find in your home directory the previously uploaded tuto_ofdm
directory.
Now, use the Minus CLI to create the task file:
tuto#@srvairlock:~$ minus task create tuto_ofdm
The success (or failure) of the creation will be printed on screen. The task file will be created at the same level and with the same name as the targeted experiment folder but with a .task
suffix, in our case tuto_ofdm.task
.
Note: You can get help on the Minus CLI at anytime with minus -h
Book the testbed with OAR
As explained here, we need to book the testbed with OAR in order to run our experiment. Once you have booked some nodes in the FIT/CorteXlab, you will be the exclusive user of those nodes; this will prevent any experimentation problems.
For the purposes of this tutorial, a shared reservation has been done in advance. This parent reservation's 'id' will be given to you by the tutorial instructors. We will need to create a child reservation inside of the parent one.
To reserve your nodes in the FIT/CorteXlab room, use this following command. Please replace mnode4
with the node number assigned to your group. Bear in mind that the preceding letter 'm' should be kept! Also, replace the <id of container>
by the number of the parent reservation.
tuto#@srvairlock:~/examples$ oarsub -t inner=<id of container> -l {"network_address in ('mnode4.cortexlab.fr')"}/nodes=1,walltime=1:00:00 -I
More documentation on oar can be found here. Among the reservation messages OAR outputs, the system will give you a reservation 'id'. Be sure to write your's down. It can be used for removing the job if necessary.
You can check if the job was properly created as well as monitor the current jobs in the gantt web interface.
Submit the task
Now, we have booked the testbed and we have a .task
file containing our experiment. In order to run it, we need to submit it to the testbed scheduler.
To submit a task to the scheduler, use the Minus CLI:
tuto#@srvairlock:~$ minus task submit tuto_ofdm.task
On screen will be prompted the id of your task in the scheduler. Note it down so that you can easily retrieve your results or monitor the progress of the experiment.
Observe the result
You can check the status of your experiment through the testbed scheduler. To do so, use the Minus CLI:
tuto#@srvairlock:~$ minus testbed status num total tasks: 2540 num tasks waiting: 0 num tasks running: 0 tasks currently running: (none)
The information given by this command enables you to deduce your experiment status. It's quite self-explanatory.
Are you having problems with your task? minus log
might help you debug your scenario and GNU Radio problems.
Checking the results
Once it's finished (we have set the duration to 2 minutes), Minus will take care of copying the results and output messages back to your home folder in srvairlock, so that you can analyze it.
For readability, all examples below consider task 15 with nodes node4 and node6. Please consider the values assigned to your group in the following.
All results are stored by task number in the results folder, inside your home folder.
Go in this folder :
tuto#@srvairlock:~/tuto_ofdm$ cd ~/results tuto#@srvairlock:~/results$ ls task_15 tuto#@srvairlock:~/results$ cd task_15 tuto#@srvairlock:~/results/task_15$ ls node4.tgz node6.tgz
So we see that we have a folder for each task and inside each folder one compressed file per participant node. Let's extract one of those files and see what's inside:
tuto#@srvairlock:~/results/task_15$ tar -zxf node4.tgz tuto#@srvairlock:~/results/task_15$ ls node4 node4.tgz node6.tgz tuto#@srvairlock:~/results/task_15$ cd node4 tuto#@srvairlock:~/results/task_15/node4$ ls rx_ofdm.grc scenario.yaml stdout.txt tx_ofdm.py rx_ofdm.py stderr.txt tx_ofdm.grc
We see that all of the files we used to create the task are inside. The other two are:
stdout.txt
: all output messages from your GNU Radio python script are written here. These include GNU Radio messages as well as all “print”s you include in your code. Seeing the contents of this file is useful to assert a correct operation.stderr.txt
: all error messages are printed here. If you see strange things on thestdout.txt
or nothing at all, it might be interesting to take a look at thestderr.txt
to debug your code.
Let's take a look inside stdout.txt
:
tuto#@srvairlock:~/results/task_15/node4$ less stdout.txt
You should get a long file that looks more or less like this:
linux; GNU C++ version 4.9.2; Boost_105500; UHD_003.010.git-33-g9401bdbd -- Opening a USRP2/N-Series device... -- Current recv frame size: 1472 bytes -- Current send frame size: 1472 bytes -- Detecting internal GPSDO.... Found an internal GPSDO -- Setting references to the internal GPSDO Using Volk machine: avx_64_mmx_orc Press Enter to quit: ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 0 Source: n/a Key: packet_num Value: 114 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 96 Source: n/a Key: packet_num Value: 115 Offset: 192 Source: n/a Key: packet_num Value: 116 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 288 Source: n/a Key: packet_num Value: 117 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 384 Source: n/a Key: packet_num Value: 118 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 480 Source: n/a Key: packet_num Value: 119 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 576 Source: n/a Key: packet_num Value: 120 ---------------------------------------------------------------------- ---------------------------------------------------------------------- Tag Debug: Rx Bytes Input Stream: 00 Offset: 672 Source: n/a Key: packet_num Value: 121 ----------------------------------------------------------------------
Eventually, the output file can start with some decoding error looking like this :
INFO: Detected an invalid packet at item 432 INFO: Parser returned #f