ROS课程讲义--2 Catkin工作空间和Package

2.2 Catkin工作空间

Catkin工作空间是创建、修改、编译catkin软件包的目录。catkin的工作空间,直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用。在可视化图形界面里是一个文件夹。我们自己写的ROS代码通常就放在工作空间中,本节就来介绍catkin工作空间的结构。

2.2.1 初始化catkin工作空间

介绍完catkin编译系统,我们来建立一个catkin的工作空间。首先我们要在计算机上创建一个初始的catkin_ws/路径,这也是catkin工作空间结构的最高层级。输入下列指令,完成初始创建。

$ mkdir -p ~/catkin_ws/src  
$ cd ~/catkin_ws/
$ catkin_make #初始化工作空间

第一行代码直接创建了第二层级的文件夹src,这也是我们放ROS软件包的地方。第二行代码使得进程进入工作空间,然后再是catkin_make。

注意:1. catkin_make命令必须在工作空间这个路径上执行 2.原先的初始化命令catkin_init_workspace仍然保留

2.2.2 结构介绍

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工作空间的结构,它包括了srcbuilddevel三个路径,在有些编译选项下也可能包括其他。但这三个文件夹是catkin编译系统默认的。它们的具体作用如下:

  • src/: ROS的catkin软件包(源代码包)
  • build/: catkin(CMake)的缓存信息和中间文件
  • devel/: 生成的目标文件(包括头文件,动态链接库,静态链接库,可执行文件等)、环境变量

在编译过程中,它们的工作流程如图:

ROS课程讲义--2 Catkin工作空间和Package

后两个路径由catkin系统自动生成、管理,我们日常的开发一般不会去涉及,而主要用到的是src文件夹,我们写的ROS程序、网上下载的ROS源代码包都存放在这里。

在编译时,catkin编译系统会递归的查找和编译src/下的每一个源代码包。因此你也可以把几个源代码包放到同一个文件夹下,如下图所示:

ROS课程讲义--2 Catkin工作空间和Package

小结

catkin工作空间基本就是以上的结构,package是catkin工作空间的基本单元,我们在ROS开发时,写好代码,然后catkin_make,系统就会完成所有编译构建的工作。至于更详细的package内容,我们将在下节继续介绍。

 

2.3 Package软件包

在1.6节我们曾对package软件包进行了分类,分别介绍了二进制包和源代码包。而ROS中的package的定义更加具体,它不仅是Linux上的软件包,更是catkin编译的基本单元,我们调用catkin_make编译的对象就是一个个ROS的package,也就是说任何ROS程序只有组织成package才能编译。所以package也是ROS源代码存放的地方,任何ROS的代码无论是C++还是Python都要放到package中,这样才能正常的编译和运行。
一个package可以编译出来多个目标文件(ROS可执行程序、动态静态库、头文件等等)。

2.3.1 package结构

一个package下常见的文件、路径有:

  ├── CMakeLists.txt    #package的编译规则(必须)
  ├── package.xml       #package的描述信息(必须)
  ├── src/              #源代码文件
  ├── include/          #C++头文件
  ├── scripts/          #可执行脚本
  ├── msg/              #自定义消息
  ├── srv/              #自定义服务
  ├── models/           #3D模型文件
  ├── urdf/             #urdf文件
  ├── launch/           #launch文件

其中定义package的是CMakeLists.txtpackage.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.txtpackage.xml是必须的,其余路径根据软件包是否需要来决定。

2.3.2 package的创建

创建一个package需要在catkin_ws/src下,用到catkin_create_pkg命令,用法是:
catkin_create_pkg package depends
其中package是包名,depends是依赖的包名,可以依赖多个软件包。

例如,新建一个package叫做test_pkg,依赖roscpp、rospy、std_msgs(常用依赖)。

$ catkin_create_pkg test_pkg roscpp rospy std_msgs

这样就会在当前路径下新建test_pkg软件包,包括:

  ├── CMakeLists.txt
  ├── include
  │   └── test_pkg
  ├── package.xml
  └── src

catkin_create_pkg帮你完成了软件包的初始化,填充好了CMakeLists.txtpackage.xml,并且将依赖项填进了这两个文件中。

2.3.3 package相关命令

rospack

rospack是对package管理的工具,命令的用法如下:

rostopic命令 作用
rospack help 显示rospack的用法
rospack list 列出本机所有package
rospack depends [package] 显示package的依赖包
rospack find [package] 定位某个package
rospack profile 刷新所有package的位置记录

以上命令如果package缺省,则默认为当前目录(如果当前目录包含package.xml)

roscd

roscd命令类似与Linux系统的cd,改进之处在于roscd可以直接cd到ROS的软件包。

rostopic命令 作用
roscd [pacakge] cd到ROS package所在路径

rosls

rosls也可以视为Linux指令ls的改进版,可以直接lsROS软件包的内容。

rosls命令 作用
rosls [pacakge] 列出pacakge下的文件

rosdep

rosdep是用于管理ROS package依赖项的命令行工具,用法如下:

rosdep命令 作用
rosdep check [pacakge] 检查package的依赖是否满足
rosdep install [pacakge] 安装pacakge的依赖
rosdep db 生成和显示依赖数据库
rosdep init 初始化/etc/ros/rosdep中的源
rosdep keys 检查package的依赖是否满足
rosdep update 更新本地的rosdep数据库

一个较常使用的命令是rosdep install --from-paths src --ignore-src --rosdistro=kinetic -y,用于安装工作空间中src路径下所有package的依赖项(由pacakge.xml文件指定)。