Hi everyone,
I'm working on a cognitive radio demonstrator as part of my bachelor thesis and I'm currently facing issues with overflows and underflows in my GNU Radio flowgraph when using a USRP device.
I've attached screenshots of my flowgraph for simulations:
I think the issue might be related to my OOT blocks. The problem is that I need to dynamically set the occupied carriers, but with the existing GNU Radio blocks, I couldn't find a way to do it — so I created a custom block for that purpose.
However, due to latency between the two inputs of the allocator block, it ends up crashing. I modified my code to use buffers, but the performance is quite slow.
Does anyone have suggestions on how to address this issue, or any ideas on how to dynamically set the number of subcarriers in the allocator with an existing block?:
Thanks in advance.
Here is the code of the allocator block:
import numpy as np
from collections import deque
from gnuradio import gr
class Allocator(gr.sync_block):
"""
Allocator block optimized for performance
"""
def __init__(self, mask_len=128):
gr.sync_block.__init__(self,
name="Allocator",
in_sig=[np.complex64, (np.float32, mask_len)],
out_sig=[(np.complex64, mask_len)]
)
self.mask_len = mask_len
self.data_buffer = np.zeros(0, dtype=np.complex64)
self.mask_buffer = deque()
def work(self, input_items, output_items):
in_data = input_items[0]
in_mask = input_items[1]
out = output_items[0]
n_symbols = min(len(in_mask), len(out))
self.data_buffer = np.append(self.data_buffer, in_data)
self.mask_buffer.extend(in_mask)
symbols_written = 0
data_idx = 0
for i in range(n_symbols):
if len(self.mask_buffer) == 0:
break
mask = self.mask_buffer.popleft()
if len(mask) != self.mask_len:
raise ValueError(f"error mask len")
occupied_carriers = np.where(mask < 0.5)[0]
num_occupied = len(occupied_carriers)
if data_idx + num_occupied > len(self.data_buffer):
break
ofdm_symbol = np.zeros(self.mask_len, dtype=np.complex64)
ofdm_symbol[occupied_carriers] = self.data_buffer[data_idx:data_idx + num_occupied]
data_idx += num_occupied
out[i][:] = ofdm_symbol
symbols_written += 1
self.data_buffer = self.data_buffer[data_idx:]
return symbols_written
Read the mailing list of the GNU project right here! The information here is regarding the GNU radio project for USRP radios.
Tuesday, April 29, 2025
Re: Help with setting manually occupied carriers in a OFDM allocator
Hi Miguel.
U's mean you are not sending samples to the USRP Sink device fast enough. It is having to read and send from the transmit buffer before you've set all the memory. O's mean the USRP source device buffer is not being read from fast enough, it is overflowing before you read from it.
The sample rate of your USRP devices is the ultimate stressor for this behavior. The higher the sample rate, the more likely you are to encounter O's and/or U's. This rate, coupled with the amount of processing you have to do in the transmit and receive paths, ultimately determines whether you will get O's or U's.
What sample rate are you using, and are you required to use this rate? Is there a sample rate you can lower the tx/rx to that makes the U's and O's go away?
If there is no sample rate that makes the O's and U's go away, then the amount of processing you're doing is the problem. You need to do less, get more efficient at what you're doing, or a combination of the two. If you don't need a realtime system, you can preprocess the entire transmitter and dump what would feed the transmitter into a file. Then when you use a USRP, all you do is read from a file directly into the transmitter. The same can be done on the receiver. Dump the USRP directly into a file. Then read from that file and process it through the receive chain.
Hope this helps.
Rich
On Tue, Apr 29, 2025 at 6:20 AM Miguel Calvo <micalost14@gmail.com> wrote:
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment