ROS: Core concepts
In the previous post, we covered an overview of ROS and hopefully the installation is done and dusted. In this article, we will go through some of the core concepts of ROS, familiarize with the jargon so to speak. The objective is to provide a brief introduction to the concepts you may come across while going through ROS tutorials or elsewhere. If you followed the installation and subsequent configuration, you should have a directory named catkin_ws somewhere in your filesystem (depending on how you setup the configuration). So what is this directory and why is it important?
Wait, what is catkin? It is a build system for your application. Think of it as a more “advanced” version of CMake or GNU Make. As your ROS application may include a range of software from .cpp to .py files and a vast number of dependencies, ROS developers felt the best off-the-shelf solution to the build problem would be catkin. You can read more about its adoption here. Catkin workspace is the home of your ROS application. This is the place where the code is developed, built and installed. For all practical purposes, you can have as many workspaces in your desktop as you please. They need not be named catkin_ws, it can be any valid directory name.
So how would you decide when to make a new workspace? It depends. There is no hard rule against using just one workspace for all your projects or go to the other extreme and have one workspace for each package (explained below), but both of them would be ill-advised. Think of the workspace as your application, so all the code and related files should be placed there. For example, if you are working on two projects: one on the mobile robot and another one on an arm-manipulator, it makes sense to put the relevant “packages” into separate workspace for ease of code building, sharing, and management.
That’s all alright, but you may wonder where would you actually write your code? Somewhere in the catkin workspace.
This is the place where you actually put your code in. It can be thought of as a smallest independent user developed entity that can be built, installed and run. Think of it this way: While working on a project for driving an autonomous mobile robot (or a self-driving car for that matter), there will be several smaller applications working together to accomplish the end objective. For example, one of the tasks will be to interface with the cameras and provide the visual data, another task will be to interpret this data for identifying lanes, obstacles, signboards. Yet another task is to do path planning, and the list goes on. Each of these tasks would require different expertise from the developer and are quite different in terms of their role in the overall application.
A ROS package then is the place to hold all the source code, scripts, CMakeLists, launch files, message files, service files and other files for each of these tasks. Again, there is no hard rule for a ROS package to just focus on one particular aspect of application but it is prudent to maintain it this way. If you want to know more about the design and components of a ROS package, refer to this article for an in-depth understanding.
Thus far I have used the word “processes” to refer to any application code that is executed. In the ROS ecosystem, such an executable is called a ROS Node. It is nothing but a program that uses the ROS framework for communication with other such executables. It offers the means to communicate using publishers, subscribers, services or action server-clients.
Publishers and Subscribers
Consider a typical situation in the development of a mobile robot, you want the localization module to continuously provide the robot pose in a world reference frame. This pose has to be used by the control algorithm to track a given path, this controller node will then send out the velocity commands to the motor driver process. Note that both the robot pose and the velocity commands have to be provided at all times, without exception. To accomplish this functionality ROS provides publishers and subscribers. In the example that we have been discussing, your localization node will be “publishing” the robot pose, your controller node will be “subscribing” to this information and in turn “publish” the motion commands. Here is a question you should be having at this, “If they are all sending out and receiving data, how do they know which data to use and for what purpose”.
This is where ROS Topics come in. A ROS node essentially broadcasts (publishes) the data(message) on a particular topic and one or more than one nodes can receive (subscribe) to this information. Each of these topics uniquely identifies these messages. Here is the thing, the type of data needed to define a robot pose is significantly different from the one describes a camera stream. ROS comes with some in-built message types for most of the commonly needed information, it allows the user the ability to define their own message types as per application needs.
A representational figure is shown below where a publisher sends out the data and one or more nodes can subscribe to that information.
While a publisher-subscriber mechanism is typically suited for more continuous communication, it is often needed to make a Remote Procedural Call (RPC). It is nothing but an inter-process equivalent of a function call, involving a request by the client and a response by the server. It is generally suited for more discretely placed events such as turning an LED on/off, set or get a parameter or any other suitable function evaluation. Just like publishers-subscribers, services also have a unique service name and a comprising the request and response pairs is defined in the service type. Furthermore, similar to messages, ROS comes with some pre-built services and allows the user to develop as per demand.
As you can see from the figure above, each service host can answer several requests but these are NOT concurrent i.e. reach request is processed one at a time and the rest of the queries are queued (length of such a queue can be specified by the user).
Here is a scenario. Suppose a situation demands that a particular action be initiated, provides feedback and then terminates after success, failure or preemption. As an example, a robot in a logistics operation has a conveyor belt on top it, you want to initiate the conveyor movement when you have docked to that precise location and terminate the movement when the loading operation completes. A lazy way to go about this operation is to initiate a service call from the task manager to the conveyor control, wait and hope for the response when the process is complete, blocking your entire code while this operation is underway. What if there was a problem with the actuation and it isn’t moving at all? Clearly, you’ll be left in a no man’s land with your code stuck at the service with no way out. ROS actionlib is built on top of ROS messages to provide off the shelf functionality for such situations. An action client initiates the call with a goal request with an ability to preempt the goal, the action server provides continuous feedback while it is active and success/failure based on user-defined criteria upon termination. With some liberty, it can be understood as a mix of a service call to initiate a certain action with subscriber like functionality to listen to the feedback and finally accept a response from the server. Similar to messages and services, action files can be used to define the action type of the data exchanged and a topic name to identify. As always, ROS has some in-built action types while providing users the ability to create their own custom action files.
A schematic representation of actionlib based communication is shown below. While an action server can answer requests by multi clients, each goal request to the server preempts the previous computation. This means that at a time only one client can meaningfully communicate with the action server.
That’s it really!
I hope this two-part series provided you a basic understanding of ROS and some of its core components. The objective really was to provide a launch-pad for you to kick start your development journey. ROS tutorials is a great place to pursue your learning, ROS answers is the place to ask the right questions but taking up a project is really the best to go about mastering anything. Happy learning. Cheers!