ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

Understanding ROS 2 publisher size, subscriber size, and topic size

asked 2023-04-14 08:13:15 -0500

choton gravatar image

(I asked this question in robotics.stackexchange.com but did not received any answer! That is why asking in here with some modifications.) I have the following ROS 2 scripts for a publisher node:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String
import time
class MinimalPublisher(Node):
    def __init__(self):
        super().__init__('minimal_publisher')
        self.publisher_ = self.create_publisher(String, 'topic', 1)
        self.timer1 = self.create_timer(1, self.timer1_callback)
        self.timer2 = self.create_timer(2, self.timer2_callback)
        self.timer3 = self.create_timer(3, self.timer3_callback)
        self.i = 1
        self.j = 1
        self.k = 1
    def timer3_callback(self):
        msg = String()
        msg.data = 'timer3:  %d' % self.k
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.k += 1
    def timer2_callback(self):
        msg = String()
        msg.data = 'timer2: %d' % self.j
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.j += 1
    def timer1_callback(self):
        msg = String()
        msg.data = 'timer1: %d' % self.i
        self.publisher_.publish(msg)
        self.get_logger().info('Publishing: "%s"' % msg.data)
        self.i += 1
        # self.create_rate(4).sleep()

def main(args=None):
    rclpy.init(args=args)
    minimal_publisher = MinimalPublisher()
    time.sleep(2)
    msg = String()
    msg.data = 'Publishing garbage 1'
    minimal_publisher.publisher_.publish(msg)
    msg = String()
    msg.data = 'Publishing garbage 2'
    minimal_publisher.publisher_.publish(msg)
    msg = String()
    msg.data = 'Publishing garbage 3'
    minimal_publisher.publisher_.publish(msg)
    msg = String()
    msg.data = 'Publishing garbage 4'
    minimal_publisher.publisher_.publish(msg)
    msg = String()
    msg.data = 'Publishing garbage 5'
    minimal_publisher.publisher_.publish(msg)
    msg = String()
    msg.data = 'Publishing garbage 6'
    minimal_publisher.publisher_.publish(msg)    
    time.sleep(3)
    # rate = minimal_publisher.create_rate(5)
    # rate.sleep()
    try:
        rclpy.spin(minimal_publisher)
    except KeyboardInterrupt:
        pass    
    # minimal_publisher.destroy_node()
    # rclpy.shutdown()

if __name__ == '__main__':
    main()

I used timer to hold after publishing some garbage messages, and then started spinning using 3 timers. I have a simple subscriber node as follows:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String
import time

class MinimalSubscriber(Node):
    def __init__(self):
        super().__init__('minimal_subscriber')
        self.subscription = self.create_subscription(String,'topic',self.listener_callback, 4)
        self.subscription  # prevent unused variable warning

    def listener_callback(self, msg):
        self.get_logger().info('I heard: "%s"' % msg.data)

def main(args=None):
    rclpy.init(args=args)
    minimal_subscriber = MinimalSubscriber()
    # delay = minimal_subscriber.create_rate(2.5)
    rclpy.spin(minimal_subscriber)

if __name__ == '__main__':
    main()

I used a launch file to run both publisher and subscriber at once. I did some experiments by varying the publisher and subscriber queue size in the above code in order to understand topic size, publisher queue, subscriber queue as follows:

Experiment 1: pub queue size 1, sub queue size 1. Results: Only the 6th garbage message is shown. After that every message is received from all 3 timers (5 garbage messages lost)

Experiment 2: pub queue size 100, sub queue size 1. Results: EXACTLY SAME AS EXPERIMENT 1 (also checked for pub size 10, 5, 6 and results are same)

Experiment 3: pub queue size 1, sub queue size 100. Results: All 6 garbage messages are shown (nothing lost). After that every message is received from ... (more)

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2023-04-14 11:44:35 -0500

shonigmann gravatar image

I only skimmed your question/code since there was a lot to unpack here, so apologies if I'm missing the mark (I'm also definitely not an expert on DDS)...

But it seems like you are using the default QoS (Quality of Service) settings. I think the Durability policy might be relevant to your experiment:

By default, publishers and subscriptions in ROS 2 have “keep last” for history with a queue size of 10, “reliable” for reliability, “volatile” for durability, and “system default” for liveliness. Deadline, lifespan, and lease durations are also all set to “default”.

Volatile durability means the publisher will make no attempt to persist samples for late coming subscribers. You could try changing this (for both the publisher and subscriber) to Transient Localwhich allows the publisher to store old messages in the queue for late coming subscribers. There's more details here that you may find interesting: https://github.com/ros2/ros2/issues/464

Notably, it seems that the publisher queue size in DDS is used to store old messages (if Durability is set to Transient Local) and to support "bursts" of new messages (e.g. if messages are generated faster than they can be sent, the queue should still enable the "new" messages to get sent when possible).

edit flag offensive delete link more

Comments

I only want to understand the default settings for now (will check the other settings later on). Just tell me if the publisher queue size does matter in the default setting or is only the subscriber size is the only one that matters? Moreover, if the size is always 10, then what does the 3rd parameter in create_publisher() and the 4th parameter in create_subscription means? Does it takes as 10 whatever values I put in these two methods?

choton gravatar image choton  ( 2023-04-14 12:42:06 -0500 )edit

Question Tools

3 followers

Stats

Asked: 2023-04-14 08:13:15 -0500

Seen: 336 times

Last updated: Apr 14 '23