Free eBook - Mastering ROS for Robotics Programming - Second Edition

4.6 (5 reviews total)
By Lentin Joseph , Jonathan Cacace
  • A new free eBook every day on the latest in tech
  • 30 permanently free eBooks from our core tech library
  1. Introduction to ROS

About this book

In this day and age, robotics has been gaining a lot of traction in various industries where consistency and perfection matter. Automation is achieved via robotic applications and various platforms that support robotics. The Robot Operating System (ROS) is a modular software platform to develop generic robotic applications. This book focuses on the most stable release of ROS (Kinetic Kame), discusses advanced concepts, and effectively teaches you programming using ROS.

We begin with aninformative overview of the ROS framework, which will give you a clear idea of how ROS works. During the course of this book, you’ll learn to build models of complex robots, and simulate and interface the robot using the ROS MoveIt! motion planning library and ROS navigation stacks. Learn to leverage several ROS packages to embrace your robot models.

After covering robot manipulation and navigation, you’ll get to grips with the interfacing I/O boards, sensors, and actuators of ROS. Vision sensors are a key component of robots, and an entire chapter is dedicated to the vision sensor and image elaboration, its interface in ROS and programming. You’ll also understand the hardware interface and simulation of complex robots to ROS and ROS Industrial.

At the end of this book, you’ll discover the best practices to follow when programming using ROS.

Publication date:
February 2018
Publisher
Packt
Pages
580
ISBN
9781788478953

 

Chapter 1. Introduction to ROS

The first two chapters of this book introduce basic ROS concepts and its package management system in order to refresh your memory about concepts you should already know. In this first chapter, we will go through ROS concepts such as the ROS Master, the ROS nodes, the ROS parameter server, ROS  messages and services discussing what we need to install ROS and how to get started with the ROS master.

In this chapter, we will cover the following topics:

  • Why should we learn ROS?
  • Why should we prefer or should not prefer ROS for robots?
  • Getting started with the ROS filesystem level and its computation graph level.
  • Understanding ROS framework elements.
  • Getting started with the ROS master.
 

Why should we learn ROS?


Robot Operating System (ROS) is a flexible framework, providing various tools and libraries to write robotic software. It offers several powerful features to help developers in such tasks as message passing, distributing computing, code reusing, and implementation of state-of-the-art algorithms for robotic applications.

