An Introduction to Robot Operating System (ROS)
Developing a robot with a computer brain needs a bunch of software tools on the computer side—like software drivers, third party tools for computer vision, simulation tools, and more. ROS framework gathers all these tools and manages how you develop a code for your robot.
Developing a robot with a computer brain requires a bunch of software tools on the computer side—like software drivers, third party tools for computer vision and simulation tools. ROS framework gathers all these tools and manages how you develop a code for your robot.
Instead of reinventing the wheel every time, some frameworks can help you by gathering all these tools and managing how you develop code for your robot. ROS (Robot Operating System) is one of these frameworks. It’s a special framework initially developed by the Stanford AI Laboratory in 2007 for developing robots. The Open Source Robotics Foundation now maintains ROS.
The concept of ROS goes far beyond just a framework. ROS is an OS in concept because it provides all the services that any other OS does—like hardware abstraction, low-level device control, implementation of commonly-used functionality, message-passing between processes, and package management. Even though ROS is still a framework that isn't a standalone OS or an RTOS and isn't the only framework for robots, it seems to be adopted widely and have a large developers community.
ROS can be installed on a single-board computer (SBC) like Raspberry Pi-level and upwards with Ubuntu/Debian distro. However, other platforms are supported experimentally or by the community.
An Overview of How ROS Works
Before we go deeper and start playing with ROS, we need to see the big-picture of the system.
In general, ROS consists of code and tools that help your project's code run and do the required job—including the infrastructure for running it, like messages passing between processes.
ROS is designed to be a loosely coupled system where a process is called a node and every node should be responsible for one task. Nodes communicate with each other using messages passing via logical channels called topics. Each node can send or get data from the other node using the publish/subscribe model. We are going to see that in action later.
The primary goal of ROS is to support code reuse in robotics research and development so you can find a built-in package system. Again, keep in mind that ROS is not an OS, a library, or an RTOS. It’s a framework using the concept of an OS.
Nodes and topics. Image adapted from a tutorial from Justin Huang.
Installation and First Test
ROS supports machines that run Linux with Ubuntu or Debian distro. It has a lot of releases with names ordered alphabetically. In this article, we are going to install the Kinetic edition.
ROS versions. Image courtesy of Wikipedia.
Now, follow the instructions below to install ROS:
- Add the ROS sources to APT:
$ echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list
- Add ROS keys
$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
- Update the APT sources
$ sudo apt-get update
- Install ROS
$ sudo apt-get install ros-kinetic-desktop-full
- rosdep is a command-line tool for installing system dependencies and it needs to be initialized only once after installation
$ sudo rosdep init
$ rosdep update
- In order to use built-in ROS commands, we need to add these to the bash session each time a new shell is launched
$ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc>
$ source ~/.bashrc
- For a one time change
$ source /opt/ros/kinetic/setup.bash
Turtlebot Example: Running a Gazebo Simulation Environment
As a small test, we will run a simulation environment called Gazebo for a Turtlebot robot.
The Turtlebot. Image courtesy of Willow Garage.
To install Gazebo, run the following in the terminal:
$ sudo apt-get install ros-Kinetic-turtlebot ros-indigo-turtlebot-apps ros-Kinetic-turtlebot-interactions ros-Kinetic-turtlebot-simulator ros-Kinetic-kobuki-ftdi ros-Kinetic-ar-track-alvar-msgs
After installation is complete, type the following:
$ roslaunch turtlebot_gazebo turtlebot_world.launch
Wait for a little and the simulator should start working.
Now let’s do the first exciting thing: Let’s control the robot from the keyboard. Open a new instance of the terminal and run the following:
$ roslaunch turtlebot_teleop keyboard_teleop.launch
Now you can move the robot using the keyboard.
Congratulations! ROS is now installed and working properly!
A Deeper View of How ROS Works
Before writing our first code, let’s take a deeper dive into understanding how ROS works. We will examine some concepts using the Gazebo example.
As we said in the overview, nodes are the processes that perform tasks. However, ROS has a command-line tool called Rosnode, which can be used to show the active nodes in a running system. The Rosnode list command will list them. Let’s list the nodes in our example while turtlebot_teleop is running. The output will look something like:
/bumper2pointcloud
/cmd_vel_mux
/depthimage_to_laserscan
/gazebo
/laserscan_nodelet_manager
/mobile_base_nodelet_manager
/robot_state_publisher
/rosout
In order to manage this loosely-coupled environment, there is a Master in ROS which is responsible for name registration and lookup for the rest of the system. Without the Master, nodes would not be able to find each other or exchange messages. To start the Master you should issue roscore or roslaunch.
Master in ROS. Image adapted from a tutorial from Justin Huang.
Back to messages. Messages are structs of data filled with pieces of information by nodes. Nodes exchange them using what’s called topics (logical connection paths), then nodes either publish topics or subscribe to them.
Respectively, rostopic command-line tool can be used to list topics. Let’s see what are the available topics in this example by using rostopic list command. The output will be something like this:
One of the topics called is /cmd_vel_mux/input/teleop and it’s published by turtlebot_teleop. To be sure of this information, we will run rostopic info /cmd_vel_mux/input/teleop.
As we can see, the type of messages exchanged by it are called geometry_msgs/Twist. We will use rosmsg show geometry_msgs/Twist to learn more about this data structure.
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
ROS uses a simplified messages description language for describing the data fields in messages. You can refer to the ROS documentation website to know more about the description language.
Turtlebot_teleop is called a package in ROS. Packages are the main units for organizing software in ROS and may contain nodes, an ROS-dependent library, datasets, configuration files and others. You can browse the turtlebot_teleop package in /opt/ros/kinetic/share/turtlebot_teleop. To find out where ROS is installed, you can use the which command.
$ which rosnode
/opt/ros/kinetic/bin/rosnode
Last but not least, You can write your code in Python, C++ or Lisp. Moreover, ROS also has experimental libraries for other languages like Java.
Having several abstraction levels in ROS gives you the flexibility to write your nodes in different languages for the same system; this definitely will help with more collaboration and code reusability.
We’ve looked at the basic concepts behind ROS for a start but, to be honest, there are many more concepts to look over on the ROS documentation website. In this introductory article, these basic concepts are enough to write your first node. However, more concepts can be explored in a follow-up article.
Build Up Your First Node
An odom topic in the Gazebo environment contains the position of Turtlebot. We are going to write our first node which simply subscribes to the /odom topic and prints the position on the terminal.
ROS uses catkin as the build system. While catkin is not our interest here, you can read a conceptual overview about catkin to familiar
You must install catkin first:
$ sudo apt-get install ros-kinetic-catkin
...and the dependencies:
$ sudo apt-get install cmake python-catkin-pkg python-empy python-nose python-setuptools libgtest-dev build-essential
After installing catkin, we need to create a workspace in the home directory:
$ mkdir -p ~/catkin_ws/src
Let’s create a package to write inside our first node. We will call it location_monitor. Catkin has a tool to create packages with parameters including package name and dependencies:
$ cd catkin_ws/src/
$ catkin_create_pkg location_monitor std_msgs rospy roscpp
Before starting to write the code, we need to know the message type of /odom:
$ rostopic info /odom
Type: nav_msgs/Odometry
Publishers:
* /gazebo (http://yahya-Compaq-Presario-CQ61-Notebook-PC:37411/)
Subscribers: None
To know what Nav_msgs/Odometry contains, run rosmsg show nav_msgs/Odometry. To write the code, we will create location_monitor.cpp:
$ cd catkin_ws/src/location_monito/src/
$ gedit location_monitor.cpp
//location_monitor.cpp //Original Author: Justin Huang #include "ros/ros.h" #include "nav_msgs/Odometry.h" void OdomCallback(const nav_msgs::Odometry::ConstPtr& msg) { double x = msg->pose.pose.position.x; double y = msg->pose.pose.position.y; ROS_INFO("x: %f, y: %f", x, y); } int main(int argc,char** argv) { ros::init(argc, argv, "location_monitor"); ros::NodeHandle nh; ros::Subscriber sub = nh.subscribe("odom", 10, OdomCallback); ros::spin(); return 0; }
Let's break the code down.
ros::init(argc, argv, "location_monitor");
The above initializes ROS and allows ROS to do name remapping for our node “location_monitor”. The name should be unique in a running system.
ros::NodeHandle nh;
This creates a handle to this process's node.
ros::Subscriber sub = nh.subscribe("odom", 10, OdomCallback);
This subscribes to the odom topic. ROS will call the OdomCallback() function whenever a new message arrives. The second argument is the queue size (10 messages).
ros::spin();
This waits for messages to arrive. When a message arrives, the OdomCallback() function will be called.
void OdomCallback(const nav_msgs::Odometry::ConstPtr& msg)
{
double x = msg->pose.pose.position.x;
double y = msg->pose.pose.position.y;
ROS_INFO("x: %f, y: %f", x, y);
}
msg has the type nav_msgs/Odometry as we saw from running rostopic info /odom. While ROS_INFO is one of built-in printing functions.
The last step before building the project is to open catkin_ws/src/location_monitor/CMakeLists.txt and change its contents to add location_monitor.cpp as an executable target that must be built and to add nav_msgs to dependencies. (Refer to CmakeLists documentation page for more on this.)# %Tag(FULLTEXT)% cmake_minimum_required(VERSION 2.8.3) project(location_monitor) ## Find catkin and any catkin packages find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs nav_msgs) ## Generate added messages and services generate_messages(DEPENDENCIES std_msgs nav_msgs) ## Declare a catkin package catkin_package() ## Build talker and listener include_directories(include ${catkin_INCLUDE_DIRS}) add_executable(location_monitor src/location_monitor.cpp) target_link_libraries(location_monitor ${catkin_LIBRARIES}) add_dependencies(location_monitor location_monitor_generate_messages_cpp) # %EndTag(FULLTEXT)%
Now it’s time to build our project. First, go back to catkin_ws:
$ cd ~/catkin_ws
Then build the project:
$ catkin_make
And the last important thing to do is to update your bash session with the new package “location_monitor”:
$ source devel/setup.bash
To run the new node, we need to run Gazebo first because Gazebo is the publisher and Location_monitor is the subscriber:
$ roslaunch turtlebot_gazebo turtlebot_world.launch
Then run the “location monitor” node:
$ rosrun location_monitor location_monitor
The screenshot below represents the output (you can run keyboard_teleop to see the position value changing):
Further Reading
This has been just an introduction to ROS. There are many tools and concepts that need to be learned using formal step by step ROS tutorials.
I hope that you're inspired to consider using ROS in you next microcontroller/Arduino robotic project using a serial interface between the microcontroller/Arduino and ROS master.
Don't miss the chance to preview the list of Robots with ROS inside in lots of application fields to give you some ideas!
If you'd like more articles on ROS, let us know in the comments.
Hey, thank you for such a great post!! I recently installed ROS Indigo on my RPi 3 and wanted to know if it is possible to install and run Gazeebo on a RPi? Also would you know any good books to start out on ROS for beginners? All I’ve done till now is worked with Arduino, a bit with Pi. I really want to get started with building robots with ROS. Thanks! 😊