29.5. 아크로(Acro) 모드 제어 루프 소스 코드 분석
무인항공기의 수동 제어 모드 중 가장 순수하고 직관적인 비행 경험을 제공하는 모드가 바로 아크로(Acro) 모드이다. 아크로 모드는 기체의 수평 유지(Self-leveling) 기능을 완전히 비활성화하고, 조종기의 스틱 입력을 기체의 목표 각속도(Rate Setpoint)로 직접 변환하여 제어하는 방식이다. 본 절에서는 PX4-Autopilot(펌웨어 버전 v1.14 기준)의 아크로 모드 제어 루프가 소프트웨어적으로 어떻게 설계되고 실행되는지 소스 코드를 통해 체계적으로 분석한다.
1. 아크로 모드의 시스템적 특징과 Ardupilot과의 차이
아크로 모드의 핵심은 자세 제어(Attitude Control) 루프인 외부 루프(Outer Loop)를 바이패스(Bypass)하고, 각속도 제어(Rate Control) 루프인 내부 루프(Inner Loop)만을 사용하여 비행을 제어한다는 데 있다.
1.1 PX4-Autopilot과 Ardupilot의 철학적 차이
PX4-Autopilot과 Ardupilot 두 오픈소스 비행 제어 시스템 모두 아크로 모드를 지원하지만, 입력 처리 및 제어 안정화 철학에서 미세한 차이를 보인다.
- PX4-Autopilot: 수학적으로 엄밀한 ’슈퍼 엑스포(Super Expo)’와 같은 비선형 커브를 적용하여 스틱 중앙부에서는 매우 정밀한 제어를, 한계치에서는 극한의 각속도를 낼 수 있도록 분해능을 동적으로 스케일링한다. 이는 레이싱 드론이나 FPV 기체에서 극단적인 기동성을 확보하기 위한 최적화이다.
- Ardupilot: “Acro” 모드 뿐만 아니라 초보자를 돕는 가상 방지망(Virtual Leash) 기능이나 엑스포 값을 파라미터로 처리하여 보다 레거시한 헬리콥터 제어 방식의 연속성을 제공한다. 또한, Ardupilot은
AC_AttitudeControl라이브러리 내에서 모든 회전익 제어를 포괄적으로 다루는 반면, PX4는mc_rate_control과manual_control모듈을 더욱 명확히 분리하여 모듈성을 극대화하였다.
2. 아크로 모드의 소프트웨어 아키텍처 및 제어 흐름
기체에 아크로 모드가 인가될 때의 데이터 흐름은 다음과 같은 단계를 거친다.
graph TD
A[조종기 RC 입력 (RC_CHANNELS)] --> B[Manual Control 모듈]
B -->|스틱 입력 정규화| C[목표 각속도 변환 로직]
C -->|Expo 커브 적용| D[vehicle_rates_setpoint 발행]
E[자세 제어 로직 Bypass] -.-|> D
D --> F[mc_rate_control 모듈]
F -->|PID 제어 및 안티 와인드업| G[actuator_controls 발행]
G --> H[Control Allocation / 믹서]
H --> I[모터 PWM 출력]
비행 모드가 전환되면 PX4의 커맨더(commander) 서브시스템은 기체의 현재 상태 머신을 업데이트하여 자세 제어(Attitude Control) 스레드가 불필요하게 연산을 수행하지 않도록 동작을 중지시키거나 신호를 무시하도록 처리한다. 대신 조종기 입력(manual_control_setpoint)을 직접 수신하여 목표 각속도를 도출한다.
3. 목표 각속도 생성 및 스틱 커브(Expo) 소스 코드 분석
조종기 스틱의 선형적 변위를 회전 운동의 목표값(각속도)으로 변환하는 과정은 src/modules/manual_control/ManualControl.cpp 내에 정의되어 있다. PX4는 파일럿의 조종감을 향상시키기 위해 선형 비례 게인뿐만 아니라 비선형 지수 함수(Exponential Function) 로직을 적용한다.
// src/modules/manual_control/ManualControl.cpp 발췌 (예시 코드)
float ManualControl::apply_acro_expo(float stick_in, float expo, float super_expo, float max_rate)
{
// 1. 스틱 입력의 절대값과 부호 보존
float stick_in_abs = fabsf(stick_in);
float sign = matrix::sign(stick_in);
// 2. 일반 Expo 곡선 적용 (중앙 조종감 향상)
float expo_applied = stick_in_abs * (1.0f - expo) + powf(stick_in_abs, 3.0f) * expo;
// 3. Super Expo 적용 (극한의 각속도를 위한 스케일링)
float denominator = 1.0f - stick_in_abs * super_expo;
// 분모가 0이 되는 것을 방지
if (denominator < 0.0001f) {
denominator = 0.0001f;
}
// 4. 최종 각속도 계산 후 부호와 최대 각속도 곱셈
float rate_setpoint = sign * (expo_applied / denominator) * max_rate;
return rate_setpoint;
}
위의 소스 코드를 살펴보면, expo 파라미터는 스틱이 중앙 근처에 있을 때 조종성을 부드럽게 만들기 위한 3차 함수 기반 보간법을 수행한다. 또한 super_expo는 스틱이 끝으로 갈수록 목표 각속도를 기하급수적으로 증가시켜 조종사가 물리적인 한계를 넘는 플립(Flip)이나 롤(Roll)을 수행할 수 있게 해준다.
4. 내부 제어 루프: Rate Controller(MC Rate Control) 구현
계산된 목표 각속도(vehicle_rates_setpoint)는 내부 제어 루프를 담당하는 src/modules/mc_rate_control/RateControl.cpp 파일로 전달된다. 이 모듈은 현재 자이로스코프에서 계측된 실제 각속도와 목표 각속도의 오차를 계산하여 PID(Proportional-Integral-Derivative) 연산을 수행한다.
// src/lib/pid/pid.cpp 및 RateControl.cpp의 연계 흐름
void RateControl::update(const vehicle_rates_setpoint_s &rates_sp, const vehicle_angular_velocity_s &rates)
{
// 1. 각속도 오차 계산
matrix::Vector3f error;
error(0) = rates_sp.roll - rates.xyz[0];
error(1) = rates_sp.pitch - rates.xyz[1];
error(2) = rates_sp.yaw - rates.xyz[2];
// 2. 비례(Proportional) 제어
matrix::Vector3f torque = error.emult(_gain_p);
// 3. 적분(Integral) 제어 및 안티 와인드업(Anti-Windup)
// 포화(Saturation) 현상이 감지되면 적분값 누적을 멈춤
if (!_mixer_saturated) {
_integral_error += error * _dt;
}
torque += _integral_error.emult(_gain_i);
// 4. 미분(Derivative) 제어 (Low-pass Filter 통과 거침)
matrix::Vector3f rate_derivative = (rates_filtered_prev - rates.xyz) / _dt;
torque += rate_derivative.emult(_gain_d);
// 5. 최종 토크 값을 actuator_controls_s 구조체로 발행
publish_actuator_controls(torque, rates_sp.thrust_body);
}
제어 루프의 핵심은 다음과 같다.
- 고주파 노이즈 억제: 미분항(D-term) 연산 시 센서의 진동 노이즈가 증폭되는 것을 방지하기 위해 소프트웨어 노치 필터(Notch Filter)나 저주파 통과 필터(Low-pass Filter)를 거친 계측값을 활용한다.
- 안티 와인드업(Anti-Windup):
_mixer_saturated플래그를 통해 모터가 이미 한계 출력에 도달한 상황에서 오차가 누적되는 와인드업 현상을 사전에 방지하여, 제어 불능 상태에 빠지지 않도록 유도한다. - 토크와 추력 분리: x, y, z 축에 대한 개별적인 토크 명령(Torque)과 기체 수직 방향의 병진 추력(Thrust) 명령을 결합해 Control Allocation 시스템으로 보낸다.
5. 결론 및 실무적 고려사항
아크로 모드의 소스 코드는 외부의 복잡도(GPS, VIO, 자세 추정 등)를 최대한 걷어내고 기동의 본질에 집중할 수 있도록 고도의 최적화가 이루어져 있다. 제어 알고리즘이나 비행 특성을 튜닝하고자 하는 개발자는 단순히 PID 게인값을 수정하는 것을 넘어, ManualControl 모듈에 구현된 Expo 수식이나 mc_rate_control에서 처리되는 자이로 필터 체인을 이해해야 한다. 향후 추가적인 제어 기법 논문(“Aggressive Flight Maneuvers in Quadrotors” 등)과 결합하여 이 코드 단위를 고도화할 수 있으며, ROS2 환경(Offboard 제어)에서도 아크로 모드와 유사한 형태의 각속도 직접 제어를 응용할 수 있을 것이다.