1261.41 ROS2 인터페이스 파일(.msg, .srv, .action) 구조

1. 서론

ROS2의 통신 인프라는 노드 간 교환되는 데이터의 구조를 명세하는 인터페이스 파일에 기반한다. 인터페이스 파일은 토픽 통신을 위한 .msg 파일, 서비스 통신을 위한 .srv 파일, 액션 통신을 위한 .action 파일의 세 가지 형식으로 구분된다. 각 파일 형식은 해당 통신 패러다임의 데이터 교환 구조를 반영하는 고유한 문법 규칙을 따르며, 빌드 시점에 다중 프로그래밍 언어의 소스 코드로 변환된다. 본 절에서는 이 세 가지 인터페이스 파일의 구조, 문법 규칙, 그리고 빌드 시스템에서의 처리 과정을 체계적으로 분석한다.

2. 인터페이스 파일의 공통 요소

2.1 파일 배치 규약

ROS2 패키지 내에서 인터페이스 파일은 다음의 디렉터리 구조에 따라 배치된다.

my_package/
├── msg/
│   └── MyMessage.msg
├── srv/
│   └── MyService.srv
├── action/
│   └── MyAction.action
├── CMakeLists.txt
└── package.xml

각 인터페이스 파일의 이름은 PascalCase(또는 UpperCamelCase) 명명 규칙을 따른다. 파일 이름은 해당 인터페이스의 타입 이름이 되므로, 명확하고 설명적인 이름을 부여하여야 한다.

2.2 공통 문법 요소

세 가지 인터페이스 파일은 다음의 공통 문법 요소를 공유한다.

필드 선언: 각 필드는 자료형과 필드 이름의 쌍으로 선언된다. 필드 이름은 snake_case 규칙을 따른다.

float64 position_x
string robot_name

주석: # 기호로 시작하는 행은 주석으로 처리되며, 코드 생성에 영향을 미치지 않는다.

# 로봇의 3차원 위치 좌표
float64 x

상수 선언: 상수는 자료형 이름=값 형식으로 선언되며, 실행 시점에 변경할 수 없는 불변 값을 정의한다.

uint8 STATE_IDLE=0
uint8 STATE_ACTIVE=1
uint8 STATE_ERROR=2

기본값 지정: 필드 선언 시 기본값을 지정할 수 있다.

float64 velocity 0.0
bool enabled true

2.3 지원되는 자료형

ROS2 인터페이스 파일에서 사용 가능한 자료형은 다음과 같이 분류된다.

분류자료형설명
논리형bool참/거짓
정수형int8, uint8, int16, uint16, int32, uint32, int64, uint64부호 있는/없는 정수
부동소수점형float32, float64단정밀도/배정밀도
문자형char, byte문자, 바이트
문자열형string, wstringUTF-8 문자열, 와이드 문자열
제한 문자열string<=N최대 N 문자 길이로 제한된 문자열

배열 자료형은 다음의 문법으로 선언한다.

배열 형식문법설명
고정 길이 배열float64[3]정확히 3개의 요소
무한 가변 배열float64[]상한 없는 가변 길이
제한 가변 배열float64[<=100]최대 100개 요소

3. .msg 파일의 구조

3.1 기본 구조

.msg 파일은 토픽 통신에서 사용되는 메시지의 데이터 구조를 정의한다. 파일은 필드 선언의 목록으로 구성되며, 각 필드는 독립된 행에 기술된다.

# 로봇의 현재 위치와 속도 정보
std_msgs/Header header
geometry_msgs/Point position
geometry_msgs/Vector3 velocity
float64 battery_level
uint8 status

3.2 중첩 메시지의 참조

다른 패키지에 정의된 메시지를 필드로 포함하는 경우, 패키지명/메시지명 형식으로 전체 경로(fully qualified name)를 명시한다. 동일 패키지 내의 메시지를 참조하는 경우에도 패키지 이름을 포함하는 것이 명시성 측면에서 권장된다.

