27.5.4. 기압계 및 고도 퓨전 (`fuseBaro`)

27.5.4. 기압계 및 고도 퓨전 (fuseBaro)

무인항공기가 추락하지 않고 정밀한 3차원 궤적을 그리며 비행하기 위해 절대적으로 확보해야 하는 것은 안정적인 수직 고도(Altitude)다. GPS 고도는 전리층 굴절 지연 등으로 인해 수 미터(m) 단위의 오차를 수시로 내뿜으며, 카메라 기반의 오도메트리(VIO)도 지면의 텍스처(Texture)가 부족하면 발산하기 쉽다. 반면 기압계(Barometer) 는 주변 대기의 압력을 측정하여 비교적 부드럽고 단기적인 정확도(Short-term Accuracy)가 뛰어난 고도 데이터를 제공한다.

PX4-Autopilot의 확장 칼만 필터(EKF2)에서 Ekf::fuseBaro() 함수는 바로 이 기압 고도를 EKF의 핵심 수직 상태 변수(인덱스 9번: p_D, Down Position)에 융합하는 역할을 한다. 본 절에서는 단순해 보이는 1차원 데이터 퓨전이 소스 코드 레벨에서 어떻게 GPS 및 가속도계와 상호 보완적인 파이프라인을 구축하는지 상세히 분석한다.


1. 다중 소스 고도(Altitude Origin) 퓨전의 딜레마

PX4 EKF2 아키텍처는 고도의 기준(Reference)을 단 하나의 소스(Primary Height Source) 에서만 잡도록 설계되어 있다. EKF2_HGT_REF 파라미터를 통해 사용자는 기압계(Baro, 0), GPS(1), 거리 측정 센서(Range Finder, 2) 중 하나를 주(Primary) 고도 소스로 지정할 수 있다.

만약 기압계가 주 데이터 소스로 선택되었다면, fuseBaro()가 호출될 때 다음과 같은 수학적 모델링이 수반된다. 기압계가 측정하는 고도는 EKF 상태 벡터 상 지구 고정 좌표계의 Down(아래쪽) 방향(p_D) 의 역방향(음수)에 해당한다. 즉, 고도가 높아지면 기압은 낮아지고, p_D 는 음수 방향으로 커진다.

1.1 관측 모델과 야코비안(\mathbf{H}) 계산

기압계 데이터는 1차원 스칼라 값이므로 관측 행렬 \mathbf{H} 의 구성은 매우 단순하다. 24차원 벡터 중 Down 위치(인덱스 9번)에만 민감도를 갖는다.

// src/lib/ecl/EKF/baro_fusion.cpp 의 의사코드

// Down Position(p_D)의 예상 관측치. 
// 센서 데이터는 위로 갈수록 (+), p_D는 위로 갈수록 (-) 이므로 부호 반전이 필수
float baro_pred = -_state.pos(2);  

// H 행렬 성분. Down 방면 상태 벡터 인덱스 9번의 미분값은 -1.0
float H_baro = -1.0f;

이렇게 구성된 H 성분과 예상 관측치를 fuse() 템플릿 로직에 던져 넣으면 1회의 스칼라 업데이트(Scalar Update)가 이루어진다.


2. 저주파 융합과 고주파 융합(Complementary Filtering)의 조화

기압계가 단기적 정확도가 뛰어나다고는 하나, 센서 자체의 데이터 갱신 주기(Update Rate)는 통상 50Hz ~ 100Hz 수준에 머무른다. 드론 제어기가 진동(Vibration)을 이겨내고 능동적으로 모터를 제어하기 위한 수백 헤르츠(400Hz)의 고주파 제어에는 턱없이 부족한 시간 해상도다.

fuseBaro() 함수 자체는 EKF 관측 업데이트 루틴으로, 기압계 샘플 링버퍼(_baro_buffer)에 새로운 데이터가 팝업(Pop)될 때만 간헐적으로 실행되는 저주파(Low-frequency) 융합 로직이다.

