ROS 빌드 시스템

이용욱·2022년 3월 17일
0

ROS1

목록 보기
1/5
post-thumbnail

pc 환경 : Ubuntu 18.04 melodic, ROS1

1. 로스 빌드 시스템

로스의 빌드 시스템은 기본적으로 CMake(Cross Platform Make)[2] 를 이용하고 있고, 패키지 폴더에 CMakeLists.txt 라는 파일에 빌드 환경을 기술하고 있다. 로스에서는 CMake를 로스에 맞도록 수정하여 로스에 특화된 캐킨 빌드 시스템을 만들었다.

로스에서 CMake를 이용하고 있는 이유는 멀티플랫폼에서 로스 패키지를 빌드할 수 있도록 위함이다. Make[3]가 유닉스계열만 지원하는 것과 달리, CMake는 유닉스 계열인 리눅스, BSD, OS X 뿐만 아니라 윈도우 계열도 지원하기 때문이다. 또한, 마이크로소프트 비주얼 스튜디오도 지원하고 QT개발에도 쉽게 적용될 수 있다.

더욱이, 캐킨 빌드 시스템은 로스와 관련된 빌드, 패키지 관리, 패키지간의 의존관계 등을 편리하게 사용할 수 있도록 하고 있다.

2. 패키지 생성

로스 패키지를 생성하기 위해서는 다음과 같은 명령어를 이용한다. "catkin_create_pkg" 는 사용자가 패키지를 작성할때 캐킨 빌드 시스템에 꼭 필요한 CMakeLists.txt 와 package.xml 를 포함한 패키지 폴더를 생성한다. 실제로 간단한 패키지를 작성해 보자.

catkin_create_pkg <패키지이름> [의존하는패키지1] [의존하는패키지2] [의존하는패키지3]

1) 작업 폴더로 이동

$ cd ~/catkin_ws/src

2) 패키지 생성

"my_first_ros_pkg" 라는 이름의 패키지를 생성할 것이다.

로스에서는 패키지 이름에는 모두 소문자를 사용하며, 스페이스바와 같은 공백이 있으면 안된다. 그리고 일반적으로 하이픈(-) 대신에 밑줄(_)을 사용하여 각 단어를 이어붙이는 것을 관례로 하고 있다.

그리고 이번에는 의존하는 패키지로 "std_msgs"와 "roscpp"를 옵션으로 달아주었다. 로스의 표준 메시지 패키지인 std_msgs 와 로스에서 c/c++을 사용하기 위하여 클라이언트라이브러인 roscpp를 사용하겠다는 것으로 패키지 생성에 앞어서 미리 설치해야한다는 의미이다. 이러한 의존하는 패키지의 설정은 패키지 생성할 때 지정할 수도 있지만, 생성 후 package.xml 에서 직접 입력하여도 된다.

$ catkin_create_pkg my_first_ros_pkg std_msgs roscpp

위와 같이 패키지를 생성하였으면 "~/catkin_ws/src"에 "my_first_ros_pkg" 라는 패키지 폴더 및 로스 패키지가 갖추어야할 기본 내부 폴더 및 CMakeLists.txt 와 package.xml가 생성된다. 다음과 같이 명령어로 ls 를 입력하여 내용을 보던가 윈도우의 탐색기와 같은 역할을 하는 GUI기반의 Nautilus를 이용하여 패키지 내부를 살펴보도록 하자.

3. 패키지 설정 파일 (package.xml) 수정

