User Tools

Site Tools


aff3ct_dvbs2_benchmark_example

AFF3CT based DVB-S2 benchmark example

This tutorial runs a DVB-S2 transmission between two nodes in CorteXlab. It uses the DVB-S2 SDR Transciever developed as part of the AFF3CT project.

It is mostly used as a way to demonstrate that it is possible to run AFF3CT based projects in CorteXlab. But can also be a starting example to run more advanced experiments.

The docker image

A docker image containing all the pre-built components is available at ghcr.io/notou/dvbs2:0.1, from this repo

The rest of this section is intended for those curious about what is in this image. It is not necessary for the execution of the tutorial.


The image is build from the following Dockerfile.

FROM m1mbert/cxlb-gnuradio-3.10:1.2

SHELL [ "/bin/bash", "-lc"  ]
RUN git clone -b cxlb https://github.com/Notou/dvbs2.git
RUN cd dvbs2 && git submodule update --init --recursive --remote
RUN cd dvbs2 && mkdir build
RUN cd dvbs2/build && cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-Wall -funroll-loops -msse4.1" -DAFF3CT_LINK_HWLOC=OFF -DAFF3CT_OVERRIDE_VERSION=0.1.0 -DCMAKE_INSTALL_PREFIX=/cortexlab/toolchains/current ..
RUN cd dvbs2/build && make install -j$(nproc) && ldconfig

