ROS Concept Part 2
Visualize ROS graph using rqt_graph
• When
unchecked
Debug
• There is one
node </rosout>
• run rosnode list
• Can see two
nodes:
</rosout>
</rqt_gui_py_node_4086>
Run the
cpp
node
Refresh
the rqt
graph
Unchecked Debug
- Debug will
always show
“other
stuff”(explain
later)
Only the cpp node
is shown
• Run the python
code
• Refresh rqt graph
to see 2 nodes
• But the 2 nodes
are not
communicating
with each other
Testing Nodes using TurtleSim
• Kill cpp and python codes (from earlier)
• Install turtlesim package
• Checkpoint!
• Run the package turtlesim using the command rosrun
• turtlesim is the name of the node
• turtlesim node can call many executables, such as draw_square,
mimic, turtlesim_node and turtle_teleop_key
• run the turtlesim_node
• You get a window with a
turtle
** We just launched a node
and we get a GUI window,
meaning, you can configure
a node to do a lot of things!
So a node is just like any
other program/app
• The teleop_key is an executables that monitor user keyboard input
(external command), by sending messages.
Checkpoint!
So several nodes are running now..
• /rosout is default node
• /teleop_turtle and /turtlesim are the two nodes running
Checkpoint!
Use the rosnode info
<package name> to see
various details of the
package including what
nodes the package
publish to, what is
subscribes to, what other
services available
(will discuss later)
rosnode ping <packagename> will
show successful ping if the package is
running
• rosrun rqt_graph
• Can see the
/teleop_turtle node and
/turtle_sim node is
communicating through
some configuration
• Can also launch
rqt_graph directly
ROS TOPICS
Analogy: a radio transmitter give out radio frequency (98.7) that represents a radio station. Users
need to connect to 98.7 to receive music from the radio station
• ROS consider 98.7 as a ros topic
• The radio transmitter as the publisher of the topic some data string is published by radio
transmitter over the 98.7 topic
• User use a device (eg phone) to listen to the radio station. Meaning the phone is the subscriber of
the topic
• To play music on your phone from the radio transmitter, you also need to send/receive the same
kind of message/data string. (if transmitter encode FM frequency and your phone only decodes AM
frequency, it won’t work!)
• Example of a topic, with 3 subscribers
• Can have as many subscriber for a topic
• Can also have more than 1 publisher to the topic
• Analogy: different zone requires different radio transmitter, but
all these transmitter can represent the same radio station
• All 5 in blue boxes are ros nodes!
• All the subscriber nodes have no clue who is publishing the data, they only know they
receive data from the 98.7 topic. They don’t event know there are other subscribers!
• Same goes on the publisher side, the publishers only know it is the publisher of the 98.7
topic. No clue about other publishers or who are the listener/subscribers
Other combinations are possible too
• Can have 3 subscribers for a
topic and no publishers
• This configuration can work
(not an error), but the
problem is, the subscribers
will receive nothing
• 2 publishers sending data to
a topic, but no one is
subscribing to it
• Can you decompose these configurations?
• What about these?
Summary..
• TCPIP protocol
• Topic is like a
DNS server
Create a python publisher
Follow analogy, create radio transmitter as publisher
• Create a new python file inside your python scripts folder
• Make it executable
• And edit it
• Let’s keep the node name similar to file name for now
• Call the Publisher class in ros
• Specify the topic name for the publisher, say /robot_news_radio
• We also need to specify the data/message type for the topic
• For the radio transmitter example, we wanted to send String message
• Check out std_msgs string message for standard command available
• Message String just contain a simple string data
• So need to import String from std_msgs
• And specify data/message type String
• With the string message, must include queue_size
• The queue_size acts like a buffer
• A topic can send gazillion messages, so subscribers may not have the
time to listen and process them all, the buffer allows the subsribers
some time to process the messages
• While the node is running, we will publish data of the topic, following
a rate, say 2 Hz 2 messages at every second
• Specify the type and message content
• Publish the message using the publish method
• The shutdown() kills the node but not the program/script
• This is a problem because when we kill the node we usually wants the
program to stop (kill the program too)
• Good practice to add to make sure node is stopped before exiting the
program
• If you run, nothing is output, because we only publish, we didn’t ask
program to print something to the terminal.
• rosnode list will show /robot_news_radio_transmitter node is running
• rostopic list
• To listen to a publisher’s message, use the rostopic echo
• Here u can see the message is published at every 0.5 seconds (rate =
2hz = publish 2 message every 1 second)
• If you kill the node (ctrl+Z), “Node was stopped” appears
Create a python subscriber
Follow analogy, create smartphone as subscriber
• Create a python program called smartphone
• Make it executable
• Edit it
• Initialize a new node smartphone
• Using class Subscriber to create a subscriber to the topic
robot_news_radio (make sure the name of topic is correct)
• Specify the same message type (in this case String)
• For subscribers, we do not specify queue_size, instead we create a
callback function to receive the data
The callback should indicate the message is received
• A callback receive the message
• So need to create a function that will have 1 msg as a parameter
• A spin will keep the script running with all the callback, until the
rosnode smartphone is stopped
• Running the subscriber will not
show anything too, because
currently there is no messages
received
• The subscriber will only get
messages when a publisher is
run too! So need to run
robot_news_radio_transmitter
• both publisher and subscriber are running
Create a C++ Publisher
• Repeat the same thing using C++
• Create publisher robot_news_radio_transmitter.cpp
• Edit
• Intialize a node for the publisher, keeping the node name the same a
our cpp filename for now
• Need a nodehandle
• Similarly, need to call the topic name robot_news_radio
• And give queue size 10
• Specify message type String
• And need to import std_msgs header
• This time say we want to send 3 messages per second (rate = 3)
• While ros is ok, we will create a new message, with some data “Hi,
this is William from the Robot News Radio”
• Publish using the publish method
• Add sleep interval
• To compile, need to create a new executables in CMakeLists
• Now you can catkin_make
• Can rosrun the publisher
• Nothing should appear for now
rostopic echo the message to see what is being published to the topic
Create a C++ Subscriber
• Lets call it smartphone_node
• Initialize the smartphone node for subscriber
• Use the subscribe method to connect to the topic, and give a buffer
• The buffer 1000 will chunk the bulk of messages for the subscriber, so
the subscriber has time to process the messages
• Create the callback function
• That receive string message
• We can print the message using ROS INFO, but need to make sure the
message is converted into string format (msg.data.c_str())
• Keep spinning the messages until we kill the program
• To compile, need to create a new executables in CMakeLists
• Now you can catkin_make
• Nothing output because publisher is not called
• Run publisher
• And check again the
subscriber
ROS is language agnostic
• Try mix and match the python publisher with c++ subscriber, and vice
versa!
• Launch roscore on one terminal
• Launch robot_news_radio_transmitter python publisher
• Check rosnode list
• Launch the cpp subscriber.. We still receive the messages (“Dan”)
• Try the opposite!
• Should show “William” from the cpp publisher
• What about 2 subsribers and 2 publishers combination??
• Both publishers have the same name!! ROS does not allow same
name nodes to run in parallel
Setting a node to become “anonymous”
• 2 publishers with the same node name is a conflict
• Specify the node to become anonymous
• The function randomly assign a number at the end of the node name
(e.g. robot_news_radio_transmitter2, but user don’t see this)
• Running the python publisher again and no shutdown request anymore
• Interestingly, the rosnode list will show a publisher with some random
number at the back
• Run 2 python publisher at the same time, and no shutdown request error
• interestingly, 2 publishers with random number appear under rosnode list
• Kill all python publisher nodes, except for 1. at the same time launch the cpp
publisher
• Rosnode list will show 1 node with random number (from python publisher) and
another node without random number (from cpp publisher)
• You can also make cpp node anonymous
• catkin_make again
The cpp publisher is anonymous now
Remark!
• Try not to make all nodes anonymous!
• When is best to use anonymous node? Discuss
Debugging Topics with command line tools
• Run the cpp publisher
• Echo the rostopic to see what the publisher’s message
• rostopic info shows the message type..
• Info also shows who is publisher of the topic
• That publisher is available because you have run it (and not killed it)
• It will show None is not subscribers is launched
• Launching a subscriber for the topic
• Now smartphone is shown as subscriber
• Info is useful to help debug what’s going on for a topic
• Rostopic pub will
publish on this topic
• -1 is to publish 1
time
• To publish at 5hz, use -r
• You get this if another python publisher is running..
• If you kill the python publisher, only hello world should be seen
• Try combine the publisher and subscriber nodes then use the
rqt_graph for graph representation
• For example, can u get this graph?