discuss-gnuradio
[Top][All Lists]
Advanced

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

Re: [Discuss-gnuradio] How to "kill flowgraph" with a custom block


From: David Kersh
Subject: Re: [Discuss-gnuradio] How to "kill flowgraph" with a custom block
Date: Wed, 4 Jan 2017 13:40:59 +0000

Ah! Thank you so much Marcus! I've managed to transplant this correction into my bigger flow graph and now everything works as intended.

>You're using a hard-coded port of 58 in your server. That probably means you're running GNU Radio as root (because classically, normal users can't bind to sockets <1024). I changed that to 1200.

Yes, that isn't a coincidence but I did not know that users cannot bind to ports <1024 without root. I'll play with that.

 I know this is just an example, but to point this out now: your server source should return the number of items you produced. Right now, you always fill as much buffer as there is, but you probably want to receive your UDP packet into a buffer that's stored within your class, then copy as much content of the UDP packet as fits into the output buffer `out`, and return the number of floats you've copied. Notice that UDP transports bytes, but you produce 4-Byte-floats – make sure you keep at 4B boundaries when copying. If there's less space in the output buffer than you've received via UDP (yes, that can and will happen), you need to store the remainder of that UDP data for the next call to work(). Only if that "leftover buffer" is empty you should do a `recvfrom` to re-fill that buffer.

Yeah I'm pretty confused with how this works to be honest. The serverSource block is literally just to parse a "stop" command, otherwise it should remain dormant, listening for that packet. How would I go about stopping it from writing to the buffer? It's just wasted processing.

The way you're writing your broadcaster seems to be OK.

Excellent :)

If you're writing a network application from scratch, I'd recommend you look into using the ZMQ blocks – ZeroMQ is like sockets done right :) The architecture you'd aim for is a "ZMQ * Message Source" (with * being something like SUB or PULL, see zeromq.org for a tutorial on these types of sockets), which gives you one GNU Radio message per packet you receive. You could then have multiple of these sockets - one for control ("ZMQ * Message Source"), one for stream data ("ZMQ * Source"). The ZMQ blocks have the advantage of being able to pass tags, if you happen to connect two remote flow graphs! And: ZMQ takes care of things like flow control, even in a multi-producer/single-consumer kind of network architecture, so your GNU Radio flow graph could "slow down" whoever is sending samples in case things get congested in GNU Radio due to high load.

I'll definitely investigate this - thank you.

I suppose a final question is, how do I kill the QtGUI thread if I do want a GUI? 

Many thanks,
David

On Wed, Jan 4, 2017 at 12:54 PM, Marcus Müller <address@hidden> wrote:

Dear David,

using your gr-research OOT, I was able to notice the following:

It shuts down just fine!

A few notes:

* You're using the Qt GUI build mode, which gives you a GUI window. That GUI thread then lingers. As soon as you change your build mode to "No GUI"/"Run To Completion" in the options block, it just works as expected for me

* You're using a hard-coded port of 58 in your server. That probably means you're running GNU Radio as root (because classically, normal users can't bind to sockets <1024). I changed that to 1200.

* Your example grc sends the message "STOP", but you check for "stop"... so that doesn't really work.

* I know this is just an example, but to point this out now: your server source should return the number of items you produced. Right now, you always fill as much buffer as there is, but you probably want to receive your UDP packet into a buffer that's stored within your class, then copy as much content of the UDP packet as fits into the output buffer `out`, and return the number of floats you've copied. Notice that UDP transports bytes, but you produce 4-Byte-floats – make sure you keep at 4B boundaries when copying. If there's less space in the output buffer than you've received via UDP (yes, that can and will happen), you need to store the remainder of that UDP data for the next call to work(). Only if that "leftover buffer" is empty you should do a `recvfrom` to re-fill that buffer.

* The way you're writing your broadcaster seems to be OK.

* If you're writing a network application from scratch, I'd recommend you look into using the ZMQ blocks – ZeroMQ is like sockets done right :) The architecture you'd aim for is a "ZMQ * Message Source" (with * being something like SUB or PULL, see zeromq.org for a tutorial on these types of sockets), which gives you one GNU Radio message per packet you receive. You could then have multiple of these sockets - one for control ("ZMQ * Message Source"), one for stream data ("ZMQ * Source"). The ZMQ blocks have the advantage of being able to pass tags, if you happen to connect two remote flow graphs! And: ZMQ takes care of things like flow control, even in a multi-producer/single-consumer kind of network architecture, so your GNU Radio flow graph could "slow down" whoever is sending samples in case things get congested in GNU Radio due to high load.

* Nabble really seems to be making it hard for you to answer on-list. Please simply abandon Nabble, it bears no advantage whatsoever. You use a GMail account – it's really easy to use that to directly subscribe to the mailing list via https://lists.gnu.org/mailman/listinfo/discuss-gnuradio and GMail has excellent  "filter emails like this" functionality that allows you to automatically skip your inbox for mailing list emails that aren't directly part of discussion that involve you and add a mailing list tag.

