Difference between revisions of "YAML GRC"

From GNU Radio
Jump to navigation Jump to search
(Added info about input ports in YAML blocks)
(Added "Category" field, including creating subcategories.)
 
(13 intermediate revisions by 9 users not shown)
Line 1: Line 1:
Starting with release 3.8, XML replaces YAML as the file format for GNU Radio Companion. This is triggered by switching from Cheetah to Mako as the templating engine, since Cheetah does not support Python 3. Specifically, this will impact .grc files, block descriptions and block tree files. This article won’t focus on the .grc files, because they aren’t meant for manual editing.
[[Category:3.8]]
Starting with release 3.8, YAML replaces XML as the file format for GNU Radio Companion (for 3.7 see [[XML_GRC|XML GRC]]). This is triggered by switching from Cheetah to Mako as the templating engine, since Cheetah does not support Python 3. Specifically, this will impact .grc files, block descriptions and block tree files. This article won’t focus on the .grc files, because they aren’t meant for manual editing.


The most notable change is of course the absence of XML’s angle brackets in favour of YAML’s colon-separated keys and values, and the change in file names for blocks. The latter is important for GRC to recognise the file. Namely, the “.xml” ending has been replaced with “.block.yml” for block descriptions and the underscore in block tree files has been replaced with a dot. (For example, “qtgui_tree.xml” becomes “qtgui.tree.yml”)
The most notable change is of course the absence of XML’s angle brackets in favour of YAML’s colon-separated keys and values, and the change in file names for blocks. The latter is important for GRC to recognise the file. Namely, the “.xml” ending has been replaced with “.block.yml” for block descriptions and the underscore in block tree files has been replaced with a dot. (For example, “qtgui_tree.xml” becomes “qtgui.tree.yml”)
Line 9: Line 10:
=== ID ===
=== ID ===


<syntaxhighlight lang="python" line="line" highlight="1">
<syntaxhighlight lang="yaml" line="line" highlight="1">
id: blocks_multiply_const_vxx
id: blocks_multiply_const_vxx
label: Multiply Const
label: Multiply Const
Line 23: Line 24:
=== Label ===
=== Label ===


<syntaxhighlight lang="python" line="line" highlight="2">
<syntaxhighlight lang="yaml" line="line" highlight="2">
id: blocks_multiply_const_vxx
id: blocks_multiply_const_vxx
label: Multiply Const
label: Multiply Const
Line 37: Line 38:
=== Flags (optional) ===
=== Flags (optional) ===


<syntaxhighlight lang="python" line="line" highlight="3">
<syntaxhighlight lang="yaml" line="line" highlight="3">
id: blocks_throttle
id: blocks_throttle
label: Throttle
label: Throttle
Line 49: Line 50:


