Chapter 29. 수동 비행 모드(Manual, Stabilized, Acro) 소스 코드 분석
- 29.1 수동 비행 제어 소프트웨어 스택 및 아키텍처 심층 분석
- 29.1.1 FlightModeManager 스레드 구조 및 모드 라우팅 로직 (
src/modules/flight_mode_manager)
- 29.1.1.1
FlightModeManager.cpp의 메인 실행 루프 및 이벤트 폴링(Event Polling) 주기 최적화 코드 분석
- 29.1.1.2
vehicle_control_mode_s 구조체 내 제어 플래그 비트맵 분석 (수동 제어, 자세 제어, 각속도 제어 플래그의 논리합 조합 로직)
- 29.1.1.3 상태 머신(State Machine) 전환 논리에 따른 하위 비행 태스크(Flight Task) 동적 인스턴스화 및 메모리 해제 메커니즘
- 29.1.2 수동 모드 uORB 메시지 파이프라인 데이터 흐름도 (엔드투엔드)
- 29.1.2.1 입력단:
input_rc_s 구조체의 원시 타임스탬프 처리 및 다채널 배열 신호 수신 로직
- 29.1.2.2 처리단:
manual_control_setpoint_s 구조체의 축별 정규화 필드 및 보조 스위치 제어 신호 맵핑
- 29.1.2.3 출력단: 목표 자세, 목표 각속도, 최종 액추에이터 제어 명령으로 이어지는 제어 권한 위임(Delegation) 소스 흐름
- 29.2 하드웨어 드라이버 및 조종기(RC) 입력 전처리 커널 분석 (
src/modules/manual_control)
- 29.2.1 UART/SBUS/CRSF 인터럽트 처리 및 제어 신호 퍼블리싱 (
src/drivers/rc_input)
- 29.2.1.1 하드웨어 타이머 인터럽트 기반 통신 프로토콜 프레임 디코딩 C/C++ 소스 분석
- 29.2.1.2 직접 메모리 접근(DMA) 기술을 활용한 수신 버퍼 처리 및 CPU 점유율 최소화 기법
- 29.2.1.3 독립 스레드에서의 유효 프레임 카운팅 및 조종기 입력 데이터 uORB 퍼블리싱 조건문 분석
- 29.2.2
ManualControl 클래스의 제어 신호 정규화(Normalization) 알고리즘 (ManualControl.cpp)
- 29.2.2.1 선형 보간법(Linear Interpolation)을 이용한 원시 통신 신호의 유효 제어 범위 실수형 정규화 코드 (
apply_calibration() 함수)
- 29.2.2.2 캘리브레이션 트림(Trim) 값 오차에 따른 비대칭(Asymmetric) 스케일링 보상 수학적 모델 소스 레벨 검증
- 29.2.2.3 스틱 방향 역전 비트 연산 및 부호 반전 알고리즘 로직
- 29.2.3 조종감(Feel) 최적화를 위한 비선형 디지털 신호 처리(DSP) 알고리즘 (
src/lib/mathlib)
- 29.2.3.1 스틱 짐벌 마모를 고려한 데드존(Deadzone) 필터링: 분기 예측(Branch Prediction) 최적화가 적용된 필터 소스
- 29.2.3.2 엑스포넨셜 커브 피팅: 중앙부 미세 제어를 위한 3차 다항식 모델(Cubic Polynomial Model) 매핑 소스 (
math::expo())
- 29.2.3.3 수신 신호 지터(Jitter) 제거를 위한 1차 저주파 통과 필터(1st-order IIR LPF): 시정수(Time constant) 및 이산화(Discretization) 모델 수식
- 29.2.4 다중 관제(RC vs GCS) 충돌 해결 및 다중화(Multiplexing) 시스템
- 29.2.4.1 MAVLink 수동 제어 메시지 수신 시 수신 핸들러 함수 분석
- 29.2.4.2 제어 권한 파라미터에 따른 통신 소스 선택기(Source Selector) 제어 흐름 및 하위 스코프 분석
- 29.2.4.3 통신 소스 혼용 모드에서의 입력 스위칭 지연(Hysteresis) 및 플로팅(Floating) 현상 방지 코드
- 29.3 매뉴얼(Manual) 모드 제어 바이패스(Bypass) 로직 분석
- 29.3.1 기체 동역학 아키텍처별 매뉴얼 제어 분기 (
src/modules/commander/commander.cpp)
- 29.3.1.1 멀티로터 동역학 불안정성으로 인한 순수 매뉴얼 모드 차단 및 자세 안정화(Stabilized) 모드 강제 전환(Fallback) 조건문 소스
- 29.3.1.2 고정익 공기역학 모델 및 로버 지상 제어 모델에서의 직접 제어면(Control Surface) 개입 허용 논리 검증
- 29.3.2 고정익 다이렉트 패스스루(Direct Passthrough) 알고리즘 (
src/modules/fw_att_control)
- 29.3.2.1
FlightTaskManual 기반 스틱 입력 데이터의 직접 메모리 복사 연산 과정
- 29.3.2.2 메인 제어 루프 내 수동 제어 활성화 플래그 검사 시 PID 피드백 제어 연산 생략(Bypass) 코드 분석
- 29.3.2.3 믹서(Mixer) 모듈로 직행하는 액추에이터 제어 배열 할당 및 제어값 클리핑(Clipping) 로직
- 29.3.3 매뉴얼 모드 안전 장치 및 EKF 독립성 검증
- 29.3.3.1 확장 칼만 필터(EKF) 추정 상태 발산 시 상태 머신이 매뉴얼 모드 제어권을 최우선으로 유지하는 구조적 이유
- 29.3.3.2 시동 활성화 상태에서의 스로틀 아이들(Idle) 최저 출력 강제 유지 시스템 안전 코드
- 29.4. 안정화(Stabilized) 모드 제어 루프 소스 코드 분석
- 29.4.1. 자세 목표 생성기(Attitude Setpoint Generator) 아키텍처 (
src/lib/FlightTasks/tasks/ManualPosition)
- 29.4.1.1. 조종 입력값을 목표 오일러 각(Euler Angle)으로 변환: 최대 기울기 파라미터 연동 비례 연산 및 한계 구속 함수(
math::constrain) 적용
- 29.4.1.2. 요(Yaw) 입력의 동적 적분: 오일러 각 누적 적분 방정식 코드 및 짐벌 락(Gimbal Lock) 방지를 위한 회전각 임계 범위 정규화 로직
- 29.4.1.3. 3차원 회전 변환: 오일러 각 객체 생성 후 쿼터니언(Quaternion) 대수계로의 캐스팅 연산자 오버로딩 소스 분석
- 29.4.2. 추력(Thrust) 및 고도 보상 매핑 알고리즘
- 29.4.2.1. 스틱 중앙값을 호버링 추력 기저값으로 일치시키는 비선형 조각 함수(Piecewise function) 변환 수식
- 29.4.2.2. 뱅크각 보상(Bank Angle Compensation): 삼각함수 기반의 고도 유지 추력 보상 방정식을 적용하여 기체 기울어짐에 따른 수직 추력 손실을 보상하는 C++ 구현부
- 29.4.2.3. 배터리 전압 강하 모니터링 시스템 연동 및 추력 설정점 동적 스케일링(Dynamic Scaling) 로직
- 29.4.3. 자세 제어기(Attitude Controller - Outer Loop) 핵심 소스 (
src/modules/mc_att_control/AttitudeControl.cpp)
- 29.4.3.1. 제어 루프 내 EKF 현재 쿼터니언 상태량과 목표 쿼터니언 간의 쿼터니언 회전 오차 연산 공식 적용 코드
- 29.4.3.2. 최단 회전 경로(Shortest Rotation Path) 결정을 위한 에러 쿼터니언의 스칼라부 부호 확인 및 기하학적 반전 로직
- 29.4.3.3. 비례 제어(Proportional Control): 자세 오차 벡터 요소에 제어 이득(Gain)을 행렬 곱 연산(Matrix Multiplication)으로 처리하는 구조
- 29.4.3.4. 도출된 제어량을 목표 각속도 포맷으로 변환 및 피드포워드(Feedforward) 제어항 가산 로직
- 29.5. 아크로(Acro) 모드 제어 루프 소스 코드 분석
- 29.5.1. 아크로 모드 스레드 제어 분리 및 자세 제어 루프 우회
- 29.5.1.1. 커맨더 모듈에서 자세 제어 플래그 비활성화 및 각속도 제어 플래그 활성화로 설정되는 논리적 상태 전이 추적
- 29.5.1.2. 외부 루프(Outer Loop) 제어 스레드의 대기 상태 진입 또는 연산 생략을 유도하는 구조적 조건문 확인
- 29.5.2. 목표 각속도 변환(Rate Setpoint Generation) 동역학 모델 (
src/modules/manual_control/ManualControl.cpp)
- 29.5.2.1. 선형 비례 연산: 스틱 입력값과 최대 각속도 파라미터 간의 선형 비례 방정식 구조
- 29.5.2.2. 슈퍼 엑스포(Super Expo) 비선형 함수: 극한의 기동성을 위한 지수 함수 기반 제어량 증폭 모델의 C++ 구현 소스
- 29.5.2.3. 아크로 엑스포(Acro Expo) 적용: 중앙 제어 영역의 분해능(Resolution) 향상을 위한 비선형 곡선 튜닝 알고리즘
- 29.5.3. 각속도 제어기(Rate Controller - Inner Loop) 핵심 소스 (
src/modules/mc_rate_control/RateControl.cpp)
- 29.5.3.1. 각속도 센서 지연 최소화를 위한 고속 폴링(High-speed Polling) 및 노치 필터(Notch Filter) 연동부
- 29.5.3.2. PID 연산 코어 (
src/lib/pid/pid.cpp 호출부): 오차 계산, 비례항, 적분항 누적, 저주파 통과 필터가 적용된 미분항 연산의 순차적 시퀀스 분석
- 29.5.3.3. 적분기 누적 포화 방지(Integrator Wind-up Protection): 포화 상태 감지 시 적분 누적을 즉각 정지시키는 안티 와인드업(Anti-windup) 알고리즘
- 29.5.3.4. 최종 믹서 입력값인 3축 회전 모멘트(Torque) 및 병진 추력(Thrust) 명령어 합성 및 유효 범위 정규화 소스
- 29.5.4. 극한 기동 튜닝 보조 메커니즘
- 29.5.4.1. Acro Trainer 모드: 자세 제어기가 백그라운드에서 동작하며, 설정된 피치/롤 각도 한계를 초과할 때 각속도 명령을 오버라이드(Override)하는 하이브리드 제어 알고리즘
- 29.5.4.2. 에어모드(Airmode): 자유 낙하 시에도 기체 제어력을 상실하지 않도록 믹서 포화 검사기를 우회하여 PID 루프를 강제 활성화하는 제어 보장 로직
- 29.6. 수동 모드 간 상태 전이(State Transition) 메커니즘 소스 분석
- 29.6.1. 상태 머신(State Machine) 제어 로직 (
src/modules/commander/state_machine_helper.cpp)
- 29.6.1.1. 조종기 스위치 할당 파라미터에 따른 물리적 채널 값의 상태 임계치(Threshold) 판별 로직
- 29.6.1.2. 상태 전환 함수 내 모드 전환 사전 조건(Pre-condition) 검증: 센서 건강 상태, 시동 유무, 상태 추정기 유효성 확인 분기문
- 29.6.2. 범플리스 트랜스퍼(Bumpless Transfer) 제어 연속성 알고리즘
- 29.6.2.1. 제어 모드 전환 시 튐(Jerking) 방지: 전환 직전의 EKF 상태 추정치를 목표 자세로 동기화하여 초기 오차율을 영점화(Zeroing)하는 C++ 구현부
- 29.6.2.2. 내부 제어기 초기화: 모드 전환 감지 시 각속도 제어기 내의 PID 객체 내부 누적 상태 및 이전 오차 변수를 클리어하는 초기화 함수 호출 추적
- 29.6.3. 센서 결함 감지 및 자율 폴백(Autonomous Fallback) 시스템
- 29.6.3.1. 위성 항법 장치 수신 오차 임계치 초과 또는 EKF 위치 추정 실패 시, 위치 제어 모드에서 자세 안정화 모드로 강제 상태 하향(Downgrade)을 트리거하는 인터럽트 소스
- 29.6.3.2. 폴백 발생 시 관제 시스템으로 전송되는 청각적 경고(Buzzer) 및 비주얼 텍스트 경고 메시지 생성 파이프라인
- 29.7 수동 제어 예외 상황(Edge Case) 처리 및 소프트웨어 디버깅 기법
- 29.7.1 스틱 제스처(Stick Gestures) 기반 하드웨어 제어 커맨드 분석
- 29.7.1.1 스틱 시동 논리: 특정 조종 축의 극단점 배치를 논리적 시간 카운터로 검증하여 시동 활성화 플래그를 변경하는 로직
- 29.7.1.2 시동 전제 조건 검사: 메인 추진체 스로틀 입력이 최하단 기저점에 근접하지 않았을 때 인터락(Interlock) 해제를 거부하는 물리적 안전 확보 분기문
- 29.7.2 극단적 자세 및 동역학적 특이점 한계 상황 처리
- 29.7.2.1 짐벌 락(Gimbal Lock) 근접 시 쿼터니언 미분 발산 방지: 피치 각도의 수직 한계 임계점 부근에서 특이점(Singularity)을 우회하고 계산 값을 클리핑하는 소스 코드
- 29.7.2.2 자유 낙하(Freefall) 및 역방향(Inverted) 기동 감지: 중력 가속도 벡터 변화를 감지하여 일시적으로 적분 제어항 누적을 멈추는 동적 제어 이득(Gain) 스케줄링 구현부
- 29.7.3 비행 데이터 로깅(ULog) 기반 수동 모드 제어 성능 심층 분석법
- 29.7.3.1 제어 시스템 지연(Latency) 계산 쿼리: 입력 제어 토픽의 타임스탬프와 액추에이터 출력 토픽의 타임스탬프 간 시스템 클럭 델타값을 추출하는 로깅 분석 기법
- 29.7.3.2 주파수 응답성 보드 플롯(Bode Plot) 분석을 위한 로그 추출: 목표 입력과 실제 센서 출력 데이터 매칭을 통해 수동 제어 루프의 대역폭(Bandwidth) 및 위상 여유(Phase Margin)를 분석하는 방법론
- 29.7.4 수동 제어 소스 코드 사용자 정의(Customization) 실무 가이드
- 29.7.4.1 상태 머신 매니저의 팩토리 패턴(Factory Pattern)을 수정하여 사용자 정의 특수 비행 모드 클래스를 의존성 주입(Dependency Injection)하는 펌웨어 수정 방법
- 29.7.4.2 빌드 시스템 환경 설정 파일(
CMakeLists.txt) 내 컴파일 타겟 추가 및 Kconfig 연동을 통한 신규 제어 파라미터 등록 절차