1.创建工作空间
1. 创建工作空间并初始化
$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ catkin_init_workspace
2. 对工作空间进行编译
$ cd ~/catkin_ws/
$ catkin_make
3. source环境变量,确保当前空间能够被设置脚本正确覆盖
$ source devel/setup.bash
4. 检查路径是否正确
$ echo $ROS_PACKAGE_PATH
/home/youruser/catkin_ws/src:/opt/ros/indigo/share
2. 创建catkin程序包
首先切换到之前通过创建catkin工作空间教程创建的catkin工作空间中的src目录下:
# This is an example, do not try to run this
# catkin_create_pkg [depend1] [depend2] [depend3]
catkin_create_pkg命令会要求你输入package_name,如果有需要你还可以在后面添加一些需要依赖的其它程序包,这个文件夹里面包含一个package.xml文件和一个CMakeLists.txt文件,这两个文件都已经自动包含了部分你在执行catkin_create_pkg命令时提供的信息。
自定义package.xml列子
1
2
3 beginner_tutorials
4 0.1.0
5 The beginner_tutorials package
6
7 Your Name
8 BSD
9 http://wiki.ros.org/beginner_tutorials
10 Jane Doe
11
12 catkin
13
14 roscpp
15 rospy
16 std_msgs
17
18 roscpp
19 rospy
20 std_msgs
21
22
CMakeList.txt实例及组成分析
结构:
Required CMake Version (cmake_minimum_required)
Package Name (project())
Find other CMake/Catkin packages needed for build (find_package())
Enable Python module support (catkin_python_setup())
Message/Service/Action Generators (add_message_files(), add_service_files(), add_action_files())
Invoke message/service/action generation (generate_messages())
Specify package build info export (catkin_package())
Libraries/Executables to build (add_library()/add_executable()/target_link_libraries())
Tests to build (catkin_add_gtest())
Install rules (install())
1. CMake Version要求
cmake_minimum_required(VERSION 2.8.3)
2. Package name
project(robot_brain)
3. 寻找依赖的CMake包,Finding Dependent CMake Packages
我们需要使用CMake find_package函数指定需要找到哪些其他CMake包来构建我们的项目。 总是至少有一种依赖性:
find_package(catkin REQUIRED)
对于编译而言,也可以将其他包定义成组建,例如使用包:nodelet
find_package(catkin REQUIRED COMPONENTS nodelet)
或者:
find_package(catkin REQUIRED) find_package(nodelet REQUIRED)
3.1find_package()工作原理:
如果CMake通过find_package发现一个包,它会创建几个CMake环境变量,提供有关找到的包的信息。 这些环境变量可以稍后在CMake脚本中使用。 环境变量描述了软件包头文件导出的位置,源文件的位置,软件包所依赖的库以及这些库的路径。 名称始终遵循
3.2为什么将Catkin软件包指定为组件?
Catkin包不是真正的catkin的组成部分。 相反,CMake的组件功能被用于设计catkin以节省您大量的打字时间。
对于catkin包,如果将它们作为catkin的组件包装,那么这是有利的,因为将会利用catkin_prefix创建一组环境变量。 例如,让我们假设您在代码中使用了包nodelet。 推荐的方法是:
find_package(catkin REQUIRED COMPONENTS nodelet)
这意味着nodelet导出的包含路径,库等也会附加到catkin_variables。catkin_INCLUDE_DIRS不仅包含catkin的包含路径,还包含nodelet的包含路径! 这将在以后派上用场。
我们可以选择find_package nodelet:
find_package(nodelet)这意味着nodelet路径,库等不会被添加到catkin_variables中。
find_package(catkin REQUIRED COMPONENTS nodelet)
也能生成nodelet_INCLUDE_DIRS,nodelet_LIBRARIES等.
3.3 Boost:
如果使用C ++和Boost,则需要在Boost上调用find_package(),并指定用作组件的Boost的哪些方面。例如,如果你想使用Boost线程,你会说:
find_package(Boost REQUIRED COMPONENTS thread)
4. catkin_package()
catkin_package()是一个catkin提供的CMake宏。这需要指定特定于catkin的信息到构建系统,而这些信息又被用于生成pkg-config和CMake文件。
在使用add_library()或add_executable()声明任何目标之前,必须调用此函数。该函数有5个可选参数:
INCLUDE_DIRS - The exported include paths (i.e. cflags) for the package
LIBRARIES - The exported libraries from the project
CATKIN_DEPENDS - Other catkin projects that this project depends on
DEPENDS - Non-catkin CMake projects that this project depends on. For a better understanding, see this explanation.
CFG_EXTRAS - Additional configuration options
As an example:
catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS roscpp nodelet DEPENDS eigen opencv)
这表明包文件夹中的文件夹“include”是导出头文件的位置。 CMake环境变量$ {PROJECT_NAME}将评估您之前传递给project()函数的任何内容,在这种情况下,它将是“robot_brain”。 “roscpp”+“nodelet”是构建/运行此程序包时需要存在的程序包,“eigen”+“opencv”是构建/运行此程序包时需要存在的系统依赖关系。
5. 指定构建目标,Specifying Build Targets
构建目标可以采取多种形式,但通常它们代表两种可能性之一:
Executable Target :可执行目标 - 我们可以运行的程序
Library Target:库目标 - 可在构建和/或运行时可执行目标所使用的库
5.1包含路径和库路径Include Paths and Library Paths
在指定目标之前,您需要指定可以为所述目标找到资源的位置,特别是头文件和库:
include_directories(
link_directories(
include_directories的参数应该是由find_package调用生成的* _INCLUDE_DIRS变量以及需要包含的任何其他目录。如果您使用catkin和Boost,则include_directories()调用应该如下所示:
include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
CMake link_directories()函数可用于添加其他库路径,但不建议这样做。所有catkin和CMake包在find_packaged时会自动添加链接信息。只需链接到target_link_libraries()中的库
5.2. 可执行目标Executable Target
要指定必须构建的可执行目标,我们必须使用add_executable()CMake函数。
add_executable(myProgram src/main.cpp src/some_file.cpp src/another_file.cpp)
5.3. 库目标Library Target
add_library()CMake函数用于指定要构建的库。默认情况下,catkin构建共享库。
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})
5.4. target_link_libraries
使用target_link_libraries()函数来指定可执行目标所链接的库。这通常是在add_executable()调用之后完成的。添加$ {catkin_LIBRARIES}
target_link_libraries(, , , ... )
Example:
add_executable(foo src/foo.cpp) add_library(moo src/moo.cpp) target_link_libraries(foo moo) -- This links foo against libmoo.so
ROS中的消息(.msg),服务(.srv)和动作(.action)文件在ROS包构建和使用之前需要特殊的预处理器构建步骤。 这些宏的要点是生成编程语言特定的文件,以便人们可以在他们选择的编程语言中使用消息,服务和动作。 构建系统将使用所有可用的生成器(例如gencpp,genpy,genlisp等)生成绑定。
add_message_files
add_service_files
add_action_files
这些宏必须随后调用调用生成的宏:
generate_messages()
要求:
这些宏必须在catkin_package()宏之前出现,以便生成正常工作。
find_package(catkin REQUIRED COMPONENTS ...) add_message_files(...) add_service_files(...) add_action_files(...) generate_messages(...) catkin_package(...) ...
catkin_package( ... CATKIN_DEPENDS message_runtime ... ...)
find_package(catkin REQUIRED COMPONENTS message_generation)如果你有一个目标(甚至是可传递的)依赖于需要构建消息/服务/动作的其他目标,则需要在目标catkin_EXPORTED_TARGETS上添加一个显式依赖项,以便它们按正确的顺序构建。
add_dependencies(some_target ${catkin_EXPORTED_TARGETS})如果您有构建消息和/或服务的软件包以及使用这些软件的可执行文件,则需要在自动生成的消息目标上创建明确的依赖关系,以便它们按正确的顺序构建。
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
1 # Get the information about this package's buildtime dependencies 2 find_package(catkin REQUIRED 3 COMPONENTS message_generation std_msgs sensor_msgs) 4 5 # Declare the message files to be built 6 add_message_files(FILES 7 MyMessage1.msg 8 MyMessage2.msg 9 ) 10 11 # Declare the service files to be built 12 add_service_files(FILES 13 MyService.srv 14 ) 15 16 # Actually generate the language-specific message and service files 17 generate_messages(DEPENDENCIES std_msgs sensor_msgs) 18 19 # Declare that this catkin package's runtime dependencies 20 catkin_package( 21 CATKIN_DEPENDS message_runtime std_msgs sensor_msgs 22 ) 23 24 # define executable using MyMessage1 etc. 25 add_executable(message_program src/main.cpp) 26 add_dependencies(message_program ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 27 28 # define executable not using any messages/services provided by this package 29 add_executable(does_not_use_local_messages_program src/main.cpp) 30 add_dependencies(does_not_use_local_messages_program ${catkin_EXPORTED_TARGETS})
如果有action文件,需要在generate_messages()之前添加:
add_action_files(FILES MyAction.action )
TARGETS - which targets to install
ARCHIVE DESTINATION - Static libraries and DLL (Windows) .lib stubs
LIBRARY DESTINATION - Non-DLL shared libraries and modules
RUNTIME DESTINATION - Executable targets and DLL (Windows) style shared libraries
install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )
包含Python绑定的库必须安装到不同的文件夹才能在Python中导入:
install(TARGETS python_module_library ARCHIVE DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION} )
catkin_install_python(PROGRAMS scripts/myscript DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
install(DIRECTORY include/${PROJECT_NAME}/ DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} PATTERN ".svn" EXCLUDE )
包含的子文件夹与包名称不匹配:
install(DIRECTORY include/ DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION} PATTERN ".svn" EXCLUDE )
install(DIRECTORY launch/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch PATTERN ".svn" EXCLUDE)