Skip to content

Automatic/adaptive subscription QoS #1868

@emersonknapp

Description

@emersonknapp

Feature request

Feature description

Provide the ability for a subscription to automatically choose a QoS based on detected QoS of publishers in the graph. Most times for the business logic of robot applications, we want to explicitly specify QoS policies to clearly lay out communication behavior requirements.

However, some tooling and infrastructure by design does not care about the exact behavior and just wants to match with publishers no matter what, at as high a level of fidelity/service as possible. Three use cases come to mind up front:

  • rosbag2 - wants to subscribe to all publishers regardless of QoS, to record all traffic possible
  • ros2cli - ros2 topic echo in my view should always start printing messages, if there is a publisher providing them, regardless of QoS mismatch
  • topic_tools - these generic tools like relay, throttle and mux generally want to receive messages from publishers and imitate those publisher's behaviors, with modifications

This feature API might be:

  • A special Subscription subclass AdaptiveQoSSubscription that provides this behavior
  • A SubscriptionOptions value that turns this on
  • A special QoS profile object AdaptiveSubscriptionQoSProfile that acts as a flag to enable the behavior

Behavior considerations:

  • Does subscription continue noticing for new publishers to re-adapt if necessary? Or, does it only adapt to publishers available at subscription time? Probably the former.
  • A subscription could use a "maximally lax"/"minimal strict" QoS profile request such that it matches with all possible publishers, but a more desirable behavior is to get the highest QoS possible - such that if a publisher is reliable with some durabilty, those latched messages are received, and reliable communication is used.
  • When there are multiple publishers on a topic, offering different QoS profiles, that's the most difficult case. rosbag2 uses adaptive logic (see links below) to craft a single QoS request that will match all publishers. This may downgrade the quality of service from one higher-qos publisher to match with a lower-qos one as well. This seems to be the only tradeoff we can make, given that we can't subscribe to a specific publisher individually - but I am open to alternative suggestions.

Implementation considerations

Will need this in both rclpy and rclcpp. Python is necessary to expose to ros2cli and some topic_tools. Given that, maybe this feature belongs in rcl or maybe even in some RMW utility package.

There are two current implementations that I know of for this feature, in rosbag2 and in topic_tools. Using those as a starting point for a "core" implementation makes sense to me.

See https://github.com/ros2/rosbag2/blob/master/rosbag2_transport/src/rosbag2_transport/qos.cpp for rosbag2 logic - those tools used around https://github.com/ros2/rosbag2/blob/master/rosbag2_transport/src/rosbag2_transport/recorder.cpp#L238

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions