28.7.1. 1단계: 신규 Navigation State 정의 및 uORB 통신망 구축
PX4-Autopilot 생태계 내에서 기체의 두뇌 역할을 하는 모든 모듈(Commander, Flight Mode Manager, Position Control 등)은 서로가 현재 무슨 ’생각(비행 모드)’을 하고 있는지 파악하기 위해 uORB(Micro Object Request Broker) 통신 버스를 사용한다. 그중에서도 시스템 전체의 비행 상태 지휘봉을 쥐고 있는 가장 핵심적인 메시지 파일이 바로 vehicle_status.msg 이다.
커스텀 비행 모드를 시스템에 완전히 뿌리내리게 하려면 최하단 통신망인 이 메시지 파일부터 수정하여 새로운 상태(State)의 존재를 선언해야 한다. 본 절에서는 1단계 과정인 통신망 구축 절차를 코드 레벨에서 상세히 분석한다.
1. vehicle_status 메시지의 역할과 구조
PX4 시스템 소스 코드 트리의 msg/VehicleStatus.msg (또는 PX4 버전에 따라 msg/vehicle_status.msg) 파일을 열어보면, 기체의 비행 모드 상태를 정의하는 수십 개의 상수(Constant)가 나열되어 있다.
이 파일에 정의된 상수들은 navigation_state 필드를 채우는 열거형(Enum) 데이터로 사용된다. 예를 들어, 조종사가 조종기 스위치를 ’위치 제어 모드’로 딸깍 올리면, Commander는 즉각 vehicle_status.nav_state = NAVIGATION_STATE_POSCTL 신호를 uORB 버스에 쏘아 전체 시스템에 전파한다.
따라서 우리가 새롭게 추가할 Custom Mode 또한 시스템 전역에서 동일한 신분증(ID)을 인정받으려면 이 파일 안에 당당히 한 줄을 차지해야 한다.
2. 신규 상태(Navigation State) 상수 할당 절차
msg/VehicleStatus.msg 파일을 열고, 기존의 상태 변수 목록의 맨 마지막에 (또는 논리적으로 적합한 위상에) 신규 모드의 상수를 명시적으로 추가한다.
2.1 상수 할당 및 명명 규칙(Naming Convention)
상수의 이름은 반드시 NAVIGATION_STATE_ 접두사를 가져야 하며, 그 뒤에 모드의 성격을 나타내는 명확한 대문자 영어 단어를 결합한다. (예: NAVIGATION_STATE_CUSTOM_WALL_FOLLOW)
숫자 ID는 기존의 할당된 번호(예: 0~21)와 절대 겹치지 않도록 다음 순번의 가장 빠른 빈 번호를 엄격하게 채번(Numbering)해야 한다.
# msg/VehicleStatus.msg 파일 내부 수정 예시
uint8 NAVIGATION_STATE_MANUAL = 0 # Manual mode
uint8 NAVIGATION_STATE_ALTCTL = 1 # Altitude control mode
uint8 NAVIGATION_STATE_POSCTL = 2 # Position control mode
# ... (중략) ...
uint8 NAVIGATION_STATE_DESCEND = 21 # Descend mode (no position control)
# [NEW] 여기에 새로운 상태를 정의한다. (이전 번호가 21이었으므로 22 할당)
uint8 NAVIGATION_STATE_CUSTOM_FOO = 22 # Custom Foo Flight Mode
2.2 주석(Comment)의 메타데이터화 규칙
PX4 시스템에서 uORB .msg 파일 옆에 달린 # 주석은 단순한 텍스트가 아니다. 빌드 시스템(Cmake & Python Scripts) 파서(Parser)가 이 주석을 읽어 들여 특정 시스템 문서 자동 생성이나 헤더 파일(Header File) 생성을 수행할 때 메타데이터로 활용하기도 한다.
따라서 새로 추가한 줄 우측에 반드시 해당 모드가 어떤 모드인지 짧고 명시적인 영어 주석(예: # My Custom Hovering Mode)을 달아주어야 한다.
3. uORB 메시지 생성 스크립트 빌드 및 의존성 갱신
메시지 텍스트 파일(.msg)을 단 한 줄이라도 수정했다면, C++ 소스 코드가 이를 인식할 수 있도록 시스템 구조를 다시 컴파일해 주어야 한다. PX4 빌드 툴체인(Toolchain)은 .msg 파일을 파싱하여 내부적으로 C/C++ 구조체(Struct)가 담긴 헤더 파일(.h)들을 자동으로 찍어낸다.
3.1 빌드 루틴의 동작 원리
터미널에서 펌웨어 컴파일 명령(make px4_fmu-vX_default 등)을 치면, msg/CMakeLists.txt에 정의된 파이썬 생성기 스크립트(genmsg 모듈)가 가동된다.
이 스크립트는 우리가 방금 수정하여 저장한 VehicleStatus.msg를 읽고 번역하여 build/px4_fmu-vX_default/uORB/topics/vehicle_status.h 라는 핵심 헤더 파일로 자동 변환시킨다.
헤더 파일 내부에는 다음과 같은 C/C++ 매크로 상수가 자동으로 생성되어 박힌다.
/* Auto-generated header: build/px4_fmu-vX_default/uORB/topics/vehicle_status.h */
#define vehicle_status_s__NAVIGATION_STATE_CUSTOM_FOO 22
3.2 의존 모듈(Dependency)의 트리거(Trigger) 컴파일
이 vehicle_status.h 헤더 파일은 시스템의 핵심부이므로, Commander, Navigator, Flight Mode Manager 등 무수히 많은 소스 파일들이 #include <uORB/topics/vehicle_status.h> 형태로 이 파일에 의존(Dependency)하고 있다.
따라서 상수 하나를 추가하고 빌드를 돌리면, 의존성을 가진 펌웨어 내 수백 개의 .cpp 소스 코드들이 줄줄이 재컴파일(Re-compile) 되는 폭포수 현상(Cascade recompilation)이 발생한다.
이 단계에서 만약 상수의 번호가 중복 할당되었거나 파일 포맷이 어긋났다면, 파이썬 스크립트 에러와 함께 빌드가 즉시 터지며 치명적인 컴파일 에러(Fatal Error)를 내뿜게 된다. 빌드가 단 한 번의 경고(Warning) 없이 성공적으로 100% 완료되었다면, 새로운 신분증 발급 단계인 1단계 통신망 구축이 완벽하게 끝난 것이다.