.: What is Done in This Example? :.

The follow figures illustrate the flow of the zero forcing example.

This example runs the following steps.

    1. tx2 creates a socket to wait for the trigger from rx1.
    2. rx1 first setups the USRP2 and connects to the socket at tx1 to trigger the transmission.
    3. tx2 synchronizes two USRP2s, and sets the transmitting timestamp to TIMESTAMP=256000000. Two antennas at tx2 reads samples from the files 'tx2-ofdm-freq-1.dat' and 'tx2-ofdm-freq-2.dat', respectively. After sending three access codes, tx2 waits for rx1 to compute the channel.
    4. rx1 estimates the channels, compute the precoding vector, and sends the precoding vector back to tx2 via backend Ethernet.
    5. Once tx2 gets the precoding vector, it sets the timestamp of the first sample of payload to (TIMESTAMP+GAP) to ensure that two USRP2s can again send the first sample at the same time. tx2 then precodes the frequency-domand samples of the payload based on the feedback channel estimation. To verify the performance of zero forcing, we let tx2 send 40 symbols with zero forcing, 40 null symbols (i.e., transmitting zeros), 40 symbols with zero forcing, 40 null symbols, and the rest symbols without zero forcing.
    6. rx1 dumps the results to files. Decoding is performed offline.

.: Run the Example :.

    1. In the receiver side $ cd gr-mimo/python
    2. In the transmitter side $ cd source
    3. In the receiver-side, link the python module 'mimo_usrp2_ofdm_receiver_zf.py' to 'mimo_usrp2_ofdm_receiver.py'. Make sure the file is linked correctly. $ ln -sf mimo_usrp2_ofdm_receiver_zf.py mimo_usrp2_ofdm_receiver.py
      $ ls -la mimo_usrp2_ofdm_receiver.py
      Re-build this folder if there are errors when you run the python code. $ make clean
      $ make
    4. Start the transmitter program first. You can change the central frequency and interpolation. $ sudo mimo_zf_tx2 -f 2.45G -i 64 -e eth1 -a eth2 -v
    5. Wait a bit until two transmitters print the message 'wait for trigger....'. Then, start the receiver program. You can change the central frequency, decimation, ip address, socket ports and the interface, but remember to keep "rx_ant_num" as 1. $ sudo ./mimo_usrp2_rx.py -f 2.45G -d 64 -e eth1 --rx_ant_num 1 --tx2_ip_addr xxx.xxx.xxx.xxx --tx2_sock_port 9999 -v
    6. In the receiver side, the program will keep running to capture the trace. Press 'Ctrl-C' to stop the program once you see the message '@ enter_finish_first_pkt'.
    7. In the receiver, offline decode the access codes and plot the raw signals. $ cp *.dat ../../matlab/
      $ cd ../../matlab/
      $ matlab &
      Run decode_miso() in matlab

TIP: In this example, after sending the preamble and three access codes, tx2 needs to wait for the trigger from rx1 through backend Ethernet. We set the gap between the timestamp of sending the first symbol and the timestamp of sending data payload as 38400 clock ticks, which equals 3000, 6000, and 12000 samples if you set the decimation to 128, 64, and 32, respectively. Note that if you cannot cancel the signal correctly, one possible reason is that the latency of your backend Ethernet channel is too long so that the GAP (38400 ticks) is not large enough. If this is the case, please modify the default setting of the micro called 'GAP' in your transmitter code (gnuradio/usrp2/host/app/mimo_zf_tx2.cc). The sample problem might happen in the forth example.

.: Result :.

Similar to the second example, the matlab code decode_miso() will plot the channels from two antennas (USRP2s) at tx2 computed in python and in matlab, respectively, as shown in the following.

It also plots the raw received signals. If tx2 cancels its signals properly, you should see the raw signals like the following figure on the left.

raw signal (nulling correctly)

raw signal (USRP2s are not synced correctly)

Remember that we set GAP to 38400. Because we set the decimation to 64, the number of samples during this gap duration should be 38400/64=6000. In our example code, we send a null symbol before the preamble in order to clean the USRP2 buffer. Thus, the first sample of data payload should be at around the (6000-128*2=5744)th sample in the above figure of the raw signals. Subtracting 128*2 is because we use the symbol length equal to 128 and truncate the first null symbol and the preamble in the raw signal figure. You might see that the signal starts at 5746~5749. The offset is due to the hardware delay, which should be a constant value depending on your USRP2.

If you cannot cancel the signals correctly, you will see the figure similar to the right figure. If this is the case, please modify the default setting of GAP.