그렇다면 비행 중 실시간 기체의 수직 속도와 고도는 무엇이 책임지는가? 바로 가속도계(Accelerometer) 다.

  1. 가속도계 적분 (고주파 예측): EKF의 predictState() 단계에서 IMU 가속도계의 Z축(a_Z)을 적분하여 수직 속도(v_D)를 구하고 한 번 더 적분하여 수직 위치(p_D)를 초당 400번씩 매우 부드럽게 예측(Prediction)해 낸다.
  2. 기압계 보정 (저주파 관측): 하지만 이 가속도계 적분치는 시간(dt)에 비례하여 바이어스 오차(Bias Drift)가 무한정 발산한다. fuseBaro()10ms마다 한 번씩 호출되면서, 이 발산하려는 p_D 값을 꾹 눌러 잡아주고 칼만 게인(\mathbf{K})을 통해 역으로 IMU의 Z축 바이어스(인덱스 15번) 상태를 교정(Correction)한다.
flowchart TD
    A[가속도계 Z축 데이터] -->|고주파 400Hz 적분| B(z축 속도 및 고도 예측)
    B --> C[제어기(Position Controller)로 전달]
    
    D[기압계 데이터] -->|저주파 50~100Hz| E{EKF fuseBaro}
    E -->|바이어스 오차 산출| F(Innovation Test)
    F -->|칼만 게인 보정| B

이러한 구조 덕분에 PX4 드론은 가속도계의 응답성(Responsiveness) 과 기압계의 안정성(Stability) 을 모두 챙길 수 있다.


3. 기압계의 혁신 검사 (Innovation Gating) 및 보호 로직

다른 센서들과 마찬가지로 fuseBaro() 내부에서도 혁신 검사(Innovation Gating) 비율(Test Ratio) 연산이 수행된다. 파라미터 EKF2_BARO_GATE (기본값 보통 5.0) 안에 잔차(Residual)가 들어와야만 공분산 업데이트가 승인된다.

3.1 동적 외풍 조작 방어

야외 비행 시 갑작스러운 돌풍(Gust)이 치면 베르누이의 원리에 의해 동체 내부의 동압(Dynamic Pressure)이 변동하며 기압계가 일시적으로 “순식간에 위로 솟구쳤다“라고 착각하게 만드는 외란이 발생한다.
이때 기압계 잔차는 크게 튀어서 게이트 바깥으로 기각(Rejected)된다. EKF는 이 데이터를 무시하고 자신의 가속도계 추정치를 믿고 버틴다. 돌풍이 지나가 잔차가 다시 5.0배수 이하로 들어오면 자연스럽게 퓨전이 재개된다.

3.2 GPS 고도와의 페일오버(Fail-over) 연계

만약 기압계의 하드웨어 포트가 침수되거나 열화되어 장기간 Test Ratio가 1.0을 초과한다면 어떻게 될까? PX4 EKF2는 파라미터로 설정된 주요 고도 소스(Primary Source)를 강제로 포기하고, 즉시 사용 가능한 보조 소스(예: GPS의 3D 고도, fuseVelPosHeight의 Down 요소) 데이터를 새로운 기준점(Reference)으로 가로채는 대체 퓨전(Fallback) 기능을 작동시킨다. 이는 EKF 상태 관리 모듈 레벨에서 고도 시스템의 생존성을 이중으로 뒷받침하는 핵심 로직이다.


4. 소결

PX4의 기압계 퓨전 로직 fuseBaro() 자체는 -1.0이라는 초라해 보이는 야코비안 행렬 스칼라 하나를 넘겨주는 매우 단순한 함수처럼 보일 수 있다. 하지만 이를 품고 있는 EKF2 아키텍처는 가속도계의 적분 드리프트를 단단하게 무효화 시키는 닻(Anchor)으로서 이 1차원 데이터를 극도로 우아하게 활용한다.

이어지는 내용에서는 기압계가 지닌 물리학적, 환경적 치명타인 ‘온도 변화에 따른 드리프트(Thermal Drift)’ 현상과 이를 소프트웨어 레벨에서 필터링하기 위한 PX4의 고도화된 추정 로직을 집중적으로 분석한다.