Create a ROS C++ project
Goal: learn how to structure your C++ code using catkin package manager
Requirements:
- Quick start with coding on QTrobot
- Basic understanding of ROS framework
- Good knowledge of C++ and Cmake build system
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
- 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
, androscpp
- 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.
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.
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>
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
-
you can simply use Ubuntu gedit text editor or install Atom or Visual Studio Code whichever comes as your favorite. ↩