Embedded Python Block: Difference between revisions
(added another example) |
(added instructions for setting default editor) |
||
Line 45: | Line 45: | ||
** select <q>Open in Editor</q> | ** select <q>Open in Editor</q> | ||
** select <q>Use Default</q> or <q>Choose Editor</q> | ** select <q>Use Default</q> or <q>Choose Editor</q> | ||
** For some platforms the <q>Use Default</q> button may do nothing | ** For some platforms the <q>Use Default</q> button may do nothing; see below. | ||
** if you select <q>Choose Editor</q>, the /usr/bin folder will open for you to pick one. | ** if you select <q>Choose Editor</q>, the /usr/bin folder will open for you to pick one. | ||
** When you have finished editing, save the file (usually Ctrl-S). | ** When you have finished editing, save the file (usually Ctrl-S). | ||
Line 51: | Line 51: | ||
** If there are any syntax errors, they are shown in the <q>Properties</q> window. | ** If there are any syntax errors, they are shown in the <q>Properties</q> window. | ||
** select <q>OK</q>. It is not necessary to select <q>Apply</q>. | ** select <q>OK</q>. It is not necessary to select <q>Apply</q>. | ||
* to change the default editor (works for Debian): | |||
** open File Manager | |||
** single right click a file of type .py | |||
** left click on 'Properties' | |||
** click on the pull down for 'Open with:' | |||
** click on the editor of your choice | |||
** click OK | |||
<p><b>Important:</b> It is highly recommended that any flowgraph using an Embedded Python Block be placed in a separate directory (folder); particularly so if more than one Embedded Python Block is used in the same directory. This is because the generation process creates a file <q>epy_block_0.py</q> from that flowgraph. If you generate a different flowgraph in the same directory, its Embedded Python Block will overwrite the file.</p> | <p><b>Important:</b> It is highly recommended that any flowgraph using an Embedded Python Block be placed in a separate directory (folder); particularly so if more than one Embedded Python Block is used in the same directory. This is because the generation process creates a file <q>epy_block_0.py</q> from that flowgraph. If you generate a different flowgraph in the same directory, its Embedded Python Block will overwrite the file.</p> | ||
<p><b>Warning:</b> To make changes to the Python code, you <u>must</u> follow the steps above. If you edit the <q>epy_block_0.py</q> file directly and then generate the flowgraph again, your changes will be wiped out! (The most recent edited code is actually stored in the .grc file.)</p> | <p><b>Warning:</b> To make changes to the Python code, you <u>must</u> follow the steps above. If you edit the <q>epy_block_0.py</q> file directly and then generate the flowgraph again, your changes will be wiped out! (The most recent edited code is actually stored in the .grc file.)</p> |
Revision as of 13:30, 19 October 2019
Allows you to create a new (custom) block in Python without needing to make and install an Out of Tree Module (OOT). When you add the block to your flowgraph, the pre-populated code simply takes the input stream and multiplies it by a constant. Note that the structure of this Python block matches the structure of an Out of Tree Module (OOT) Python block. It's essentially a Python OOT block built into a grc flowgraph.
Initial code in the Python block
Here is the pre-populated code:
""" Embedded Python Blocks: Each time this file is saved, GRC will instantiate the first class it finds to get ports and parameters of your block. The arguments to __init__ will be the parameters. All of them are required to have default values! """ 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""" def __init__(self, example_param=1.0): # only default arguments here """arguments to this function show up as parameters in GRC""" gr.sync_block.__init__( self, name='Embedded Python Block', # will show up in GRC in_sig=[np.complex64], out_sig=[np.complex64] ) # 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): """example: multiply with constant""" output_items[0][:] = input_items[0] * self.example_param return len(output_items[0])
User notes
- To revise the Python code:
- right click on the Embedded Python block
- select
Properties
- select
Open in Editor
- select
Use Default
orChoose Editor
- For some platforms the
Use Default
button may do nothing; see below. - if you select
Choose Editor
, the /usr/bin folder will open for you to pick one. - When you have finished editing, save the file (usually Ctrl-S).
- close the edit window.
- If there are any syntax errors, they are shown in the
Properties
window. - select
OK
. It is not necessary to selectApply
.
- to change the default editor (works for Debian):
- open File Manager
- single right click a file of type .py
- left click on 'Properties'
- click on the pull down for 'Open with:'
- click on the editor of your choice
- click OK
Important: It is highly recommended that any flowgraph using an Embedded Python Block be placed in a separate directory (folder); particularly so if more than one Embedded Python Block is used in the same directory. This is because the generation process creates a file epy_block_0.py
from that flowgraph. If you generate a different flowgraph in the same directory, its Embedded Python Block will overwrite the file.
Warning: To make changes to the Python code, you must follow the steps above. If you edit the epy_block_0.py
file directly and then generate the flowgraph again, your changes will be wiped out! (The most recent edited code is actually stored in the .grc file.)
Parameters
The parameters for this block are simply those of your embedded Python block itself.
Note that every parameter needs a default value. For example, in the code above, note line:
def __init__(self, example_param=1.0): # only default arguments here
If you don't have any parameters, change that line of code to
def __init__(self):
If you have a vector length equal to a variable of your block, note that the default value must be "hardcoded".
Example Flowgraph
This flowgraph shows how an Embedded Python Block can be used to convert a string from a Message Edit Box to a byte string for the output port. The text is sent through a Throttle to a Text Sink, which is an OOT module. See gr-display.
This is the epy_block_0.py code:
""" Embedded Python Block demo """ # epy_block_0.py # created 10/17/2019 import numpy as np from gnuradio import gr import pmt textboxValue = "" class my_sync_block(gr.sync_block): """ reads input from a message port outputs text """ def __init__(self): gr.sync_block.__init__(self, name = "Embedded Python demo", in_sig = None, out_sig = [np.byte]) self.message_port_register_in(pmt.intern('msg_in')) self.message_port_register_out(pmt.intern('clear_input')) self.set_msg_handler(pmt.intern('msg_in'), self.handle_msg) def handle_msg(self, msg): global textboxValue textboxValue = pmt.symbol_to_string (msg) # print (textboxValue) def work(self, input_items, output_items): global textboxValue # get length of string _len = len(textboxValue) if (_len > 0): # terminate with LF textboxValue += "\n" _len += 1 # store elements in output array for x in range(_len): output_items[0][x] = ord(textboxValue[x]) textboxValue = "" self.message_port_pub(pmt.intern('clear_input'), pmt.intern('')) return (_len) else: return (0)
Another example can be found in https://github.com/duggabe/gr-morse-code-gen