bastibl / gr-ieee802-11

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

Pilot symbol structure and CSI estimation #130

Closed sayaz closed 5 years ago

sayaz commented 5 years ago

Hi Bastian,

I have installed the gr-ieee802-11 module and run the wifi_loopback.grc which is working fine. As I have installed your tool now, I wanted to check if I can get Channel State Information from wifi_rx. I haven't found any link for documentation on this, can you give me any link if you have one? Also Had some questions for you:

  1. Can I do CSI estimation with what the gr-ieee-802-11 already has? Or I need to do some modifications? Like adding some extra blocks like "OFDM CHANNEL ESTIMATION".

  2. If I can do CSI, what is being used to estimate it? Is it the pilot symbols or the sync words? As on previous ofdm/examples/ of gnuradio they used sync words to estimate the CSI (which should not be the way in wifi).

  3. If I understand right is there 127 pilot symbols? And are these combination of STF, LTF, SIG preambles of 802.11a?

  4. If I want to develop 802.11n over your module, should only changing the pilot symbols work?

Apologies for asking some basic question. But I needed to get clear before I start working on it. Will also be happy if you can give me a documentation link of the applied blocks.

bastibl commented 5 years ago

Can I do CSI estimation with what the gr-ieee-802-11 already has? Or I need to do some modifications? Like adding some extra blocks like "OFDM CHANNEL ESTIMATION".

Yes, it's done in the equalizer. But by default its not logged. For example the simple LS equalizer: https://github.com/bastibl/gr-ieee802-11/blob/next/lib/equalizer/ls.cc#L39

If I can do CSI, what is being used to estimate it? Is it the pilot symbols or the sync words? As on previous ofdm/examples/ of gnuradio they used sync words to estimate the CSI (which should not be the way in wifi).

Depends on the equalizer. The LS equalizer, for example, uses only the long preamble symbols.

If I understand right is there 127 pilot symbols? And are these combination of STF, LTF, SIG preambles of 802.11a?

There are two short training symbols (used for frame detection) and two long training symbols (used to estimate the channel). See the standard for further information.

If I want to develop 802.11n over your module, should only changing the pilot symbols work?

11n and 11a does not only differ in terms of pilots. So no.

sayaz commented 5 years ago

Thank you Bastian for the quick reply.

So I have combined both the wifi_tx.grc & wifi_rx.grc in the same file. Replaced the USRPs with virtual source/sink and channel model. QT gui runs without any error except for the below lines in console. Then I have activated LS algorithm in WIFI FRAME EQUALIZER with both LOG & DEBUG enabled. I have also attached a Tag debug to it. But cannot see any output in the console for the complex CSI values. Am I doing this correct?

MAPPER: encoding: 0
set_min_output_buffer on block 9 to 397056
set_min_output_buffer on block 11 to 397056
set_min_output_buffer on block 13 to 397056
set_min_output_buffer on block 14 to 397056
set_min_output_buffer on block 16 to 397056
LS
set_min_output_buffer on block 35 to 96000
set_min_output_buffer on block 51 to 100000
bastibl commented 5 years ago

The output is normal but won't tell you anything if you did it right.

Tthe CSI values are not logged. If you want to output them, you'll have to change the source code. Either

sayaz commented 5 years ago

Hi Bastian,

I am not sure if this is the right place to ask this question as this might be more on the perspective of GnuRadio & OFDM preamble fields. But as you have used this in your flow, I could not stop asking.

Please correct me if I am wrong. You have used the 2 x L-STF and 2 x L-LTF symbols in the sync word argument field and not in pilot symbols of OFDM CARRIER ALLOCATOR. If so then I have 2 questions:

  1. As from the 802.11a standard, the L-STF occurs on every 4th sub-carrier (1x L-STF consist of 12 symbols) and has a value of (1+j), 0, 0, 0, (-1+j) and so on. But I am seeing you have used something like (1.4719601443879746+1.4719601443879746j) why is so?

  2. And on L-LTF I am seeing the second L-LTF is used exactly as said in the standard but the first L-LTF is different, which lead me to more confusion.

  3. If all the L-STF & L-LTF are used in sync word argument then what input is given on the pilot symbol fields? example : (1, 1, 1, -1), (1, 1, 1, -1)......What do these represent?

bastibl commented 5 years ago

If's fine, but you could also write to the GNU Radio mailing list.

You have used the 2 x L-STF and 2 x L-LTF symbols in the sync word argument field and not in pilot symbols of OFDM CARRIER ALLOCATOR. If so then I have 2 questions:

