Introduction to Nodes and Topics
- ROS is a distributed operating system
- Meaning it controls potentially (and typically) multiple computers
- One of them is in the robot itself
- Almost always there is at least one more which is more powerful
- It could be your laptop or your web workspace which runs on our
rover
cluster
- The computers have to be on the same network
Communication model
- Message based
- Most important model is “publish/subscribe”
- publish a topic, subscribe to a topic
- Many to many (Nodes can publish to many topics and subscribe to many topics)
- Topics have a name (e.g. /cmd_vel)
- Topics have an associated message
- Important to understand the difference between Topics and Messages
- Think of the topic as a function name, and the Message as argument list.
ROS Nodes
- A ROS application is designed as a collection of separate ROS Nodes that communicate with each other
- ROS Nodes are separate processes and they can run on the different computers
- ROS Nodes are nothing more than programs written in C++ or Python
- What makes them a “node” is that they communicate with other programs in very specific ways
roscore
- roscore is a special program provided by ROS
- It is the “traffic cop” or “name service”
- It is the center of the ROS universe
- It is run on one of the computers
- Whenever a new ROS node starts, the first thing it does is to announce itself to roscore
- That way roscore always has a picture of the graph of ROS Nodes
ROS topics
- ROS Nodes are separate processes (which can even be running on separate computers)
- A function, method or class created in one Node is invisible and cannot be used or called by another
- They are really really separate
- ROS Nodes talk to each other with ROS topics
Topics
- Topics have a name and a message type
- Two of the most common basic ones:
/cmd_vel
and /odom
- Topics can be published and subscribed
- Which sends a receives messages of a certain message type
cmd_vel
: sent to a robot to command it to move (locomotion)
odom
: received from a robot to report where (it thinks) it is
Message Types
Twist
message is used for cmd_vel
- Expresses a velocity in linear and angular aspects
- Note our robot can only move forward and backward (x axis)
- And it can only rotate around (z axis)
- Twist doesn’t say anything about where the robot (thinks it) is
- “cmd_vel” is the topic to directly command the base (people often refer to the robot as a whole as the base) to move. The message type for cmd_vel is Twist
Publishing and Subscribing
- A node can “publish” a ROS topic
- Another node can “subscribe” to a ROS topic
- The two ROS Nodes don’t know about each other
- A node can subscribe to a ROS topic that no one is publishing
- Two ROS Nodes can publish the same ROS topic with no one subscribing
- etc. etc. etc.
- What is being published and subscribed?
- messages
- A message is a data structure with named and typed fields
- A collection of messages already exists, e.g. Int32, which is message with one element, a 32 bit integer.
ROS Topic /cmd_vel
- A common ROS topic that you will become very familiar with
- When a node (for example one you write) publishes
cmd_vel
it is asking the robot to move
- The message will include speed and direction
- There is a node (e.g.
motor_control
) which subscribes to cmd_vel
motor_control
comes with the robot and is run automatically
motor_control
is connected to the motors.
motor_control
exists and runs even if no other node is publishing cmd_vel
- Or if more than one node publishes
cmd_vel
- They are totally decoupled!
ROS Topic /odom
- Another very common ROS topic that you will become very familiar with
- Odometry is the term for data coming from the wheels which allow the robot to estimate its location and speed.
- In this case, ROS is publishing the ROS topic
odom
constantly (say 30 times per second)
- Any node can subscribe to that ROS topic if it needs to know the current Odometry values
- Here is the message definition
- Here is a diagram
subs = rospy.Subscriber("/odom", Odometry, odom_callback)
def odom_callback(msg):
x_position = msg.pose.pose.position.x
ROS Topic /scan
- Another very common ROS topic that you will learn and use a lot
- /scan contains information coming from the LIDAR sensor on a robot
- It also is published constantly, say 30 times per second
- It contains data about the surrounding area and obstacles seen by the robot
- Any node can subscribe to that ROS topic if it needs to know the current values
- Here is the message definition
- Here is a diagram
def scan_callback(self, msg):
indices = list(range(350, 360)) + list(range(0, 11))
relevant_ranges = [msg.ranges[i] for i in indices]
valid_ranges = [r for r in relevant_ranges if msg.range_min < r < msg.range_max]
if valid_ranges:
self.average_distance = sum(valid_ranges) / len(valid_ranges)
def main():
rospy.init_node('scan_subscriber', anonymous=True)
rospy.Subscriber("/scan", LaserScan, scan_callback)
rospy.spin()
Takeaways
- ROS: distributed operating system
- Node: One process which can run on any computer
- roscore: Single process which is the master controller
- Topic: Messages sent between nodes
Some Further details
- Queues
- When you define your node as a Publisher you need to supply a queue_size
- Messages that are published are kept in the queue until all subscribers have received them
- Therefore if you publish at a rate faster than all the subscribers are processing, you will loose topics
- A good starting queue_size is 10
- Latched Topics
- New subscribers to a latched topic automatically get the last published message for that topic
- Useful for topics which change rarely
Publishing to a Topic
- You will find all the book’s examples in [cosi119_src]](https://github.com/campusrover/cosi119_src)
- If you just type in the example from the book it will not work
- See
~/catkin_ws/src/cosi119_src/src/topic_publisher.py
- Remember:
- to do the necessary code generation and compilation you must run
catkin_make
- to run
roscore
in another terminal
- Run it and examine that it is publishing as expected, as follows:
$ roscore
# open a new tab
$ roslanch cosi119_src pubsubexample.launch
# open a new tab
$ rostopic list
$ rostopic echo counter -n 5
Checking That Everything Works as Expected
- Make sure you can see that topics are being published (see
rostopic
)
- Make sure you can see that topics are being subscribed (see console output)
- Try running
rqt_graph
to see the publisher/subscriber relationships for node and topics
Subscribing to a Topic
- See
samples
topic_subscriber.py
- It defines and runs a node whch subscribes to the counter, and prints it
# shell commands
$ roscd samples
$ chmod +x scripts/topic_subscriber.py
$ rosrun samples topic_subscriber.py