Skip to main content
Version: QTrobot V1

Create a ROS C++ project

Overview

 Level:  Basic
 Goal:  learn how to structure your C++ code using catkin package manager
 Requirements:

This tutorial guides you towards creating and structuring your C++ code for QTrobot. You will learn, how to create a ROS package for your C++ code, how to build it and how to run your code using rosrun and roslaunch. We will also show you how to configure your code using ROS parameters and launch file.

What is catkin?

Catkin is the official build system of ROS. In some simple words, catkin helps you to better structure you code, its dependencies within an isolated workspace known as catkin workspace (e.g. ~/catkin_ws folder). Catkin offers different commands to create a ROS package, build and manage its dependencies. You can read more about catkin on official ROS website.

Structure of catkin workspace folder

Catkin folder usually consists of src, devel and build folder. The src folder is the place where the your codes are hosted. the devel and build folder are automatically created and updated by catkin commands to configure and build your codes.

~/catkin_ws
- src
- devel
- build
Reminder
  • Ensure that you have already read carefully the Quick start guide for coding and have your setup ready to follow this tutorial on QTPC.
  • Both QTRP and QTPC has its own catkin folder which are located in the home folder: ~/catkin_ws! We are running this tutorial (and the most following tutorials) on the QTPC.

Our first C++ project

In the following steps, we will create a package called my_cpp_tutorial with the following information. Then step by step we fill it with our C++ code.

  • package name: my_cpp_tutorial
  • package dependencies: std_msgs, and roscpp
  • package description: My first C++ tutorial
  • package version: 1.0.0
  • package author name: my name

Create project's structure

Open a terminal on QTPC, switch to ~/catkin_ws/src folder and run the following commands:

cd ~/catkin_ws/src
catkin_create_pkg my_cpp_tutorial std_msgs roscpp -D "My first C++ tutorial" -V "1.0.0" -a "my name"

That creates a new package called my_cpp_tutorial in the src folder of our catkin workspace on QTPC:

Created file my_cpp_tutorial/package.xml
Created file my_cpp_tutorial/CMakeLists.txt
Created folder my_cpp_tutorial/include/my_tutorial
Created folder my_cpp_tutorial/src
Successfully created files in /home/qtrobot/catkin_ws/src/my_cpp_tutorial. Please adjust the values in package.xml.

You can open open the package.xml file and update its content such as description, version, authors name, emails etc.

Create C++ code file

The above command only creates an empty structure for our project. We need to add our C++ files by ourselves as follows:

cd my_cpp_tutorial/src touch my_cpp_tutorial_node.cpp

open the my_cpp_tutorial_node.cpp file using your favorite editor1 and add the following content to it:

#include "ros/ros.h"

int main(int argc, char **argv) {
ros::init(argc, argv, "my_cpp_tutorial_node");
ROS_INFO_STREAM("my_cpp_tutorial_node is started");
ros::NodeHandle n;

ros::spin();
return 0;
}

The above code simply starts a ROS node called my_cpp_tutorial_node which does nothing until we press <CTRL+C> to stop it.

Update Cmake file

We also need to tell catkin to compile and build our C++ files. To do that, open my_cpp_tutorial/CMakeLists.txt file and modify the following lines:

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
add_executable(${PROJECT_NAME}_node src/my_cpp_tutorial_node.cpp)

## Specify libraries to link a library or executable target against
target_link_libraries(${PROJECT_NAME}_node
${catkin_LIBRARIES}
)

