ament和catkin的混合研究(catment) [Alyssa@9595]

接下来的一切都是试验性的和推测性的。 [Alyssa@9596]

背景

曾经有一个编译工具被称为 rosbuild 。然后推出了另外一个工具叫做 catkin ,很大程度上取代了 rosbuild 。最近介绍一个工具叫做 ament ,有一天可能会取代 catkin[Alyssa@9599]

这三种工具都可以被认为是“元构建系统”。它们位于其他构建系统之上 (例如,CMake、Python setuptools),并提供旨在使这些构建系统更易于使用的额外功能,尤其是在跨多个包管理依赖关系以及在单个工作区中构建多个包时。 [Alyssa@9600]

这些元构建系统中的每一个都会执行两个操作: [Alyssa@9601]

  1. 将API添加到底层构建系统 (例如,CMake),可用于简化常见任务 (例如,在构建可执行文件时提供由依赖包导出的所有标志)。通常有钩子程序允许包在核心元构建系统之外注入额外的API。 [Alyssa@9602]

    • rosbuild: mk/cmake.mk, rosbuild_init(), rosbuild_add_executable()[Alyssa@9603]

    • catkin: catkin_package(), catkin_install_python()[Alyssa@9604]

    • ament: ament_target_dependencies(), ament_export_dependencies(), ament_package()[Alyssa@9605]

  2. 提供一种工具,该工具可用于在包含许多包的工作区上按依赖项顺序迭代,构建并可能安装每个包。 [Alyssa@9606]

将所有这些系统连接在一起的是将代码分成**包**的共同线程,每个包包含一个清单文件 ( manifest.xmlpackage.xml )。该清单是元构建系统 (API和构建工具) 两个部分运行所必需的 (除了一些例外)。 [Alyssa@9610]

假设

  1. 虽然我们通常认为元构建系统的两个方面是耦合的,但它们不是必须的。 包内部使用的API和遍历包的工具可以被认为在很大程度上是独立的,包清单构成它们之间的接口。原则上没有理由,例如,不能修改 rosmake 来迭代一个由 catkin 包组成的工作空间,按照依赖关系的顺序进入软件包,并为每个软件包执行通常的 mkdir build; cd build; cmake ..; make install 惯例 (通过将适当的标志传递给 cmakemake )。 [Alyssa@9612]

  2. 从一个元构建系统迁移到另一个元构建系统所需的工作量应该被最小化。rosbuildcatkin 的大规模迁移是困难的,对社区中的许多人来说仍然是一个痛点。虽然要求开发人员进行改变以换取对新功能的访问是合理的,但在不牺牲新系统的有效性的前提下所需的更改应尽可能小。当旧系统被广泛使用时,情况尤其如此。 [Alyssa@9613]

    1. 推论: 没有很好的理由,就不需要迁移到新的元构建系统。 如果开发者不想要新系统提供的功能,那么她就不应该被强迫从老的系统迁移到新的系统,除非旧系统有什么不可挽回故障 (例如, rosbuild 的源内构建模式和缺少 "install" 步骤)。 [Alyssa@9614]

  3. 互通性是一件好事。 只要有可能 (不是所有的组合都是可行的),开发人员应该能够混合和匹配元构建系统,包括混合他们不同的方面 (例如,使用来自一个系统的构建工具和来自另一个系统的API)。当开发人员想要将使用一个元构建系统 (例如,带有 catkin 的ROS)的现有的大型代码,与使用另一个元构建系统的代码提供的新的库和工具 (例如,ROS 2和 ament )组合使用时,这种混合和匹配就是尤其重要的。理想情况下,这种组合可以在不需要更改任何代码库使用的API的情况下完成,也不需要告诉开发人员使用哪个构建器工具。 [Alyssa@9615]

    1. 推论: 工作空间不必同质。 没有理由不能自由混合,例如在两个方向上都存在依赖关系的 catkinament 包在一个工作区,只要正在使用的构建器工具知道如何同时构建它们。包 (至少是CMake控制的包) 之间的主要接口是它们的CMake配置文件。只要该配置文件遵循标准协议 (设置 foo_LIBRARIES 等),那么谁编写该文件就无关紧要。它可以由 catkinament 自动生成,甚至可以由想要在其包中使用纯CMake的开发人员手动编写,但仍要有 catkinament 包依赖。 [Alyssa@9616]

