How to get all topics ready for publishing before anything else!

Here is an example of how to get all your topics ready so that whenever you publish into them they will work once.

class RobotControl(object):

    def __init__(self):

        # create publishers
        # Use a queue size that works. See Reference 2 below.
        self.pub_cmd_vel = rospy.Publisher("/cmd_vel", Twist, queue_size=10)
        self.pub_take_off = rospy.Publisher("/drone/takeoff", Empty, queue_size=10)
        self.pub_land = rospy.Publisher("/drone/land", Empty, queue_size=10)

        # These are the topic you intend to get ready before anything else!
        self.pub_list = [self.pub_cmd_vel, self.pub_take_off, self.pub_land]

        # create messages to publish
        self.move = Twist()
        self.takeoff = Empty()
        self.land = Empty()

        # only if you need it. See Reference 3 below.
        self.rate = rospy.Rate(10)  

        # now get all the topics ready
        self.connect_to_all_topics()

    def connect_to_all_topics(self):
        # Wait for all topics to be ready. See Referece 1.
        for i in self.pub_list:
            while i.get_num_connections() < 1:
                rospy.loginfo("Connecting to all topics...")

        rospy.loginfo("Connected to all topics!")

References:

  1. How to publish once (only one message) into a topic and get it to work - #5
  2. ROS Publishers - what is queue_size and why is it important?
  3. Proper use of rospy.Rate or ros::Rate
2 Likes

Iā€™m not able edit the original post.
I later realised the proper use of rospy.Rate(), and found it not needed for this purpose. I would recommend the following changes to the post:

import time

class RobotControl(object):

    def __init__(self):

        # create publishers
        # Use a queue size that works. See Reference 2 below.
        self.pub_cmd_vel = rospy.Publisher("/cmd_vel", Twist, queue_size=1)
        self.pub_take_off = rospy.Publisher("/drone/takeoff", Empty, queue_size=1)
        self.pub_land = rospy.Publisher("/drone/land", Empty, queue_size=1)

        # These are the topic you intend to get ready before anything else!
        self.pub_list = [self.pub_cmd_vel, self.pub_take_off, self.pub_land]

        # create messages to publish
        self.move = Twist()
        self.takeoff = Empty()
        self.land = Empty()

        # now get all the topics ready
        self.connect_to_all_topics()

    def connect_to_all_topics(self):
        # give ROS a second to establish the publishers
        time.sleep(1)
        # Wait for all topics to be ready. See Referece 1.
        for topic in self.pub_list:
            while topic.get_num_connections() < 1:
                rospy.loginfo("Connecting to all topics...")

        rospy.loginfo("Connected to all topics!")
1 Like