28.1.3.2.1. PX4의 uORB Publish/Subscribe 비동기 통신망 기반의 모드 독립성
PX4 아키텍처에서 수백여 개의 C++ 마이크로 앱 데몬들이 공중에서 엉키지 않고 정교한 스위스 시계의 톱니바퀴처럼 완벽하게 맞물려 돌아가는 기적의 배경에는, 펌웨어의 심장부 신경망 역할을 하는 uORB (Micro Object Request Broker) 통신망이 매우 든든하게 받쳐주고 있기 때문이다.
비행 모드(Flight Mode) 통제 시스템 역시 이 거대한 uORB 미들웨어의 축복을 온전히 받아, 철저하게 **하단 액추에이터 하드웨어 믹서망 및 상단 센서 디바이스 시스템으로부터 완벽한 소프트웨어적 모듈 독립성(Total Module Independence)**을 궁극적으로 쟁취해 냈다.
1. 아키텍처의 거대한 분단: 생산자(Publisher)와 소비자(Subscriber)의 물리적 철저한 격리
비행 모드 산출 관련 클래스들(FlightTask 파생 객체들)은 본인들이 머리를 쥐어짜 내어 생성한 3차원 비행 타겟 궤적이, 당장 기체 프레임의 어떤 ESC 모터를 얼마나 스피닝(Spinning) 시켜 타각을 만들어낼지 일절 관여하지도 않으며, 아키텍처 레벨에서 알려고 조차 하지 않는다. 이들은 오로지 uORB 세계관 안에서 순수 데이터의 ’소비자’이자 또 다른 궤적의 ’생산자’로서만 건조하게 철저히 행동할 뿐이다.
- 상태 데이터 수동적 구독(Subscribe):
- 비행 모드 타스크는 EKF2 칼만 추정기가 쉴 새 없이 산출해 내는
vehicle_local_position.msg(내 현재 기체의 X, Y, Z 물리적 절대 위치 및 속도 편차) 데이터 덩어리를 순수 입력(Input)으로만 받아먹는 철저한 대기조 **소비자(Async Subscriber)**다. - 비행 모드는 이 데이터를 만들어내는 EKF2 데몬 스레드가 현재 디바이스 램(RAM)의 어떤 번지수에 살아서 동작 중인지, C++ 포인터 메모리 주소 따위를 단 한 번도 묻고 따지지 않는다. 오직 uORB 파이프 통로를 열어 놓고 깨끗하게 정제된 구조체 물이 버퍼로 비동기적으로 흘러 들어오기만을 이벤트 기반으로 기다릴 뿐이다.
- 제어 목표 궤적 데이터 발행(Publish):
- 조종기의 아날로그 스틱 파싱, 혹은 미션 웨이포인트 알고리즘 연산이 모두 끝나면 비행 모드 모듈의 임무는 끝이 난다. 본인이 계산한
trajectory_setpoint.msg(기체가 궁극적으로 앞으로 0.1초 뒤에 달성해야 할 타겟 가속도/속도 수학 벡터 매트릭스) 구조체 빈칸에 숫자를 예쁘게 채워 넣고서, 백그라운드 uORB 우체통에 쿨하게 **발행(Publish)**해 허공에 던져버린 후 그대로 자신의 틱 루프 스레드 제어권을 OS 시스템에 반환하고 휴식에 들어간다.
2. 하단 컨트롤러와의 완벽무결한 물리적 디커플링(Decoupling)
이렇게 비행 모드 함수가 공중에 툭 뱉어놓고 떠난 순수 수학적 trajectory_setpoint 토픽 데이터는, 비동기 파이프라인 버퍼를 스르르 흘러 내려가며 또 다른 아래쪽 계층의 굶주린 소비자 데몬 마이크로서비스 입으로 빨려 들어간다.
- 이 허공에 뜬 벡터 데이터를 실시간 낚아채는 최하단 블루칼라 행동대장 모듈이 바로 기체 전용 하위 물리 제어기 집단인
mc_pos_control(멀티로터 위치/자세 제어기) 혹은fw_pos_control(고정익 비행기 고도/자세 제어기) 데몬들이다. - 최상단 비행 모드 프로그래머 입장에서는 내가 발행한 위대한 명령어 토픽 패킷을 아래에서 가져가서 모터를 돌리는 놈이 멀티로터 믹서 펌웨어인지, 고정익 날개 서보모터 제어기 펌웨어인지, 아니면 시뮬레이터(SITL/Gazebo)인지, 그것도 아니면 단순 화면 표시를 위해 ROS2 동반 컴퓨터(Companion Computer)에서 빼내가는 로깅/뷰어 데몬인지 알 방법도 없고 알 명분도 없다.
- 이러한 극단적인 맹목성 메커니즘을 통해 상단 비행 정책 로직(Flight Task Mode)과 하위 기체 물리 믹서(Physics Mixer) 간의 완벽한 100% 종속성 단절(Absolute Independence & Decoupling) 우주가 C++ 코드 베이스 상에 완벽히 구축되는 것이다.
3. 타 프레임워크가 모방 불가능한 샌드박스 다중화 확장성
이러한 메시지 규격화 Publish/Subscribe 기반의 느슨한 비동기식 샌드박스 아키텍처는, 과거의 아두이노 시절에 머물러 있는 단일 스레드 포인터 스파게티 참조망(Ardupilot 모놀리식 기반)에서는 감히 흉내 내거나 포팅할 수조차 없는 상상 밖의 극단적인 아키텍처 생존 결함 능력을 뽐낸다.
- 실시간 코드 핫스와핑(Hot-swapping) 및 무한 다중화 생존:
만약 공중 비행 중 기존의 메인 EKF2 칼만 필터 스레드 메모리가 우주 방사선이나 노이즈 연산 패닉으로 터져버려vehicle_local_position토픽 발행 파이프라인이 즉각 중단되어 버리면 어떻게 될까? PX4 아키텍처는 내부에서 섀도우 런(Shadow Run) 중이던 백업 보조 추정 필터(예: LPE 매끄러운 보간 필터 데몬 시스템)가 스스로 스레드 활성화되어 기존과 완전히 동일한 이름표(vehicle_local_position.msg)를 단 생명줄 토픽 구조체를 즉시 빈 uORB 빈방에 밀어 넣어 버리며 퍼블리시 전권을 가로챈다.
이때 놀랍게도 이 데이터를 받아먹는 상단 계층의 비행 모드 로직은, 파이프 너머의 데이터 출처 발신지 IP가 바뀌었음을 0.1초의 딜레이 체감이나 다운타임도 느끼지 못한 채 그저 똑같이 데이터값이 주어지니 하던 일 그대로, 본연의 부드러안 궤적 제어를 죽지 않고 영속적으로 보존 연장해 내는 불사조 같은 페일세이프(Failsafe) 다중화를 스스로 시연한다. - 비인가 전역 변수 침범의 컴파일 타임(Compile-Time) 원천 차단:
주니어 개발자가 게으름 피우느라 실수로 비행 모드 코드 루프 내부 안에서 최하단 모터 믹서의 PWM 펄스값을 직접 덮어쓰기 조작하려는 금지된 다이렉트 해킹 함수를 짜넣으려고 시도해 보라. 애초에 불가능하다.
빌드 컴파일 단계(CMake)에서 아예 비행 모드 디렉터리와 모터 믹서 디렉터리는 서로의 헤더 파일(Header File) 인클루드 패스(Include Path) 공간조차 물리적으로 완전히 이등분 격리 분리되어 있어, 타 객체 전역 변수에 접근하는 우회 통로 자체가 문법적으로 아키텍처단에 완전 폐쇄되어 있기 때문이다. 오로지 사전에 엄격하게 합의 스펙 된 uORB.msg구조체 규격 서류 쪼가리로만 서로 대화 문서를 던지고 받을 수 있는 가장 삭막하고 무미건조하지만 강철같이 단단한 마이크로서비스(Microservices) 시스템의 정원이다.