현대 자율 시스템, 특히 드론과 같은 고성능 로봇의 핵심에는 복잡하고 다양한 소프트웨어 구성 요소 간의 원활하고 신뢰할 수 있는 통신을 보장하는 강력한 메시징 시스템이 자리 잡고 있습니다. 오픈 소스 자동 조종 장치 소프트웨어인 PX4에서 이 중추적인 역할은 uORB(마이크로 객체 요청 브로커)라는 이름의 미들웨어가 수행합니다. uORB는 단순히 PX4의 여러 기능 중 하나가 아니라, PX4의 핵심 설계 철학에서 비롯된 필연적인 아키텍처적 결과물입니다. 이 섹션에서는 uORB의 존재 이유를 탐구하고, PX4의 근본적인 설계 원칙이 어떻게 uORB와 같은 전문화된 고성능 메시징 계층을 필요로 하는지 분석합니다.
PX4의 시스템 설계는 근본적으로 “반응형(reactive)” 모델을 따릅니다.1 이 철학은 시스템의 모든 기능이 상호 교환 가능한 독립적인 구성 요소로 분할되고, 이들 간의 통신은 비동기적 메시지 전달을 통해 이루어지며, 시스템 전체가 가변적인 작업 부하를 효과적으로 처리할 수 있도록 설계되었음을 의미합니다. 이러한 반응형 모델은 현대 비행 제어기의 복잡성을 관리하기 위한 전략적 선택입니다. 단일체(monolithic) 설계와 달리, 이 접근 방식은 모듈성, 재사용성, 그리고 병렬성을 극대화합니다.
비동기 메시징은 이 아키텍처의 핵심입니다. 각 작업이 다른 작업을 차단(blocking)하는 것을 방지함으로써, 고주파 센서 데이터를 처리하고, 제어 루프를 실행하며, 외부 통신을 관리하는 등 여러 작업을 동시에 수행해야 하는 실시간 시스템의 필수 요건을 충족시킵니다. 한 모듈이 다른 모듈의 완료를 기다리며 멈추는 대신, 메시지를 발행하고 즉시 다음 작업으로 넘어갈 수 있습니다. 데이터를 필요로 하는 모듈은 메시지가 도착했을 때 비동기적으로 처리합니다. 이러한 구조는 시스템의 응답성을 보장하고, 특정 작업의 지연이 전체 시스템의 안정성에 치명적인 영향을 미치는 것을 방지합니다.
더 나아가, 이 모듈성은 런타임 중에도 구성 요소를 교체할 수 있는 강력한 유연성을 제공합니다.1 예를 들어, 연구자는 표준 EKF2(확장 칼만 필터) 상태 추정기를 자신이 개발한 새로운 알고리즘으로 교체하고자 할 때, 전체 펌웨어를 재설계할 필요가 없습니다. 새로운 추정기 모듈이 기존의 센서 토픽을 구독하고 동일한 형식의 자세 및 위치 추정 토픽을 발행하기만 하면, 시스템의 다른 부분(예: 제어기, 내비게이터)은 아무런 변화 없이 새로운 추정치를 기반으로 작동합니다. 이는 전체 코드베이스에 대한 깊은 이해 없이도 특정 구성 요소를 수정하고 테스트할 수 있게 하여, 연구 및 신속한 프로토타이핑의 진입 장벽을 극적으로 낮춥니다.
이러한 반응형 아키텍처를 실현하는 기술적 기반이 바로 uORB입니다. uORB(micro Object Request Broker)는 PX4 내에서 스레드 간(inter-thread) 및 프로세스 간(inter-process) 통신을 위해 사용되는 비동기 발행/구독(publish/subscribe) 메시징 API입니다.3 그 이름에서 알 수 있듯이, uORB의 역할은 서로 다른 소프트웨어 모듈 간의 데이터 객체(메시지)에 대한 요청을 중개하는 것입니다. 접두사 “마이크로(micro)”는 이 시스템이 마이크로컨트롤러(MCU)와 같이 자원이 제한된 환경을 위해 특별히 설계되었음을 강조합니다.
uORB는 uorb 모듈로 구현되며, PX4의 부팅 시퀀스 초기에 uorb start 명령을 통해 자동으로 시작됩니다.3 부팅 스크립트(rcS)에서 이처럼 조기에 초기화되는 이유는 PX4의 거의 모든 핵심 애플리케이션이 uORB에 의존하기 때문입니다.3 상태 추정기, 제어기, 내비게이터, 커맨더 등 비행에 필수적인 모듈들은 uORB 없이는 서로 데이터를 교환할 수 없으며, 결과적으로 시스템 전체가 작동 불능 상태에 빠지게 됩니다. 따라서 uORB는 PX4 아키텍처의 가장 기초적인 구성 요소이자, 모든 데이터 흐름이 시작되는 중심 허브라고 할 수 있습니다.
uORB의 기능은 네 가지 핵심 개념, 즉 메시지(Message), 토픽(Topic), 모듈(Module), 그리고 발행/구독(Publish/Subscribe) 패턴을 기반으로 구축됩니다.6 이러한 기본 요소들은 개발자에게 명확하고 효과적인 추상화 계층을 제공하며, 복잡한 시스템을 이해하고 관리하기 쉽게 만듭니다. 이를 레스토랑 운영에 비유하여 설명할 수 있습니다.6
모듈(Module): 모듈은 특정 작업을 수행하는 독립적이고 자족적인 기능 단위입니다. 예를 들어, attitude_estimator는 센서 데이터를 기반으로 기체의 자세를 추정하고, position_controller는 목표 위치와 현재 위치를 비교하여 기체를 이동시키기 위한 제어 명령을 생성합니다. 레스토랑 비유에서 모듈은 주방장, 웨이터, 고객과 같은 개별적인 행위자에 해당합니다.6 각 모듈은 자신에게 할당된 명확한 역할과 책임을 가집니다.
메시지(Message): 메시지는 모듈 간에 교환되는 데이터의 구조를 정의합니다. 이는 언어의 문법이나 레스토랑의 주문서 양식과 유사합니다.6 예를 들어,
sensor_combined 메시지는 특정 시점의 가속도계 및 자이로스코프 측정값을 담는 필드들로 구성됩니다. 모든 메시지는 데이터의 형식과 내용을 명확하게 규정하여, 데이터를 보내는 모듈과 받는 모듈이 동일한 방식으로 정보를 해석할 수 있도록 보장합니다.
토픽(Topic): 토픽은 특정 유형의 메시지가 전달되는 명명된 통신 채널 또는 “깔때기”입니다.3 모듈은 특정 토픽에 메시지를 발행(publish)하고, 다른 모듈들은 해당 토픽을 구독(subscribe)하여 메시지를 수신합니다. 예를 들어, 센서 드라이버는
sensor_combined 토픽에 측정값을 발행하고, attitude_estimator 모듈은 이 토픽을 구독하여 데이터를 받아 자세 추정에 사용합니다. 레스토랑 비유에서 ‘파스타 주문’이라는 토픽은 고객의 주문 메시지를 웨이터에게 전달하는 채널 역할을 합니다.6
발행/구독(Publish/Subscribe): 이 패턴은 uORB 통신의 핵심 메커니즘입니다. 발행자는 구독자가 누구인지 알 필요 없이 단순히 토픽에 메시지를 보냅니다. 구독자는 발행자가 누구인지 알 필요 없이 관심 있는 토픽으로부터 메시지를 받습니다. 이러한 느슨한 결합(loose coupling)은 시스템의 유연성과 확장성을 크게 향상시킵니다. 새로운 모듈(예: 로깅 모듈)이 시스템에 추가될 때, 기존의 발행자나 구독자를 수정할 필요 없이 단지 관심 있는 토픽을 구독하기만 하면 됩니다.
uORB 시스템에서 개발자는 사람이 읽을 수 있는 .msg 파일을 통해 메시지 구조를 정의합니다. 이 파일들은 CamelCase 명명 규칙을 따르며(예: VelocityLimits.msg), uint64_t, float32와 같은 데이터 유형과 필드 이름으로 구성됩니다.4 모든 메시지 정의에는 uint64_t timestamp 필드가 필수로 포함되어야 합니다.4 이 타임스탬프는 로깅 및 데이터 동기화에 매우 중요하며, 서로 다른 센서로부터 들어오는 데이터를 융합하는 EKF와 같은 상태 추정 알고리즘에 필수적인 일관된 시간 기준을 제공합니다.
이렇게 정의된 .msg 파일은 PX4 빌드 프로세스 중에 자동으로 C/C++ 코드로 변환됩니다. msg/CMakeLists.txt 파일에 명시된 지침에 따라, 빌드 시스템은 px_generate_uorb_topic_files.py라는 파이썬 스크립트와 EmPy 템플릿을 호출합니다.7 이 스크립트는 .msg 파일을 파싱하여 해당 메시지에 대한 C struct가 정의된 헤더 파일(.h)과 관련 소스 파일(.cpp)을 자동으로 생성합니다.7
이 자동화된 코드 생성 과정은 PX4 생태계의 개발자 생산성을 높이는 핵심 요소입니다. 개발자는 데이터 구조를 수동으로 만들고 직렬화 코드를 작성하는 지루하고 오류가 발생하기 쉬운 작업을 추상화할 수 있습니다. 단지 간단한 텍스트 파일에 데이터 구조를 정의하기만 하면, 빌드 시스템이 나머지 모든 것을 처리해 줍니다.
.msg 파일은 단순한 데이터 구조 정의 이상의 의미를 가집니다. 이는 시스템의 서로 다른 부분 간의 안정적인 API 계약을 나타냅니다. .msg 파일을 변경하는 것은 해당 토픽을 발행하거나 구독하는 모든 모듈에 영향을 미칠 수 있습니다. 이러한 이유로 PX4는 필드 및 메시지를 더 이상 사용하지 않을 때를 위한 공식적인 절차를 갖추고 있습니다. 사용되지 않는 필드는 # DEPRECATED 주석으로 표시하고, 삭제된 메시지는 msg/CMakeLists.txt의 deprecated_msgs 목록에 추가해야 합니다.4 이 공식적인 절차는 변경 사항을 체계적으로 관리하고 가능한 경우 하위 호환성을 유지하도록 보장합니다. 이는 개발자가 자신의 변경 사항이 시스템 전체에 미치는 영향을 고려하도록 강제하며, uORB 토픽이 단순한 내부 변수가 아니라 안정적이고 버전이 관리되는 인터페이스라는 개념을 강화합니다.
uORB의 아키텍처적 역할과 철학을 이해했다면, 이제 그 작동 방식, 즉 “어떻게”에 대한 심층적인 분석이 필요합니다. 이 섹션에서는 uORB API의 코드 수준 메커니즘과 개발자가 시스템과 상호 작용하는 데 사용하는 도구들을 상세히 살펴봅니다. uORB의 발행, 구독, 그리고 실시간 모니터링 과정은 PX4 모듈 개발의 근간을 이룹니다.
모듈이 토픽에 데이터를 발행하기 전에, 먼저 orb_advertise() 함수를 사용하여 해당 토픽을 발행할 의도가 있음을 “광고(advertise)”해야 합니다.3 이 함수는 orb_advert_t 타입의 핸들을 반환하며, 이 핸들은 이후 orb_publish() 함수를 호출하여 실제 데이터를 전송하는 데 사용됩니다. 광고 단계는 본질적으로 해당 모듈을 특정 토픽의 발행자로 등록하는 일회성 설정 과정입니다. 이 과정을 통해 uORB 시스템은 필요한 내부 데이터 구조를 생성하고 초기화합니다. 중요한 점은, 이 광고 과정은 반드시 인터럽트 컨텍스트 외부에서 이루어져야 한다는 것입니다.5 인터럽트 서비스 루틴(ISR) 내에서는 새로운 토픽을 광고할 수 없습니다.
일단 광고가 완료되면, orb_publish() 호출은 매우 가벼운 작업이 됩니다. 이 함수는 제공된 데이터를 해당 토픽의 공유 버퍼로 복사하는 역할을 합니다. 발행자는 “발사 후 망각(fire-and-forget)” 방식으로 작동하며, 누가 이 데이터를 수신하는지 알 필요 없이 자신의 데이터를 발행합니다.
PX4 시스템은 종종 동일한 유형의 여러 센서를 가질 수 있습니다. 예를 들어, 비행 제어기에는 내장 자력계와 외부 GPS에 연결된 자력계가 모두 있을 수 있습니다. 이러한 경우를 처리하기 위해 uORB는 orb_advertise_multi() 함수를 제공합니다.5 이 함수는 동일한 토픽의 여러 독립적인 “인스턴스(instance)”를 생성할 수 있게 해줍니다. 각 인스턴스는 자체적인 데이터 버퍼를 가집니다. 예를 들어, 두 개의 자력계는 각각 vehicle_magnetometer 토픽의 0번 인스턴스와 1번 인스턴스에 데이터를 발행할 수 있습니다. 그러면 구독자는 orb_subscribe_multi()를 사용하여 특정 인스턴스 또는 모든 인스턴스를 구독하고, 데이터의 상태를 비교하여 가장 신뢰할 수 있는 센서 데이터를 선택할 수 있습니다. 이 다중 인스턴스 기능은 시스템의 견고성과 이중화(redundancy)를 구현하는 데 매우 중요합니다.
모듈이 특정 토픽의 데이터를 수신하려면 orb_subscribe(ORB_ID(topic_name)) 함수를 사용하여 해당 토픽을 구독해야 합니다.3 이 함수는 파일 디스크립터와 유사한 정수 값을 반환하며, 이 값은 이후 해당 구독을 식별하는 데 사용됩니다.
데이터를 구독한 후, 모듈은 새로운 데이터가 발행되었는지 확인해야 합니다. 이는 주로 orb_check() 함수를 호출하거나, 더 일반적인 방법으로 여러 구독을 동시에 대기할 수 있는 px4_poll() 시스템 호출을 사용하여 수행됩니다. px4_poll()은 지정된 구독 중 하나에 새로운 데이터가 도착할 때까지 대기하거나, 타임아웃이 발생하면 반환됩니다.
새로운 데이터가 사용 가능함이 확인되면, 모듈은 orb_copy() 함수를 사용하여 데이터를 검색합니다.3 이 함수는 uORB 구독 모델의 핵심적인 부분으로, 토픽의 공유 버퍼에 있는 데이터를 구독자 모듈의 로컬 구조체로 직접 메모리 복사(memory copy)합니다. 이 작업은 매우 빠르고 원자적(atomic)으로 수행되어, 구독자가 무거운 동기화 프리미티브(예: 뮤텍스) 없이도 일관된 데이터 스냅샷을 얻을 수 있도록 보장합니다. 뮤텍스와 같은 동기화 메커니즘은 발행자를 차단하여 시스템의 실시간 성능을 저해할 수 있으므로, 이를 피하는 것이 중요합니다. 데이터를 자신의 로컬 버퍼로 복사한 후, 구독자는 발행자의 컨텍스트와 완전히 분리된 상태에서 안전하게 데이터를 처리할 수 있습니다.
이러한 발행과 구독 API는 미묘하지만 중요한 비대칭성을 드러냅니다. 발행자의 주된 역할은 orb_publish()를 호출하는 것으로, 이는 매우 빠른 “발사 후 망각” 작업입니다. 반면, 구독자는 더 많은 책임을 가집니다. 새로운 데이터를 확인(orb_check())하고 복사(orb_copy())해야 합니다. 이 설계는 데이터 관리의 부담을 수신자에게 두어, 느린 구독자가 고주파 발행자를 차단하거나 지연시키는 것을 방지합니다. 발행자는 자신의 고유한 속도로 토픽을 계속 업데이트할 수 있으며, 구독자는 자신에게 적합한 속도로 데이터를 샘플링할 수 있습니다. 이러한 분리는 전체 시스템의 실시간 성능을 유지하는 데 필수적입니다.
PX4 시스템 콘솔, 즉 NuttX 셸(NSH)은 uORB를 디버깅하고 모니터링하기 위한 강력한 명령줄 도구 모음을 제공합니다. 이러한 내부 검사(introspection) 도구는 개발자에게 시스템 내부에서 데이터가 어떻게 흐르는지에 대한 귀중한 통찰력을 제공합니다.
ls /obj: 이 명령어는 현재 활성화된 모든 uORB 토픽 노드를 나열합니다.5 uORB 토픽이 가상 파일 시스템(
/obj/) 내의 디바이스 노드로 표현되기 때문에, 표준 파일 목록 명령어인 ls를 사용하여 모든 토픽의 존재 여부를 확인할 수 있습니다. 이는 uORB가 기본 운영 체제(NuttX)의 파일 시스템 추상화를 영리하게 활용하고 있음을 보여줍니다. 이 설계 덕분에 개발자는 친숙한 POSIX 스타일의 개념을 통해 메시징 시스템과 상호 작용할 수 있으며, 표준 셸 명령어로 시스템 상태를 쉽게 탐색할 수 있어 디버깅이 크게 간소화됩니다.
uorb top: 이 명령어는 모든 토픽의 상태를 실시간으로 보여주는 top과 유사한 유틸리티입니다.5 출력에는 각 토픽의 발행 빈도(Hz), 구독자 수, 그리고 초당 손실된 메시지 수가 포함됩니다.
uorb top은 성능 문제를 진단하는 첫 번째 방어선입니다. 예를 들어, 핵심 센서 토픽의 발행 빈도가 갑자기 떨어지거나 메시지 손실 수가 증가한다면, 이는 특정 프로세스가 CPU를 과도하게 사용하고 있거나 드라이버에 오류가 발생했음을 즉시 알려주는 신호입니다.
listener <topic_name> [num_messages]: 이 명령어는 특정 토픽에서 발행되는 메시지의 내용을 실시간으로 출력합니다.5 개발자는 이 명령어를 사용하여 시스템을 통해 흐르는 원시 데이터를 직접 확인할 수 있으며, 이를 통해 모듈이 올바른 값을 생성하고 소비하는지 검증할 수 있습니다.
printf와 같은 디버깅 문을 코드에 추가하면 시스템 타이밍이 변경되어 문제를 파악하기 어려워질 수 있지만, listener는 이러한 부작용 없이 데이터를 관찰할 수 있게 해줍니다. 특히 강력한 기능은 이 명령어가 QGroundControl의 MAVLink 콘솔을 통해 무선으로도 사용될 수 있다는 점입니다. 즉, 기체가 비행 중인 상태에서도 원격으로 시스템 내부의 데이터 흐름을 모니터링할 수 있어 현장 테스트 및 디버깅에 매우 유용합니다.
PX4 소스 코드에 포함된 px4_simple_app 예제는 uORB 개발의 전체 과정을 보여주는 완벽한 “Hello, World!”입니다.3 이 애플리케이션은 uORB API의 핵심 기능들을 실제로 어떻게 사용하는지 명확하게 보여줍니다.
orb_subscribe()를 사용하여 sensor_combined 토픽을 구독합니다.px4_poll()을 사용하여 새로운 센서 데이터가 도착하기를 기다립니다.orb_copy()를 사용하여 데이터를 로컬 구조체로 복사합니다.orb_advertise()를 사용하여 vehicle_attitude 토픽을 발행할 것임을 광고합니다.vehicle_attitude 구조체를 채운 다음, orb_publish()를 사용하여 이 새로운 데이터를 토픽에 발행합니다.이 예제의 코드를 따라가 보면, 신규 개발자는 거의 모든 PX4 모듈의 기초를 형성하는 “구독-처리-발행”의 기본 패턴과 uORB API 함수들의 실제 사용법을 명확하게 이해할 수 있습니다.
uORB의 API와 메커니즘을 이해하는 것을 넘어, 실제 환경에서의 성능을 비판적으로 평가하는 것이 중요합니다. 이 섹션에서는 uORB의 지연 시간, 처리량, 그리고 하드웨어 실시간 제어 루프에 대한 적합성을 분석합니다. uORB의 성능은 PX4가 비행 중에 안정성을 유지하고 명령에 신속하게 반응하는 능력과 직결됩니다.
uORB 통신은 공유 메모리(shared memory)를 기반으로 합니다.2 전체 PX4 미들웨어는 단일 주소 공간에서 실행되므로, 모든 모듈 간에 메모리가 공유됩니다. 이는 uORB의 고성능을 뒷받침하는 가장 중요한 설계적 결정입니다. 커널 수준의 데이터 복사나 네트워크 스택을 거치지 않기 때문에, orb_publish()와 orb_copy()는 사실상 직접적인 메모리 연산에 가깝습니다. 그 결과, 지연 시간은 마이크로초 단위로 극히 낮고 처리량은 매우 높습니다.
이러한 공유 메모리 접근 방식은 uORB가 비행 제어기의 심장부인 긴밀하고 고주파수의 ‘센서-추정기-제어기’ 데이터 경로에 완벽하게 적합한 이유입니다. 예를 들어, sensor_combined와 같은 핵심 센서 토픽은 일반적으로 약 250Hz의 주기로 발행됩니다.9 EKF의 바이어스 보정과 필터링을 거친 vehicle_acceleration 토픽 역시 빠른 제어 루프에 적합한 고속 데이터입니다.10 이러한 고속 데이터 스트림이 최소한의 지연으로 처리될 수 있는 것은 전적으로 공유 메모리 아키텍처 덕분입니다.
uORB의 높은 성능은 특정 문제 영역에 대한 전문화된 도구로서의 역할을 명확히 보여줍니다. uORB는 단일 주소 공간을 사용함으로써 속도를 얻지만, 이는 동시에 중요한 제약 조건이 됩니다.2 즉, uORB는 그 자체만으로는 서로 다른 프로세스 간이나 네트워크를 통해 컴패니언 컴퓨터와 통신할 수 없습니다. 이는 결함이 아니라 의도적인 설계 선택입니다. uORB는 비행 제어기 내부의 초저지연 통신이라는 가장 중요한 문제를 해결하기 위해 최적화되었습니다. 이러한 전문성이 바로 외부 통신을 위해 uXRCE-DDS 브리지와 같은 별도의 복잡한 메커니즘이 필요한 이유이며, 이 주제는 다음 섹션에서 자세히 다룰 것입니다.
uORB 메커니즘 자체는 매우 가볍게 설계되었지만, 이를 사용하는 모듈들은 상당한 CPU 부하를 유발할 수 있습니다. 개발자가 “더 빠른 반응”을 위해 제어 루프의 발행 빈도를 250Hz에서 400Hz로 높이려는 시도는 CPU 사용률에 큰 영향을 미칠 수 있습니다.9 만약 총 CPU 부하가 마이크로컨트롤러의 처리 용량을 초과하면, 작업의 마감 시간(deadline)을 놓치게 되어 지터(jitter)가 발생하고 잠재적으로 시스템 불안정을 초래할 수 있습니다.
따라서 모듈의 성능을 측정하고 최적화하는 것이 중요합니다. PX4는 이를 위해 성능 카운터(perf counters)를 제공합니다. 개발자 포럼에서 언급된 바와 같이, 성능 카운터를 사용하여 특정 모듈의 실행 시간을 정밀하게 측정할 수 있습니다.11 이를 통해 개발자는 자신의 제어 루프가 할당된 시간 내에 완료될 수 있는지 확인하고, 시스템 전체의 CPU 부하를 관리할 수 있습니다. uORB 자체의 오버헤드는 낮지만, 시스템의 전체적인 성능은 각 모듈의 효율성에 크게 좌우됩니다.
드론의 효과적인 성능은 시스템 수준의 속성이지, 단일 구성 요소의 속성이 아닙니다. 단지 uORB의 속도에만 초점을 맞추는 것은 오해의 소지가 있습니다. 예를 들어, 개발자는 sensor_combined가 250Hz로 발행되는 것을 보고 이것이 시스템의 반응 시간이라고 가정할 수 있습니다. 그러나 다른 자료에 따르면, 제어 루프에서 사용되는 vehicle_acceleration은 EKF 바이어스 보정 및 필터링을 거치기 때문에 sensor_combined에 비해 약간의 지연 시간을 가집니다.10 이는 종단 간(end-to-end) 지연 시간이 여러 uORB 토픽과 처리 모듈을 거치면서 누적된다는 것을 보여줍니다. 포럼에서 언급된 “지연(lag)” 9은 바로 이 누적된 종단 간 지연 시간을 의미합니다. 따라서 시스템을 최적화하려면 uorb top이나 성능 카운터와 같은 도구를 사용하여 메시징 계층뿐만 아니라 전체 데이터 처리 체인에서 병목 현상을 식별하는 전체적인 시각이 필요합니다.
uORB는 진공 상태에서 작동하지 않습니다. 그 실시간 성능은 기반이 되는 실시간 운영 체제(RTOS), 즉 NuttX와 본질적으로 연결되어 있습니다. PX4는 POSIX API와 FIFO와 같은 실시간 스케줄링을 제공하는 운영 체제에서 실행되도록 설계되었습니다.2 좋은 제어 응답의 핵심은 단순히 루프 속도를 높이는 것이 아니라, 센서 입력에서 모터 출력까지의 지연 시간(lag)을 최소화하는 것입니다.9
RTOS 스케줄러는 센서 처리 및 자세 제어 루프와 같은 고우선순위 작업이 예측 가능하게 실행되고 마감 시간을 준수하도록 보장하는 책임을 집니다. uORB의 비동기적이고 비차단적인 특성은 RTOS 스케줄러와 조화롭게 작동하도록 설계되었습니다. uORB 토픽을 기다리는 모듈은 스케줄러에 의해 휴면 상태로 전환되어 다른 작업에 CPU를 양보할 수 있으며, 데이터가 도착하면 즉시 깨어납니다. 이는 바쁜 대기(busy-waiting)로 인한 CPU 사이클 낭비를 방지하고 전체 시스템의 지터(실행 시간의 변동성)를 줄입니다. 결국, 종단 간 지연 시간을 최소화하는 것이 궁극적인 목표이며, 이는 효율적인 메시징(uORB)과 효과적인 스케줄링(NuttX)의 결합을 통해 달성됩니다.
uORB가 PX4 내부의 효율적인 통신을 담당한다면, 현대 드론 애플리케이션의 복잡성은 종종 비행 제어기(FCU)의 처리 능력을 넘어서는 연산을 요구합니다. 컴퓨터 비전, SLAM(동시적 위치추정 및 지도작성), 복잡한 경로 계획과 같은 작업은 더 강력한 컴패니언 컴퓨터로 오프로드되어야 합니다. 이를 위해 FCU의 uORB 세계와 외부 로보틱스 생태계, 특히 ROS 2(Robot Operating System 2)를 연결하는 강력하고 안정적인 다리가 필요합니다. 이 섹션에서는 uORB와 ROS 2를 잇는 uXRCE-DDS 브리지의 아키텍처, 데이터 흐름, 그리고 설정 방법을 상세히 분석합니다.
전통적으로 PX4와 외부 시스템 간의 통신은 MAVLink 프로토콜을 통해 이루어졌습니다. MAVLink는 지상 관제소(GCS)와의 텔레메트리 교환이나 고수준 명령 전송에는 탁월하지만, 몇 가지 한계가 있습니다. 특히, 새로운 맞춤형 메시지를 추가하거나 수정하는 작업이 복잡하고, 실시간 제어를 위한 고주파 데이터 스트림을 처리하기에는 설계적으로 적합하지 않습니다.12
이러한 한계를 극복하고 컴패니언 컴퓨터에서 실행되는 고급 기능을 PX4와 긴밀하게 통합하기 위해 ROS 2와의 연동이 새로운 길을 열었습니다. ROS 2는 uORB 메시지에 직접 접근하여 PX4의 기능을 확장할 수 있는 가능성을 제공합니다.14 이를 실현하는 것이 바로 uXRCE-DDS 브리지입니다. 이 브리지는 비행 제어기와 오프보드 구성 요소 간에 시간에 민감한 정보를 안정적으로 공유해야 할 때 사용되며, 컴패니언 컴퓨터의 소프트웨어가 PX4 내부의 모듈과 동등한 “피어(peer)”가 될 수 있도록 합니다.13
uXRCE-DDS 미들웨어는 자원이 제한된 장치를 더 큰 네트워크에 통합하기 위한 전형적인 클라이언트-에이전트 아키텍처를 따릅니다. 이 구조는 PX4에서 실행되는 uxrce_dds_client와 컴패니언 컴퓨터에서 실행되는 micro XRCE-DDS agent로 구성됩니다. 이 둘은 시리얼(UART) 또는 UDP 링크를 통해 데이터를 교환합니다.15
uxrce_dds_client on PX4): 이는 PX4 펌웨어 내에서 실행되는 가벼운 데몬 프로세스입니다. 클라이언트의 주된 역할은 특정 uORB 토픽을 구독하고, 수신한 메시지를 직렬화(serialize)하여 물리적 링크를 통해 에이전트에게 전송하는 것입니다. 반대 방향으로는 에이전트로부터 직렬화된 데이터를 수신하여 역직렬화(deserialize)한 후, 이를 해당하는 uORB 토픽에 발행합니다. 클라이언트는 DDS 네트워크의 복잡한 세부 사항(예: 노드 발견, QoS 관리)으로부터 격리되어, 오직 데이터 송수신에만 집중합니다.micro XRCE-DDS agent on Companion Computer): 이는 컴패니언 컴퓨터에서 실행되는 더 비중 있는 프로세스입니다. 에이전트는 클라이언트의 프록시(proxy) 역할을 수행합니다. 클라이언트로부터 데이터를 수신하여 역직렬화한 후, 이를 표준 ROS 2/DDS 토픽으로 (재)발행하여 ROS 2 생태계에 노출시킵니다. 반대 방향으로는 특정 ROS 2 토픽을 구독하고, 수신한 데이터를 직렬화하여 클라이언트에게 전달합니다. 즉, 에이전트는 DDS의 노드 발견, 통신 설정, QoS 정책 관리 등 복잡한 작업을 처리하여, 자원이 제한된 FCU의 부담을 덜어줍니다.이러한 구조는 PX4가 표준 DDS 기반 브리지(DDS-XRCE는 제한된 장치를 위한 공식 OMG 표준임)를 채택함으로써 주류 로보틱스 커뮤니티와 깊이 있게 정렬하려는 전략적 결정을 반영합니다. 이는 이전의 비표준적인 Fast-RTPS 브리지에서 벗어나 16, 더 넓은 DDS 및 Micro-ROS 생태계의 도구와 발전을 활용할 수 있게 하여 장기적인 호환성과 확장성을 보장합니다.20 이는 PX4가 고립된 비행 스택이 아닌, 더 큰 로봇 시스템의 완전한 실시간 구성 요소로서의 미래를 보고 있음을 시사합니다.
uORB 메시지와 ROS 2 토픽 간의 원활한 변환은 빌드 시점의 코드 생성과 명시적인 설정 파일을 통해 이루어집니다.
PX4 펌웨어가 빌드될 때, uxrce_dds_client가 함께 생성됩니다. 이때 코드 생성기는 dds_topics.yaml이라는 설정 파일에 명시된 uORB 토픽 목록을 참조하여 해당 토픽들을 처리하는 코드를 클라이언트에 포함시킵니다.15
dds_topics.yaml 파일은 uORB 토픽과 ROS 2 토픽 간의 매핑을 정의하며, 데이터의 방향(PX4에서 발행하는 publication 또는 PX4가 구독하는 subscription)과 ROS 2 토픽의 네임스페이스(일반적으로 PX4에서 나가는 데이터는 /fmu/out/, 들어오는 데이터는 /fmu/in/)를 지정합니다.15
한편, 컴패니언 컴퓨터의 ROS 2 애플리케이션은 px4_msgs라는 패키지를 포함하는 작업 공간에서 빌드되어야 합니다. 이 패키지에는 PX4의 .msg 파일과 일치하도록 자동으로 생성된 ROS 2 메시지 정의가 포함되어 있어, 양측 간의 데이터 타입 호환성을 보장합니다.14
이러한 메커니즘을 통해 데이터는 다음과 같이 흐릅니다:
vehicle_odometry uORB 토픽에 데이터를 발행합니다.dds_topics.yaml에 따라 이 토픽을 구독하도록 설정된 uxrce_dds_client가 이 메시지를 수신합니다./fmu/out/vehicle_odometry라는 ROS 2 토픽에 발행합니다./fmu/in/offboard_control_mode 토픽에 데이터를 발행합니다.offboard_control_mode uORB 토픽에 발행합니다.commander 모듈이 이 명령을 수신하여 해당 동작을 수행합니다.이 uXRCE-DDS 브리지는 단순한 데이터 파이프 이상의 역할을 합니다. dds_topics.yaml 파일은 제어된 게이트웨이 역할을 하여, 100개가 넘는 uORB 토픽 중 오프보드 애플리케이션에 필수적인 일부만을 선택적으로 노출합니다. 이는 비행에 중요한 도메인과 상위 수준의 로보틱스 도메인 간의 “API 표면”을 명확하게 정의하는 보안 및 성능상의 조치입니다. 불필요한 데이터로 컴패니언 컴퓨터가 과부하되는 것을 방지하고, 특정 토픽만 FCU로 주입되도록 허용하여 시스템의 안정성을 높입니다.
uXRCE-DDS 브리지를 실제 하드웨어에 배포하는 과정은 유연한 설정 옵션을 통해 지원됩니다.
UXRCE_DDS_* 접두사를 가진 파라미터들을 통해 설정됩니다. UXRCE_DDS_CFG 파라미터를 사용하여 통신에 사용할 포트(예: TELEM2 시리얼 포트, Ethernet)를 지정할 수 있습니다. UDP를 사용하는 경우, UXRCE_DDS_AG_IP와 UXRCE_DDS_PRT 파라미터를 통해 에이전트의 IP 주소와 포트 번호를 설정합니다.15MicroXRCEAgent udp4 -p 8888.17이러한 설정 방식은 다양한 배포 시나리오를 가능하게 합니다. 실험실 환경에서는 USB-to-Serial 어댑터를 사용한 유선 연결이 편리할 수 있으며, 실제 비행 환경에서는 비행 제어기와 컴패니언 컴퓨터 간의 고속 Wi-Fi 링크(UDP)가 일반적으로 사용됩니다. 개발자는 자신의 하드웨어 구성에 맞게 브리지 설정을 쉽게 조정할 수 있습니다.
현대 드론 시스템 아키텍처는 단일 통신 프로토콜에 의존하지 않습니다. 대신, 각기 다른 목적과 제약 조건에 최적화된 여러 프로토콜이 상호 보완적으로 사용됩니다. uORB, MAVLink, 그리고 ROS 2/DDS는 정교한 자율 드론에서 가장 중요한 세 가지 통신 방식입니다. 이들을 경쟁 관계로 보는 것은 흔한 오해이며, 실제로는 각자의 역할과 영역이 명확히 구분된 보완적인 스택을 형성합니다. 이 섹션에서는 이 세 가지 프로토콜을 전략적 관점에서 비교 분석하여, 그들의 고유한 역할과 설계상의 트레이드오프를 명확히 합니다.
각 프로토콜은 특정 통신 문제 해결을 위해 설계되었습니다.
이러한 아키텍처적 차이는 실제 성능에서 명확한 차이를 만들어냅니다. MAVLink 기반의 MAVROS 브리지와 MicroXRCE-DDS 기반 브리지를 비교한 한 연구는 이러한 차이를 정량적으로 보여줍니다.12
정교한 자율 드론 시스템에서 이 세 프로토콜은 다음과 같이 상호 보완적인 스택을 형성하며 시너지를 창출합니다.
mavlink 모듈이 vehicle_status, vehicle_attitude와 같은 주요 uORB 토픽을 구독하고, 이 데이터를 MAVLink 메시지로 패키징하여 무선 텔레메트리를 통해 GCS로 전송합니다.uxrce_dds_client 모듈이 vehicle_odometry와 같은 고주파 uORB 토픽을 구독하고, 이 데이터를 DDS 브리지를 통해 컴패니언 컴퓨터로 전송합니다.TrajectorySetpoint)을 DDS 브리지를 통해 전송합니다. 이 데이터는 FCU에서 uORB 토픽으로 발행되고, PX4의 위치 제어기가 이를 구독하여 기체를 제어합니다.이처럼 각 프로토콜은 자신이 가장 잘 할 수 있는 역할을 수행하며, 전체 시스템의 견고성과 성능을 극대화합니다.
시스템 아키텍트가 특정 데이터 통신 경로에 적합한 프로토콜을 신속하게 선택할 수 있도록, 다음 표는 세 프로토콜의 주요 특징과 트레이드오프를 요약합니다.
| 특징 | uORB | MAVLink | ROS 2/DDS (브리지 경유) |
|---|---|---|---|
| 주요 사용 사례 | FCU 내부의 실시간 모듈 간 통신 | GCS 및 저대역폭 주변 장치와의 통신 | FCU와 고성능 컴패니언 컴퓨터 간의 통신 |
| 아키텍처 | 발행/구독 (단일 주소 공간) | 점대점 메시징 프로토콜 | 발행/구독 (분산 네트워크) |
| 전송 방식 | 공유 메모리 | 직렬, UDP, TCP | UDP, TCP, 직렬 (클라이언트-에이전트 간) |
| 일반적 지연 시간 | 극히 낮음 (<10μs) | 높음 (수십-수백 ms) | 낮음 (수백 μs - 수 ms) |
| 실시간 성능 | 하드 실시간에 적합 | 소프트 실시간/비실시간 | 소프트 실시간에 적합 |
| 자원 오버헤드 | 매우 낮음 | 낮음 (저사양 장치에 최적화) | 중간 (네트워크 스택 및 DDS 오버헤드 포함) |
| 확장성 | 맞춤형 메시지 정의 용이 | 맞춤형 메시지 정의 복잡 | ROS 2 생태계와 완벽히 통합, 확장 용이 |
| 핵심 강점 | 최고의 성능과 낮은 지연 시간 | 표준화, 단순성, 저대역폭 링크에서의 견고성 | 유연성, 강력한 도구, 로보틱스 생태계 통합 |
본 보고서는 PX4의 uORB 메시징 패브릭에 대한 심층적인 분석을 제공했습니다. uORB의 아키텍처적 필연성부터 시작하여, 핵심 메커니즘, 성능 특성, 그리고 uXRCE-DDS 브리지를 통한 외부 로보틱스 생태계와의 통합까지 다루었습니다. 마지막으로, uORB를 MAVLink 및 DDS와 비교하여 드론 시스템 내에서의 고유한 역할을 명확히 했습니다. 이 마지막 섹션에서는 보고서의 모든 분석 내용을 종합하고, 임베디드 시스템 설계에 대한 더 넓은 결론을 도출하며, 개발자와 시스템 아키텍트를 위한 구체적이고 실행 가능한 권장 사항을 제시합니다.
uORB는 특정하고 제한된 문제 영역을 탁월한 효율성으로 해결하는 고도로 전문화된 미들웨어의 성공적인 사례입니다. uORB의 설계는 네트워크 투명성이나 범용 기능과 같은 특징을 희생하는 대신, FCU 내부 통신이라는 명확한 목표를 위해 성능과 낮은 오버헤드를 최우선으로 고려했습니다. 이러한 전문화는 uORB의 가장 큰 강점입니다. 공유 메모리를 기반으로 한 아키텍처는 다른 어떤 범용 메시징 시스템도 따라올 수 없는 수준의 낮은 지연 시간과 높은 처리량을 보장하며, 이는 비행 안정성을 위한 하드 실시간 제어 루프에 필수적입니다. uORB의 성공은 모든 문제를 해결하려는 단일 미들웨어보다, 특정 문제에 최적화된 전문 도구들의 조합이 더 우수할 수 있음을 보여주는 강력한 증거입니다.
PX4의 uXRCE-DDS 브리지 아키텍처는 Micro-ROS의 아키텍처와 거의 동일합니다. Micro-ROS는 자원이 제한된 마이크로컨트롤러를 위한 ROS 2의 확장으로, NuttX와 같은 RTOS에서 실행되며, 경량 클라이언트, DDS-XRCE 미들웨어, 그리고 호스트 컴퓨터의 에이전트로 구성됩니다.20
이러한 아키텍처적 유사성은 우연이 아닙니다. 이는 임베디드 장치를 ROS 2 생태계에 통합하기 위한 설계 패턴이 자연스럽게 융합되고 있음을 나타냅니다. 이러한 관점에서 볼 때, uORB-to-DDS 브리지를 갖춘 PX4 생태계는 현재 Micro-ROS에서 공식화되고 있는 원칙들의 성숙하고 현장에서 검증된 사실상의 참조 구현(de facto reference implementation)으로 볼 수 있습니다. PX4에서 축적된 교훈과 확립된 설계 패턴은 더 넓은 임베디드 로보틱스 커뮤니티에 귀중한 통찰력을 제공합니다.
미래에는 이 통합이 더욱 긴밀해질 가능성이 높습니다. PX4의 uxrce_dds_client가 완전히 호환되는 Micro-ROS 클라이언트로 발전하여, PX4 기반 비행 제어기가 ROS 2 세계에서 네이티브하고 일급 시민(first-class citizen)으로 자리매김하는 것을 상상할 수 있습니다. 이는 PX4 개발자와 ROS 2 개발자 간의 경계를 허물고, 더욱 강력하고 복잡한 자율 시스템의 개발을 가속화할 것입니다.
본 보고서의 분석을 바탕으로, 견고하고 확장 가능하며 고성능인 드론 시스템을 설계하는 아키텍트를 위해 다음과 같은 세 가지 핵심 전략을 권장합니다.
가이드라인 1: 비행에 중요한 루프는 FCU에 유지하라.
핵심적인 안정성 제어, 자세/위치 제어 루프, 그리고 페일세이프(failsafe) 로직은 항상 uORB를 통해 통신하는 네이티브 PX4 모듈로 구현해야 합니다. 이는 uORB의 실시간 성능을 최대한 활용하고, 컴패니언 컴퓨터와의 연결이 끊어지더라도 기체의 안정성을 보장하는 가장 중요한 원칙입니다. 고수준의 지능이 실패하더라도, 드론은 기본적인 비행 능력을 유지해야 합니다.
가이드라인 2: 텔레메트리 및 고수준 명령에는 MAVLink를 사용하라.
MAVLink는 GCS와의 통신, OSD 데이터 전송, 그리고 간단한 주변 장치 제어와 같은 본래의 목적에 맞게 사용해야 합니다. MAVLink를 통해 고주파의 저지연 데이터를 스트리밍하려는 시도는 피해야 합니다. 이는 프로토콜의 설계 목적에 맞지 않으며, 불필요한 오버헤드와 지연을 유발하여 시스템 성능을 저하시킬 뿐입니다.
가이드라인 3: 오프보드 인텔리전스를 위해 DDS 브리지를 활용하라.
SLAM, 시각-관성 주행 거리 측정(VIO), 복잡한 임무 계획, 객체 탐지 등 상당한 계산 능력을 요구하는 모든 작업은 컴패니언 컴퓨터로 오프로드해야 합니다. 이때, FCU와 컴패니언 컴퓨터 간의 고성능 데이터 링크로 uXRCE-DDS 브리지를 사용하십시오. ROS 2 노드는 고수준의 목표(예: TrajectorySetpoint, VehicleCommand)를 계산하여 PX4로 다시 전송하고, FCU는 이 목표를 받아 저수준의 실행을 담당하도록 설계해야 합니다. 이러한 계층적 접근 방식은 각 하드웨어가 가장 잘하는 작업을 수행하게 하여, 견고하고 확장 가능하며 강력한 자율 시스템을 구축하는 가장 효과적인 방법입니다.
결론적으로, uORB는 PX4의 성공에 있어 핵심적인 역할을 수행하는 정교하고 효율적인 미들웨어입니다. 그 설계 원칙을 이해하고, MAVLink 및 DDS와 같은 다른 프로토콜과의 관계 속에서 그 역할을 명확히 파악하며, 제시된 아키텍처 권장 사항을 따름으로써 개발자는 차세대 자율 시스템의 잠재력을 최대한 발휘할 수 있을 것입니다.
Architectural Overview / PX4 Development Guide - shnuzxd, accessed July 7, 2025, https://shnuzxd.gitbooks.io/px4-development-guide/en/concept/architecture.html
| PX4 Architectural Overview | PX4 Guide (main) - PX4 docs, accessed July 7, 2025, https://docs.px4.io/main/en/concept/architecture.html |
PX4 Research Log [4] – A first look at PX4 architecture, example code, uORB and NSH script - UAV Lab @ Sydney, accessed July 7, 2025, https://uav-lab.org/2016/08/02/px4-research-log4-a-first-look-at-px4-architecture/
| uORB Messaging | PX4 Guide (main), accessed July 7, 2025, https://docs.px4.io/main/en/middleware/uorb.html |
| uORB Messaging | PX4 User Guide (v1.14) - PX4 docs - PX4 Autopilot, accessed July 7, 2025, https://docs.px4.io/v1.14/en/middleware/uorb.html |
PX4 uORB Explained: Part 1, accessed July 7, 2025, https://px4.io/px4-uorb-explained-part-1/
PX4 uORB Explained : Part 2, accessed July 7, 2025, https://px4.io/px4-uorb-explained-part-2/
| HG-PX4 Example Lab 2: uORB Publish | NXP HoverGames, accessed July 7, 2025, https://nxp.gitbook.io/hovergames/developerguide/px4-tutorial-example-code/hg-px4-example-lab-2 |
Increase uORB publishing frequency - PX4 Autopilot, accessed July 7, 2025, https://discuss.px4.io/t/increase-uorb-publishing-frequency/11291
Differences between acceleration data and getting correct data via Mavsdk - PX4 Autopilot, accessed July 7, 2025, https://discuss.px4.io/t/differences-between-acceleration-data-and-getting-correct-data-via-mavsdk/30935
Best way to determine module performance (tick rate) - PX4 Discussion Forum, accessed July 7, 2025, https://discuss.px4.io/t/best-way-to-determine-module-performance-tick-rate/12479
Latency Reduction and Packet Synchronization in Low-Resource …, accessed July 7, 2025, https://www.mdpi.com/1424-8220/23/22/9269
RTPS/ROS2 Interface: PX4-FastRTPS Bridge - Hamish Willee, accessed July 7, 2025, https://hamishwillee.gitbooks.io/havdevguide/en/middleware/micrortps.html
Custom flight modes using PX4 and ROS 2 - RIIS LLC, accessed July 7, 2025, https://www.riis.com/blog/custom-flight-modes-using-px4-and-ros2
| uXRCE-DDS (PX4-ROS 2/DDS Bridge) | PX4 Guide (main) - PX4 docs, accessed July 7, 2025, https://docs.px4.io/main/en/middleware/uxrce_dds.html |
ROS 2 User Guide - GitHub, accessed July 7, 2025, https://github.com/PX4/PX4-user_guide/blob/main/tr/ros2/user_guide.md
| ROS 2 User Guide | PX4 Guide (main) - PX4 docs, accessed July 7, 2025, https://docs.px4.io/main/en/ros2/user_guide.html |
RTPS/ROS2 Interface: PX4-FastRTPS Bridge - bkueng, accessed July 7, 2025, https://bkueng.gitbooks.io/px4-devguide/en/middleware/micrortps.html
| uXRCE-DDS (PX4-ROS 2/DDS Bridge) | PX4 User Guide (v1.14) - PX4 docs, accessed July 7, 2025, https://docs.px4.io/v1.14/en/middleware/uxrce_dds.html |
Features and Architecture - micro-ROS, accessed July 7, 2025, https://micro.ros.org/docs/overview/features/
a robotic framework - micro-ROS, accessed July 7, 2025, https://micro.ros.org/download/micro-ROS_Brochure.pdf
PX4 Messages in ROS 2 - Auterion Documentation, accessed July 7, 2025, https://docs.auterion.com/app-development/app-framework/px4-messages-in-ros-2
PX4/px4_msgs: ROS/ROS2 messages that match the uORB messages counterparts on the PX4 Firmware - GitHub, accessed July 7, 2025, https://github.com/PX4/px4_msgs
tiiuae/PX4-msgs: ROS/ROS2 messages that match the uORB messages counterparts on the PX4 Firmware - GitHub, accessed July 7, 2025, https://github.com/tiiuae/PX4-msgs
ROS 2 User Guide, accessed July 7, 2025, https://px4.gitbook.io/px4-user-guide/robotics/ros/ros2/ros2_comm
Overview Analysis of Micro-ROS System as an Embedded Solution for Microcontrollers in Automatics and Robotics Applications, accessed July 7, 2025, http://pe.org.pl/articles/2024/12/48.pdf