Files
fhd_rtk_ws/docs/UM982-RTK-Fixed-진단기록_2026-07-30.md
hjkim be9e83d2f4 Add um982_driver + gnss_comm (renamed from rtk_ws to fhd_rtk_ws)
UM982 RTK GNSS driver workspace used by the triple-camera scan GUI for
recording /ublox_driver/receiver_pvt alongside LiDAR/camera bags. Ported
from FAST-LIVO2-RTK-ROS2's um982_driver spec, adapted for this UM982
receiver instead of the original repo's GNSS module.
2026-08-07 14:15:06 +09:00

11 KiB
Raw Permalink Blame History

UM982 RTK Fixed 진단 기록 (2026-07-30, 옥상)

목적: fhd_rtk_ws(um982_driver C++ 드라이버) 기준으로 UM982 로깅 파이프라인을 검증하던 중, 옥상에서 RTK Fixed가 안 나오는 문제를 끝까지 추적한 기록. 결론부터 말하면 안테나 위치(높이/ 개방도)가 결정적 원인이었고, 소프트웨어/설정 쪽에서 발견한 버그 2건은 실제 버그였지만 그것만으론 Fixed가 안 나왔다.

⚠️ 재현 검증 진행 중: RELIABILITY를 원래 엄격값(3 1)으로 되돌린 뒤 난간 위치에서 재테스트 예정(§2.9). 위치만으로 Fixed가 재현되는지, RELIABILITY 완화가 실제로 필요했는지를 분리해서 확인하기 위함.


1. 결과 요약

시점 안테나 위치 결과
옥상, 테이블 위 (여러 차례, 총 20분+) 테이블(낮음, 난간보다 낮은 높이) SINGLE ↔ PSRDIFF(위성 5~9개) 반복, Float/Fixed 도달 못 함
옥상, 난간 위 난간(옥상 가장자리, 탁 트인 위치, 테이블보다 높음) NTRIP 접속 후 약 3.4초 만에 RTK FIXED, 위성 31개, h_acc 2.9cm

두 위치 모두 안테나는 거치된 상태(손으로 든 적 없음)였다. 차이는 높이와 개방도다 — 테이블은 난간보다 낮고, 난간은 옥상 가장자리라 하늘이 훨씬 트여 있다.

[um982_driver]: 상태: SINGLE(pos_type=16)    | nSV=28 hσ=1.771m  diff_age=0.0s   (t+0.03s)
[um982_driver]: NTRIP 접속: RTS1.ngii.go.kr:2101/VRS-RTCM34                      (t+0.8s)
[um982_driver]: 상태: OTHER(pos_type=17)     | nSV=13 hσ=1.378m  diff_age=0.6s   (t+1.8s)
[um982_driver]: 상태: RTK FIXED(pos_type=50) | nSV=31 hσ=0.029m  diff_age=1.1s   (t+3.4s)

테이블 위치에서는 같은 옥상, 같은 NTRIP 계정/마운트포인트, 같은 RELIABILITY 설정으로 8분 넘게 시도해도 위성 89개, 정확도 46m에서 정체됐던 것과 극명히 대비된다.


2. 조사 경과 (시간순)

2.1 파이프라인 기초 검증 (실내 → 실외 이동 전)

  • ros2 launch um982_driver um982_driver.launch.py 정상 기동, /ublox_driver/receiver_pvt 10Hz 발행 확인.
  • 실내에서는 num_sv=0/fix_type=NONE — 예상된 정상 동작(위성 미포착).
  • ros2 bag record 15초 테스트 → 148개 메시지 정상 기록 확인.

2.2 시리얼 권한 문제

  • /dev/ttyUSB0dialout 그룹 소유인데 사용자가 그룹 미가입 → Permission denied.
  • 임시 조치: sudo chmod a+rw. 영구 조치는 sudo usermod -aG dialout $USER 권장(재로그인 필요).

2.3 ⚠️ 버그 발견 #1 — install 설정이 stale

  • ros2 launchsrc/가 아니라 install/share/um982_driver/config/um982.yaml 복사본을 읽는데, 최초 빌드(11:30) 이후 리빌드가 안 돼서 ntrip_user/ntrip_pass가 계속 빈 문자열이었음.
  • 즉 그동안의 모든 실행이 NTRIP 인증 없이 시도되고 있었을 가능성이 큼.
  • 조치: colcon build --packages-select um982_driver 리빌드 → 계정 정보 반영 확인.
  • 이후 NTRIP 계정을 hyukhyuk6578로 수정(사용자 확인), 재빌드로 반영.

