인터페이스는 ROS2에서 노드 간 통신을 위해 사용되는 토픽,서비스,액션의 메시지 타입과 통신방법을 정의하는 것을 의미한다. 이러한 인터페이스는 별도의 패키지를 만들어 사용하는 것이 권장된다.
그 이유는 다음과 같다.
| 개념 | 설명 | 예시 |
|---|---|---|
| 인터페이스 | 시스템 간 데이터 교환 방식을 정의한 규약으로, 통신에 사용되는 데이터 구조를 정의 | example_interfaces/srv/AddTwoInts, sensor_msgs/msg/Image |
| 타입 | 데이터의 형태와 의미를 정의하며, 변수나 객체가 가질 수 있는 값의 종류를 지정 | int32, float64, string, geometry_msgs/msg/Point |
ros2 pkg create --build-type ament_cmake ros_study_msgs

생성한 패키지 안에 action,msg,srv 폴더를 만든다.

그리고 각 인터페이스를 정의하는데 필요한 파일을 폴더에 넣어준다.

액션 목표(Action Goal), 피드백(Action Feedback), 결과(Action Result)의 데이터 형식을 정의해준다.

토픽에 사용될 메시지의 데이터 타입(정수형, 부동소수점, 문자열 등)을 정의해준다.

서비스의 요청(request)과 응답(response)의 데이터 형식을 정의해준다.
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>builtin_interfaces</exec_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
인터페이스 전용 패키지를 만들 때는 필수적으로 들어가야할 의존성 패키지이다.

set(msg_files
"msg/MyMsg.msg"
)
set(srv_files
"srv/MySrv.svr"
)
set(action_files
"action/MyAction.action"
)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
${srv_files}
${action_files}
DEPENDENCIES builtin_interfaces
)
set 명령어로 각 파일을 지정하고 rosidl_generate_interfaces에 해당하는 set들을 작성한다.

colcon build --packages-select ros_study_msgs 를 실행하여 빌드 결과를 확인한다.

ros2_ws/install/ros_study_msgs/include/ros_study_msgs/ros_study_msgs/에서 작성한 인터페이스를 사용하기 위한 파일들을 확인할 수 있다.

C에서 사용하는 *.c와 C++에서 사용하는 *.hpp 등을 확인할 수 있다.
새로운 패키지를 생성하여 msg interface를 테스트 해본다.
ros2 pkg create --build-type ament_python ros_study_py
ros_study_py 폴더에서 my_msg_test.py로 퍼블리셔 코드를 작성해주자. 그러면 MyMsg 라는 토픽을 생성하게 된다.
import rclpy
frm rlcpy.node import Node
from.ros_study_msgs.msg import MyMsg
class my_msg_test(Node):
def __init__(self):
super().__init__('my_msg_test') # 노드 이름: my_msg_test
self.publisher_ = self.create_publisher(MyMsg, 'MyMsg', 10)
timer_period =0.5
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 0.0
def timer_callback(self):
msg = MyMsg
msg.num = self.i
self.publisher_.publish(msg)
self.get_logger().info(str(msg.num))
self.i +=1
def main(args=None):
rclpy.init(args=args)
my_msg_test_publisher = my_msg_test() #클래스 인스턴스화
rclpy.spin()
my_msg_test_publisher.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
<depend>ros_study_msgs</depend>
인터페이스 패키지에 대한 의존성을 추가한다.

my_msg_test = ros_study_py.my_msg_test:main
콘솔 스크립트에 명령어를 추가한다.

터미널1에 ros2 run ros_study_py my_msg_test 를 실행한다.

my_msg_test 에서 토픽이 발행된 것을 확인할 수 있다.
터미널2에서 ros2 topic list로 현재 발행되고 있는 토픽 리스트를 확인할 수 있다.

이후, ros2 topic echo /MyMsg로 MyMsg로 발행되는 메시지를 터미널에 출력하게 하였다.