主要介绍ROS package程序包里package.xml,cmakelist.txt,launch文件,分别介绍文件里的语法组成,对于后续开发ROS程序有很大帮助。一个catkin程序包必须包含 package.xml和CMakeList.txt文件,这个package.xml文件提供有关程序包的元信息,而catkin metapackages中必须包含一个对CMakeList.txt文件的引用。
Part 1: 最简单的程序包:
my_package/
CMakeLists.txt
package.xm
一个简单catkin工作空间:
Workspace_folder -- WORKSPACE
src/ -- SOURCE SPACE
CMakeLists.txt -- ‘Toplevel’CMake file, provided by catkin
package_1/
CMakeLists.txt -- CMakeLists.txt file for package_1
package.xml -- Package manifest for package_1
…
package_n/
CMakeLists.txt -- CMakeLists.txt file for package_n
package.xml -- Package manifest for package_n
Part 2: package.xml
每一个package.xml文件都以<package>作为根标签
<package>
...
</package>
在<package>内部至少得包含以下一系列标签:
<name> - 标签名
<version> - 程序包版本号
<description> - 程序包内容描述
<maintainer> - 维护程序包人名
<license> - 软件协议如GPL, BSD, ASL等
最简单package.xml文件example:
<package>
<name>foo_core</name>
<version>1.2.4</version>
<description>
This package provides foo capability.
</description>
<maintainer email="ivana@willowgarage.com">Ivana Bildbotz</maintainer>
<license>BSD</license>
</package>
接下来的标签用来描述程序包的各种依赖项,这些依赖项分为build_depend、buildtool_depend、run_depend、test_depend。buildtool_depend指的编译package所需要systemtools,build_depend指的编译这个package所需要的package,run_depend运行这个包里代码所需的package或library,test_depend指的是单元测试所需的额外依赖项。
<buildtool_depend> <build_depend> <run_depend> <test_depend> 至少得有一个依赖的项。
<package>
<name>foo_core</name>
<version>1.2.4</version>
<description>
This package provides foo capability.
</description>
<maintaineremail="ivana@willowgarage.com">Ivana Bildbotz</maintainer>
<license>BSD</license>
<buildtool_depend>catkin</buildtool_depend>
</package>
此外,还有<url> <author>等标签。
Part 3: CMakeList.txt
CMakeList.txt文件需要以以下格式,否则不能正确编译
1,Required CMake Version (cmake_minimum_required)2,Package Name (project())
3,Find other CMake/Catkin packages needed for build (find_package())
4,Message/Service/Action Generators (add_message_files(), add_service_files(), add_action_files())
5,Invoke message/service/action generation (generate_messages())
6,Specify package build info export (catkin_package())
7,Libraries/Executables to build (add_library()/add_executable()/target_link_libraries())
8,Tests to build (catkin_add_gtest())
9,Install rules (install())
(1) CMakeLists.txt最开始指出CMake所需版本,Catkin 要求2.8.3或者更高
cmake_minimum_required(VERSION 2.8.3)
(2) 接下来项是package name
project(beginner_tutorials)
(3) find_package用来指明build project所需要其他的CMake package
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg) 依赖于catkin roscpp rospy std_msgs message_generation。
(4) catkin_package() 是一个catkin Cmake宏,必须在 add_library()和add_executable()之前,catkin_package()包含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
CFG_EXTRAS - Additional configuration options
例如
catkin_package(INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv)
(5) Build Targets:编译目标有多种形式,通常是可执行目标文件或者可执行文件编译和运行所需要的库文件。
1. include_directories() link_directories()
include_directories(<dir1>, <dir2>, ..., <dirN>)
link_directories(<dir1>, <dir2>, ..., <dirN>)
例如使用catkin和Boost,则 include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS}) 第一个参数”include”指的是package内的include/路径
link_directories()可以用来添加额外库的路径,但是一般不推荐。 比如: link_directories(~/my_libs)
2. add_executable()
add_executable(myProgramsrc/main.cpp src/some_file.cpp src/another_file.cpp)
把src/main.cpp src/some_file.cpp src/another_file.cpp.编译成可执行文件myProgram
3. add_library()
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})
4. target_link_libraries()
target_link_libraries() 指明可执行文件运行所需要的链接库
语法:target_link_libraries(<executableTargetName>,<lib1>, <lib2>, ... <libN>)
例子:
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 actions
有3个宏分别用来添加messages services 和actions: add_message_files() add_service_files() add_action_files(),紧接着 generate_messages()生成对应的messages,services,actions 。这些宏必须在 catkin_package()宏之前,如下:
find_package(catkinREQUIRED COMPONENTS ...)
add_message_files(...)
add_service_files(...)
add_action_files(...)
generate_messages(...)
catkin_package(...)
...
(7) catkin_package()
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
必须有个CATKIN_DEPENDS 、message_runtime。
Part 4: launch
例如下面launch xml文件
<launch>
<groupns="turtlesim1">
<nodepkg="turtlesim"name="sim"type="turtlesim_node"/>
</group>
<groupns="turtlesim2">
<nodepkg="turtlesim"name="sim"type="turtlesim_node"/>
</group>
<nodepkg="turtlesim"name="mimic"type="mimic">
<remapfrom="input"to="turtlesim1/turtle1"/>
<remapfrom="output"to="turtlesim2/turtle1"/>
</node>
</launch>
<launch> 以launch标签开头以表明这是一个launch文件
<groupns="turtlesim1">
<nodepkg="turtlesim"name="sim"type="turtlesim_node"/>
</group>
<groupns="turtlesim2">
<nodepkg="turtlesim"name="sim"type="turtlesim_node"/>
</group>
创建了两个节点分组并以'命名空间(namespace)'标签来区分,其中一个名为turtulesim1,另一个名为turtlesim2,两个组里面都使用相同的turtlesim节点并命名为'sim'。这样可以同时启动两个turtlesim模拟器而不会产生命名冲突。
<nodepkg="turtlesim"name="mimic"type="mimic">
<remapfrom="input"to="turtlesim1/turtle1"/>
<remapfrom="output"to="turtlesim2/turtle1"/>
</node>
在这里我们启动模仿节点,并将所有话题的输入和输出分别重命名为turtlesim1和turtlesim2,这样就会使turtlesim2模仿turtlesim1。
</launch> 这个是launch文件的结束标签。