2.4 데이터 무결성 검증 (드라이버와 별개로 원시 데이터 직접 확인)

  • BESTNAV 바이너리: SYNC(AA 44 B5) + CRC-32(Appendix 1 알고리즘)를 파이썬으로 재구현해 원시 시리얼 60프레임 캡처 → CRC 통과율 100%. 콘솔에 뜨는 "CRC 불일치" 경고 1회는 포트를 여는 시점에 이미 스트리밍 중이던 프레임 중간에 끼어든 것으로, 실제 재현 안 됨(benign).
  • GPGGA($GNGGA): 1Hz로 정상 출력, fix quality=1, 체크섬 정상 → NTRIP GGA 부트스트랩 조건 충족.

2.5 NTRIP/RTCM 검증 (드라이버와 별도로 직접 접속)

  • 리빌드 후 재실행 → 로그에 NTRIP 접속: RTS1.ngii.go.kr:2101/VRS-RTCM34 출력(=서버가 200 OK 응답해야만 찍히는 로그이므로 인증 성공 확인).
  • 드라이버 코드에 진단 로그 2건 추가(파일: src/um982_driver/src/um982_driver_node.cpp):
    • 상태 로그에 pos_type(정수) + diff_age 표시
    • NTRIP 수신 누적 바이트 수(5초 스로틀)
  • 이 코드로 확인: RTCM이 꾸준히 초당 800B 이상 안정적으로 유입됨.
  • 드라이버와 독립적으로 같은 NTRIP 스트림에 파이썬으로 직접 접속해 RTCM3 프레임을 파싱: 정상적인 VRS 네트워크 RTK 메시지 세트 확인 — 1005/1007(기준국 좌표/안테나), 1030~1033(네트워크 RTK 보조), 1075/1085/1095/1115 (GPS/GLONASS/Galileo/QZSS MSM5). 북두(BeiDou) 보정 메시지는 이 마운트포인트에 없음 (단, 이후 §2.7에서 이게 핵심 원인이 아니었음이 드러남 — 수신기가 애초에 북두를 포함해 31개까지 위성을 쓸 수 있었기 때문).

2.6 수신기 설정 검증 (CONFIG 명령으로 직접 조회)

  • MODE 쿼리 → MODE ROVER UAV 확인(정상, 필수 사전조건 충족).
  • CONFIG SIGNALGROUP 4 5 확인 → Unicore 매뉴얼 Table 4-32 대조 결과 UM982 공장 기본값 그대로였음(Master=4/Slave=5, BDS+GPS+GLO+GAL+QZSS 5개 위성군 추적하는 넓은 설정). 문제 아님.

2.7 RTK RELIABILITY 조정 (테이블 위치에서 시도)

  • CONFIG 덤프에서 CONFIG RTK RELIABILITY 3 1 확인(매뉴얼 Table 4-10: 파라미터1=RTK 포지셔닝 엔진 신뢰도, 3=Relatively high=기본값 / 파라미터2=ADR 신뢰도, 1=Low=기본값).
  • 과거 기록(~/rtk/RTK_Fixed_달성기록.md, 2026-06-09)에 따르면, 위성 2731개/HDOP 0.50.6인 좋은 조건에서도 RELIABILITY 3이면 5분 넘게 Float에서 Fixed로 안 넘어갔고, 1 1로 낮춘 뒤에야 약 3분 만에 Fixed 달성한 전례가 있음. 이 설정은 RAM에만 있으면 전원 재시작/ FRESET 시 3으로 되돌아간다고 명시돼 있었고, 실제로 되돌아가 있었음(아마 매뉴얼 참고 재설정 과정에서 초기화된 것으로 추정).
  • 조치: CONFIG RTK RELIABILITY 1 1 + SAVECONFIG 실행, 재조회로 영구 저장 확인.
  • 그런데도 테이블 위치에서는 4분 이상 재시도해도 위성 8~9개, PSRDIFF에서 못 벗어남 → RELIABILITY만으로는 해결되지 않았고, 그 이전 단계(Float 진입 자체)가 위성 수 부족으로 막혀 있었다는 뜻이었음.

2.8 테이블 vs 난간 위치 비교 (결정적 실험)

  • 옥상, 옆 건물 있음 → 초기엔 "옆 건물發 멀티패스"로 추정.
  • 위성 수 격차(테이블 89개 vs 과거 성공 기록 2731개)가 "옆 건물 정도"로 설명하기엔 과도하게 크다고 판단해 다른 원인(안테나 흔들림 등)도 검토했으나, 실제로는 흔들림이 아니라 테이블 자체가 난간보다 낮은 위치였던 것이 원인이었음(사용자 확인).
  • 난간(옥상 가장자리, 트인 위치)으로 옮겨 재시도 → §1의 결과. 위성 수 89개 → 2831개로 즉시 회복, NTRIP 접속 3.4초 만에 RTK FIXED.

