The Beginner Tutorial is quite long so I made this article to quickly go through everything we need to know about ROS.

My Environment:

ROS kinetic on Ubuntu 16.04

ROS melodic on Ubuntu 18.04

Prerequisite

  • Knowing Programming Language (C++, Python)
  • Knowing some CMake basics
  • Knowing Linux commands (MOST IMPORTANT)

What is ROS?

ROS = Robot Operating System

It is not the Operating System like windows, mac but it is like a robotics middleware that lifts between the actual operating system and program.

  • Plumbing - you can have multiple programs running and programs can communicate between each other. Also it provide a lot of device drivers so you can easily communicate with your hardware.

  • Tools - Simulation, Visualization, Graphical user interface, Data logging.

  • Capabilities - Control, Planning, Perception, Mapping, Manipulation.

  • Ecosystem - Software is organized in packages as you can easily install and use them.

ROS Philosophy

  • Peer to peer - Individual programs communicate over defined API (ROS messages, services, etc)
  • Distributed - Programs can be run on mulitple computers and communicate over the network
  • Multi-lingual - ROS modules can be written in any language for which a client library exists (C++, Python, MATLAB, Java, etc.)
  • Light-weight - Standalone libraries are wrapped around with a thin ROS layer
  • Free and Open-source

ROS Concept

ROS Filesystem Level

The filesystem level concepts mainly cover ROS resources that you encounter on disk, such as:

  • Packages: Packages are the main unit for organizing software in ROS. A package may contain ROS runtime processes (nodes), a ROS-dependent library, datasets, configuration files, or anything else that is usefully organized together. Packages are the most atomic build item and release item in ROS. Meaning that the most granular thing you can build and release is a package.

  • Metapackages: Metapackages are specialized Packages which only serve to represent a group of related other packages. Most commonly metapackages are used as a backwards compatible place holder for converted rosbuild Stacks.

  • Package Manifests: Manifests (package.xml) provide metadata about a package, including its name, version, description, license information, dependencies, and other meta information like exported packages.

  • Repositories: A collection of packages which share a common VCS system. Packages which share a VCS share the same version and can be released together using the catkin release automation tool bloom. Often these repositories will map to converted rosbuild Stacks. Repositories can also contain only one package.

  • Message (msg) types: Message descriptions, stored in my_package/msg/MyMessageType.msg, define the data structures for messages sent in ROS.

  • Service (srv) types: Service descriptions, stored in my_package/srv/MyServiceType.srv, define the request and response data structures for services in ROS.

ROS Computation Graph Level

The Computation Graph is the peer-to-peer network of ROS processes that are processing data together. The basic Computation Graph concepts of ROS are nodes, Master, Parameter Server, messages, services, topics, and bags, all of which provide data to the Graph in different ways.

  • Nodes: Nodes are processes that perform computation.

  • Master: The ROS Master provides name registration and lookup to the rest of the Computation Graph. Without the Master, nodes would not be able to find each other, exchange messages, or invoke services.

  • Parameter Server: The Parameter Server allows data to be stored by key in a central location. It is currently part of the Master.

  • Messages: Nodes communicate with each other by passing messages. A message is simply a data structure, comprising typed fields. Standard primitive types (integer, floating point, boolean, etc.) are supported, as are arrays of primitive types. Messages can include arbitrarily nested structures and arrays (much like C structs).

  • Topics: Messages are routed via a transport system with publish / subscribe semantics. A node sends out a message by publishing it to a given topic. The topic is a name that is used to identify the content of the message. A node that is interested in a certain kind of data will subscribe to the appropriate topic. There may be multiple concurrent publishers and subscribers for a single topic, and a single node may publish and/or subscribe to multiple topics. In general, publishers and subscribers are not aware of each others’ existence. The idea is to decouple the production of information from its consumption. Logically, one can think of a topic as a strongly typed message bus. Each bus has a name, and anyone can connect to the bus to send or receive messages as long as they are the right type.

  • Services: The publish / subscribe model is a very flexible communication paradigm, but its many-to-many, one-way transport is not appropriate for request / reply interactions, which are often required in a distributed system. Request / reply is done via services, which are defined by a pair of message structures: one for the request and one for the reply. A providing node offers a service under a name and a client uses the service by sending the request message and awaiting the reply. ROS client libraries generally present this interaction to the programmer as if it were a remote procedure call.

  • Bags: Bags are a format for saving and playing back ROS message data. Bags are an important mechanism for storing data, such as sensor data, that can be difficult to collect but is necessary for developing and testing algorithms.

