이번 포스팅부터는 ROS2 프로그래밍을 본격적으로 해보자. 우선, 가장 기초가 되는 부분인 인터페이스 패키지 만들기부터 시작을 하겠다.
참고한 링크는 다음과 같다.
https://cafe.naver.com/openrt/24629
💡 인터페이스
ROS2에서는 데이터를 주고 받기 위한 메시지 통신(토픽, 서비스, 액션)을 하는데 이에 메시지 통신을 위해서 사용하는 수단을 인터페이스라고 한다. 기본적인 자료형 및 간단한 자료구조, 배열 등을 사용한다.
- 토픽: msg 인터페이스
- 서비스: srv 인터페이스
- 액션: action 인터페이스
위와 같이 사용하게 된다.
만약 이미 존재하는 인터페이스(예 - sensor_msgs/msg/PointCloud2)로 내가 담고자 하는 데이터를 모두 담아내지 못한다면, 커스텀 인터페이스를 작성해야 한다. 그리고 커스텀 인터페이스를 작성할 때 의존성 측면을 고려한다면 별도의 인터페이스 패키지를 작성하는 것이 훨씬 간편하다. 이러한 맥락에서 이번 포스팅에서는 인터페이스 패키지를 작성할 것이다.
msg, srv, action 인터페이스에 따른 구조는 이전 포스팅("파라미터와 인터페이스")을 참고하면 된다.
우선 패키지를 생성한다.
$ cd robot_ws/src
$ ros2 pkg create --build-type ament_cmake msg_srv_action_interface_example
그리고 mkdir 명령어 혹은 텍스트 에디터를 통해 패키지 내에 msg, srv, action 폴더를 생성해주자. 또, 다음과 같은 구조로 파일을 생성하자.
├── action
│ └── ArithmeticChecker.action
├── msg
│ └── ArithmeticArgument.msg
└── srv
└── ArithmeticOperator.srv
.msg, .srv, .action 파일들은 .h(pp) 파일로 변환한 후 인터페이스 타입으로 사용된다.
각각 파일들은 다음과 같이 작성한다.
builtin_interfaces/Time stamp
float32 argument_a
float32 argument_b
# consts
int8 PLUS = 1
int8 MINUS = 2
int8 MULTIPLY = 3
int8 DIVISION = 4
# Request
int8 arithmetic_operator
---
# Response
float32 arithmetic_result
# Goal
float32 goal_sum
---
# Result
string[] all_formula
float32 total_sum
---
# Feedback
string[] formula
딱 보면 각 인터페이스 별 구조의 차이가 보일 것이다.
그리고 package.xml 파일과 CMakeLists.txt 파일을 수정하자. 인터페이스 패키지는 순수 파이썬 패키지가 아니기 때문에 setup.py가 아니라 CMakeLists.txt 파일을 수정해야 한다.
<?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>msg_srv_action_interface_example</name>
<version>0.1.0</version>
<description>basic interface pkg</description>
<maintainer email="suberkut76@gmail.com">kimhoyun</maintainer>
<license>Apache 2.0</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>builtin_interfaces</exec_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>
</package>
인터페이스 패키지를 생성할 때, 빌드 시에는 DDS에서 사용하는 IDL(Interface Definition Language) 생성과 관련된 rosidl_default_generators 가 사용된다는 점, 실행 시에는 builtin_interfaces 와 rosidl_default_runtime 이 사용된다는 점을 반드시 기억해야 한다.
이는 인터페이스 패키지를 작성할 때 반드시 필요한 의존성 패키지기 때문이다.
cmake_minimum_required(VERSION 3.8)
project(msg_srv_action_interface_example)
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(builtin_interfaces REQUIRED)
find_package(rosidl_default_generators REQUIRED)
set(msg_files
"msg/ArithmeticArgument.msg"
)
set(srv_files
"srv/ArithmeticOperator.srv"
)
set(action_files
"action/ArithmeticChecker.action"
)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
${srv_files}
${action_files}
DEPENDENCIES builtin_interfaces
)
ament_export_dependencies(rosidl_default_runtime)
ament_package()
일반적인 CMakeLists.txt 파일과 다르게 set 명렁어를 통해서 msg, srv, action 파일을 지정하고, rosidl_generate_interfaces에 해당 set들을 기입하면 된다.
$ cd .. (혹은 cd robot_ws)
$ colcon build --symlink-install --packages-select msg_srv_action_interface_example
이를 통해서 빌드를 하고, 성공적으로 실행 파일을 생성할 수 있다.