13.1.3.3.1. MSM 헤더(Header), 위성 데이터(Satellite Data), 신호 데이터(Signal Data) 블록 메모리 매핑
RTCM v3.2 규격에서 창안된 다중 신호 메시지(Multiple Signal Messages, MSM) 포맷은 복수 위성군의 데이터를 고압축률로 전송하기 위해 극도로 계산적인 메모리 레이아웃을 채택하였다. 이는 기존 Legacy 방식의 선형 직렬 나열법을 완전히 탈피하여, 데이터 계급(Hierarchy)에 따라 공통 분모가 큰 덩어리를 앞쪽에 배치하고 분해가 필요한 속성 데이터들을 뒤로 연기하는 3단 메모리 세그멘테이션(3-Stage Memory Segmentation) 구조로 구성된다.
본 절에서는 각 블록이 차지하는 비트맵의 의미와 PX4-Autopilot과 같은 RTOS(Real-Time Operating System, 예: NuttX) 환경의 GPS 디코더(src/drivers/gps)가 이 가변 길이 바이너리를 어떻게 C/C++ 포인터 메모리 구조로 안전하게 매핑(Mapping)하는지 분석한다.
1. 3단 메모리 블록 매핑 아키텍처
하나의 완성된 MSM 메시지 페이로드 영역은 논리적으로 명확한 3단계 구역으로 쪼개어 연속적인 주소번지를 점유한다. 이는 GCS나 베이스 스테이션에서 데이터를 송출하는 순서이기도 하다.
graph TD
A[MSM Payload Buffer] --> B[1. MSM Header Block : 모든 위성 공통 메타데이터]
A --> C[2. Satellite Data Block : N개의 위성별 거친 개략치]
A --> D[3. Signal Data Block : M개의 개별 신호에 대한 정밀 관측치]
B -. 비트마스킹(N 산출) .-> C
B -. 비트마스킹(M 산출) .-> D
디코더의 핵심 알고리즘은 포인터 연산(Pointer Arithmetic) 이다. 항공용 소프트웨어 규격 특성상 PX4 내에서는 런타임에 커지는 가변 스트림을 처리하기 위해 동적 할당(malloc, new)을 남발하는 것을 엄격히 금지한다. 따라서 사전에 충분히 넓게 확보된 정적 배열(Static Array) 레이아웃 위에 바이트-오프셋 커서를 전진시켜 첫 번째 블록부터 각 블록의 경계를 나누는 방식을 채택한다.
2. 블록별 세부 구조 및 물리적 변수
2.1 첫 번째: MSM 헤더 블록 (Header Block)
이 블록의 목적은 이어지는 위성 블록과 신호 블록의 크기(Size)와 조합을 정의하는 일종의 ‘메타데이터 목차’ 역할을 수행하는 것이다. 따라서 항상 고정된 길이(통상 169비트 등)를 가진다.
주요 포함 정보:
- Message Number (12-bit): 1074(GPS MSM4), 1087(GLONASS MSM7) 등 아이디.
- Reference Station ID (12-bit): 베이스 스테이션 식별 번호. (GCS에서 기체로 보내는 여러 베이스 중첩 디버깅에 활용)
- GNSS Epoch Time (30-bit): 밀리초(ms) 단위의 기준국 관측 시간. 위성 데이터와 신호 데이터는 모두 이 기준 시간(Epoch)에 종속된다.
- Satellite Mask (64-bit): 64자리의 비트 중
1로 세팅된 자리는 해당 PRN(위성 번호)의 관측 데이터가 존재함을 의미한다. 이 비트에서 1의 개수를 모두 세면, 다음에 올Satellite Data Block요소의 개수 **N**을 확정지을 수 있다. - Signal Mask (32-bit): L1C/A, L2C, L5 등 어떤 무선 주파수 신호들이 추적되었는지 나타낸다. (결과 셀 파악에 기여)
2.2 두 번째: 위성 데이터 블록 (Satellite Data Block)
헤더에서 계산된 N개의 위성만큼 순차적으로 나열되는 블록이다.
이 블록은 한 위성에 여러 주파수 채널이 송출되더라도, “해당 위성까지의 대략적인 거리(Rough Range)“와 거친 도플러 편이율 등 주파수와 무관하게 위성 그 자체의 궤도 기하학과 관련된 ’공통 성분’을 전송한다.
- 예시 변수: Rough Range (밀리초 단위 계산치), 위성 관측 각도에 따른 전리층/대류권 오차 추정 요소(MSM7 기준).
- 효과: 각 채널(L1, L2) 데이터마다 수만 킬로미터 단위의 거리 정수를 중복 전송하지 않게 하므로, 대역폭 점유를 획기적으로 낮춘다.
2.3 세 번째: 신호 데이터 블록 (Signal Data Block)
가장 비중이 크고 실제 EKF2 추정기가 소화해야 하는 정밀 보정치가 담긴 영역이다.
여기에 존재하는 데이터 셀(Cell)의 총 개수 **M**은 앞선 위성 마스크와 신호 마스크, 현행 관측 셀 마스크(Cell Mask)의 논리곱(AND) 맵을 통해 정의된다. 쉽게 설명해 위성 10대(N=10)에 대하여 L1과 L2 두 가지 신호를 모두 수신했다면, 최대 20개의 신호 셀(M=20)이 이 블록에 배열된다.
- 예시 변수:
- Fine Pseudorange (위성 블록의 거친 거리와의 차잇값 보정량, Delta)
- Fine Phase (정밀 반송파 위상 사이클 계산치)
- PhaseRange Rate (ms 단위의 극초정밀 시선 속도, MSM7전용)
- CNR (신호대 잡음비, dBHz 단위)
3. PX4 환경에서의 메모리 매핑 절차적 고찰
펌웨어가 QGroundControl로부터 MAVLink GPS_RTCM_DATA 토픽을 주입받아 u-blox와 같은 드라이버 버퍼단으로 넘길 때, C++ 엔진은 다음과 같이 메모리를 스캐닝한다.
- 수신 버퍼 포인터 초기화
buffer_ptr = data_start. extract_bits(buffer_ptr, offset, 169)로 헤더 블록에서 마스크 배열 추출.- 마스크 파싱 로직 구현:
_builtin_popcountll(satellite_mask)등의 어셈블리 내장 함수를 호출하여 64비트 정수 안의 1 갯수를 N으로 즉각 산출. - 만들어진 N과 비트폭을 곱해 위성 데이터 블록의 길이를 확정짓고, 여기서부터 M개의 신호 로직을 다시 순회 탐색(Cursor traversal)한다.
- 최종 추출된 정수형 Delta 값들에 Scale Factor(예: 2^{-24}, 2^{-29} 등)를 곱해 절대적인
float/double형식의 위상, 거리 데이터 구조체(sensor_gps_s등) 내부에 차곡차곡 할당.
데이터 통신에서 비효율을 제거하기 위한 이러한 낭비 없는 매핑 사상은 극도로 보수적인 항공 시스템의 내결함성(Fault Tolerance)을 달성하는 기저 원리이다. 이는 또한 C언어의 포인터 오프셋 연산이 PX4 생태계 내에서 여전히 가장 중요한 소프트웨어 기술 요소 중 하나임을 증명한다.