mqtt_client icon indicating copy to clipboard operation
mqtt_client copied to clipboard

ROS2 Reliable QoS Support

Open MazFed opened this issue 1 year ago • 7 comments

Hello,

I'm trying to use the mqtt_client to subscribe to ROS2 topics with QoS of type RELIABLE, VOLATILE but i get the error of incompatible QoS:

[mqtt_client-1] [WARN] [1704882384.623365432] [mqtt_client]: New publisher discovered on topic '/laser/data', offering incompatible QoS. No messages will be sent to it. Last incompatible policy: RELIABILITY_QOS_POLICY

I saw in the documentation that it is possible to change the QoS of MQTT topics. Is it possible to do the same thing for ROS2 topics as well?

MazFed avatar Jan 10 '24 11:01 MazFed

Currently, the mqtt_client doesn't give precise control over the QoS settings of publishers and subscribers. This is most likely due to coming from ROS 1, where one only had to specify a queue_size.

Note that the queue_size is still configurable in the ROS 2 version as well:

Subscription

ros2mqtt.ros.subscriber = create_generic_subscription(
          ros_topic, msg_type, ros2mqtt.ros.queue_size, bound_callback_func);

Publisher

mqtt2ros.ros.publisher = create_generic_publisher(
        mqtt2ros.ros.topic, ros_msg_type, mqtt2ros.ros.queue_size);

These functions actually require to pass an rclcpp::QoS object (doc), but I belive that passing an integer implicitly uses a special rclcpp::QoS constructor that only sets history_depth (doc).

I guess it would make sense to add more configuration options to mqtt_client to make the QoS profile fully configurable. Please feel free to work on that, I'd be happy to merge a PR! Unfortunately, I will not have time for this anytime soon, but could still assist with suggestions on how to implement.

lreiher avatar Jan 17 '24 11:01 lreiher

Hi @lreiher, thanks for the explanation. Indeed when an integer is passed, it is used to set history_depth of QoS object with "transient local" durability and "reliable" reliability. For my test configuration i only need to serialize topics that have "best effort" reliability. So for now i just made a temporary modification replacing the QoS object passed to the create_generic_subscription function to one compatible, like this:

rclcpp::QoS m_qosBestEffort = rclcpp::QoS(ros2mqtt.ros.queue_size)
    .reliability(RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT);

ros2mqtt.ros.subscriber = create_generic_subscription(
    ros_topic, msg_type, m_qosBestEffort, bound_callback_func);

I noticed that this also guarantees me compatibility with the "reliable" topics, although I suppose it doesn't guarantee me reliability. In case I need to use mixed types of QoS, I will try to make a more complete and elegant implementation to submit.

MazFed avatar Jan 25 '24 08:01 MazFed

I think it make sense to have explicit QoS support for the mqtt->ros converison, but for the ros -> mqtt conversion since the subscribers are created lazily, isn't it as simple as doing: get_publisher_info_by_topic instead of get_topic_names_and_types and then using the QoS matching the publisher?

JayHerpin avatar Apr 16 '24 20:04 JayHerpin

at the risk of hijacking, I am working on a patch locally that adds configuration like this:

mqtt2ros:
 ...
   my/mqtt/topic:
          ros_topic: /my/ros/topic
          ros_type: std_msgs/msg/Bool
          advanced:
            ros:
               queue_size: 1
               qos:
                  reliability: reliable
                  durability: transient_local

its not just setting the QoS, its being explicit with the ros message type creation (explicitly about the mqtt->ros direction)

But I am not sure that doing something similar in the other direction is really useful since it seems fine to me to just wait until we see a publisher and get the type and qos information from them.

JayHerpin avatar Apr 16 '24 20:04 JayHerpin

Cool that you are working on flexibly defining QoS!

For the ros-to-mqtt connections, how about also offering the flexible configuration, but also allowing to the QoS parameters to auto? In the auto case you would simply infer the information from the publisher.

lreiher avatar Apr 18 '24 08:04 lreiher

sure, I could do that. I did implement that auto qos fix I suggested and it does work. I don't mind adding in the explicit for that direction flow direction as well.

JayHerpin avatar Apr 18 '24 16:04 JayHerpin

Sounds great, looking forward to a PR!

lreiher avatar Apr 18 '24 19:04 lreiher