로스의 필수 설정 파일 중 하나인 package.xml 은 패키지의 정보를 담은 XML 파일로써 패키지의 이름, 저작자, 라이선스, 의존성 패키지 등을 기술하고 있다.

  • ?xml
    : 문서 분법을 정의하는 문구로 아래의 내용은 xml 버전 1.0을 따르고 있다는 것을 알리고 있다.
  • package
    : 이 구문부터 까지가 로스 패키지 설정 부분이다.
  • name
    : 패키지의 이름이다. 패키지 생성할때 입력한 패키지 이름이 사용된다. 다른 옵션도 마찬가지이지만 이는 사용자가 원할때 언제든지 변경할 수 있다.
  • version
    : 패키지의 버전이다. 자유롭게 지정할 수 있다.
  • description
    : 패키지의 간단한 설명이다.
  • maintainer
    : 패키지 관리자의 연락처를 기재한다.
  • license
    : 라이선스를 기재한다. BSD, MIT, GPLv3, LGPLv3 등을 기재하면 된다. 오로카에서는 MIT를 사용하고 있다.
  • url
    : 패키지를 설명하는 웹 페이지 또는 버그관리, 저장소 등의 주소를 기입한다. 이 종류에 따라 type에 website, bugtracker, repository 를 대입하면 된다. 참고로 url 태그는 옵션이다.
  • author
    : 패키지 개발에 참여한 개발자를 적어주면 된다. 참고로 author 태그는 옵션이다.
  • buildtool_depend
    : 빌드 시스템의 의존성을 기술한다. 지금은 캐킨 빌드 시스템을 이용하고 있기 때문에 catkin 를 입력하면 된다.
  • build_depend
    : 패키지를 빌드할 때 의존하는 패키지명을 적어준다.
  • run_depend
    : 패키지를 실행할 때 의존하는 패키지명을 적어준다.
  • test_depend
    : 패키지를 테스트할때 의존하는 패키지명을 적어준다. 테스트이외에는 사용하지 않는다.
  • export
    : 로스에서 명시하지 않은 태그명을 사용할때 쓰인다. 일반적인 경우 쓸일이 없다.
  • metapackage/
    : export 태그 안에서 사용하는 공식적인 태그로 현재의 패키지가 메타패키지의 경우 이를 선언한다.
<?xml version="1.0"?>
<package>
  <name>my_first_ros_pkg</name>
  <version>0.0.1</version>
  <description>The my_first_ros_pkg package</description>
 
  <maintainer email="passionvirus@gmail.com">Yoonseok Pyo</maintainer>
  <license>MIT</license>
  <url type="website">http://cafe.naver.com/openrt/2500</url>
  <url type="repository">https://github.com/oroca/oroca_ros_tutorials.git</url>
  <author email="passionvirus@gmail.com">Yoonseok Pyo</author>
 
  <buildtool_depend>catkin</buildtool_depend>
 
  <build_depend>std_msgs</build_depend>
  <build_depend>roscpp</build_depend>
 
  <run_depend>std_msgs</run_depend>
  <run_depend>roscpp</run_depend>
 
  <export>
  </export>
</package>

4. 빌드 설정 파일(CMakeLists.txt) 수정

로스의 빌드 시스템인 캐킨은 기본적으로 CMake를 이용하고 있어서 패키지 폴더에 CMakeLists.txt 라는 파일에 빌드 환경을 기술하고 있다. 이는 실행 파일 생성, 의존성 패키지 우선 빌드, 링크 생성 등을 설정하게 되어 있다.

