usrp-users@lists.ettus.com

Discussion and technical support related to USRP, UHD, RFNoC

View all threads

Writing GRC block for preamble detection

BA
Bakshi, Arjun
Sun, Jun 11, 2017 2:51 AM

Hello everyone,

I'm trying to build a GRC block in Python for the first time. I want a preamble detection block. I've read the guided tutorial here:https://wiki.gnuradio.org/index.php/Guided_Tutorial_GNU_Radio_in_Python , but am still unclear on what is happening under the hood.

I want to use a general/basic block that takes in len(preamble) floats and returns 1 float (correlation value).  My questions are:

  1. What should the input output signature look like? I'm thinking that I could write the signature as len(preamble):1, or in some M:N format like 1024:1024-len(preamble)+1. It is currently:
    def init(self, preamble, th=0.8):
    gr.basic_block.init(self,
    name="pre_detect_ff",
    in_sig=[(numpy.float32, len(preamble))],
    out_sig=[numpy.float32])

  2. What does the forecast function do? I think it tells gnuradio how to slice the input stream so that each chunk can be used to generate the required output. But Its not clear how the slicing is happening. My forecast function looks like:
    def forecast(self, noutput_items, ninput_items_required):
    for i in range(len(ninput_items_required)):
    ninput_items_required[i] = 1 # setting to len(self.preamble) gives error, not enough inputs to generate output
    # setting to 1 seems to make it work

How do I use consume? I think consume tells gnuradio to move on to the next chunk of data to process. I'm currently using it as follows in my general_work function:
def general_work(self, input_items, output_items):
print "called gen work"
for i in range(input_items[0].shape[0]):
result = numpy.corrcoef(input_items[0][i], self.preamble)[0, 1]
if result > self.th:
result = 1.0
else:
result = 0.0
output_items[0][i] = result
# consume(0,1)  # gives an error, undefined function, but this call was added by gr_modtool
self.consume_each(1)  # consume 1 data point on all streams (there is only 1 stream)

    return len(output_items[0])

I'm also having trouble with the QA tests(itemsize mismatch), but that my be due to bugs in my class code. I'd really appreciate someone answering these questions, and pointing out bugs in the code.

Thank you,

Arjun

Hello everyone, I'm trying to build a GRC block in Python for the first time. I want a preamble detection block. I've read the guided tutorial here:https://wiki.gnuradio.org/index.php/Guided_Tutorial_GNU_Radio_in_Python , but am still unclear on what is happening under the hood. I want to use a general/basic block that takes in len(preamble) floats and returns 1 float (correlation value). My questions are: 1. What should the input output signature look like? I'm thinking that I could write the signature as len(preamble):1, or in some M:N format like 1024:1024-len(preamble)+1. It is currently: def __init__(self, preamble, th=0.8): gr.basic_block.__init__(self, name="pre_detect_ff", in_sig=[(numpy.float32, len(preamble))], out_sig=[numpy.float32]) 2. What does the forecast function do? I think it tells gnuradio how to slice the input stream so that each chunk can be used to generate the required output. But Its not clear how the slicing is happening. My forecast function looks like: def forecast(self, noutput_items, ninput_items_required): for i in range(len(ninput_items_required)): ninput_items_required[i] = 1 # setting to len(self.preamble) gives error, not enough inputs to generate output # setting to 1 seems to make it work 3. How do I use consume? I think consume tells gnuradio to move on to the next chunk of data to process. I'm currently using it as follows in my general_work function: def general_work(self, input_items, output_items): print "called gen work" for i in range(input_items[0].shape[0]): result = numpy.corrcoef(input_items[0][i], self.preamble)[0, 1] if result > self.th: result = 1.0 else: result = 0.0 output_items[0][i] = result # consume(0,1) # gives an error, undefined function, but this call was added by gr_modtool self.consume_each(1) # consume 1 data point on all streams (there is only 1 stream) return len(output_items[0]) I'm also having trouble with the QA tests(itemsize mismatch), but that my be due to bugs in my class code. I'd really appreciate someone answering these questions, and pointing out bugs in the code. Thank you, Arjun
BS
Brent Stapleton
Mon, Jun 12, 2017 4:12 PM

Hi Arjun,

Your question would be better suited on the GNU Radio mailing list (
discuss-gnuradio@gnu.org); you may want to send it there as well.

The Correlation Estimator block
https://gnuradio.org/doc/doxygen/classgr_1_1digital_1_1corr__est__cc.html
sounds like it might do what you want. It will correlate against and tag
your preamble, and acts as a sync block (it does not remove the preamble
from the sample stream).

  1. the forecast block for general blocks is a suggestion to the GNU Radio
    scheduler, and can be tricky to get right for blocks that only sometimes
    change the number of samples in the stream. If possible, its much
    simpler/easier to use a block with a constant output:input ratio.

  2. Call consume with the  number of samples you used in the input (probably
    len(self.preamble)). The return value of general_work (or the argument to
    produce()) is the number of samples you generated in output_items (this
    should be 1 in your block).

Cheers,
Brent

On Sat, Jun 10, 2017 at 7:51 PM, Bakshi, Arjun via USRP-users <
usrp-users@lists.ettus.com> wrote:

Hello everyone,

