29.5.1.2. 외부 루프(Outer Loop) 제어 스레드의 대기 상태 진입 또는 연산 생략을 유도하는 구조적 조건문 확인
PX4-Autopilot의 아크로(Acro) 모드 전환 시, 커맨더(Commander) 모듈에 의해 flag_control_attitude_enabled 플래그가 false로 설정된다. 본 절에서는 이 플래그가 멀티로터의 제어 스택 중 외부 루프(Outer Loop) 역할을 하는 자세 제어기(Attitude Controller, mc_att_control) 모듈 내부에서 어떻게 수신되고, 어떠한 구조적 조건문(Conditional Statement)을 통해 무거운 수학 연산을 생략(Bypass)하며 스레드를 대기 상태(Idle)로 유지하는지 소스 코드 레벨에서 명확히 확인한다.
1. 자세 제어 모듈(mc_att_control)의 스레드 동작 구조
PX4의 모듈들은 대부분 NuttX RTOS 상에서 독립적인 워크큐(Work Queue) 태스크나 스레드 형태로 동작하며, uORB 토픽의 업데이트를 폴링(Polling)하는 방식으로 이벤트 루프를 구성한다. mc_att_control 모듈 역시 자신의 실행 주기마다 vehicle_control_mode 토픽을 확인하여 자신이 제어 권한을 가지고 있는지 판단해야 한다.
1.1 제어 모드 플래그 업데이트 감지
해당 모듈의 주 실행 루프인 MulticopterAttitudeControl::Run() 함수가 호출되면, 가장 먼저 하는 작업은 제어 모드가 변경되었는지 확인하는 것이다.
// src/modules/mc_att_control/mc_att_control_main.cpp의 루프 초기 부분
void MulticopterAttitudeControl::Run()
{
// ... 생략: 자이로스코프 데이터 폴링 대기 등 ...
// vehicle_control_mode 토픽에 업데이트가 있는지 구독(Subscription) 확인
if (_v_control_mode_sub.updated()) {
vehicle_control_mode_s v_control_mode{};
// 플래그 구조체 복사본 획득
if (_v_control_mode_sub.copy(&v_control_mode)) {
// 로컬 변수에 플래그 저장
_v_control_mode = v_control_mode;
}
}
위의 과정을 통해 자세 제어기는 커맨더 모듈이 브로드캐스트한 가장 최신의 flag_control_attitude_enabled 값을 로컬 변위인 _v_control_mode 구조체 내에 갱신하게 된다. 아크로 모드라면 이 시점에 해당 플래그는 false로 덮어씌워진다.
1.2 연산 생략을 유도하는 핵심 조건문(Guard Clause)
PX4 소프트웨어 아키텍처는 CPU 사이클을 아끼기 위해 조기 반환(Early Return) 패턴의 방어적 프로그래밍(Guard Clause)을 적극적으로 사용한다. 플래그를 갱신한 이후, 아래와 같은 구조적 조건문을 만나게 된다.
// src/modules/mc_att_control/mc_att_control_main.cpp의 태스크 우회 구간
// 조건문 1: 자세 제어(Attitude Control) 자체가 비활성화 되었는가?
if (!_v_control_mode.flag_control_attitude_enabled) {
// [핵심] 아크로 모드 또는 수동 제어가 아닌 상태에서는 이 블록이 실행됨
// 자세 제어가 필요 없으므로 기존의 내부 적분기(Integral) 리셋 등 정리 작업만 수행
// _thrust_sp = 0.0f; (필요 시 추력 초기화)
// 연산을 더 이상 진행하지 않고 즉시 스레드 루프를 반환(Return)하여 대기 상태로 진입
return;
}
// --- 이 아래의 코드는 아크로(Acro) 모드일 때 절대 도달하지 않음 ---
// 쿼터니언(Quaternion) 오차 계산, 회전 행렬(Rotation Matrix) 변환 연산
// ... 삼각함수 및 행렬 곱셈 등 시스템 부하가 큰 로직 ...
위의 조건문 if (!_v_control_mode.flag_control_attitude_enabled)이 바로 외부 루프의 실행 스레드를 대기 상태로 되돌리고 모든 자세 제어 연산을 생략하게 만드는 핵심 장치다. 이 조건이 1번이라도 만족되면(true), 스레드는 더 이상의 복잡한 쿼터니언 연산을 진행하지 않고 return 구문을 통해 자신의 실행 턴을 운영체제(NuttX)에 반환한다.
1.3 우회 아키텍처가 시스템에 미치는 영향
이러한 구조적 조건문을 통한 스레드 연산 생략은 단순히 “기체가 수평을 맞추지 않는다“는 기체 동역학적 특징 외에도, 소프트웨어 자원 측면에서 지대한 이득을 창출한다.
- 컨텍스트 스위칭 최소화 및 효율성 증대: 쿼터니언 미분 방정식 및 PID 오차 계산을 우회함으로써 스레드의 CPU 체류 시간이 짧아지고, 유휴(Idle)로 돌아가는 속도가 빨라진다.
- 파이프라인 독립성 보장: 이 조건문은 Ardupilot이 하나의 루프 안에서 비행 모드별로 스위치를 나누어 분기하는 것과 달리, 기능별(자세/각속도) 모듈의 파이프라인(Thread Pipeline)을 원천적으로
Cut-off하는 역할을 한다. 따라서 병렬적으로 돌고 있는mc_rate_control(각속도 제어) 스레드는 자세 제어 스레드의 실행 지연이나 행(Hang) 현상에 전혀 영향을 받지 않고 오직 최단 경로의 각속도 연산만을 보장받게 된다.
결과적으로, PX4의 아크로 모드는 제어 권한 트리거 변수 하나만으로 하드웨어 자원을 가장 필요한 곳(Rate Loop)에 집중할 수 있도록 C++의 간결한 조건문을 통해 매우 우아한 마이크로서비스 형태의 절제(Bypass) 메커니즘을 완성하였다.