What is ROS(Robot Operating System)?
For all you text-is-boring people, here’s a video version of this blog on my YouTube channel.
Hello there! This is a jargon-less (almost) post talking about what ROS is, what it’s not, and its superstar role in Robotics.
Before we begin, I would like to point out that ROS is not Robotics.
Robotics is still what it was before ROS — a system of hardware + software which perceives and interprets its surroundings, decides how to respond, and takes action to alter the state (of itself + environment) for a mission.
ROS is ubiquitous in robotics because it provides a great software framework for hardware-software codesign leveraged by the robotics community. In its truest sense, I would call it “Hardware-Software-Codesign Operating System” 😉
Oh, wait! It is also technically not an operating system. ROS is an OS only in concept because it provides all the services that any other OS does — hardware abstraction, low-level device control, implementation of commonly-used functionality, message-passing between processes, and package management.
Sorry, no jargon!
Let’s start fresh with a problem statement, shall we? ;)
Billy, the Humanoid Bot
Our problem statement — Build Billy, the Humanoid Bot which picks up trash in our room and puts it in the garbage bag.
If we dissect Billy (hardware-software system), it would decompose into three broad categories (behold the holy trinity of robotics systems)
- Things that move/actuate(example — servo motors for robot limbs)
- Things that perceive(example — cameras for visual perception)
- Control Systems/Robot Brain (example — internal software to process perception and command limbs)
Note — this is a rather over-simplified description of the system. But it’ll do well to drive our message home.
System Architecture
We have divided our system into 3 logical components — perception, brain, and actuation.
If we naively start imagining our software, we should have 3 files (we’re oversimplifying to later focus on the importance of ROS, instead of system design)
- perception.py — This module will take input images from Billy’s cameras and get insights from them (like the presence of trash).
- actuation.py — This module will command servo motors to move Billy’s limbs. Imagine Billy moving towards trash, picking it up, moving to the bin, and throwing it there. Movements are controlled using actuation’s code
- brain.py — This codebase takes insights from the perception module and Billy’s current state(actuator states), processes this information, and informs the actuation module about what to do next.
The brain module is literally like a human brain here, taking in information through sense organs, and commanding appropriate actions through actuators(motors). Sweet!
But how do these three running modules interact with each other?
Perception needs to inform the brain about the visual environment constantly and the brain needs to command actuation to do something. In code, this can be done in many ways —
- Polling — The brain can keep polling to check the data structures perception populates for each visual frame. Once the brain finds something interesting, it can call a function in the actuation module asking the limbs to move in a certain way. This is fine for a simple system only. Polling has unnecessary bandwidth wastage, risks of race conditions, and bad code for a big system.
- Interrupts — Interrupts are extremely important in hardware-software systems. If you’re familiar with hardware or embedded systems, you would know what Interrupt Service Routines are. Here is a nice example of interrupt handling in python.
Simply put, interrupts are used to trigger a functionality (i.e. call a method) when a specific event occurs. In our case, every time perception processes a visual frame, a method can be called (using interrupts) in the brain module to further decide the course of action based on this new information. The brain can further initiate an interrupt to call actuation’s method with the relevant course of action.
See, we’re already moving away from naive polling to an event-based system.
Side note — Event-based software design is an integral part of hardware-software codesign. ICs,ASICs, microcontrollers, microprocessors — all of them rely on event-based processes. Even pure hardware is designed in ways where signal changes(events) trigger a different part of the circuitry.
So, we decided on building our software systems using either polling(not recommended) or an event-based design(like interrupts).
Tada! It’s time for our protagonist ROS to enter the scene *dramatic music*
ROS says — Hey! Don’t worry about how your modules will share information. I will abstract out how an event-based system can be created. I’ll implement mechanisms internally to do this. All you need to do is make different modules like you always did, and use my APIs to pass information between modules.
Btw, that’s why ROS is conceptually a middleware — hidden translation layer enabling communication and data management for distributed applications.
See, we did not need jargon to understand this ;)
How does ROS abstract out communication and data management?
ROS enables event-based communication between modules (one ROS node in each for simplification) using — topics and services.
Topics —
Imagine our modules (perception, actuation, and brain) are real humans (called ROS Nodes) for a second. Sounds stupid. But stay with me, please!
Perception says — I want to process visual information and frequently talk about “trash_detection” (this is a topic name). And I don’t want to listen to anyone because I don’t care.
Actuation says — I want to listen to “limb_commands”, execute them and frequently talk about “current_limb_state” based on my motor states
Brain says — I want to listen to “trash_detection” and “current_limb_state” to decide what to do. And I want to frequently talk about “limb_commands” to command the limbs
We have a communication system set up already! A person can only access a topic if it is either talking about it(called publishing) or listening to it(called subscribing). Everything else is non-existent to that person. In our system, we have smartly selected topics so that each module is only publishing or subscribing to topics relevant to it.
Services —
Brain usually only cares about Perception’s visual information in every frame. But once in a while, Brain wants to know the battery status of Perception’s camera. It will be a waste of processing power if Perception talks about its camera’s battery levels frequently if Brain only wants to know it sparsely and sporadically.
In this case, a service is set up in Perception(called Server) which can be asked by Brain’s client API to send battery levels. This can be asked by Brain at whatever frequency and regularly/irregularly.
To tie topics and services back to ROS’s event-based APIs, publishing, subscribing, service client calls, servers, all have standard APIs exposed by ROS. Moreover, everything is conceptually event-based because only when some information is published on a topic, the subscriber’s method(callback) is called to process this information. Similarly, only when a service client requests information, server’s method is called which returns the relevant information.
Note — ROS has another information passing mechanism called “Actions”, which we skip in our current discussion.
To reiterate, ROS abstracts out communication and data flow. An application layer developer just needs to use ROS’ APIs to pass information using topics or services.
Is that it about ROS?
Not really, in addition to the abstraction mentioned above, ROS helps with the following-
- Infrastructure — ROS is a software framework supporting infrastructure to run, test and deploy our modules (both in isolation and integrated)
- Open Source Packages — We were using the word “modules” for perception, actuation, and brain. In ROS lingo, they are called “packages”. If developed well, each package is a complete unit serving a specific purpose (for instance, a package for Kalman Filtering, or SLAM). ROS’ Open Source community has thousands of packages. For example, if we have multiple sensors in our system and want to use Kalman Filters, we can download a Kalman Filter ROS package. Looking at what topics and services the package uses, we can publish relevant sensor information and subscribe to relevant outputs.
- Package management — ROS uses catkin_make (colcon in ROS2) as a package manager which includes handling all builds.
Billy in our over-simlified case, did not exploit ROS in the truest sense. As the system requirements increase, we uncover ROS’ strengths. But this is it for now!
Parting Notes —
As mentioned before, ROS is a software framework to enable communication, data flow, and suitable infrastructure development for a hardware-software system (robotics being the best application). The core functionally still lives in old and new non-ROS robotics concepts (math, embedded systems and hardware).
This post was a basic overview of ROS intended to describe its role in Robotics Development. To start with ROS dev, please refer to their official documentation. There is a bigger world to discover. We barely scratched the surface! 😉
As always, I’d love to know what you think. Feedback is always helpful :)
Stay Awesome,
Sharad