Yes, because pilots are the interleaved comb pilots, whereas sync words are at the start of the frame, i.e., the preamble.

As from the 802.11a standard, the L-STF occurs on every 4th sub-carrier (1x L-STF consist of 12 symbols) and has a value of (1+j), 0, 0, 0, (-1+j) and so on. But I am seeing you have used something like (1.4719601443879746+1.4719601443879746j) why is so?

The sync words are generated with the sync_words.py script in the utils folder. I guess that should explain most questions. But, anyhow, the values are normalized to the same avg power. Otherwise, the short training sequence would have much lower power.

And on L-LTF I am seeing the second L-LTF is used exactly as said in the standard but the first L-LTF is different, which lead me to more confusion.

That's because the long training sequence uses a different symbol format. It's not the usual cyclic prefix and the symbol but over two symbols it is [half sequence, full sequence, full sequence]. Putting the strange sequence in the carrier allocator through the cyclic prefix block, we get exactly that. It's the price we have to pay for using the standard OFDM blocks.

If all the L-STF & L-LTF are used in sync word argument then what input is given on the pilot symbol fields? example : (1, 1, 1, -1), (1, 1, 1, -1)......What do these represent?

These are the comb pilots, which are interleaved with the data symbols.

sayaz commented 5 years ago

Hi Bastian,

Thanks for the answer. I can now get the CSI values for all 52 subcarriers.

Everything is fine in wifi_loopback file, but when I aggregate tx_wifi & rx_wifi in a single file(replacing USRPs with channel model) and selecting the algorithm LS in Wifi Frame Equalizer block I can't see the CSI printed, though the file runs with the QT. Can you say something about this?

Also is there a way to see the timestamp for these CSI? Or do I just print the time from the system?

bastibl commented 5 years ago

Is there any way to get the timestamp for the CSI, or I just need to print the system clock time?

I did not add a custom method to get and print system time. But GNU Radio allows to access the current sample number, which is like a relative time stamp. The problem is that only a subset of all samples arrives at the equalizer. So if you wanted to use the sample number, you'd have to annotate it in the sync short block.

