[ROS2] ROS2의 패키지 파일

HY K·2024년 9월 19일

ROS2

목록 보기
9/18

이번 포스팅에서는 ROS2의 패키지 내부의 파일들에 대해서 다뤄보겠다.
참고한 링크는 다음과 같다.
https://cafe.naver.com/openrt/24422


패키지 파일

💡 패키지 파일(Package File)

  • 패키지 설정 파일(package.xml)
  • 빌드 설정 파일(CMakeLists.txt)
  • 파이썬 패키지 설정 파일(setup.py)
  • 파이썬 패키지 환경설정 파일(setup.cfg)
  • RQt 플러그인 설정 파일(plugin.xml)
  • 패키지 변경로그 파일(CHANGELOG.rst)
  • 라이선스 파일(LICENSE)
  • 패키지 설명 파일(README.md)

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

  • 패키지 정보를 기술하는 파일
  • 패키지 이름, 저작자, 라이선스, 의존성 패키지 등을 XML 형식으로 기술
  • rclcpp와 rclpy 사이에서 약간의 차이가 발생함

rclcpp의 경우

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_first_ros_rclcpp_pkg</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="pyo@robotis.com">pyo</maintainer>
  <license>TODO: License declaration</license>
  <buildtool_depend>ament_cmake</buildtool_depend>
  <depend>rclcpp</depend>
  <depend>std_msgs</depend>
  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>
  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

rclpy의 경우

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_first_ros_rclpy_pkg</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="pyo@robotis.com">pyo</maintainer>
  <license>TODO: License declaration</license>
  <depend>rclpy</depend>
  <depend>std_msgs</depend>
  <test_depend>ament_copyright</test_depend>
  <test_depend>ament_flake8</test_depend>
  <test_depend>ament_pep257</test_depend>
  <test_depend>python3-pytest</test_depend>
  <export>
    <build_type>ament_python</build_type>
  </export>
</package>

package.xml 파일에 담겨있는 핵심 내용들은 다음과 같다.

💡 패키지 설정 파일 내용들

<xml> : 문서 문법을 정의하는 문구
<package> ~ </package> : ROS 패키지 설정 부분
<name> : 패키지 이름
<version> : 패키지 버젼
<descrption> : 패키지에 대한 간단한 설명
<maintainer> : 패키지 관리자 이름 및 이메일
<license> : 라이선스 기재
<url> : 패키지 설명 페이지 주소 등
<author> : 패키지 개발자 이름 및 이메일 주소
<buildtool_depend> : 빌드 툴의 의존성 기술
<build_depend> : 패키지 빌드할 때 필요한 의존성 패키지
<exec_depend> : 패키지 실행시 필요한 의존성 패키지
<test_depend> : 패키지 테스트 시 필요한 의존성 패키지
<export> : 위에 명시되지 않는 내용들을 작성할 때 사용

빌드 설정 파일(CMakeLists.txt)

C++의 경우 빌드 시스템으로 CMake를 이용하고 있고(정확히는 ament_cmake), 이에 따라서 빌드 설정 파일을 작성해야 한다. 이 빌드 설정 파일에는 실행 파일 생성, 의존성 패키지 우선 빌드, 링크 생성 등을 설정하게 된다.

CMakeLists.txt 파일 내용은 다음과 같다.

cmake_minimum_required(VERSION 3.5)
# 현재 cmake의 최소 요구 버젼
project(my_first_ros_rclcpp_pkg)
# 프로젝트의 이름

# Default to C99
if(NOT CMAKE_C_STANDARD)
  set(CMAKE_C_STANDARD 99)
endif()

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()
# 여기까지는 컴파일러 버젼을 기재하는 것

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# 컴파일 옵션을 추가하는 것

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# ament 빌드를 할 때 요구되는 구성 요소 패키지들

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

위 파일에는 빠져있지만, 내가 작성한 인터페이스 파일을 사용할 경우 rosidl_generate_interfaces 를 사용해서 인터페이스를 추가해야 한다.

set(msg_files
  "msg/Count.msg"
)

set(srv_files
  "srv/Calculation.srv"
)

set(action_files
  "action/Led.action"
)

rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  ${srv_files}
  ${action_files}
  DEPENDENCIES std_msgs action_msgs
  ADD_LINTER_TESTS
)

위와 같이 작성하면 인터페이스 헤더 파일을 자동으로 생성한다.

그리고 include_directories 에서 헤더 파일 폴더를 지정하고, add_executable 에서 빌드할 때 참조하는 ㅋ코드와 실행 파일 이름을 지정한다. 이후 ament_target_dependencies 에서 해당 라이브러리 및 실행 파일을 빌드하기에, 해당 라이브러리 및 실행 파일을 빌드하기 전에 생성해야 할 의존성이 있는 인터페이스가 있다면 우선적으로 이를 수행하라는 설정이다.

예시를 들면 다음과 같다.

include_directories(
  include
)

set(PUBLISHER_NODE_NAME publisher)
set(SUBSCRIBER_NODE_NAME subscriber)
set(dependencies
  "examples_msgs"
  "rclcpp"
)

add_executable(${PUBLISHER_NODE_NAME} src/publisher/main.cpp src/publisher/counter.cpp)
ament_target_dependencies(${PUBLISHER_NODE_NAME} ${dependencies})

add_executable(${SUBSCRIBER_NODE_NAME} src/subscriber/main.cpp src/subscriber/observer.cpp)
ament_target_dependencies(${SUBSCRIBER_NODE_NAME} ${dependencies})

설치 옵션도 빌드 옵션과 마찬가지로, 예시는 다음과 같다.

install(TARGETS
  ${PUBLISHER_NODE_NAME}
  ${SUBSCRIBER_NODE_NAME}
  DESTINATION lib/${PROJECT_NAME}
)

install(DIRECTORY launch meshes param resource urdf worlds
  DESTINATION share/${PROJECT_NAME}
)

특정 폴더에 두고 설치 시 함께 포함시켜야 하는 것이 있다면 설치 옵션에서 기술하면 된다.

파이썬 패키지 설정 파일(setup.py)

순수한 ROS2 파이썬 패키지에서만 사용하는 설정 파일로, setup.py를 파일명으로 사용한다.

from setuptools import setup

package_name = 'my_first_ros_rclpy_pkg'

setup(
    name=package_name,
    version='0.0.0',
    packages=[package_name],
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='pyo',
    maintainer_email='pyo@robotis.com',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
        ],
    },
)

솔직히 다른 것은 읽어보면 너무 간단하고, 중요한 것은 entry_points에 내가 실행하고자 하는 노드의 이름과 경로를 작성하는 것이다.

파이썬 패키지 환경설정 파일(setup.cfg)

파이썬 패키지 배포를 위한 환경설정 파일이다. 파일명으로는 setup.cfg를 사용하게 되며 develop 옵션과 install 옵션을 설정해 스크립트의 저장 위치를 설정한다.

[develop]
script-dir=$base/lib/my_first_ros_rclpy_pkg
[install]
install-scripts=$base/lib/my_first_ros_rclpy_pkg

RQt 플러그인 설정 파일(plugin.xml)

RQt 플러그인으로 패키지를 작성할 때의 필수 구성 요소로 XML 태그를 통해 각 속성을 기술한다. 기본적인 구조는 다음과 같다.

<library path="src">
  <class name="Examples" type="examples_rqt.examples.Examples" base_class_type="rqt_gui_py::Plugin">
    <description>
      A plugin visualizing messages and services values
    </description>
    <qtgui>
      <group>
        <label>Visualization</label>
        <icon type="theme">folder</icon>
        <statustip>Plugins related to visualization</statustip>
      </group>
      <label>Viewer</label>
      <icon type="theme">utilities-system-monitor</icon>
      <statustip>A plugin visualizing messages and services values</statustip>
    </qtgui>
  </class>
</library>

그 외 패키지 변경로그 파일, 라이선스 파일, README.md 파일 등이 있으며, 이 중에서 가장 핵심은 패키지에 대한 각종 자세한 설명을 기술한 README.md 파일이라고 할 수 있다.

profile
로봇, 드론, SLAM, 제어 공학 초보

0개의 댓글