18.7 성능 프로파일링 및 내부 디버깅 메커니즘
수백 개의 토픽이 눈에 보이지 않게 교차하며 오가는 uORB 아키텍처 내부에서, EKF 필터가 갑자기 발산하거나 기체가 제멋대로 요동치기 시작했다면 엔지니어는 어디서부터 디버깅을 시작해야 할까?
“센서 데이터가 너무 빨리 들어와서 큐가 넘쳤는가(Overflow)?”, “아니면 특정 제어기가 데이터를 너무 늦게 가져가고(Starvation) 있는가?” 와 같은 질문에 답하기 위해, PX4는 JTAG 디버거 없이도 실시간 비행 중에 미들웨어의 건강 상태를 진단할 수 있는 가장 강력한 내장형 (Built-in) 프로파일링 도구들을 제공한다.
1. uorb top: 미들웨어 실시간 성능 모니터링
리눅스의 top 명령어가 프로세스의 CPU/RAM 점유율을 보여주듯, PX4의 NuttShell(NSH)에서 실행할 수 있는 uorb top 명령어는 현재 런타임 시스템의 uORB 통신 대역폭과 병목 현상을 실시간으로 렌더링해 보여준다.
이 도구는 uORB 매니저가 전역적으로 관리하고 있는 디바이스 노드 링크드 리스트(uORBDeviceMaster)를 순회하며 다음과 같은 치명적 단서들을 화면에 뿌려준다.
- 발행 주기 (RATE): 현재 해당 토픽이 1초에 몇 번(Hz) 발행되고 있는지 나타낸다. (예:
sensor_gyro가 400Hz가 아닌 200Hz로 찍히고 있다면 버스 통신이나 드라이버 설정에 문제가 있는 것이다). - 구독자 수 (SUB): 현재 이 토픽의 파이프에 몇 개의 모듈이 빨대를 꽂고(구독 중인지) 있는지 추적할 수 있다.
- 데이터 손실 (LOSS): 가장 중요한 디버깅 지표 중 하나다. 발행자는 400Hz로 쏘고 있는데 구독자의 콜백이 늦게 깨어나거나 큐 사이즈가 너무 작으면, 세대 카운터가 어긋나며 미처 읽지 못한 데이터가 버려진다.
LOSS열의 숫자가 0이 아니라 계속 증가하고 있다면 시스템 어딘가에 치명적인 태스크 스케줄링 지연(Overload)이 발생하고 있다는 명백한 증거다.
2. listener: 런타임 패킷 스니퍼(Packet Sniffer)
하드웨어 디버깅 중에 특정 센서(예: 공기속도 센서 airspeed)의 값이 정상적으로 EKF에 전달되고 있는지 수치 자체를 눈으로 확인하고 싶을 때가 있다. 이때 NSH 터미널에 listener airspeed 라고 타이핑하면 된다.
listener 앱은 내부적으로 orb_subscribe를 호출하여 일회성 임시 구독자로 위장한 뒤, 링 버퍼에 들어있는 최신 데이터를 한 번 훔쳐 온다(orb_copy). 그리고 .msg 파일에서 자동 생성된 메타데이터를 활용하여 이 바이너리 C 구조체를 인간이 읽을 수 있는 JSON 혹은 텍스트 형태로 예쁘게 파싱(Parsing)하여 콘솔에 출력해 준다. 물리적 센서의 결함인지, 소프트웨어의 논리적 버그인지 단숨에 갈라치기할 수 있는 훌륭한 터미널 툴이다.
3. 내부 상태 덤프: uorb status
현재 가상 파일 시스템(VFS) /obj 디렉토리에 마운트된 모든 활성 인스턴스(예: sensor_accel0, sensor_accel1)의 목록과 메모리 할당 상태, 그리고 링 버퍼 매개변수들을 텍스트 형태로 통째로 덤프(Dump)하여 보여준다. 다중 인스턴스(Multi-instance) 센서 퓨전 시스템을 디버깅할 때, 내가 설계한 두 번째 GPS가 정상적으로 vehicle_gps_position1 노드로 등록되었는지 검증하는 가장 확실한 방법이다.