Robot Operating System
Lecturers: Leobardo Emanuel Campos Macı́as
Email: lecampos@[Link]
Abstract
This course gives an introduction to the Robot Operating System (ROS) including many of the available
tools that are commonly used in robotics. With the help of different examples, the course should provide
a good starting point for students to work with robots. They learn how to create software including
simulation, to interface sensors and actuators, and to integrate control algorithms.
Robot Operating System by Leo Campos 2
Objective
I ROS architecture: Master, nodes, topics, messages,
services, parameters and actions
I Console commands: Navigating and analyzing the
ROS system and the catkin workspace
I Creating ROS packages: Structure, launch-files, and
best practices
I ROS C++ client library (roscpp): Creating your
own ROS C++ programs
I Simulating with ROS: Gazebo simulator, robot
models (URDF) and simulation environments (SDF)
I Working with visualizations (RViz) and user interface
tools (rqt)
I Inside ROS: TF transformation system, time, bags
Robot Operating System by Leo Campos 3
Content
This course consists of a guided tutorial and exercises with increasing level of difficulty when working
with an autonomous robot. You learn how to setup such a system from scratch using ROS, how to
interface the individual sensors and actuators, and finally how to implement first closed loop control
systems.
Robot Operating System by Leo Campos 4
Disclaimer
This presentation may contain copyrighted material, the use of which may not have been specifically
authorized by the copyright owner. Some slides are based material from online available resources and
adapted for the purpose of this course.
Robot Operating System by Leo Campos 5
Preparation before the course
As the course will start using ROS and Ubuntu on the first day, we expect you to prepare your laptop
with a working environment before the course with the Course Preparation Instructions (PDF,816Kb)
Robot Operating System by Leo Campos 6
Outline Course
Linux Introduction
C++ Compilation
Object-Oriented Programming (OOP)
Robot Operating System - I
Robot Operating System - II
Robot Operating System - III
Robot Operating System - IV
Robot Operating System by Leo Campos 7
Linux Introduction
Linux Introduction
Ubuntu Installation
Linux History
Linux Distribution Families
Filesystem Hierarchy Standard
Command Line
Robot Operating System by Leo Campos 8
Ubuntu Installation
Is everybody at this point?
Robot Operating System by Leo Campos 9
Linux History
I Linux is a free open source computer operating
system initially developed for Intel x86-based personal
computers.
I Linus Torvalds started writing his own operating
system kernel
I In 1992, Linux was re-licensed using the General
Public License (GPL) by GNU
I Combining the kernel with other system components
from the GNU project, Linux Distributions were
created
I Today, Linux powers more than half of the servers on
the Internet, the majority of smart-phones, and nearly
all of the world’s most powerful supercomputers.
Robot Operating System by Leo Campos 10
Linux Distribution Families
Three Major Linux Distribution Families
Robot Operating System by Leo Campos 11
Debian Family
The Debian distribution is upstream for several other distributions including Ubuntu
I The Linux kernel 3.13 is used in Ubuntu 14.04
I It uses the DPKG-based apt-get package manager to install,
update, and remove packages in the system
I Ubuntu has been widely used for Robotics
I While Ubuntu is built on top of Debian, it uses the Unity
graphical interface
Robot Operating System by Leo Campos 12
Filesystem Hierarchy Standard
Robot Operating System by Leo Campos 13
Command Line
Graphical user interfaces make easy tasks easier, while command line interfaces make difficult tasks
possible
I No GUI overhead
I Virtually every task can be accomplished using the
command line
I You can script tasks and series of procedures
I You can log on remotely to networked machines
anywhere on the Internet
I You can initiate graphical apps directly from the
command line
Robot Operating System by Leo Campos 14
Command Line
Most input lines entered at the shell prompt have three basic elements:
I Command
I Options
I Arguments
The command is the name of the program you are executing. It may be followed by one or more options
(or switches) that modify what the command may do. Options usually start with one or two dashes, for
example,-p or–print, in order to differentiate them from arguments, which represent what the command
operates on.
Robot Operating System by Leo Campos 15
SUDO
Sudo allows users to run programs using the security privileges of another user, generally root (superuser).
The functionality of sudo is similar to that of run as in Windows.
Robot Operating System by Leo Campos 16
Basic Operations
Robot Operating System by Leo Campos 17
Accessing Directories
Robot Operating System by Leo Campos 18
Absolute and Relative Paths
Robot Operating System by Leo Campos 19
Exploring the FileSystem
Robot Operating System by Leo Campos 20
Searching for Files
I The locate utility program performs a search through a previously constructed database of files
and directories on your system, matching all entries that contain a specified character string.
To get a shorter more relevant list we can use the grep program as a filter; grep will print only the
lines that contain one or more specified strings as in: $ locate zip — grep bin
I The find command lists all files in the current directory and all of its subdirectories. Commonly
used options to shorten the list include -name (only list files with a certain pattern in their name),
-iname (also ignore the case of file names), and -type (which will restrict the results to files of a
certain specified type, such as d for directory, l for symbolic link or f for a regular file, etc).
Searching for files and directories named ”gcc”: $ find /usr -name gcc
Robot Operating System by Leo Campos 21
Viewing Files
Robot Operating System by Leo Campos 22
touch and mkdir
I touch is often used to set or update the access, change, and modify times of files. By default it
resets a file’s time stamp to match the current time.
However, you can also create an empty file using touch:$ touch <filename>
I mkdir is used to create a directory.
To create a sample directory named sampdir under the current directory, type $ mkdir sampdir.
Robot Operating System by Leo Campos 23
Removing a File
Robot Operating System by Leo Campos 24
Renaming or Removing a Directory
Robot Operating System by Leo Campos 25
Package Management Systems on Linux
The Advanced Packaging Tool (apt) is the underlying package management system that manages
software on Debian-based systems. While it forms the backend for graphical package managers, such
as the Ubuntu Software Center and synaptic, its native user interface is at the command line, with
programs that include apt-get and apt-cache.
Robot Operating System by Leo Campos 26
C++ Compilation
C++ Compilation
Basic Compilation
Projects Structure
CMakeList
Google C++ Programming Standard
Assignment 1
Robot Operating System by Leo Campos 27
Basic Compilation
To compile the program, go to the directory where
you have saved the .cpp file and use the command
in the following format
Install build-essential, a package that consists of
various software that you will need to compile $ g++ -o exe_name file_name.cpp
programs, including gcc and g++ compilers.
Normally, build-essential should already be installed with -o option, your are telling the compiler to
on your system. generate the executable code.
Once you have compiled the code, you’ll get the
$ sudo apt-get install build-essential
executable file. You just need to run it in the
following manner
$ ./exe_name
Robot Operating System by Leo Campos 28
Random Numbers Generator
/* rand example: guess the number */
Create a folder for our project #include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */
$ mkdir rand_gen
$ cd rand_gen int main ()
{
int iSecret;
Then, we will create a main file and add our code int iGuess;
/* initialize random seed: */
srand (time(NULL));
$ gedit [Link]
/* generate secret number between 1 and 10: */
iSecret = rand() % 10 + 1;
When finish, save it and compile it do{
printf ("Guess the number (1 to 10): ");
scanf ("%d", &iGuess);
$ g++ -o rand [Link] if (iSecret < iGuess){
printf("The secret number is lower");
}else if (iSecret > iGuess){
And we are ready for execution printf("The secret number is higher");
}
} while (iSecret != iGuess);
$ ./rand printf("Congratulations!");
return 0;
}
Robot Operating System by Leo Campos 29
Projects Structure
The recommended structure for C++ projects
Let’s change the structure of our project and try to compile it
$ g++ -o rand ../src/[Link]
Robot Operating System by Leo Campos 30
CMakeList
Install cmake, a package for compiling C++ code
using CMakeList files Finally the source code and executable name are
included
$ sudo apt-get install cmake
add_executable( randexe src/[Link] )
The project name and the minimum version of
Example:
cmake are located at the top of the CMakeFile
cmake_minimum_required(VERSION 2.8.3)
cmake_minimum_required(VERSION 2.8.3)
project(rand)
project(rand)
set(CMAKE_CXX_FLAGS "-std=c++11 -O3 ${CMAKE_CXX_FLAGS}")
It is followed by the compilation flags parameters
INCLUDE_DIRECTORIES(
set(CMAKE_CXX_FLAGS "-std=c++11 -O3 ${CMAKE_CXX_FLAGS}") include )
add_executable(
Then, the headers directories are specified randexe
src/[Link] )
INCLUDE_DIRECTORIES( include )
Robot Operating System by Leo Campos 31
CMakeList
Call cmake .. for start creating cmake files and
cache
$ cmake ../
Create and move to build directory
$ mkdir build
$ cd build
and simply make to compile the source files and
generate the executable
$ make
Robot Operating System by Leo Campos 32
Google C++ Programming Standard
I Headers and source code must be separated (some class [Link] some class [Link])
I Place code in a namespace
I Use more than three characters for variable naming
I No magic numbers! always use const variables
I Pass constant variables trough reference
I Destructor should be virtual
I Prefer small and focused functions
I Place local variables declaration at the top of the function
More info at: [Link]
Robot Operating System by Leo Campos 33
Example
/* sort example: sort a random list of numbers */
for(int indx=0; indx < exp_num; indx++)
#include <iostream> // cout
{
#include <stdlib.h> // random generator
for(int ind=0; ind < klist_size; ind++)
#include <time.h> // get system date
{
#include <ctime> // get clock
numbers[ind] = (rand()%limit_rand + 1);
//push a random number to vector
void sort_list(int *numbers);
}
void printList(int *numbers);
void my_sort(int *numbers);
std::cout<<" Original : \n ";
printList(numbers);
static const int klist_size = 10;
begin = clock();
int main()
sort_list(numbers);
{
end = clock();
int numbers[klist_size]; //array for random numbers
time_sum += double(end - begin) / CLOCKS_PER_SEC;
clock_t begin; // gets curret state of clock time proc
}
clock_t end; // gets current state of clock time proc
std::cout<<" Time : " << time_sum / (double)exp_num;
const int limit_rand = 30;
std::cout<<"\n Ordered : \n ";
const int exp_num = 1;
printList(numbers);
double time_sum = 0.0;
return 0;
srand(time(NULL)); // get time from system and is used
}
// as input for rand numbers gen
Robot Operating System by Leo Campos 34
Example
void sort_list(int *numbers)
{
for(int idx = 0; idx < klist_size; idx++)
{
for(int idy = idx + 1; idy < klist_size; idy++)
{
if( numbers[idx] > numbers[idy])
{
int temp = numbers[idx];
numbers[idx] = numbers[idy];
numbers[idy] = temp;
}
}
}
}
void printList(int *numbers)
{
for(int ind=0; ind < klist_size; ind++)
{
std::cout<<numbers[ind]<<" ";
}
}
void my_sort(int *numbers)
{
// your code here
}
Robot Operating System by Leo Campos 35
Assignment 1
I Create a function that receives a variable list of n-size and returns a sorted list
I Test your code and measure the execution time
I Should be better than the implemented in class
I Do not use sort method of STL
I Code must be uploaded to BlackBoard
I Must use setup script for packing and checking your code
This Assignment is individual Copied programs will be canceled
Robot Operating System by Leo Campos 36
OOP
Object-Oriented Programming (OOP)
Why OOP?
OOP Basics
Separating Header and Implementation
Example: The Point Class
Assignment 2
Robot Operating System by Leo Campos 37
Why OOP?
Traditional procedural-oriented languages (such as C) suffer some notable drawbacks in creating reusable
software components:
I The programs are made up of functions.
Functions are often not reusable. It is very
difficult to copy a function from one program
and reuse in another program because the the
function is likely to reference the headers,
global variables and other functions.
I The procedural languages are not suitable of
high-level abstraction for solving real life
problems. For example, C programs uses
constructs such as if-else, for-loop, array,
function, pointer, which are low-level and hard
to abstract real problems.
Robot Operating System by Leo Campos 38
Why OOP?
Object-oriented programming (OOP) languages are designed to overcome these problems.
I The basic unit of OOP is a class, which
encapsulates both the static attributes and
dynamic behaviors within a ”box”, and
specifies the public interface for using these
boxes. Since the class is well-encapsulated
(compared with the function), it is easier to
reuse these classes.
I OOP languages permit higher level of
abstraction for solving real-life problems. The
traditional procedural language (such as C)
forces you to think in terms of the structure of
the computer (e.g. memory bits and bytes,
array, decision, loop) rather than thinking in
terms of the problem you are trying to solve.
Robot Operating System by Leo Campos 39
Why OOP?
Suppose you wish to write a computer soccer games. Using OOP languages, you can easily model the
program accordingly to the ”real things” appear in the soccer games.
I Player: attributes include name, number,
location in the field, and etc; operations
include run, jump, kick-the-ball, and etc.
I Ball:
I Reference:
I Field:
I Audience:
I Weather:
Robot Operating System by Leo Campos 40
Classes & Instances
I Class: A class is a definition of objects of the same kind. In other words, a class is a blueprint,
template, or prototype that defines and describes the static attributes and dynamic behaviors
common to all objects of the same kind.
I Instance: An instance is a realization of a particular item of a class. In other words, an instance is
an instantiation of a class. All the instances of a class have similar properties, as described in the
class definition. For example, you can define a class called ”Student” and create three instances of
the class ”Student” for ”Peter”, ”Paul” and ”Pauline”.
The term object usually refers to instance. But it is often used quite loosely, which may refer to a class
or an instance.
Robot Operating System by Leo Campos 41
Classes & Instances
A class can be visualized as a three-compartment box:
I Classname (or identifier): identifies the class.
I Data Members or Variables (or attributes,
states, fields): contains the static attributes of
the class.
I Member Functions (or methods, behaviors,
operations): contains the dynamic operations
of the class.
Robot Operating System by Leo Campos 42
Classes & Instances
A few examples of classes:
Robot Operating System by Leo Campos 43
Classes & Instances
Two instances of the class Student, identified as ”paul” and ”peter”:
Robot Operating System by Leo Campos 44
Class Definition
In C++, we use the keyword class to define a class
class Circle // classname class SoccerPlayer // classname
{ {
private: private:
double radius; // Data members (variables) int number; // Data members (variables)
string color; string name;
int varx, vary;
public: public:
double getRadius(); // Member functions void run(); // Member functions
double getArea(); void kickBall();
} }
Robot Operating System by Leo Campos 45
Creating Instances of a Class
// Construct 3 instances of the class Circle: c1, c2, and c3
Circle circ1(1.2, "red"); // radius, color
To create an instance of a class, you have to: Circle circ2(3.4); // radius, default color
Circle circ3; // default radius and color
I Declare an instance identifier (name) of a
particular class. Alternatively, you can invoke the constructor explicitly
I Invoke a constructor to construct the using the following syntax:
instance Circle circ1 = Circle(1.2, "red"); // radius, color
Circle circ2 = Circle(3.4); // radius, default color
Circle circ3 = Circle(); // default radius and color
Robot Operating System by Leo Campos 46
Dot (.) Operator
/// Declare and construct instances c1 and c2 of the class Circle
Circle circ1(1.2, "blue");
Circle circ2(3.4, "green");
// Invoke member function via dot operator
cout << [Link]() << endl;
To reference a member of a object (data cout << [Link]() << endl;
member or member function), you must: // Reference data members via dot operator
[Link] = 5.5;
I First identify the instance you are [Link] = 6.6;
interested in, and then
I Use the dot operator (.) to reference Calling getArea() without identifying the instance is
the member, in the form of meaningless, as the radius is unknown.
[Link]
In general, suppose there is a class called AClass with a data
member called aData and a member function called
aFunction(). An instance called anInstance is constructed for
AClass. You use [Link] and
[Link]().
Robot Operating System by Leo Campos 47
Data Members (Variables)
A data member (variable) has a name (or identifier) and a type; and holds a value of that particular
type. A data member can also be an instance of a certain class. Data Member Naming Convention:
A data member name shall be a noun or a noun phrase made up of several words.
Robot Operating System by Leo Campos 48
Member Functions
A member function:
I receives parameters from the caller
I performs the operations defined in the function body
I returns a piece of result (or void) to the caller
Member Function Naming Convention: A function name shall be a verb, or a verb phrase made up
of several words.
Robot Operating System by Leo Campos 49
Example
A class called Circle is to be defined. It contains
two data members: radius (of type double) and
color (of type String); and three member functions:
getRadius(), getColor(), and getArea().
Three instances of Circles called circ1, circ2, and
circ3 shall then be constructed with their
respective data members.
Robot Operating System by Leo Campos 50
Example
/* The Circle class */
#include <iostream> // using IO functions
#include <string> // using string
const double var_pi = 3.1416; // Test driver function
class Circle { int main()
private: {
double radius_; // Data member (Variable) // Construct a Circle instance
string color_; // Data member (Variable) Circle circ1(1.2, "blue");
cout << "Radius=" << [Link]() << " Area=" << [Link]()
public: << " Color=" << [Link]() << endl;
// Constructor with default values for data members
Circle(double radius = 1.0, string color = "red") { // Construct another Circle instance
radius_ = radius; Circle circ2(3.4); // default color
color_ = color; cout << "Radius=" << [Link]() << " Area=" << [Link]()
} << " Color=" << [Link]() << endl;
double getRadius() { // Member function (Getter)
return radius_; // Construct a Circle instance using default no-arg constructor
} Circle circ3; // default radius and color
cout << "Radius=" << [Link]() << " Area=" << [Link]()
string getColor() { // Member function (Getter) << " Color=" << [Link]() << endl;
return color_; return 0;
} }
double getArea() { // Member function
return radius*radius*var_pi;
}
}; // need to end the class declaration with a semi-colon
Robot Operating System by Leo Campos 51
Constructors
A constructor is a special function that has the function name same as the classname. A constructor is
used to construct and initialize all the data members.
// Constructor has the same name as the class
I The name of the constructor is the same as Circle(double radius = 1.0, string color = "red")
{
the classname. radius_ = radius;
I Constructor has no return type (or implicitly }
color_ = color;
returns void). Hence, no return statement is
allowed inside the constructor’s body. To create a new instance of a class, you need to
I Constructor can only be invoked once to declare the name of the instance and invoke the
initialize the instance constructed. You cannot constructor.
call the constructor afterwards in your
Circle circ1(1.2, "blue");
program. Circle circ2(3.4); // default color
Circle circ3; // default radius and color
I Constructors are not inherited // Take note that there is no empty bracket ()
Robot Operating System by Leo Campos 52
public vs. private
An access control modifier can be used to control the visibility of a data member or a member function
within a class. We begin with the following two access control modifiers:
For example, in the above Circle definition, the
data member radius is declared private. As the
I public: The member (data or function) is result, radius is accessible inside the Circle class,
accessible and available to all in the system. but NOT outside the class. In other words, you
I private: The member (data or function) is cannot use [Link] to refer to circ1’s radius in
accessible and available within this class only. main(). Observe the error message:
error: 'double Circle::radius' is private
Robot Operating System by Leo Campos 53
Keyword this
Use keyword this to refer to this instance inside a class definition.
One of the main usage of keyword this is to resolve ambiguity between the names of data member and
function parameter.
class Circle {
private:
double radius; // Member variable called "radius"
......
public:
void setRadius(double radius) { // Function's argument also called "radius"
this->radius = radius;
// "[Link]" refers to this instance's member variable
// "radius" resolved to the function's argument.
}
......
}
You can use keyword this to resolve this naming conflict. this-¿radius refers to the data member; while
radius resolves to the function parameter.
this is actually a pointer to this object.
Use a prefix (such as m ) or suffix (such as ) to name the data members to avoid name crashes.
Robot Operating System by Leo Campos 54
const Member Functions
A const member function, identified by a const keyword at the end of the member function’s header,
cannot modifies any data member of this object.
double getRadius() const{ // const member function
radius = 0;
// error: assignment of data-member 'Circle::radius' in read-only structure
return radius;
}
Robot Operating System by Leo Campos 55
Destructor
A destructor, similar to constructor, is a special function that has the same name as the classname, with
a prefix , e.g., Circle(). Destructor is called implicitly when an object is destroyed.
If you do not define a destructor, the compiler provides a default, which does nothing.
class MyClass {
public:
// The default destructor that does nothing
virtual ~MyClass() { }
......
}
Robot Operating System by Leo Campos 56
Separating Header and Implementation
For better software engineering, it is recommended that the class declaration and implementation be
kept in 2 separate files: declaration is a header file .h; while implementation in a .cpp.
This is known as separating the public interface (header declaration) and the implementation. Interface
is defined by the designer, implementation can be supplied by others.
While the interface is fixed, different vendors can provide different implementations. Furthermore, only
the header files are exposed to the users, the implementation can be provided in an object file ”.o” (or
in a library). The source code needs not given to the users.
Robot Operating System by Leo Campos 57
Example: The Point Class
The Point class, as shown in the class diagram, models 2D
points with x and y co-ordinates.
In the class diagram, - denotes private member; + denotes
public member. = xxx specifies the default value of a data
member.
The Point class contains the followings:
I Private data members x and y (of type int), with default
values of 0.
I A constructor, getters and setters for private data
member x and y.
I A function setXY() to set both x and y coordinates of a
Point.
p
I A function getMagnitude() which returns x2 + y 2 .
I A function getArgument() which returns tan−1 (x/y).
I A function print() which prints (x,y) of this instance.
Robot Operating System by Leo Campos 58
Example: The Point Class
[Link] - Implementation
Point.h - Header
/* The Point class Implementation ([Link]) */
/* The Point class Header (Point.h) */ #include "Point.h" // user-defined header in the same directory
#ifndef POINT_H #include <iostream>
#define POINT_H #include <cmath>
// Point class declaration // Constructor (default values can only be specified in the declaration)
class Point Point::Point(int varx, int vary) : varx_(varx), vary_(vary) { }
{ // Public getter for private data member x
private: int Point::getX() const {
// private data members (variables) return varx_;
int varx_; }
int vary_; // Public setter for private data member x
void Point::setX(int varx) {
public: this->varx_ = varx;
// Declare member function prototypes }
Point(int varx = 0, int vary = 0); // Constructor with default values // Public getter for private data member y
int getX() const; int Point::getY() const {
void setX(int varx); return vary_;
int getY() const; }
void setY(int vary); // Public setter for private data member y
void setXY(int varx, int vary); void Point::setY(int vary) {
double getMagnitude() const; this->vary_ = vary;
double getArgument() const; }
void print() const; // Public member function to set both x and y
}; void Point::setXY(int varx, int vary) {
this->varx_ = varx;
#endif this->vary_ = vary;
}
Robot Operating System by Leo Campos 59
Example: The Point Class
[Link] - Test Driver
/* A test driver for the Point class ([Link]) */
#include <iostream>
#include <iomanip>
[Link] - Implementation #include "Point.h" // using Point class
using namespace std;
// Public member function to return the magitude
int main() {
double Point::getMagnitude() const {
// Construct an instance of Point p1
return sqrt(varx_*varx_ + vary_*vary_); // sqrt in <cmath>
Point point1(3, 4);
}
[Link]();
cout << "x = " << [Link]() << endl;
// Public member function to return the argument
cout << "y = " << [Link]() << endl;
double Point::getArgument() const {
cout << fixed << setprecision(2);
return atan2(vary_, varx_); // atan2 in <cmath>
cout << "mag = " << [Link]() << endl;
}
cout << "arg = " << [Link]() << endl;
[Link](6);
// Public member function to print description about this point
[Link](8);
void Point::print() const {
[Link]();
cout << "(" << varx_ << "," << vary_ << ")" << endl;
[Link](1, 2);
}
[Link]();
// Construct an instance of Point using default constructor
Point point2;
[Link]();
}
Robot Operating System by Leo Campos 60
Assignment 2: Moving Pendulum
A simple pendulum means a mass m suspended by a string or weightless rigid rod of length l so that
it can swing in a plane. The y-axis is directed down, x-axis is directed horizontally, i.e. x = l sin θ,
y = l cos θ. The kinetic energy is then
1 1 1
T = mv 2 = m(ẍ2 + ÿ 2 ) = m(lθ̇)2
2 2 2
Write a class with the following characteristics:
I Private data members l (length) and g (gravity) (of type double), with default corresponding
values.
I A constructor, getters and setters for private data member l and g.
I A function setLG() to set both l and g constants for the pendulum.
I A function getPeriod() which returns the period of the pendulum.
I A function getFrequency() which returns the frequency of the pendulum.
I A function print() which prints (l, g) of this instance.
Robot Operating System by Leo Campos 61
Assignment 2: Moving Pendulum
Assignment instructions:
I You have to create three instances, one for test you pendulum with a desired length in the earth,
other for test it in the moon, and a third for testing in an airplane in free fall.
I Create in a PDF the class diagram and include in data directory
I Code must be uploaded to BlackBoard
I Must use setup script for packing and checking your code
This Assignment is individual Copied programs will be canceled
Robot Operating System by Leo Campos 62
Outline I
Robot Operating System - I
ROS architecture & philosophy
Console commands
Catkin workspace and build system
Launch-files
Gazebo simulator
Robot Operating System by Leo Campos 63
ROS Installation
Setup your [Link]
sudo sh -c 'echo "deb [Link]
\$(lsb\_release -sc) main" $>$ /etc/apt/[Link].d/
[Link]'
Set up your keys Different versions
sudo apt-key adv --keyserver 'hkp://[Link]'
of ROS exits
--recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
Update debian package index
sudo apt-get update
NOTE: You may need to copy by
Install desktop full version hand the commands (ctrl+c may
sudo apt-get install ros-melodic-desktop-full not work)
Initialize rosdep
sudo rosdep init &&
rosdep update
More Info
Robot Operating System by Leo Campos [Link] 64
What is ROS ?
ROS = Robot Operating System
Plumbing Tools Capabilities Ecosystem
I Process I Simulation I Control I Package
management I Visualization I Planning organization
I Inter-process I Graphical user I Perception I Software distribution
communication interface I Mapping I Documentation
I Device drivers I Data logging I Manipulation I Tutorials
Robot Operating System by Leo Campos 65
History of ROS
I Originally developed in 2007 at the Stanford
Artificial Intelligence Laboratory
I Since 2013 managed by OSRF
I Today used by many robots, universities and
companies
I De facto standard for robot programming
Robot Operating System by Leo Campos 66
ROS Philosophy
I Peer to peer
Individual programs communicate over defined API (ROS messages, services, etc.).
I Distributed
Programs can be run on multiple computers and communicate over the network.
I Multi-lingual
ROS modules can be written in any language for which a client library exists (C++, Python,
MATLAB, Java, etc.).
I Light-weightr
Stand-alone libraries are wrapped around with a thin ROS layer.
I Free and open-source
Most ROS software is open-source and free to use.
Robot Operating System by Leo Campos 67
ROS Master
Master
Manages the communication between nodes
Every node registers at startup with the master
Start a master with
roscore
More Info
[Link]
Robot Operating System by Leo Campos 68
ROS Nodes
I Single-purpose, executable program
I Individually compiled, executed, and managed Registration Master Registration
I Organized in packages
Node 1 Node 2
Run a node with
rosrun package_name node_name
See active nodes with
rosnode list
Retrieve information about a node with
rosnode info node_name
More Info
[Link]
Robot Operating System by Leo Campos 69
ROS Topics
I Nodes communicate over topics
I Nodes can publish or subscribe to a topic
I Typically, 1 publisher and n subscribers
I Topic is a name for a stream of messages Registration Master Registration
Inf Connection
Node 1 Messages Node 2
List active topics with Publisher Subscriber
rostopic list
Subscribe and print the contents of a topic topic
Publish Subscribe
with
rostopic echo /topic
Show information about a topic with
rostopic info /topic
More Info
[Link]
Robot Operating System by Leo Campos 70
ROS Messages
I Data structure defining the type of a topic
I Compromised of a nested structure of integers,
Registration Master Registration
floats, booleans, strings etc. and arrays of
Inf Connection
objects
Node 1 Messages Node 2
I Defined in *.msg files
Publisher Subscriber
See the type of a topic topic
Publish Subscribe
rostopic type /topic
int number
Publish a message to a topic
double width Message definition
rostopic pub /topic type args
string description
More Info
[Link]
Robot Operating System by Leo Campos 71
ROS Messages
Pose Stamped Example
geometry msgs/[Link]
geometry msgs/[Link]
float64 x
float64 y
float64 z std msgs/Header header
uint32 seq
time stamp
string frame id
geometry msgs/Pose pose
geometry msgs/Point position
float64 x
std msgs/Header header float64 y
uint32 seq time stamp float64 z
string frame id geometry msgs/Quaternion
uint32 height orientation
uint32 width float64 x
string encoding float64 y
uint8 is bigendian float64 z
uint32 step float64 w
uint8[] data
Robot Operating System by Leo Campos 72
Example
Console Tab Nr. 1 – Starting a roscore
Start a roscore with
roscore
Robot Operating System by Leo Campos 73
Example
Console Tab Nr. 2 – Starting a talker node
Run a talker demo node with
rosrun roscpp_tutorials talker
Robot Operating System by Leo Campos 74
Example
Console Tab Nr. 3 – Analyze talker node
See the list of active nodes
rosnode list
Show information about the talker node
rosnode info /talker
See information about the chatter topic
rostopic info /chatter
Robot Operating System by Leo Campos 75
Example
Console Tab Nr. 3 – Analyze chatter topic
Check the type of the chatter topic
rostopic type /chatter
Show the message contents of the topic
rostopic echo /chatter
Analyze the frequency
rostopic hz /chatter
Robot Operating System by Leo Campos 76
Example
Console Tab Nr. 4 – Starting a listener node
Run a listener demo node with
rosrun roscpp_tutorials listener
Robot Operating System by Leo Campos 77
Example
Console Tab Nr. 3 – Analyze
See the new listener node with
rosnode list
Show the connection of the nodes over the
chatter topic with
rostopic info /chatter
Robot Operating System by Leo Campos 78
Example
Console Tab Nr. 3 – Publish Message from Console
Close the talker node in console nr. 2 with
Ctrl + C
Publish your own message with
rostopic pub /chatter std_msgs/String
"data: 'ROS Course'"
Check the output of the listener in console
nr. 4
Robot Operating System by Leo Campos 79
catkin Build System
I catkin is the ROS build system to generate
executables, libraries, and interfaces
I We suggest to use the Catkin Command Line Tools
Use catkin build instead of catkin make
Installation in-
Navigate to your catkin workspace with dependent of
ROS packages
cd ~/ros_ws
Build a package with
catkin build package_name
Whenever you build a new package, update your
environment
source devel/[Link]
More Info
[Link]
Robot Operating System by Leo Campos [Link] 80
catkin Build System
The catkin workspace contains the following spaces
src build devel
Work here Don’t touch Don’t touch
The source space contains the The build space is where CMake The development (devel) space
source code. This is where you is invoked to build the packages is where built targets are placed
can clone, create, and edit in the source space. Cache (prior to being installed).
source code for the packages you information and other
want to build. intermediate files are kept here.
If necessary, clean the entire build and devel space with
More Info
catkin clean [Link]
Robot Operating System by Leo Campos 81
catkin Build System
The catkin workspace setup can be checked
with
catkin config
For example, to set the CMake build type
to Release (or Debug etc.), use
catkin build --cmake-args
-DCMAKE_BUILD_TYPE=Release
More Info
[Link]
catkin_config.html
[Link]
[Link]
Robot Operating System by Leo Campos 82
Example
Open a terminal and browse to your git folder
[Link]/leggedrobotics/ros_best_practices.git
cd ~/git
Clone the Git repository with
git clone
[Link]
Symlink the new package to your catkin workspace
ln -s ~/git/ros_best_practices/ ~/ros_ws/src/
Note: You could also directly clone to your catkin workspace, but using a
common git folder is convenient if you have multiple catkin workspaces.
Robot Operating System by Leo Campos 83
Example
Go to your catkin workspace
cd ~/ros_ws
Build the package with
catkin build ros_package_template
Re-source your workspace setup
source devel/[Link]
Launch the node with
roslaunch ros_package_template
ros_package_template.launch
Robot Operating System by Leo Campos 84
ROS Launch
Example console output for
roslaunch roscpp tutorials talker [Link]
I launch is a tool for launching multiple
nodes (as well as setting parameters)
I Are written in XML as *.launch files
I If not yet running, launch
automatically starts a roscore
Browse to the folder and start a launch file
with
roslaunch file_name.launch
Start a launch file from a package with
roslaunch package_name file_name.launch
More Info
[Link]
Robot Operating System by Leo Campos 85
ROS Launch
File Structure
talker [Link]
Notice the syntax difference
<launch>
for self-closing tags:
<node name="listener" pkg="roscpp_tutorials" type="listener" output="screen"/>
<tag></tag> and
<node name="talker" pkg="roscpp_tutorials" type="talker" output="screen"/>
</launch> <tag/>
I launch: Root element of the launch file
I node: Each <node> tag specifies a node to be launched
I name: Name of the node (free to choose)
I pkg: Package containing the node
I type: Type of the node, there must be a corresponding executable with the same name
I output: Specifies where to output log messages (screen: console, log: log file)
More Info
[Link]
Robot Operating System by Leo Campos 86
ROS Launch
Arguments <?xml version="1.0"?>
<launch>
<arg name="use_sim_time" default="true"/>
I Create re-usable launch files with <arg> <arg name="world" default="gazebo_ros_range"/>
tag, which works like a parameter <arg name="debug" default="false"/>
(default optional) <arg name="physics" default="ode"/>
<arg name="arg_name" default="default_value"/>
<group if="$(arg use_sim_time)">
<param name="/use_sim_time" value="true" />
I Use arguments in launch file with </group>
$(arg arg_name) <include file="$(find gazebo_ros)
/launch/empty_world.launch">
<arg name="world_name" value="$(find gazebo_plugins)/
I When launching, arguments can be set test/test_worlds/$(arg world).world"/>
<arg name="debug" value="$(arg debug)"/>
with
<arg name="physics" value="$(arg physics)"/>
roslaunch launch_file.launch arg_name:=value </include>
</launch>
More Info
[Link]
Robot Operating System by Leo Campos 87
ROS Launch
Including Other Launch Files <?xml version="1.0"?>
<launch>
I Include other launch files with <arg name="use_sim_time" default="true"/>
<include> tag to organize large <arg name="world" default="gazebo_ros_range"/>
<arg name="debug" default="false"/>
projects
<arg name="physics" default="ode"/>
<include file="package_name"/>
<group if="$(arg use_sim_time)">
<param name="/use_sim_time" value="true" />
</group>
I Find the system path to other
packages with <include file="$(find gazebo_ros)
$(find package_name) /launch/empty_world.launch">
<arg name="world_name" value="$(find gazebo_plugins)/
test/test_worlds/$(arg world).world"/>
<arg name="debug" value="$(arg debug)"/>
I Pass arguments to the included file <arg name="physics" value="$(arg physics)"/>
</include>
<arg name="arg_name" value="value"/>
</launch>
More Info
[Link]
Robot Operating System by Leo Campos 88
Gazebo Simulator
I Simulate 3d rigid-body dynamics Object tree Toolbar
I Simulate a variety of sensors including
noise
I 3d visualization and user interaction
I Includes a database of many robots
and environments (Gazebo worlds)
I Provides a ROS interface
I Extensible with plugins
Run Gazebo with
rosrun gazebo_ros gazebo
Properties Start and pause simulation
More Info
[Link]
[Link]
Robot Operating System by Leo Campos 89
Further References
I ROS Wiki I [Link]
I [Link] releases/download/0.0.1/
ROScheatsheet_catkin.pdf
I Installation
I [Link] I ROS Best Practices
I Tutorials I [Link]
I [Link] best_practices/wiki
I Available packages I ROS Package Template
I [Link] I [Link]
best_practices/tree/master/ros_
I ROS Cheat Sheet package_template
Robot Operating System by Leo Campos 90
Outline II
Robot Operating System - II
ROS package structure
ROS C++ client library (roscpp)
ROS subscribers and publishers
ROS parameter server
RViz visualization
Robot Operating System by Leo Campos 91
ROS Packages
Separate message definition
I ROS software is organized into
packages from other packages!
packages, which can contain source
code, launch files, configuration files,
package_name package_name_msgs
message definitions, data, and config action
documentation Parameter files (YAML) Action definitions
I A package that builds up on/requires include/package_name msg
C++ include headers Message definitions
other packages (e.g. message launch srv
definitions), declares these as *.launch files Service definitions
dependencies To create a new package, src [Link]
Source files CMake build file
test [Link]
use Unit/ROS tests Package information
[Link]
CMake build file
catkin_create_pkg package_name {dependencies}
[Link]
Package information
More Info
[Link]
Robot Operating System by Leo Campos 92
ROS Packages - [Link]
<?xml version="1.0"?>
<package format="2">
<name>ros_package_template</name>
<version>0.1.0</version>
I The [Link] file defines the <description>A template for ROS packages.</description>
properties of the package <maintainer email="lecamp@g...">Leo Campos</maintainer>
I <license>BSD</license>
Package name
I Version number <url type="website">[Link]</url>
I Authors <author email="lecamp@g...">Leo Campos</author>
I Dependencies on other packages
I ... <buildtool_depend>catkin</buildtool_depend>
<depend>roscpp</depend>
<depend>sensor_msgs</depend>
</package>
More Info
[Link]
Robot Operating System by Leo Campos 93
ROS Packages - [Link]
The [Link] is the input to the CMakebuild system
1. Required CMake Version (cmake minimum required)
2. Package Name (project()) cmake_minimum_required(VERSION 2.8.3)
project(ros_package_template)
3. Find other CMake/Catkin packages needed for build
(find package())
## Use C++11
4. Message/Service/Action Generators (add message files(), add_definitions(--std=c++11)
add service files(), add action files())
5. Invoke message/service/action generation ## Find catkin macros and libraries
(generate messages()) find_package(catkin REQUIRED
COMPONENTS
6. Specify package build info export (catkin package())
roscpp
7. Libraries/Executable to build sensor_msgs
(add library()/add executable()/target link libraries()) )
8. Tests to build (catkin add gtest())
9. Install rules (install()) More Info
[Link]
Robot Operating System by Leo Campos 94
ROS Packages - [Link] - Example
Use the same name as in the [Link]
cmake_minimum_required(VERSION 2.8.3) We use C++11 by default
project(ros_arduino_car)
add_definitions(--std=c++11) List the packages that your package requires to
find_package(catkin REQUIRED build (have to be listed in [Link])
COMPONENTS roscpp sensor_msgs ) Specify build export information
catkin_package(
INCLUDE_DIRS include I INCLUDE DIRS: Directories with header files
# LIBRARIES I LIBRARIES: Libraries created in this project
CATKIN_DEPENDS roscpp sensor_msgs
I CATKIN DEPENDS: Packages dependent projects
# DEPENDS
)
also need
include_directories(include ${catkin_INCLUDE_DIRS}) I DEPENDS: System dependencies dependent
add_executable(${PROJECT_NAME} projects also need (have to be listed in
src/${PROJECT_NAME}_node.cpp [Link])
src/comm_interface.cpp ) Specify locations of of header files
target_link_libraries(${PROJECT_NAME}
Declare a C++ executable
${catkin_LIBRARIES})
Specify libraries to link the executable against
Robot Operating System by Leo Campos 95
ROS C++ Client Library (roscpp)
ROS main header file include
#include <ros/ros.h>
ros::init(...) has to be called before calling other
int main(int argc, char** argv)
{ ROS functions
ros::init(argc, argv, "hello_world");
ros::NodeHandle nodeHandle; The node handle is the access point for
ros::Rate loopRate(10); communications with the ROS system (topics,
unsigned int count = 0; services, parameters)
while(ros::ok()) {
ROS_INFO_STREAM("Hello_World" ros::Rate is a helper class to run loops at a desired
<< count);
frequency ros::ok() checks if a node should
ros::spinOnce();
[Link]();
count++;
continue running
}
Returns false if SIGINT is received (Ctrl + C) or
return 0; ros::shutdown() has been called
}
ROS INFO() logs messages to the filesystem
More Info ros::spinOnce() processes incoming messages via
[Link] callbacks
[Link]
Robot Operating System by Leo Campos 96
ROS C++ Client Library (roscpp)
Node Handle
I There are four main types of node handles For a node in namespace looking up topic,
these will resolve to:
1. Default (public) node handle:
Recommended
nh = ros::NodeHandle();
/namespace/topic
2. Private node handle:
nh private = ros::NodeHandle("~"); /namespace/node/topic
3. Namespaced node handle:
nh itesm = ros::NodeHandle("course");
/namespace/course/topic
recommended
4. Global node handle: /topic
Not
nh global = ros::NodeHandle("/");
More Info
[Link]
Robot Operating System by Leo Campos 97
ROS C++ Client Library (roscpp) - Logging
I Mechanism for logging human readable text
from nodes in the console and to log files
Debug Info Warn Error Fatal
I Instead of std::cout, use e.g. ROS INFO stdout x x
I Automatic logging to console, log file, and stderr x x x
/rosout topic Log file x x x x x
/rosout x x x x x
I Different severity levels (Info, Warn, Error
etc.)
I Supports both printf- and stream-style
To see the output in the console, set the output
formatting configuration to screen in the launch file
ROS_INFO("Result: %d", result); <launch>
ROS_INFO_STREAM("Result: " << result); <node name="listener" output="screen"/>
</launch>
I Further features such as conditional, throttled,
delayed logging etc.
More Info
[Link]
[Link]
Robot Operating System by Leo Campos 98
ROS C++ Client Library (roscpp)
Subscriber
I Start listening to a topic by calling the
method subscribe() of the node handle #include "ros/ros.h"
#include "std_msgs/String.h"
ros::Subscriber subscriber =
[Link](topic, queue_size, callback_function);
void chatterCallback(const std_msgs::String& msg)
{
ROS_INFO("I_heard:_[%s]", [Link].c_str());
I When a message is received, callback }
function is called with the contents of the int main(int argc, char **argv)
message as argument {
ros::init(argc, argv, "listener");
I Hold on to the subscriber object until you ros::NodeHandle nodeHandle;
want to unsubscribe ros::Subscriber subscriber =
[Link]("chatter",10,
ros::spin() processes callbacks and will not chatterCallback);
return until the node has been shutdown ros::spin();
return 0;
More Info }
[Link]
20Subscribers
Robot Operating System by Leo Campos 99
ROS C++ Client Library (roscpp)
Publisher #include <ros/ros.h>
I Create a publisher with help of the node #include <std_msgs/String.h>
handle
int main(int argc, char **argv) {
ros::Publisher publisher = ros::init(argc, argv, "talker");
[Link]<message_type>(topic, queue_size); ros::NodeHandle nh;
ros::Publisher chatterPublisher =
[Link]<std_msgs::String>("chatter", 1);
I Create the message contents ros::Rate loopRate(10);
I Publish the contents with unsigned int count = 0;
while (ros::ok()) {
[Link](message);
std_msgs::String message;
[Link] = "hello_world" +
std::to_string(count);
ROS_INFO_STREAM([Link]);
[Link](message);
ros::spinOnce();
[Link]();
count++;
More Info }
[Link] return 0;
20Subscribers }
Robot Operating System by Leo Campos 100
ROS C++ Client Library (roscpp)
Object Oriented Programming
[Link] [Link]
#include <ros/ros.h> [Link] [Link]
#include "my_package/[Link]"
int main(int argc, char** argv) class MyPackage class Algorithm
{
ros::init(argc, argv, "my_package"); Main node class Class implementing
ros::NodeHandle nodeHandle("~");
my_package::MyPackage myPackage(nodeHandle); providing ROS interface the algorithmic part
ros::spin(); (subscribers, parameters, of the node
return 0;
} timers etc.) Note: The algorithmic part
of the code could be
separated in a
(ROS-independent) library
Specify a function handler to a method from within the class as
More Info
subscriber_ = nodeHandle_.subscribe(topic, queue_size, &ClassName::methodName, this);
[Link]
tutorials/Tutorials/
Robot Operating System by Leo Campos 101
ROS Parameter Server
I Nodes use the parameter server to store
and retrieve parameters at runtime camera:
I Best used for static data such as left:
configuration parameters name: left_camera
exposure: 1
I Parameters can be defined in launch files
right:
or separate YAML files name: right_camera
List all parameters with exposure: 1.1
rosparam list
Get the value of a parameter with <launch>
<node name="name" pkg="package" type="node_type">
rosparam get parameter_name <rosparam command="load"
file="$(find package)/config/[Link]" />
Set the value of a parameter with </node>
</launch>
rosparam set parameter_name value
More Info
[Link]
Robot Operating System by Leo Campos 102
ROS Parameter Server
C++ API
I Get a parameter in C++ with
[Link](parameter_name, variable)
I Method returns true if parameter was found, false
ros::NodeHandle nodeHandle("~");
otherwise std::string topic;
I Global and relative parameter access: if ()
{
[Link]("/package/camera/left/exposure", variable) ROS_ERROR("Could not find
topic parameter!");
I Relative parameter name (relative to the node handle)
}
[Link]("camera/left/exposure", variable)
I For parameters, typically use the private node handle
ros::NodeHandle(” ”)
More Info
[Link]
Robot Operating System by Leo Campos 103
RViz
I 3D visualization tool for ROS Displays Tools Views
I Subscribes to topics and visualizes the
message contents
I Different camera views (orthographic,
top- down, etc.)
I Interactive tools to publish user
information
I Save and load setup as RViz
configuration
I Extensible with plugins
Run RViz with
rosrun rviz rviz
Time
More Info
[Link]
Robot Operating System by Leo Campos 104
RViz
Display Plugins
Robot Operating System by Leo Campos 105
RViz
Visualizing Point Clouds Example
Frame in which the data is displayed (has to exist!)
Choose the topic for the display
Change the display options (e.g. size)
Robot Operating System by Leo Campos 106
Example
Two Wheeled Robot Controller
External Sensors
Mission
wrobot_controller wrobot_comm
High level config
[Link] msg
controller Parameter files (YAML) Message definitions
CMake build file
x_ref, y_ref [Link]
[Link] [Link]
Package information include/package_name
x, y Low level C++ include headers [Link]
controller [Link]
angular
[Link]
launch CMake build file
velocities *.launch files
[Link]
[Link] Package information
I The controller action is given
src
by the angular velocity of a two Source files
wheeled robot. Separte the algoritmic [Link]
I The loop is closed with the part from ROS
[Link]
robot position respect to the
world.
Robot Operating System by Leo Campos 107
I Configure the [Link] in order to properly
Example - wrobot comm generate the header files from the created messages
[Link]
cmake_minimum_required(VERSION 2.8.3)
project(wrobot_comm)
I Two messages types are defined:
find_package(catkin REQUIRED COMPONENTS
I [Link]: Position of the
geometry_msgs
robot w.r.t world frame
I [Link]: Angular velocity for message_generation
each wheel std_msgs)
[Link] # Declare the message files to be built
Header header add_message_files( FILES
std_msgs/Float32 velocity # [rad/s] [Link]
[Link])
[Link]
generate_messages(DEPENDENCIES
Header header
geometry_msgs
geometry_msgs/Pose2D pose # [m]
std_msgs)
catkin_package(CATKIN_DEPENDS
message_runtime)
Robot Operating System by Leo Campos 108
Example - wrobot comm
I Finally the [Link] element must include the message generation.
<?xml version="1.0"?>
<package>
<name>wrobot_comm</name>
<version>0.0.1</version>
<description>The wrobot_comm pkg</description>
<maintainer email="lecampos@[Link]">Leo Campos</maintainer>
<author>Leo Campos</author>
<license>ASL 2.0</license>
<buildtool_depend>catkin</buildtool_depend>
<!-- Dependencies needed to compile this package. -->
<build_depend>message_generation</build_depend>
<build_depend>geometry_msgs</build_depend>
<!-- Dependencies needed after this package is compiled. -->
<run_depend>message_runtime</run_depend>
</package>
Robot Operating System by Leo Campos 109
Example - wrobot controller
The core of the algorithm (controller) is separated from ROS libraries
[Link] [Link]
#ifndef CONTROLLER_HPP_ #include "wrobot_controller/[Link]"
#define CONTROLLER_HPP_
namespace controller
/* add any C++ library need it */ {
CController::CController(double *K)
namespace controller {
{ /* Any initialization, for example, some
class CController gains for the controller*/
{ this->K_gains[0] = K[0];
protected: this->K_gains[1] = K[1];
/*Any variable or private members here this->K_gains[2] = K[2];
i.e. gains */ }
double K_gains[3]; CController::~CController(void)
public: {
CController(double *K); }
virtual ~CController(void); void CController::getNewVelocity(double x_pos, double y_pos,
void getNewVelocity(double x_pos, double y_pos, double &vw_left, double &vw_right)
double &vw_left, double &vw_right); {
}; //Write your control here!
}
} /* controller */ } /* controller */
#endif // CONTROLLER_HPP_
Robot Operating System by Leo Campos 110
Example - wrobot controller [Link]
#include <ros/ros.h>
#include "wrobot_comm/WheelVelocity.h"
I Write two subscribers, one for the #include "wrobot_comm/RobotPosition.h"
reference and other for the current robot #include "wrobot_controller/[Link]"
position controller::CController *g_controllerHandler;
void getConstantParams(void);
I The msg type must be
wrobot comm::RobotPosition int main(int argc, char **argv)
{
I Write two publishers for both angular ros::init(argc, argv, "wrobot_controller");
ros::NodeHandle nh;
velocity wheels double timeStep = 0.01;
double x_pos; double y_pos; double vw_left; double vw_right;
I The msg type must be
wrobot comm::WheelVelocity while (ros::ok()){
ros::spinOnce();
I Complete your control library adding the // callback obtain the position and reference
g_controllerHandler->getNewVelocity(x_pos,y_pos,vw_left,vw_right);
necessary methods // publish new velocity...
ros::Duration(timeStep).sleep();
I Propose a control algorithm }
I Create a launch file for loading the gains }
return 0;
of the control. NOTE: This is helpful since you void getConstantParams(void){
//get params from YAML
avoid recompilation in the tuning process double *K_gains;
g_controllerHandler = new controller::CController(K_gains);
}
Robot Operating System by Leo Campos 111
Further References
I ROS Wiki I [Link]
I [Link] releases/download/0.0.1/
ROScheatsheet_catkin.pdf
I Installation
I [Link] I ROS Best Practices
I Tutorials I [Link]
I [Link] best_practices/wiki
I Available packages I ROS Package Template
I [Link] I [Link]
best_practices/tree/master/ros_
I ROS Cheat Sheet package_template
Robot Operating System by Leo Campos 112
Outline III
Robot Operating System - III
TF Transformation System
rqt User Interface
Robot models (URDF)
Simulation descriptions (SDF)
CAD to Gazebo
Gazebo plugins for ROS
Robot Operating System by Leo Campos 113
TF Transformation System
I Tool for keeping track of coordinate frames
over time
I Maintains relationship between coordinate
frames in a tree structure buffered in time
I Lets the user transform points, vectors, etc.
between coordinate frames at desired time
I Implemented as publisher/subscriber model on
the topics /tf and /tf static
Node Liste
ning
Broadcasting
Node /tf
Node
More Info
[Link]
Robot Operating System by Leo Campos 114
TF Transformation System
Transform Tree
I TF listeners use a buffer to listen to
all broadcasted transforms
I Query for specific transforms from
the transform tree
geometry_msgs/TransformStamped[] transforms
std_msgs/Header header
uint32 seqtime stamp
string frame_id
string child_frame_id
geometry_msgs/Transform transform
geometry_msgs/Vector3 translation
geometry_msgs/Quaternion rotation
Robot Operating System by Leo Campos 115
TF Transformation System
Tools
View Frames
Command line RViz
Creates a visual graph (PDF) of
Print information about the 3D visualization of the
the transform tree
current transform tree transforms
rosrun tf view_frames
rosrun tf tf_monitor
Print information about the
transform between two frames
rosrun tf tf_echo source_frame
target_frame
Robot Operating System by Leo Campos 116
TF Transformation System
RViz Plugin
Robot Operating System by Leo Campos 117
TF Transformation System - Transform Listener C++ API
I Create a TF listener to fill up a buffer
#include <ros/ros.h>
tf2_ros::Buffer tfBuffer; #include <tf2_ros/transform_listener.h>
#include <geometry_msgs/TransformStamped.h>
tf2_ros::TransformListener tfListener(tfBuffer);
int main(int argc, char** argv) {
ros::init(argc, argv, "tf2_listener");
ros::NodeHandle nodeHandle;
I Make sure, that the listener does not run tf2_ros::Buffer tfBuffer;
tf2_ros::TransformListener tfListener(tfBuffer);
out of scope!
ros::Rate rate(10.0);
I To lookup transformations, use while ([Link]()) {
geometry_msgs::TransformStamped transformStamped;
try {
geometry_msgs::TransformStamped transformStamped = transformStamped = [Link]("base",
[Link](target_frame_id, "odom", ros::Time(0));
} catch (tf2::TransformException &exception) {
source_frame_id, time);
ROS_WARN("%s", [Link]());
ros::Duration(1.0).sleep();
continue;
}
I For time, use ros::Time(0) to get the [Link]();
}
latest available transform return 0;
};
More Info
[Link]
20listener%20%28C%2B%2B%29
Robot Operating System by Leo Campos 118
rqt User Interface
I User interface base on Qt
I Custom interfaces can be setup
I Lots of existing plugins exist
I Simple to write own plugins
Run RQT with
rosrun rqt_gui rqt_gui
or
rqt
More Info
[Link]
Robot Operating System by Leo Campos 119
rqt User Interface - rqt image view
I Visualizing images
Run rqt graph with
rosrun rqt_image_view rqt_image_view
More Info
[Link]
Robot Operating System by Leo Campos 120
rqt User Interface - rqt plot
I Visualizing numeric values in 2D plots
Run rqt plot with
rosrun rqt_plot rqt_plot
More Info
[Link]
Robot Operating System by Leo Campos 121
rqt User Interface - rqt graph
I Visualizing the ROS computation graph
Run rqt graph with
rosrun rqt_graph rqt_graph
More Info
[Link]
Robot Operating System by Leo Campos 122
rqt User Interface - rqt console
I Displaying and filtering ROS messages
Run rqt console with
rosrun rqt_console rqt_console
More Info
[Link]
Robot Operating System by Leo Campos 123
rqt User Interface - rqt logger level
I Configuring the logger level of ROS nodes
Run rqt logger level with
rosrun rqt_logger_level rqt_logger_level
More Info
[Link]
Robot Operating System by Leo Campos 124
Example
I Start turtlesim example with keyboard
teleoperation:
In console nr. 1:
Start a roscore with
roscore
In console nr. 2:
Run a turtlesim demo node with
rosrun turtlesim turtlesim_node
In console nr. 3:
Run a key controller node with
rosrun turtlesim turtle_teleop_key
Robot Operating System by Leo Campos 125
Example - rqt graph
In console nr. 4:
Run rqt grap with
rosrun rqt_graph rqt_graph
Robot Operating System by Leo Campos 126
Example - rqt plot
In console nr. 4:
Run rqt plot with
rosrun rqt_plot rqt_plot
Robot Operating System by Leo Campos 127
Example - rqt logger level
CIn console nr. 4:
Run rqt logger level with
rosrun rqt_logger_level rqt_logger_level
Robot Operating System by Leo Campos 128
Robot Models
Unified Robot Description Format (URDF)
I Defines an XML format for representing a
robot model
I Kinematic and dynamic description
I Visual representation
I Collision model
I URDF generation can be be scripted with
XACRO
More Info
[Link]
[Link]
Robot Operating System by Leo Campos 129
Robot Models - Unified Robot Description Format (URDF)
<link name="link_name">
<visual>
<geometry>
I Description consists of a set of link <mesh filename="[Link]"/>
</geometry>
elements and a set of joint elements </visual>
I Joints connect the links together <collision>
<geometry>
<cylinder length="0.6" radius="0.2"/>
[Link] </geometry>
</collision>
< robot name = " robot " > <inertial>
< link > ... </ link > <mass value="10"/>
< link > ... </ link > <inertia ixx="0.4" ixy="0.0" />
</inertial>
< link > ... </ link >
</link>
< joint > .... </ joint >
< joint > .... </ joint >
< joint > .... </ joint >
</ robot >
<joint name="joint_name" type="revolute">
<axis xyz="0 0 1"/>
<limit effort="1000.0" upper="0.548" />
More Info <origin rpy="0 0 0" xyz="0.2 0.01 0"/>
[Link] <parent link="parent_link_name"/>
<child link="child_link_name"/>
</joint>
Robot Operating System by Leo Campos 130
Simulation Descriptions
Simulation Description Format (SDF)
I Defines an XML format to describe
I Environments (lighting, gravity etc.)
I Objects (static and dynamic)
I Sensors
I Robots
I SDF is the standard format for Gazebo
I Gazebo converts a URDF to SDF
automatically
More Info
[Link]
Robot Operating System by Leo Campos 131
Example - A two wheeled mobile robot
As example, we will create a two wheeled
mobile robot that uses a differential drive <?xml version="1.0"?>
mechanism for movement. <model>
I A model is usually conformed by two files: <name>wheeled_robot</name>
I model config file <version>1.0</version>
I model sdf file <sdf version='1.4'>[Link]</sdf>
Create the model directory <author>
<name>Leo Campos</name>
mkdir -p ~/.gazebo/models/wrobot <email>lecampos@[Link]</email>
</author>
Create a model config file
<description>
gedit ~/.gazebo/models/wrobot/[Link] A two wheeled robot for itesm seminar.
</description>
Create a model sdf file </model>
gedit ~/.gazebo/models/my_robot/[Link] More Info
[Link]
Robot Operating System by Leo Campos 132
Example <?xml version='1.0'?>
<sdf version='1.4'>
A two wheeled mobile robot <model name="wheeled_robot">
<static>true</static>
<link name='chassis'>
<pose>0 0 .1 0 0 0</pose>
I This are the necessary tags to instantiate a <collision name='collision'>
model named wheeled robot using Gazebo <geometry>
<box>
linked against SDF version 1.4
<size>.4 .2 .1</size>
I static means it will be ignored by the </box>
physics engine </geometry>
I Adding the rectangular base: </collision>
I A model may contain a link, joint or <visual name='visual'>
<geometry>
sensor
I A box with a size of 0.4 x 0.2 x 0.1 <box>
meters <size>.4 .2 .1</size>
I The collision element specifies the shape </box>
used by the collision detection engine </geometry>
I The visual element specifies the shape </visual>
used by the rendering engine </link>
</model>
</sdf>
Robot Operating System by Leo Campos 133
Example <! </visual> ... ->
<collision name='caster_collision'>
A two wheeled mobile robot <pose>-0.15 0 -0.05 0 0 0</pose>
<geometry>
Then, we will add a sphere with no friction <sphere>
<radius>.05</radius>
I A sphere with a radius of 0.05 meters </sphere>
</geometry>
I We will use ODE as default physics engine <surface>
in Gazebo <friction>
<ode>
I mu is the Coulomb friction coefficient for <mu>0</mu>
<mu2>0</mu2>
the first friction direction <slip1>1.0</slip1>
<slip2>1.0</slip2>
I mu2 is the friction coefficient for the </ode>
second friction direction </friction>
</surface>
I slip is the artificial contact slip in the </collision>
<visual name='caster_visual'>
primary friction direction <pose>-0.15 0 -0.05 0 0 0</pose>
I slip2 is the artificial contact slip in the <geometry>
<sphere>
secondary friction direction <radius>.05</radius>
</sphere>
More Info </geometry>
[Link] </visual>
dev/[Link]
Robot Operating System by Leo Campos 134
Example - A two wheeled mobile robot
Try out our model to make sure the sphere and the box appears properly
Robot Operating System by Leo Campos 135
Example <! </link> ... ->
A two wheeled mobile robot <link name="left_wheel">
<pose>0.1 0.13 0.1 0 1.5707 1.5707</pose>
<collision name="collision">
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
Now let’s add a left wheel </collision>
I A cylinder with a radius and length of 0.1
<visual name="visual">
and 0.05 meters respectively
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</visual>
</link>
Robot Operating System by Leo Campos 136
Example - A two wheeled mobile robot
Then, the right wheel
<! </link> ... ->
<link name="right_wheel">
<pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose>
<collision name="collision"> At this point the robot should have a chassis with a
<geometry> sphere and two wheels
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</collision>
<visual name="visual">
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</visual>
</link>
Robot Operating System by Leo Campos 137
Example
A two wheeled mobile robot
<! </link> ... ->
<joint type="revolute" name="left_wheel_hinge">
<pose>0 0 -0.03 0 0 0</pose>
Finally add two hinge joints for the left and <child>left_wheel</child>
right wheels <parent>chassis</parent>
I The two joints rotate about the y axis <axis>
<xyz>0 1 0</xyz>
<xyz>0 1 0< /xyz>, and connect each
</axis>
wheel to the chassis </joint>
I Make the model dynamic by setting
<static> to false <joint type="revolute" name="right_wheel_hinge">
<pose>0 0 0.03 0 0 0</pose>
More Info
[Link] <child>right_wheel</child>
dev/[Link] <parent>chassis</parent>
<axis>
<xyz>0 1 0</xyz>
</axis>
</joint>
Robot Operating System by Leo Campos 138
Example - A two wheeled mobile robot
Under the Force tab, increase the force applied to each joint to about 0.1N-m. The robot should move
around
Robot Operating System by Leo Campos 139
CAD to Gazebo
I Models with textures and 3D meshes can improve your
visual experience, and more importantly improve the
realism of an environment
I Gazebo can only use STL, OBJ or Collada files, so is
highly probably that you have to convert this file and
plugin
then add it to our model
I Closed plugins for SolidWorks exists
I You can import from SolidWorks to Blender instead
Instead of the geometry specification at the visual element you
include
More Info
<mesh> [Link]
<uri>model://your_robot/meshes/[Link]</uri> [Link]
Collada_exporter_for_SolidWorks-[Link]
</mesh> [Link]
[Link]
Robot Operating System by Leo Campos 140
Gazebo plugin for ROS
ROS Control
I A set of packages that include controller interfaces,
controller managers, transmissions and
hardware interfaces
I Takes as input the joint state data from your robot’s
actuator’s encoders and an input set point
I It uses a generic control loop feedback mechanism,
typically a PID controller
I The available controller plugins are
I effort controllers
I joint state controller
I position controllers
I velocity controllers
I You can of course create your own
More Info
[Link]
Robot Operating System by Leo Campos 141
Gazebo plugin for ROS
ROS Control
I Simulating a robot’s controllers in
Gazebo can be accomplished using
ros control and a simple Gazebo
plugin adapter
I The default plugin XML should be
added to your SDF file:
<plugin name="gazebo_ros_control"
filename="libgazebo_ros_control.so">
<robotNamespace>/MYROBOT</robotNamespace>
</plugin>
More Info
[Link]
Robot Operating System by Leo Campos 142
Further References
I ROS Wiki I [Link]
I [Link] releases/download/0.0.1/
ROScheatsheet_catkin.pdf
I Installation
I [Link] I ROS Best Practices
I Tutorials I [Link]
I [Link] best_practices/wiki
I Available packages I ROS Package Template
I [Link] I [Link]
best_practices/tree/master/ros_
I ROS Cheat Sheet package_template
Robot Operating System by Leo Campos 143
Outline IV
Robot Operating System - IV
ROS services
ROS actions (actionlib)
ROS time
ROS bags
Debugging Strategies
Robot Operating System by Leo Campos 144
ROS Services
I Request/response communication between
nodes is realized with services
I The service server advertises the service
I The service client accesses this service
I Similar in structure to messages, services are
defined in *.srv files Response
Node 1 Node 2
Service Client Request Service Server
List available services with
rosservice list
Response service Response
Show the type of a service Request name Request
rosservice type /service_name
Request
- - -
Service definition
Call a service with the request contents Response
rosservice call /service_name args
More Info
[Link]
Robot Operating System by Leo Campos 145
ROS Services
Examples
nav msgs/[Link]
std srvs/[Link]
Request geometry_msgs / PoseStamped start
--- geometry_msgs / PoseStamped goal
bool success float32 tolerance
string message ---
Response nav_msgs / Path plan
Robot Operating System by Leo Campos 146
ROS Service Example
Starting a roscore and a add two ints server node
In console nr. 1:
Start a roscore with
roscore
In console nr. 2:
Run a service demo node with
rosrun roscpp_tutorials add_two_ints_server
Robot Operating System by Leo Campos 147
ROS Service Example
Console Nr. 3 – Analyze and call service
See the available services with
rosservice list
See the type of the service with
rosservice type /add_two_ints
Show the service definition with
rossrv show roscpp_tutorials/TwoInts
Call the service (use Tab for auto-complete)
rosservice call /add_two_ints "a: 10 b: 5"
Robot Operating System by Leo Campos 148
ROS C++ Client Library (roscpp)
Service Server
// add_two_ints_server.cpp
I Create a service server with #include <ros/ros.h>
#include <roscpp_tutorials/TwoInts.h>
ros::ServiceServer service = bool add(roscpp_tutorials::TwoInts::Request &request,
[Link](service_name, roscpp_tutorials::TwoInts::Response &response)
{
callback_function);
[Link] = request.a + request.b;
ROS_INFO("request: x=%ld, y=%ld", (long int)request.a,
(long int)request.b);
I When a service request is received, ROS_INFO(" sending back response: [%ld]",
callback function is called with the request (long int)[Link]);
return true;
as argument }
I Fill in the response to the response int main(int argc, char **argv)
argument {
ros::init(argc, argv, "add_two_ints_server");
I Return to function with true to indicate ros::NodeHandle nh;
ros::ServiceServer service =
that it has been executed properly [Link]("add_two_ints", add);
ros::spin();
More Info
return 0;
[Link]
}
Robot Operating System by Leo Campos 149
ROS C++ Client Library (roscpp)
Service Client
// add_two_ints_client.cpp
#include <ros/ros.h>
I Create a service client with #include <roscpp_tutorials/TwoInts.h>
#include <cstdlib>
ros::ServiceClient client = int main(int argc, char **argv) {
[Link]<service_type> ros::init(argc, argv, "add_two_ints_client");
if (argc != 3) {
(service_name); ROS_INFO("usage: add_two_ints_client X Y");
return 1;
}
I Create service request contents
ros::NodeHandle nh;
[Link] ros::ServiceClient client =
I Call service with [Link]<roscpp_tutorials::TwoInts>("add_two_ints");
roscpp_tutorials::TwoInts service;
[Link].a = atoi(argv[1]);
[Link](service); [Link].b = atoi(argv[2]);
if ([Link](service)) {
ROS_INFO("Sum: %ld", (long int)[Link]);
I Response is stored in [Link] } else {
ROS_ERROR("Failed to call service add_two_ints");
More Info return 1;
[Link] }
return 0;
}
Robot Operating System by Leo Campos 150
ROS Actions (actionlib)
I Similar to service calls, but provide possibility
to
I Cancel the task (preempt) Action
I Receive feedback on the progress Goal
Node 1 Cancel Node 2
I Best way to implement interfaces to time-
Action Client Status Action Server
extended, goal-oriented behaviors
Result
I Similar in structure to services, action are Feedback
defined in *.action files
I Internally, actions are implemented with a set Goal
- - -
of topics Result
- - -
Action definition *.action
More Info Feedback
[Link]
[Link]
Robot Operating System by Leo Campos 151
ROS Actions (actionlib)
[Link]
[Link]
int32 samples
---
float32 mean
Goal n av ig at i on _m s gs / Path path
---
float32 std_dev
bool success
--- Result ---
int32 sample
float32 r e m a i n i n g _ d i s t a n c e
float32 data
float32 i n i t i a l _ d i s t a n c e
float32 mean Feedback
float32 std_dev
Robot Operating System by Leo Campos 152
ROS Parameters, Dynamic Reconfigure, Topics, Services, and
Actions Comparison
Dynamic
Parameters Topics Services Actions
Reconfigure
Non-blocking,
Local, changeable Continuous data Blocking call for
Description Global constant parameters preemptable goal
parameters streams processing a request
oriented tasks
One-way continuous Short triggers or Task executions and
Application Constant settings Tuning parameters
data flow calculations robot actions
Topic names, camera Trigger change,
Sensor data, robot Navigation, grasping,
Examples settings, calibration Controller parameters request state,
state motion execution
data, robot setup compute quantity
Robot Operating System by Leo Campos 153
ROS Time
I To take advantage of the simulated time, you
should always use the ROS Time APIs:
I ros::Time
I Normally, ROS uses the PC’s system clock as
time source (wall time) ros::Time begin = ros::Time::now();
double secs = [Link]();
I For simulations or playback of logged data, it
is convenient to work with a simulated time I ros::Duration
(pause, slow-down etc.)
I To work with a simulated clock: ros::Duration duration(0.5); // 0.5s
I Set the /use sim time parameter
I ros::Rate
rosparam set use_sim_time true
ros::Rate rate(10); // 10Hz
I Publish the time on the topic /clock from
I Gazebo (enabled by default) I If wall time is required, use ros::WallTime,
I ROS bag (use option –clock) ros::WallDuration, and ros::WallRate
More Info
[Link]
[Link]
Robot Operating System by Leo Campos 154
ROS Bags
Show information about a bag
I A bag is a format for storing message data
rosbag info bag_name.bag
I Binary format with file extension *.bag
I Suited for logging and recording datasets for Read a bag and publish its contents
later visualization and analysis
Record all topics in a bag rosbag play bag_name.bag
rosbag record --all Playback options can be defined e.g.
Record given topics rosbag play --rate=0.5 bag_name.bag
rosbag record topic_1 topic_2 topic_3 - -rate=factor Publish rate factor
- -clock Publish the clock time (set
param use sim time to true)
Stop recording with Ctrl + C Bags are saved with
- -loop Loop playback etc.
start date and time as file name in the current
More Info
folder (e.g. [Link]) [Link]
Robot Operating System by Leo Campos 155
Debugging Strategies
Debug with the tools you have learned
I Compile and run code often to catch bugs I If things don’t make sense, clean your workspace
early
catkin clean --all
I Understand compilation and runtime error
messages Learn new tools
I Use analysis tools to check data flow (rosnode I Build in debug mode and use GDB or Valgrind
info, rostopic echo, roswtf, rqt graph etc.)
I Visualize and plot data (RViz, RQT Multiplot catkin config --cmake-args -DCMAKE_BUILD_TYPE=Debug
etc.)
I Divide program into smaller steps and check I Use Eclipse breakpoints
intermediate results (ROS INFO, I Maintain code with unit tests and integration tests
ROS DEBUG etc.) More Info
[Link]
I Make your code robust with argument and [Link]
[Link]
return value checks and catch exceptions
Robot Operating System by Leo Campos 156
Further References
I ROS Wiki I [Link]
I [Link] releases/download/0.0.1/
ROScheatsheet_catkin.pdf
I Installation
I [Link] I ROS Best Practices
I Tutorials I [Link]
I [Link] best_practices/wiki
I Available packages I ROS Package Template
I [Link] I [Link]
best_practices/tree/master/ros_
I ROS Cheat Sheet package_template
Robot Operating System by Leo Campos 157