机器人系统——ROS2文档(进阶)—使用 rosdep 管理依赖
目标: 使用 rosdep 管理外部依赖。
教程级别: 中级
时间: 5 分钟
本教程将解释如何使用 rosdep 管理外部依赖。
什么是 rosdep?
rosdep 是一个依赖管理工具,可以与包和外部库一起使用。它是一个命令行工具,用于识别和安装构建或安装包所需的依赖项。rosdep 本身并不是一个包管理器;它是一个元包管理器,利用其对系统和依赖项的了解,在特定平台上找到要安装的适当包。实际安装使用系统包管理器完成(例如 Debian/Ubuntu 上的 apt,Fedora/RHEL 上的 dnf 等)。
它最常在构建工作空间之前调用,用于安装该工作空间内包的依赖项。
它能够处理单个包或一个目录中的包(例如工作空间)。
关于 package.xml 文件
package.xml 是您的软件中 rosdep 查找依赖集的文件。package.xml 中的依赖列表完整且正确非常重要,这使所有工具能够确定包的依赖关系。缺失或不正确的依赖可能导致用户无法使用您的包,导致工作空间中的包构建顺序错误,以及包无法发布。
package.xml 文件中的依赖通常被称为“rosdep 键”。这些依赖由包的创建者手动填充在 package.xml 文件中,应该是其所需的所有非内置库和包的详尽列表。
这些以以下标签表示(完整规范请参阅 REP-149):
<depend>
这些是您的包在构建时和运行时都应提供的依赖。对于 C++ 包,如果有疑问,请使用此标签。纯 Python 包通常没有构建阶段,因此不应使用此标签,而应使用 <exec_depend>。
<build_depend>
如果您只在构建包时使用某个特定依赖,而在执行时不使用,您可以使用 <build_depend> 标签。
对于这种类型的依赖,您包的已安装二进制文件不需要安装该特定包。
但是,如果您的包导出的头文件包含了此依赖的头文件,这可能会造成问题。在这种情况下,您还需要 <build_export_depend>。
<build_export_depend>
如果您导出的头文件包含了来自依赖的头文件,那么其他依赖您包的包在构建时将需要它。这主要适用于头文件和 CMake 配置文件。您导出的库所引用的库包通常应指定 <depend>,因为它们在执行时也需要。
<exec_depend>
此标签声明共享库、可执行文件、Python 模块、启动脚本和运行包时所需的其他文件的依赖。
<test_depend>
此标签声明仅测试所需的依赖。这里的依赖不应与 <build_depend>、<exec_depend> 或 <depend> 指定的键重复。
rosdep 如何工作?
rosdep 将检查其路径中的 package.xml 文件或特定包,并找到其中存储的 rosdep 键。然后将这些键与中央索引进行交叉引用,以在各种包管理器中找到适当的 ROS 包或软件库。最后,一旦找到包,它们就会被安装并准备就绪!
rosdep 通过将中央索引检索到本地机器上来工作,这样它就不必在每次运行时访问网络(在 Debian/Ubuntu 上,其配置存储在 /etc/ros/rosdep/sources.list.d/20-default.list 中)。
中央索引被称为 rosdistro,可以在线找到。我们将在下一节中进一步探讨。
如何知道在 package.xml 中放入哪些键?
好问题,很高兴你提出!
- 如果您想在包中依赖的包是基于 ROS 的,并且已经发布到 ROS 生态系统中,例如 nav2_bt_navigator,您可以直接使用包的名称。您可以在 rosdistro 仓库的对应发行版目录下的 distribution.yaml 文件中找到所有已发布 ROS 包的列表。
- 如果您想依赖一个非 ROS 包,通常称为“系统依赖”,您需要找到特定库的键。一般来说,有两个感兴趣的文件:
- rosdep/base.yaml 包含 apt 系统依赖
- rosdep/python.yaml 包含 Python 依赖
- 要查找键,请在这些文件中搜索您的库并找到名称。这就是要放入 package.xml 文件中的键。
例如,假设一个包依赖于 doxygen,因为它是一个关心高质量文档的优秀软件。我们会在 rosdep/base.yaml 中搜索 doxygen 并找到:
doxygen:
arch: [doxygen]
debian: [doxygen]
fedora: [doxygen]
freebsd: [doxygen]
gentoo: [app-doc/doxygen]
macports: [doxygen]
nixos: [doxygen]
openembedded: [doxygen@meta-oe]
opensuse: [doxygen]
rhel: [doxygen]
ubuntu: [doxygen]
这意味着我们的 rosdep 键是 doxygen,它将在不同操作系统的包管理器中解析为这些不同的名称进行安装。
如果我的库不在 rosdistro 中怎么办?
如果您的库不在 rosdistro 中,您可以体验开源软件开发的伟大之处:您可以自己添加它!rosdistro 的拉取请求通常在一周内被合并。
有关如何贡献新的 rosdep 键的详细说明,请参阅 rosdistro 仓库的贡献指南。如果由于某种原因无法公开贡献,还有其他选项:
- 分叉 rosdistro 并维护一个包含额外键的替代索引(使用自定义 Rosdistro 版本)
- 创建一个包含自定义键的新文件,并指示 rosdep 在填充本地索引时检查它(补充自定义 rosdep 键)
如何使用 rosdep 工具?
rosdep 安装
如果您在 ROS 中使用 rosdep,它很方便地与 ROS 发行版一起打包。这是获取 rosdep 的推荐方式。您可以通过以下方式安装:
Ubuntu:
sudo apt install python3-rosdep
如果您在 ROS 之外使用 rosdep,系统包可能不可用。在这种情况下,您可以直接从 PyPI 安装它:
pip install rosdep
rosdep 操作
现在我们对 rosdep、package.xml 和 rosdistro 有了一些了解,我们准备使用这个工具本身!首先,如果这是第一次使用 rosdep,必须通过以下方式初始化:
sudo rosdep init
rosdep update
这将初始化 rosdep,update 将更新本地缓存的 rosdistro 索引。定期 update rosdep 以获取最新索引是个好主意。
最后,我们可以运行 rosdep install 来安装依赖项。通常,这是通过一次调用在包含许多包的工作空间上运行,以安装所有依赖项。如果在工作空间根目录且 src 目录包含源代码,该调用将如下所示:
rosdep install --from-paths src -y --ignore-src
分解一下:
- –from-paths src 指定检查 package.xml 文件以解析键的路径
- -y 表示默认同意包管理器的所有提示,无需提示安装
- –ignore-src 表示即使存在 rosdep 键,如果包本身也在工作空间中,也忽略安装依赖
还有其他参数和选项可用。使用 rosdep -h 查看它们,或查看 rosdep 的更完整文档。
夜雨聆风