首页 关于
树枝想去撕裂天空 / 却只戳了几个微小的窟窿 / 它透出天外的光亮 / 人们把它叫做月亮和星星
目录

创建和编译Package

在ROS中,软件是以Package为基本单位组织的。一个Package中可能包含了可执行文件、配置文件、第三方的软件等等任何可以构成一个有用模块的东西。 把软件划分称为各个Package的一个主要目的是,降低系统的耦合度,提高代码的复用率。ROS的Package遵循如下的设计原则:

Enough functionality to be useful, but not too much that the package is heavyweight and difficult to use from other software.

虽然Package中可能包涵各种各样的文件,具体的组织方式也没有明确的说法。但是一个Package之所以是Package,是因为它里面至少包含了两个文件:package.xml和CMakeLists.txt。 package.xml描述了一个Package中的各种信息,包括作者信息,版权,依赖关系等。CMakeLists.txt则是ROS的编译系统catkin需要使用的文件,它描述了Package的各种编译规则, 需要的源文件、库文件、搜索路径等。一个Package都有用一个独立的目录,保存它的各种文件,package.xml和CMakeLists.txt则保存在它的根目录下。

我们可以手动创建一个Package,就是麻烦一点,不过有比较高的自定义特性。也可以用ROS的工具catkin_create_pkg来创建,比较简单方便。 在本文中,我们主要讲ROS系统的Package,所以先介绍通过工具创建的方法,以后再讲手动创建的方法。

1. 创建一个catkin package

首先,我们把工作目录切换到上一篇文章最后创建的工作空间下。 然后运行catkin_create_pkg创建一个叫做beginner_tutorials的Package,它依赖与std_msgs、rospy、roscpp三个包。

        $ cd ~/catkin_ws/src
        $ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
        Created file beginner_tutorials/package.xml
        Created file beginner_tutorials/CMakeLists.txt
        Created folder beginner_tutorials/include/beginner_tutorials
        Created folder beginner_tutorials/src
        Successfully created files in /home/gyc/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml.
根据提示信息,我们可以看到catkin_create_pkg创建了一个beginner_tutorials的目录,并在其中创建了package.xml和CMakeLists.txt两个文件,以及include和src两个子目录。 打开创建的那两个文件,可以发现catkin_create_pkg已经根据我们提供的信息,在package.xml和CMakeLists.txt中添加了一些内容,剩下的工作是根据我们的需要补充和修改一些信息就好了。

利用工具,我们仅用了一条语句就创建了一个Package,虽然现在还什么功能都还没有实现,但我们也可以进行编译。

        $ cd ~/catkin_ws
        $ catkin_make
然后添加工作空间的环境,我们就可以用ros提供的各种文件系统工具访问新创建的Package了。
        $ source devel/setup.bash
        $ rosls beginner_tutorials/
        CMakeLists.txt  include  package.xml  src

2. package.xml

package.xml中描述了一个Package的作者信息、版权、依赖关系等信息。下面是由catkin生成的package.xml的内容,我去除了其中的注释部分。

        <?xml version="1.0"?>
        <package>
          <name>beginner_tutorials</name>
          <version>0.0.0</version>
          <description>The beginner_tutorials package</description>
          <maintainer email="gyc@todo.todo">gyc</maintainer>
          <license>TODO</license>
        
          <buildtool_depend>catkin</buildtool_depend>
          <build_depend>roscpp</build_depend>
          <build_depend>rospy</build_depend>
          <build_depend>std_msgs</build_depend>
          <run_depend>roscpp</run_depend>
          <run_depend>rospy</run_depend>
          <run_depend>std_msgs</run_depend>
        </package>
大体上,package.xml文件分为两个部分,其中name, version, description等部分就是对package的各种描述,他们对于怎么编译package不起任何作用,就是一些描述信息。 而buildtool_depend,build_depend, run_depend部分则描述了package对于其它工具的依赖关系。在编译和运行时,ros系统会根据这些描述信息,在系统中查找对应的工具包, 如果没有找到将会报错。

这里的依赖关系中,std_msgs, rospy和roscpp是我们在创建package时指定的依赖关系,运行指令rospack的depends1可以查看一个package的直接依赖关系:

        $ rospack depends1 beginner_tutorials 
        roscpp
        rospy
        std_msgs
我们可以通过修改这个package文件删除或者添加依赖关系。比如说,我们把关于std_msgs的两个依赖删除,然后运行rospack,就可以看到它的直接依赖关系中少了std_msgs。
        $ rospack depends1 beginner_tutorials 
        roscpp
        rospy

一个package依赖于某个工具,而该工具则可能依赖于另外一些工具,这样就形成了一系列的间接依赖关系。通过rospack的depends可以查看package所依赖的所有工具:

        $ rospack depends beginner_tutorials 
        cpp_common
        rostime
        roscpp_traits
        roscpp_serialization
        catkin
        ...

3. CMakeLists.txt

CMakeLists.txt是CMake编译系统下用于描述代码的编译规则的文件,熟悉CMake的读者应该对它的工作流程比较了解,只需要执行如下的一系列指令就可以完成一个项目的编译和安装:

        # In a CMake project
        $ mkdir build
        $ cd build
        $ cmake ..
        $ make
        $ make install  # (optionally)
在上述的cmake工作流程中,我们需要保证在项目的根目录下有一个CMakeLists.txt的文件。再创建一个build目录用于存放编译过程中生成的各种中间文件, 在build目录下运行指令cmake ..解决编译过程中需要的查询路径、库文件,进而生成一个Makefile文件。其中..指的是build的父目录,即包含CMakeLists.txt的根目录。 然后运行make编译项目,必要的话还要运行make install安装项目。

在ROS的catkin_make编译环境下,对cmake的这一工作流程做了很多封装,以至于我们可以一键编译工作空间下的所有package。按照cmake的常规使用方式, 我们需要在package的根目录下创建一个CMakeLists.txt的文件。

在使用catkin_make编译时,我们需要先保证系统中已经安装了package的所有依赖,否则在编译过程中将因为没有找到相应的依赖而报错退出。 同时还需要保证已经导入了ROS的工作环境,如果没有则运行如下指令导入,然后在工作空间的根目录下运行catkin_make进行编译。

        $ source /opt/ros/kinetic/setup.bash
        $ cd ~/catkin_ws
        $ catkin_make
上述指令,将编译在src目录下找到的所有package。如果我们根据需要把package放到了一个其它的目录下,通过参数--source指定package的路径即可。
        $ catkin_make --source $PACKAGE_PATH

4. 总结

package是ROS系统中软件的基本组织形式。每一个package都有一个独立的目录,在这个目录中至少包含package.xml和CMakeLists.txt分别描述了package的依赖关系和编译规则。 我们可以用catkin_create_pkg自动的创建一个package,使用catkin_make对其进行编译。在没有指定参数的情况下,catkin_make会把其中src目录下见到的所有package都给编译的。




Copyright @ 高乙超. All Rights Reserved. 京ICP备16033081号-1