Note: This tutorial assumes that you have completed the previous tutorials: ROS 파일시스템의 탐색.
(!) 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.

ROS 패키지의 작성

Description: 이 자습서는 roscreate-pkg 또는 catkin을 이용해 새로운 패키지를 작성하는 방법에 대해 설명합니다. 또한 rospack을 이용해 패키지의 의존성을 확인하는 법도 알아봅니다.

Tutorial Level: BEGINNER

Next Tutorial: ROS 패키지 빌드하기

roscreate 사용하기

본격적으로 패키지를 만들기 전에 roscreate-pkg 명령행 도구의 사용법을 알아봅시다. 모든 ROS 패키지들은 manifests, CMakeLists.txt, mainpage.dox, Makefiles 등 비슷한 파일들이 공통으로 들어 있습니다. 직접 손으로 위의 파일들을 만드는 것은 매우 수고로울 뿐 아니라, 빌드관련 파일과 매니패스트의 작성 시 사소한 실수때문에 에러가 생길 수 있습니다. roscreate-pkg는 이 과정을 자동화 해서 새로운 패키지를 만드는 데 도움을 줍니다.

현재 폴더 안에 새로운 패키지를 만드려면 아래와 같이 입력합니다.

# roscreate-pkg [package_name]

만들면서 패키지의 의존성을 정해줄 수 도 있습니다.

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

새로운 ROS Package 작성하기

이제 홈이나 프로젝트 폴더로 이동해 자습서에서 사용할 beginner_tutorials 패키지를 만들게 될 것입니다. 의존성이 있는 패키지로는 기본 ROS 패키지에 포함된 std_msgs, roscpp, rospy를 지정할 것입니다.

이제 ~/ros_workspace/sandbox 폴더로 이동합니다.

$ cd ~/ros_workspace/sandbox

또는 Fuerte나 그 이전의 버전을 사용하고 계신다면 간단히 아래의 방법을 사용할 수도 있습니다.

$ roscd
$ cd sandbox

그 다음 새로운 패키지를 만들어 봅시다.

$ roscreate-pkg beginner_tutorials std_msgs rospy roscpp

명령이 실행되면 아래와 같은 화면이 출력될 것입니다.

  • 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

우리는 beginner_tutorials/manifest.xml파일에 좀 더 관심을 가질 필요가 있습니다. manifests는 ROS에서 패키지의 빌드, 실행, 문서화 과정 모두에 영향을 미치기 때문에 링크를 통해 세부사항을 알아두시면 좋습니다.

이제 ROS가 새로 만들어진 패키지도 찾아낼 수 있는지 알아보겠습니다. 저장된 경로에 변경사항이 생겼을 때 새로고침을 해 주는 rospack profile을 사용해 새로운 패키지를 찾아낼 수 있게 해줍니다.

$ rospack profile
$ rospack find beginner_tutorials 
  • YOUR_PACKAGE_PATH/beginner_tutorials

만약 실패했다면, 이는 ROS가 새로 만들어진 패키지를 찾지 못했다는 것입니다. $ROS_PACKAGE_PATH와 관련이 깊은 문제이므로 자신이 설치한 방법(소스코드 또는 바이너리)의 설치 지침을 찾아 검토해 보시길 바랍니다. 만약 $ROS_PACKAGE_PATH 경로 밖의 폴더에 새 패키지를 만드셨을 경우는 새 경로를 $ROS_PACKAGE_PATH에 지정해 주시고 ros_workspace안의 setup.bash를 쉘에 다시 등록(re-source)시켜 주시기 바랍니다.

이제 패키지의 안으로 이동하겠습니다.

$ roscd beginner_tutorials 
$ pwd
  • YOUR_PACKAGE_PATH/beginner_tutorials

1차 패키지 의존성

앞서 roscreate-pkg를 사용할 때, 몇 가지 의존 패키지들을 같이 입력했었습니다. 이들을 1차 패키지 의존성(first-order dependencies)라 하고 rospack 도구를 이용해 다시 확인할 수 있습니다.

