bastibl / gr-ieee802-11

IEEE 802.11 a/g/p Transceiver
https://wime-project.net/
GNU General Public License v3.0
750 stars 292 forks source link

Issue on IQ data extraction from PDU to Tagged Stream #327

Closed islamshohidul closed 2 years ago

islamshohidul commented 2 years ago

Hello @bastibl I've been working on a project, and for various reasons, I'm unable to obtain the exact IQ data point shown in the constellation diagram. The flow diagram for wifi_rx is as follows:

image

constellation

As you can see, I'm attempting to save IQ data from the PDU to a file sink using tagged stream blocks. Later, I used a python script to analyse the data and make a graph, but I was unable to replicate the constellation graph created in the wifi receiver code. My Python code is as follows:

`import numpy, scipy import matplotlib.pyplot as plt samples = numpy.fromfile(open("bib1.bin"), dtype=numpy.complex64) real = numpy.real(samples) imag = numpy.imag(samples)

plt.scatter(real,imag) plt.ylabel('Imaginary') plt.xlabel('Real') plt.show()`

After data processing I got the graph like this: download

Would you mind taking a look and letting me know what I'm missing to get the desired results?

Hardware specifications:

Ubuntu 19.04 (For receiver and transmitter 2 different laptops being used) `-------------------------------------------------- -- UHD Device 0

Device Address: serial: 3237C05 name: MyB210 product: B210 type: b200 ` GNU Radio Companion 3.7.13.4

Issues and other sources that I looked into before writing this post: https://github.com/bastibl/gr-ieee802-11/issues/199 https://github.com/bastibl/gr-ieee802-11/pull/294 https://github.com/bastibl/gr-ieee802-11/issues/217 https://github.com/bastibl/gr-ieee802-11/issues/242 https://www.bastibl.net/bib/bloessl2018physical/bloessl2018physical.pdf https://github.com/bastibl/gr-ieee802-11/issues/216 https://github.com/bastibl/gr-ieee802-11/issues/293

I hope I've been able to clarify the issue and the purpose of this post. Thank you very much.

bastibl commented 2 years ago

You might be overplotting the actual interesting data with bogus values. I'd try to set an alpha value and zoom in to [-3;3].

islamshohidul commented 2 years ago

I followed your advice and was able to replicate something similar to what is seen below.

image

The graph has a lot of noise data in it, which prevents me from seeing the QPSK 4 constellation points. However, the four data points visible at point -0.7 and 0.7 in the image. If you could explain me how to acquire the exact point after noise reduction, that would be great. I ranged the x and y axis data points [-1,1], because the QPSK data constellation data point lied between -0.7 and 0.7. I'd appreciate it if you could provide some noise reduction resources or shed some light on the subject.

I have collected data from the wifi_loopback code and reproduce the graph (BPSK constellation diagram) as below:

image

It has provided me the constellation diagram as predicted because there is no noise, it is completely noise free. My current challenge is to decrease noise in the acquired data in order to recreate the intended constellation diagram. Thank you very much.

bastibl commented 2 years ago

Your plot suggests that the receiver tried to sync on bogus data, which results in noise-like constellation points. You probably want to check your receiver configuration and setup. (no underruns, gain settings, check antenna, etc. etc)

islamshohidul commented 2 years ago

Thank you for your quick reply. I have changed the gain to .75 and set transmitter pdu length 5 and interval 10. I obtained constellation data like this, which always has middle noise.

image

Because of the noise, the graph in the Matlab script looks like this. image

We can see from the constellation points that the QPSK points are exactly as expected, however there is noise causing signal distortion. It would be really appreciated if you could provide any ideas.

bastibl commented 2 years ago

If you found the issue, it would be great if you could add it to this issue to make this more useful for others.

islamshohidul commented 2 years ago

Thanks for your guideline. If there any query I will post her.

islamshohidul commented 2 years ago

Hello @bastibl ,

I am not sure it's worth to ask you. I am getting another silly error right now. After storing data before and after equalization. I am getting like below graph.

image

My grc block diagram like bellow image

There are no contellation points in my FFT block file sink data other than all points in a single point.

After zooming in on the graph, I noticed something like this, which does not appear to be QPSK. image

If you have any suggestions for how to resolve this, I would really appreciate it. Thank you.

bastibl commented 2 years ago

This is exactly as expected. There is nothing to resolve. The amplitude changes with gain settings, antenna, and attenuation of the channel. It won't just have an average power of 1. The equalizer does the rescaling. It also just outputs the OFDM symbols that are part of the frame (it knows through decoding the signal field). So a 1-to-1 comparison of these symbols doesn't make much sense.

