众所周知,ROS是一种分布式的框架,我们使用的软件都以相互独立的软件包的形式存在,用起来确实方便,但是对于编译系统来讲,还是有相当的挑战的,它不仅需要正确、快速地完成自动化构建过程,还需要解决每个软件包之间的相互依赖关系。虽然ROS中的编译系统一直采用标准的构建工具,比如CMake、Python setuptools,但是这些工具并没有办法完全满足ROS的需求,都需要添加一些额外的功能。
一、ament的前世今生
那ament是何方神圣呢? ament是一种元编译系统,用来构建组成应用程序的多个独立功能包,它并不是一个全新的东西,而是catkin编译系统进一步演化的版本,这两个单词也是近义词。
ament主要分为两个部分:
1. 编译系统:配置、编译、安装独立的功能包
2. 构建工具:将多个独立的功能包按照一定的拓扑结构进行链接
关于独立功能包之间的依赖关系,和ROS1相同,也需要在清单文件——package.xml中进行声明,如果有兴趣可以查看这个文件的定义标准 (REP 140)。
二、ament的命令行工具
ament_tools是ament为用户提供的一种命令行工具,可以让用户完成功能包的编译、测试、安装、卸载,而且它本身也是一个Python的功能包。从功能上来看,ament_tools和cantkin系统中的catkin_tools类似,目前并不提供并行构建的能力,将来应该会加入。
三、ament vs catkin
从上边看来,ament貌似和catkin差不多,那为什么要从catkin演化成ament呢?既然名字都改了,总得有点不同吧。
相比ROS最初使用的rosbuild,catkin在很多方面还是先进很多的,比如支持外部构建,CMake配置文件的自动生成等等。但是catkin也并不完美,针对开发者对catkin缺陷提交的反馈,催生了新一代的编译系统。这些缺陷包括:
1. CMake centric
catkin系统以 CMake为中心,所以只包含python代码的功能包也需要由CMake进行处理,但是CMake并不支持Python setuptools中的所有功能,而且也很难在Window上进行移植。
2. Devel space
在catkin系统构建完成后,会在工作目录下生成一个devel文件夹,里边是编译好的功能包,以及环境变量的设置等等,基本上等同于ROS安装完成后的目录结构和作用。但是相信很多初学者因为devel中的环境变量而苦恼过,这确实为用户带来了一些不必要的麻烦。
3. CMAKE_PREFIX_PATH
catkin会将编译多个工作区的前缀存储到环境变量CMAKE_PREFIX_PATH 中,但是这种方法会干扰变量中的其他值,在ament中,不同工作区的前缀会放到不同的环境变量中。
4. catkin_simple
catkin_simple是一个用于改善用户catkin体验的工具包,可以减少复杂的CMake代码,但是会存在不稳定的情况。ament也是实现了类似的功能,但是可靠性更强。
5. Building within a single CMake context
使用catkin_make命令可以一次性编译工作空间中的所有功能包,虽然方便,但如果存在相同命名的功能包时,会编译失败,ament在这方面也进行了改善。
针对以上缺陷,ament都进行了优化,最最重要的是,为了配合ROS2,当然也要换一个全新的名字,这样才有区分度嘛。
四、安装ament
说了这么多,重要的是这个新的编译系统到底怎么用,那我们就来尝试一下。
1. 创建目录
和catkin工作空间一样,我们首先要为将来的代码创建一个工作空间:
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
2. 下载代码
这里需要用到一个版本控制的工具——vcs,可以参考https://github.com/dirk-thomas/vcstool进行安装:
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116
sudo apt-get update
sudo apt-get install python-vcstool
然后需要安装一些列依赖的软件包,我用的ubuntu16.04是新安装的,很多软件包没安装,可以参考一下https://github.com/ros2/ros2/wiki/Linux-Development-Setup里边需要安装的软件包,管他能不能用的上,全装了,要不然后患无穷呀(后边编译了很多次才领悟到):
sudo apt-get update
sudo apt-get install git wget
sudo apt-get install build-essential cppcheck cmake libopencv-dev libpoco-dev libpocofoundation9v5 libpocofoundation9v5-dbg python-empy python3-dev python3-empy python3-nose python3-pip python3-setuptools python3-vcstool
# dependencies for testing
sudo apt-get install clang-format pydocstyle pyflakes python3-coverage python3-mock python3-pep8 uncrustify
# dependencies for fastrtps
sudo apt-get install libboost-chrono-dev libboost-date-time-dev libboost-program-options-dev libboost-regex-dev libboost-system-dev libboost-thread-dev
sudo apt-get install libboost-all-dev libpcre3-dev zlib1g-dev python-empy python-pkg-resources
好啦,现在可以开始现在下载ament的代码了:
vcs import ~/ros2_ws/src < ros2.repos
这里要git下来很多代码包,时间较长,比如我用了整整一天的时间,现在可以去干点其他事情了。
3. 开始编译
代码下载完成后,就可以来编译这些代码了:
src/ament/ament_tools/scripts/ament.py build --build-tests --symlink-install
这时,可能会报一个错误:
ament build: Circular dependency within the following packages: rmw_implementation, rmw_opensplice_cpp
google一下,发现这个问题是一个bug(https://github.com/ros2/ros2/issues/303),解决的办法是删掉rmw_opensplice这个包。
继续用上边的命令编译,终于可以开始编译了,看到畅快的编译界面了么!!!
去喝杯咖啡,稍等一下,大概需要十几分钟。
编译完成后可以使用下边的命令编译测试程序:
src/ament/ament_tools/scripts/ament.py test
4. 设置环境变量
ament编译完成后,所有声称的文件都放到了ros_ws工作目录下的install文件夹里:
生成的命令在bin文件夹下,如果我们需要在终端中调用这些命令,当然还是老办法,设置环境变量:
. install/local_setup.bash
5. 运行例程
在刚才编译完成的例程中,就包括我们前边讲到的talker和listener,但是这次我们是从源码编译的,更显“奢华,先来运行一下这两个例程,看到的效果应该和我们之前讲到的一样:
五、编译自己的功能包
ament现在装好了,就可以来编译我们在ros2里边写的功能包了,现在就让我们来看一下如何在ros2中开发自己的功能包。
我们可以在ros_ws的src里边创建自己的功能包,但是目前的工作区里边都是ros2相关的代码,我们还是重新创建一个工作区吧:
mkdir -p ~/ros2_overlay_ws/srccd ~/ros2_overlay_ws/src
由于我们目前还没有写过ros2的功能包,那就还是先用ros2的example吧:
git clone https://github.com/ros2/examples.git
下载完成后,我们就可以编译这个新的工作区了(注意:之前编译好的ament的环境变量设置,可以写到.bashrc文件里):
cd ~/ros2_overlay_ws
ament build --cmake-args -DCMAKE_BUILD_TYPE=Debug
编译的过程和catkin差不多,编译完成后也会在工作区产生一个install文件,里边的目录结构和我们之前编译ament所生成的一样,example里边也包含talker和listener,运行的方法一样,先设置环境变量,然后运行,但是这次运行的程序是overlay工作区里边的。
通过这篇文章,主要可以让我们知道怎么样去使用ament的命令,今后的探索中,我们再继续研究如何自己用ros2写代码。
参考资料
The meta build system “ament”:http://design.ros2.org/articles/ament.html
Ament Tutorial:https://github.com/ros2/ros2/wiki/Ament-Tutorial