discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] sample wise execution of blocks in grc flow graph


From: Martin Braun
Subject: Re: [Discuss-gnuradio] sample wise execution of blocks in grc flow graph?
Date: Thu, 16 Jun 2011 09:37:43 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

On Wed, Jun 15, 2011 at 03:27:18PM -0700, Henry Matt wrote:
> Thanks for the detailed and helpful replies about the sampling rates. Now, I
> have another issue which is unclear to me. I am printing out "noutput_items"
> for my custom block which come out to be either 1 or 2. As I mentioned before,
> the custom block is intended to do sample by sample calculation, i.e., for an
> input sample it calculates the output sample which is then transmitted by the 
> a
> usrp to another usrp which sends a feedback to first usrp; that feedback, 
> after
> some processing goes into the input of the custom block. So, you can imagine
> that  I am kind of running my algorithm iteratively. Now, question is that how
> can I force noutput_items=1? Apparently it seems to me if noutput_items is set
> to 2 then scheduler will wait for the arrival of second input sample to 
> compute
> two output samples at the same time but what I want from scheduler is to
> compute a single output sample, no less and no more. So, if the input to the
> custom block is coming at a rate of 20 samples/sec, how frequent will work() 
> or
> general_work be called? Also, if during a call to work(), noutput_items comes
> out to be "n" (more than 1) then it computes "n" output samples at the same
> time which I do not want. I want to generate 1 sample, send it, wait for the
> feedback, and then after arrival of feedback compute the new output sample 
> from
> custom block and so on. How to do it? Any ideas?

Hi Henry,

some thoughts:

noutput_items is the number of items your block is *expected* to
produce. You can always choose to translate 1 input sample into 1
output sample and then exit the work() function. Simply end your
work() function with 'return 1;'.
(You should be using a gr_sync_block, not a gr_block, for this!)
Something like:
int block::work(...)
{
        const unsigned char *in = &input_items[0];
        unsigned char *out = &output_items[0];

        *in = f(*out); // Where f(x) is what you do
        return 1;
}

Still, I don't think this will help you and actually, I'm not sure you
understood what Colby and John have been trying to say.
GNU Radio does *not* have a concept of time and sampling frequencies.

You make it sound like precisely clocked elements in digital circuitry,
but GNU Radio kind of randomly assigns processor time to each block, you
have no real way to influence *when* it is actually run!
So, to say your block has a sampling rate of x is completely
meaningless for its guts. This is what you need for most kind of signal
processing, anyway.
So, to answer your question: work() or general_work() are called at
random times, whenever the GNU Radio scheduler decides there's enough
stuff in the input buffer of your block. You won't know when. Neither in
sample time, nor in real time.

For this reason, feedback loops are very difficult to implement. A
feedback loop inside a flow graph is not even possible.
Via air, it might be doable--but I don't recommend actually using GNU
Radio for this, at least not at this state of the code.

If you're familiar with real-time programming (i.e. writing code where
instructions get executed at a guaranteed timing) you might even write a
custom application that uses UHD.
If you're not used to doing this, the only other option I can think of
is a pact with the devil: Matlab/Simulink has realtime capabilities and
supports feedback loops.

Good luck,
MB

> 
> 
> Thanks a lot,
> 
> H.
> 
>    
> 
> 
> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
> From: John Andrews <address@hidden>
> 
> 
> 
> On Wed, Jun 15, 2011 at 1:31 AM, Henry Matt <address@hidden> wrote:
> 
> 
>     Hi Colby,
> 
> 
>     So it means that it if one input comes at 20 samples/sec then it limits 
> the
>     output rate of my custom block to exactly 20 samples/sec? That is, the
>     other input, gr_noise_source can provide samples at a rate faster than 20
>     samples/sec to the custom block input but the custom block produces output
>     only when both inputs are available. Am I right?
> 
>  
> 
> Yes, the custom block will execute its general_work() function only when the
> right number of input items are available on all the input streams.
> 
> 
> 
>     I am sorry for not being clear about the other part of question. The
>     question is that if I further multiply the output of the custom block
>     (which has a sample rate of 20 samples/sec) with another signal of 
> sampling
>     rate 2M samples/sec then what will be the sampling rate of the product
>     signal?
> 
> 
> Look at the general_work() function for the simplest of blocks such as
> gr_add_cc etc to understand the behaviour. Look at the following example. In
> this I am producing 1/4th the number of input items I am using. I am sending
> out every 4th input sample to the output, and effectively reducing the 
> sampling
> rate by 4. So as long as the input is available I keep sending every 4th item
> to the output. If the input doesn't arrive then the executing thread waits
> until it has something to work with.
> 
> int
> custom_block_b::general_work(int noutput_items,gr_vector_int &
> ninput_items,gr_vector_const_void_star &input_items,gr_vector_void_star &
> output_items)
> { 
>   const unsigned char *in = (const unsigned char *)input_items[0];
>  unsigned char *out = (unsigned char *)output_items[0];
>  int j=0;
>   for(int i=0;i<noutput_items;i++) {
>       if(i%4==0){
>          out[j] = in[i];
>          j++;
>     }
> 
> The output rate is determined by your work function. In the following code I 
> am
> producing more output than what I am using at the input.
> 
> int
> custom_block_b::general_work(int noutput_items,gr_vector_int &
> ninput_items,gr_vector_const_void_star &input_items,gr_vector_void_star &
> output_items)
> { 
>   const unsigned char *in = (const unsigned char *)input_items[0];
>  unsigned char *out = (unsigned char *)output_items[0];
>  int j=0;
>  int k=0;
>   for(int i=0;i<noutput_items;i++) {
>       if(in[i]==0x00){
>         for (int j=0;j<4;j++){
>            out[k]=in[i] ;
>            k++;
>         }
>        else{
>          for(int j=0;j<4;j++){
>              out[k]=~in[i];
>              k++;
>          }
>       }
>       
>    consume(noutput_items);
>    return k;
> }
> 
> 
> As Colby has already mentioned, you must be careful about having mismatched
> rates.
> 
> I hope this helps.
> 
> 
> 
> 

> _______________________________________________
> Discuss-gnuradio mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio


-- 
Karlsruhe Institute of Technology (KIT)
Communications Engineering Lab (CEL)

Dipl.-Ing. Martin Braun
Research Associate

Kaiserstraße 12
Building 05.01
76131 Karlsruhe

Phone: +49 721 608-43790
Fax: +49 721 608-46071
www.cel.kit.edu

KIT -- University of the State of Baden-Württemberg and
National Laboratory of the Helmholtz Association

Attachment: pgpshOUwSka5b.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]