13.6.1.1. QGC MAVLink Console 및 NuttX NSH(NuttShell) 활용: gps status, listener vehicle_gps_position 출력 결과의 구조체 매핑 및 변수 해석
비행 전(Pre-flight) 기체가 하늘로 날아오르기를 거부하고 요지부동인 순간, QGroundControl(QGC)의 상단 메뉴바에 있는 Mavlink Console(명령 프롬프트 아이콘) 버튼은 굳게 잠긴 비행 제어기(FC) 백엔드 코어(NuttX RTOS) 로 통하는 가장 강력한 백도어(Back-door) 터미널 셸(NSH)을 활성화시켜 준다. 이 검은색 터미널 화면 속 텍스트야말로 드론 엔지니어의 생명줄이다.
본 절에서는 “왜 내 비행기가 RTK Fix로 넘어가지 못하는가?“에 대한 결론을 도출하기 위해, 현장에서 조종사가 가장 자주 구사해야 하는 양대 커맨드 프롬프트 명령어인 gps status와 listener vehicle_gps_position의 콘솔 실시간 출력 결과(Standard Output Dump)를 심층 분석하고, 이 숫자열들이 PX4 펌웨어 C++ 소스 코드의 어떤 구조체(Struct) 멤버 변수와 기계적으로 1:1 매핑(Mapping)되는지 정밀하게 해독해 낸다.
1. gps status 명령어: C++ 드라이버 스레드의 전역 변수 해부(Dump)
QGC 콘솔에 gps status 라고 입력하고 엔터(Enter)를 치면, 백그라운드 워크 큐(Work Queue)에서 은밀하게 루프를 돌고 있던 서브시스템 드라이버 태스크(src/drivers/gps/gps.cpp)가 멈칫하고 자신이 지금껏 센서 포트로부터 누적해온 통계량과 전역 상태 지표를 터미널로 왈칵 토해낸다(Dump).
1.1 콘솔 출력 로그 예시와 해석 구조
nsh> gps status
INFO [gps] Main GPS
INFO [gps] protocol: UBX
INFO [gps] status: OK, port: /dev/ttyS3, baudrate: 115200
INFO [gps] sat info: disabled
INFO [gps] u-blox F9P
INFO [gps] rate position: 5.00 Hz
INFO [gps] rate velocity: 5.00 Hz
INFO [gps] RTCM injection rate: 2.10 Hz (Success: 1205, Failed: 12)
이 평범해 보이는 로그 지표는 다음과 같은 펌웨어 레벨의 강력한 맥락(Context)을 대변한다.
status: OK, port: /dev/ttyS3:GPS클래스가 POSIX::open()함수를 호출하여 해당 물리UART 계층과의 결합을 락커(Lock) 및 타임아웃 오류 없이 완수했음을 의미한다.rate position: 5.00 Hz: 이 수치가 보이지 않거나 1\text{Hz} 미만으로 간헐적으로 튀면, 시리얼 보드레이트 대역폭이 모자라거나 UART 핀 연결부위에 하드웨어 단선 스파크(Noise)가 발생해 폴링(Polling) 패킷이 절반 이상 버려지고 있다는 끔찍한 뜻이다.RTCM injection rate및 성공/실패 맵(Map): **가장 주목해야 할 디버깅 포인트(Hotspot)**다. 이 라인은ubx.cpp모듈 내의 상태 누적기인_rtcm_injections_successful및_rtcm_crc_failuresC++ 멤버 변수를 그대로 리턴(Return)한 것이다. 만약 괄호 안의 실패율(Failed)이 미친 듯이 올라가고 있다면 베이스 스테이션 모뎀이나 QGC의 라우팅 대역폭에 심각한Buffer Overrun(오버런)혹은 RTCM 버전 프로토콜 차질이 발생하고 있다는 적색경보이다.
2. listener vehicle_gps_position 명령어: uORB 데이터 버스 스니핑(Sniffing)
gps status가 공장의 하드웨어 기계 작동 여부 자체를 점검하는 것이라면, listener 명령어는 공장에서 뛰쳐나온 컨베이어 벨트에 무슨 실물 제품이 놓여 있는지 집어서 성분을 조사하는 것(Sniffing)과 진배없다.
PX4의 심장인 EKF2 필터 엔진으로 들어가는 가장 핵심적인 입력 토픽(uORB Topic)이 바로 vehicle_gps_position_s 라는 C 구조체이다.
2.1 콘솔 출력 로그 예시와 파라미터 변수 매핑(Mapping)
nsh> listener vehicle_gps_position
TOPIC: vehicle_gps_position
vehicle_gps_position_s
timestamp: 1234567890 (0.0123s ago)
lat: 374921600 # (10^-7 degree) 위도
lon: 1270271500 # (10^-7 degree) 경도
alt: 55030 # (mm) 고도 (WGS84)
eph: 0.8 # (m) 수평 오차
epv: 1.2 # (m) 수직 오차
vel_m_s: 0.05
satellites_used: 18
fix_type: 6 # ★ RTK 핵심: FIX (3=3D, 5=FLOAT, 6=FIXED)
jamming_state: 0
이 갓 뽑아낸 덤프(listener) 스크린을 통해 엔지니어는 펌웨어 코드로 침투(Drill-down)할 수 있다.
-
timestamp(수명 주기 지표)
이 구조체가 uORB 버스(orb_publish())에 방금 0.01초 전에 등록되었음을 시사한다. 이 괄호 안초수(ago) 값이 가만히 멈춰 있거나1.5s ago처럼 크다면, GPS 드라이버 스레드가 죽어(Stalled) 버렸거나 더 이상 하드웨어 수신 루프가 돌지 않는다는 뜻이다(데드락 진단 필수). -
eph(수평 분산 / Standard Deviation)
EKF2가 이 GPS 위도/경도(lat/lon) 정보를 얼마나 신뢰할지 결정짓는 공분산(Covariance) 가중치의 재료가 되는 표준 편차 미터(m) 값이다.ubx.cpp가UBX-NAV-PVT의 정확도 필드(hAcc)에서 계산해 추출한 값으로, 수치가 1.0\text{m} 이상으로 치솟고 있다면 칩셋 알고리즘단 필터가 환경적 멀티패스(Multipath) 잔상으로 인해 자기장 위치 추적 파이프라인에서 방황하고 있다는 치명적 의미를 내포한다. -
fix_type: 6(캐리어 솔루션 매직넘버)
앞의 장에서carrSoln비트가 2일 때, 내부 구조체 로직에 의해 매핑되는 그 위대한 정수형 열거형 변수6(RTK Fixed)이다. QGC 화면에 녹색으로 ’RTK GPS’라고 뜨는 원천 소스가 바로 이 숫자 단 한 자리이다. 만약 이 숫자가 스물스물5로 떨어져 있다면, 그것은 1\text{cm} 의 오차 통계 분산(Variance)이 20\text{cm} 구역으로 퍼졌다는 ‘RTK Float’ 상태 격하(Downgrade)를 직설적으로 대변해 준다. -
jamming_state시스템 공격 감지 지표
이 덤프에는 외부 악의적 시그널이나 전파 재밍(Jamming, 스푸핑 Spoofing 등)이 감지되어 RF 신호 레벨 AGC 레지스터가 튀었을 때 u-blox가 올려주는 지표 또한 그대로 기록된다(0이면 정상).
결론적으로, 터미널 셸 위에서 타이핑하는 한 줄 한 줄의 CLI(gps status, listener)는 QGC의 무감각한 2D 그림 지도를 완전히 벗어나 PX4 펌웨어 C++ 데몬 모델의 속살을 뜯어내고, 구조체 배열과 비트 플래그 단위로 통계를 파싱하여 문제를 입증해 내는 하드-코어 프로그래밍적 투시(Programming X-ray) 기법의 정점이다. 이를 통달한 파일럿 시스템 개발자만이 예측 불허의 오작동 앞에서도 진정한 공학적 대응력을 갖추게 된다.