本章主要介绍了ROS的工程结构,也就是ROS的文件系统结构。要学会建立一个ROS工程,首先要认识一个ROS工程,了解它们的组织架构,从根本上熟悉ROS项目的组织形式,了解各个文件的功能和作用,才能正确的进行开发和编程。
本章的主要内容有,介绍catkin的编译系统,catkin工作空间的创建和结构,package软件包的创建和结构,介绍CMakeLists.txt文件,package.xml以及其他常见文件。从而系统的梳理了ROS文件空间的结构,对于我们ROS学习和开发有着重要的作用。
01 Catkin编译系统
对于源代码包,我们只有编译才能在系统上运行。而Linux下的编译器有gcc、g++,随着源文件的增加,直接用gcc/g++命令的方式显得效率低下,人们开始用Makefile来进行编译。然而随着工程体量的增大,Makefile也不能满足需求,于是便出现了Cmake工具。CMake是对make工具的生成器,是更高层的工具,它简化了编译构建过程,能够管理大型项目,具有良好的扩展性。对于ROS这样大体量的平台来说,就采用的是CMake,并且ROS对CMake进行了扩展,于是便有了Catkin编译系统。
早期的ROS编译系统是rosbuild,但随着ROS的不断发展,rosbuild逐渐暴露出许多缺点,不能很好满足系统需要。在Groovy版本面世后,Catkin作为rosbuild的替代品被正式投入使用。Catkin操作更加简化且工作效率更高,可移植性更好,而且支持交叉编译和更加合理的功能包分配。目前的ROS同时支持着rosbuild和Catkin两种编译系统,但ROS的核心软件包也已经全部转换为Catkin。rosbuild已经被逐步淘汰,所以建议初学者直接上手Catkin。
本节我们主要来介绍catkin的编译系统。
1.1 Catkin特点
Catkin是基于CMake的编译构建系统,具有以下特点:
Catkin沿用了包管理的传统像 find_package()基础结构,pkg-config
扩展了CMake,例如
软件包编译后无需安装就可使用
自动生成find_package()代码,pkg-config文件
解决了多个软件包构建顺序问题
一个Catkin的软件包(package)必须要包括两个文件:
package.xml: 包括了package的描述信息
name, description, version, maintainer(s), license
opt. authors, url’s, dependencies, plugins, etc…
CMakeLists.txt: 构建package所需的CMake文件
调用Catkin的函数/宏
解析package.xml
找到其他依赖的catkin软件包
将本软件包添加到环境变量
1.2 Catkin工作原理
catkin编译的工作流程如下:
首先在工作空间catkin_ws/src/下递归的查找其中每一个ROS的package。
package中会有package.xml和CMakeLists.txt文件,Catkin(CMake)编译系统依据CMakeLists.txt文件,从而生成makefiles(放在catkin_ws/build/)。
然后make刚刚生成的makefiles等文件,编译链接生成可执行文件(放在catkin_ws/devel)。
也就是说,Catkin就是将cmake与make指令做了一个封装从而完成整个编译过程的工具。catkin有比较突出的优点,主要是:
操作更加简单
一次配置,多次使用
跨依赖项目编译
1.3 使用catkin_make进行编译
要用catkin编译一个工程或软件包,只需要用catkin_make指令。一般当我们写完代码,执行一次catkin_make进行编译,调用系统自动完成编译和链接过程,构建生成目标文件。编译的一般性流程如下:
$ cd ~/catkin_ws #回到工作空间,catkin_make必须在工作空间下执行 $ catkin_make #开始编译 $ source ~/catkin_ws/devel/setup.bash #刷新坏境
注意: catkin编译之前需要回到工作空间目录,catkin_make在其他路径下编译不会成功。编译完成后,如果有新的目标文件产生(原来没有),那么一般紧跟着要source刷新环境,使得系统能够找到刚才编译生成的ROS可执行文件。这个细节比较容易遗漏,致使后面出现可执行文件无法打开等错误。
catkin_make命令也有一些可选参数,例如:
catkin_make [args] -h, --help 帮助信息 -C DIRECTORY, --directory DIRECTORY 工作空间的路径 (默认为 '.') --source SOURCE src的路径 (默认为'workspace_base/src') --build BUILD build的路径 (默认为'workspace_base/build') --use-ninja 用ninja取代make --use-nmake 用nmake取'make --force-cmake 强制cmake,即使已经cmake过 --no-color 禁止彩色输出(只对catkin_make和CMake生效) --pkg PKG [PKG ...] 只对某个PKG进行make --only-pkg-with-deps ONLY_PKG_WITH_DEPS [ONLY_PKG_WITH_DEPS ...] 将指定的package列入白名单CATKIN_WHITELIST_PACKAGES, 之编译白名单里的package。该环境变量存在于CMakeCache.txt。 --cmake-args [CMAKE_ARGS [CMAKE_ARGS ...]] 传给CMake的参数 --make-args [MAKE_ARGS [MAKE_ARGS ...]] 传给Make的参数 --override-build-tool-check 用来覆盖由于不同编译工具产生的错误
02 Catkin工作空间
Catkin工作空间是创建、修改、编译catkin软件包的目录。catkin的工作空间,直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用。在可视化图形界面里是一个文件夹。我们自己写的ROS代码通常就放在工作空间中,本节就来介绍catkin工作空间的结构。
2.1 创建catkin工作空间
创建一个 catkin 工作空间:
$ mkdir -p ~/catkin_ws/src # 创建了第二层级的文件夹src,这是放ROS软件包的地方 $ cd ~/catkin_ws/src # 进入工作空间,catkin_make必须在工作空间这个路径上执行 $ catkin_init_workspace # 初始化src目录,生成的CMakeLists.txt为功能包编译配置
2.2 编译工作空间
$ cd ~/catkin_ws # 回到工作空间,catkin_make必须在工作空间下执行; $ catkin_make # 开始编译,调用系统自动完成编译和链接过程,构建生成目标文件
注意: catkin编译之前需要回到工作空间目录,catkin_make在其他路径下编译不会成功。
==编译完成后,如果有新的目标文件产生(原来没有),那么一般紧跟着要source刷新环境,使得系统能够找到刚才编译生成的ROS可执行文件。==这个细节比较容易遗漏,致使后面出现可执行文件无法打开等错误。
catkin_make命令也有一些可选参数,例如:
catkin_make [args] -h, --help 帮助信息 -C DIRECTORY, --directory DIRECTORY 工作空间的路径 (默认为 '.') --source SOURCE src的路径 (默认为'workspace_base/src') --build BUILD build的路径 (默认为'workspace_base/build') --use-ninja 用ninja取代make --use-nmake 用nmake取'make --force-cmake 强制cmake,即使已经cmake过 --no-color 禁止彩色输出(只对catkin_make和CMake生效) --pkg PKG [PKG ...] 只对某个PKG进行make --only-pkg-with-deps ONLY_PKG_WITH_DEPS [ONLY_PKG_WITH_DEPS ...] 将指定的package列入白名单CATKIN_WHITELIST_PACKAGES, 之编译白名单里的package。该环境变量存在于CMakeCache.txt。 --cmake-args [CMAKE_ARGS [CMAKE_ARGS ...]] 传给CMake的参数 --make-args [MAKE_ARGS [MAKE_ARGS ...]] 传给Make的参数 --override-build-tool-check 用来覆盖由于不同编译工具产生的错误
注意, 对于 Python 3 用户,在一个空的 catkin 工作空间中第一次运行 catkin_make的命令应为:
$ catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
这将会配置 catkin_make 使用 Python 3.你可以在随后的构建中只使用 catkin_make。
2.3 设置环境变量
另外,如果你查看一下当前目录应该能看到 ‘build’ 和 ‘devel’ 这两个文件夹。在 ‘devel’ 文件夹里面你可以看到几个 setup.*sh 文件。source 这些文件中的任何一个都可以将当前工作空间设置在ROS工作环境的最顶层。接下来首先 source 一下新生成的 setup.*sh 文件:
$ source devel/setup.bash # 刷新坏境
2.4 检查环境变量
要想保证工作空间已配置正确,需确保ROS_PACKAGE_PATH
环境变量包含你的工作空间目录,采用以下命令查看:
$ echo $ROS_PACKAGE_PATH # 出现 /home/<youruser>/catkin_ws/src:/opt/ros/kinetic/share
到此你的工作环境已经搭建完成。
03 catkin结构介绍
catkin的结构十分清晰,具体的catkin工作空间结构图如下。初看起来catkin工作空间看起来极其复杂,其实不然,catkin工作空间的结构其实非常清晰。
在工作空间下用tree命令,显示文件结构。
$ cd ~/catkin_ws $ sudo apt install tree $ tree
结果为:
─ build │ ├── catkin │ │ └── catkin_generated │ │ └── version │ │ └── package.cmake │ ├── ...... │ ├── catkin_make.cache │ ├── CMakeCache.txt │ ├── CMakeFiles │ │ ├── ...... ├── devel │ ├── env.sh │ ├── lib │ ├── setup.bash │ ├── setup.sh │ ├── _setup_util.py │ └── setup.zsh └── src └── CMakeLists.txt -> /opt/ros/kinetic/share/catkin/cmake/toplevel.cmake
通过tree命令可以看到catkin工作空间的结构,它包括了src、build、devel三个路径,在有些编译选项下也可能包括其他。但这三个文件夹是catkin编译系统默认的。它们的具体作用如下:
src/: ROS的catkin软件包(源代码包)
build/: catkin(CMake)的缓存信息和中间文件
devel/: 生成的目标文件(包括头文件,动态链接库,静态链接库,可执行文件等)、环境变量
在编译过程中,它们的工作流程如图:
后两个路径由catkin系统自动生成、管理,我们日常的开发一般不会去涉及,而主要用到的是src文件夹,我们写的ROS程序、网上下载的ROS源代码包都存放在这里。
在编译时,catkin编译系统会递归的查找和编译src/下的每一个源代码包。因此你也可以把几个源代码包放到同一个文件夹下,如下图所示:
小结
catkin工作空间基本就是以上的结构,package是catkin工作空间的基本单元,我们在ROS开发时,写好代码,然后catkin_make,系统就会完成所有编译构建的工作。至于更详细的package内容,我们将在下节继续介绍。