29.2 ROS2 Service 인터페이스(IDL) 명세 및 데이터 직렬화 원리

ROS2(Robot Operating System 2)의 서비스(Service) 통신은 클라이언트 노드의 요청(Request)과 서버 노드의 응답(Response)이라는 양방향 메시지 교환으로 구성된다. 이러한 데이터 트랜잭션이 상이한 컴퓨팅 환경과 프로그래밍 언어 간에 원활하게 이루어지기 위해서는, 교환되는 데이터의 구조를 명확히 정의하고 이를 네트워크 전송에 적합한 형태로 변환하는 표준화된 체계가 필수적이다. 본 절에서는 ROS2 서비스의 데이터 명세에 사용되는 인터페이스 정의 언어(IDL, Interface Definition Language)의 구조적 특성과, 정의된 데이터를 네트워크 바이트 스트림으로 패킹하는 데이터 직렬화(Serialization) 원리를 학술적 관점에서 서술한다.

1. 서비스 인터페이스 정의 언어(IDL)의 구조적 명세

ROS2 인터페이스는 플랫폼 및 개발 언어에 종속되지 않는 추상화된 데이터 모델을 제공한다. 서비스 데이터 구조는 일반적인 토픽 메시지(.msg)와 구분되어 .srv 확장자를 가지는 텍스트 파일로 명세된다.

서비스 IDL 명세의 핵심은 요청 블록과 응답 블록의 엄격한 분리이다. .srv 파일 내에서 세 개의 대시 기호(---)를 경계로 상단은 클라이언트가 전송하는 요청 매개변수의 타입을, 하단은 서버가 연산 후 반환하는 응답 데이터의 타입을 정의한다.

각 블록 내부는 필드 데이터 타입과 변수명의 쌍으로 기술된다. ROS2 IDL은 bool, int8, uint32, float64, string 등 다양한 기본 스칼라(Scalar) 원시 타입을 지원하며, 고정 길이 배열(Fixed-size Array) 및 가변 길이 배열(Variable-size Array)의 명세도 포함한다. 또한, 다른 패키지에 정의된 기존 .msg 파일을 필드의 데이터 타입으로 중첩(Nesting)하여 복합적인 계층형 데이터 구조를 설계하는 것도 가능하다. 이러한 IDL 기반 구조화 체계는 런타임 이전(Compile-time)에 시스템 간 데이터 송수신 규약을 완전하게 확정짓는 역할을 수행한다.

2. 인터페이스 식별자 생성(Code Generation) 메커니즘

작성된 .srv 명세 파일은 런타임에서 직접 해석되지 않으며, 빌드 시스템인 colconament_cmake 파이프라인 프로세스 단계에서 언어 특화 소스 코드로 변환된다. 이 과정은 rosidl 프레임워크에 의해 자동으로 제어된다.

rosidl 파이프라인 내의 타겟 생성기(Generator) 패키지들(예: rosidl_generator_c, rosidl_generator_cpp, rosidl_generator_py)은 파싱된 IDL AST(Abstract Syntax Tree) 구조를 입력으로 받아, C/C++ 시스템을 위한 구조체 및 헤더 파일과 Python 환경을 위한 클래스 및 모듈을 각각 생성한다. 서비스의 경우, 내부적으로 요청을 위한 네임스페이스와 응답을 위한 네임스페이스가 분리되어 개별 구조체 객체(예: Service_Request, Service_Response)로 메모리상에 컴파일되도록 매핑 코드가 구현된다. 결과적으로 개발자는 하부 네트워크 계층을 의식하지 않고 직관적인 언어 단일 문법을 통해 서비스 객체 인스턴스 멤버에 접근할 수 있게 된다.

3. 데이터 직렬화(Serialization) 및 역직렬화(Deserialization) 원리

메모리 상에 할당된 서비스 요청/응답 객체는 프로세스 경계를 넘어 네트워크 소켓으로 전송되기 위해 선형적인 연속 바이트 스트림(Byte stream) 형태로 변환되어야 한다. 이 변환 과정을 직렬화(Serialization)라 하며, 수신된 바이트 열을 다시 응용 계층의 메모리 객체 구조로 복원하는 역과정을 역직렬화(Deserialization)라 부른다.

ROS2의 기본 하위 미들웨어인 DDS(Data Distribution Service) 표준에서는 상호 운용성을 달성하기 위하여 객체 관리 그룹(OMG, Object Management Group)이 제정한 CDR(Common Data Representation) 표준 직렬화 기법을 도입하여 구동한다. 미들웨어 인터페이스 역할을 수행하는 rmw(ROS Middleware) 구현체 계층은 상위에서 전달된 개별 타입을 CDR 표준 포맷 바이트 배열로 인코딩한다.

CDR 직렬화 모델의 주요 특징은 이기종 시스템 간의 데이터 무결성 보장이다. 스트림의 헤더 부분에 엔디안(Endianness, 바이트 배열 순서 지시자) 플래그 정보를 삽입하여, 리틀 엔디안(Little-endian) 기반의 x86 아키텍처와 빅 엔디안(Big-endian) 기반의 임베디드 아키텍처 간의 데이터 교환 시 수신 측 인코딩 계층에서 적합한 방향으로 바이트 스왑(Byte Swap) 연산을 통제할 수 있도록 지원한다.

4. 데이터 패킹 구조 및 메모리 정렬(Memory Alignment) 정책

신속한 직렬화 및 역직렬화 처리 연산을 위해서는 데이터의 메모리 정렬(Memory Alignment) 원리가 중요하게 작용한다. CDR 스펙은 원시 데이터 타입들이 자신의 메모리 크기에 대응하는 바이트 경계에 맞춰 저장되도록 할당 패딩(Padding) 바이트를 암시적으로 삽입한다. 예를 들어, 1바이트 int8 타입 필드 직후에 8바이트 float64 타입이 배치되는 IDL 명세를 가질 경우, 직렬화 과정에서 float64 요소가 8의 배수 오프셋 주소에서 시작될 수 있도록 중간에 7바이트의 패딩 공간이 강제로 추가된다.

이러한 정렬 정책은 메모리 버스 단위의 효율적 로드 연산을 보장하여 접근 지연(Latency)을 최소화하는 하드웨어 친화적 특성을 보장하지만, 반대로 바이트 페이로드의 크기를 불필요하게 증가시켜 네트워크 대역폭(Bandwidth)을 소모하는 요인이 되기도 한다. 따라서 대용량 혹은 고빈도의 서비스를 설계할 때에는, 데이터 타입의 크기가 큰 필드부터 내림차순으로 IDL을 구성하여 패딩 발생을 최소화하는 구조적 최적화 패턴이 권장된다.

가변 길이 문자열(String)과 동적 배열 필드는 데이터 본문 시작 지점 앞에 32비트 정수 타입으로 요소의 길이 정보 슬롯을 직렬화하여 추가한다. 수신 노드는 해당 길이 척도를 우선적으로 해석하여 런타임 상에서 직렬화 버퍼를 동적 할당받고 후속 데이터를 추출하는 제어 시퀀스를 수행한다.