이번 포스팅에서는 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)
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> : 위에 명시되지 않는 내용들을 작성할 때 사용
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}
)
특정 폴더에 두고 설치 시 함께 포함시켜야 하는 것이 있다면 설치 옵션에서 기술하면 된다.
순수한 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를 사용하게 되며 develop 옵션과 install 옵션을 설정해 스크립트의 저장 위치를 설정한다.
[develop]
script-dir=$base/lib/my_first_ros_rclpy_pkg
[install]
install-scripts=$base/lib/my_first_ros_rclpy_pkg
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 파일이라고 할 수 있다.