Learning ROS – Part II

The Robot Operating System (ROS) is awesome because it allows robotics developers to share their code in a standardised fashion. Here’s what I’ve learnt from the introductory ROS tutorials.

What is ROS (in a nutshell)?

ROS is a robotics framework that allows you to run software, on a robot, in a modular fashion. A typical robot might comprise of a localization system that takes care of the mapping, a perception system that allows the robot to see the world, and a control system that ensures that the robot moves smoothly in expected ways. Each of these can be decoupled and implemented separately as ROS nodes (an executable connected to the ROS network) . Each node could even be implemented in different programming languages such as C++ or Python and on different architectures (eg. an Arduino microprocessor sending messages to a laptop and an Android phone).

ROS messages and topics

ROS is basically a graph that consists of nodes and connections corresponding to communication between nodes. Nodes are executables that do something, and communicate with other nodes. For example, there might be a node for the localization module. In order to communicate efficiently, nodes use a special ROS data type called a message. Communication on topics happens by sending ROS messages between nodes which have the same message type. ROS nodes publish to or subscribe to a ROS topic in order to send or receive messages, respectively. It is this paradigm and the ROS client libraries (rospy and roscpp) that makes it possible to implement each module in a different programming language because the message interface (what the nodes “see”) is a common data type between nodes.

A ROS message is described in a msg file that provides a blueprint for generating the code for messages in multiple languages. When a message is published to a topic, it is streaming at a particular rate. The subscriber is implemented using a callback function that “does something” each time a new message is published to the topic.

ROScore

In order for nodes to not get confused, a name service is required. In ROS, this is called a Master. For debugging purposes, ROS has a stdout/stderr equivalent called rosout as well as a parameter server which allows for the sharing of parameters across nodes. The Master+rosout+parameter sever is known as roscore.

Debugging tools

ROS provides a really handy debugging tool called rqt_graph which plots a graph showing all the nodes and topics currently running (with arrows to distinguish nodes that are publishing or subscribing to a topic). rostopic also provides commands such as echo, list,pub and type which also aid with debugging. Similarly, rosnode info is also useful. The human readable YAML markup language can be used for rostopic pub arguments. Another useful tool is rqt_plot which plots the data published on topics.

The output from any node can be viewed by launching the rqt_console node which displays the ROS logging framework output in a nice GUI. The messages and their associated severity (fatal, error, warning, info, debug – where fatal is the highest priority) are also shown. rqt_logger_level launches a GUI that allows you to change the message severity level (or verbosity) of nodes while they run. Selecting a logger level gives you access to messages of that level and higher priority.

ROS services

Nodes can publish message streams (data) to topics or subscribe to such stream. ROS services allow nodes to send a request and receive a response. You can think of services as almost like calling “methods or procedures” that perform a particular function, such as clearing a screen, at a specific time. This is distinct from streaming data between nodes using ROS messages published to ROS topics.

A ROS service is described in a srv file that provides a blueprint for generating the code for services. It contains a request and response.

ROS parameters

The ROS parameter server stores integers, floats, Boolean, dictionaries, and lists using YAML markup language. When changing a parameter value using rosparam set, you need to call rosservice call /clear for the change to take effect. The parameters can be saved to a file and loaded back using any namespace for convenience. Parameters and services are accessible to all nodes however only nodes having the required message type and publishing to or subscribing from a topic can access that particular topic. So ROS services and parameters are in a sense universal across all nodes, whilst ROS topics are communication links between nodes.

Starting multiple ROS nodes

It may happen that you want to start multiple nodes at the same time. This can be achieved by writing an XML launch file which is run using the roslaunch command.

Playing back data

ROS allows one to record published messages in a bag file, using the rosbag command. These can then be played back to mimic a running system (although the timing is not absolutely perfect).

ROS commands

rospack = ros+pack(age)

roscd = ros+c(hange)d(irectory)

rosls = ros + l(i)st files

roscp = ros + c(o)p(y)

rosmsg = ros + m(es)s(a)g(e)

rossrv = ros + s(e)rv(ice)

catkin_make = compile catkin ROS package

A summary

I found this concepts summary incredibly helpful and a nice reference to refer to while getting used to using ROS.