Best regards,

Marcus

On 01/04/2017 12:03 PM, David Kersh wrote:
Okay, these are what you want.

dkblocks has the udpBroadcast block
research (as in, me messing about) has the udpServer block

Thanks again
David

On Wed, Jan 4, 2017 at 10:51 AM, Marcus Müller <address@hidden> wrote:

The whole directory "gr-davidsmodulename"


On 04.01.2017 11:45, David Kersh wrote:
Hi Marcus,

I made these using the gr_modtool.

I don't know what the "whole module" refers to. You can generate the exact same directory as me by using the gr_modtool I think.

Even if you get my flowgraph running however, you'll need some software to send a "stop" packet to the computer so the flowgraph will attempt to stop. I have some hardware in place which does this for me.

Apologies for the incomplete set of files.

Thank you
David

On Wed, Jan 4, 2017 at 10:40 AM, Marcus Müller <address@hidden> wrote:

Hi David,

did you write these blocks "free-standing" or generated them from with in an OOT with gr_modtool?

Really, I want to locally reproduce your problem, but I'm not overly eager to first manually fiddle your xml files into my system, place the python files in a directory where python looks for them, then note down what I'd have to clean up later, just to be able to run your example. That's why I asked for the *whole* module.

Best regards,
Marcus


On 04.01.2017 11:28, David Kersh wrote:
Hi Marcus,

I've attached the python source for the two blocks I made, their respective .xml files, the .grc file for the flow graph, and the top_block.py

Many thanks,
David

On Wed, Jan 4, 2017 at 10:19 AM, Marcus Müller <address@hidden> wrote:

Can you really share your whole Out-Of-Tree module including an example .grc or python flow graph?


Best regards,

Marcus


On 04.01.2017 10:53, David Kersh wrote:
Hi Marcus,

The 'stop' comparison definitely triggers as the appropriate text is printed to the GRC console.

I think you're right about my UDP broadcaster. I want it to be one of those types of blocks similar to the two default blocks in a flowgraph: Options and Variable. I think the way I've created it is wrong as I essentially just removed the input and output terminals in the .xml file and added arguments for IP address, port and message packet. So actually I plan not to use the inputs and outputs later on, I just don't really know what I'm doing / don't know how to remove the input / output related code from the python file.

Apart, from the two blocks I mentioned earlier and the Options and Variable blocks, the serverSource blocks outputs to the pre-defined Vector Sink block.

Thank you
David



On Wed, Jan 4, 2017 at 12:34 AM, Marcus Müller <address@hidden> wrote:
Hi David,

are you sure the 'stop' comparison ever triggers?

I'm not quite sure your UDP broadcaster /should/ be a GNU Radio block –
it doesn't have any in- or outputs (but I presume you plan to add these
later on).

What's the whole Flow graph you're using?


Best regards,

Marcus

On 03.01.2017 09:53, davidk wrote:
> Dear Marcus, Happy new year!
>
> Here is my UDP Server Block Python Code:
>
> /import numpy
> import socket
> from gnuradio import gr
> from gnuradio import blocks
>
> UDP_IP = "192.168.10.2"
> UDP_PORT = 58
>
> sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>
> class serverSource(gr.sync_block):
>     def __init__(self):
>
> gr.sync_block.__init__(self,name="serverSource",in_sig=None,out_sig=[numpy.float32])
>         print "Setting up server"
>         sock.bind((UDP_IP, UDP_PORT))
>
>     def work(self, input_items, output_items):
>         out = output_items[0]
>         data, addr = sock.recvfrom(1024)
>         packetString = repr(data)
>
>         packetString = packetString.replace('\\x00','')
>         packetString = packetString.replace('\'','')
>
>         print "message received: ", packetString
>         print "address: ", addr
>
>         if packetString == 'stop':
>             return -1
>
>         return len(output_items[0])/
>
> and here is my UDP Broadcast block:
>
> /import numpy
> import socket
> from gnuradio import gr
>
> class udpBroadcast(gr.basic_block):
>     def __init__(self, ip, port, message):
>
> gr.basic_block.__init__(self,name="udpBroadcast",in_sig=[numpy.float32],out_sig=[numpy.float32])
>         print "Setting up UDP Message"
>
>         UDP_IP = ip
>         UDP_PORT = port
>         MESSAGE = message
>
>         sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>         sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))/
>
> Hopefully you can make out what I'm aiming for here.
>
> Many thanks
> David
>
>
>
> --
> View this message in context: http://gnuradio.4.n7.nabble.com/How-to-kill-flowgraph-with-a-custom-block-tp62332p62402.html
> Sent from the GnuRadio mailing list archive at Nabble.com.
>
> _______________________________________________
> Discuss-gnuradio mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio











reply via email to

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