[Documentation] [TitleIndex] [WordIndex

Note: This tutorial assumes that you have completed the previous tutorials: navigating the ROS filesystem.
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Tạo một gói ROS

Description: Hướng dẫn tạo ra một gói ROS mới dùng roscreate-pkg hoặc catkin , và rospack để liệt kê danh sách gói phụ thuộc.

Tutorial Level: BEGINNER

Next Tutorial: Building a ROS package

Using roscreate

Before we create a package, let's see how the roscreate-pkg command-line tool works. This creates a new ROS package. All ROS packages consist of the many similar files : manifests, CMakeLists.txt, mainpage.dox, and Makefiles. roscreate-pkg eliminates many tedious tasks of creating a new package by hand, and eliminates common errors caused by hand-typing build files and manifests.

To create a new package in the current directory:

# roscreate-pkg [package_name]

You can also specify dependencies of that package:

# roscreate-pkg [package_name] [depend1] [depend2] [depend3]

Creating a New ROS Package

Now we're going to go into your home or project directory and create our beginner_tutorials package. We are going to make it depend on std_msgs, roscpp, and rospy, which are common ROS packages.

Now go into the ~/fuerte_workspace/sandbox directory:

$ cd ~/fuerte_workspace/sandbox

Alternatively, if you use Fuerte or later release, you can simply do:

$ roscd
$ cd sandbox

Then create your package:

$ roscreate-pkg beginner_tutorials std_msgs rospy roscpp

You will see something similar to:

  • Creating package directory ~/fuerte_workspace/sandbox/beginner_tutorials
    Creating include directory ~/fuerte_workspace/sandbox/beginner_tutorials/include/beginner_tutorials
    Creating cpp source directory ~/ros/ros_tutorials/beginner_tutorials/src
    Creating python source directory ~/fuerte_workspace/sandbox/beginner_tutorials/src/beginner_tutorials
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/Makefile
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/manifest.xml
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/CMakeLists.txt
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/mainpage.dox
    
    Please edit beginner_tutorials/manifest.xml and mainpage.dox to finish creating your package

You're going to want to spend some time looking at beginner_tutorials/manifest.xml. manifests play an important role in ROS as they define how Packages are built, run, and documented.

Now lets make sure that ROS can find your new package. It is often useful to call rospack profile after making changes to your path so that new directories will be found:

$ rospack profile
$ rospack find beginner_tutorials 
  • YOUR_PACKAGE_PATH/beginner_tutorials

If this fails, it means ROS can't find your new package, which may be an issue with your ROS_PACKAGE_PATH. Please consult the installation instructions for setup from SVN or from binaries, depending how you installed ROS. If you've created or added a package that's outside of the existing package paths, you will need to amend your ROS_PACKAGE_PATH environment variable to include that new location. Try re-sourcing your setup.sh in your fuerte_workspace.

Try moving to the directory for the package.

$ roscd beginner_tutorials 
$ pwd
  • YOUR_PACKAGE_PATH/beginner_tutorials

First-order package dependencies

When using roscreate-pkg earlier, a few package dependencies were provided. These first-order dependencies can now be reviewed with the rospack tool.

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy; it may take some time to be reflected in the packages. If you see an issue similar to this with the next command, you can skip to the following command.

$ rospack depends1 beginner_tutorials 
  • std_msgs
    rospy
    roscpp

As you can see, rospack lists the same dependencies that were used as arguments when running roscreate-pkg. These dependencies for a package are stored in the manifest file. Take a look at the manifest file.

$ roscd beginner_tutorials
$ cat manifest.xml
  • <package>
    
    ...
    
      <depend package="std_msgs"/>
      <depend package="rospy"/>
      <depend package="roscpp"/>
    
    </package>

Indirect package dependencies

In many cases, a dependency will also have its own dependencies. For instance, rospy has other dependencies.

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy; it may take some time to be reflected in the packages. If you see an issue similar to this with the next command, you can skip to the following command.

$ rospack depends1 rospy
  • roslib
    roslang

A package can have quite a few indirect dependencies. Luckily rospack can recursively determine all nested dependencies.

$ rospack depends beginner_tutorials
  • rospack
    roslib
    std_msgs
    rosgraph_msgs
    rosbuild
    roslang
    rospy
    cpp_common
    roscpp_traits
    rostime
    roscpp_serialization
    xmlrpcpp
    rosconsole
    roscpp

Note: in Fuerte, the list is much shorter:

  • std_msgs
    roslang
    rospy
    roscpp

ROS Client Libraries

You may be wondering what rospy and roscpp dependencies are from the previous examples. rospy and roscpp are Client Libraries. The client libraries allow different programming languages to communicate through ROS. rospy is the client library for Python. roscpp is the client library for C++.

Review

Lets just list some of the commands we've used so far:

  • roscreate-pkg = ros+create-pkg : generates all the files needed to create a ROS package
  • rospack = ros+pack(age) : provides information related to ROS packages
  • rosstack = ros+stack : provides information related to ROS stacks

Những gì tạo nên một gói catkin ?

Để tạo thành một gói được xem là gói catkin phải thỏa mãn những yêu cầu sau:

  • Gói phải chứa một tập tin catkin compliant package.xml .

    • Tập tin package.xml cung cấp thông tin (meta information) về gói đó.
  • Gói phải chứa tập tin CMakeLists.txt which uses catkin. Nếu nó là một gói lớn catkin metapackage nó phải chứa những bản mẫu CMakeLists.txt liên quan.

  • Trong mỗi thư mục không có hơn một gói.
    • Điều này có nghĩa không có gói chứa những gói khác hoặc nhiều gói trong cùng một thư mục.

Một gói đơn giản nhất sẽ có cấu trúc giống như sau:

  • my_package/
      CMakeLists.txt
      package.xml

Gói trong một không gian làm việc catkin (hay catkin Workspace)

Phương pháp khuyên dùng làm việc với gói catkin là dùng một không gian làm việc catkin workspace, nhưng cũng có thể xây dựng một gói catkin độc lập. Một không gian làm việc thường giống như sau:

  • workspace_folder/        -- WORKSPACE không gian làm việc
      src/                   -- SOURCE SPACE không gian chứa mã nguồn
        CMakeLists.txt       -- 'Toplevel' tập tin CMake, cung cấp bởi catkin
        package_1/
          CMakeLists.txt     -- tập tin CMakeLists.txt cho package_1
          package.xml        -- gói Package manifest cho package_1
        ...
        package_n/
          CMakeLists.txt     -- tập tin CMakeLists.txt cho package_n
          package.xml        -- gói manifest cho package_n

Trước khi tiếp tục với hướng dẫn tạo ra một catkin workspace rỗng theo hướng dẫn sauCreating a workspace for catkin.

Tạo một gói catkin (hay catkin Package)

Hướng dẫn sẽ minh họa làm cách nào dùng catkin_create_pkg script để tạo ra một gói catkin, và những gì bạn có thể làm sau khi gói đã tạo ra.

Đầu tiên đi đến thư mục mã nguồn bạn đã tao ra theo hướng dẫn trước Creating a Workspace for catkin tutorial:

# Thư mục bạn đã tạo ra trong mục Tạo một không gian làm việc
$ cd ~/catkin_ws/src

Bây giờ dùng catkin_create_pkg script để tạo ra một gói mới gọi là 'beginner_tutorials' phụ thuộc vào các gói std_msgs, roscpp, và rospy:

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

Nó sẽ tạo ra một thư mục beginner_tutorials trong đó chứa tập tin package.xmlCMakeLists.txt, với những thông tin mà bạn đã đưa khi dùng lệnh catkin_create_pkg.

catkin_create_pkg yêu cầu bạn đưa ra tên gói 'package_name' và lựa chọn danh sách những gói sẽ phụ thuộc :

# Đây là một ví dụ, không thử chạy dòng này
# catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

catkin_create_pkg cũng cung cấp nhiều chức năng tiện ích khác được mô tả trong catkin/commands/catkin_create_pkg.

Xây dựng không gian catkin và thiết đặt mã nguồn

Bây giờ bạn cần tạo gói trong không gian làm việc catkin:

$ cd ~/catkin_ws
$ catkin_make

Sau khi workspace xây dựng xong nó sẽ có cấu trúc giống trong thư mục con devel devel như bạn thường thấy /opt/ros/$ROSDISTRO_NAME.

Để thêm workspace vào môi trường ROS bạn cần thiết đặt nguồn bởi tập tin cài đặt đã tạo ra:

$ . ~/catkin_ws/devel/setup.bash

Sự phụ thuộc của gói (package dependencies)

Sự phụ thuộc First-order

Khi dùng catkin_create_pkg ở trên, một vài gói phụ thuộc được cung cấp. Sự phụ thuộc đầu tiên (first-order) có thể được xem với công cụ rospack.

$ rospack depends1 beginner_tutorials
  • std_msgs
    rospy
    roscpp

Như bạn thấy, rospack liệt kê danh sách phụ thuộc giống như khi ta tạo ra gói dùng catkin_create_pkg với các tham số phụ thuộc . Sự phụ thuộc của một gói sẽ lưu trữ trong tập tin package.xml :

$ roscd beginner_tutorials
$ cat package.xml
  • <package>
    ...
      <buildtool_depend>catkin</buildtool_depend>
      <build_depend>roscpp</build_depend>
      <build_depend>rospy</build_depend>
      <build_depend>std_msgs</build_depend>
    ...
    </package>

Phụ thuộc gián tiếp (Indirect dependencies)

Trong nhiều trường hợp, một sự phụ thuộc sẽ những sự phụ thuộc của riêng nó. Một ví dụ, rospy có những sự phụ thuộc khác.

$ rospack depends1 rospy
  • genpy
    rosgraph
    rosgraph_msgs
    roslib
    std_msgs

Một gói có thể có khá nhiều sự phụ thuộc gián tiếp. May mắn thay, rospack có thể duyệt hết sự phụ thuộc gián tiếp này.

$ rospack depends beginner_tutorials
cpp_common
rostime
roscpp_traits
roscpp_serialization
genmsg
genpy
message_runtime
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
catkin
rospack
roslib
rospy

Tùy chỉnh gói của bạn

Phần này sẽ xem xét từng tập tin được sinh ra bởi catkin_create_pkg và mô tả , theo từng dòng , mỗi thành phần của những tập tin và làm thế nào để tùy chỉnh chúng cho gói bạn cần.

Tùy chỉnh tập tin package.xml

Tập tin tạo ra package.xml phải ở trong gói mới tạo ra. Bây giờ tìm hiểu package.xml các thành phần quan trọng.

mô tả nhãn (tag)

Đầu tiên cập nhật nhãn mô tả:

   5   <description>The beginner_tutorials package</description>

Thay đổi mô tả sang bất cứ điều gì bạn thích, nhưng theo quy ước, câu đầu tiên nên ngắn gọn trong khi bao quát phạm vi của gói. Nếu khó có thể mô tả gói trong một câu thì có thể cần phải chia nhỏ.

nhãn quản trị

Tiếp theo là thẻ quản trị viên:

   7   <!-- One maintainer tag required, multiple allowed, one person per tag --> 
   8   <!-- Example:  -->
   9   <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  10   <maintainer email="user@todo.todo">user</maintainer>

Đây là thẻ bắt buộc và quan trọng cho package.xml vì nó cho phép những người khác biết ai để liên lạc. Ít nhất một người bảo trì là bắt buộc, nhưng bạn có thể có nhiều nếu bạn thích. Tên của người bảo trì đặt trong phần thân của thẻ, nhưng cũng cần có một email:

   7   <maintainer email="you@yourdomain.tld">Your Name</maintainer>

nhãn giấy phép

Tiếp theo là thẻ giấy phép, cũng được yêu cầu:

  12   <!-- One license tag required, multiple allowed, one license per tag -->
  13   <!-- Commonly used license strings: -->
  14   <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  15   <license>TODO</license>

Bạn nên chọn một giấy phép và điền nó vào đây. Một số giấy phép mã nguồn mở phổ biến là BSD, MIT, Boost Giấy phép phần mềm, GPLv2, GPLv3, LGPLv2.1 và LGPLv3. Bạn có thể đọc về một số điều này tại Sáng kiến Nguồn mở Source Initiative. Đối với hướng dẫn này, chúng ta sẽ sử dụng giấy phép BSD vì các thành phần ROS cốt lõi sử dụng nó:

   8   <license>BSD</license>

nhãn phụ thuộc

Tập tiếp theo của các thẻ mô tả các phụ thuộc của gói của bạn. Các phụ thuộc được chia thành build_depend, buildtool_depend, run_depend, test_depend. Để có giải thích chi tiết hơn về các thẻ này, hãy xem tài liệu về Catkin Dependencies. Vì chúng ta đã đưa vào std_msgs, roscpp và rospy như các đối số cho catkin_create_pkg, các phụ thuộc sẽ giống như sau:

  27   <!-- The *_depend tags are used to specify dependencies -->
  28   <!-- Dependencies can be catkin packages or system dependencies -->
  29   <!-- Examples: -->
  30   <!-- Use build_depend for packages you need at compile time: -->
  31   <!--   <build_depend>genmsg</build_depend> -->
  32   <!-- Use buildtool_depend for build tool packages: -->
  33   <!--   <buildtool_depend>catkin</buildtool_depend> -->
  34   <!-- Use exec_depend for packages you need at runtime: -->
  35   <!--   <exec_depend>python-yaml</exec_depend> -->
  36   <!-- Use test_depend for packages you need only for testing: -->
  37   <!--   <test_depend>gtest</test_depend> -->
  38   <buildtool_depend>catkin</buildtool_depend>
  39   <build_depend>roscpp</build_depend>
  40   <build_depend>rospy</build_depend>
  41   <build_depend>std_msgs</build_depend>

Tất cả các phụ thuộc được liệt kê đã được thêm như là build_depend , ngoài buildtool_depend mặc định trên catkin. Trong trường hợp này, chúng ta muốn tất cả các phụ thuộc được chỉ định có sẵn tại thời điểm tạo và thực thi, vì vậy chúng ta sẽ thêm một thẻ run_depend cho mỗi một trong số chúng:

  12   <buildtool_depend>catkin</buildtool_depend>
  13 
  14   <build_depend>roscpp</build_depend>
  15   <build_depend>rospy</build_depend>
  16   <build_depend>std_msgs</build_depend>
  17 
  18   <exec_depend>roscpp</exec_depend>
  19   <exec_depend>rospy</exec_depend>
  20   <exec_depend>std_msgs</exec_depend>

Final package.xml

Như bạn thấy final package.xml, nếu không có chú thích và không dùng thẻ, sẽ trở nên súc tích:

   1 <?xml version="1.0"?>
   2 <package format="2">
   3   <name>beginner_tutorials</name>
   4   <version>0.1.0</version>
   5   <description>The beginner_tutorials package</description>
   6 
   7   <maintainer email="you@yourdomain.tld">Your Name</maintainer>
   8   <license>BSD</license>
   9   <url type="website">http://wiki.ros.org/beginner_tutorials</url>
  10   <author email="you@yourdomain.tld">Jane Doe</author>
  11 
  12   <buildtool_depend>catkin</buildtool_depend>
  13 
  14   <build_depend>roscpp</build_depend>
  15   <build_depend>rospy</build_depend>
  16   <build_depend>std_msgs</build_depend>
  17 
  18   <exec_depend>roscpp</exec_depend>
  19   <exec_depend>rospy</exec_depend>
  20   <exec_depend>std_msgs</exec_depend>
  21 
  22 </package>

Tùy chỉnh tập tin CMakeLists.txt

Bây giờ gói tinpackage.xml có chứa thông tin meta đã được chỉnh sửa cho gói của bạn, bạn đã sẵn sàng tiếp tục theo hướng dẫn. Tệp CMakeLists.txt được tạo bởi catkin_create_pkg sẽ được đề cập đến trong các hướng dẫn sau về xây dựng mã ROS.

Bay giờ bạn sẽ tạo một gói ROS mới , bắt đầu với build our ROS package.


2019-10-19 13:20