前言
功能包是啥
简单理解,功能包就是一个文件夹,一个具备一定功能的文件夹,一个有组织有结构的文件夹,一个能方便分享给其他人使用的文件夹,比如我们的小海龟功能包,它就是一个文件夹,名字叫turtlesim,在turtlesim文件夹下包含了其他几个子文件夹(src、msg、srv、action、include等等),这几个子文件夹里面又包含了一些配置文件、源文件等等内容,它们总体组织成了具备海龟仿真功能的一份功能包,我们可以使用它来订阅cmd_vel主题、发布消息等等。
在ROS 2的功能包开发环境中,ament充当其元编译系统(编译系统+构建工具,编译系统主要负责配置、编译和安装独立的功能包,而构建工具则负责将多个独立的功能包按照一定的拓扑结构进行链接),而colcon为其构建工具(用于构建、测试和分发功能包),官方支持通过CMake(跨平台编译工具,可以用简单的语句来描述所有平台的编译过程,能够产生makefile文件和project文件)或python创建一个功能包(当然,其他类型也是支持的)。
包里面都有啥
上图为小海龟仿真功能包内况,由于其是官方为了演示ROS的诸项知识点而写的,所以文件内容较为齐全,它涵盖了功能包(C/C++类型)的几个基本必须项:
include/<package_name>:功能包所需的公共头文件;
src:功能包源代码文件;
CMakeLists.txt:构建功能包规则文件;
package.xml:包的一些原始信息文件。
而在python类型的包中(比C/C++类型啰嗦些):
package.xml:包的一些原始信息文件;
resource/<package_name>:包的标记文件;
setup.cfg:包被启动运行(ros2 run)时需要这个启动配置文件;
setup.py:包进行安装时的指导脚本文件;
<package_name>:与包同名的文件夹(包含了__init__.py,上一篇我们有通过修改它来解决rosdep update超时问题),ROS 2工具利用它来找到我们的包。
工作空间中的功能包
一个工作空间中可以包含很多的包,这些包都有属于各自独立的文件夹(一个工作空间中包的类型不局限于某一个,而是可以百花齐放共存),这样组织架构就很简单明了,方便管理。我们可以在工作空间根src路径下创建这些功能包,包1、包2、包3...,这些包都处于同一级,也就是包之间不能相互嵌套(比如包2在包1内,这是不允许的)。
常见的一个工作空间中包的的情况如下:
workspace_folder/src/cpp_package_1/CMakeLists.txtinclude/cpp_package_1/package.xmlsrc/py_package_1/package.xmlresource/py_package_1setup.cfgsetup.pypy_package_1/...cpp_package_n/CMakeLists.txtinclude/cpp_package_n/package.xmlsrc/
动动手
创建一个功能包
我们打开一个终端,第一步要做的事情就是激活下基础层(underlay)的环境变量,因为我们的包都会依赖于一些基础层提供的支持,还记得命令不:
$source /opt/ros/iron/setup.bash
第二步,我们需要进入到ros2_ws/src路径下,因为这里是创建功能包的地方:
$cd ~/ros2_ws/src
第三步,使用下面的命令创建我们的新包:
$ros2 pkg create --build-type ament_cmake --license Apache-2.0 <package_name>
在官方提供的教程当中,我们会添加--node-name选项创建一个简单的Hello World类型的功能包,如下(--license为版本声明):
$ros2 pkg create --build-type ament_cmake --license Apache-2.0 --node-name my_node my_package
通过上面的命令它为我们在src路径下创建了一个名字为my_package的功能包文件夹,该文件夹下又生成了包的几个基本组成项,看下面:
my_package/src下面也已经生成了一个名为my_node.cpp的源代码文件,里面的内容如下:
只是会打印一句“hello world my_package package”。
构建一个功能包
现在我们需要退出到工作空间根路径下(cd ~/ros2_ws)进行功能包的构建工作:
$colcon build
上面这个命令会将src路径下的所有可用的功能包都会构建一遍,这样构建的时间与资源会与包的数量成正比关系,如果我们在src下有很多其他的功能包,我们只是想构建我们关心的包,那我们可用通过之前的colcon build --packages-up-to <package_name>命令以及下面的命令进行单独构建(我们可以在终端输入colcon build --hep进行查看更多的参数使用方法):
$colcon build --packages-select <package_name>
我们来单独构建my_package包:
$colcon build --packages-select my_package
激活环境变量
我们再打开一个新终端(运行和构建的环境最好分开,以免蹦出一些令人懵逼尴尬的东西),先source ROS 2安装环境(underlay)的工作变量(source /opt/ros/iron/setup.bash)再进入我们的ros2_ws路径source 工作空间的环境变量(overlay),这可以让我们的工作空间能够添加到路径当中,我们就能正常使用功能包了。
$source install/local_setup.bash
使用功能包
$ros2 run <package_name> <node_name>
通过上面的命令使用我们的功能包,<package_name>是功能包的名字,<node_name>是这个功能包支持的节点的名字(如果不清楚有哪些节点,我们可以在输入完包名字后连续两次按tab键,它会罗列出可用的节点,就像下图所演示的那样),我们试试:
$ros2 run my_package my_node
这个节点打印出了“hello world my_package package”,同my_node.cpp里面写的那样。
自定义package.xml
在前言里面我们曾提到过package.xml这个文件,它描述了这个功能包的一些基本信息,如作者信息、版本信息、构建类型、依赖信息等等,同时在创建我们的my_package包时,它有打印出下图的信息内容:
其中你能看到“description: TODO: Package description ”及“maintainer:['mike <mike@todo.todo>']”,这个TODO意思是需要我们手动重新编辑填充的,并不是由相关工具进行自动填充设置。下图是my_package包里面的package.xml文件内容:
我们来完善这个包信息文件,修改后的内容如下(别忘了编辑完保存):
本篇完。