21.5.3. 런타임(Runtime) 파라미터 동적 업데이트 설계
수천 개의 파라미터를 SD 카드에서 읽어와 내 C++ 변수에 예쁘게 담는 과정(초기화)을 성공적으로 마쳤다.
하지만 진짜 지옥은 비행 도중(Runtime)에 사용자가 조종기 다이얼이나 마우스 휠을 돌려 이 파라미터 값을 갑자기 바꿔버렸을 때 일어난다.
“P 게인 값을 기존 1.5에서 2.0으로 바꿨습니다!”
이 변동 사실을 제어기(Controller)의 1000Hz짜리 메인 런루프(Run-loop) 속으로 0.1초의 지연도 없이, 그리고 메모리 충돌 없이 곧장 밀어 넣어야만 드론이 춤을 추지 않고 안정적으로 비행을 이어갈 수 있다.
이를 달성하기 위해 PX4는 매우 독특하고 강력한 비동기 토픽(Topic) 구독 모델을 런타임 업데이트 설계의 핵심으로 채택했다.
1. 무식한 폴링(Polling)의 참사
만약 PX4 시스템이 없었다면 초보 개발자들은 런루프 안에서 매 사이클마다 이렇게 코딩했을지도 모른다.
void CustomApp::Run() {
while (!should_exit()) {
// [절대 금지] 1000번 반복될 때마다 파라미터 서버에 통신을 시도함!
param_get(my_param_handle, &_my_speed);
// 제어 로직 수행...
calculate_pid();
}
}
제어 루프는 1초에 수백, 수천 번을 도는 극도로 예민한 공간이다. 거기에 대고 매번 운영체제 커널을 두드리며 “파라미터 바뀐 거 있나요?“라고 물어보는 원시적인 함수(param_get)를 호출한다면, 1000Hz 루프는 삽시간에 10Hz로 병목(Bottleneck)이 걸려버린다.
아무리 템플릿 최적화가 잘 된 _param_custom_app_max.update() 메서드라도 런루프 안에서 매 틱(Tick)마다 맹목적으로 호출하는 것은 심각한 CPU 낭비이다.
2. uORB 토픽 구독 (Publish-Subscribe) 모델의 도입
이 병목을 끊어내기 위해 PX4는 비행 데이터 통신망인 **uORB (Micro Object Request Broker)**를 파라미터 업데이트 알림망으로 전격 차용했다.
설계 철학은 아주 단순 명료하다.
- 사용자가 QGC에서 어떤 값을 딱 하나 수정하고 엔터를 친다.
- 파라미터 글로벌 서버(데몬)가 이 변경 사항을 감지하고, 시스템 전역에
parameter_update_s라는 이름의 uORB 알림 방송(Broadcast)을 한 번 쾅! 하고 쏘아 보낸다. - 내 모듈은 평소에는 자기 할 일만 미친 듯이 하다가, 오직 저 방송이 내 귀(Subscriber)에 들렸을 때만, 아주 잠깐 멈춰서 파라미터 동기화 함수(
updateParams())를 호출한다.
이 방식을 통해 런루프는 파라미터를 감시하는 데 단 1클럭의 CPU 자원도 낭비하지 않게 되며, 오직 진짜 값이 변했을 때만 반응형(Reactive)으로 동작하는 아름다운 비동기 데이터 파이프라인이 완성된다.
그렇다면 C++ 코드로 이 parameter_update_s 방송을 어떻게 구독(Subscribe)하고 런루프 안에서 어떻게 빠르게 검사하는지, 실제 구현 코드를 다음 단원(21.5.3.1)에서 낱낱이 파헤쳐보겠다.