QuickStart

1
2
3
4
5
6
mkdir -p ~/<your_workspace>/src
cd ~/<your_workspace>/src
catkin_init_workspace
catkin_make
catkin_make install
source ./devel/setup.bash

ROS Workspace

Create a workspace

<distro> can be kinetic or melodic.

1
source /opt/ros/<distro>/setup.bash

You can add this source /opt/ros/<distro>/setup.bash into ~/.bashrc so you dont have to type it everytime.

1
2
3
mkdir -p <your_workspace>/src
cd <your_workspace>
catkin_make

What is inside a workspace

In case you messed up with the build or devel folder, you can clean them by

1
catkin clean

This will remove the build and devel folder but keep your src folder. Then you can rebuild again.

Check the workspace

The workspace setup can be checked with

1
catkin config

ROS Package

For a package to be considered a catkin package it must meet a few requirements:

  • The package must contain a catkin compliant package.xml file.
    • That package.xml file provides meta information about the package.
  • The package must contain a CMakeLists.txt which uses catkin.
    • If it is a catkin metapackage it must have the relevant boilerplate CMakeLists.txt file.
  • Each package must have its own folder
    • This means no nested packages nor multiple packages sharing the same directory.

A trivial workspace might look like this:

1
2
3
4
5
6
7
8
9
10
workspace_folder/        -- WORKSPACE
src/ -- SOURCE SPACE
CMakeLists.txt -- 'Toplevel' CMake file, provided by catkin
package_1/
CMakeLists.txt -- CMakeLists.txt file for package_1
package.xml -- Package manifest for package_1
...
package_n/
CMakeLists.txt -- CMakeLists.txt file for package_n
package.xml -- Package manifest for package_n

Create package

Your should create package in <your workspace>/src directory.

1
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

ROS Nodes

A Node is an executable that uses ROS to communicate with other nodes.

  • Single-purpose, executable program
  • Individually compiled, executed, and managed
  • Organized in packages

rosout

ROS quivalent of stdout/stderr.

ROS Master

  • Manages the communication between nodes
  • Every node registers at startup with the master

roscore = ros + core

roscore is the first thing you should run when using ROS.

rosnode

rosnode = ros + node

To check the ROS nodes that are currently running:

1
rosnode list

You can also check the info about a specific node.

1
rosnode info [node]

rosrun

rosrun = ros + run

Directly run a node within a package (without having to know the package path)

1
rosrun [package_name] [node_name]

ROS Topics

Nodes are communicating with each other through a ROS Topic.

  • Nodes can publish or subscribe to a topic (Typically 1 publisher and n subscribers)
  • Topic is a name for a stream of messages

List active topics with

1
rostopic list

What is Going on in the system?

Use rqt_graph to create a dynamic graph of what’s going on in the system.

1
rosrun rqt_graph rqt_graph

A window will pop up and you can refresh it.

  • The wordings on the arrow is a TOPIC.

ROS Messages

  • Data structure defining the type of a topic
  • Compromised of a nested structure of integers, floats, booleans, string etc. and arrays of objects
  • Defined in *.msg files

^Example: geometry_msgs/Point.msg

1
2
3
float64 x
float64 y
float64 z

Messages can be nested together. see another example:

geometry_msgs/PoseStamped.msg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
std_msgs/Header header
uint32 seq
time stamp
string frame_id
geometry_msgs/Pose pose
geometry_msgs/Point position
float64 x
float64 y
float64 z
geometry_msgs/Quaternion orientation
float64 x
float64 y
float64 z
float64 w

What type of Messages are those on Topic?
rostopic type returns the message type of any topic be published.

1
rostopic type [topic]

You can also look at the details of the message using rosmsg.

1
rosmsg show [msg_type]

Sending Message to a Topic

