GR4 tutorial: tags
This tutorial explains how to use tags in GNU Radio 4.0 blocks. There are the following main differences regarding tags in GNU Radio 4.0, compared to GNU Radio 3.10:
- A GNU Radio 4.0 tag has a relative
index
and amap
which is agr::property_map = std::map<std::string, pmtv::pmt>
. This means that a single tag can hold multiple pieces of data, each with a different key in thestd::map
. In comparison, a GNU Radio 4.0 tag has an absoluteoffset
, a key and a singlevalue
, both of which arepmt::pmt_t
s, and asrcid
(which is rarely used).
- Generally speaking, in GNU Radio 4.0 an item (sample) can only hold at most one tag. Tags that go into the same item are merged by the runtime by merging the two corresponding
gr::property_map
s.
- In GNU Radio 4.0, calls to
processBulk()
depend on tags. In general, the input spans to process bulk will be chunked in such a way that if there is a tag, it will always be in the first item in the input span given toprocessBulk()
. In GNU Radio 3.10, tags may be present at any location within the buffers given to the work function.
- In GNU Radio 4.0 tags are used to update block parameters at runtime. If a block receives a tag that has a key in the
gr::property_map
that matches the name of a block parameter, the block will automatically update the parameter with the value corresponding to that key. In GNU Radio 3.10 this functionality needs to be implemented manually whenever it is needed.
A block can add a tag to an item in its output stream by calling the publishTag()
method of the output port. The arguments of this function are the gr::property_map
for the tag, and an index relative to the current output span. For instance, the following will add a tag to the first output sample published by the current processBulk()
call.
const gr::property_map tag = { { "foo", "bar" } };
out.publishTag(tag, 0);
To process input tags, a block can check whether there is a tag in the first input item by calling this->input_tags_present()
. If this function returns true
, it can then call this->mergedInputTag()
, which returns the tag, as a gr::Tag
object. For instance, the following code snippet can be used to modify all the input tags by adding an additional key before sending them to the output.
if (this->input_tags_present()) {
auto tag = this->mergedInputTag();
tag.map["my_key"] = pmtv::pmt_null(); // or any other value as a PMT
out.publishTag(tag.map); // the default index for publishTag is zero
}
As in GNU Radio 3.10, in GNU Radio 4.0 there are different tag propagation policies. The tag propagation policy is declared as a constexpr static gr::TagPropagationPolicy tag_policy
member in the block class. For instance, blocks that implement their own tag handling should generally use
constexpr static gr::TagPropagationPolicy tag_policy = gr::TagPropagationPolicy::TPP_CUSTOM;