Skip to content

ROS Fundamentals

Erick Mejia Uzeda edited this page Sep 3, 2020 · 3 revisions

Written by: Erick Mejia Uzeda

Use the SumoROS repo to show examples for how to use concepts covered in this wiki!

ROS stands for Robot Operating System and serves as a framework for coding up robots. ROS is open source and has a large community of contributors for a variety of packages. Lots of things you will learn and more can be found in ROS Answers, but to cover the fundamentals this wiki will go over:

A good resources to consult is the book: A Gentle Introduction to ROS

  • ROS architecture
    • master
    • nodes
    • topics + messages
  • Coding in ROS
    • workspaces
    • packages
    • launch files
  • Transforms
  • ROS commands

ROS architecture

When running ROS, a network of nodes is created with topics and services serving as communication channels between them. When visualized using rqt_graph, the full network looks like a graph with ROS nodes serving as graph nodes and edges being ROS topics as seen in the following image

Another representation consists of ROS nodes as circle nodes and topics being rectangular nodes

master

To run the ROS master, run roscore in a terminal. Note that roscore has no additional arguments and will consume the terminal until the process is killed (Ctrl+C). The master needs to be running for the entire time ROS is running.

ROS master can be thought of as the brain which enables nodes to connect to it, run and as well as sets up and manages the whole communication network via topics and services between nodes. It even holds a parameter server to store data. Note that when using roslaunch the master will start automatically!

nodes

An instance of a ROS program is called a ROS node. Nodes are generally written in C++ or Python and can be thought of units that perform some form of data processing.

From the pov of the ROS master, nodes can be a subscriber and/or publisher. Subscribers are nodes that "subscribe" to a topic and read the messages published on it. Publishers are nodes that "publish" messages to a topic, enabling data transfer between nodes. In essence, subscribing and publishing is how a node performs IO operations.

The following image shows the relationship between the master, nodes and topics:

topics + messages

Communication between nodes is done via topics, with messages being passed through them. Note that each topic can only use one message type but we can have multiple topics using the same message type.

One can compare a topic to a data bus (in electronics) which allows transferring data between different nodes, with the message being the format in which the data is being transferred in. A subscriber/publisher would be a node that connects to that data bus and reads/publishes the data from the bus using the specified message type.

In reality, the ROS master sets up peer-to-peer connections between nodes based on the topics. Note that one can define their own custom message types as well.

Coding in ROS

Workspaces and packages are created and managed using catkin. The general structure of a ROS development environment looks as follows:

workspace_folder/         -- WORKSPACE
  src/                    -- SOURCE SPACE
    CMakeLists.txt        -- The 'toplevel' CMake file
    package_1/
      CMakeLists.txt
      package.xml
      ...
    package_n/
      CATKIN_IGNORE       -- Optional empty file to exclude package_n from being processed
      CMakeLists.txt
      package.xml
      ...
  build/                  -- BUILD SPACE
    CATKIN_IGNORE         -- Keeps catkin from walking this directory
  devel/                  -- DEVELOPMENT SPACE (set by CATKIN_DEVEL_PREFIX)
    bin/
    etc/
    include/
    lib/
    share/
    .catkin
    env.bash
    setup.bash
    setup.sh
    ...
  install/                -- INSTALL SPACE (set by CMAKE_INSTALL_PREFIX)
    bin/
    etc/
    include/
    lib/
    share/
    .catkin             
    env.bash
    setup.bash
    setup.sh
    ...

workspaces

A workspace is a folder where one builds, modifies and installs packages. All ROS development is done within a workspace.

To create a workspace, run:

mkdir -p catkin-ws/src
cd catkin-ws
catkin_make

First we create a workspace folder called catkin-ws and an inner folder called src - which will hold all our packages. Then run catkin_make in /catkin-ws to initialize the workspace. catkin_make also builds all packages found in /src. Note that you will have 2 more folders in /catkin-ws after running catkin_make: /build and /devel - you can leave those folders alone, they contain your compiled ROS code.

To have access to the code we just built, we "source" the terminal. This makes the newly compiled packages visible to the terminal. To source, go into /catkin-ws and run:

source devel/setup.bash`

packages

Quoting the ROS wiki: "Software in ROS is organized in packages. A package might contain ROS nodes, a ROS-independent library, a dataset, configuration files, a third-party piece of software, or anything else that logically constitutes a useful module. The goal of these packages it to provide this useful functionality in an easy-to-consume manner so that software can be easily reused. In general, ROS packages follow a "Goldilocks" principle: enough functionality to be useful, but not too much that the package is heavyweight and difficult to use from other software."

Packages are created in /src using catkin by executing:

cd catkin-ws/src
catkin_create_package <package_name> <dependencies>

Some common directories found in packages are:

  • /launch which houses launch files
  • /src which houses C++ code for nodes
  • /scripts which houses Python code for nodes

Moreover, if one wants to use someone else's package, then clone the package repository into the /src folder. Packages can also be installed globally using sudo apt-get install ros-<distro>-<package>.

launch files

Launch files are written in XML, generally exist in the /launch folder of a package and can run multiple nodes, call other launch files as well as set parameters in the ROS parameter server. It also automatically launches/re-uses ROS master.

Any launch file is enclosed in the <launch></launch> tag. Other common tags are:

<arg>

Specify an input argument to the launch file

<include>

Call another launch file

<node>

Run a node

Launch files can be run using:

roslaunch <package> <file>.launch <arg>:=<value>

For a full list of tags and attributes, see the ROS wiki. Note that we can evaluate simple python expressions in launch files and access variables using the $(...) operator.

Transforms

Given that robots have many moving parts, one must manage the different frames (coordinate systems) that exist. This is done in ROS via the tf package - Note. the tf2 package is replacing the tf package in ROS.

Mathematically, the relationship between different coordinate systems is described using a transform. A transform is described using a 4x4 matrix and describes the translation, rotation and scale needed to go from one frame to another. If you have a well defined origin, then a transform can describe a frame itself.

Example of a TRS 4x4 transform matrix with unit scaling

From the pov of ROS (the tf package), it creates a data structure called the transform tree (tf_tree) to maintain the relationships between the various frame. The tf_tree can be viewed by running rosrun rqt_tf_tree rqt_tf_tree.

The nodes of the tree correspond to frames (ie. a coordinate system) and the edges show the relationship between the frames. A tree is used to avoid any contradictions when querying the transform between two frames.

ROS Commands

There are a variety of cheat sheets giving a high level overview of command line ROS commands that can be found. This is one of them. The important commands are:

rostopic

list to get all current topics.

echo <topic> to print out the messages being published to the specified topic.

pub <topic> <msg_type> <msg> to publish a message to a topic.

roslaunch <package> <file>.launch

runs launch files which serve as scripts that can run many ROS nodes and other launch files.

rosrun <package> <node>

runs executables from as ROS nodes.

rqt_graph rqt_graph opens up the rqt GUI with the graph plugin. Allows to view nodes and topics.

rqt_tf_tree rqt_tf_tree opens up rqt GUI with the tf_tree plugin. Allows to view frames and their relationships.