We have simply uncommented few lines in the original Cmake file. The add_executable(... tells cmake to compile our my_cpp_tutorial_node.cpp within src folder and the target_link_libraries(... command tells cmake to build an executable called my_cpp_tutorial_node!

You can read more about Cmake build system on official Cmake website.

Build and configure our C++ project

Before adding an actual action to our C++ code, let's just first build and run it and check if everything is fine. To build a catkin package, we need to run catkin_make command within catkin workspace.

Note

The catkin_make command must be run within the top most level of catkin workspace, that is in ~/catkin_ws and NOT in ~/catkin_ws/src.

cd ~/catkin_ws
catkin_make

the above command compiles and builds our my_cpp_tutorial package along with other packages in catkin source directory.

Tip

To build a single package (e.g. my_cpp_tutorial) from source directory, you can call catkin_make --pkg my_cpp_tutorial!

Run and check our C++ project

There are different way to run a C++ project in ROS. You can simply run the executable file from command line. However, the most standard way of running a C++ project in ROS is to use rosrun or roslaunch command. Let's start with rosrun command. The interesting fact of these two commands is that you do not need to be in the same folder or use the absolute path to run your C++ executable. You can run it from anywhere on QTPC as follows:

 rosrun my_cpp_tutorial my_cpp_tutorial_node

the first parameter of rosrun command is the name of our package and the second on is the name of our executable. That should creates a new ROS node called my_cpp_tutorial_node in the ROS network. we can see it using rosnode list command from another terminal:

/controller
/my_cpp_tutorial_node <---
/qt_motor
/qt_nuitrack_app
/qt_robot_interface
/qt_setting_interface
/qt_vosk_app
/rosapi
/rosauth
/rosbridge_websocket
/rosout

To stop the code, just press <CTRL+C> in the same terminal where we run our code.

Adding parameters to our C++ project

ROS framework offers parameter Server where strings, integers, floats, Booleans, lists and etc. can be stored as key-value objects. The parameter server can be accessed via command line and within all ROS supported programing languages such as our C++ code. We can also sets the parameters within our code. Lets first modify our C++ code and add a line to read a parameters called param1

#include "ros/ros.h"

int main(int argc, char **argv) {
ros::init(argc, argv, "my_cpp_tutorial_node");
ROS_INFO_STREAM("my_cpp_tutorial_node is started");
ros::NodeHandle n;

std::string param1;
n.param<std::string>("/my_cpp_tutorial_node/param1", param1, "default_value");
ROS_INFO_STREAM("value of param1 is "<< param1);

ros::spin();
return 0;
}

The above code looks for param1 key within our node namespace /my_cpp_tutorial_node/. Notice that, we already specified the node namespace name in our C++ code when we were initializing it: ros::init(argc, argv, "my_cpp_tutorial_node");

Since we have not set any value for param1 in parameter server yet, the above code should print the default_value! Now let's set a value for param1 using rosparam command from command line. open a terminal and type:

  rosparam set /my_cpp_tutorial_node/param1 "QT"

This set a param1 key specifically for our my_cpp_tutorial_node. Now if we rebuild and run our C++ code, it will get the value (i.e. "QT") of the param1 and print it out. You can read more about rosparam in C++ on official ROS website.

Preparing ROS launch file

Launch files are very common in ROS. They provide a convenient way to start up multiple nodes, setting up parameters for nodes and etc. Let's create our first launch file. First we need to create the launch folder within our C++ project folder. Catkin does not do this automatically. Then we need to create a launch file:

cd ~/catkin_ws/src/my_cpp_tutorial
mkdir launch
cd launch
touch my_cpp_tutorial.launch

now open my_cpp_tutorial.launch and add the following content:

<launch>
<node name="my_cpp_tutorial_node" pkg="my_cpp_tutorial" type="my_cpp_tutorial_node" output="screen">
</node>
</launch>

This is the very basic setting of a ROS launch file. we just indicated that we would like to run one node which is located in my_cpp_tutorial package. Within this package, we want to run our executable which is given as type="my_cpp_tutorial_node". The optional output parameter indicate where our code's log output should be printed.

Running our C++ project using launch file

Now we have our launch file ready we can launch it from everywhere on QTPC using the roslaunch command:

roslaunch my_cpp_tutorial my_cpp_tutorial.launch

Setting parameters using launch file

Modify my_cpp_tutorial.launch file as follow to set a value for param1 key.

<launch>
<node name="my_cpp_tutorial_node" pkg="my_cpp_tutorial" type="my_cpp_tutorial_node" output="screen">
<param name="param1" value="QTrobot :)" />
</node>
</launch>

Congratulations! 😉

You have just created your first C++ project in ROS. In the next tutorial, you will learn how to extend this tutorial to access QTrobot interfaces.

Footnotes

  1. you can simply use Ubuntu gedit text editor or install Atom or Visual Studio Code whichever comes as your favorite.