28.7.1.1. vehicle_status.msg 내 NAVIGATION_STATE_CUSTOM_XXX 상수 할당 및 주석 규칙
PX4-Autopilot의 커스텀 비행 모드 추가 1단계에서 가장 먼저 손대야 하는 파일은 msg/VehicleStatus.msg (버전에 따라 msg/vehicle_status.msg) 이다. 이 파일은 시스템 전역에서 기체가 “현재 논리적으로 어떤 비행 상태에 있는지“를 판별하는 고유 ID 테이블 역할을 한다.
커스텀 모드를 위한 신분증(ID)을 정상적으로 발급받기 위해서는 단순히 빈 줄에 코드를 끼워 넣는 것을 넘어, PX4 빌드 생태계가 텍스트를 파싱(Parsing)하는 규칙을 정확히 이해하고 준수해야 한다. 본 절에서는 이 파일 내부의 상수 할당 원칙과 주석(Comment)에 숨겨진 메타데이터 작성 규칙을 해부한다.
1. vehicle_status.msg 파일의 소스 구조
이 메시지 파일은 단순한 C++ 헤더 파일이 아니라, uORB(Micro Object Request Broker) 인터페이스 정의어 파일이다. 파일을 열어보면 상단에서부터 비행기의 핵심 상태를 관장하는 uint8 포맷의 매크로 상수(Constants)들이 빼곡하게 나열되어 있고, 하단에는 실제 통신에 묻어 나가는 변수(Fields)들이 정의되어 있다.
# 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_AUTO_MISSION = 3 # Auto mission mode
uint8 NAVIGATION_STATE_AUTO_LOITER = 4 # Auto loiter mode
uint8 NAVIGATION_STATE_AUTO_RTL = 5 # Auto return to launch mode
# ... (중략) ...
uint8 NAVIGATION_STATE_DESCEND = 21 # Descend mode (no position control)
# [여기에 우리의 신규 상태를 삽입해야 한다]
비행 모드 관리를 위한 핵심 변수는 uint8 nav_state 필드다. Commander나 Flight Mode Manager는 이 nav_state 변수 안에 위에서 정의된 상수 번호(0, 1, 2, … 21) 중 하나를 담아 uORB 버스에 퍼블리싱(Publishing)한다.
2. 신규 상태(Navigation State) 상수의 할당 원칙
커스텀 모드의 존재를 선언하기 위해 상수를 새로 만들 때, PX4 코어 개발자들의 규칙(PR Convention)을 위배하면 본 시스템과 소스 코드가 심각하게 꼬일 수 있다.
- 접두사(Prefix) 규칙:
반드시NAVIGATION_STATE_라는 접두사로 시작해야 한다. 빌드 툴체인 및 여러 플래그 파서(Parser)가 이 접두사를 기준으로 상태 변수의 범위를 식별하기 때문이다. - 명명(Naming) 규칙:
영문 대문자와 언더스코어(_)만을 사용하여 직관적인 단어의 조합으로 모드 이름을 기재한다. 커스텀 모드임을 명기하기 위해 관례적으로CUSTOM_을 붙이는 것이 안전하다.
- 권장:
NAVIGATION_STATE_CUSTOM_WALL_FOLLOW - 비권장:
NAVIGATION_STATE_MY_MODE_1
- 순번 할당(Numbering) 규칙:
기존에 할당된 맨 마지막 번호의 바로 다음 번호(MAX\_ID + 1)를 수동으로 입력한다. 중간에 비어있는 번호가 있더라도(과거 버전에서 삭제된 모드 등), 하위 호환성을 위해 절대 중간 번호를 재사용해서는 안 되며, 무조건 리스트의 끝에 증분 할당(Incremental Allocation)을 해야 한다. 역대 가장 큰 숫자가 21이었다면 새 모드는 22를 배정받는다.
uint8 NAVIGATION_STATE_CUSTOM_WALL_FOLLOW = 22
3. 주석(Comment) 작성의 숨겨진 메타데이터 규칙
PX4의 .msg 파일 내에서 # 문자는 단순한 사람용 메모장이 아니다. PX4 빌드 툴체인(Python 기반 genmsg 스크립트 등)은 이 메시지 파일을 읽으면서 열(Column)과 들여쓰기를 분석(Parsing)하여 로보틱스 프레임워크 문서를 자동 생성하거나 QGroundControl(GCS)과의 파라미터 연동 명세서를 뽑아낸다.
따라서 단순히 상수를 선언하는 데 그치지 않고, 반드시 \t(탭 문자)로 간격을 맞춘 다음 해당 모드가 어떤 역할을 하는지 직관적인 영어 설명(Description) 을 달아주어야 한다.
# 옳은 예시 (빌드 스크립트가 파싱 가능)
uint8 NAVIGATION_STATE_CUSTOM_WALL_FOLLOW = 22 # Custom mode for lidar-based wall following
# 틀린 예시 (주석 누락으로 인해 문서화 스크립트에서 공백(Null)으로 추출될 확률 높음)
uint8 NAVIGATION_STATE_CUSTOM_WALL_FOLLOW = 22
이 주석 텍스트는 훗날 MAVLink 직렬화(Serialization)를 거치거나 내부 Flight Task 이름을 매핑할 때, 로깅(ULog) 파일의 메타 카탈로그에 “어떤 비행 모드를 켰었는지” 사람이 읽을 수 있는 이름표(Human-readable Label)로 남겨지는 등 핵심적인 힌트(Hint)가 된다.
4. ArduPilot의 매크로 상수 체계 대비 uORB 구조체의 장단점
- ArduPilot (매크로 스위치 기반):
ArduCopter디렉토리 내mode.h파일 등에#define COPTER_MODE_CUSTOM 25처럼 전처리기(Preprocessor) 매크로나 Enum 클래스로 직접 선언한다. 소스 코드 안에서 직관적으로 관리되지만, 외부로 나가는 통신 메시지 구조와 파일 내부 상태 변수가 하드 코딩으로 강하게 묶이는 단점이 있다. - PX4-Autopilot (통신 정의 기반 캡슐화): 아예 C++ 코드가 아닌, 미들웨어 통신 인터페이스인
.msg파일 안에 상수 셋을 몰아넣고, 이를 통해 헤더 파일을 역으로 생성해 내는 객체 지향적 브로커(Broker) 방식을 취한다.
이는 PX4 내부의 여러 앱(App)들이VehicleStatus.msg단 하나만 참조해도 시스템의 모든 비행 모드 ID표를 알 수 있게 만들어, 마이크로서비스 아키텍처(Microservices Architecture) 처럼 모듈 간의 결합도를 극단적으로 낮추는 탁월한 장점을 발휘한다. 다만 빌드 과정이 추가되어 수정 후 컴파일 타임이 길어진다는 트레이드오프를 동반한다.