islamshohidul commented 2 years ago

Thank you for your quick response. I went over the constellation and equalization code bases in the lib folder. According to my understanding, the OFDM data is mapped in a QPKS or other modulation scheme while being translated into time domain, and the data is recovered in frequency domain in the receiver using the FFT block. That is to say, after FFT, I should obtain the mapped data in the form of a QPSK constellation point. In 802.11a OFDM, 52 sub-carriers are broadcast over the air, with 4 serving as pilot data and 48 serving as data sub-carriers (which are actual data that used in the receiver to demodulate the actual data).

Overall WiFi infrastructure: I just want to make sure I'm clear on how WiFi works. Please correct me if I'm mistaken. In IEEE 802.11, OFDM is utilized to deliver multiple(52) sub-carriers of data, using variety of QAM modulation techniques. The frequency domain data is transferred into the time domain(IFFT) in the transmitter, and the opposite is true in the receiver (FFT use for that).

bastibl commented 2 years ago

This is roughly correct. I'd recommend to check the standard as this is the definite source on how exactly IEEE 802.11(a) works. But there are also many other works that explain the functionality much better than I could in this issue.

islamshohidul commented 2 years ago

Hello @bastibl , Can you give me some sort of idea? How can I get CSI data from the C++ code. image I am trying to collect H channel matrix data. In the ls.cc file like below code ` else {

          int c = 0;
          for (int i = 0; i < 64; i++) {
              if ((i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) ||
                  (i < 6) || (i > 58)) {
                  continue;
              } else {
                  symbols[c] = in[i] / d_H[i];
                   //I try to collect data (in file) of symbol, in and d_h but it doesn't give 
                 me similar data that I found from gnu radio block after fft block and 
                 equalize data
                  bits[c] = mod->decision_maker(&symbols[c]);
                  c++;
              }
          }`

My question is: how can I get the H value from the gnu radio block or by modifying the C++ code? Thank you.

bastibl commented 2 years ago

You already found the code where CSI is used, I guess you lack the C++ knowledge. I'd recommend to use the maint-3.9 branch. It already has a CSI output, which you can pipe into a file sink, i.e., you only have to modify the flowgraph and not the code.

islamshohidul commented 2 years ago

Thanks again. I understand what you say. From the flow graph can I get the H value as I mentioned earlier? I only got the data from the flow graph like below.

image

My code is like below: `else {

    int c = 0;
    for(int i = 0; i < 64; i++) {
        if( (i == 11) || (i == 25) || (i == 32) || (i == 39) || (i == 53) || (i < 6) || ( i > 58)) {
            continue;
        } else {
            symbols[c] = in[i] / d_H[i];

            std::FILE* p1File;
                p1File = std::fopen("/tmp/h_file.bin", "wb");
    //for (unsigned long long j = 0; j < 1024; ++j){
        //Some calculations to fill a[]
                 std::fwrite(d_H, 64, 64 * sizeof(gr_complex), p1File);
    //}
                std::fclose(p1File);

            std::FILE* p2File;
                p2File = std::fopen("/tmp/in_file.bin", "wb");
                //for (unsigned long long j = 0; j < 1024; ++j){
                //Some calculations to fill a[]
                std::fwrite(in, 64 , 64 * sizeof(gr_complex), p2File);
    //}
                std::fclose(p2File);

            std::FILE* pFile;
                pFile = std::fopen("/tmp/s_file.bin", "wb");
                //for (unsigned long long j = 0; j < 1024; ++j){
                //Some calculations to fill a[]
                 std::fwrite(symbols, 64 , 64 * sizeof(gr_complex), pFile);
    //}
                std::fclose(pFile);

            bits[c] = mod->decision_maker(&symbols[c]);
            c++;
        }
    }
}`

I am not able to reproduce the same result from the code like flow graph. I am using 3.7 repository. I had some issues to work on 3.9 repo cause my ubuntu os version is 19.04.

Code location in repository: https://github.com/bastibl/gr-ieee802-11/blob/maint-3.8/lib/equalizer/ls.cc#L57
Sorry, I didn't understand how can I get the H value from the flow-graph.

bastibl commented 2 years ago

Sorry, but I cannot debug your C++ code. Here is the PR where CSI was added: https://github.com/bastibl/gr-ieee802-11/pull/294 Either you update your OS, you back-port this patch for 3.7, or you have to debug your C++ code. Whatever you find easier. I can only help with bugs of the current code base.