Besides when I run a new file which aggregates wifi_tx.grc & wifi_rx.grc (USRPs replaced by channel model, I don't see the CSI getting printed. But no error is shown either. I have selected the algorithm 'LS' in Wifi Frame Equalizer block but no luck.

I see no reason why that shouldn't work. I guess it's a bug from copy-pasting flow graphs. I'm not sure why you are doing this in the first place. This should be the same thing as the loopback flow graph.

sayaz commented 5 years ago

Hi Bastian,

I have 3 more question. If you think it is not the right place to make this question here, you can delete this post and mail me at ayazmahmud@hotmail.com (if you prefer to answer).

  1. The 802.11a standard says there are 10 identical STFs. In that case, are you doing the packet detection with only 2? The advantage is, of course, reduced header size. But what is the difference in terms of detection?

  2. Regarding the delay of 16 in packet detection. What I read is each STF symbol has 16 samples. But I don't understand how we get this 16 samples & why is used in delay. Can you give me an idea on this?

  3. Is the same method used for packet detection in 802.11n (GreenField mode). As it also has this L-STF field.

bastibl commented 5 years ago

The 802.11a standard says there are 10 identical STFs. In that case, are you doing the packet detection with only 2? The advantage is, of course, reduced header size. But what is the difference in terms of detection?

I don't get the question. But the receiver correlates the symbol with the next one (delay = 16) but averages over multiple copies (window parameter).

Regarding the delay of 16 in packet detection. What I read is each STF symbol has 16 samples. But I don't understand how we get this 16 samples & why is used in delay. Can you give me an idea on this?

It's a 64-bin FFT (=64 samples) with a 1/4 cyclic prefix (=16 samples). So a complete symbol is 80 samples. The STF is 2 symbols (=160 samples) and corresponds to 10 repetitions. That means one repetition of the pattern is 16 samples.

Is the same method used for packet detection in 802.11n (GreenField mode). As it also has this L-STF field.

I didn't have a close look at 11n.

sayaz commented 5 years ago

Hi Bastian,

static const int MIN_GAP = 480; static const int MAX_SAMPLES = 540 * 80;

  1. Can you please help me understand what does MIN_GAP & MAX_SAMPLES represent in sync_short.cc. and how you came to this values? MAX_SAMPLES = Total no. of samples in a packet?

  2. I would also like to check whether i understand the flow correctly in sync_short.cc, can you please comment whether I am right? Or if I have missed anythin ?

bastibl commented 5 years ago

MIN_GAP is the minimum gap between two frames. So once frame detection was triggered, it won't be triggered again during the next MIN_GAP frames. I set it to 6 symbols (6 * 80 = 480, 4 preamble, 1 signal field, 1 data symbol). MAX_SAMPLES corresponds to the largest frame that can be decoded. IIRC, the number corresponds to a BPSK 1/2 frame with 1500 byte (I think the standard allows larger frames, but I didn't see some in the real-world, if you wanted to decode larger frames, you'd have to adapt parameters in lib/utils.h). At Sync Short block, the receiver just knows that there is a frame, but it cannot know its size. So for every detected frame, it pipes samples corresponding to a maximum-sized frame into the flow graph. The algorithm looks good, but it doesn't always copy MAX_SAMPLES. Only if no other frame was detected within MIN_GAP and MAX_SAMPLES. If it would always copy MAX_SAMPLES, it would miss ACKs or CTS in reply to RTS.

sayaz commented 5 years ago

Thank you, Bastian, for explaining my questions patiently. I have another one:

  1. Can you briefly explain the algorithm on how you are extracting the LTF at Rx in order to calculate CSI. For example, let's say for LS method we must use the LTF, my question is how do you know the position of the LTF in the received signal? and how are you extracting it?
bastibl commented 5 years ago

That's done in the Sync Long block (the code is quite horrible). It uses a matched filter to determine the exact position of the LTF pattern. See Figure 4.5 in here: https://www.bastibl.net/bib/bloessl2018physical/bloessl2018physical.pdf

sayaz commented 5 years ago

That's a really good information source, thanks for sharing.

  1. When I run the wifi_loopback.grc I get the CSI (using LS) like as below. Though I am not running this with USRPs, but aren't the magnitude showing very high? Is this ok? I was thinking that it should be in a lower range (I have made no change in flowgraph).

CSI(46.0934,4.01396) CSI(51.703,-2.12965) CSI(57.3512,-4.21838) CSI(50.8338,0.444033) CSI(48.9158,-0.356066) CSI(47.2136,3.14362)

  1. The LTF (1/2 + 1 + 1) is the 1/2 is related to GuardInterval that I am seeing in other docs?

capture

  1. For MIN_GAP you have set it to 6 symbols (6 * 80 = 480, 4 preamble, 1 signal field, 1 data symbol) But when you are adding the extra 32 samples in LTF(1/2) is it staying 160 samples anymore after adding the CP ? (32 + 64 + 64)LTF + (16)CP+(16)CP = 192

  2. In OFDM allocator block, you have the 64 pilot symbols defined separately, but isn't there should be just 1 of them like (1,1,1,-1) as we need only 4 of them in 64 sub-carriers? Ca you explain a bit on this?

  3. Is sync_long is also responsible for removing the CP?

  4. After detection/symbol sync are the STF & LTF removed or it gets pass to the output ?

  5. The document you shared, on page 53 it says 'Y1,2 are the two received copies of the long training sequence'. Do the 2 received copies means the 2 OFDM symbols of LTF or receiving 2 OFDM symbols separately one after another?

  6. I am trying to add another preamble (HT-LTF) similar to LTF in addition of what you have in Sync Words. I ami willing to use the exact block you have to detect / sync the frame at Rx. And then extract the new HT-LTF and do the channel estimation. In this case, can you suggest what I might need to do any change in your flowgraph before Wifi Sync Long block ?

Apologizing for making so many questions & editing :-(

bastibl commented 5 years ago

Aren't the magnitude showing very high?

They are. Still, you shouldn't look at the CSI but the IQ stream that would be sent to the device. If hardware is used, both I and Q components have to be in the range [-1, 1].

As you noticed, the loopback flow graph does not involve any hardware. That means amplitudes can be whatever. I wanted to keep it simple and used a constant noise power of 1 and rescaled the signal so that we reach the target SNR. The flowgraphs that are supposed to be used with hardware normalize the signal differently.

The LTF (1/2 + 1 + 1) is the 1/2 is related to GuardInterval that I am seeing in other docs?

All symbols OFDM use a 1/4 cyclic prefix. The LTS is the only exception here. As depicted in the figure it uses a 1/2 guard in the beginning and then the two similar symbols back to back.

  1. I think this sentence is broken. No idea what you mean but the calculation already include the LTS (= the preamble). 4 symbols for the preamble (4 80 samples) already includes the STS and LTF including their guard periods (otherwise it would be 4 64...)

  2. The comb pilots are sometime inverted, following a 127 long sequence. Please see the standard.

  3. Yes.

  4. LTF is passed through for initial channel estimation in subsequent blocks.

  5. I don't understand the question. Its T1 and T2 in the picture above...

  6. No idea what you are expecting here. Depends on what you are planning to do, i.e., how you want to use the premamble and where. I guess that's the bit that you have to figure out.

sayaz commented 5 years ago

Thanks, Bastian I guess I have got your answer. What I was confused about was the 2.5 LTF. So the 1/2 at the beginning is actually the guard interval (32 samples long). And as we are using the OFDM carrier allocator block, due to its limitation of adding the GI, you are using the hardcoded modified symbol for the 1st LTF. And passing this through the IFFT & CP it gives an o/p of 2.5 repetitions of LTF. I really hope i am getting this correct this time.

capture

And can you just tell me what the o/p is going to be like after FFT? Will it be like : LTF(64), LTF(64), Data....LTF(64), LTF(64), Data....

bastibl commented 5 years ago

Exactly. It's happening here: https://github.com/bastibl/gr-ieee802-11/blob/next/lib/sync_long.cc#L130-L133

The first two symbols of the LTF (rel < 128) are consecutive samples. And for the rest, remove the guard. That means we forward always the "interesting" samples of each symbol.

sayaz commented 5 years ago

Hi again, How have you made sure that data is 64 or (64+16 CP) = 80 samples and not more/ less for every frame? Is there any way to cross check that in your flowgraph? And though there is no SIG field in the frame but you have counted as 80 samples just to be safe ?

bastibl commented 5 years ago

I don't understand the question. Maybe there is some misconception about how that works... In Sync Long, the receiver estimates the symbol alignment. Then it skips 16 samples (cyclic prefix), copies 64 samples (OFDM symbol), skips 16, copies 64, .... Or maybe you are irritated by 80? Which is the length of an OFDM symbol (64 samples + 16 samples cyclic prefix)

sayaz commented 5 years ago

Thanks, Bastian, it's now clear. Regarding the CSI with LS algorithm.

capture

Is there any specfic reason to take both the copies of LTF (y1 and y2)? Why not just take one LTF (64 samples) and compre with the known sample? I have actually tried this out, but the plot looks garbage, so wanted to know the reason behind this formula.

bastibl commented 5 years ago

The signal is probably garbage because you didn't fully adapt the receiver to use just one symbol. But there is really no reason to do that in the first place. The standard mandates that two copies are sent, so why not use them... Channel estimation based on two realizations of the channel is better (i.e., more accurate) than an estimate based on just one symbol.

sayaz commented 5 years ago

Thanks, Bastian, I got everything working now with some modification for my project. Just one more thing to know, could you achieve the 10MSPS with your USRP (N210) using this flowgraph? Because I am using B210 and could not generate that sampling rate. It is true that I have USB 2 interface and not 3. Do you think it might be an issue ? Or anything else I might look into?

bastibl commented 5 years ago

I don't get what you mean with "could not get the sample rate." The question is if the SDR did not deliver fast enough or if your PC did not consume the sample fast enough, i.e., had to drop samples.

It is true that I have USB 2 interface and not 3.

I don't know what PC you have, but the B210 supports USB3. When you plug it into a USB3 port, it should mention on the console that it uses USB3 mode. Make sure that this is the case.

If you see lots of 'O's on the console, your PC might not process the samples fast enough.

amogh-panchagatti commented 6 months ago

Thank you Bastian for the quick reply.

So I have combined both the wifi_tx.grc & wifi_rx.grc in the same file. Replaced the USRPs with virtual source/sink and channel model. QT gui runs without any error except for the below lines in console. Then I have activated LS algorithm in WIFI FRAME EQUALIZER with both LOG & DEBUG enabled. I have also attached a Tag debug to it. But cannot see any output in the console for the complex CSI values. Am I doing this correct?

MAPPER: encoding: 0
set_min_output_buffer on block 9 to 397056
set_min_output_buffer on block 11 to 397056
set_min_output_buffer on block 13 to 397056
set_min_output_buffer on block 14 to 397056
set_min_output_buffer on block 16 to 397056
LS
set_min_output_buffer on block 35 to 96000
set_min_output_buffer on block 51 to 100000

Hey, were you able to extract the csi?