# 외부 패키지 메시지 참조
geometry_msgs/Pose target_pose
sensor_msgs/LaserScan scan_data

# 동일 패키지 메시지 참조
my_package/RobotState current_state

3.3 표준 메시지 패키지

ROS2는 빈번하게 사용되는 데이터 구조를 표준 메시지 패키지로 제공한다. 주요 표준 메시지 패키지는 다음과 같다.

  • std_msgs: Header, String, Bool, Int32, Float64 등 기본 메시지
  • geometry_msgs: Point, Pose, Twist, Transform, Quaternion 등 기하학적 메시지
  • sensor_msgs: Image, LaserScan, PointCloud2, Imu, JointState 등 센서 메시지
  • nav_msgs: Odometry, Path, OccupancyGrid, MapMetaData 등 내비게이션 메시지
  • diagnostic_msgs: DiagnosticStatus, DiagnosticArray 등 진단 메시지

4. .srv 파일의 구조

4.1 요청-응답 분리 구문

.srv 파일은 서비스 통신의 요청(Request)과 응답(Response) 데이터 구조를 단일 파일에 정의한다. 요청과 응답은 세 개의 대시(---)로 구분된다.

# 요청(Request) 영역
float64 target_x
float64 target_y
float64 target_z
---
# 응답(Response) 영역
bool success
string message
float64 estimated_time

대시 구분자 위의 필드는 클라이언트가 서버에 전송하는 요청 데이터를 구성하며, 구분자 아래의 필드는 서버가 클라이언트에 반환하는 응답 데이터를 구성한다.

4.2 빈 요청 또는 응답

요청 또는 응답에 데이터가 필요하지 않은 경우, 해당 영역을 비워 둘 수 있다. 예를 들어, 트리거 서비스는 요청 데이터 없이 서버의 특정 동작을 촉발하므로 다음과 같이 정의된다.

# 빈 요청 (트리거 서비스)
---
bool success
string message

ROS2는 이러한 패턴을 위하여 std_srvs/Trigger 표준 서비스를 제공한다.

4.3 코드 생성 결과

.srv 파일로부터 빌드 시스템은 세 가지 타입을 생성한다. MyService 서비스 파일의 경우, MyService(서비스 자체), MyService_Request(요청 메시지), MyService_Response(응답 메시지)의 세 가지 타입이 생성된다. C++에서는 my_package::srv::MyService, my_package::srv::MyService::Request, my_package::srv::MyService::Response로 접근할 수 있다.

5. .action 파일의 구조

5.1 삼분 구조

.action 파일은 액션 통신의 목표(Goal), 결과(Result), 피드백(Feedback) 데이터 구조를 단일 파일에 정의한다. 세 영역은 각각 세 개의 대시(---)로 구분된다.

# 목표(Goal) 영역
geometry_msgs/PoseStamped target_pose
float64 max_velocity
bool use_orientation
---
# 결과(Result) 영역
bool success
float64 total_distance
float64 elapsed_time
string error_message
---
# 피드백(Feedback) 영역
geometry_msgs/PoseStamped current_pose
float64 distance_remaining
float64 estimated_time_remaining
float32 progress_percentage

첫 번째 구분자 위의 필드는 클라이언트가 서버에 전달하는 목표 데이터를, 두 구분자 사이의 필드는 작업 완료 시 반환되는 최종 결과 데이터를, 두 번째 구분자 아래의 필드는 작업 수행 중 주기적으로 전달되는 피드백 데이터를 정의한다.

5.2 코드 생성 결과

.action 파일로부터 빌드 시스템은 상당히 복잡한 코드를 생성한다. MyAction 액션 파일의 경우 다음의 타입이 생성된다.

  • MyAction(액션 자체)
  • MyAction_Goal(목표 메시지)
  • MyAction_Result(결과 메시지)
  • MyAction_Feedback(피드백 메시지)
  • MyAction_SendGoal(목표 전송 서비스)
  • MyAction_GetResult(결과 조회 서비스)
  • MyAction_FeedbackMessage(피드백 래핑 메시지)

이 타입들은 내부적으로 목표 전송 서비스, 결과 조회 서비스, 취소 서비스, 피드백 토픽, 상태 토픽 등 다수의 DDS 엔드포인트에 대응된다.

6. 빌드 시스템에서의 인터페이스 처리

6.1 CMakeLists.txt 설정

인터페이스 파일을 포함하는 ROS2 패키지의 CMakeLists.txt에는 다음의 설정이 필요하다.

find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/MyMessage.msg"
  "srv/MyService.srv"
  "action/MyAction.action"
  DEPENDENCIES geometry_msgs std_msgs
)

rosidl_generate_interfaces 매크로는 지정된 인터페이스 파일로부터 코드 생성을 트리거한다. DEPENDENCIES 인자에는 인터페이스 파일이 참조하는 외부 패키지의 이름을 열거한다.

6.2 package.xml 설정

package.xml에는 인터페이스 코드 생성에 필요한 빌드 의존성과 실행 시점 의존성이 선언되어야 한다.

<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>

rosidl_default_generators는 빌드 시점에 코드 생성기를 제공하며, rosidl_default_runtime은 생성된 코드의 실행 시점 의존성을 포함한다. rosidl_interface_packages 그룹 멤버십은 패키지가 인터페이스 정의를 포함함을 선언한다.

7. 인터페이스 파일 설계의 실무적 고려사항

7.1 인터페이스 전용 패키지의 분리

인터페이스 파일은 구현 코드와 분리된 전용 패키지에 정의하는 것이 권장된다. 이는 순환 의존성(circular dependency)을 방지하고, 인터페이스 변경의 영향 범위를 최소화하며, 인터페이스 패키지의 독립적 버전 관리를 가능하게 한다. 관례에 따라 인터페이스 전용 패키지의 이름에는 _msgs, _srvs, _interfaces 등의 접미사가 사용된다.

7.2 하위 호환성의 유지

인터페이스의 변경은 해당 인터페이스를 사용하는 모든 노드에 영향을 미친다. 필드의 추가는 기존 코드의 재빌드를 요구하며, 필드의 제거나 타입 변경은 기존 코드의 수정을 요구한다. 따라서 운영 환경에서 인터페이스를 변경할 때에는 기존 인터페이스와의 하위 호환성을 신중히 고려하여야 하며, 파괴적 변경(breaking change)이 불가피한 경우 버전 관리 전략을 수립하여야 한다.

7.3 메시지 크기의 최적화

인터페이스 설계 시 메시지의 직렬화 크기를 고려하여야 한다. 불필요하게 큰 자료형의 사용(예: 0~255 범위의 값에 int64 사용), 중복 데이터의 포함, 사용하지 않는 필드의 잔존은 통신 대역폭의 낭비를 초래한다. 특히 고빈도로 발행되는 토픽 메시지의 경우 메시지 크기가 시스템 성능에 미치는 영향이 상당하다.

8. 결론

ROS2의 세 가지 인터페이스 파일 형식은 각각의 통신 패러다임에 특화된 데이터 구조 정의 기법을 제공한다. .msg 파일은 토픽의 단방향 데이터 흐름을, .srv 파일은 서비스의 요청-응답 쌍을, .action 파일은 액션의 목표-결과-피드백 삼원 구조를 정의한다. 이 파일들은 빌드 시점에 rosidl 파이프라인을 통하여 다중 언어의 타입 안전한 코드로 변환되며, 이는 ROS2 통신의 정확성과 상호운용성의 기반이 된다. 인터페이스 파일의 설계에서는 표준 메시지의 재사용, 패키지 분리, 하위 호환성 유지, 그리고 메시지 크기 최적화의 원칙을 준수하여야 한다.