빌드 설정 파일 (CMakeLists.txt)의 각 옵션들은 다음과 같다.

  • cmake_minimum_required(VERSION 2.8.3)
    : 운영체제에 설치되어 있는 cmake의 최소한의 버전이다. 현재에는 2.8.3 버전으로 명시되어 있다. 이 보다 낮은 cmake를 사용하는 경우에는 버전 업데이트를 해줘야 한다.

  • project(my_first_ros_pkg)
    : 패키지의 이름이다. package.xml 에서 입력한 패키지 이름을 그대로 사용하자.

  • find_package(catkin REQUIRED COMPONENTS
    roscpp
    std_msgs)

    : 캐킨 빌드를 할 때 요구되는 구성요소 패키지이다. 현재 의존성 패키지로 roscpp 및 std_msgs가 추가되어 있다. 여기에 입력된 패키지가 없는 경우 캐킨 빌드할 때 사용자에게 에러가 표시된다. 즉, 사용자가 만든 패키지가 의존하는 패키지를 먼저 설치하게 만드는 옵션이다.
  • find_package(Boost REQUIRED COMPONENTS system)
    : 로스 이외의 패키지를 사용하는 경우에 사용되는 방법이다. 예를들어 다음의 경우, Boost를 사용할때 system 이라는 패키지가 설되어 있어야 한다. 기능은 위에서 설명한 의존하는 패키지를 먼저 설치하게 만드는 옵션이다.
  • catkin_python_setup() : 파이썬을 사용할 때 설정하는 옵션이다. 파이썬은 cmake를 사용할 필요없는 스크립트 언어이지만 패키지의 호환성을 위해 아래와 같이 독자적인 설정을 하게 되어 있다.
  • add_message_files(
    FILES
    Message1.msg
    Message2.msg)

    : 사용하는 메시지 파일을 추가하는 옵션이다. FILES를 사용하면 패키지 폴더의 "msg" 안의 .msg 파일들을 참조하게 된다. 다음의 예제에서는 Message1.msg 및 Message2.msg 의 메시지 파일을 이용하겠다는 옵션이다.
  • add_service_files(
    FILES
    Service1.srv
    Service2.srv)

    : 사용하는 서비스 파일을 추가하는 옵션이다. FILES를 사용하면 패키지 폴더의 "srv" 안의 .srv 파일들을 참조하게 된다. 다음의 예제에서는 Service1.srv 및 Service2.srv 의 서비스 파일을 이용하겠다는 옵션이다.
  • generate_messages(
    DEPENDENCIES
    std_msgs)

    : 의존하는 메시지를 사용하겠다는 옵션이다. 다음의 예제에서는 DEPENDENCIES 옵션에 의하여 std_msgs 라는 메시지 패키지를 사용하겠다는 설정이다.
  • catkin_package(
    INCLUDE_DIRS include
    LIBRARIES my_first_ros_pkg
    CATKIN_DEPENDS roscpp std_msgs
    DEPENDS system_lib)

    : 캐킨 빌드 옵션이다.
    "INCLUDE_DIRS"는 뒤에 설정한 패키지 내부 폴더인 "include"의 헤더파일을 사용하겠다는 설정이다.
    "LIBRARIES"는 뒤에 설정한 패키지의 라이브러리를 사용하겠다는 설정이다.
    "CATKIN_DEPENDS" 캐킨 빌드할 때 의존하는 패키지들이다. 현재 roscpp 및 std_msgs가 의존하고 있다는 설정이다.
    "DEPENDS" 시스템 의존 패키지를 기술하는 설정이다.

  • include_directories(
    ${catkin_INCLUDE_DIRS})
    : 인클루드 폴더를 지정할 수 있는 옵션이다. 현재 ${catkin_INCLUDE_DIRS} 라고 설정되어 있는데 이는 각 패키지안의 "include" 폴더를 의미하고 이안의 헤더파일을 이용하겠다는 설정이다.

  • add_library(my_first_ros_pkg
    src/${PROJECT_NAME}/my_first_ros_pkg.cpp)

    : cpp 라이브러리를 선언한다. src/ ${PROJECT_NAME}/my_first_ros_pkg.cpp 파일을 참조하여 my_first_ros_pkg 라는 라이브러리를 생성하게 된다.

  • add_executable(my_first_ros_pkg_node src/my_first_ros_pkg_node.cpp) : cpp 실행 파일을 선언한다. src/my_first_ros_pkg_node.cpp 파일을 참조하여 my_first_ros_pkg_node 라는 실행파일을 생성한다.
  • add_dependencies(my_first_ros_pkg_node my_first_ros_pkg_generate_messages_cpp)
    : 패키지를 빌드하기 앞서서 생성해야할 메시지 헤더파일이 있을 경우 빌드전에 우선적으로 메시지를 생성하라는 설정이다. 현재 my_first_ros_pkg_generate_messages_cpp 를 우선적으로 빌드하고 my_first_ros_pkg_node 를 빌드하게 하는 설정이다.

  • target_link_libraries(my_first_ros_pkg_node
    ${catkin_LIBRARIES}

    : my_first_ros_pkg_node 를 생성하기 앞서서 링크해야하는 라이브러리 및 실행파일을 링크해주는 옵션이다.

cmake_minimum_required(VERSION 2.8.3)
project(my_first_ros_pkg)
 
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
)
 
catkin_package(
  INCLUDE_DIRS include
  CATKIN_DEPENDS roscpp std_msgs
  DEPENDS system_lib
)
 
include_directories(
  ${catkin_INCLUDE_DIRS}
)
 
