28.7. 커스텀 비행 모드(Custom Flight Mode) 및 Task 확장을 위한 소스 코드 수정 지침서

28.7. 커스텀 비행 모드(Custom Flight Mode) 및 Task 확장을 위한 소스 코드 수정 지침서

PX4-Autopilot이 전 세계 학계와 산업계에서 가장 각광받는 오픈소스 비행 제어 소프트웨어로 자리 잡은 핵심적인 이유는 그 탁월한 모듈성(Modularity)확장성(Extensibility) 에 있다. 개발자는 기존의 수동 모드(Stabilized, Position 등)나 자율 임무 모드(Mission, Return)만으로는 해결할 수 없는 독창적인 비행 로직—예컨대 AI 비전 기반의 벽면 회피 추종(Wall Following), 매니퓰레이터(Manipulator) 연동 무게 중심 보상 비행, 또는 군집(Swarm) 랑데부 궤적 생성—을 구현하고자 할 때, 필연적으로 자신만의 커스텀 비행 모드(Custom Flight Mode) 를 펌웨어 깊숙한 곳에 이식해야 한다.

본 장(Chapter)에서는 PX4 펌웨어 빌드 환경 위에서 완전히 새로운 비행 모드를 창조해 내기 위해 건드려야 하는 소스 코드의 파이프라인(Message Definition \rightarrow Flight Task \rightarrow Commander \rightarrow MAVLink \rightarrow GCS) 전체를 단계별로 관통하는 기술적 지침(Technical Guide)을 제시한다.


1. 커스텀 비행 모드 확장의 아키텍처 철학

PX4에서 비행 모드를 하나 추가한다는 것은 단순히 어떤 함수(Function) 하나를 끼워 넣는 수준이 아니다. 그것은 기체의 두뇌인 Flight Mode Manager (비행 모드 관리자) 프로세스 안에 완전히 독립적인 생명주기를 가진 객체 지향적(Object-Oriented) 상태 기계(State Machine)를 하나 분양받는 것을 의미한다.

이 확장의 중심에는 FlightTask 프레임워크 가 있다. PX4는 커스텀 로직이 시스템 전체의 코어 안정성을 해치지 못하도록, 위치 제어기(mc_pos_control) 상단에 FlightTask라는 C++ 추상 클래스(Abstract Class) 층을 덮어씌워 두었다. 개발자는 그저 이 템플릿을 상속받아 자식 클래스(FlightTaskCustom)를 만들고, 목표 위치(Setpoint)를 뱉어내는 수학 공식만 채워 넣으면 된다. 나머지는 커맨더(Commander)와 uORB 버스가 알아서 모터까지 전달해 준다.


2. 모드 확장을 위한 4단계(4-Step) 파이프라인

새로운 모드를 추가하여 기체를 띄우고 지상 관제소(GCS)에서 버튼을 눌러 그 모드를 실행하기까지는, 시스템의 밑바닥 메시지 정의부터 최상단 UI까지 꿰뚫는 방대한 4단계의 수정 작업이 요구된다. 이후의 하위 절(Subsection)에서는 다음 4단계를 코드 레벨에서 상세히 다룬다.

2.1 1단계: 신규 Navigation State 정의 및 uORB 통신망 구축 (통신 기반)

가장 먼저 시스템 전체가 이 ’새로운 모드’의 존재를 알아차릴 수 있도록 고유한 ID 번호(상수)를 부여해야 한다. 기체의 현재 상태를 방송하는 핵심 uORB 메시지인 vehicle_status 안에 커스텀 상태(Navigation State)를 정의하고, 파이프라인을 관통하는 메시지를 빌드하는 절차를 수행한다.

2.2 2단계: FlightTaskCustom 파생 클래스 템플릿 작성 (물리 제어 로직)

수학적 역학과 아이디어가 코드로 발현되는 메인 스테이지다. src/modules/flight_mode_manager/tasks 디렉토리 하위에 새로운 폴더를 파고, C++ 클래스를 상속받아 update() 루프 안에 커스텀 웨이포인트(Trajectory Setpoint)를 생성해 내는 로직을 작성한다.

2.3 3단계: Commander 및 Flight Mode Manager 컴포넌트 스위칭 (상태 머신 편입)

생성된 클래스를 PX4의 심장인 커맨더(commander) 서브시스템에 등록한다. 조종사의 조종기 스위치나 MAVLink 명령이 들어왔을 때, 기체가 이 모드로 진입해도 되는지(예: GPS가 켜져 있는가?) 검증하는 허가 분기(Transition Check)를 추가하고, Flight Mode Manager의 스위치 보드에 이 클래스를 인스턴스화하여 연결한다.

2.4 4단계: MAVLink 인터페이스 연동 및 관제 시스템(GCS) UI 반영 (인프라 통합)

PX4 내부에서 모드가 완성되었다 하더라도, 외부 관제 시스템(QGroundControl)이 이를 알지 못하면 사용할 수 없다. MAVLink 프로토콜의 모드 매핑(Mapping) 테이블을 수정하여 커스텀 ID를 외계어로 번역해 주고, 최종적으로 QGroundControl의 C++ 백엔드 소스(PX4FirmwarePlugin)를 수정하여 화면의 Drop-down 메뉴에 “Custom Flight” 라는 고유한 이름이 노출되도록 반영한다.


3. ArduPilot과의 모드 확장성 비교

오픈소스 생태계에서 PX4와 ArduPilot은 모드 추가 아키텍처에서 확연히 다른 접근 방식을 보여준다.

  • ArduPilot (매크로 및 스위치 케이스 기반 편입): Copter 디렉토리 산하에 mode_custom.cpp를 만들고, 펌웨어 전역에 걸친 거대한 switch-case 문과 매크로 헤더에 모드 번호를 우겨넣는 방식이 주류다. 로직 추가는 직관적일 수 있으나, 전역 변수 오염이나 메인 비행 루프(Fast Loop)에 직접적인 연산 부하를 줄 위험성이 높다.
  • PX4 (엄격한 객체 지향 및 모듈 캡슐화): PX4의 FlightTask 아키텍처는 철저하게 샌드박스(Sandbox)화 되어 있다. 개발자가 짠 커스텀 모드에서 Segmentation Fault 급의 버그가 나지 않는 한, 그 로직 밖으로 쓰레기 데이터가 튀어나가 메인 위치 제어기를 오염시키는 것을 프레임워크 단(_trajectory_setpoint 버퍼 검증 등)에서 일차적으로 차단한다. 이는 비행 안전성을 극상으로 끌어올리지만, 모드 하나를 추가하기 위해 건드려야 하는 파일의 개수(Boilerplate Code)가 많고 C++ 다형성(Polymorphism)에 대한 높은 이해도를 요구한다는 진입 장벽을 발생시킨다.