这部分对应MOOC里面的第二课-工程结构,主要是讲解了一些ROS的文件路径和控制台创建ROS工程的一些基本操作。
一、catkin工作空间与编译系统
所谓catkin操作空间,实际上就是ros里面最高的一个层次,是管理组织ROS代码的地方,之所以加上了catkin,是因为这个工作空间是对ROS在一般的工作空间上加上了catkin,所以是ROS定制的一个编译构建系统,是对CMake的扩展,是针对ROS这种大体量的项目进行的进一步定制,可以优化很多的功能。整个的项目路径如下:
使用时首先要创建工作空间,也就是创建写代码的文件夹,文件夹的名字无所谓,但是一定要在下面带一个src文件夹,创建之后进入目录,使用catkin_make指令就可以创建工作空间。
mkdir -p ~/文件夹的名字/src
cd ~/catkin_ws/
catkin_make
除了创建工作空间,catkin_make指令更多情况下是用来完成编译任务的,在编写好代码之后,在工作空间目录下再使用一遍catkin_make指令,系统就可以编译并构建工程,最重要的是编译完成之后要使用source ~/catkin_ws/devel/setup.bash指令,去刷新一下环境,不然系统是无法找到我们需要的package的。
cd ~/文件夹的名字
catkin_make
source ~/文件夹的名字/devel/setup.bash
# 刷新环境 将workspace刷新到环境变量里面去
对于刚刚创建好的工作空间,一般下面会有三个文件夹:src、build、devel,src用于存放package的源代码,一般操作都是在src文件夹下面进行的,build用于存放cmake或者catkin缓存和中间文件,而devel则用于存放目标文件,后面两个文件一般不需要人为的操作,代码的编写完全是在src下面进行的。
继续向下展开文件路径,进入src之后就是各种各样的package,package是catkin编译的基本单元,编译时catkin会递归地在src文件夹下查找package,所以将多个package放在其余文件夹下也是可行的。
二、Package组成
Package是ROS软件的基本组织形式,是catkin编译的基本单元,一个package里面可以包含多个可执行文件。一个package之所以可以称为一个package,主要还是因为package文件夹下面都存在有的两个文件:CMakeLists.txt和package.xml,这两个文件就可以让编译系统将文件夹识别为package。一个最简单的package即使没有创建任何的内容,都会包含着这两个文件。
针对这两个文件,CMakeList.txt规定catkin编译的规则,例如源文件、依赖源和目标文件。
而package.xml则用于定义package的属性,包括包的名字、版本号、作者、依赖等内容。相当于对这个package进行一定的描述。和一般的xml文件一样,package.xml文件也是利用标签的方式进行内容的表示,常用的表示如下:
name-package的名字
version-版本
description-package的描述信息
maintainer-维护者
license-软件许可
buildtool_depend-编译工具
build_depend-编译依赖
run-depend-运行依赖
一般修改的都是最后两项的内容。
如果要对内容进行填充,那么package下面的结构就会变得更加复杂,一般都是见名知意
代码文件包括shell或者Python脚本、C++的头文件和源文件,这部分文件存放在scripts、include和src文件夹下,其中scripts存放脚本文件、include存放C++的头文件,而src则用于存放编写的C++源文件,准确的说scr存放的应该是代码文件,有些情况下src也会存放一些Python文件。
自定义的通信格式包括消息(msg)、服务(srv)、动作(action),这部分内容也用对应名称的文件见存放在package路径下。所以自定义通信格式是比较方便的。
还有一部分的配置文件比如yaml文件和launch文件,也是单独开辟文件夹放在package里面。前面提到过一个package里面可以存放多个可执行文件,如果需要一次运行好几个,就可以利用launch文件,一次性运行多个可执行文件。
现在整个包的结构基本已经清楚了,两个用于让编译系统将文件夹识别成package的文件-CMakeList.txt/package.xml,存放代码文件的文件夹-scripts(.py .sh)/inculde(.h)/src(.cpp .py),存放自定义通信格式的文件夹-msg(.msg)/srv(.srv)/action(.action),存放其余配置文件的文件夹-config(.yaml)/launch(.launch)。
对于package,还有一些常用的操作,可以帮助开发者快速管理或者查找包的信息:
三、MeatPackage
MetaPackage翻译过来叫做虚包,里面没有实质性的内容,但是依赖了很多别的包。引入MeatPackage最大的好处,就是节省了安装的操作,在需要大量安装依赖包的时候,可以引入一个虚包,虚包内部没有实际的内容,但是将一开始需要安装的包都依赖进了虚包中,这样安装一个虚包,就相当于安装了一开始需要安装的全部包,节省了输入指令的时间。
四、实际操作截图
首先使用mkdir,创建一个包含src的文件夹,文件夹的名字无所谓,但是内部一定要包含src文件夹。创建成功之后,使用catkin_make指令完成工作空间的创建。
创建成功之后,查看内部的结构,可以看见前面提到的三个文件夹:
接下来进入src内部,开始package的创建,使用指令catkin_create_package+包名来创建一个package:
可以看出,创建之前src下面只有一个CMakeList.txt,但是创建之后就有了我们创建的package。此时test1是一个刚刚创建的package,里面什么操作都还没进行,所以只包含最简单的两个文件,用于告诉编译系统这个文件夹是个package。
在实际开发过程中,一般会在创建时提前引入一些依赖,这种情况就可以直接在创建包的指令后面跟上需要的包的名字,创建系统会自动修改创建的包的内容:
此时可以看出,相较于什么都不带创建的test1,在test2里面多了include和src,我们加入的依赖其实系统已经在CMakeList.txt和package.xml文件中加上了,就不需要自己再去写。
搞定了这些之后,使用catkin_make完成编译,这时内部文件的结构会变得特别复杂,一张图完全截不下来。编译完成之后一定要source一下,让系统知道这个新创建的包。只有这样才可以利用管理包的指令对这个新创建的包进行管理。
这个source的操作实际上限制很多,首先是生命周期短,只在一个控制台有效,如果重开了另一个控制台就需要重新source激活一下。此外即使是在同一个控制台,一次只有一个package是可以被系统查看的,如果换另一个工作空间去source一下,之前已经source的工作空间就没有了。