13.5.2. PX4 내부 uORB 기반 데이터 라우팅 파이프라인 및 드라이버 주입 로직

13.5.2. PX4 내부 uORB 기반 데이터 라우팅 파이프라인 및 드라이버 주입 로직

무선 텔레메트리(Telemetry)를 뚫고 쏟아져 들어온 MAVLink 패킷 덩어리가 비행 제어기(FC)의 하드웨어 직렬 수신 핀(RX)에 도달했다고 해서 끝이 아니다. PX4-Autopilot의 운영체제(NuttX RTOS) 안에는 MAVLink 스택, 센서 퓨전(EKF2) 코어, 그리고 무수한 백그라운드 드라이버들이 거미줄처럼 얽혀 있다.

이 복잡성 속에서, QGroundControl(QGC)이 쏘아 올린 조각난 RTCM 보정 데이터(GPS_RTCM_DATA, ID 233)를 오직 GPS 드라이버 프로세스만이 조용히 낚아채어 물리적인 GPS 모듈 포트(예: UART4)로 밀어 넣어야 한다. 이 무정지(Non-stop), 무지연(Zero-latency) 라우팅을 가능하게 하는 PX4의 핵심 혈관이 바로 uORB (Micro Object Request Broker) 미들웨어이다.

본 절에서는 MAVLink Receiver 모듈에서 촉발된 RTCM 데이터가 uORB 토픽(gps_inject_data)이라는 혈관을 타고 넘어가, 최종적으로 gps 하드웨어 데몬 스레드의 파일 디스크립터(File Descriptor) 쓰기(Write) 호출에 의해 칩셋 내부에 주입(Injection)되기까지의 C++ 콜스택(Call stack) 파이프라인을 해부한다.

1. uORB 미들웨어의 중재자(Broker) 역할

PX4 아키텍처의 철저한 객체 지향적(Object-Oriented) 비동기 통신 철학에 따라, MAVLink 수신 모듈(mavlink_receiver)과 GPS 구동 모듈(gps)은 서로의 존재를 알지 못한다. 즉, 직접적인 전역 변수 참조나 함수 호출(Function Call)로 묶여 있지 않고, 독립된 프로세스(Task) 혹은 워크 큐(Work Queue) 스레드로 각자 작동한다.

  • 퍼블리셔 (Publisher): mavlink_receiver는 텔레메트리 포트에서 GPS_RTCM_DATA 패킷을 읽자마자 그 찌꺼기 없는 알맹이(180 \text{ bytes})를 떼어내어 uORB의 gps_inject_data 토픽(주제)으로 ’무작정 발행(Publish)’한다.
  • 서브스크라이버 (Subscriber): gps 드라이버는 기체가 부팅될 때부터 gps_inject_data 토픽의 변경 사항을 수 밀리초 단위로 엿보는 ‘구독(Subscribe)’ 대기 상태에 빠져 있다.

이 Publish-Subscribe 패턴은 RTCM 데이터의 도착 빈도가 불규칙하거나 무선 모뎀의 통신 장애로 끊어지더라도, 양측 모듈 중 어느 한쪽이 교착 상태(Deadlock)에 빠지는 것을 막아주는 완벽한 아이솔레이션(Isolation) 효과를 제공한다.

2. 드라이버 주입(Injection) 파이프라인의 3단계 C++ 아키텍처

RTCM 통신의 성패를 가르는 PX4의 아키텍처 파이프라인은 크게 세 부분으로 나열될 수 있다.

2.1 Phase 1: MAVLink 역단편화와 uORB 구조체 매핑

MavlinkReceiver::handle_message_gps_rtcm_data() 메서드에서 개시된다. 무선 규격을 통과하기 위해 포장되었던 MAVLink C 구조체(mavlink_gps_rtcm_data_t) 안의 180\text{ bytes} 페이로드 길이를 검사하고, 이 데이터를 정확히 동일한 바이트 구조를 가진 uORB 메시지 구조체인 gps_inject_data_s 배열로 옮겨 담는다. 그리고 orb_publish() 호출을 통해 NuttX 커널(Kernel)의 내부 버퍼에 이 조각을 띄운다.

2.2 Phase 2: gps_inject_data_s 링 버퍼링(Ring Buffering)

RTCM 조각은 1초에도 수십 개씩(1~4KB / 180bytes = 약 20회) 쏟아진다. 만약 GPS 드라이버 스레드가 다른 센서를 세팅하느라 단 1\text{ms} 라도 처리가 늦어지면 이 퍼블리싱 데이터는 곧바로 덮어씌워져 유실된다.
이를 방지하기 위해 uORB는 내부적으로 큐 크기(Queue Size)가 확장된 링 버퍼(Ring Buffer)를 동적으로 할당하여 수신된 패킷들을 쌓아놓고(FIFO), 락-프리(Lock-free) 알고리즘 혹은 포직스(POSIX) 세마포어(Semaphore)를 통해 안전하게 교통 정리를 수행한다.

2.3 Phase 3: GPS 인터페이스 (UART/CAN 기반 write 동작)

구독자인 gps 데몬 스레드는 uORB의 링 버퍼에서 gps_inject_data 덩어리들을 뽑아낸다(Pop/Copy).
데이터를 건진 드라이버는 이 C 배열 뭉치를 UBXNMEA 프로토콜 해석기(Parser)를 돌리지 않고 블랙박스(Blackbox) 취급한다. 오직 OS 레벨 시스템 콜인 ::write(_serial_fd, _inject_data.data, _inject_data.len) 함수를 직렬 포트에 호출하여 베어메탈(Bare-metal) 수준에서 GPS 수신기 핀으로 맹렬하게 부어넣는다(Inject).

3. 요약: 무감각한 로직의 위대함

PX4의 RTCM 라우팅 파이프라인 소스코드를 분석해 보면, 개발진은 이 데이터가 ’수학적으로 얼마나 정교한 반송파 보정 방정식’을 담고 있는지 전혀 관심을 가지지 않는다. 오로지 들어온 바이트 배열(Byte Array) 덩어리를 얼마나 빠르고 훼손 없이(Without Memory Corruption), 그리고 다른 EKF2 스레드를 블로킹(Blocking)하지 않고 하드웨어 포트 끝단까지 배달할 것인가 하는 순수 네트워크 보급망 최적화 관점에만 집중하고 있다.

이와 같은 “무지(Ignorance)를 가정한 파이프라인” 지연이 극도로 억제되어 설계되었기에, 사용자는 QGC 펌웨어 업데이트 없이도 최신 RTCMv3 규격이나 MSM 다중 위성 보증 규격 모델을 자유자재로 변경해 가며 드론에 주입할 수 있는 강력한 하방 호환성(Backward Compatibility)을 누릴 수 있다.