The ROS project was started in 2007, with the name Switchyard, by Morgan Quigley (http://wiki.osrfoundation.org/morgan), as part of the Stanford STAIR robot project. The main development of ROS happened at Willow Garage (https://www.willowgarage.com/).

The ROS community is growing very fast, and there are many users and developers worldwide. Most of the high-end robotics companies are now porting their software to ROS. This trend is also visible in industrial robotics, in which companies are switching from proprietary robotic applications to ROS.

The ROS industrial movement has gained momentum in the past few years, owing to the large amount of research done in that field. ROS Industrial can extend the advanced capabilities of ROS to manufacturing. The increasing applications of ROS can generate a lot of job opportunities in this field. So, after some years, a knowledge of ROS will be an essential requirement for a robotics engineer.

 

Why we prefer ROS for robots


Imagine that we are going to build an autonomous mobile robot. Here are some of the reasons why people choose ROS over other robotic platforms, such as Player, YARP, Orocos, MRPT, and so on:

  • High-end capabilities: ROS comes with ready-to-use capabilities. For example, Simultaneous Localization and Mapping (SLAM) and Adaptive Monte Carlo Localization (AMCL) packages in ROS can be used for performing autonomous navigation in mobile robots, and the MoveIt package can be used for motion planning of robot manipulators. These capabilities can directly be used in our robot software without any hassle. These capabilities are its best form of implementation, so writing new code for existing capabilities is like reinventing the wheel. Also, these capabilities are highly configurable; we can fine-tune each capability using various parameters.
  • Tons of tools: ROS is packed with tons of tools for debugging, visualizing, and performing a simulation. The tools, such as rqt_gui, RViz, and Gazebo, are some of the strong open source tools for debugging, visualization, and simulation. A software framework that has these many tools is very rare.
  • Support for high-end sensors and actuators: ROS is packed with device drivers and interface packages of various sensors and actuators in robotics. The high-end sensors include Velodyne-LIDAR, Laser scanners, Kinect, and so on, and actuators such as DYNAMIXEL servos. We can interface these components to ROS without any hassle.
  • Inter-platform operability: The ROS message-passing middleware allows communication between different nodes. These nodes can be programmed in any language that has ROS client libraries. We can write high-performance nodes in C++ or C and other nodes in Python or Java. This kind of flexibility is not available in other frameworks.
  • Modularity: One of the issues that can occur in most of the standalone robotic applications is that if any of the threads of main code crash, the entire robot application can stop. In ROS, the situation is different; we are writing different nodes for each process, and if one node crashes, the system can still work. Also, ROS provides robust methods to resume operations even if any sensors or motors are dead.
  • Concurrent resource handling: Handling a hardware resource via more than two processes is always a headache. Imagine we want to process an image from a camera for face detection and motion detection; we can either write the code as a single entity that can do both, or we can write a single-threaded code for concurrency. If we want to add more than two features in threads, the application behavior will get complex and will be difficult to debug. But in ROS, we can access the devices using ROS topics from the ROS drivers. Any number of ROS nodes can subscribe to the image message from the ROS camera driver, and each node can perform different functionalities. It can reduce the complexity in computation and also increase the debug ability of the entire system.
  • Active community: When we choose a library or software framework, especially from an open source community, one of the main factors that needs to be checked before using it is its software support and developer community. There is no guarantee of support from an open source tool. Some tools provide good support and some tools don't. In ROS, the support community is active. There is a web portal to handle the support queries from users too (http://answers.ros.org). It seems that the ROS community has a steady growth in developers worldwide.

There are many reasons to choose ROS other than the preceding points.

Next, we can check the various reasons why people don't use ROS. Here are some of the existing reasons.

 

Why some do not prefer ROS for robots


Here are some of the reasons why some people do not prefer ROS for their robotic projects:

  • Difficulty in learning: ROS can be difficult to learn. It has a steep learning curve and developers should become familiar with many new concepts to get benefits from the ROS framework. 
  • Difficulties in starting with simulation: The main simulator in ROS is Gazebo. Even though Gazebo works well, to get started with Gazebo is not an easy task. The simulator has no inbuilt features to program. Complete simulation is done only through coding in ROS. When we compare Gazebo with other simulators, such as V-REP and Webots, they have inbuilt functionalities to prototype and program the robot. They also have a rich GUI toolset support a wide variety of robots and have ROS interfaces too. These tools are proprietary but can deliver a decent job. The toughness of learning simulation using Gazebo and ROS is a reason for not using it in projects.
  • Difficulties in robot modeling: The robot modeling in ROS is performed using URDF, which is an XML-based robot description. In short, we need to write the robot model as a description using URDF tags. In V-REP, we can directly build the 3D robot model in the GUI itself, or we can import the mesh. In ROS, we should write the robot model definitions using URDF tags. There is a SolidWorks plugin to convert a 3D model from SolidWorks to URDF, but if we use other 3D CAD tools, there are no options at all. Learning to model a robot in ROS will take a lot of time, and building using URDF tags is also time-consuming compared to other simulators.
  • Potential limitations: Current ROS versions have some limitations. For example, there is a lack of a native real-time application development support or the complexity to implement robust multi-robot distributed applications.
  • ROS in commercial robot products: When we deploy ROS on a commercial product, a lot of things need to be taken care of. One thing is the code quality. ROS code follows a standard coding style and keeps best practices for maintaining the code too. We have to check whether it satisfies the quality level required for our product. We might have to do additional work to improve the quality of the code. Most of the code in ROS is contributed by researchers from universities, so if we are not satisfied with the ROS code quality, it is better to write our own code, which is specific to the robot and only use the ROS core functionalities if required.

We now know where we have to use ROS and where we do not. If ROS is really required for your robot, let's start discussing ROS in more detail. First, we can see the underlying core concepts of ROS. There are mainly three levels in ROS: the filesystem level, computation graph level, and community level. We will briefly have a look at each level.

 

Understanding the ROS filesystem level


ROS is more than a development framework. We can refer to ROS as a meta-operating system, since it offers not only tools and libraries but even OS-like functions, such as hardware abstraction, package management, and a developer toolchain. Like a real operating system, ROS files are organized on the hard disk in a particular manner, as depicted in the following figure:

Figure 1: ROS filesystem level

Here are the explanations for each block in the filesystem:

  • Packages: The ROS packages are the most basic unit of the ROS software. They contain one or more ROS programs (nodes), libraries, configuration files, and so on, which are organized together as a single unit. Packages are the atomic build item and release item in the ROS software.
  • Package manifest: The package manifest file is inside a package that contains information about the package, author, license, dependencies, compilation flags, and so on. The package.xml file inside the ROS package is the manifest file of that package.
  • Metapackages: The term metapackage refers to one or more related packages which can be loosely grouped together. In principle, metapackages are virtual packages that don't contain any source code or typical files usually found in packages.
  • Metapackages manifest: The metapackage manifest is similar to the package manifest, the difference being that it might include packages inside it as runtime dependencies and declare an export tag.
  • Messages (.msg): The ROS messages are a type of information that is sent from one ROS process to the other. We can define a custom message inside the msg folder inside a package (my_package/msg/MyMessageType.msg). The extension of the message file is .msg.
  • Services (.srv): The ROS service is a kind of request/reply interaction between processes. The reply and request data types can be defined inside the srv folder inside the package (my_package/srv/MyServiceType.srv).
  • Repositories: Most of the ROS packages are maintained using a Version Control System (VCS), such as Git, Subversion (svn), Mercurial (hg), and so on. The collection of packages that share a common VCS can be called repositories. The package in the repositories can be released using a catkin release automation tool called bloom.

The following screenshot gives you an idea of the files and folders of a package that we are going to create in the upcoming sections:

Figure 2: List of files inside the exercise package

ROS packages

A typical structure of an ROS package is shown here:

Figure 3: Structure of a typical C++ ROS package

We can discuss the use of each folder as follows:

  • config: All configuration files that are used in this ROS package are kept in this folder. This folder is created by the user and it is a common practice to name the folder config to keep the configuration files in it.
  • include/package_name: This folder consists of headers and libraries that we need to use inside the package.
  • script: This folder keeps executable Python scripts. In the block diagram, we can see two example scripts.
  • src: This folder stores the C++ source codes.
  • launch: This folder keeps the launch files that are used to launch one or more ROS nodes.
  • msg: This folder contains custom message definitions.
  • srv: This folder contains the services definitions.
  • action: This folder contains the action files. We will see more about these kind of files in the next chapter.
  • package.xml: This is the package manifest file of this package.
  • CMakeLists.txt: This files contains the directives to compile the package.

We need to know some commands to create, modify, and work with the ROS packages. Here are some of the commands used to work with ROS packages:

  • catkin_create_pkg: This command is used to create a new package
  • rospack: This command is used to get information about the package in the filesystem
  • catkin_make: This command is used to build the packages in the workspace
  • rosdep: This command will install the system dependencies required for this package

To work with packages, ROS provides a bash-like command called rosbash (http://wiki.ros.org/rosbash), which can be used to navigate and manipulate the ROS package. Here are some of the rosbash commands:

  • roscd: This command is used to change the current directory using a package name, stack name, or a special location. If we give the argument a package name, it will switch to that package folder.
  • roscp: This command is used to copy a file from a package.
  • rosed: This command is used to edit a file using the vim editor.
  • rosrun: This command is used to run an executable inside a package.

The definition of package.xml of a typical package is shown in the following screenshot:

Figure 4: Structure of package.xml

The package.xml file consists of the package name, version of the package, the package description, author details, package build dependencies, and runtime dependencies. The <build_depend></build_depend> tag includes the packages that are necessary to build the source code of the package. The packages inside the <run_depend></run_depend> tags are necessary during runtime of the package node.

ROS metapackages

Metapackages are specialized packages in ROS that only contain one file, that is, a package.xml file. They don't contain folders and files like a normal package.

Metapackages simply group a set of multiple packages as a single logical package. In the package.xml file, the metapackage contains an export tag, as shown here:

  <export> 
    <metapackage/> 
  </export>  

Also, in metapackages, there are no <buildtool_depend> dependencies for catkin; there are only <run_depend> dependencies, which are the packages grouped in the metapackage.

The ROS navigation stack is a good example of metapackages. If ROS and its navigation package are installed, we can try the following command, by switching to the navigation metapackage folder:

$ roscd navigation

Open package.xml using your favorite text editor (gedit in the following case):

$ gedit package.xml

This is a lengthy file; here is a stripped-down version of it:

Figure 5: Structure of meta-package package.xml

ROS messages

The ROS nodes can write or read data that has a different type. The types of data are described using a simplified message description language, also called ROS messages. These datatype descriptions can be used to generate source code for the appropriate message type in different target languages.

The data type description of ROS messages is stored in .msg files in the msg subdirectory of a ROS package. Even though the ROS framework provides a large set of robotic-specific messages already implemented, developers can define their own message type inside their nodes.

The message definition can consist of two types: fields and constants. The field is split into field types and field names. The field type is the data type of the transmitting message and field name is the name of it. The constants define a constant value in the message file.

Here is an example of message definitions:

int32 number 
string name 
float32 speed 

Here, the first part is the field type and the second is the field name. The field type is the data type and the field name can be used to access the value from the message. For example, we can use msg.number for accessing the value of the number from the message.

Here is a table showing some of the built-in field types that we can use in our message:

Primitive type

Serialization

C++

Python

bool(1)

Unsigned 8-bit int

uint8_t(2)

bool

int8

Signed 8-bit int

int8_t

int

uint8

Unsigned 8-bit int

uint8_t

int (3)

int16

Signed 16-bit int

int16_t

int

uint16

Unsigned 16-bit int

uint16_t

int

int32

Signed 32-bit int

int32_t

int

uint32

Unsigned 32-bit int

uint32_t

int

int64

Signed 64-bit int

int64_t

long

uint64

Unsigned 64-bit int

uint64_t

long

float32

32-bit IEEE float

float

float

float64

64-bit IEEE float

double

float

string

ascii string(4)

std::string

string

time

secs/nsecs unsigned 32-bit ints

ros::Time

rospy.Time

duration

secs/nsecs signed 32-bit ints

ros::Duration

rospy.Duration

Other kinds of messages are designed to cover a specific application necessity, such as exchanging common geometrical (geometry_msgs) or sensor (sensor_msgs) information. A special type of ROS message is called a message header. Headers can carry information, such as time, frame of reference or frame_id, and sequence number. Using headers, we will get numbered messages and more clarity in who is sending the current message. The header information is mainly used to send data such as robot joint transforms (TF). Here is an example of the message header:

uint32 seq 
time stamp 
string frame_id 

The rosmsg command tool can be used to inspect the message header and the field types. The following command helps to view the message header of a particular message:

$ rosmsg show std_msgs/Header

This will give you an output like the preceding example message header. We will look at the rosmsg command and how to work with custom message definitions further in the upcoming sections.

The ROS services

The ROS services are a type request/response communication between ROS nodes. One node will send a request and wait until it gets a response from the other. The request/response communication is also using the ROS message description.

Similar to the message definitions using the ".msg" file, we have to define the service definition in another file called ".srv", which has to be kept inside the srv subdirectory of the package. Similar to the message definition, a service description language is used to define the ROS service types.

An example service description format is as follows:

#Request message type 
string str 
--- 
#Response message type 
string str 

The first section is the message type of the request that is separated by --- and in the next section is the message type of the response. In these examples, both Request and Response are strings.

In the upcoming sections, we will look at how to work with ROS services.

 

Understanding the ROS computation graph level


The computation in ROS is done using a network of a process called ROS nodes. This computation network can be called the computation graph. The main concepts in the computation graph are ROS Nodes, Master, Parameter server, Messages, Topics, Services, and Bags. Each concept in the graph is contributed to this graph in different ways.

The ROS communication-related packages including core client libraries, such as roscpp and rospython , and the implementation of concepts, such as topics, nodes, parameters, and services are included in a stack called ros_comm (http://wiki.ros.org/ros_comm).

This stack also consists of tools such as rostopic, rosparam, rosservice, and rosnode to introspect the preceding concepts.

The ros_comm stack contains the ROS communication middleware packages and these packages are collectively called the ROS Graph layer:

Figure 6: Structure of the ROS Graph layer

The following are abstracts of each graph's concepts:

  • Nodes: Nodes are the process that perform computation. Each ROS node is written using ROS client libraries. Using client library APIs, we can implement different ROS functionalities, such as the communication methods between nodes, which is particularly useful when different nodes of our robot must exchange information between them. Using the ROS communication methods, they can communicate with each other and exchange data. One of the aims of ROS nodes is to build simple processes rather than a large process with all the functionality. Being a simple structure, ROS nodes are easy to debug.
  • Master: The ROS Master provides the name registration and lookup to the rest of the nodes. Nodes will not be able to find each other, exchange messages, or invoke services without a ROS Master. In a distributed system, we should run the master on one computer, and other remote nodes can find each other by communicating with this master.
  • Parameter server: The parameter server allows you to keep the data to be stored in a central location. All nodes can access and modify these values. The parameter server is a part of the ROS Master.
  • Messages: Nodes communicate with each other using messages. Messages are simply a data structure containing the typed field, which can hold a set of data, and that can be sent to another node. There are standard primitive types (integer, floating point, Boolean, and so on) and these are supported by ROS messages. We can also build our own message types using these standard types.
  • Topics: Each message in ROS is transported using named buses called topics. When a node sends a message through a topic, then we can say the node is publishing a topic. When a node receives a message through a topic, then we can say that the node is subscribing to a topic. The publishing node and subscribing node are not aware of each other's existence. We can even subscribe a topic that might not have any publisher. In short, the production of information and consumption of it are decoupled. Each topic has a unique name, and any node can access this topic and send data through it as long as they have the right message type.
  • Services: In some robot applications, the publish/subscribe communication model may not be suitable. For example, in some cases, we need a kind of request/response interaction, in which one node can ask for the execution of a fast  procedure to another node; for example, asking for some quick calculation. The ROS service interaction is like a remote procedure call.
  • Logging: ROS provides a logging system for storing data, such as sensor data, which can be difficult to collect but is necessary for developing and testing robot algorithms: the bagfiles. Bagfiles are very useful features when we work with complex robot mechanisms.

The following graph shows how the nodes communicate with each other using topics. The topics are mentioned in a rectangle and the nodes are represented in ellipses. The messages and parameters are not included in this graph. These kinds of graphs can be generated using a tool called rqt_graph (http://wiki.ros.org/rqt_graph):

Figure 7: Graph of communication between nodes using topics

ROS nodes

ROS nodes are a process that perform computation using ROS client libraries such as roscpp and rospy. One node can communicate with other nodes using ROS Topics, Services, and Parameters.

A robot might contain many nodes; for example, one node processes camera images, one node handles serial data from the robot, one node can be used to compute odometry, and so on.

Using nodes can make the system fault tolerant. Even if a node crashes, an entire robot system can still work. Nodes also reduce the complexity and increase debug-ability compared to monolithic code because each node is handling only a single function.

All running nodes should have a name assigned to identify them from the rest of the system. For example, /camera_node could be a name of a node that is broadcasting camera images.

There is a rosbash tool to introspect ROS nodes. The rosnode command can be used to get information about a ROS node. Here are the usages of rosnode:

  • $ rosnode info [node_name]: This will print the information about the node
  • $ rosnode kill [node_name]: This will kill a running node
  • $ rosnode list: This will list the running nodes
  • $ rosnode machine [machine_name]: This will list the nodes running on a particular machine or a list of machines
  • $ rosnode ping: This will check the connectivity of a node
  • $ rosnode cleanup: This will purge the registration of unreachable nodes

We will look at example nodes using the roscpp client and will discuss the working of ROS nodes that use functionalities such ROS Topics, Service, Messages, and actionlib.

ROS messages

ROS nodes communicate with each other by publishing messages to a topic. As we discussed earlier, messages are a simple data structure containing field types. The ROS message supports standard primitive datatypes and arrays of primitive types.

Nodes can also exchange information using service calls. Services are also messages. The service message definitions are defined inside the srv file.

We can access the message definition using the following method. For example, to access std_msgs/msg/String.msg, we can use std_msgs/String. If we are using the roscpp client, we have to include std_msgs/String.h for the string message definition.

In addition to message data type, ROS uses an MD5 checksum comparison to confirm whether the publisher and subscriber exchange the same message data types.

ROS has inbuilt tools called rosmsg to get information about ROS messages. Here are some parameters used along with rosmsg:

  • $ rosmsg show [message]: This shows the message description
  • $ rosmsg list: This lists all messages
  • $ rosmsg md5 [message]: This displays md5sum of a message
  • $ rosmsg package [package_name]: This lists messages in a package
  • $ rosmsg packages [package_1] [package_2]: This lists packages that contain messages

ROS topics

ROS topics are named buses in which ROS nodes exchange messages. Topics can anonymously publish and subscribe, which means that the production of messages is decoupled from the consumption. The ROS nodes are not interested in knowing which node is publishing the topic or subscribing topics; they only look for the topic name and whether the message types of the publisher and subscriber are matching.

The communication using topics are unidirectional. If we want to implement a request/response, such as communication, we have to switch to ROS services.

The ROS nodes communicate with topics using TCP/IP-based transport known as TCPROS. This method is the default transport method used in ROS. Another type of communication is UDPROS, which has low-latency, loose transport, and is only suited for teleoperations.

The ROS topic tool can be used to get information about ROS topics. Here is the syntax of this command:

  • $ rostopic bw /topic: This command will display the bandwidth used by the given topic.
  • $ rostopic echo /topic: This command will print the content of the given topic in a human readable format. Users can use the "-p" option to print data in a csv format.
  • $ rostopic find /message_type: This command will find topics using the given message type.
  • $ rostopic hz /topic: This command will display the publishing rate of the given topic.
  • $ rostopic info /topic: This command will print information about an active topic.
  • $ rostopic list: This command will list all active topics in the ROS system.
  • $ rostopic pub /topic message_type args: This command can be used to publish a value to a topic with a message type.
  • $ rostopic type /topic: This will display the message type of the given topic.

ROS services

When we need a request/response kind of communication in ROS, we have to use the ROS services. ROS topics can't implement natively such kind of communication because it is unidirectional. The ROS services are mainly used in a distributed system.

The ROS services are defined using a pair of messages. We have to define a request datatype and a response datatype in a srv file. The srv files are kept in a srv folder inside a package.

In ROS services, one node acts as a ROS server in which the service client can request the service from the server. If the server completes the service routine, it will send the results to the service client. For example, consider a node able to provide the sum of two numbers received in input, implementing this functionality through a ROS service. The other nodes of our system might request the sum of two numbers via this service. Differently, topics are used to stream continuous data flow.

The ROS service definition can be accessed by the following method; for example, if my_package/srv/Image.srv can be accessed by my_package/Image.

In ROS services also, there is an MD5 checksum that checks in the nodes. If the sum is equal, then only the server responds to the client.

There are two ROS tools to get information about the ROS service. The first tool is rossrv, which is similar to rosmsg, and is used to get information about service types. The next command is rosservice, which is used to list and query about the running ROS services.

The following explain how to use the rosservice tool to get information about the running services:

  • $ rosservice call /service args: This tool will call the service using the given arguments
  • $ rosservice find service_type: This command will find services in the given service type
  • $ rosservice info /services: This will print information about the given service
  • $ rosservice list: This command will list the active services running on the system
  • $ rosservice type /service: This command will print the service type of a given service
  • $ rosservice uri /service: This tool will print the service ROSRPC URI

ROS bags

A bag file in ROS is for storing ROS message data from topics and services. The .bag extension is used to represent a bag file.

Bag files are created using the rosbag command, which will subscribe one or more topics and store the message's data in a file as it's received. This file can play the same topics as they are recorded from or it can remap the existing topics too.

The main application of rosbag is data logging. The robot data can be logged and can visualize and process offline.

The rosbag command is used to work with rosbag files. Here are the commands to record and playback a bag file:

  • $ rosbag record [topic_1] [topic_2] -o [bag_name]: This command will record the given topics into a bag file that is given in the command. We can also record all topics using the -a argument.
  • $ rosbag play [bag_name]: This will playback the existing bag file.

Further details about this command can be found at: http://wiki.ros.org/rosbag/Commandline

There is a GUI tool to handle the record and playback of bag files called rqt_bag. To learn more about rqt_bag, go to: http://wiki.ros.org/rqt_bag.

The ROS Master

The ROS Master is much like a DNS server, associating unique names and IDs to ROS elements active in our system. When any node starts in the ROS system, it will start looking for the ROS Master and register the name of the node in it. So, the ROS Master has the details of all the nodes currently running on the ROS system. When any details of the nodes change, it will generate a callback and update with the latest details. These node details are useful for connecting with each node.

When a node starts publishing a topic, the node will give the details of the topic, such as name and data type, to the ROS Master. The ROS Master will check whether any other nodes are subscribed to the same topic. If any nodes are subscribed to the same topic, the ROS Master will share the node details of the publisher to the subscriber node. After getting the node details, these two nodes will interconnect using the TCPROS protocol, which is based on TCP/IP sockets. After connecting to the two nodes, the ROS Master has no role in controlling them. We might be able to stop either the publisher node or the subscriber node according to our requirement. If we stop any nodes, it will check with the ROS Master once again. This same method is used for the ROS services.

The nodes are written using the ROS client libraries, such as roscpp and rospy. These clients interact with the ROS Master using XML Remote Procedure Call (XMLRPC)-based APIs, which act as the backend of the ROS system APIs.

The ROS_MASTER_URI environment variable contains the IP and port of the ROS Master. Using this variable, ROS nodes can locate the ROS Master. If this variable is wrong, the communication between nodes will not take place. When we use ROS in a single system, we can use the IP of a localhost or the name localhost itself. But in a distributed network, in which computation is on different physical computers, we should define ROS_MASTER_URI properly; only then will the remote nodes be able find each other and communicate with each other. We need only one Master in a distributed system, and it should run on a computer in which all other computers can ping it properly to ensure that remote ROS nodes can access the Master.

The following diagram shows an illustration of how the ROS Master interacts with a publishing and subscribing node, with the publisher node publishing a string type topic with a Hello World message and the subscriber node subscribing to this topic:

Figure 8: Communication between the ROS Master and Hello World publisher and subscriber

When the publisher node starts publishing the Hello World message in a particular topic, the ROS Master gets the details of the topic and details of the node. It will search whether any node is subscribing to the same topic. If there are no nodes subscribing to the same topic at that time, both nodes remain unconnected. If the publisher and subscriber nodes run at the same time, the ROS Master exchanges the details of the publisher to the subscriber and they will connect and can exchange data through ROS messages.

Using the ROS parameter

When programming a robot, we might have to define robot parameters, such as robot controller gains P, I, and D. When the number of parameters increases, we might need to store them as files. In some situations, these parameters have to share between two or more programs too. In this case, ROS provides a parameter server, which is a shared server in which all ROS nodes can access parameters from this server. A node can read, write, modify, and delete parameter values from the parameter server.

We can store these parameters in a file and load them into the server. The server can store a wide variety of data types and can even store dictionaries. The programmer can also set the scope of the parameter, that is, whether it can be accessed by only this node or all the nodes.

The parameter server supports the following XMLRPC datatypes:

  • 32-bit integers
  • Booleans
  • Strings
  • Doubles
  • ISO8601 dates
  • Lists
  • Base64-encoded binary data

We can also store dictionaries on the parameter server. If the number of parameters is high, we can use a YAML file to save them. Here is an example of the YAML file parameter definitions:

/camera/name : 'nikon'  #string type 
/camera/fps : 30     #integer   
/camera/exposure : 1.2  #float  
/camera/active : true  #boolean 

The rosparam tool is used to get and set the ROS parameter from the command line. The following are the commands to work with ROS parameters:

  • $ rosparam set [parameter_name] [value]: This command will set a value in the given parameter
  • $ rosparam get [parameter_name]: This command will retrieve a value from the given parameter
  • $ rosparam load [YAML file]: The ROS parameters can be saved into a YAML file and it can load to the parameter server using this command
  • $ rosparam dump [YAML file]: This command will dump the existing ROS parameters to a YAML file
  • $ rosparam delete [parameter_name]: This command will delete the given parameter
  • $ rosparam list: This command will list existing parameter names

The parameters can be changed dynamically during the execution of the node that uses these parameters, using the dyamic_reconfigure package (http://wiki.ros.org/dynamic_reconfigure).

 

ROS community level


These are ROS resources that enable a new community for ROS to exchange software and knowledge. The various resources in these communities are as follows:

  • Distributions: Similar to the Linux distribution, ROS distributions are a collection of versioned metapackages that we can install. The ROS distribution enables easier installation and collection of the ROS software. The ROS distributions maintain consistent versions across a set of software.
  • Repositories: ROS relies on a federated network of code repositories, where different institutions can develop and release their own robot software components.
  • The ROS Wiki: The ROS community Wiki is the main forum for documenting information about ROS. Anyone can sign up for an account and contribute their own documentation, provide corrections or updates, write tutorials, and more.
  • Bug ticket system: If we find a bug in the existing software or need to add a new feature, we can use this resource.
  • Mailing lists: The ROS-users mailing list is the primary communication channel about new updates to ROS, as well as a forum to ask questions about the ROS software.
  • ROS Answers: This website resource helps to ask questions related to ROS. If we post our doubts on this site, other ROS users can see this and give solutions.
  • Blog: The ROS blog updates with news, photos, and videos related to the ROS community (http://www.ros.org/news).
 

What are the prerequisites for starting with ROS?


Before getting started with ROS and trying the code in this book, the following prerequisites should be met:

  • Ubuntu 16.04 LTS / Ubuntu 15.10 / Debian 8: ROS is officially supported by Ubuntu and Debian operating systems. We prefer to stick with the LTS version of Ubuntu, that is, Ubuntu 16.04.
  • ROS kinetic desktop full installation: Install the full desktop installation of ROS. The version we prefer is ROS kinetic, the latest stable version. The following link gives you the installation instruction of the latest ROS distribution: http://wiki.ros.org/kinetic/Installation/Ubuntu. Choose the ros-kinetic-desktop-full package from the repository list.

Running the ROS Master and the ROS parameter server

Before running any ROS nodes, we should start the ROS Master and the ROS parameter server. We can start the ROS Master and the ROS parameter server by using a single command called roscore, which will start the following programs:

  • ROS Master
  • ROS parameter server
  • rosout logging nodes

The rosout node will collect log messages from other ROS nodes and store them in a log file, and will also re-broadcast the collected log message to another topic. The /rosout topic is published by ROS nodes by using ROS client libraries such as roscpp and rospy, and this topic is subscribed by the rosout node which rebroadcasts the message in another topic called /rosout_agg. This topic has an aggregate stream of log messages. The roscore command is a prerequisite before running any ROS node. The following screenshot shows the messages printing when we run the roscore command in a Terminal.

The following is a command to run roscore on a Linux Terminal:

$ roscore

Figure 9: Terminal messages while running the roscore command

The following are explanations of each section when executing roscore on the Terminal:

  • In section 1, we can see a log file is created inside the ~/.ros/log folder for collecting logs from ROS nodes. This file can be used for debugging purposes.
  • In section 2, the command starts a ROS launch file called roscore.xml. When a launch file starts, it automatically starts the rosmaster and the ROS parameter server. The roslaunch command is a Python script, which can start rosmaster and the ROS parameter server whenever it tries to execute a launch file. This section shows the address of the ROS parameter server within the port.
  • In section 3, we can see the parameters such as rosdistro and rosversion displayed on the Terminal. These parameters are displayed when it executes roscore.xml. We look at roscore.xml and its details further in the next section.
  • In section 4, we can see the rosmaster node is started using ROS_MASTER_URI, which we defined earlier as an environment variable.
  • In section 5, we can see the rosout node is started, which will start subscribing the /rosout topic and rebroadcasting into /rosout_agg.

The following is the content of roscore.xml:

<launch> 
 <group ns="/"> 
  <param name="rosversion" command="rosversion roslaunch" /> 
  <param name="rosdistro" command="rosversion -d" /> 
  <node pkg="rosout" type="rosout" name="rosout" respawn="true"/> 
 </group> 
</launch> 

When the roscore command is executed, initially, the command checks the command-line argument for a new port number for the rosmaster. If it gets the port number, it will start listening to the new port number; otherwise, it will use the default port. This port number and the roscore.xml launch file will pass to the roslaunch system. The roslaunch system is implemented in a Python module; it will parse the port number and launch the roscore.xml file.

In the roscore.xml file, we can see the ROS parameters and nodes are encapsulated in a group XML tag with a / namespace. The group XML tag indicates that all the nodes inside this tag have the same settings.

The two parameters called rosversion and rosdistro store the output of the rosversionroslaunch and rosversion-d commands using the command tag, which is a part of the ROS param tag. The command tag will execute the command mentioned on it and store the output of the command in these two parameters.

The rosmaster and parameter server are executed inside roslaunch modules by using the ROS_MASTER_URI address. This is happening inside the roslaunch Python module. The ROS_MASTER_URI is a combination of the IP address and port in which rosmaster is going to listen. The port number can be changed according to the given port number in the roscore command.

Checking the roscore command output

Let's check the ROS topics and ROS parameters created after running roscore. The following command will list the active topics on the Terminal:

$ rostopic list

The list of topics is as follows, as per our discussion on the rosout node subscribe /rosout topic. This has all the log messages from the ROS nodes and /rosout_agg will rebroadcast the log messages:

/rosout/rosout_agg

The following command lists the parameters available when running roscore. The following is the command to list the active ROS parameter:

$ rosparam list

The parameters are mentioned here; they have the ROS distribution name, version, address of the roslaunch server and run_id, where run_id is a unique ID associated with a particular run of roscore:

/rosdistro/roslaunch/uris/host_robot_virtualbox__51189/rosversion/run_id

The list of the ROS service generated during the running roscore can be checked using the following command:

$ rosservice list

The list of services running is as follows:

/rosout/get_loggers/rosout/set_logger_level

These ROS services are generated for each ROS node for setting the logging levels.

 

Questions


After going through the chapter, you should now be able to answer the following questions:

 

  • Why should we learn ROS?
  • How does ROS differ from other robotic software platforms?
  • What are the basic elements of ROS framework?
  • What is the internal working of roscore?
 

Summary


ROS is now a trending software framework among roboticists. Gaining knowledge in ROS is essential in the upcoming years if you are planning to build your career as a robotics engineer. In this chapter, we have gone through the basics of ROS, mainly to refresh the concepts if you have already learned ROS. We discussed the necessity of learning ROS and how it excels among the current robotics software platforms. We went through the basic concepts, such as the ROS Master, the parameter server, and roscore , and looked at the explanation of the working of roscore. In the next chapter, we will introduce the ROS package management, discussing some practical examples of the ROS communication system.

About the Authors

  • Lentin Joseph

    Lentin Joseph is an author and robotics entrepreneur from India. He runs a robotics software company called Qbotics Labs in India. He has 7 years of experience in the robotics domain primarily in ROS, OpenCV, and PCL.

    He has authored four books in ROS, namely, Learning Robotics using Python, Mastering ROS for Robotics Programming, ROS Robotics Projects, and Robot Operating System for Absolute Beginners.

    He is currently pursuing his master's in Robotics from India and is also doing research at Robotics Institute, CMU, USA.

    Browse publications by this author
  • Jonathan Cacace

    Jonathan Cacace was born in Naples, Italy, on December 13, 1987. He received his Master’s degree in computer science, and a Ph.D. degree in Information and Automation Engineering, from the University of Naples Federico II.

    Currently, he is a postdoc at the PRISMA Lab of the University of Naples Federico II. He is involved in different research projects focused on industrial and service robotics in which he has developed several ROS-based applications integrating robot perception and control

    Browse publications by this author

Latest Reviews

(5 reviews total)
muito bom o livro é excelente a qualidade é muito boa
A simple purchase process.
k as s sa fda sf sd sd fsa fda dfa

Recommended For You

ROS Robotics Projects - Second Edition

Build exciting robotics projects such as mobile manipulators, self-driving cars, and industrial robots powered by ROS, machine learning, and virtual reality

By Ramkumar Gandhinathan and 1 more
Artificial Intelligence for Robotics

Bring a new degree of interconnectivity to your world by building your own intelligent robots

By Francis X. Govers
Learning Robotics using Python - Second Edition

Design, simulate, and program interactive robots

By Lentin Joseph
ROS Robotics By Example - Second Edition

Learning how to build and program your own robots with the most popular open source robotics programming framework

By Carol Fairchild and 1 more