说明:本文主要是结合 ROS 官网的相关内容以及自己的相应操作心得整理而成,记录在此处仅仅是为了自己查找方便!
ROS 官网相关参考内容网址:http://wiki.ros.org/ROS/Tutorials/CreatingPackage
1. catkin package 由什么组成?
一个 package 被认为是 catkin package,必须要满足下面几个条件:
- 这个 package 必须包含一个符合 catkin 要求的 package.xml 文件。这个 package.xml 文件提供关于这个 package 的元信息。
- 这个package必须包含一个使用 catkin 的 CMakeLists.txt。如果这是一个 catkin metapackage,必须包含一个相关的样板 CMakeLists.txt。
- 每个 package 必须有自己的文件夹。这意味着没有嵌套的 package,也没有共享同一目录的多个 package。
最简单的 package 可能是这样的结构:
my_package/
CMakeLists.txt
package.xml
2. catkin 工作区的 package
使用 catkin package 的推荐方法是使用 catkin 工作区,但是也可以直接 build catkin package。简单的工作区可能像下面这样:
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
2.1 create catkin 工作区
一般 catkin 已经默认安装好了,只需要 source 一下:
source /opt/ros/melodic/setup.bash
然后就可以直接 create catkin 工作区
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/
catkin_make
catkin_make 命令是用于处理 catkin 工作区的便捷工具。 第一次在工作区中运行它,将在“src”文件夹中创建一个 CMakeLists.txt 链接。
系统默认的 Python 版本是 Python2,Python3 的用户还需要进行额外操作,参见:
http://wiki.ros.org/catkin/Tutorials/create_a_workspace
此外,如果查看当前目录,可以看到“build”和“devel”文件夹。 在“devel”文件夹中,可以看到现在有几个 setup.*sh 文件, source 这些文件中的任何一个都会将此工作区覆盖在环境之上。想了解更多信息可查看:
在继续 source 新的 setup.*sh 文件之前:
source devel/setup.bash
为确保安装脚本正确覆盖工作区,需确保 ROS_PACKAGE_PATH 环境变量包含所在的目录:
echo $ROS_PACKAGE_PATH
3. create catkin package
本文将演示如何使用 catkin_create_pkg 脚本来 create 新的 catkin package,以及在 create 后可以使用它来做什么。
首先切换到在 create catkin 工作区一文中 create 的 catkin 工作区的源空间目录:
cd ~/catkin_ws/src
现在使用 catkin_create_pkg 脚本 create 一个名为“beginner_tutorials”的新 package,它依赖于 std_msgs、roscpp 和 rospy:
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
这将 create 一个名为 beginner_tutorials 的文件夹,包含一个 package.xml 和一个 CMakeLists.txt,其中部分填充了提供给 catkin_create_pkg 的信息。
catkin_create_pkg 需要给它一个 package_name 和可能存在的依赖:
catkin_create_pkg <package_name> [depend1] [depend2] [depend3]
catkin_create_pkg 还有更多的功能,可参考:http://wiki.ros.org/catkin/commands/catkin_create_pkg
4. build 一个 catkin 工作区并 source 设置文件
在 catkin 工作区中 build package:
cd ~/catkin_ws
catkin_make
工作区 build 好后就会在 devel 的子文件夹中 create 类似 /opt/ros/melodic 下类似的结构。
要将工作区添加到 ROS 环境,需要 source 生成的设置文件:
. ~/catkin_ws/devel/setup.bash
5. package 依赖
5.1 一阶依赖
之前使用 catkin_create_pkg 时,提供了一些 package 依赖。 现在可以使用 rospack 工具查看这些一阶依赖。
rospack depends1 beginner_tutorials
rospack 列出了在运行 catkin_create_pkg 时用作参数的相同依赖,这些依赖存储在 package.xml 文件中:
roscd beginner_tutorials
cat package.xml
5.2 间接依赖
在许多情况下,依赖也会有它自己的依赖。 例如,rospy 有其他依赖项。
rospack depends1 rospy
一个 package 可以有很多间接依赖,幸运的是 rospack 可以递归地确定所有嵌套的依赖。
rospack depends beginner_tutorials
6. 定制 package
这一部分将查看由 catkin_create_pkg 生成的每个文件,并逐行描述这些文件的每个组件以及如何为自己的 package 自定义它们。
6.1 定制 package.xml
新 package 中应该包含生成的 package.xml,现在查看新的 package.xml 并修改需要注意的任何元素。下面是上文 5.1 执行了“cat package.xml”命令后的结果,供参考:
rokin@OMEN:~/catkin_ws/src/beginner_tutorials$ cat package.xml
<?xml version="1.0"?>
<package format="2">
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>The beginner_tutorials package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="rokin@todo.todo">rokin</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>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/beginner_tutorials</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>
6.1.1 description tag
<description>The beginner_tutorials package</description>
可以把描述改成喜欢的任何东西,但按照惯例,第一句话应该简短,同时涵盖了 package 的范围。如果很难用一句话来描述这个 package,那么它可能需要被分解。
6.1.2 maintainer tags
<!-- 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>
这是 package.xml 的必需且重要的标签,因为它让其他人知道该 package 的相关事宜。 至少需要一名 maintainer;但如果愿意,也可以拥有许多 maintainers。 maintainer 的名字进入标签正文,还有一个 email 属性需要填写:
<maintainer email="you@yourdomain.tld">Your Name</maintainer>
6.1.3 license tags
<!-- 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>
需要选择并填写一个 license 在此处。 一些常见的开源 license 是 BSD、MIT、Boost Software License、GPLv2、GPLv3、LGPLv2.1 和 LGPLv3,可以在开源计划中阅读其中的一些内容,网址为:https://opensource.org/licenses/alphabetical
在本文中,我们将使用 BSD 许可证,因为其余的核心 ROS 组件已经使用它:
<license>BSD</license>
6.1.4 dependencies tags
这一组标签描述了 package 的依赖关系。 依赖分为build_depend、buildtool_depend、exec_depend、test_depend。 有关这些标签的更详细说明,请参阅有关 Catkin 依赖的文档(http://wiki.ros.org/catkin/package.xml#Build.2C_Run.2C_and_Test_Dependencies)。 由于我们将 std_msgs、roscpp 和 rospy 作为参数传递给 catkin_create_pkg,因此依赖将如下所示:
<!-- The *_depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>genmsg</build_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>python-yaml</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
除了 catkin 上的默认 buildtool_depend 之外,列出的所有依赖都已添加为 build_depend。 在这种情况下,我们希望所有指定的依赖在 build 和 run 时都可用,因此我们还将为每个依赖添加一个 exec_depend 标记:
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
6.1.5 完整的 package.xml
如果没有注释和未使用的标签,完整的 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>
6.2 定制 CMakeLists.txt
catkin_create_pkg create 的 CMakeLists.txt 文件将在后面关于 build ROS 代码的文章中介绍。