![精通ROS机器人编程(原书第3版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/21/51444021/b_51444021.jpg)
2.1 创建ROS功能包
ROS软件包是ROS系统的基本单位。我们可以创建,然后编译生成一个ROS软件包,并将其向公众发布。当前我们使用的ROS发布版本是Noetic Ninjemys。我们使用catkin编译系统来编译生成ROS软件包。编译系统主要负责将用户的源码生成“目标(target)”(可执行文件或库文件)。在较老的ROS发行版本中,例如Electric和Fuerte,使用rosbuild来编译生成软件包。由于rosbuild存在各种缺陷,所以catkin应运而生了。catkin基本上基于跨平台编译器(Cross Platform Make,CMake)。它有很多优点,例如可以将软件包移植到另一个操作系统(如Windows)上。如果操作系统支持CMake和Python,就可以轻松地将基于catkin的软件包移植到该系统上。
使用ROS软件包的第一个要求是创建ROS的catkin工作区。安装好ROS后,创建一个名为catkin_ws的catkin工作区:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/38_01.jpg?sign=1739911470-CtVW90ymYhdkVS9BKnkLxV6vXK16nAo7-0-094526c0a9b966e8ff97edc5e7c2d8e9)
为了编译工作区,我们需要获取ROS的环境变量,以便访问ROS系统提供的功能:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/38_02.jpg?sign=1739911470-rY3eZJi5e96kfStQI6hZqRwZgb9KU2ZG-0-d9a7a5279e113e32ec05f5d6de117656)
切换到前面创建的源码文件夹src中:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/38_03.jpg?sign=1739911470-PwXPCziufr7JkoBQyKKVb15TKUfifdsf-0-81757d49015e3e35f494d2e611a4c481)
初始化新的catkin工作区:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/38_04.jpg?sign=1739911470-TdYf9uiEnBh1YqDgm5pjm7IAJkvPIPtZ-0-6b4b43b75e52e7129ea9e63e1b49121f)
即使现在工作区中没有软件包,我们也可以编译工作区。使用以下命令切换到工作区文件夹中:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/39_01.jpg?sign=1739911470-aTMUiQFDztNC9xieDflMnMeyH3z61XUX-0-3e139b5cba0ee0e1c14418a03bccec83)
下面使用catkin_make编译工作区:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/39_02.jpg?sign=1739911470-mPEVSbWRrwMujU9sVTDTytFl2uJdOGkQ-0-986497d3addd373456710ea6f035a884)
执行完上面这条命令后,在catkin工作区中将生成devel和build文件夹。各种安装文件位于devel文件夹中。要将创建的ROS工作区添加到ROS环境变量中,我们需要获取其中的一个安装文件setup.bash。此外,在每次使用以下命令启动新的bash会话时,我们都可以获取此工作区的配置文件:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/39_03.jpg?sign=1739911470-haQbqkugZJ12TkIUvbs5imyxtONjx3UC-0-14e81d8f886b17446cfdeac4d962a8a9)
配置好catkin工作区后,我们就可以创建自己的软件包了,其中将包含示例节点,用来演示ROS主题、消息、服务和动作库(actionlib)的工作方式。注意,如果没有正确设置工作区,则无法使用任何ROS命令。catkin_create_pkg命令就是用来创建ROS软件包的。我们将用它创建各种ROS概念的演示示例。
切换到catkin工作区的src文件夹后,使用以下命令创建软件包:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/39_04.jpg?sign=1739911470-H5ozYU93kqU0rJTPvEUQ6KfWGlqwMfF2-0-756afbec79ea07aea3c03550ef8e6d0a)
源码文件夹:所有的ROS软件包(无论是从头创建的还是从其他代码库中下载的)都必须放在ROS工作区的src文件夹中,否则ROS系统将无法识别它们,从而导致无法编译。
下面是创建ROS示例软件包的命令:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/39_05.jpg?sign=1739911470-CoQ6vN78VRNmI3CUsR0elAa8HuFitfMJ-0-a4ebe2a170b78d379d864875138e7908)
该功能包中的依赖项如下:
roscpp:这是ROS的C++实现,一个ROS客户端库,为C++开发人员提供API,使用ROS主题、服务和参数等生成ROS节点。包含该依赖的原因是我们要编写的是一个C++实现的ROS节点。任何使用C++节点代码的ROS软件包都必须添加此依赖项。
std_msgs:该软件包包含了基本的ROS原始数据类型,例如整型、浮点型、字符串、数组等。我们可以在节点中直接使用这些数据类型,而无须定义新的ROS消息。
actionlib:该超软件包提供了在ROS节点中创建可抢占任务的接口。我们在这个软件包中创建了基于actionlib的节点,所以我们需要包含该软件包来创建ROS节点。
actionlib_msgs:该软件包包含了与动作服务器和动作客户端交互所需的标准消息定义。
创建了软件包后,我们也可以通过编辑CMakeLists.txt和package.xml这两个文件来手动添加其他依赖项。如果成功创建了软件包,我们将收到以下信息,如图2.1所示。
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/40_01.jpg?sign=1739911470-ySNCbifvMRx7yY5XmZJvxN7uGse1MUNd-0-bdbf3b3d016d4248c89b8e6b5099680b)
图2.1 创建ROS软件包时的终端信息
创建了这个软件包后,可以使用catkin_make命令来编译生成软件包,但是它不会增加任何节点。我们必须在catkin工作区的根路径下执行此命令。以下是我们编译生成空ROS软件包的命令:
![](https://epubservercos.yuewen.com/0D546D/30334936404123306/epubprivate/OEBPS/Images/40_02.jpg?sign=1739911470-J0nf4FGLdak46Y4DmMZpFfEKEyC8bd6v-0-610d6233a5e8c7031331709275f741ca)
成功编译生成软件包后,我们可以将节点源码添加到工作区下的src文件夹中。
在CMake的build文件夹中主要包含了节点的可执行文件,该节点的源码位于catkin工作区的src文件夹中。devel文件夹主要包含了在编译过程中生成的Bash脚本、头文件和可执行文件。我们可以看到使用catkin_make创建并编译生成ROS节点的过程。