18.7.1.2 세대 카운터 변화량 산출을 통한 실시간 발행 주기(Rate, Hz) 및 메시지 유실률(Drop Rate) 계산 공식
uorb top은 활성 토픽의 목록만 달랑 보여주고 끝나는 것이 아니라, 해당 토픽이 현재 몇 Hz로 퍼블리싱되고 있는지(Rate), 그리고 시스템의 부하 등 모종의 이유로 인해 큐에서 밀려나 지워진(Drop) 메시지가 어느 정도인지 실시간으로 계산하여 화면에 시연해 준다.
이와 같은 동적 통계치 산출은 무거운 타이머나 복잡한 로깅 인터페이스 없이, 각 노드 내부에 존재하는 ‘세대 카운터(Generation Counter)’ 통계의 시계열적 비교만을 통해 아주 수학적이고 가볍게 계산된다.
1. 실시간 발행 주기 (Publishing Rate, Hz) 산출 로직
uorb top 로직은 이전(Previous) 타임스탬프 t_{n-1}에 측정해 놓았던 전역 세대 카운터 값 G_{n-1}을 미리 기억해 둔다. 그리고 1초(또는 지정된 갱신 간격 \Delta t) 뒤인 t_n 시점에서 다시 노드의 최신 전역 세대 카운터 값 G_n을 얻어온다.
따라서 현재 퍼블리셔가 데이터를 밀어 넣고 있는 실시간 주파수(Rate_{pub}) 계산은 단순히 다음 공식으로 도출된다.
Rate_{pub} = \frac{G_{n} - G_{n-1}}{\Delta t_{sec}} \quad \text{[Hz]}
(단, \Delta t_{sec} = (t_n - t_{n-1}) / 1,000,000 (마이크로초를 초로 환산))
이 수식은 타임스탬프와 카운터만으로 동작하므로 퍼블리셔에게 어떠한 오버헤드도 전가하지 않는 완벽한 수동적(Passive) 관찰 방식이다.
메시지 유실률 (Drop Rate) 산출 로직
메시지 유실(Drop)은 퍼블리셔가 링 버퍼에 데이터를 쓰는 속도가, 특정 구독자가 데이터를 퍼가는 속도보다 빨라서 미처 읽히지 못한 낡은 데이터가 새로운 데이터에 의해 덮어써져 버렸을 때 발생한다.
각 Subscriber 객체는 자신이 이전에 읽었던 ’로컬 세대 카운터’와 데이터를 최신으로 읽어내려고 할 때 마주친 ’노드 전역 세대 카운터’의 차이를 바탕으로, 자신이 몇 개의 메시지를 건너뛰었는지(Drop) 인지할 수 있다. PX4는 이 유실 카운트를 누적하는 변수(_subscriber_lost_messages)를 개별 구독자 객체마다 관리한다.
uorb top은 특정 토픽(노드)에 매달린 전체 구독자 명단을 순회하며, \Delta t 시간 동안 증가한 ’잃어버린 메시지 총합의 델타값(\Delta D_{total})’을 합산해 낸다. 이 누적 데이터 손실량을 통해 유실률을 초 단위로 계산한다.
Rate_{drop} = \frac{\sum_{i=0}^{K} (D_{i,n} - D_{i,n-1})}{\Delta t_{sec}} \quad \text{[Hz]}
(단, K는 해당 토픽에 매달린 구독자의 총수, D_i는 i번째 구독자의 누적 유실 카운트)
2. 통계 산출 로직의 아키텍처적 의의
이처럼 단순히 세대 카운터 값 두 개(Global, Local)를 조합하여 레이트(Hz)와 드롭(Drop) 상태를 완벽히 역산해내는 구조는 uORB 아키텍처 설계의 백미 중 하나이다.
비행 코드 본연의 임무에 전혀 영향을 끼치지 않으면서도, 개발자가 uorb top 명령을 통해 특정 센서의 주파수가 반 토막이 났다거나 (I2C 버스 에러 암시 등), 혹은 특정 모듈에서 Drop Rate가 치솟고 있다는 것 (해당 스레드가 CPU 기아 현상을 겪고 있음을 암시 등)을 한눈에 라이브로 직관하게 해 주는 강력한 진단 렌즈가 되는 것이다.