(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

보시다시피 rospackroscreate-pkg 명령을 쓸 때 입력한 의존성들을 모두 보여주는 것을 확인할 수 있습니다. 이 패키지 의존성은 매니페스트 파일에 기록되어 있습니다. 한번 매니페스트 파일을 살펴보겠습니다.

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

간접 패키지 의존성

많은 경우에 한개의 의존성은 자기 나름대로의 의존성을 가지고 있습니다. 예를 들면, rospy는 두개의 의존성을 품고 있습니다.

(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

rospack은 재귀적으로 이러한 내포된 의존성까지 알아낼 수 있습니다.

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

참고: Fuerte에서는 목록이 많이 짧아졌습니다.

  • std_msgs
    roslang
    rospy
    roscpp

ROS 클라이언트 라이브러리

혹시 이전 예제에서 보았던 rospyroscpp의 의존성에 대해 궁금해 하실 분들이 계실 지 모르겠습니다. rospyroscppClient Libraries의 일종입니다. 클라이언트 라이브러리는 ROS상에서 서로 다른 프로그래밍 언어로 통신하는 것을 가능케 합니다. 각각 rospy는 python, roscpp는 C++에 대한 클라이언트 라이브러리입니다.

복습

이 자습서에서 소개한 명령어들을 적어보겠습니다.

  • roscreate-pkg = ros+create-pkg : 새로운 ROS 패키지를 만드는 데 필요한 파일을 자동으로 만들어 줍니다.
  • rospack = ros+pack(age) : ROS 패키지와 관련된 정보를 알려줍니다.
  • rosstack = ros+stack : ROS 스택과 관련된 정보를 알려줍니다.

catkin 패키지는 어떻게 이루어져 있나요?

어떤 패키지를 catkin 패키지라 하기 위해서는 몇 가지 조건에 부합해야 합니다.

  • 패키지는 반드시 catkin compliant package.xml 파일을 포함해야 한다.

    • package.xml 파일은 패키지의 메타 정보를 제공하는 것입니다.
  • 패키지는 반드시 catkin에서 쓰이는 CMakeLists.txt을 포함하고 있어야 한다.

    • 이 규칙의 예외로는 CMakeLIsts.txt파일을 가지지 않는 catkin metapackages 가 있습니다.

  • 한 폴더 당 한 개의 패키지만이 대응될 수 있습니다.
    • 이는 내포된 패키지 또는 같은 폴더를 공유하는 복수의 패키지를 용납하지 않는다는 의미입니다.

가능한 패키지의 예시 중 가장 간단한 예시를 보겠습니다.

  • my_package/
      CMakeLists.txt
      package.xml

catkin 작업공간 내의 패키지들

catkin패키지에 대한 작업을 할 때 추천하는 방법은 catkin 작업공간을 사용하는 것입니다. 그러나 단일(standalone)으로 catkin패키지를 빌드할 수도 있습니다 일반적인 작업공간의 예제는 아래와 같습니다.

  • workspace_folder/        -- 작업공간
      src/                   -- 소스 폴더
        CMakeLists.txt       -- catkin이 제공하는 '최상위'의 CMake 파일,
        package_1/
          CMakeLists.txt     -- package_1에 대한 CMakeLists.txt 파일
          package.xml        -- package_1에 대한 매니패스트
        ...
        package_n/
          CMakeLists.txt     -- package_n에 대한 CMakeLists.txt 파일
          package.xml        -- package_n에 대한 매니패스트

이 자습서를 시작하기 전에 catkin에서 작업공간 만들기 자습서를 참고해 빈 catkin작업공간을 만들어 두세요.

catkin패키지 작성하기

이 자습서는 catkin_create_pkg를 어떻게 사용하는지, 만들고 난 뒤에 할 일에 대해 설명할 것입니다. catkin_create_pkg는 새로운 catkin 패키지를 만드는 스크립트입니다.

먼저 catkin에서 작업공간 만들기 자습서에서 만들어 둔 catkin 작업공간의 소스 폴더로 이동합니다.

#이 경로는 catkin에서 작업공간 만들기 자습서에서 만드셨을 것입니다.
$ cd ~/catkin_ws/src

이제 std_msgs, roscpp, rospy에 대한 의존성을 가지는 'beginner_tutorials' 패키지를 만들기 위해catkin_create_pkg 스크립트를 사용해 보겠습니다.

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

이를 수행하면 package.xmlCMakeLists.txt가 들어있는 beginner_tutorials폴더가 만들어 집니다. 여러분이 catkin_create_pkg에 주어 준 정보로 package.xml과 CMakeLists.txt의 일부가 채워집니다.

catkin_create_pkg에는 기본적으로 패키지의 이름을 입력하고 선택사항으로, 의존성을 가질 패키지들을 입력할 수도 있습니다

# 이것은 예시입니다. 그대로 따라하지 마세요.
# catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

catkin_create_pkg은 몇 가지 진보된 기능을 제공합니다. 이에 대한 정보는catkin/commands/catkin_create_pkg의 링크를 참고하세요.

패키지 의존성

1차 의존성

위에서 catkin_create_pkg를 사용했을 때 몇 가지 의존성 정보를 입력했었습니다. 이들을 1차 의존성이라 하고 rospack 도구를 이용해 다시 확인 할 수 있습니다.

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy, which takes sometime until the change gets reflected on your computer. If you see a similar issue like this with the next command, you can skip to the next command.

$ rospack depends1 beginner_tutorials 
  • std_msgs
    rospy
    roscpp

보시다시피 rospack은 우리가 catkin_create_pkg을 쓸 때 입력한 의존성 목록과 일치하는 결과를 보여줍니다. 패키지의 의존성은 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>

간접 의존성

많은 경우에 하나의 의존 패키지는 자체로도 의존 패키지를 가지고 있습니다. 일례로 rospy는 아래의 의존성을 가집니다.

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy, which takes sometime until the change gets reflected on your computer. If you see a similar issue like this with the next command, you can skip to the next command.

$ rospack depends1 rospy
  • genpy
    rosgraph
    rosgraph_msgs
    roslib
    std_msgs

rospack은 재귀적으로 모든 간접 의존성을 알아낼 수 있습니다.

$ 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

패키지 사용자화

이 부분은 catkin_create_pkg명령이 생성한 각각의 파일들을 한줄한줄, 각각의 구성요소 별로 살펴보게 될 것입니다. 이 과정을 통해 어떻게 여러분의 패키지를 사용자화 하는지 알게 될 것입니다.

package.xml 사용자화

package.xml는 반드시 여러분이 새로 만든 패키지의 안에 있어야 합니다. 이제 package.xml안으로 들어가, 주의가 필요한 부분을 세세하게 짚어보도록 하겠습니다.

description tag

맨 먼저 description tag를 수정 해 보겠습니다.

   5   <description>The beginner_tutorials package</description>

가능한 한줄로 요약한다는 전제를 가지고, 자유롭게 패키지에 대한 설명을 적어봅니다. 한 줄로는 설명이 어려운 경우 여러 줄로 입력하셔도 됩니다.

maintainer tags

다음은 maintainer tag에 대해 알아보겠습니다.

   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>

이 부분은 package.xml에서 가장 중요한 부분 중 하나입니다. 패키지의 관리자에 대한 정보가 기록 되는 부분이며 최소 한 명 이상의 정보가 입력되어야 합니다. 관리자의 이름은 태그의 몸체가 되고, 반드시 입력되어야 하는 웹메일 주소를 속성으로 가지고 있습니다.

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

license tags

다음은 license tag입니다.

  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>

여기서 라이센스에 대한 정보를 반드시 입력해야 합니다. 자주 쓰이는 라이센스로는 BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 등이 있습니다. Open Source Initiative에서 이들에 대한 내용을 찾아보실 수 있습니다. 이 자습서에서는 ROS의 핵심 부분에서 이미 사용되고 있는 BSD라이센스를 사용합니다.

   8   <license>BSD</license>

dependencies tags

다음은 패키지의 의존성을 알려주는 태그의 모음들을 볼 수 있습니다. 의존성 목록들은 build_depend, buildtool_depend, run_depend, test_depend에 맞추어 나누어져 있습니다. 보다 상세한 설명을 원하시면 Catkin Dependencies의 링크를 참고하시길 바랍니다. 우리는 catkin_create_pkg에서 std_msgs, roscpp, rospy를 의존성으로 정하였으므로 여기서는 아래와 같이 보일 것입니다.

  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>

우리가 지정한 모든 의존성이 build_depend에 있고 기본 buildtool_depend에 catkin이 있음을 확인할 수 있습니다. 우리가 지정해 둔 의존성은 빌드할 때나 실행할 때도 필요한 패키지들이기 때문에 run_depend 태그로도 등록해 둡니다.

  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>

수정된 package.xml

위에서 수정한 부분을 주의하며 주석과 사용하지 않는 태그들을 정리하면 훨씬 간결해진 package.xml을 볼 수 있습니다.

   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>

CMakeLists.txt의 사용자화

이제 메타 정보가 담긴 package.xml 파일이 패키지에 맞게 변형되었습니다. catkin_create_pkg 가 자동으로 만들어 낸 CMakeLists.txt를 수정하는 부분은 이후 ROS 코드를 빌드하는 자습서에서 다루게 될 것입니다.

이제 새로운 ROS패키지가 만들어 졌습니다. 다음 자습서로 이동합니다. ROS 패키지 빌드하기

Wiki: ko/ROS/Tutorials/CreatingPackage (last edited 2013-07-03 13:55:55 by elitechrome)