add_executable(hello_world_node src/hello_world_node.cpp)
add_dependencies(hello_world_node my_first_ros_pkg_generate_messages_cpp)
target_link_libraries(hello_world_node ${catkin_LIBRARIES})

5. 소스코드 작성

위에서 필자가 작성한 CMakelists.txt 파일을 참고하길 바란다. 실행파일 생성 부분에서 다음과 같이 설정해 놓았다. 즉, 패키지의 "src" 폴더에 있는 "hello_world_node.cpp" 소스코드를 참고하여 "hello_world_node" 라는 실행파일을 생성하라는 설정이다. 여기서, "hello_world_node.cpp" 소스코드가 없기에 간단한 예제로 하나 작성해 보자. 다음의 예제에서는 nano라는 에디터를 사용하였으나 vi, gedit, qtcreator 등 자신이 원하는 편집기를 이용하면 된다.

"add_executable(hello_world_node src/hello_world_node.cpp)"

$ cd src     (여기서 src 는 자신의 패키지 폴더안의 src 라는 소스코드를 담는 폴더를 말한다.)
$ nano hello_world_node.cpp
#include <ros/ros.h>
#include <std_msgs/String.h>

#include <sstream>

int main(int argc, char **argv)
{
  ros::init(argc, argv, "hello_world_node");
  ros::NodeHandle nh;
  ros::Publisher chatter_pub = nh.advertise<std_msgs::String>("say_hello_world", 1000);

  ros::Rate loop_rate(10);
  int count = 0;
  while (ros::ok())
  {
    std_msgs::String msg;
    std::stringstream ss;
    ss << "hello world " << count;
    msg.data = ss.str();
    ROS_INFO("%s", msg.data.c_str());
    chatter_pub.publish(msg);
    ros::spinOnce();
    loop_rate.sleep();
    ++count;
  }
  return 0;
}

6. 패키지 빌드

이제 패키지 빌드를 위한 모든 작업이 완료되었다. 빌드에 앞서서 다음의 명령어로 로스 패키지의 프로파일을 갱신시켜주자. 앞서 제작한 우리의 패키지를 로스 패키지 목록에 반영시켜주는 명령어이다. 필수 사항은 아니지만 새로 패키지를 생성한 후에 갱신해주면 이용하기 편하다.

$ rospack profile

다음은 캐킨 빌드 이다. 캐킨 작업 폴더로 이용하여 캐킨 빌드를 해주자.

$ cd ~/catkin_ws && catkin_make

또는

$ cm

.bashrc 파일에 alias cm='cd ~/catkin_ws && catkin_make' 라고 설정해두면 터미널 창에서 "cm" 이라는 간단한 명령어로 위의 명령어를 대체할 수 있다.

7. 노드 실행

에러 없이 빌드가 완료되었으면 "~/catkin_ws/devel/lib/my_first_ros_pkg" 에 "hello_world_node" 라는 파일이 생성되었을 것이다. 한번 확인해 보자.

다음 단계는 노드를 실행하는 것인데 노드 실행에 앞서서 roscore를 구동하자. 로스의 모든 노드는 roscore를 구동한 후에 이용할 수 있다.

$ roscore

마지막으로 새로운 터미널창을 열어 아래의 명령어로 노드를 실행해보자. my_first_ros_pkg 라는 패키지의 hello_world_node 라는 노드를 실행하라는 명령어이다.

$ rosrun my_first_ros_pkg hello_world_node
---------------------------------------------------------------------------
[ INFO] [1380598894.131775283]: hello world 0
[ INFO] [1380598894.231826916]: hello world 1
[ INFO] [1380598894.331798085]: hello world 2
[ INFO] [1380598894.431796634]: hello world 3
[ INFO] [1380598894.531808660]: hello world 4
[ INFO] [1380598894.631800431]: hello world 5
[ INFO] [1380598894.731805683]: hello world 6

[출처] 로봇 운영체제 강좌 : ROS 빌드 시스템 (오픈소스 소프트웨어 & 하드웨어: 로봇 기술 공유 카페 (오로카)) | 작성자 표윤석

profile
자율주행에 관심이 있으며, Lidar SLAM을 공부하고 있습니다. [개인 홈페이지 : https://woogiee.wixsite.com/youngwooklee]

0개의 댓글