具有实验性实现的使用案例 [Alyssa@9617]

将ROS包添加到ROS 2工作空间并使用 ament build 构建 [Alyssa@9618]

假设您要添加一些现有的ROS包到ROS2的工作空间中, 但不想将ROS包从 catkin 迁移到 ament (反之亦然)。以下是两个允许您执行此操作的补丁: [Alyssa@9619]

  • ament_package : 增加对格式1包清单的支持,而不是要求格式2。这一变化与 catkinament 的对比没有严格的关系,因为格式2已经出现一段时间并且 catkin 支持它,所以开发人员已经可以将他们的清单更新为格式2。但是有大量的ROS代码使用格式1,所以我们应该支持它。该实现可以改进,例如,通过推理各种类型的依赖标签以及它们在格式1和2之间的差异。 [Alyssa@9620]

  • ament_tools : 在 ament 中添加一个新的 catkin 构建类型。此实现只是将 catkin 包与纯 cmake 包同等对待,这样似乎工作正常。它还可以做得更复杂。 [Alyssa@9621]

示例用法: [Alyssa@9622]

  1. 使用上面提到的分支,像往常一样获取ROS 2代码。 [待校准@9623]

  2. 向您的工作空间添加一些 catkin ROS包,确保满足它们的所有依赖项 (或者存在于工作空间中,或者在source合适的安装shell文件后安装在其他地方)。 [Alyssa@9624]

  3. 像往常一样构建 (例如, ./src/ament/ament_tools/scripts/ament.by build )。 [Alyssa@9625]

瞧: 您的现有代码不会仅仅因为使用了新构建工具而突然崩溃。 [Alyssa@9626]

变体: 用 ament build 构建ROS包 [Alyssa@9627]

假设您喜欢新的 ament 工具,并希望使用它来构建内部使用 catkin 的现有ROS包。这里有一个如何做到这一点的例子,安装一个最轻量的 ament 工具,然后用它来构建一个完全由ROS catkin 包组成的工作空间: [Alyssa@9628]

mkdir -p ~/ament_ws/src
cd ~/ament_ws/src
git clone https://github.com/osrf/osrf_pycommon.git
git clone https://github.com/ament/ament_package.git
cd ament_package
git checkout catkin
cd ..
git clone https://github.com/ament/ament_tools.git
cd ament_tools
git checkout catkin
cd ../..
 ./src/ament_tools/scripts/ament.py build

现在构建ROS包: [Alyssa@9629]

. $HOME/ament_ws/install/setup.bash
cd ~/ros_catkin_ws
ament build

瞧: 你使用 ament 构建工具来构建了你的 catkin 包,而不必迁移它们。 [Alyssa@9630]

变体: 在ROS 2包中使用 catkin API [待校准@9631]

让我们假设你正在内部使用 ament API的ROS 2之上构建,并且您想要使用 catkin API添加一个新包。 [Alyssa@9632]

为了完成这项工作,我们需要安装一个 Python3的 catkin (二进制debians使用Python2.7)。下面是一个安装到 $HOME/catkin 的例子: [Alyssa@9633]

# install catkin_pkg
git clone https://github.com/ros-infrastructure/catkin_pkg.git
cd catkin_pkg
git checkout ament
python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb
# install catkin
git clone https://github.com/ros/catkin.git
cd catkin
git checkout ament
mkdir build
cd build
PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3
make install

要使用该版本的catkin,您只需source $HOME/catkin/setup.bash 文件。 [Alyssa@9634]

假设您在 ~/ros2_ws 中有通常的ROS 2工作空间,并且您在 ament_packageament_toolscatkin 分支上。将来自 https://github.com/gerkey/catmentimage_tools_catkin 包添加到该工作空间,这是ROS 2 image_tools 包的一个简单端口,将其从 ament API转换为 catkin API。使用以下命令构建它: [Alyssa@9635]

cd ~/ros2_ws
. $HOME/catkin/setup.bash
./src/ament/ament_tools/scripts/ament.py build

