GR4 tutorial: tags

From GNU Radio
Jump to navigation Jump to search

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 a map which is a gr::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 the std::map. In comparison, a GNU Radio 4.0 tag has an absolute offset, a key and a single value, both of which are pmt::pmt_ts, and a srcid (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_maps.
  • 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 to processBulk(). 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;