ros_package conventions

Folder Structure

We try to follow this folder structure for the ROS packages:

ros_package/
|   CMakeLists.txt
|   package.xml
|
└───src/
|   |   cpp_node.cpp
|
└───include/
|   └───ros_package/
|       |   cpp_header.hpp
|
└───src_py/
|   |   py_node.py
|
└───ros_package/
|   |   __init__.py
|   |   py_module.py
|
└───launch/
    |   launch_file.launch.py
  • Every ROS package contains the CMakeLists.txt and package.xml in the root directory.

  • In case of development using C++, the executables are located in the src/ directory. The corresponding headers are located in the include/ directory, inside a sub-directory that equals the package name.

  • In case of development using Python, the executables are located in the src_py/ directory.

  • A sub-directory ros_package/ with the same name as the ROS package can be used to create a Python package. This directory contains an __init__.py file and the Python modules of the Python package.

  • Possible launch files are located in the launch/ directory.

  • More directories are possible, like urdf/ for urdf files or config/ for config files.

CMakeLists.txt

This CMakeLists.txt file shows the different parts required to build a ROS package:

 1# SPDX-FileCopyrightText: Alliander N. V.
 2#
 3# SPDX-License-Identifier: Apache-2.0
 4
 5cmake_minimum_required(VERSION 3.5)
 6project(ros_package)
 7
 8# CMake dependencies:
 9find_package(ament_cmake REQUIRED)
10find_package(ament_cmake_python REQUIRED)
11
12# Other dependencies:
13find_package(geometry_msgs REQUIRED)
14find_package(vision_msgs REQUIRED)
15
16# C++ executables:
17add_executable(cpp_node src/cpp_node.cpp)
18ament_target_dependencies(cpp_node geometry_msgs vision_msgs)
19install(
20  TARGETS cpp_node
21  DESTINATION lib/${PROJECT_NAME}
22)
23
24# Python executables:
25install(
26  DIRECTORY src_py/
27  DESTINATION lib/${PROJECT_NAME}
28)
29
30# Python package:
31ament_python_install_package(${PROJECT_NAME})
32
33# Shared folders:
34install(
35  DIRECTORY launch
36  DESTINATION share/${PROJECT_NAME}
37)
38
39# Default test:
40if(BUILD_TESTING)
41  find_package(ament_lint_auto REQUIRED)
42  ament_lint_auto_find_test_dependencies()
43endif()
44
45ament_package()

5-10:
The file always starts with a version definition, the package name and the CMake dependencies when building C++ and/or python files.

12-14:
If the package depends on other packages, these are defined. In this case, the packaged depends on the vision_msgs and geometry_msgs packages.

16-22:
Building a C++ executable requires 3 steps: defining the executable, linking dependencies (if any) and installing the targets to the lib directory.

24-28:
For Python executables, we can simply install them all at the same time, by providing the directory.

30-31:
If the package contains a Python package, it needs to be installed.

33-37:
All shared folders are installed into the share directory. This includes the directory of launch files, but also other possible directories, like urdf/ or config/, if these exist.

39-45:
The file always ends with a default test and the ament_package() command.

package.xml

The package.xml file is related to the CMakeLists.txt file:

 1<?xml version="1.0"?>
 2<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 3
 4<!--
 5SPDX-FileCopyrightText: Alliander N. V.
 6
 7SPDX-License-Identifier: Apache-2.0
 8-->
 9
10<package format="3">
11  <name>ros_package</name>
12  <version>0.1.0</version>
13  <description>A ros package.</description>
14  <maintainer email="researchcenter@alliander.com">RCDT</maintainer>
15  <license>Apache 2.0</license>
16
17  <buildtool_depend>ament_cmake</buildtool_depend>
18  <buildtool_depend>ament_cmake_python</buildtool_depend>
19
20  <depend>geometry_msgs</depend>
21  <depend>vision_msgs</depend>
22
23  <test_depend>ament_lint_auto</test_depend>
24
25  <export>
26    <build_type>ament_cmake</build_type>
27  </export>
28</package>

1-2:
The files starts with default xml definitions.

10-15:
Inside the package tag, we start with some general information about the package.

17-18:
Next, we define the build tool dependencies for building C++ and/or Python files.

20-21:
Next, we define other packages where our package depends on.

23-28:
The file ends with the default test dependency and an export definition.