本文介绍了ROS的工作空间,也就是ROS的文件系统结构。要学会建立一个ROS工程,首先要认识一个ROS工程,了解它们的组织架构,从根本上熟悉ROS项目的组织形式,了解各个文件的功能和作用,才能正确的进行开发和编程。
1. Catkin编译系统
1.1 基本概念
对于源代码包,我们只有编译才能在系统上运行。而Linux下的编译器有gcc、g++,随着源文件的增加,直接用gcc/g++命令的方式显得效率低下,人们开始用Makefile来进行编译。然而随着工程体量的增大,Makefile也不能满足需求,于是便出现了Cmake工具。CMake是对make工具的生成器,是更高层的工具,它简化了编译构建过程,能够管理大型项目,具有良好的扩展性。对于ROS这样大体量的平台来说,就采用的是CMake,并且ROS对CMake进行了扩展,于是便有了Catkin编译系统,因此Catkin是基于CMake的编译构建系统。
1.2 工作空间结构
Catkin工作空间是创建、修改、编译catkin软件包的目录。catkin的工作空间,直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用。在可视化图形界面里是一个文件夹。我们自己写的ROS代码通常就放在工作空间中,catkin工作空间的结构如下:
这三个文件夹是catkin编译系统默认的。它们的具体作用如下:
- src/: ROS的catkin软件包(源代码包)
- build/: catkin(CMake)的缓存信息和中间文件
- devel/: 生成的目标文件(包括头文件,动态链接库,静态链接库,可执行文件等)、环境变量
src文件中放着我们的功能包package,每个功能包实现一个特定的功能。
package是catkin工作空间的基本单元,我们在ROS开发时,写好代码,然后catkin_make,系统就会完成所有编译构建的工作。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_make
。
1.3 构建工作空间
1 | mkdir -p ~/catkin_ws/src |
2. Package功能包
2.1 基本概念
ROS中的package的定义是catkin编译的基本单元,是集中完成一个任务的代码合集。一个package可以编译出来多个目标文件(ROS可执行程序、动态静态库、头文件等等)。
2.2 功能包结构
一个package下常见的文件、路径有:
1 | ├── CMakeLists.txt #package的编译规则(必须) |
其中定义package的是CMakeLists.txt
和package.xml
,这两个文件是package中必不可少的。catkin编译系统在编译前,首先就要解析这两个文件。这两个文件就定义了一个package。
- CMakeLists.txt: 定义package的包名、依赖、源文件、目标文件等编译规则,是package不可少的成分
- package.xml: 描述package的包名、版本号、作者、依赖等信息,是package不可少的成分
- src/: 存放ROS的源代码,包括C++的源码和(.cpp)以及Python的module(.py)
- include/: 存放C++源码对应的头文件
- scripts/: 存放可执行脚本,例如shell脚本(.sh)、Python脚本(.py)
- msg/: 存放自定义格式的消息(.msg)
- srv/: 存放自定义格式的服务(.srv)
- models/: 存放机器人或仿真场景的3D模型(.sda, .stl, .dae等)
- urdf/: 存放机器人的模型描述(.urdf或.xacro)
- launch/: 存放launch文件(.launch或.xml)
通常ROS文件组织都是按照以上的形式,这是约定俗成的命名习惯,建议遵守。以上路径中,只有CMakeLists.txt
和package.xml
是必须的,其余路径根据软件包是否需要来决定。
2.3 构建功能包
1 | catkin_create_pkg pkg_name [dependencies ...] |
3. CMakeList.txt
CMakeLists.txt
是Cmake编译系统的规则文件,而Catkin编译系统基本沿用了CMake的编译风格,只是针对ROS工程添加了一些宏定义。所以在写法上,catkin的CMakeLists.txt
与CMake的基本一致。
这个文件直接规定了这个package要依赖哪些package,要编译生成哪些目标,如何编译等等流程。所以CMakeLists.txt
非常重要,它指定了由源码到目标文件的规则,catkin编译系统在工作时首先会找到每个package下的CMakeLists.txt
,然后按照规则来编译构建。
CMakeLists.txt
的基本语法都还是按照CMake,而Catkin在其中加入了少量的宏,总体的结构如下:
1 | cmake_minimum_required() #CMake的版本号 |
如果你想了解CMake的语法,请阅读《CMake实践》:https://github.com/Akagi201/learning-cmake/blob/master/docs/cmake-practice.pdf 。但是如果你用rospy做开发,基本不会用到太多,最常用的就是add_xxx_files()
和generate_message()
生成自定义的msg/srv/action
接口。还有就是catkin_python_setup()
与setup.py对应,对于包含自定义Python模块和包的场景不能少。
4. package.xml
package.xml
也是一个catkin的package必备文件,它是这个软件包的描述文件。pacakge.xml
包含了package的名称、版本号、内容描述、维护人员、软件许可、编译构建工具、编译依赖、运行依赖等信息。实际上rospack find
、rosdep
等命令之所以能快速定位和分析出package的依赖项信息,就是直接读取了每一个package中的package.xml
文件。它为用户提供了快速了解一个package的渠道。
pacakge.xml
遵循xml标签文本的写法,包含的标签为:
1 | <pacakge> 根标记文件 |
注:指定了<depend>XXX</depend>
相当于同时指定了<build_depend>
<exec_depend>
等,不需要分开写了。如果有什么项目是只有编译依赖或只有运行依赖的,才再<build_depend>
或<exec_depend>
上指定。
5. Metapackage元功能包
这部分内容只有在超大型项目才用得到,这里只是出于知识的完整性加以简单介绍。Metapackage在之前的版本中叫Stack(功能包集),指的是将多个功能接近、甚至相互依赖的软件包的放到一个集合中去。
moveit是ROS中机械臂运动规划相关的元功能包,项目地址https://github.com/ros-planning/moveit。
打开moveit元功能包目录:
没有源码,只有CMakeList.txt
和package.xml
。
CMakeLists.txt
写法如下:
1 | cmake_minimum_required(VERSION 3.1.3) |
pacakge.xml
写法如下:
1 |
|
个人感觉有点像Python写包时候的__init__.py
,将所有模块并进了同一个命名空间。