Reputation: 397
The top Embedded Python Block in this GRC application is the stock block. The bottom one is a LPF the code for which is below.
Without the Throttle Block the application works. With the Throttle Block the error gr::log :ERROR: thread_body_wrapper - ERROR thread[thread-per-block[2]: <block Embedded Python Block 2(3)>]: ValueError: could not broadcast input array from shape (17,) into shape (16,)
is generated. There is no such problem when the Throttle Block is in the path of the stock block.
I learning GRC and would like to understand why the introduction of the Throttle Block is causing the problem.
import numpy as np
from gnuradio import gr
class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block
"""Embedded Python Block example - a simple multiply const"""
h = np.array([0.0397989, -0.0488053, -0.0345932, 0.0659844, 0.0315417, -0.1074744,
-0.0299212, 0.3187633, 0.5294118, 0.3187633, -0.0299212, -0.1074744, 0.0315417,
0.0659844, -0.0345932, -0.0488053, 0.0397989], dtype=np.float32)
a = True;
def __init__(self, example_param=2.0): # only default arguments here
"""arguments to this function show up as parameters in GRC"""
gr.sync_block.__init__(
self,
name='Embedded Python Block 2', # will show up in GRC
in_sig=[np.float32],
out_sig=[np.float32]
)
# if an attribute with the same name as a parameter is found,
# a callback is registered (properties work, too).
self.example_param = example_param
def work(self, input_items, output_items):
"""Convolution of input with LPF coefficients"""
output_items[0][:] = np.convolve(input_items[0], self.h, 'same')
return len(output_items[0])
Upvotes: 0
Views: 895
Reputation: 36346
First of all, this won't work – convolution has memory, and your convolver doesn't save that. This makes the numbers that come out of your blk
to depend on in what kind of "chunks" your input signal is delivered. That's not OK, because GNU Radio can (and will) use different lengths at any time.
Your algorithm must be written in a way that always yields the same result, no matter how your (infinite or finite) input stream is being partitioned for individual calls to work
.
That's basically it – the problem here seems to be that the result of your np.convolve
call doesn't have the same length as output_itmes[0]
. Read the documentation of numpy.convolve
; it specifies exactly why and when this happens:
Mode ‘same’ returns output of length max(M, N). Boundary effects are still visible.
So, if the chunk of samples you've gotten is shorter than h
, then you're trying to save len(h)
items in a len(output_items[0])
sized array, which is too short.
This can always happen – as said, GNU Radio needs to "cut" the signal into pieces and hand them to your work
, and the length of these chunks isn't fixed. Your Throttle just makes it more likely to happen.
So, you first need to conceptually solve the fact that this is not proper mathematically (the convolution of a long signal is not the same as a sequence of truncated convolutions of short sub-segments, simple as that). Most likely the answer to this is to just use one of the filter blocks GNU Radio comes with anyway.
Upvotes: 1