## page was copied from ROS/Tutorials/CustomMessagePublisherSubscriber(python) ## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## links to any required tutorials ## note.0= [[ROS/Tutorials/WritingPublisherSubscriber(python)|Writing a Simple Publisher and Subscriber (Python)]] ## descriptive title for the tutorial ## title = Writing a Publisher and Subscriber with a Custom Message(Python) ## multi-line description to be displayed in search ## description = This tutorial covers how to write a publisher and subscriber using a custom message in python. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= ## next.1.link= ## what level user is this tutorial for ## level= IntermediateCategory ## keywords = custom message, publisher, subscriber, python #################################### <<IncludeCSTemplate(TutorialCSHeaderTemplate)>> <<TableOfContents(4)>> == Writing the Custom Message == Before proceeding, a custom message should be defined following the [[ROS/Tutorials/CreatingMsgAndSrv#Creating_a_msg|Creating A Message]] tutorial. The message used in this tutorial will be named Person.msg and have the following structure: {{{ #!block=message string name int32 age }}} == Writing the Publisher == Change directory the package that you wrote the custom message for. In this tutorial, the beginner_tutorials package will be used. {{{ $ roscd beginner_tutorials }}} === The Code === Inside the scripts folder of the beginner_tutorials package, lets create a file custom_talker.py: {{{ #!python block=publisher #!/usr/bin/env python import rospy from beginner_tutorials.msg import Person def talker(): pub = rospy.Publisher('custom_chatter', Person) rospy.init_node('custom_talker', anonymous=True) r = rospy.Rate(10) #10hz msg = Person() msg.name = "ROS User" msg.age = 4 while not rospy.is_shutdown(): rospy.loginfo(msg) pub.publish(msg) r.sleep() if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass }}} Don't forget to make the node executable: {{{ $ chmod +x custom_talker.py }}} === The Code Explained === Now, lets look at how this code differs from the code created in the simple publisher. <<CodeRef(publisher,3,3)>> If you recall, in the simple publisher, this line was: {{{ #!python from std_msgs.msg import String }}} We have simply changed the package from {{{std_msgs}}} to {{{beginner_tutorials}}} and changed name of the message that's imported from {{{String}}} to {{{Person}}} <<CodeRef(publisher,6,6)>> This line is very similar to the simple publisher version: {{{ #!python pub = rospy.Publisher('chatter', String) }}} However, there are two changes. First, we changed the name of the topic from {{{chatter}}} to {{{custom_chatter}}}. This change was made so we don't publish two different message types to the same topic. Second, we changed the specified message type from {{{String}}} to our custom message {{{Person}}}. <<CodeRef(publisher,9,9)>> This line assigns our variable to message object that we imported. <<CodeRef(publisher,10,11)>> These lines change the attributes of our message. If we recall the format of our message: <<CodeRef(message,1,2)>> It contains the name and the age field. These fields are now accessible as attributes to our message == Writing the Subscriber == === The Code === Back in the scripts directory: {{{ roscd beginner_tutorials/scripts }}} Lets create a file called custom_listener.py: {{{ #!python block=subscriber #!/usr/bin/env python import rospy from beginner_tutorials.msg import Person def callback(data): rospy.loginfo("%s is age: %d" % (data.name, data.age)) def listener(): rospy.init_node('custom_listener', anonymous=True) rospy.Subscriber("custom_chatter", Person, callback) # spin() simply keeps python from exiting until this node is stopped rospy.spin() if __name__ == '__main__': listener() }}} Don't forget to make the node executable: {{{ $ chmod +x custom_listener.py }}} === The Code Explained === <<CodeRef(subscriber,3,3)>> Again, we need to import the message type so that we can use it. <<CodeRef(subscriber,5,6)>> The message is given to this function by the variable that's passed in. In this case, {{{data}}}. As you can see in the loginfo() statement, we can access the attributes of the message as we would access the attributes of any type of object. == Building your nodes == Remember, in order for your messages to be generated, you must build your node. Go to your catkin_workspace and run catkin_make: {{{ $ cd ~/catkin_ws $ catkin_make }}} ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE