1261.39 ROS2 메시지 직렬화와 역직렬화

1. 서론

분산 로봇 시스템에서 노드 간 통신은 데이터를 네트워크를 통하여 전송하는 과정을 수반한다. 프로그래밍 언어의 메모리 내에서 표현되는 구조체(structure)나 객체(object)는 포인터, 정렬(alignment), 엔디안(endianness) 등 플랫폼 의존적 특성을 갖기 때문에, 이를 직접 네트워크로 전송하면 수신 측에서 올바르게 해석할 수 없다. 직렬화(serialization)는 메모리 내의 데이터 구조를 바이트 스트림(byte stream)으로 변환하는 과정이며, 역직렬화(deserialization)는 수신된 바이트 스트림을 원래의 데이터 구조로 복원하는 역과정이다. 본 절에서는 ROS2의 메시지 직렬화 및 역직렬화 메커니즘의 원리, 구현 구조, 그리고 성능적 함의를 학술적으로 분석한다.

2. 직렬화의 기본 개념

2.1 직렬화의 정의와 필요성

직렬화(serialization)는 메모리 상의 복합 데이터 구조를 연속적인 바이트 시퀀스(byte sequence)로 인코딩(encoding)하는 과정이다. 이 변환은 다음의 세 가지 목적을 위하여 수행된다.

첫째, 네트워크 전송을 위한 것이다. 네트워크 프로토콜은 바이트 스트림을 기본 전송 단위로 사용하므로, 구조화된 데이터를 바이트 시퀀스로 변환하여야 전송이 가능하다.

둘째, 플랫폼 독립성의 확보를 위한 것이다. 서로 다른 프로세서 아키텍처(x86, ARM 등)는 상이한 바이트 순서(byte order), 데이터 정렬(data alignment), 기본 자료형 크기를 갖는다. 직렬화는 이러한 차이를 표준화된 형식으로 추상화한다.

셋째, 언어 독립성의 확보를 위한 것이다. ROS2는 C++, Python, Java 등 다수의 프로그래밍 언어를 지원하며, 각 언어의 데이터 표현 방식은 상이하다. 직렬화는 언어에 무관한 공통 형식을 제공한다.

2.2 역직렬화의 정의

역직렬화(deserialization)는 직렬화의 역과정으로, 수신된 바이트 시퀀스를 해석하여 수신 측의 프로그래밍 언어 및 플랫폼에 적합한 데이터 구조로 복원하는 과정이다. 역직렬화 과정에서는 바이트 시퀀스의 무결성 검증, 자료형 일치 확인, 메모리 할당 및 데이터 복사가 수행된다.

3. ROS2의 직렬화 계층 구조

3.1 CDR 직렬화 형식

ROS2는 DDS(Data Distribution Service) 미들웨어 위에 구축되어 있으며, DDS 표준에서 정의한 CDR(Common Data Representation) 형식을 직렬화에 사용한다. CDR은 OMG(Object Management Group)의 CORBA(Common Object Request Broker Architecture) 표준에서 유래한 이진(binary) 직렬화 형식이다.

CDR 형식의 주요 특성은 다음과 같다.

  • 엔디안 표시: 직렬화된 데이터의 첫 바이트에 엔디안 정보를 포함하여 송신 측과 수신 측의 바이트 순서 차이를 처리한다.
  • 자연 정렬(natural alignment): 각 기본 자료형은 자신의 크기에 맞추어 정렬된다. 예를 들어, 4바이트 정수는 4바이트 경계에, 8바이트 부동소수점은 8바이트 경계에 정렬된다.
  • 가변 길이 데이터 처리: 문자열(string)이나 가변 길이 배열(sequence)은 길이 정보를 선행하여 기록한 후 실제 데이터를 배치한다.

ROS2 Jazzy 버전 기준, CDR v1과 CDR v2 형식이 지원되며, DDS 벤더 구현에 따라 사용되는 CDR 버전이 상이할 수 있다.

3.2 rosidl 직렬화 인프라

ROS2는 rosidl(ROS Interface Definition Language) 인프라를 통하여 메시지의 직렬화 및 역직렬화 코드를 자동 생성한다. .msg, .srv, .action 파일에 정의된 인터페이스 명세로부터 빌드 시점(build time)에 다음의 코드가 생성된다.

  • 타입 지원(type support) 함수: 각 메시지 타입에 대한 메타데이터를 제공하며, DDS 미들웨어가 적절한 직렬화/역직렬화 함수를 동적으로 선택할 수 있게 한다.
  • 직렬화/역직렬화 함수: CDR 형식과 언어별 데이터 구조 사이의 변환을 수행하는 함수이다.
  • 언어별 바인딩(binding): C, C++, Python 등 각 클라이언트 라이브러리에 적합한 데이터 타입과 접근 함수를 생성한다.

이 자동 생성 과정은 rosidl_generator_c, rosidl_generator_cpp, rosidl_generator_py 등의 패키지에 의하여 수행된다.

4. 기본 자료형의 직렬화

4.1 정수형과 부동소수점형

ROS2 메시지에서 사용되는 기본 자료형과 그 CDR 직렬화 특성은 다음과 같다.

ROS2 자료형크기(바이트)CDR 정렬설명
bool11참/거짓 값
int8 / uint811부호 있는/없는 8비트 정수
int16 / uint1622부호 있는/없는 16비트 정수
int32 / uint3244부호 있는/없는 32비트 정수
int64 / uint6488부호 있는/없는 64비트 정수
float3244IEEE 754 단정밀도 부동소수점
float6488IEEE 754 배정밀도 부동소수점

CDR 직렬화에서 다바이트(multi-byte) 자료형은 리틀 엔디안(little-endian) 또는 빅 엔디안(big-endian) 중 송신 측의 네이티브(native) 순서로 기록되며, 헤더에 엔디안 정보가 명시된다. 수신 측은 이 정보를 참조하여 필요한 경우 바이트 순서 변환을 수행한다.

4.2 문자열과 가변 길이 시퀀스

문자열(string)은 4바이트 길이 필드(널 종단 문자 포함)에 이어 UTF-8 인코딩된 문자열 데이터와 널 종단 문자(null terminator)가 기록된다. 가변 길이 배열(sequence)은 4바이트 요소 수(element count) 필드 이후에 각 요소가 순차적으로 직렬화된다.

고정 길이 배열은 길이 필드 없이 각 요소가 순차적으로 직렬화된다. 이는 고정 길이 배열의 크기 정보가 인터페이스 정의에 이미 포함되어 있기 때문이다.

5. 복합 메시지의 직렬화

5.1 중첩 메시지의 처리

ROS2 메시지는 다른 메시지를 필드로 포함하는 중첩(nested) 구조를 가질 수 있다. 예를 들어, geometry_msgs/msg/PoseStampedstd_msgs/msg/Headergeometry_msgs/msg/Pose를 필드로 포함한다. 중첩 메시지의 직렬화는 각 필드를 재귀적(recursive)으로 탐색하며, 기본 자료형에 도달할 때까지 하향식(top-down)으로 진행된다.

직렬화 과정에서 각 중첩 메시지의 필드는 인터페이스 정의에 선언된 순서대로 직렬화된다. 필드 간의 정렬 패딩(alignment padding)은 CDR 규칙에 따라 삽입되며, 이는 직렬화된 데이터의 크기가 메시지의 논리적 데이터 크기보다 클 수 있음을 의미한다.

5.2 배열과 시퀀스를 포함하는 메시지

센서 데이터 메시지는 빈번하게 대규모 배열을 포함한다. sensor_msgs/msg/PointCloud2는 수만 개의 3차원 점 데이터를 uint8[] 배열로 운반하며, sensor_msgs/msg/Image는 수백만 화소의 영상 데이터를 포함한다. 이러한 대규모 배열의 직렬화에서는 메모리 복사(memory copy) 비용이 지배적이며, 이는 직렬화 성능의 병목 지점이 될 수 있다.

6. 직렬화 성능과 최적화

6.1 제로 카피(Zero-Copy) 전송

동일한 호스트 내의 노드 간 통신에서는 네트워크 전송이 불필요하므로, 직렬화-역직렬화 과정을 생략하여 성능을 향상시킬 수 있다. ROS2는 공유 메모리(shared memory) 기반의 제로 카피(zero-copy) 전송을 지원하며, 이는 데이터의 물리적 복사 없이 메모리 참조의 전달만으로 통신을 수행한다.

제로 카피 전송은 DDS 벤더의 구현에 의존한다. Eclipse Cyclone DDS의 iceoryx 플러그인과 eProsima Fast DDS의 공유 메모리 전송이 대표적인 구현이다. 제로 카피 전송이 활성화된 경우 직렬화 오버헤드가 제거되어, 영상 데이터나 포인트 클라우드 등 대용량 메시지의 전송 지연이 현저히 감소한다.

6.2 직렬화 오버헤드의 분석

직렬화 연산의 시간 비용은 메시지의 크기와 복잡도에 비례한다. 단순한 기본 자료형으로 구성된 메시지(예: geometry_msgs/msg/Twist, 48바이트)의 직렬화 시간은 수 마이크로초 이내이다. 반면 대규모 배열을 포함하는 메시지(예: 640×480 해상도의 RGB 영상, 약 921,600바이트)의 직렬화 시간은 수백 마이크로초에 이를 수 있다.

직렬화 오버헤드를 저감하기 위한 기법으로는 다음이 활용된다.

  • 고정 크기 메시지의 사전 할당(pre-allocation): 직렬화 버퍼를 사전에 할당하여 동적 메모리 할당의 반복을 회피한다.
  • 인라인 직렬화(inline serialization): 컴파일러 최적화를 통하여 직렬화 함수의 호출 오버헤드를 제거한다.
  • 벌크 복사(bulk copy): 연속된 기본 자료형의 배열은 개별 요소의 직렬화 대신 memcpy에 의한 일괄 복사로 처리한다.

6.3 메시지 크기와 대역폭의 관계

직렬화된 메시지의 크기는 네트워크 대역폭 소비와 직결된다. CDR 직렬화에서 정렬 패딩에 의한 오버헤드는 메시지 구조에 따라 상이하나, 일반적으로 5~15% 범위 내이다. 대역폭이 제약된 환경(무선 통신, 원격 조종 등)에서는 직렬화된 메시지의 크기를 최소화하는 메시지 설계가 중요하다.

7. 역직렬화의 안전성

7.1 타입 해시와 호환성 검증

ROS2는 메시지 타입의 정합성을 보장하기 위하여 타입 해시(type hash) 메커니즘을 사용한다. 발행자와 구독자가 동일한 토픽에 연결될 때, DDS 미들웨어는 양자의 메시지 타입 정보를 비교하여 호환성을 검증한다. 타입이 불일치하는 경우 연결이 거부되어, 잘못된 역직렬화에 의한 데이터 손상을 방지한다.

7.2 버전 호환성

메시지 인터페이스의 필드가 추가되거나 제거된 경우, 직렬화 형식의 비호환이 발생한다. ROS2는 이러한 상황에서 DDS 수준의 타입 불일치 탐지를 통하여 통신을 차단한다. 점진적인 인터페이스 변경이 요구되는 경우, 새로운 메시지 타입의 정의와 병행 운용(parallel deployment) 전략이 필요하다.

8. 결론

메시지 직렬화와 역직렬화는 ROS2 통신 인프라의 기반을 이루는 핵심 메커니즘이다. CDR 형식에 기반한 직렬화는 플랫폼 독립성과 언어 독립성을 보장하며, rosidl 인프라에 의한 자동 코드 생성은 개발자의 부담을 최소화한다. 로봇 행동 제어 시스템의 설계에서는 직렬화 오버헤드가 제어 루프의 시간 제약에 미치는 영향을 고려하여야 하며, 대용량 센서 데이터에 대해서는 제로 카피 전송 등의 최적화 기법을 적극적으로 활용하여야 한다.