您的位置:首页 > 编程语言

ROS-indigo下创建工作空间,创建程序包,package.xml,CMakeLists.txt相关代码记录及文件解析

2018-03-05 17:07 861 查看
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 <package_name> [depend1] [depend2] [depend3]catkin_create_pkg命令会要求你输入package_name,如果有需要你还可以在后面添加一些需要依赖的其它程序包,这个文件夹里面包含一个package.xml文件和一个CMakeLists.txt文件,这两个文件都已经自动包含了部分你在执行catkin_create_pkg命令时提供的信息。

自定义package.xml列子 1 <?xml version="1.0"?>
2 <package format="2">
3 <name>beginner_tutorials</name>
4 <version>0.1.0</version>
5 <description>The beginner_tutorials package</description>
6
7 <maintainer email="you@yourdomain.tld">Your Name</maintainer>
8 <license>BSD</license>
9 <url type="website">http://wiki.ros.org/beginner_tutorials</url>
10 <author email="you@yourdomain.tld">Jane Doe</author>
11
12 <buildtool_depend>catkin</buildtool_depend>
13
14 <build_depend>roscpp</build_depend>
15 <build_depend>rospy</build_depend>
16 <build_depend>std_msgs</build_depend>
17
18 <exec_depend>roscpp</exec_depend>
19 <exec_depend>rospy</exec_depend>
20 <exec_depend>std_msgs</exec_depend>
21
22 </package>

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 nameproject(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脚本中使用。 环境变量描述了软件包头文件导出的位置,源文件的位置,软件包所依赖的库以及这些库的路径。 名称始终遵循<PACKAGE NAME> _ <PROPERTY>的约定:

<NAME>_FOUND - Set to true if the library is found, otherwise false
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES - The include paths exported by the package
<NAME>_LIBRARIES or <NAME>_LIBS - The libraries exported by the package
<NAME>_DEFINITIONS - ?

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中。
这会导致生成nodelet_INCLUDE_DIRS,nodelet_LIBRARIES等。当然
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 Paths - Where can header files be found for the code (most common in C/C++) being built
Library Paths - Where are libraries located that executable target build against?
include_directories(<dir1>, <dir2>, ..., <dirN>)
link_directories(<dir1>, <dir2>, ..., <dirN>)

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(<executableTargetName>, <lib1>, <lib2>, ... <libN>)Example:add_executable(foo src/foo.cpp)
add_library(moo src/moo.cpp)
target_link_libraries(foo moo) -- This links foo against libmoo.so

6.Messages, Services, and Action Targets

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})

Example

   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
)

7.Optional Step: Specifying Installable Targets

如果您希望能够对代码进行“make install”,则需要指定目标应该在哪里结束。
这是使用CMake install()函数完成的,有如下参数:

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}
)

8.Installing Python Executable Scripts

catkin_install_python(PROGRAMS scripts/myscript
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})


9.Installing header files

install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE
)
包含的子文件夹与包名称不匹配:
install(DIRECTORY include/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE
)

10.Installing roslaunch Files or Other Resources

其他资源如launchfiles可以安装到$ {CATKIN_PACKAGE_SHARE_DESTINATION}:
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
PATTERN ".svn" EXCLUDE)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息