28.5 uORB 제어 플래그(Control Flags)와 내부 컴포넌트 라우팅
PX4-Autopilot의 아키텍처를 분석할 때 가장 눈에 띄는 철학적 특징 중 하나는 메인 상태 머신(State Machine)과 실제 기체를 제어하는 컨트롤러 모듈들이 강하게 결합되어 있지 않다는 점이다. 대신, 이들 사이에는 uORB(Micro Object Request Broker) 통신 미들웨어가 존재하며, 제어 플래그(Control Flags) 메시지를 통해 각 하위 컴포넌트가 언제 개입해야 하는지를 비동기적으로(Asynchronously) 지시받는다.
본 장에서는 PX4 내부 모듈 간 트래픽 라우팅의 매개체가 되는 uORB 제어 플래그의 아키텍처적 특성과 컴포넌트 간 데이터 흐름 모델을 심층 분석한다.
1. 디커플링(Decoupling) 아키텍처의 설계 철학
전통적인 오픈소스 비행 제어 소프트웨어나 산업용 제어 시스템 중 상당수는 ’모드 관리자’가 ’하위 컨트롤러’의 함수를 직접 호출(Direct Function Call)하는 방식으로 설계되어 있다. 예를 들어 “Mission 모드로 진입하라“라는 명령이 떨어지면, 상위 모체가 run_mission_controller()라는 함수를 직접 트리거하는 방식이다. ArduPilot의 오래된 분기문 로직이 이러한 특성을 일부 가지고 있다.
반면, PX4는 퍼블리셔-서브스크라이버(Publisher-Subscriber) 패턴 기반의 uORB 메시징에 전적으로 의존한다.
- 지시자(Commander / Flight Mode Manager): 기체의 상태와 현재 요구되는 비행 모드를 종합적으로 판단한 뒤, “지금은 위치(Position) 제어가 필요한 상태임“을 나타내는 Boolean 플래그 메시지를 브로드캐스트(Broadcast)한다. 어떤 모듈이 이 메시지를 받을지는 신경 쓰지 않는다.
- 실행자(Position Controller / Attitude Controller): 매 루프마다 이 컨트롤 플래그 토픽을 구독(Subscribe)한다. 만약 자신에게 해당하는 플래그(예:
flag_control_position_enabled)가true로 수신되면 자신의 제어 루프를 연산하여 액추에이터 명령을 하달하고,false라면 시스템 유휴 상태로 전환하거나 내부 타이머를 리셋하며 대기한다.
이러한 느슨한 결합(Loose Coupling)은 구조적으로 새로운 컨트롤러를 추가하거나, 시스템을 ROS2 등 외부로 쉽게 분산시킬 수 있게 하는 원동력이 된다.
2. uORB 트래픽 라우팅: vehicle_control_mode 메신저
제어 플래그 라우팅의 중심에는 vehicle_control_mode.msg라는 아주 작지만 강력한 uORB 토픽이 있다.
2.1 라우팅 파이프라인 흐름
- 입력 처리:
commander모듈은 조종기(RC), GCS(MAVLink), 내부 Failsafe 로직으로부터 원하는 비행 모드(Nav State)를 결정한다. - 번역 및 분배:
flight_mode_manager(FMM)는 이 Nav State(예:NAVIGATION_STATE_POSCTL)를 전달받아, 해당 모드를 실현하기 위해 활성화되어야 하는 하위 제어 차수학(Degrees of Freedom)을 분해한다. - 플래그 세팅: FMM은
vehicle_control_mode구조체의 플래그들을true/false켜고 끄는 멀티플렉서(Multiplexer) 역할을 수행 후 퍼블리싱한다. - 역할 수행: 멀티로터의 경우
mc_pos_control,mc_att_control모듈 프로세스가 이 토픽을 구독하여 각자의 스위치를 켠다.
graph LR
A[조종기 / GCS 입력] -->|MAVLink/RC| Cmd(Commander)
Cmd -->|vehicle_status| FMM(Flight Mode Manager)
FMM -->|vehicle_control_mode<br>uORB Topic| B1(mc_pos_control)
FMM -->|vehicle_control_mode<br>uORB Topic| B2(mc_att_control)
FMM -->|vehicle_control_mode<br>uORB Topic| B3(fw_pos_control_l1)
B1 -->|Vehicle Local Position Setpoint| B2
B2 -->|Actuator Controls| C[Mixer / Motors]
2.2 메인 Boolean 플래그 종류 (개요)
vehicle_control_mode 내부에 선언된 핵심 불리언 플래그는 다음과 같은 위계(Hierarchy)를 가진다.
flag_control_manual_enabled: 조종사의 직접 스틱 개입 여부flag_control_position_enabled: 수평 방향(XY) 공간 위치 제어 루프 활성화flag_control_velocity_enabled: 수평 방향(XY) 속도 제어 루프 활성화flag_control_altitude_enabled: 수직 방향(Z) 고도 제어 루프 활성화flag_control_attitude_enabled: 3축 자세(Roll/Pitch/Yaw) 각도 제어 활성화flag_control_rates_enabled: 3축 각속도(Angular Rates) 제어 활성화
이들은 상호 배타적이지 않으며, 상위 플래그가 참결과일 땐 일반적으로 하위 플래그도 모두 참이 동반된다. (예: Position 제어가 켜지면 당연히 하위의 Velocity, Attitude, Rates 플래그도 켜진다.)
3. 기능 라우팅을 위한 소스 코드 분석 예제
C++ 소스 코드 레벨에서 이 플래그가 어떻게 구독(Subscribe)되고 루프를 스위칭하는지 멀티로터 위치 제어기(mc_pos_control)를 예로 들어 살펴보자.
// mc_pos_control/MulticopterPositionControl.cpp (PX4 v1.14 구조)
void MulticopterPositionControl::Run()
{
// 1. vehicle_control_mode 토픽 데이터 폴링(Polling) 및 갱신
if (_control_mode_sub.updated()) {
vehicle_control_mode_s control_mode;
_control_mode_sub.copy(&control_mode);
_control_manual_enabled = control_mode.flag_control_manual_enabled;
_control_position_enabled = control_mode.flag_control_position_enabled;
_control_velocity_enabled = control_mode.flag_control_velocity_enabled;
_control_altitude_enabled = control_mode.flag_control_altitude_enabled;
}
// 2. Position 플래그가 꺼져 있다면 루프 진입 차단 (Early Return)
if (!_control_position_enabled) {
// 내부 적분기(Integrator) 리셋 및 상태 초기화 루틴
_control.resetPosition();
return;
}
// 3. 플래그가 참일 경우 실제 제어 알고리즘(PID 등) 연산 수행
_control.updatePositionController();
// ... 이하 속도 제어, 가속도 생성 로직 실행
}
이와 같이 PX4의 컨트롤러들은 스스로가 현재 어떤 비행 모드(Altitude인지 Mission인지)에 처해있는지 알 필요가 없다. 단지 자신에게 할당된 제어 권한 플래그(Control Authority Flag) 인 _control_position_enabled가 true인지 false인지만을 감시할 뿐이다.
4. ArduPilot 통신 아키텍처와의 차이점 정리
| 특성 | PX4-Autopilot | ArduPilot |
|---|---|---|
| 제어 개론 | Message-based, Publish/Subscribe 방식 (uORB) | Method-call, Class Inheritance 방식 (C++) |
| 모듈 독립성 | 매우 강함. 특정 컨트롤러 모듈 프로세스를 끄고 완전히 다른 커스텀 컨트롤러(예: ROS2 노드)로 무중단 대체 가능. | 메인 루프 안에 강하게 컴파일 결합되어 있어 커스텀 모듈을 주입하기 위해서는 소스 트리를 심하게 건드려야 함. |
| 데이터 동기화 | 비동기 폴링(Asynchronous Polling) 형태이므로 토픽 딜레이(지연 시간) 고려 필요 최소화된 락(Lock-free) 기반 설계. | 동기식(Synchronous) 실행 루프 구조라 순서(Sequence) 보장이 강력함. |
5. 커스텀 모드 개발을 위한 라우팅 확장성 (ROS2 연동)
이러한 메시지 기반 제어 라우팅 기법은 ROS2, 즉 Micro XRCE-DDS 기반의 외부 에이전트 연동에서 막강한 위력을 발휘한다.
자율 주행 에이전트(Offboard Mode)를 설계할 때, 개발자는 PX4 내부 소스코드를 수정할 절차적 필요성 없이, ROS2 노드단에서 vehicle_control_mode.msg의 플래그들을 강제로 덮어쓰거나(Override) Offboard 플래그와 연계하여 원하는 특정 제어 계층(예: 속도 제어나, 직접 각속도 제어 등)만을 선택적으로 바이패스(Bypass) 활용할 수 있다. 이는 완전한 플러그 앤 플레이(Plug-and-play) 제어기 확장의 밑거름이 된다.