ROS #9 - Interface 기초 설계

남생이·2024년 10월 21일

ROS

목록 보기
9/28

1. Interface

  • 정의: ROS에서 노드 사이의 데이터 통신 시, 사용되는 데이터 타입

  • 종류

    • Topic - .msg
    • Service - .srv
    • Action - .action
  • 특징

    • 보통 여러개의 패키지를 가지는 경우가 대다수이기에, 별도의 인터페이스 패키지를 생성하여 사용하는 것을 추천

    • std_msgs, geometry_msgs 등과 같이 미리 선언된 인터페이스 사용가능

      from std_msgs.msg import String
      msg = String()
      msg.data = "string"
    • 필요에 따라 인터페이스를 커스텀하여 사용 가능

      $ mkdir <workspace>/<pkg_name>/<msg/srv/action>
      # message.msg 파일 내용
      float32 num
       string text

2. Interface package 생성

  • 주의점
    - 각 인터페이스에 해당하는 폴더 생성
    - 해당 폴더 내에 파일 생성, camel-case를 적용하여 생성
    - 파일의 첫문자가 소문자일 경우 빌드 시 오류 발생

2.1 msg, srv, action 파일 작성

  • 아래의 파일 작성 후, package.xml과 CMakeLists.txt 파일에서 해당 파일들을 참조하도록 수정 필요

2.1.1 MyMsg.msg

# MyMsg.msg
int32 id # 고유 id
string name # 텍스트 정보 저장(센서의 이름등)
float32 value
# float32[] values : 여러 수치 데이터 집합 표시

2.1.2 MySrv.srv

  • 요청과 응답 분리 --> '---'
# MySrv.srv
# Request
float32 req
---
# Response
float32 res

2.1.3 MyAction.action

  • 요청과 응답 분리 --> '---'
# Goal
float32 go
---
# Result
float32 res
---
# Feedback
string[] str

3. package.xml 수정

  <buildtool_depend>ament_cmake</buildtool_depend>
  <buildtool_depend>rosidl_default_generators</buildtool_depend>

  <exec_depend>buildtool_interfaces</exec_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_groups>rosidl_interface_packages</member_of_groups>

위의 코드를 package.xml 파일에 추가한다. 각 코드의 기능을 설명하도록 하겠다.

  • <buildtool_depend>ament_cmake</buildtool_depend>: CMake ROS2 패키지 빌드 도구

  • <buildtool_depend>rosidl_default_generators</buildtool_depend>
    : ROS2의 인터페이스 파일을 자동으로 생성하는 데 필요한 도구

  • <exec_depend>buildin_interfaces</exec_depend>
    : ROS2 패키지 실행에 필요한 의존성 정의

  • <exec_depend>rosidl_default_runtime</exec_depend>
    : ROS2 메시지를 사용하기 위해 런타임에 필요한 의존성 정의, 생성된 인터페이스 실행 시 필요

  • <member_of_groups>rosidl_interface_packages</member_of_groups>
    : 패키지의 그룹을 정의

  • rosidl(ROS interface Definition language)
    - 인터페이스 정의: msg,srv,action의 형식 및 구조 정의
    - 자동 코드 생성
    - 구문 검사
    - 다양한 언어 지원

nameexplanation
rosidl_default_generators.msg, .srv, .action 파일에서 C++ 및 Python 클래스를 생성
rosidl_interface_packagesROS 2에서 인터페이스 패키지들을 관리하기 위한 메타 패키지
여러 인터페이스 패키지들을 통합하여 관리하는 데 사용
rosidl_default_runtimeROS 2에서 정의된 메시지, 서비스, 및 액션 인터페이스의 런타임 지원을 제공하는 패키지

4. CMakeLists.txt 수정

find_package(builtin_interfaces REQUIRED)
find_package(rosidl_default_generators REQUIRED)

set(msg_files
"msg/MyMsg.msg")
set(srv_files
"srv/MySrv.srv")
set(action_files
"action/MyAction.action")

rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  ${srv_files}
  ${action_files}
  DEPENDENCIES builtin_interfaces
)
  • find_packages : CMake에서 다른 패키지를 찾아서 사용할 수 있도록 하는 명령어
    - REQUIRED: 해당 패키지가 필수임을 나타내어 패키지를 찾지 못하면 오류 발생
  • set: 각 인터페이스 파일의 경로 지정, 파일 경로를 리스트 형으로 정의
  • rosidl_generate_interfaces: 인터페이스 파일로부터 python 클래스를 자동 생성
  • builtin_interfaces: time, duration, string 등의 메시지 형식이 정의되어 있음

5. build


6. new package 생성

study_msg_test.py 작성

import rclpy
from rclpy.node import Node
from rclpy.qos import QoSProfile
from study_msgs.msg import MyMsg

class study_msg_test(Node):
    def __init__(self):
        super().__init__("study_msg_test")
        qos_profile = QoSProfile(depth=10)
        self.publisher_ = self.create_publisher(MyMsg, 'MyMsg', qos_profile)  # 수정된 부분
        self.timer = self.create_timer(0.5, self.timer_callback)
        self.i = 0.0
        
    def timer_callback(self):
        msg = MyMsg()
        msg.number = self.i
        self.publisher_.publish(msg)
        self.get_logger().info('test msg %s', self.i)  # 수정된 부분
        self.i += 1
        
def main(args=None):
    rclpy.init(args=args)
    study_msg_test_publisher = study_msg_test()
    
    rclpy.spin(study_msg_test_publisher)
    
    study_msg_test_publisher.destroy_node()
    rclpy.shutdown()

7. package.xml, setup.py 수정

  <depend>study_msgs</depend>

위 코드를 추가하여 인터페이스 패키지를 빌드 및 실행 시 사용하도록 설정

8. 빌드 및 실행

profile
공부하는 거북이

0개의 댓글