|
From: | Johannes Demel |
Subject: | Re: GNU Radio 3.9.3.0 Python basic block - issues with forecast and produce |
Date: | Sat, 22 Jan 2022 12:25:59 +0100 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.14.0 |
Hi Patric,since your goal is to produce a variable number of output items, your `general_work` approach seems to be the correct one. I mean "variable number of output items" in the sense that there is no fixed relation between the number of input items to the number of output items. Just for reference.
`WORK_CALLED_PRODUCE` is one of those "magic values" that are defined somewhere in the system. I've never personally used it in any block.
It is documented here: https://www.gnuradio.org/doc/doxygen/classgr_1_1block.html The function is found here: https://www.gnuradio.org/doc/doxygen/classgr_1_1block.html#aa5581727d057bdd8113f8b2a3fc5bd66I use `bpython3` to explore Python methods etc. In your case, I expect that `self.WORK_CALLED_PRODUCE` should be available.
BUT: Don't use `produce`! In your case use: `return self.buffer_len`Why? Because the all the buffer pointer updates will be handled after you return from `general_work`. The `produce` method exists for cases where you have multiple output buffers and want to produce different numbers of output items. e.g 5 samples on `output_items[0]` and 25 samples on `output_items[1]`.
In your case, you `return 0` which tells the scheduler that you did not produce any items.
More generally, try to minimize calls to `consume`/`produce`. Keep track of the number of samples your `general_work` consumes and how many samples you've written to your output buffer. At the end of `general_work` report these values to the system:
- consumed items via `consume_each` - produced items via `return integer_with_number_of_consumed_items`.The `forecast` method expects estimates. The scheduler will call `general_work` anyways at some point, if the system is unable to fulfill your forecast requirement. `set_output_multiple` is much more strict.
In your case I'd start with: `ninput_items_required[0] = noutput_items`which might be inefficient. But you can update it with better forecasts later. Talking about efficiency: I'd only worry about efficiency in C++ blocks. Python blocks incur quite a penalty.
Cheers Johannes On 21.01.22 15:14, Patric Müller wrote:
Hello everyone, I am currently trying to create a basic block similar to this issue: https://stackoverflow.com/questions/68289222/gnu-radio-buffer-size Some software and hardware info: GNU Radio version: 3.9.3.0 Python version: 3.9.7 OS: Ubuntu 20.04I always want to work on the same number of items, say 1024. Now I would like to use up all of the items, but I want to produce something between say 500 - 1500 items. For now, I would like to create a simple block with one input and one output, which consumes a set number of items and outputs only a fraction of those incoming items in order to understand it better.Therefore I started with a general block and wanted to change ninput_items_required[0]. However, ninput_items_required is an integer. Trying to directly change this integer values results in:Unable to cast Python instance to C++ type (compile in debug mode for details)My second question is about the produce() function. If it is used, general_work() should returnWORK_CALLED_PRODUCEbut how exactly? After calling produce() and telling the scheduler how many items are produced, can I then change output_items[0]?My attempt at the forecast() function and general_work() is provided below. General suggestions/hints or a basic example would be helpful and immensely appreciated. If additional background is required, let me know and I will gladly provide more information.def forecast(self, noutput_items, ninput_items_required):# Estimate, that we will always need self.buffer_len items on input port [0]ninput_items_required[0] = self.buffer_len def general_work(self, input_items, output_items): # Firstly check, if input_items has a sufficient amount of items if len(input_items[0]) >= self.buffer_len: # Then consume exactly self.buffer_len items on input_port[0] self.consume(0, self.buffer_len)# Now I would like to only output a fraction of the input items# say the first self.out_items, on output port[0] self.produce(0, self.out_items) # Do I set my output_items[0] here? # Now I only need to return WORK_CALLED_PRODUCE, but how exactly? return 0 Kind regards, Patric Müller
[Prev in Thread] | Current Thread | [Next in Thread] |