### 0.0.1 EKF2 내부의 Innovation Test(관측치와 EKF 예측치 간의 잔차 검증) 실패 판별 소스 코드 및 임계값(EKF2_GPS_V_GATE, P_GATE) 분석
모든 다중 경로(Multipath) 신호나 GPS Glitch가 기체의 추락으로 이어지는 것은 아니다. PX4의 심장인 EKF2 알고리즘 내부에는 이 불량 데이터들이 함부로 위치 추정 로직(State Vector)에 섞여 들어가지 못하도록 철저한 수문장(Gatekeeper) 코드가 이식되어 있다.
본 절에서는 EKF2 모듈 내부의 혁신 테스트(Innovation Test) 소스 코드 구조를 해부하고, 이 검증을 통과해야만 데이터를 받아들이는 핵심 게이트 임계값 파라미터(EKF2_GPS_V_GATE, EKF2_GPS_P_GATE)의 물리적 의미를 분석한다.
0.1 혁신(Innovation) 연산과 잔차(Residual) 검증의 수학적 배경
src/modules/ekf2/ 디렉토리 하위의 핵심 코드들(예: EKF/gps_control.cpp 또는 EKF/control.cpp)을 열어보면, GPS 데이터를 융합(Fusion)하기 직전에 항상 혁신 값과 혁신 분산(Innovation Variance)을 계산하는 것을 볼 수 있다.
수학적으로 위치 혁신 벡터(Innovation Vector, \vec{\tilde{y}})는 다음과 같이 정의된다.
\vec{\tilde{y}} = \vec{z}_{gps} - h(\vec{x}_{pred})
- \vec{z}_{gps}: 방금 수신기가 던져준 원시(Raw) GPS 측정값.
- h(\vec{x}_{pred}): 현재 기체의 내부 상태(IMU 적분값 기반) 행렬을 예측 모델 h() 에 넣어 계산해 낸, ‘이론상 GPS가 내놓았어야 할 위치’.
혁신(Innovation)은 다름 아닌 관측치와 예측치의 차이(잔차, Residual) 다. 이 차이가 0에 가까울수록 센서와 EKF2 예측 모델이 완벽히 동기화되어 있다는 뜻이다.
0.2 혁신 테스트(Innovation Test) 통과 조건과 소스 코드 로직
코드 내부에서는 단순히 혁신의 절대적인 크기(m)만 보지 않는다. EKF2는 자신의 ’불확실성(Covariance)’까지 고려하여, 통계적으로 이 혁신 값이 얼마나 뜬금없는 수치인지를 비율(Test Ratio) 로 나타낸다. (이를 정규화된 혁신 제곱(Normalized Innovation Squared) 게이트, 즉 NIS Gate 방식이라고 한다).
수식화된 판별 조건은 대체로 다음과 같은 논리 흐름을 가진다.
// (EKF2 소스코드 상의 논리적 흐름 예시)
float test_ratio = sq(innovation) / (innovation_variance * sq(gate_size));
if (test_ratio > 1.0f) {
// Gate Test Failed!
_gps_check_fail_status.flags.pos_failed = true;
reject_gps_data();
} else {
// Gate Test Passed. Proceed with fusion.
fuse_gps_data();
}
test_ratio가 1.0보다 크다는 것은, 계산된 위치 오차가 사용자가 파라미터로 허용한 최대 표준편차(gate_size) 경계선을 벗어났음을 의미한다.- 이 순간 EKF2는 해당 데이터 패킷을 미련 없이 버리고(Reject), 내부 상태 변수(State Vector) 업데이트를 건너뛴다.
0.3 EKF2_GPS_V_GATE 및 EKF2_GPS_P_GATE 파라미터 분석
수문장의 빗장을 얼마나 단단히 걸어 잠글지, 아니면 얼마나 너그럽게 허용할지를 결정하는 것이 바로 QGC에서 튜닝 가능한 GATE 파라미터들이다.
EKF2_GPS_V_GATE(속도 게이트): 단위는 표준편차(SD, \sigma)다. 기본값은 보통 5.0 가량이다. 이는 EKF 내부 예측 분산 대비 5배(5\sigma)가 넘는 거대한 속도 오차 스파이크(Spike)가 들어올 때만 막아낸다는 뜻이다.EKF2_GPS_P_GATE(위치 게이트): 마찬가지로 기본값은 5.0이다.
파라미터 튜닝의 딜레마 (Trade-off):
- 게이트 좁히기 (예: 2.0 ~ 3.0 설정): 빗장을 매우 좁게 설정하면 작은 다중 경로 오차(Glitch)에도 민감하게 반응하여 데이터를 튕겨낸다. 도심 환경에서 기체가 갑자기 튀는 현상을 철저히 막을 수 있지만, 부작용으로 정상적인 비행 상황에서도 툭하면 “GPS Rejected” 알람이 뜨며 드론이 혼자 무서워서 위치 제어(Position Hold) 모드를 해제해 버릴 수 있다.
- 게이트 넓히기 (예: 10.0 이상 설정): 빗장을 너무 느슨하게 풀면, 거의 모든 GPS 측정치를 받아들인다. 필터 기각(Rejection)이 잘 안 걸리므로 짜증 나는 경고 메시지는 줄어들지만, 대형 반사파를 얻어맞아 기체가 10m씩 텔레포트(Fly-away) 하더라도 EKF가 묵인해 버리는 치명적인 관제 공백이 발생한다.
결국 이 게이트 임계값의 분석과 튜닝은, ’다중 경로 에러를 얼마나 기민하게 막아낼 것인가’와 ‘얼마나 자주 폴백(Fallback) 모드 진입의 불편함을 감수할 것인가’ 사이의 고도의 정밀 타협 기법이라 할 수 있다.