rostopic pub publishes data to a topic.

1
rostopic pub [option] [topic] [msg_type] -- [args]

For [option], You can:
use -1 to cause rostopic to only publish 1 message then exit.
use -r 1 to cause rostopic publish a steady stream of commands at 1 Hz.

The -- (double dash) is telling none of the following arguments is an option. This is required in cases where your arguments have a leading dash -, like negative numbers.

Report the rate at which data is published

1
rostopic hz [topic]

Time Plot of the data on Topics

rqt_plot displays a scrolling time plot of the data published on topics.

1
rosrun rqt_plot rqt_plot

If above command is giving error, run

1
rqt

Then traverse through plugins->Visualization->Plot to get the MatPlot.

ROS Services

rosservice = ros + service

Services are another way that nodes can communicate with each other.
Services allow nodes to send a request and receive a response.

  • Request/Response communication between nodes is realized with service
  • Similar in structure to messages, services are defined in *.srv files

What Services do we have in the node?

To print information about active services:

1
rosservice list

Now we can see the services provided by the node.

How to use a Service

1
rosservice call [service] [args]

Using rosparam

rosparam = ros + param

You can use rosparam to store and manipuate data on the ROS Parameter Server.

1
rosparam list

Set and Get parameters

1
2
rosparam set [param_name] [args]
rosparam get [param_name]

you can use rosparam get / to show the contents of the entire parameter server.

Short Summary

  • A workspace has many packages
  • A package has 1 / Many nodes
  • A Node has many Services, it communicate with other Nodes through Topics.

Debug Matters

Display output from nodes

1
rosrun rqt_console rqt_console

rqt_console is used to monitor the output.

Change the verbosity level of nodes

1
rosrun rqt_logger_level rqt_logger_level

rqt_logger_level can be used to pick the type of log we want.

ROS Launch

roslaunch starts nodes as defined in a launch file.

  • launch is a tool for launching multiple nodes
  • Are written in XML as *.launch files
  • If roscore not yet running, launch automatically starts a roscore.

Start a launch file from a package with

1
roslaunch [package] [filename.launch]

ROS Launch File Structure

Basic Example: talker_listener.launch

1
2
3
4
<launch>
<node name="listener" pkg="roscpp_tutorials" type="listener" output="screen"/>
<node name="talker" pkg="roscpp_tutorials" type="talker" output="screen"/>
</launch>

Notice the syntax differenece for self-closing tags: <tag></tag> and <tag/>

  • launch: Root element of the launch file
  • node: Each <node> tag specifies a node to be launched
  • name: Name of the node (free to choose)
  • pkg: Package containing the node
  • type: Type of the node, there must be a corresponding executable with the same name
  • output: Specifies where to output log messages (screen: console, log: log file)

ROS Launch Arguments

  • Create re-usable launch files with <arg> tag, which works like a parameter (default optional)
1
<arg name="arg_name" default="default_value"/>

Then when launching, arguments can be set with

1
roslaunch [filename.launch] arg_name:=value

ROS Launch Including Other Launch Files

Include other launch files with <include> tag to organize large projects

1
2
3
<include file="package_name">
...
</include>

Edit Files

1
rosed [package_name] [filename]

rosed uses vim as default editor.

Interactive Vim tutorial
VIM Cheatsheet for Beginner

Of coz, you can just:

1
vim [filename]

Running Codes on ROS

ROS Msg and Srv

http://wiki.ros.org/ROS/Tutorials/CreatingMsgAndSrv

Edit the corresponding rows in CMakeList.txt.

Write Codes for Service (Python)

Put code in scripts folder under your package folder.

For C++, The procedure is different. Check it yourself.

Create program script

1
touch scripts/program1.py

Make it executable

1
chmod +x scripts/program1.py

Then Add the program into your CMakeLists.txt:

1
2
3
catkin_install_python(PROGRAMS scripts/program1.py scripts/program2.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Refresh ROS

1
2
cd ~/<your_package>
catkin_make

Whenever you build a new package, update your environment
If you find roscd not available, it is probably because you haven’t update your environment

update your environment:

1
2
cd ~/<your_package>
source devel/setup.bash

Recommended Readings / Videos