gnuradio / gnuradio

GNU Radio – the Free and Open Software Radio Ecosystem
https://gnuradio.org
GNU General Public License v3.0
5.12k stars 1.92k forks source link

gr-uhd TSB bursts constantly produce Us #1976

Open jdemel opened 6 years ago

jdemel commented 6 years ago

Following setup: UHD 3.14.0.0-31-g98057752 with an X310 GNU Radio version: 3.7.12.0 on master branch at 8c8f166d8383c39bdcacdf8ecf28cfd4eca4452f with @ptrkrysik patch 6f4a03a9c5ea361a8fb2d4b29aab3b9dd8a7e644 EDIT: patch

I'm using gr-digital/examples/packet/uhd_packet_tx.grx. Only the random PDU generator does always generate PDUs with 1byte length.

This examples sends out a burst every 2s. After every burst, UHD prints a 'U'. This is really annoying if the transmission interval is lowered, e.g. every 10ms. The console gets flooded with 'U'. I observed the same behavoir with my custom flowgraph.

I dug a little deeper into this issue. So, what did I observe?

at: Fri Aug 24 11:24:21 2018 usrp_sink_impl::work is called with noutput_items=408 and nitems_read(0)=428 A tag is found at: Offset: 428 Source: burst_shaper_cc Key: packet_len Value: 418 So a burst is transmitted but since it is not an entire burst with 418 but only the first 408 samples _metadata.start_of_burst=true and _metadata.end_of_burst=false.

Now, UHD prints a single 'U'. ??

Why is this surprising? I expected a whole burst to be ready to be transmitted. So I would expect the missing samples till EOB to be available right after the last call to usrp_sink_impl::work.

Recall every 2s a burst is emitted via a Message Strobe in the example. When does the next call to work with then missing 10 samples occur?

at: Fri Aug 24 11:24:23 2018 2s after the last call usrp_sink_impl::work is called with noutput_items=418 and nitems_read(0)=836 A tag is found at: Offset: 846 Source: burst_shaper_cc Key: packet_len Value: 418 OK, so those 10 missing samples from the last burst finally arrived. Where were they? Anyway, those 10 samples are now send to the USRP with _metadata.start_of_burst=false and _metadata.end_of_burst=true. But only those 10 samples! And usrp_sink_impl::work returns 10. At least that's not surprising.

So there were another 408 samples ready. But since there should be an entire burst, ready for transmission, another 418 samples should be available. So when does the next call to work happen?

at: Fri Aug 24 11:24:23 2018 right after the last call with noutput_items=408 and nitems_read(0)=846 A tag is found at: Offset: 846 Source: burst_shaper_cc Key: packet_len Value: 418 So a burst is transmitted but since it is not an entire burst with 418 but only the first 408 samples _metadata.start_of_burst=true and _metadata.end_of_burst=false.

Now, UHD prints a single 'U'. ??

So the pattern repeats. There is this 10 samples offset.

A look at the very first tag shows: Offset: 10 Source: burst_shaper_cc Key: packet_len Value: 418 There is already an offset where there should be 0. This does actually cause tG to be printed which comes from usrp_sink_impl::work and is a warning that there is a tag gap. In the example the offset is always 10 samples. In my custom flowgraph it is always 64. In any case, it is really weird that this happens. And of course I wonder where this misalignment comes from.

EDIT 1: I went through the packet_tx hier block used in the example. It seems like the Polyphase Arbitrary Resampler introduces this 10 sample offset. Also, my custom flowgraph seems to be 'fixed' if I remove a Vector Insert block right before my Stream To Tagged Stream block which feeds the USRP sink. But this is not a good solution since the whole point of the Vector Insert block was to append 0.0s in order to flush the USRP. Otherwise the last samples of a previous burst appear at the beginning of a new burst.

EDIT 2: The issue seems to have 2 different soruces. in the packet_tx case it is the Polyphase Arbitrary Resampler that introduces this shift and does not get 'flushed' after every burst. In my custom flowgraph the problem arises because Vector Insert will only insert a vector at the end of my burst, when there is data for the next burst. Otherwise the scheduler does not call Vector Insert with noutput_items large enough to fill the vector to be inserted. This will happen when data for the next burst is generated. At this point we get back at the first issue. In packet_tx there needs to be a way that flushes Polyphase Arbitrary Resampler and sets the tags correctly. Burst Shaper block tries to achieve this but this messes with tag offsets after all.

ptrkrysik commented 6 years ago

Which patch is 6f4a03a9c5ea? I submitted only this one recently: https://github.com/gnuradio/gnuradio/pull/1947/commits/80dcc7103ac28f60dd122a12bc41034fc51edd37#diff-b9ec33a1b46be690a60a0ac37b5a66d5.

I tried on X310 different versions of UHD (the 98057752 and from 3.9.LTS branch) and GNU Radio 8c8f166d83, with and without my patch and the result is always the same: after each bursts there is U(nderrun).

Do you know some versions of GNU Radio and UHD when that example worked without this issue?

ptrkrysik commented 6 years ago

I'm using Burst Shapper block in order to append zeros. It changes length tag accordingly.

But the original flowgraph doesn't have the Vector Insert or the resampling block and it doesn't work correctly anyway...

EDIT: I missed the fact that you meant packet_tx hier block not the whole flow-graph.

jdemel commented 6 years ago

@ptrkrysik, that's the patch I'm referring to. I updated my comment accordingly. Apparently it wasn't all that smart to cherry-pick your commit and just grab its hash then.

I don't know of any GR/UHD version where this example works. But I didn't try many.

Yeah, I'm refering to the hier block.

jdemel commented 6 years ago

One way to fix this problem is to add set_output_multiple(periodicity); in the Vector Insert constructor. It does fix the initial problem with the Vector Insert block but also, it might cause other trouble. e.g. large periodicity values might be problematic now.

jdemel commented 6 years ago

Another note on the proposed fix. It seems like set_output_multiple(periodicity) does fix the issue. Though, choosing a value like periodicity / 2 > data.size() does make the issue worse. data is a std::vector holding the values to insert.

In light of those findings, I suggest to

  1. add a warning about that in the comments.
  2. add a GRC argument enforce periodicity multiple with default=False or 1.