rospython-classrospy

ROS (Robot Operating System) simple publisher and subscriber using class in python


I am trying to run a simple code in ROS to create a subscriber and a publisher using classes in python. I am new to using classes in python and I am not sure what I am doing wrong here.

Below is the code that I have used.

#!/usr/bin/python3

import rospy
from std_msgs.msg import String

class Publisher:
    def __init__(self):
        rospy.init_node('command_publisher', anonymous=True)
        self.pub = rospy.Publisher('command', String, queue_size=10)
        self.rate = rospy.Rate(1)
        while not rospy.is_shutdown():
            command = f"Time is {rospy.get_time()}"
            rospy.loginfo(command)
            self.pub.publish(command)
            self.rate.sleep()
        
class Subscriber:
    def __init__(self):
        rospy.init_node('command_subscriber', anonymous=True)
        rospy.Subscriber('command', String, self.callback)
        rospy.spin()

    def callback(self, data):
        rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)


def main():
    pub = Publisher()
    sub = Subscriber()

if __name__ == "__main__":
    main()

In my code I am able to get the Publisher node to publish into the command topic but I am not able to get the Subscriber to subscribe to the topic. When I do rostopic info /command I cannot see a subscriber but I can see a publisher in there. This is the output of rostopic info /command Type: std_msgs/String

Publishers: 
 * /command_publisher_4479_1703971492925 (http://ra-pi:37657/)

Subscribers: None

Solution

  • Your Publisher is blocking the initiation of your Subscriber with the while in the constructor.
    sub = Subscriber() in your main will never be called.

    What you need is an executor to spin multiple nodes from the same function (main in your case)
    See "How multiple run ros.init_node () in one python script?" or "rospyOverviewInitialization and Shutdown"

    Alternatively you could use multiple separate executables.