瞧: 在ROS 2上添加新包时,您可以在包中自由选择您喜欢的CMake API。 [待校准@9636]

  • 警告: 需要注释掉 catkin_package()CATKIN_DEPENDS 的使用,因为在某个地方有人因为像 rclcpp 这样的东西不是 catkin 包而感到不安。这种限制需要以某种方式放宽。 [Alyssa@9637]

  • 待办事项: 相同的例程,但使用依赖于 catkin 包的 ament 包 (这很容易)。 [Alyssa@9638]

  • 待办事项: 同样的例程,但用一个既不使用 ament 也不使用 catkin 的普通 CMakeLists.txt 软件包,并提供一个手动生成的 fooConfig.cmake 文件,该文件导出正确的内容,使其对外部用户来说看起来一样。 [Alyssa@9639]

catkin_make_isolated 构建ROS 2包 [待校准@9640]

让我们假设您已经熟悉了ROS和 catkin ,并且很乐于去尝试ROS2,但你没有心情学习 ament 。你宁愿坚持你所知道的,比如用 catkin_make_isolated 构建一切。这里有一个允许您这样做的补丁: [Alyssa@9641]

  • catkin : 增加对声称自己有 ament_* 构建类型的包的支持。此实现唤起 ament 来构建每个这样的包。虽然 ament_cmake 包可以被视为普通的 cmake 包 (就像我们在 ament 中添加 catkin 支持时所做的那样),但 ament_python 包需要一些粗糙的Python调用。与其试图在 catkin 中复制这种逻辑,不如让 ament 来处理它。同样在此补丁中,我们将 buildtool_export_depend 包添加到构建时考虑的集合中。 [Alyssa@9642]

  • catkin_pkg : 同样在这个补丁,我们将 buildtool_export_depend 包添加到计算拓扑顺序需要考虑的任务集中。 [Alyssa@9643]

因为我们要去调用到 ament build ,我们还需要一个 ament 的最小安装,如前一个例子做的那样: [Alyssa@9644]

mkdir -p ~/ament_ws/src
cd ~/ament_ws/src
git clone https://github.com/osrf/osrf_pycommon.git
git clone https://github.com/ament/ament_package.git
cd ament_package
git checkout catkin
cd ..
git clone https://github.com/ament/ament_tools.git
cd ament_tools
git checkout catkin
cd ../..
 ./src/ament_tools/scripts/ament.py build

然后我们需要在某处安装catkin的修改版: [Alyssa@9645]

# install catkin_pkg
git clone https://github.com/ros-infrastructure/catkin_pkg.git
cd catkin_pkg
git checkout ament
python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb
# install catkin
git clone https://github.com/ros/catkin.git
cd catkin
git checkout ament
mkdir build
cd build
PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3
make install

现在构建ROS 2包: [Alyssa@9646]

. $HOME/catkin/setup.bash
. $HOME/ament_ws/install/setup.bash
cd ~/ros2_ws
touch src/eProsima/AMENT_IGNORE
PYTHONPATH=$PYTHONPATH:/home/gerkey/ros2_ws_catkin/install_isolated/lib/python3.5/site-packages catkin_make_isolated --install

瞧: 你已经用你熟悉的工具构建了ROS 2。 [Alyssa@9647]

  • 警告: 我们忽略了工作空间中的 eProsima 包,因为它们缺少 package.xml 文件,这意味着 catkin 看不到它们。 ament 有一些处理这种包的启发式方法。选项: 将这些启发式方法反向移植到 catkin ; 切换到在工作空间之外安装不含 package.xml 的包; 或者只是在每个包中添加一个 package.xml (例如,在我们自己的fork里)。 [Alyssa@9648]

将所有ROS和ROS 2组合在一个工作空间中并构建它 (待办事项) [Alyssa@9649]

这一步需要整理一些东西,至少包括: [Alyssa@9650]

  • 包名称冲突。我们目前有ROS 2版本的ROS消息包,以及 geometry2 的一些包。要么功能需要合并到一个可以支持两个系统的包中,要么新版本需要不同的名称。 [Alyssa@9651]

  • 消息生成。ROS和ROS 2具有不同的消息生成步骤,其输出可能冲突,也可能不冲突。需要做一些复杂的事情来允许从一个消息包中生成所有正确的文件 (或者,如上所述,新的消息包需要不同的名称)。 [Alyssa@9652]

使用 bloom 释放 ament 包 (待办事项) [Alyssa@9653]

似乎 bloom 应该能够发布使用 ament CMake API的包,并且生成的发行版本应该能够在farm上构建。我们可以根据需要对 bloomros_buildfarm 进行更改以启用此用例。 [Alyssa@9654]