In order to compile and run our C++ code, we need to make sure our ROS package has those build capabilities.
This section requires the catkin_ws to be initialized and the turtlebot_dabit package created.
Please click here to learn how to initialize the catkin workspace
For this tutorial, we will be using the turtlebot_dabit catkin package we created. In order to enable building C++ files in our package, we need to edit the CMakeLists.txt and package.xml to build with our dependencies.
cd ~/catkin_ws/src/turtlebot_dabit
gedit package.xml
Near the bottom of the file, find the <buildtool_depend>catkin</buildtool_depend>
line:
...
<buildtool_depend>catkin</buildtool_depend>
...
Add the build_depend and run_depend tags for roscpp underneath the buildtool_depend line:
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>
<?xml version="1.0"?>
<package>
<name>turtlebot_dabit</name>
<version>0.0.0</version>
<description>The turtlebot_dabit package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="user@todo.todo">user</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- ... -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
gedit CMakeLists.txt
Near the top of the file, find the find_package(catkin REQUIRED)
line:
...
find_package(catkin REQUIRED)
...
Replace that line with:
find_package(catkin REQUIRED COMPONENTS
roscpp
)
Near the middle of the file, find the catkin_package(
line:
...
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES turtlebot_dabit
# CATKIN_DEPENDS other_catkin_pkg
# DEPENDS system_lib
)
...
Replace that line with:
catkin_package(
INCLUDE_DIRS
CATKIN_DEPENDS roscpp
)
Near the middle of the file, find the # include_directories(include)
line:
# include_directories(include)
Replace that line with:
include_directories(
${catkin_INCLUDE_DIRS}
)
cmake_minimum_required(VERSION 2.8.3)
project(turtlebot_dabit)
## Add support for C++11, supported in ROS Kinetic and newer
# add_definitions(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
roscpp
)
# ...
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
INCLUDE_DIRS
CATKIN_DEPENDS roscpp
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
${catkin_INCLUDE_DIRS}
)
## ...
catkin_make --directory ~/catkin_ws --pkg turtlebot_dabit
Upon success, you should see:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/catkin_ws/build
####
#### Running command: "make -j4 -l4" in "/home/user/catkin_ws/build/turtlebot_dabit"
####
Now we get to write our first c++ code to communicate with ROS.
gedit ~/catkin_ws/src/turtlebot_dabit/src/roscpp_hello_world.cpp
Start with the following Hello World code in gedit:
/*
* Hello World Example using ROS and CPP
*/
// Include the ROS library
#include <ros/ros.h>
// Main function
int main(int argc, char** argv)
{
// Initialize the ROS Node "roscpp_hello_world"
ros::init(argc, argv, "roscpp_hello_world");
// Instantiate the ROS Node Handler as nh
ros::NodeHandle nh;
// Print "Hello ROS!" to the terminal and ROS log file
ROS_INFO_STREAM("Hello from ROS node " << ros::this_node::getName());
// Program succesful
return 0;
}
gedit ~/catkin_ws/src/turtlebot_dabit/CMakeLists.txt
Near the middle of the file, find the ## Declare a C++ executable
:
...
## 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/turtlebot_dabit_node.cpp)
...
Below that line, add the following:
add_executable(roscpp_hello_world src/roscpp_hello_world.cpp)
target_link_libraries(roscpp_hello_world ${catkin_LIBRARIES})
catkin_make --directory ~/catkin_ws --pkg turtlebot_dabit
Upon success, you should see:
####
#### Running command: "make -j4 -l4" in "/home/user/catkin_ws/build/turtlebot_dabit"
####
Scanning dependencies of target roscpp_hello_world
[ 50%] Building CXX object turtlebot_dabit/CMakeFiles/roscpp_hello_world.dir/src/roscpp_hello_world.cpp.o
[100%] Linking CXX executable /home/user/catkin_ws/devel/lib/turtlebot_dabit/roscpp_hello_world
[100%] Built target roscpp_hello_world
source ~/catkin_ws/devel/setup.sh
rosrun turtlebot_dabit roscpp_hello_world
[ INFO] [1492726164.127098818]: Hello ROS!