### 0.0.1 EKF2 모듈 내부 sensor_gps 구독(Subscription) 주기 및 폴링 스레드 동작 원리
uORB 버스에 무사히 안착한 sensor_gps 데이터는, 이제 EKF2(Extended Kalman Filter 2) 모듈이라는 거대한 소비자의 선택을 기다린다. EKF2는 수많은 센서를 엮어 기체의 상태를 추정하는 만큼, 그 내부의 스레드 스케줄링 로직은 톱니바퀴처럼 정교하게 맞물려 돌아가야 한다.
본 절에서는 EKF2 모듈이 sensor_gps 토픽을 언제, 어떻게, 어떤 주기로 꺼내어 읽어가는지(Subscribe) 그 심장부의 폴링(Polling) 메커니즘을 해부한다.
0.1 ekf2_main 스레드의 주기: IMU 구동(Driven) 아키텍처
먼저 EKF2의 스케줄링 심장 박동(Heartbeat)이 누구에 의해 결정되는지 이해해야 한다. EKF2는 GPS가 데이터(10Hz)를 줄 때마다 깨어나는 구조가 아니다.
- EKF2 메인 루프(
Run())의 구동 주파수는 전적으로 관성 센서(IMU) 데이터의 유입 속도(보통 250Hz ~ 400Hz)에 완벽하게 동기화(Sync)되어 있다. - uORB 모듈 중
sensor_combined(IMU 데이터 묶음) 토픽을 수신할 때 사용되는poll()함수가 EKF2 스레드의 블로킹 타임아웃을 관장한다. 즉, 새로운 가속도/자이로 데이터가 1 틱(Tick) 들어올 때마다 EKF2 루프는 정확히 1바퀴 회전하며 예측(Prediction) 단계를 수행한다. - 이 짧은 주기(약 2.5 ~ 4 밀리초) 동안 루프는 “IMU 데이터 가져오기 \rightarrow 기구학 적분(예측) \rightarrow 다른 보조 센서들(GPS, Mag, Baro 등) 새로 들어온 거 있는지 확인 \rightarrow 보정(Correction)” 이라는 4박자 사이클을 쉼 없이 반복한다.
0.2 비동기 무충돌 구독: orb_copy와 updated 플래그
EKF2 루프가 400Hz로 팽팽하게 돌아가는 와중에, 100ms(10Hz)에 한 번꼴로 느릿하게 들어오는 GPS 데이터를 어떻게 놓치지 않고 낚아채는 것일까?
- 매 루프(IMU 틱)마다 EKF2는 GPS 구독 핸들(
_gps_sub)에 대고orb_check()함수를 호출한다. 이 함수는 토픽 버퍼에 “업데이트된 새 데이터(Dirty flag)가 있는지 없는지“를 단 몇 개의 사이클(Boolean 체크)만으로 판단한다. - 만약
updated = false라면, EKF2는 0.1마이크로초도 지체하지 않고 곧바로 기압계나 나침반 검사 로직으로 넘어간다. - 정확히 10Hz의 주기가 맞아떨어져
updated = true가 뜨는 틱(Tick)이 찾아오면, 비로소orb_copy()를 호출하여sensor_gps_s구조체 전체 메모리를 자신의 로컬 인스턴스에 복사해 넣는다. - 이러한 폴링(Polling) 앤 체크(Check) 메커니즘은 락(Lock)이나 세마포어(Semaphore)에 의한 스레드 블로킹을 원천 차단하여, 단일 스레드로 구성된 EKF2가 다중 센서를 처리함에도 연산 주기를 절대로 놓치지(Miss) 않게 만드는 비결이다.
0.3 멀티 인스턴스(Multi-instance) 순회와 최적 선택
앞 절에서 sensor_gps 토픽이 0번과 1번 슬롯(Primary/Secondary)으로 멀티 퍼블리싱될 수 있음을 확인했다. EKF2의 폴링 루프는 매 틱마다 이 다수의 인스턴스들을 모두 순회(Iterate)하며 체크한다.
- 배열 풀링(Array Polling): EKF2는 내부에 여러 개의 GPS 구독 파일 디스크립터(fd) 배열을 갖고 있다. 매 루프마다
for문을 돌리며 모든 슬롯의updated상태를 다 까본다. - 데이터 소화(Ingestion) 및 지연 버퍼 투입: 업데이트가 확인된 슬롯의 데이터들은
orb_copy()로 퍼 올린 즉시 융합 로직(Fusion)으로 직행하지 않는다. 대신 EKF2 내부의 **‘GPS 데이터 관측 링 버퍼(Observation Ring Buffer)’**라는 대기실로 일단 밀어 넣어진다. - 최고 품질 판독기(Score Evaluator): 이 대기실로 밀어 넣기 전, 혹은 융합 직전에 EKF2 매니저는 0번에서 온 데이터와 1번에서 온 데이터의 위성 개수(Num Sats), 수직/수평 신뢰 구간(
epv,eph), 나아가 재밍(Jamming) 인디케이터 수치를 종합 평가하는 스코어링(Scoring) 함수를 돌린다. 여기서 진정한 ’현재의 메인 GPS’가 결정되어 필터 보정에 투입된다.
요약하자면, EKF2의 GPS 데이터 인입 스레드 로직은 “IMU의 맹렬한 틱(Tick) 사격 속에서, 비동기 체크(orb_check)라는 거름망을 흔들어 100ms마다 한 번씩 떨어지는 굵직한 GPS 알맹이만 건져내어 스코어를 매기는 정교한 사금 퍼내기(Panning) 작업“과 정확히 일치한다.