The flags indicate special attributes of the block. The only current example of this is the throttle flag, which is used in the Throttle and hardware blocks. For more information on throttling, see the Guided Tutorial: [https://wiki.gnuradio.org/index.php/Guided_Tutorial_GRC#2.4.3._A_Note_on_the_Throttle_Block]
The flags indicate special attributes of the block. The only current example of this is the throttle flag, which is used in the Throttle and hardware blocks. For more information on throttling, see the Guided Tutorial: [https://wiki.gnuradio.org/index.php/Guided_Tutorial_GRC#2.4.3._A_Note_on_the_Throttle_Block]
=== Category (optional) ===
<syntaxhighlight lang="yaml" line="line" highlight="3">
id: sample_block
label: Sample Block
category: '[Level 1 Category]/Level 2 Category'
parameters:
-  id: type
    label: Type
(...)
</syntaxhighlight>
In the GRC Block Tree Panel, blocks are organized into categories (such as "Core"), which are then organized by further levels of categories. The category field can be used to define how your block will be stored in the Block Tree and allows for better organization.


=== Parameters ===
=== Parameters ===


=== Inputs (optional) ===
<syntaxhighlight lang="yaml" line="line" >
parameters:
-  id: tr_chan
    label: Trigger Channel
    category: Trigger
    dtype: int
    default: '0'
    hide: part
-  id: tr_type
    label: Trigger Type
    category: Trigger
    dtype: enum
    options: [TRIGGER_FREE, TRIGGER_AUTO]
    option_labels: ["Free", "Auto"]
</syntaxhighlight>
 
This part describes the parameters to display to the user. A number of keywords is used there:
; id
: A unique name for the parameter, it is not displayed to the user but can be used to reference the parameter inside this file: ${<id>}
; label
: Human readable name to display to the user.
; dtype
: [[Datatypes|Type]] of the data handled by the parameter
: This can have many values
:; Numbers
:: raw, complex, real, float, int, hex, bool
:; Vectors of numbers
:: complex_vector, real_vector, float_vector, int_vector
:; Strings
:: string, file_open, file_save, _multiline _mutiline_python_external
:; Other special types
:: gui_hint, import, id, stream_id, name and enum


<syntaxhighlight lang="python" line="line" highlight="6-14">
; default
: A default value for the parameter
; category
: Used to organise a large number of parameters. If set, a new tab will be created and named as the value of the keyword with the parameter inside.
; hide
: If the value is part, the parameter only be shown in the properties window.
: If it's all, it will never be shown, even inside the properties window.
: If it's none, it will be shown in both the properties window and on the visual block component.
; base_key
: Inherit properties from another parameter. The value given is the id of that parameter.
 
=== Inputs and Outputs (optional) ===
 
<syntaxhighlight lang="yaml" line="line" highlight="6-14">
id: qtgui_freq_sink_x
id: qtgui_freq_sink_x
(...)
(...)
Line 79: Line 139:
Message ports[https://wiki.gnuradio.org/index.php/Guided_Tutorial_Programming_Topics#5.3_Message_Passing] don't have a specified type here, but they have IDs. This message port can also be hidden, using the "Show message ports" option in the parameters.
Message ports[https://wiki.gnuradio.org/index.php/Guided_Tutorial_Programming_Topics#5.3_Message_Passing] don't have a specified type here, but they have IDs. This message port can also be hidden, using the "Show message ports" option in the parameters.


=== Outputs (optional) ===
 
The output ports work similarly.


=== Asserts (optional) ===
=== Asserts (optional) ===


<syntaxhighlight lang="python" line="line" highlight="5-6">
<syntaxhighlight lang="yaml" line="line" highlight="6-7">
id: blocks_throttle
(...)     
(...)     
     dtype: ${ type }
     dtype: ${ type }
Line 97: Line 159:
</syntaxhighlight>
</syntaxhighlight>


Asserts (previously known as "checks" for the XML blocks) are expressions that ''need'' to be true, otherwise GRC won't let you generate the flowgraph.
Asserts (previously known as "checks" for the XML blocks) are expressions that ''need'' to be true, otherwise GRC won't let you generate the flowgraph. Asserts are Python statements that should eval() to 'True' when correct, wrapped with Mako template designators '${' and '}'.


=== Templates ===
=== Templates ===


==== Imports ====
<syntaxhighlight lang="yaml" line="line" highlight="5-12">
id: blocks_message_strobe_random
(...)
    optional: true
 
templates:
    imports: |-
        from gnuradio import blocks
        import pmt
    make: blocks.message_strobe_random(${msg}, ${dist}, ${mean}, ${std})
    callbacks:
    - set_msg(${msg})
    - set_dist(${dist})
(...)
</syntaxhighlight>
 
The templates describe the code that is created when GRC generates the flowgraph. This part consists of the imports, the make/initialization statements and the callbacks. The values of these keys often happen to span over multiple lines, in which case you're likely to see the "|-" symbols. This is YAML syntax for a literal block scalar[http://yaml.org/spec/current.html#literal%20style/syntax] and the hyphen means that the line break at the end is omitted.
 
 
Your block probably utilizes parts of GNU Radio or other modules that need to be imported. These are specified as ''imports''.


==== Make ====


==== Callbacks ====
''make'' holds the initialization code, and often depends on several of the parameters. Some of the more involved blocks may also use the "%" symbol, denoting the use of a YAML directive[http://yaml.org/spec/current.html#directive/syntax]. This can occur both in ''imports'' and ''make''. The snippet below may be helpful:
 
<syntaxhighlight lang="yaml" line="line" highlight="7-11">
id: rational_resampler_xxx
(...)
    make: |-
        filter.rational_resampler_${type}(
            interpolation=${interp},
            decimation=${decim},
        % if taps:
            taps=${taps},
        % else:
            taps=None,
        % endif
</syntaxhighlight>
 
Please note that the "${}" is not valid syntax in a directive.
 
=== Documentation ===
 
<syntaxhighlight lang="yaml" line="line" highlight="3-4">
id: variable_rrc_filter_taps
(...)
documentation: |-
    This is a convenience wrapper for calling firdes.root_raised_cosine(...).
 
file_format: 1
</syntaxhighlight>
 
''documentation'' simply contains information about the block. This information is displayed in the block's Documentation tab in GRC.


=== File Format ===
=== File Format ===
Specifies the version of the GRC yml format used in the file. Should not be changed.


=== Others ===
=== Others ===
Line 116: Line 226:


== Block Tree Files ==
== Block Tree Files ==
The block tree files are fairly straightforward, and tells GRC how to divide the block tree into categories. The following example snippet from gr-digital (which is part of core GNU Radio) describes two categories, ''Coding'' and ''Equalizers''. The blocks are specified using their ''id''s, which should equal their file names without ".block.yml".
<syntaxhighlight lang="yaml" line="line" >
'[Core]':
- Coding:
  - digital_additive_scrambler_bb
  - digital_descrambler_bb
  - digital_scrambler_bb
- Equalizers:
  - digital_cma_equalizer_cc
  - digital_lms_dd_equalizer_cc
(...)
</syntaxhighlight>

Latest revision as of 22:23, 1 December 2022

Starting with release 3.8, YAML replaces XML as the file format for GNU Radio Companion (for 3.7 see XML GRC). This is triggered by switching from Cheetah to Mako as the templating engine, since Cheetah does not support Python 3. Specifically, this will impact .grc files, block descriptions and block tree files. This article won’t focus on the .grc files, because they aren’t meant for manual editing.

The most notable change is of course the absence of XML’s angle brackets in favour of YAML’s colon-separated keys and values, and the change in file names for blocks. The latter is important for GRC to recognise the file. Namely, the “.xml” ending has been replaced with “.block.yml” for block descriptions and the underscore in block tree files has been replaced with a dot. (For example, “qtgui_tree.xml” becomes “qtgui.tree.yml”)

Block Descriptions[edit]

The content of the block descriptions is still the same, although it has been shuffled around a bit. The parts are elaborated below, in the order they should appear in the files.

ID[edit]

id: blocks_multiply_const_vxx
label: Multiply Const

parameters:
-   id: type
    label: IO Type
(...)

The ID is unique for each block and is used to identify it.

Label[edit]

id: blocks_multiply_const_vxx
label: Multiply Const

parameters:
-   id: type
    label: IO Type
(...)

The label is simply the human-readable name of the block, and will be visible from within GRC. It will not appear in the generated code.

Flags (optional)[edit]

id: blocks_throttle
label: Throttle
flags: throttle

parameters:
-   id: type
    label: Type
(...)

The flags indicate special attributes of the block. The only current example of this is the throttle flag, which is used in the Throttle and hardware blocks. For more information on throttling, see the Guided Tutorial: [1]

Category (optional)[edit]

id: sample_block
label: Sample Block
category: '[Level 1 Category]/Level 2 Category'

parameters:
-   id: type
    label: Type
(...)

In the GRC Block Tree Panel, blocks are organized into categories (such as "Core"), which are then organized by further levels of categories. The category field can be used to define how your block will be stored in the Block Tree and allows for better organization.

Parameters[edit]

parameters:
-   id: tr_chan
    label: Trigger Channel
    category: Trigger
    dtype: int
    default: '0'
    hide: part
-   id: tr_type
    label: Trigger Type
    category: Trigger
    dtype: enum
    options: [TRIGGER_FREE, TRIGGER_AUTO]
    option_labels: ["Free", "Auto"]

This part describes the parameters to display to the user. A number of keywords is used there:

id
A unique name for the parameter, it is not displayed to the user but can be used to reference the parameter inside this file: ${<id>}
label
Human readable name to display to the user.
dtype
Type of the data handled by the parameter
This can have many values
Numbers
raw, complex, real, float, int, hex, bool
Vectors of numbers
complex_vector, real_vector, float_vector, int_vector
Strings
string, file_open, file_save, _multiline _mutiline_python_external
Other special types
gui_hint, import, id, stream_id, name and enum
default
A default value for the parameter
category
Used to organise a large number of parameters. If set, a new tab will be created and named as the value of the keyword with the parameter inside.
hide
If the value is part, the parameter only be shown in the properties window.
If it's all, it will never be shown, even inside the properties window.
If it's none, it will be shown in both the properties window and on the visual block component.
base_key
Inherit properties from another parameter. The value given is the id of that parameter.

Inputs and Outputs (optional)[edit]

id: qtgui_freq_sink_x
(...)
    default: '1.0'
    hide: ${ ('part' if int(nconnections) >= 10 else 'all') }

inputs:
-   domain: stream
    dtype: ${ type.t }
    multiplicity: ${ (0 if (type == 'msg_complex' or type == 'msg_float') else nconnections) }
    optional: true
-   domain: message
    id: freq
    optional: true
    hide: ${ showports }

outputs:
-   domain: message
(...)

This describes the input ports. domain can be either stream or message. Stream ports need a type, which usually is specified as a parameter. This is true for our example, the type is specified in type.t. The multiplicity tells us how many "copies" of this port we want. (Yes, this can be zero!) Finally, the optional flag tells us whether this port must be connected or not. (GRC won't generate the flowgraph if a non-optional port isn't connected)

Message ports[2] don't have a specified type here, but they have IDs. This message port can also be hidden, using the "Show message ports" option in the parameters.


The output ports work similarly.

Asserts (optional)[edit]

id: blocks_throttle
(...)    
    dtype: ${ type }
    vlen: ${ vlen }

asserts:
- ${ vlen > 0 }

templates:
    imports: from gnuradio import blocks
    make: blocks.throttle(${type.size}*${vlen}, ${samples_per_second},${ignoretag})
(...)

Asserts (previously known as "checks" for the XML blocks) are expressions that need to be true, otherwise GRC won't let you generate the flowgraph. Asserts are Python statements that should eval() to 'True' when correct, wrapped with Mako template designators '${' and '}'.

Templates[edit]

id: blocks_message_strobe_random
(...)
    optional: true

templates:
    imports: |-
        from gnuradio import blocks
        import pmt
    make: blocks.message_strobe_random(${msg}, ${dist}, ${mean}, ${std})
    callbacks:
    - set_msg(${msg})
    - set_dist(${dist})
(...)

The templates describe the code that is created when GRC generates the flowgraph. This part consists of the imports, the make/initialization statements and the callbacks. The values of these keys often happen to span over multiple lines, in which case you're likely to see the "|-" symbols. This is YAML syntax for a literal block scalar[3] and the hyphen means that the line break at the end is omitted.


Your block probably utilizes parts of GNU Radio or other modules that need to be imported. These are specified as imports.


make holds the initialization code, and often depends on several of the parameters. Some of the more involved blocks may also use the "%" symbol, denoting the use of a YAML directive[4]. This can occur both in imports and make. The snippet below may be helpful:

id: rational_resampler_xxx
(...)
    make: |-
        filter.rational_resampler_${type}(
            interpolation=${interp},
            decimation=${decim},
        % if taps:
            taps=${taps},
        % else:
            taps=None,
        % endif

Please note that the "${}" is not valid syntax in a directive.

Documentation[edit]

id: variable_rrc_filter_taps
(...)
documentation: |-
    This is a convenience wrapper for calling firdes.root_raised_cosine(...).

file_format: 1

documentation simply contains information about the block. This information is displayed in the block's Documentation tab in GRC.

File Format[edit]

Specifies the version of the GRC yml format used in the file. Should not be changed.

Others[edit]

Variable Make[edit]

Variable Value[edit]

Block Tree Files[edit]

The block tree files are fairly straightforward, and tells GRC how to divide the block tree into categories. The following example snippet from gr-digital (which is part of core GNU Radio) describes two categories, Coding and Equalizers. The blocks are specified using their ids, which should equal their file names without ".block.yml".

'[Core]':
- Coding:
  - digital_additive_scrambler_bb
  - digital_descrambler_bb
  - digital_scrambler_bb
- Equalizers:
  - digital_cma_equalizer_cc
  - digital_lms_dd_equalizer_cc
(...)