2.9 재현 검증 (진행 중)

  • 난간 테스트는 RELIABILITY가 1 1(완화값)로 설정된 상태에서 이루어짐 → 위치 개선과 RELIABILITY 완화 중 무엇이 실제로 결정적이었는지 분리가 안 된 상태.
  • RELIABILITY를 원래 엄격값 CONFIG RTK RELIABILITY 3 1 + SAVECONFIG되돌림(확인 완료).
  • 이 상태로 난간 위치에서 재테스트 예정 — 위치만으로도 Fixed가 나오는지 확인. 결과는 추후 이 문서에 추가.

3. 원인 분석

핵심 원인 (결정적, primary): 안테나 위치 — 테이블(낮음, 상대적으로 덜 트임) vs 난간(옥상 가장자리, 높고 탁 트임). 낮은 위치에서는 옆 건물 등에 의한 저고도 위성 신호 가림/멀티패스가 반송파 기반 RTK 모호성 해석을 방해했을 것으로 추정된다. SPP(단독측위)는 코드 신호만 쓰기 때문에 이 정도 환경엔 상대적으로 관대해서 SINGLE 상태의 좌표는 비교적 정상으로 보였지만, 그래서 오히려 "수신기가 위성은 잡는데 왜 Fixed가 안 되지"로 오인하기 쉬웠다.

부차 원인 (실제 버그였지만 단독으론 불충분, contributing):

  1. install/ 설정 파일이 stale해서 한동안 NTRIP 인증이 빈 계정으로 시도됨 — 리빌드로 해결.
  2. RTK RELIABILITY가 엄격 기본값(3)으로 되돌아가 있었음 — 1 1 + SAVECONFIG로 임시 완화. (§2.9 재현 검증을 위해 이후 다시 3 1로 되돌림 — 위치 개선만으로 충분한지 확인 중.)

이 두 버그는 위치 개선 없이는 어차피 Fixed가 안 나왔을 것이므로 "고쳐도 소용없었다"고 오인할 수 있지만, RTCM 인증/유입이 정상화돼 있었기 때문에 난간 이동 직후 3.4초라는 이례적으로 빠른 Fixed가 가능했을 가능성이 있다. RELIABILITY 완화가 실제로 필수였는지는 §2.9 재현 결과로 확정한다.


4. 결론 및 권장 운용 방법

  1. UM982 안테나는 최대한 높고 트인 위치에 거치할 것. 옆 건물 등 장애물이 있는 옥상이라면 낮은 테이블보다 난간·삼각대 등으로 최대한 높이고, 장애물에서 수평으로도 떨어뜨리는 게 좋다.
  2. fhd_rtk_ws/src/um982_driver/config/um982.yaml을 수정한 뒤에는 항상 리빌드할 것 (colcon build --packages-select um982_driver). install/은 심볼릭 링크가 아니라 복사본이라 리빌드 없이는 반영되지 않는다. 아니면 --symlink-install로 한 번 다시 빌드해두면 이후 src 수정이 즉시 반영된다.
  3. 수신기 CONFIG RTK RELIABILITY 값을 상황에 맞게 확인. 기본값은 3 1(엄격). 위치가 좋은데도 Float에서 Fixed로 안 넘어가면 CONFIG RTK RELIABILITY 1 1SAVECONFIG로 완화를 시도해볼 수 있다(§2.9에서 위치만으로 충분한지 재검증 중이므로, 필요 여부는 재현 결과 확인 후 최종 결론). FRESET이나 일부 재설정 작업 후 기본값으로 되돌아갈 수 있으니 CONFIG 응답의 CONFIG RTK RELIABILITY 라인으로 주기적으로 확인.
  4. 진단용 로그가 드라이버에 상시 포함됨 (um982_driver_node.cpp, 이번에 추가): 상태 전환 로그에 pos_type/diff_age가 함께 찍히고, NTRIP 수신 바이트가 5초마다 찍힌다. 다음에 비슷한 문제가 생기면 이 로그로 "NTRIP이 안 붙는지" vs "붙었는데 수신기가 못 쓰는지"를 바로 구분할 수 있다.

5. 관련 파일

파일 내용
src/um982_driver/src/um982_driver_node.cpp pos_type/diff_age/NTRIP 바이트 진단 로그 추가됨
src/um982_driver/config/um982.yaml NTRIP 계정 갱신됨 (자격증명은 리포에 평문 저장 안 함)
docs/Unicore Reference Commands Manual For N4 High Precision Products_V2_EN_R1.4.pdf MODE/RELIABILITY/SIGNALGROUP 명령 근거
~/rtk/RTK_Fixed_달성기록.md 2026-06-09 과거 Fixed 달성 기록(RELIABILITY 단서의 출처)
~/rtk/save_reliability.py RELIABILITY 저장 스크립트(포트가 /dev/ttyUSB0로 하드코딩돼 있어 포트 바뀌면 수정 필요)