I'm trying to build a GRC block in Python for the first time. I want a
preamble detection block. I've read the guided tutorial here:
https://wiki.gnuradio.org/index.php/Guided_Tutorial_GNU_Radio_in_Python ,
but am still unclear on what is happening under the hood.

I want to use a general/basic block that takes in len(preamble) floats and
returns 1 float (correlation value).  My questions are:

1. What should the input output signature look like? I'm thinking that
I could write the signature as len(preamble):1, or in some M:N format like
1024:1024-len(preamble)+1. It is currently:
    def __init__(self, preamble, th=0.8):
        gr.basic_block.__init__(self,
                                name="pre_detect_ff",
                                in_sig=[(numpy.float32,
len(preamble))],
                                out_sig=[numpy.float32])

2. What does the forecast function do? I think it tells gnuradio how
to slice the input stream so that each chunk can be used to generate the
required output. But Its not clear how the slicing is happening. My
forecast function looks like:
    def forecast(self, noutput_items, ninput_items_required):
        for i in range(len(ninput_items_required)):
            ninput_items_required[i] = 1 # setting to
len(self.preamble) gives error, not enough inputs to generate output
                                                              #
setting to 1 seems to make it work


3. How do I use consume? I think consume tells gnuradio to move on to
the next chunk of data to process. I'm currently using it as follows in my
general_work function:
def general_work(self, input_items, output_items):
        print "called gen work"
        for i in range(input_items[0].shape[0]):
            result = numpy.corrcoef(input_items[0][i],
self.preamble)[0, 1]
            if result > self.th:
                result = 1.0
            else:
                result = 0.0
            output_items[0][i] = result
            # consume(0,1)  # gives an error, undefined function, but
this call was added by gr_modtool
            self.consume_each(1)  # consume 1 data point on all
streams (there is only 1 stream)

        return len(output_items[0])

I'm also having trouble with the QA tests(itemsize mismatch), but that my
be due to bugs in my class code. I'd really appreciate someone answering
these questions, and pointing out bugs in the code.

Thank you,

Arjun


USRP-users mailing list
USRP-users@lists.ettus.com
http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com

Hi Arjun, Your question would be better suited on the GNU Radio mailing list ( discuss-gnuradio@gnu.org); you may want to send it there as well. The Correlation Estimator block <https://gnuradio.org/doc/doxygen/classgr_1_1digital_1_1corr__est__cc.html> sounds like it might do what you want. It will correlate against and tag your preamble, and acts as a sync block (it does not remove the preamble from the sample stream). 2. the forecast block for general blocks is a suggestion to the GNU Radio scheduler, and can be tricky to get right for blocks that only sometimes change the number of samples in the stream. If possible, its much simpler/easier to use a block with a constant output:input ratio. 3. Call consume with the number of samples you used in the input (probably len(self.preamble)). The return value of general_work (or the argument to produce()) is the number of samples you generated in output_items (this should be 1 in your block). Cheers, Brent On Sat, Jun 10, 2017 at 7:51 PM, Bakshi, Arjun via USRP-users < usrp-users@lists.ettus.com> wrote: > Hello everyone, > > > I'm trying to build a GRC block in Python for the first time. I want a > preamble detection block. I've read the guided tutorial here: > https://wiki.gnuradio.org/index.php/Guided_Tutorial_GNU_Radio_in_Python , > but am still unclear on what is happening under the hood. > > > I want to use a general/basic block that takes in len(preamble) floats and > returns 1 float (correlation value). My questions are: > > > > 1. What should the input output signature look like? I'm thinking that > I could write the signature as len(preamble):1, or in some M:N format like > 1024:1024-len(preamble)+1. It is currently: > def __init__(self, preamble, th=0.8): > gr.basic_block.__init__(self, > name="pre_detect_ff", > in_sig=[(numpy.float32, > len(preamble))], > out_sig=[numpy.float32]) > > 2. What does the forecast function do? I think it tells gnuradio how > to slice the input stream so that each chunk can be used to generate the > required output. But Its not clear how the slicing is happening. My > forecast function looks like: > def forecast(self, noutput_items, ninput_items_required): > for i in range(len(ninput_items_required)): > ninput_items_required[i] = 1 # setting to > len(self.preamble) gives error, not enough inputs to generate output > # > setting to 1 seems to make it work > > > 3. How do I use consume? I think consume tells gnuradio to move on to > the next chunk of data to process. I'm currently using it as follows in my > general_work function: > def general_work(self, input_items, output_items): > print "called gen work" > for i in range(input_items[0].shape[0]): > result = numpy.corrcoef(input_items[0][i], > self.preamble)[0, 1] > if result > self.th: > result = 1.0 > else: > result = 0.0 > output_items[0][i] = result > # consume(0,1) # gives an error, undefined function, but > this call was added by gr_modtool > self.consume_each(1) # consume 1 data point on all > streams (there is only 1 stream) > > return len(output_items[0]) > > > I'm also having trouble with the QA tests(itemsize mismatch), but that my > be due to bugs in my class code. I'd really appreciate someone answering > these questions, and pointing out bugs in the code. > > > Thank you, > > > Arjun > > > > _______________________________________________ > USRP-users mailing list > USRP-users@lists.ettus.com > http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com > >