Exchange Data with ROS Publishers and Subscribers
The primary mechanism for ROS nodes to exchange data is sending and receiving messages. Messages are transmitted on a topic, and each topic has a unique name in the ROS network. If a node wants to share information, it uses a publisher to send data to a topic. A node that wants to receive that information uses a subscriber to that same topic. Besides its unique name, each topic also has a message type, which determines the types of messages that are capable of being transmitted under that topic.
This publisher and subscriber communication has the following characteristics:
Topics are used for many-to-many communication. Many publishers can send messages to the same topic and many subscribers can receive them.
Publishers and subscribers are decoupled through topics and can be created and destroyed in any order. A message can be published to a topic even if there are no active subscribers.
The concept of topics, publishers, and subscribers is illustrated in the figure:
This example shows how to publish and subscribe to topics in a ROS network. It also shows how to:
Wait until a new message is received
Use callbacks to process new messages in the background
Subscribe and Wait for Messages
Start the ROS master in MATLAB® using the
Launching ROS Core... Done in 0.4251 seconds. Initializing ROS master on http://172.29.200.150:56911. Initializing global node /matlab_global_node_44033 with NodeURI http://dcc396515glnxa64:46047/ and MasterURI http://localhost:56911.
Create a sample ROS network with several publishers and subscribers using the provided helper function
list to see which topics are available.
/pose /rosout /scan /tf
rostopic info to check if any nodes are publishing to the
/scan topic. The command below shows that
node_3 is publishing to it.
rostopic info /scan
Type: sensor_msgs/LaserScan Publishers: * /node_3 (http://dcc396515glnxa64:35087/) Subscribers: * /node_1 (http://dcc396515glnxa64:34719/) * /node_2 (http://dcc396515glnxa64:38927/)
rossubscriber to subscribe to the
/scan topic. If the topic already exists in the ROS network (as is the case here),
rossubscriber detects its message type automatically, so you do not need to specify it. Use messages in struct format for better efficiency.
laser = rossubscriber("/scan","DataFormat","struct"); pause(2)
receive to wait for a new message. (The second argument is a time-out in seconds.) The output
scandata contains the received message data.
scandata = receive(laser,10)
scandata = struct with fields: MessageType: 'sensor_msgs/LaserScan' Header: [1x1 struct] AngleMin: -0.5467 AngleMax: 0.5467 AngleIncrement: 0.0017 TimeIncrement: 0 ScanTime: 0.0330 RangeMin: 0.4500 RangeMax: 10 Ranges: [640x1 single] Intensities: 
Some message types have visualizers associated with them. For the LaserScan message,
rosPlot plots the scan data. The
MaximumRange name-value pair specifies the maximum plot range.
Subscribe Using Callback Functions
Instead of using
receive to get data, you can specify a function to be called when a new message is received. This allows other MATLAB code to execute while the subscriber is waiting for new messages. Callbacks are essential if you want to use multiple subscribers.
Subscribe to the
/pose topic, using the callback function
robotpose = rossubscriber("/pose",@exampleHelperROSPoseCallback,"DataFormat","struct")
robotpose = Subscriber with properties: TopicName: '/pose' LatestMessage:  MessageType: 'geometry_msgs/Twist' BufferSize: 1 NewMessageFcn: @exampleHelperROSPoseCallback DataFormat: 'struct'
One way of sharing data between your main workspace and the callback function is to use global variables. Define two global variables
global pos global orient
The global variables
orient are assigned in the
exampleHelperROSPoseCallback function when new message data is received on the
Wait for a few seconds to make sure that the subscriber can receive messages. The most current position and orientation data will always be stored in the
pos = 1×3 -0.0133 0.0488 -0.0462
orient = 1×3 0.0385 0.0413 0.0296
If you type in
orient a few times in the command line, you can see that the values are continuously updated.
Stop the pose subscriber by clearing the subscriber variable
Note: There are other ways to extract information from callback functions besides using globals. For example, you can pass a handle object as additional argument to the callback function. See the Create Callbacks for Graphics Objects documentation for more information about defining callback functions.
Create a publisher that sends ROS string messages to the
/chatter topic (see Work with Basic ROS Messages).
chatterpub = rospublisher("/chatter","std_msgs/String","DataFormat","struct")
chatterpub = Publisher with properties: TopicName: '/chatter' NumSubscribers: 0 IsLatching: 1 MessageType: 'std_msgs/String' DataFormat: 'struct'
pause(2) % Wait to ensure publisher is registered
Create and populate a ROS message to send to the
chattermsg = rosmessage(chatterpub); chattermsg.Data = 'hello world'
chattermsg = struct with fields: MessageType: 'std_msgs/String' Data: 'hello world'
rostopic list to verify that the
/chatter topic is available in the ROS network.
/chatter /pose /rosout /scan /tf
Define a subscriber for the
exampleHelperROSChatterCallback is called when a new message is received and displays the string content in the message.
chattersub = rossubscriber("/chatter",@exampleHelperROSChatterCallback,"DataFormat","struct")
chattersub = Subscriber with properties: TopicName: '/chatter' LatestMessage:  MessageType: 'std_msgs/String' BufferSize: 1 NewMessageFcn: @exampleHelperROSChatterCallback DataFormat: 'struct'
Publish a message to the
/chatter topic. The string is displayed by the subscriber callback.
ans = 'hello world'
exampleHelperROSChatterCallback function was called as soon as you published the string message.
Shut Down ROS Network
Remove the sample nodes, publishers, and subscribers from the ROS network. Clear the global variables
exampleHelperROSShutDownSampleNetwork clear global pos orient
Shut down the ROS master and delete the global node.
Shutting down global node /matlab_global_node_44033 with NodeURI http://dcc396515glnxa64:46047/ and MasterURI http://localhost:56911. Shutting down ROS master on http://172.29.200.150:56911.