ros python publisher/subscriber

7.7k views Asked by At

I am trying to subscribe to a 4 different publishers in ROS through python. I use the following code :

def callback(data):
    rospy.loginfo (" Publisher1 Value %s ", custom_msg1.custom_string1)
    rospy.loginfo (" Publisher2 Value %s ", custom_msg2.custom_string2)
    rospy.loginfo (" Publisher3 Value %s ", custom_msg3.custom_string3)
    rospy.loginfo (" Publisher4 Value %s ", custom_msg4.custom_string4)
    rospy.loginfo (" float_publisher value %f ", data.Float64)

def python_code():
    rospy.init_node("python_code")
    rospy.Subscriber("float_publisher",Float64,callback)
    rospy.Subscriber("publisher1", custom_msg1,callback)
    rospy.Subscriber("publisher2", custom_msg2,callback)
    rospy.Subscriber("publisher3", custom_msg3,callback)
    rospy.Subscriber("publisher4", custom_msg4,callback)
    rospy.loginfo(" Test: start spinning!")
    rospy.spin()
    rospy.loginfo("node has shutdown!")

where custom_msg1.msg contains custom_string1 defined as string and in the same way custom_msg2.msg, custom_msg3.msg and custom_msg4.msg

I want know whether I have used the float message and also the custom messages correctly. Output is as follows:

Publisher1 Value <member 'custom_string1' of 'custom_msg1' objects>
Publisher2 Value <member 'custom_string2' of 'custom_msg2' objects>
Publisher3 Value <member 'custom_string3' of 'custom_msg3' objects>
Publisher4 Value <member 'custom_string4' of 'custom_msg4' objects>

Ending with an error:

rospy.loginfo (" float_publisher value %f ", data.Float64)
AttributeError: 'Custom_msg4' object has no attribute 'Float64'

I don't know what is going wrong here

2

There are 2 answers

0
TheSkydivingRobot On BEST ANSWER

If you want to subscribe to five different topics with five different message types the best way to do it is to use five different callback functions, e.g.:

  • one for publisher1 that publishes custom_msg1
  • publisher2 that publishes custom_msg2
  • publisher3 that publishes custom_msg3
  • publisher4 that publishes custom_msg4
  • and one for float_publisher that publishes float64 messages.

In the call back function the parameter data is basically a structure that has all of the components that are declared in the message header. The error that you are getting is because the call back function is being called with data of type custom_msg4 and it is looking for a component called Float64 in it.

def callback1(data):
    rospy.loginfo (" Publisher1 Value %s ", data.custom_string1)

def callback2(data):
    rospy.loginfo (" Publisher2 Value %s ", data.custom_string2)
    
def callback3(data):
    rospy.loginfo (" Publisher3 Value %s ", data.custom_string3)

def callback4(data):
    rospy.loginfo (" Publisher4 Value %s ", data.custom_string4)

def callback5(data):
    rospy.loginfo (" float_publisher value %f ", data.Float64)

def python_code():
    rospy.init_node("python_code")
    rospy.Subscriber("float_publisher",Float64,callback5)
    rospy.Subscriber("publisher1", custom_msg1,callback1)
    rospy.Subscriber("publisher2", custom_msg2,callback2)
    rospy.Subscriber("publisher3", custom_msg3,callback3)
    rospy.Subscriber("publisher4", custom_msg4,callback4)
    rospy.loginfo(" Test: start spinning!")
    rospy.spin()
    rospy.loginfo("node has shutdown!")
0
Odedy On

If you wish to use one function you will have to use an if else to

distinguish between the different subscribers.

def callback(data,who):
    if who == 5:
      rospy.loginfo (" float_publisher value %f ", data.data)
    else:
      rospy.loginfo (" Publisher%d Value %s ",who, data.data)


def python_code():
    rospy.init_node("python_code")
    rospy.Subscriber("float_publisher",Float64,callback,5)
    rospy.Subscriber("publisher1", String,callback,1)
    rospy.Subscriber("publisher2", String,callback,2)
    rospy.Subscriber("publisher3", String,callback,3)
    rospy.Subscriber("publisher4", String,callback,4)
    rospy.loginfo(" Test: start spinning!")
    rospy.spin()
    rospy.loginfo("node has shutdown!")