It thus derives from the m1mbert/cxlb-gnuradio-3.10:1.2 image that contains everything necessary to run code with the hardware of CorteXlab (especially the UHD Drivers for the USRPs). (It also contains GNU Radio 3.10, but we won't be making use of it here).

It then pulls code from a branch of a fork of the AFF3Ct DVB-S2 repo, compiles and installs it. This is done to apply a few modifications to allow proper execution on the platform:

  • Reduction of the number of threads to better fit the 4 cores CPUs available
  • Disable thread pinning (in code and with -DAFF3CTLINKHWLOC=OFF)
  • Set the instruction set to the one available to the CPUs of the platform: SSE4.1

The scenario

For the following, the task will refer to the instructions given by Airlock, the scenario file and minus. The experiment will refer to the DVB-S2 transmission.

Create on your machine a folder dvbs2_task and in it a file scenario.yaml which will indicate the nodes to use and how to use them. It should look like this :

# Example scenario description file
#
#   All lines starting with "#" and empty lines are ignored


# Scenario textual description
#   simple string (a one liner)
description: DVB-S2 with AFF3CT

# Experiment maximum duration
#   Time after which the experiment is forced to stop
#   integer (seconds)
duration: 1800

# Node list
#
#   format:
#
#   (machine):
#   entry (entry point script relative to the task root)
#   exit (exit point script relative to the task root. Use "none" for none)

nodes:

  node14:
    container:
    - image: ghcr.io/notou/dvbs2:0.1

  node16:
    container:
    - image: ghcr.io/notou/dvbs2:0.1

The file is self-explanatory, but for now let's ignore all but the indented lines following node14: and node16:. You'll have the opportunity to understand the rest better later on.

Let's go over each said line now:

  • node14:: This opens the node14 declaration of options
  • image:: This indicates which image to download and run on the node The same reasoning applies for node 16.

For more info on where these nodes are located inside the platform, please check the node position map at the home of this wiki.

Assuming your account has been correctly created, you can now copy the folder with the scenario file into the Airlock SSH front-end:

you@yourpc:~$ scp -P 2269 -v [-i path/to/your/key] [-r] path/to/local/folder/dvbs2_task username@gw.cortexlab.fr:/cortexlab/homes/[YOUR CORTEXLAB USERNAME]/workspace/

Non interactive scenario (No SSH)

The example of this tutorial demonstrates an ssh connection to the nodes. But know that you can also use the command option in a different way, by directly giving the parameters of your experience and not going through ssh. When developing an experiment (trials and errors, parameter tweaking, …), working interactively through ssh is more practical. But when the experiment is running well and you want to reproduce it several times, it is best to automatize, so that you don't need to ssh to each node and run commands manually. It's also possible, for example, that you adjust interactively a receiver first, and when it's done, you run it automatically, and you keep the interactive sessions only for adjusting and tuning the emitter node(s).

In this situation, you might want to directly call the program to run on the nodes via the command option, with a scenario file looking like the following.

# Example scenario description file
#
#   All lines starting with "#" and empty lines are ignored


# Scenario textual description
#   simple string (a one liner)
description: DVB-S2 with AFF3CT

# Experiment maximum duration
#   Time after which the experiment is forced to stop
#   integer (seconds)
duration: 120

# Node list
#
#   format:
#
#   (machine):
#   entry (entry point script relative to the task root)
#   exit (exit point script relative to the task root. Use "none" for none)

nodes:

  node14:
    container:
    - image: ghcr.io/notou/dvbs2:0.1
      command: bash -lc "/root/dvbs2/build/bin/dvbs2_rx --sim-stats --rad-threaded --rad-ip-addr 192.168.10.2 --rad-rx-subdev-spec "A:0" --rad-rx-rate 5e6 --rad-rx-freq 1100e6 --rad-rx-gain 20 -F 16 --src-type USER --src-path ../conf/src/K_14232.src --mod-cod QPSK-S_8/9 --dec-implem NMS --dec-ite 10 --dec-simd INTER"

  node16:
    container:
    - image: ghcr.io/notou/dvbs2:0.1
      command: bash -lc "sleep 5 && /root/dvbs2/build/bin/dvbs2_tx --sim-stats --rad-threaded --rad-ip-addr 192.168.10.2 --rad-tx-subdev-spec "A:0" --rad-tx-rate 5e6 --rad-tx-freq 1100e6 --rad-tx-gain 30 -F  8 --src-type USER --src-path ../conf/src/K_14232.src --mod-cod QPSK-S_8/9"

Note that, the rest of this tutorial uses the ssh method, not the one mentioned in the current section. Also note that the command must point to the file to be executed, either with a relative path, from the WORKDIR defined in your docker image (here it is /root), or with an absolute path.

Access Airlock

You can now access the Airlock SSH server that will allow you to manage your task.

you@yourpc:~$ ssh -X -v [-i path/to/the/key] username@gw.cortexlab.fr

Creating the task file

On airlock, before submitting the task to the nodes, we need first to put the task into a format that can be readily understood by Minus. Minus is the experiment controller code, responsible for doing the dirty stuff for you:

  • Firing up the right nodes to be used
  • Copying the code onto the nodes
  • Starting everything at the same instant
  • Waiting until everything finishes, and stop stubborn code from running forever
  • Copying results, error and output messages to airlock, so that you can access it
  • Turning off everything and cleaning up

Let's prepare the task, but first we need to go back to the folder containing the task:

you@srvairlock:~/ cd /cortexlab/homes/[YOUR CORTEXLAB USERNAME]/workspace/

And now, instruct Minus to create a task file:

you@srvairlock:~/workspace$ minus task create dvbs2_task
you@srvairlock:~/workspace$ ls
dvbs2_task  dvbs2_task.task

And now we have a new file called dvbs2_task.task which is ready to be submitted. Warning, do not leave a slash after the directory task name (i.e. dvbs2_task ) or the command will fail.

Submitting the task

Now we need to give the task to Minus, so that it can operate its magic.

First we need to reserve the CorteXlab room, and the nodes we want to use (in this case, 14 and 16). Please refer to the the “Submitting the task” section of Tutorial 1.

Back to the airlock terminal screen, we now can submit the minus task:

you@srvairlock:~/workspace$ minus task submit my_task.task
21743<login>.

You'll see that Minus gives you a task number (21743 in this example). You'll want to write down the number of the task as it will be important for checking its status or to abort it, if necessary.

Run the experiment

Now the node we want to use are up and running with the docker image we set up earlier. We can access them with ssh to run our experiment. To do so, open a new terminal per node you want to use, here two, access Airlock and run the following command, here for node 14 :

you@srvairlock:~/workspace$ ssh -p 2222 root@mnode14

You are now connected to the node with the docker environment you set up earlier. You can then start running commands.

First, let's chack that the DVB-S2 chain is properly compiled by running a simulated transmission on one node:

# From node 14 
root@mnode14:~/ /root/dvbs2/build/bin/dvbs2_tx_rx -m 3.4 -M 3.81 -s 0.1 --chn-max-freq-shift 0 --chn-max-delay 4.0

This is one of the reference parameters from the original repository. You should see in the console something similar to this:

root@mnode14:~/ /root/dvbs2/build/bin/dvbs2_tx_rx -m 3.4 -M 3.81 -s 0.1 --chn-max-freq-shift 0 --chn-max-delay 4.0
[trace]
# * DVB-S2 ----------------------------------------
#    ** Modulation and coding   = QPSK-S_8/9
#    ** Min  Eb/N0              = 3.400000
#    ** Max  Eb/N0              = 3.810000
#    ** Step Eb/N0              = 0.100000
#    ** Max frame errors        = 100
#    ** Type of channel         = AWGN
#    ** Maximum Channel Delay   = 4.000000
#    ** LDPC implem             = SPA
#    ** LDPC n iterations       = 50
#    ** LDPC simd               =
#    ** Path to sink file       = sink.out
#    ** Type of source          = RAND
#    ** Path to source file     = ../conf/src/K_14232.src
#    ** Perfect synchronization = NO
#    ** Estimator type          = DVBS2
# * Shaping_filter --------------------------------
#    ** N. complex samples      = 16740
#    ** N. complex symbols      = 8370
#    ** Oversampling Factor     = 2
#    ** Rolloff Factor          = 0.200000
#    ** Group Delay             = 20
# * Synchronizer_freq_coarse ----------------------
#    ** N. samples              = 16740
#    ** Type                    = NORMAL
#    ** Damping Factor          = 0.707107
#    ** Normalized Bandwidth    = 0.000100
# * Synchronizer_timing ---------------------------
#    ** N. complex samples      = 16740
#    ** Type                    = FAST
#    ** Damping Factor          = 0.707107
#    ** Normalized Bandwidth    = 0.000050
# * Synchronizer_frame ----------------------------
#    ** N. complex samples      = 8370
#    ** Type                    = FAST
#    ** Alpha                   = 0.900000
#    ** Trigger                 = 30.000000
# * Synchronizer_freq_fine ------------------------
#    ** N. samples              = 8370
#    ** Type                    = NORMAL
#    ** L&R Alpha               = 0.999000
Cloning the modules of the parallel sequence... Done (11.4372s).
# --------------------------------||------------------------------------------------------||---------------------
#        Signal Noise Ratio       ||   Bit Error Rate (BER) and Frame Error Rate (FER)    ||  Global throughput  
#              (SNR)              ||                                                      ||  and elapsed time   
# --------------------------------||------------------------------------------------------||---------------------
# ----------|----------|----------||----------|----------|----------|----------|----------||----------|----------
#     Sigma |    Es/N0 |    Eb/N0 ||      FRA |       BE |       FE |      BER |      FER ||  SIM_THR |    ET/RT 
#           |     (dB) |     (dB) ||          |          |          |          |          ||   (Mb/s) | (hhmmss) 
# ----------|----------|----------||----------|----------|----------|----------|----------||----------|----------
     0.3607 |     5.85 |     3.40 ||      100 |    19585 |      100 | 1.38e-02 | 1.00e+00 ||    0.160 | 00h00'08
     0.3565 |     5.95 |     3.50 ||      122 |    16489 |      100 | 9.50e-03 | 8.20e-01 ||    0.291 | 00h00'05
     0.3524 |     6.05 |     3.60 ||      196 |    13485 |      100 | 4.83e-03 | 5.10e-01 ||    0.390 | 00h00'07
     0.3484 |     6.15 |     3.70 ||      535 |    12390 |      100 | 1.63e-03 | 1.87e-01 ||    0.719 | 00h00'10
     0.3444 |     6.25 |     3.80 ||     4395 |    11015 |      100 | 1.76e-04 | 2.28e-02 ||    1.492 | 00h00'41

Now, let's run an actual over-the-air transmission by running these commands on each node:

# From node 14
root@mnode14:~/ /root/dvbs2/build/bin/dvbs2_rx --sim-stats --rad-threaded --rad-ip-addr 192.168.10.2 --rad-rx-subdev-spec "A:0" --rad-rx-rate 5e6 --rad-rx-freq 1100e6 --rad-rx-gain 20 -F 16 --src-type USER --src-path ../conf/src/K_14232.src --mod-cod QPSK-S_8/9 --dec-implem NMS --dec-ite 10 --dec-simd INTER
	
# From node 16
root@mnode16:~/ /root/dvbs2/build/bin/dvbs2_tx --sim-stats --rad-threaded --rad-ip-addr 192.168.10.2 --rad-tx-subdev-spec "A:0" --rad-tx-rate 5e6 --rad-tx-freq 1100e6 --rad-tx-gain 30 -F  8 --src-type USER --src-path ../conf/src/K_14232.src --mod-cod QPSK-S_8/9

To ensure reliable transmission, it is best to run the dvbs2_rx command (node 14 here) first, then the tx.

These commands are based on the examples from the official readme, modified to point to the exact IP addresses of the USRP, and to reduce the operating sample rate to 5Msps.

You should again see a dump of the transmission parameters, and on the reciever (node 14 here), something similar to:

...
# * Radio -----------------------------------------
#    ** N. samples              = 16740
#    ** Type                    = USRP
#    ** Threaded                = YES
#    ** Fifo size               = 10000000000
#    ** Clk rate                = 125000000.000000
#    ** Rx rate                 = 5000000.000000
#    ** Rx subdev               = A:0
#    ** Rx antenna              = RX2
#    ** Rx freq                 = 1100000000.000000
#    ** Rx gain                 = 20.000000
#    ** Rx File                 =
#    ** Tx File                 =
#    ** Tx subdev               = A:0
#    ** Tx antenna              = TX/RX
#    ** Tx rate                 = 0.000000
#    ** Tx freq                 = 1090000000.000000
#    ** Tx gain                 = 10.000000
[INFO] [UHD] linux; GNU C++ version 10.2.1 20210110; Boost_107400; UHD_4.3.0.0-6-g5aa6bc44
[INFO] [USRP2] Opening a USRP2/N-Series device...
[INFO] [USRP2] Current recv frame size: 1472 bytes
[INFO] [USRP2] Current send frame size: 1472 bytes
[WARNING] [UDP] The send buffer could not be resized sufficiently.
Target sock buff size: 2500000 bytes.
Actual sock buff size: 1048576 bytes.
See the transport application notes on buffer resizing.
Please run: sudo sysctl -w net.core.wmem_max=2500000
[WARNING] [UDP] The send buffer could not be resized sufficiently.
Target sock buff size: 2500000 bytes.
Actual sock buff size: 1048576 bytes.
See the transport application notes on buffer resizing.
Please run: sudo sysctl -w net.core.wmem_max=2500000
[WARNING] [UDP] The send buffer could not be resized sufficiently.
Target sock buff size: 2500000 bytes.
Actual sock buff size: 1048576 bytes.
See the transport application notes on buffer resizing.
Please run: sudo sysctl -w net.core.wmem_max=2500000
Cloning the modules of the parallel sequence... Done (1.47306s).
Waiting phase... Done (3.0949s).
Learning phase... Done (1.74851s).
# ---------------------||------------------------------------------------------||---------------------
#  Signal Noise Ratio  ||   Bit Error Rate (BER) and Frame Error Rate (FER)    ||  Global throughput  
#         (SNR)        ||                                                      ||  and elapsed time   
# ---------------------||------------------------------------------------------||---------------------
# ----------|----------||----------|----------|----------|----------|----------||----------|----------
#     Es/N0 |    Eb/N0 ||      FRA |       BE |       FE |      BER |      FER ||  SIM_THR |    ET/RT 
#      (dB) |     (dB) ||          |          |          |          |          ||   (Mb/s) | (hhmmss) 
# ----------|----------||----------|----------|----------|----------|----------||----------|----------
      14.62 |    12.17 ||     7744 |    32254 |       12 | 2.93e-04 | 1.55e-03 ||    4.231 | 00h00'26

Notice that after a while (about 25-30s), the transmitter starts printing “UUUUUUUU”, and eventually finishes. At the same time, the estimated SNR values at the reciever drop down to about 0, and the error rates increase. That is simply because the transmitter has finished sending its file, so there is nothing but noise to receive.

Note that the receiver needs to be shutdown with Ctrl-C, and may hang at shutdown with an error message like:

terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument

In that case, either wait for it to terminate on its own (may take a few minutes), or kill it directly.

Exercises

Feel free to experiment with these commands.

For instance, try to increase (or decrease) the sample rate (--rad-tx-rate 5e6) to see what is feasible by the platform. Note that only integer divisers of the USRP master clock rate (100Msps for the USRP 2032 and 200Msps for the 2944) are possible. Read the console output for errors or warnings.

Try to communicate between other pairs of nodes, at various distances, and with different USRP types (2932 or 2944). You may need to make a specific reservation to activate the desired nodes, and change the scenario file accordingly.

Play with the command parameters, according to the info available in the original repo, and the help command (/root/dvbs2/build/bin/dvbs2_rx -h)

aff3ct_dvbs2_benchmark_example.txt · Last modified: 2023/11/30 18:25 by cmorin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki