ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A

[RMW Proposal] Content Filtered Topic Suport

revive from Content Filtering Topic,

comments here or on PR are always welcome :grin:


Parameter Event Topic

Each node will publish and subscribe parameter events topic (this is configurable via node option). This topic is to support monitoring parameters for change. It is expected that client libraries will implement the ability to register a callback for specific parameter changes using this topic. there is an internal subscription for each node for /parameter_evetns topic to handle the TimeSource via “use_sim_time” parameter. rclcpp::ParameterEventsFilter is used to filter the parameter with specific names such as “use_sim_time”. As user interface, AsyncParametersClient::on_parameter_event is provided to handle parameter events.

there will be all of the parameter activity. That said everyone publishes and subscribes all of the events with this giant topic /parameter_events. This leads to a lot of unnecessary message transmission over the network.

Action Topics

Each action server will provide two topics named feedback and status as followings,

feedback and status are topics each mapped with action name and published by action server, and action clients subscribe those topics to get feedback and status. When there are many goals from many clients, the choice to have a single feedback and status topic per action server is suboptimal in terms of processing and bandwidth resource. It is up to clients to filter out feedback/status messages that are not pertinent to them. In this scenario, M goals are sent to N clients there is an unnecessary use of bandwidth and processing. especially in extreme cases where M and N are large. (each goal is identified by goal ID based on uuid, filtering out the goal id is done by client library so user application does not need to care.)


ContentFilteredTopic describes a more sophisticated subscription that indicates the subscriber does not want to necessarily see all values of each instance published under the Topic. Rather, it wants to see only the values whose contents satisfy certain criteria. This class therefore can be used to request content-based subscriptions.

What’s in it for us?

You can get what you need to receive and that will conserve network resource.

Implementation Consideration

  • ContentFilteredTopic interfaces can be used only if implementation supports.
  • If rmw implementation does not support ContentFilteredTopic interfaces, filtering will be done internally on subscriber side in rcl.
  • It can create/destroy ContentFilteredTopic based on parent topic.
  • It can set/get the filter_expression and expression_parameters for ContentFilteredTopic.
  • Filtering expression and expression parameters can be set and get at runtime.
    • As decribed above, according to DDS specification, it implies that filtering expression may not be able to be changed dynamically. But to support requirements in ROS2, it must support dynamic reconfiguration for filtering expression and paramter.
  • Filtering goal id for action feedback and status will be done ROS2 system.
  • User can specify node name and parameter name to filter the parameter evetns.
  • Filtering expression and parameter grammer will be the same with DDS standard between rcl and rmw.

Design Proposal


Will it actually save network traffic? I thought most DDS implementations use multicast anyways, which would mean the data only go once through the “wire”. It would, of course, make difference if there were many computers on the same network and only some were interested. But in a classic robot-base station config, it wouldn’t help that much in my view.

Multicast is not fully supported by many networks (especially networks more complex than a single unmanaged Ethernet switch or a single fully-integrated router/switch/AP), so often DDS implementations will use a “hybrid” to support dynamic discovery: they might use UDP multicast for the initial phase(s) of discovery, but then they’ll often use unicast by default for later phases, unless specifically configured to use multicast when you know that your network supports it.

If you use wireshark to observe your system, unless you have specifically configured your DDS implementation, I suspect that it will be using unicast for most of the traffic, both the later phases of discovery as well as the actual messages. But again, it’s highly dependent on the DDS implementation’s default choices and/or your specific configuration for your systems.

1 Like

Okay, then it probably makes sense :wink:

Even if using multicast, there will still be duplicated traffic in the final leg of each route. The duplication happens in network infrastructure, such as switches and routers. Multicast is good for the sender but makes no difference to the receivers. So content filtering will be helpful to reduce received traffic, which reduces the burden on subscribers.


This is requested at Middleware WG,

is there an concrete reproducer application that can show the overhead described?

Improvement Result

This result indicates if ContentFilteredTopic provides the improvement for CPU consumption and network traffic as we expect. Using single writer and multiple readers up to 10 with filtering expression and expression parameters.


  • Intel® Core™ i7-7700 CPU @ 3.60GHz / 8GB memory
  • Ubuntu 18.04.5 LTS
  • docker 19.03.6
  • ubuntu:20.04 container
  • ros2:rolling, rti-connext-dds-5.3.1


struct cft {
    long count;
    string flag;  // yes(receive) or no(filter out).
    string cmd;
    long data_size;
    string<8 * 1024 * 1024> data;


flag means how many readers setup with filtering parameter yes. (means that receive will receive the message) no filter means in normal topic w/o content filtering. improvement rate means how much network traffic bytes to be saved compare to no filter mode, below is the formula:


  • Publication Frequency: 10Hz, Data Size: 1KByte, Count: 3000 times
flag cpu memory tx (network load) improvement
1/10 ‘yes’ 0.40% 0.2% 11.49 KByte/s 90%
2/10 ‘yes’ 0.46% 0.2% 22.9 KByte/s 80%
3/10 ‘yes’ 0.48% 0.2% 34.28 KByte/s 70%
4/10 ‘yes’ 0.55% 0.2% 45.69 KByte/s 60%
5/10 ‘yes’ 0.60% 0.2% 57.09 KByte/s 50%
6/10 ‘yes’ 0.69% 0.2% 68.49 KByte/s 40%
7/10 ‘yes’ 0.73% 0.2% 79.89 KByte/s 30%
8/10 ‘yes’ 0.79% 0.2% 91.29 KByte/s 20%
9/10 ‘yes’ 0.84% 0.2% 102.69 KByte/s 10%
10/10 ‘yes’ 0.85% 0.2% 114.09 KByte/s 0%
no filter 0.85% 0.2% 114.05 KByte/s Baseline


The bigger data it handles, the more improvement we can have.