[Physical AI W2D1] 2/6 — RViz 개념 ②: TF·좌표계·URDF·센서 Display·디버깅

2026. 6. 20. 12:35·피지컬AI

[Physical AI W2D1 · 2/6]

RViz의 진짜 핵심은 TF(좌표계 변환)다. map·odom·base_link·laser·camera_link가 어떻게 연결되는지, URDF/RobotModel과 LaserScan·Odometry·Path·PointCloud2·Image·IMU·Marker Display를 정리하고, "데이터가 안 보일 때" 원인을 분리해 잡는 법까지 다룬다.

이 글에서 잡는 개념
TF — 좌표계 사이의 위치·회전 관계, Static vs Dynamic
주요 좌표계: map·odom·base_link·laser·camera_link
URDF / RobotModel Display
센서 Display 총정리: LaserScan·Odometry·Path·PointCloud2·Image·IMU·Marker
RViz vs Gazebo, 그리고 "데이터가 안 보일 때" 디버깅 순서

(1편의 RViz 기본 위에서, 이번엔 좌표계와 각 Display를 깊게 봅니다.)


1. TF — RViz가 "어디에 그릴지" 아는 법

TF(Transform)는 ROS 2에서 좌표계 사이의 위치·회전 관계를 표현하는 기능입니다. 로봇은 좌표계 하나만 쓰지 않습니다 — 본체·바퀴·LiDAR·카메라·IMU·지도·주행 기준이 각각 다른 좌표계를 가집니다.

map
└── odom
    └── base_link
        ├── laser
        ├── camera_link
        └── imu_link

 

각 좌표계는 따로 노는 게 아니라 서로 연결돼야 합니다. LiDAR가 본체 앞에 달렸다면 laser는 base_link 앞쪽에 위치해야 하고, 로봇이 움직이면 base_link는 odom 안에서 위치가 계속 변합니다. TF가 이 관계를 시간에 따라 관리합니다.

이동 로봇의 TF 좌표계 트리 — map에서 odom, odom에서 base_link로 내려가고 base_link에서 laser·camera_link·imu_link로 갈라지는 계층 구조. odom→base_link는 Dynamic TF(로봇 이동), base_link→센서들은 Static TF(고정 장착)로 색이나 라벨로 구분한 트리 다이어그램

RViz는 TF로 "각 센서 데이터를 화면 어디에 그릴지" 계산합니다. TF가 없으면 토픽이 정상 발행돼도 데이터가 안 보이거나 No transform 오류가 납니다.

Static TF vs Dynamic TF

구분 의미 예
Static TF 시간이 지나도 안 변하는 관계 base_link → laser, base_link → camera_link (센서 고정 장착)
Dynamic TF 시간에 따라 변하는 관계 odom → base_link (로봇이 이동)
odom
└── base_link        ← Dynamic (로봇 이동)
    ├── laser        ← Static (고정)
    ├── camera_link  ← Static
    └── imu_link     ← Static

2. 주요 좌표계의 의미

좌표계 의미 주 사용
map 전역 지도 기준 SLAM·Navigation에서 지도 기반 위치
odom 주행 추정 기준 출발 후 상대 이동(단기적으로 부드러움)
base_link 로봇 본체 기준 전진·회전 방향, 센서 장착 위치
laser LiDAR 센서 기준 거리값이 보통 이 기준으로 발행
camera_link 카메라 기준 영상·깊이·점군 데이터 기준

💡 odom은 바퀴·IMU 추정이라 누적 오차가 생기지만 단기 이동 추정엔 중요합니다. map은 SLAM/Navigation으로 보정된 전역 기준입니다.

TF Display를 추가하면 각 좌표계가 축(axes) 형태로 화면에 표시됩니다. 로봇이 움직이면 base_link가 odom 기준으로 이동하고 laser는 base_link에 붙어 함께 움직이죠. 다른 Display보다 TF Display를 먼저 확인하세요 — LaserScan·Odometry·Path가 안 보이는 원인이 대개 TF 누락입니다.


3. URDF와 RobotModel Display

URDF(Unified Robot Description Format)는 로봇의 물리 구조를 XML로 표현하는 파일입니다. Link(부품/좌표계 단위: base_link, laser_link…)와 Joint(Link 사이 연결: fixed, revolute, continuous)로 구성됩니다.

 

RobotModel Display는 URDF 기반으로 로봇 외형을 화면에 그립니다. 보통 RViz가 URDF를 직접 읽기보다, robot_state_publisher 노드가 URDF를 /robot_description으로 제공하고 Joint 상태와 함께 TF를 발행하면, RobotModel Display가 이를 표시합니다.

 

RobotModel은 단순 그림이 아니라 로봇 구조·좌표계가 올바른지 검증하는 도구입니다 — LiDAR가 앞에 있어야 하는데 뒤에 그려지면 URDF의 joint origin이 잘못된 것입니다.


4. 센서 Display 총정리

RViz가 화면에 그리는 핵심 Display들입니다. 공통적으로 "토픽 존재 + 발행 지속 + 타입 일치 + frame_id 존재 + TF 연결"의 5조건(1편)이 필요합니다.

Display 메시지 타입 대표 토픽 무엇을 보나
LaserScan sensor_msgs/msg/LaserScan /scan 2D LiDAR 거리 → 점으로
Odometry nav_msgs/msg/Odometry /odom 추정 위치·방향 → 화살표/축
Path nav_msgs/msg/Path /path 이동·계획 경로 → 선
PointCloud2 sensor_msgs/msg/PointCloud2 /points 3D 점군(LiDAR/Depth)
Image sensor_msgs/msg/Image /camera/image_raw 카메라 영상(별도 창)
IMU sensor_msgs/msg/Imu /imu 자세·각속도·가속도
Marker visualization_msgs/msg/Marker /visualization_marker 사용자 정의(점·선·화살표·텍스트)

 

핵심 디테일 몇 가지:

  • LaserScan: angle_min~angle_max(측정 범위), ranges(각 방향 거리). Display의 Style(Points/Flat Squares)·Size·Decay Time 조정. 안 보이면 Topic과 TF부터 확인.
  • Odometry: header.frame_id=odom, child_frame_id=base_link. Shape(Arrow/Axes), Keep(이전 표시 유지). TF의 odom→base_link와 어긋나면 위치가 어색해집니다.
  • Path: PoseStamped 배열을 선으로. Odometry가 "현재 위치"라면 Path는 "시간에 따른 이동 흐름".
  • PointCloud2: Color Transformer(RGB/Intensity/AxisColor/FlatColor)로 색 기준 선택. 3D 환경 인식 확인의 핵심.
  • Image: 3D View가 아닌 별도 Image 창에 표시. Transport Hint(raw/compressed). 비전 실습의 출발점.
  • IMU: 단독 시각화보다 Odometry·SLAM·센서융합과 함께 쓰임(orientation은 보통 quaternion — 5편에서).
  • Marker: 정해진 센서 형식이 아니라, 개발자가 디버깅·알고리즘 결과를 임의 도형으로 표시.

5. RViz vs Gazebo — 헷갈리지 말 것

구분 Gazebo RViz
역할 물리 시뮬레이션 ROS 2 데이터 시각화
물리 엔진 사용(중력·충돌·마찰) 사용 안 함
센서 가상 센서 생성 직접 생성 안 함
토픽 발행 주로 구독

→ Gazebo는 데이터를 만드는 쪽, RViz는 확인하는 쪽입니다(W1D1의 Gazebo /clock을 떠올리세요).

Gazebo 가상 센서 → ROS 2 Bridge/Plugin → /scan 발행 → RViz LaserScan Display → 점 시각화

⚠️ Gazebo+RViz를 함께 쓸 때는 좌표계 일관성이 중요합니다.
Gazebo 모델의 센서 위치와 TF가 어긋나면 RViz에서 센서 점이 엉뚱한 곳에 찍힙니다 — 센서 토픽뿐 아니라 TF·URDF 구조도 확인하세요.


6. 데이터가 안 보일 때 — 디버깅 순서

RViz에서 "안 보임"은 매우 흔하고, 대부분 코드가 아니라 좌표계/설정 문제입니다. 무조건 다음 6단계 순서로 원인을 분리하세요.

1. 토픽이 존재하는가          (ros2 topic list)
2. 메시지가 발행되는가         (ros2 topic echo)
3. 메시지 타입이 Display와 맞는가 (ros2 topic type)
4. 메시지의 header.frame_id는?
5. Fixed Frame은 무엇인가
6. frame_id ↔ Fixed Frame 사이 TF가 있는가

frame_id — 가장 자주 틀리는 곳

frame_id는 그 메시지가 어느 좌표계 기준인지를 나타냅니다. 철자 하나만 달라도 다른 frame으로 취급됩니다.

laser    Laser    laser_link    /laser   ← 모두 서로 다른 frame!

토픽 메시지의 frame_id와 TF가 발행하는 frame 이름을 정확히 맞춰야 합니다.

대표 오류 메시지 해석

오류 의미
Fixed Frame [odom] does not exist Fixed Frame 좌표계가 TF에 없음 → TF 발행 노드 확인
No transform from [laser] to [odom] 두 좌표계 사이 TF 변환이 없음(토픽은 정상일 수 있음)
Frame [base_link] does not exist 메시지 frame_id가 TF에 없음
Message Filter dropping message TF 변환 시간/대기 문제
Topic has no publisher 그 토픽을 발행하는 노드가 없음

예: No transform from [laser] to [odom] → /scan은 잘 나오는데 laser→…→odom TF가 없어 LiDAR 점이 안 보이는 상황입니다.

💡 .rviz 설정 파일 — Fixed Frame·Display 목록·Topic·색상·View를 .rviz 파일로 저장하면,
다음 실행에서 같은 화면을 바로 복원하고 팀과 공유할 수 있습니다(데이터가 아니라 화면 구성을 저장). 3편 실습에서 직접 만듭니다.


2편 정리

  • TF = 좌표계 사이 위치·회전 관계. map→odom→base_link→{laser,camera,imu} 트리. Static(고정 장착) vs Dynamic(이동).
  • TF Display를 가장 먼저 — 안 보이는 원인의 대부분이 TF 누락.
  • URDF/RobotModel = 로봇 구조·좌표계 검증(robot_state_publisher가 TF·/robot_description 제공).
  • 센서 Display(LaserScan·Odometry·Path·PointCloud2·Image·IMU·Marker)는 5조건 공통 + 각자 디테일.
  • 안 보이면 6단계 순서(토픽→발행→타입→frame_id→Fixed Frame→TF). frame_id 철자가 단골 범인.

다음 편 예고

개념은 충분히 잡았습니다. 3편에서는 직접 실습합니다 — RViz는 GUI라 순수 터미널론 안 되니, GCP VM에 헤드리스 GUI 스택(Xvfb + VNC + noVNC + Cloudflared) 을 세워 브라우저로 RViz2를 띄우고, Publisher 노드로 LaserScan·Odometry·Path·TF를 발행해 화면에서 확인합니다.

📚 Week2 Day1 전체 목차 (총 6편)

  • 1/6 RViz로 로봇을 눈으로 보다 — 시각화 흐름·Fixed Frame·Display
  • 2/6 RViz 개념 ② — TF·좌표계·URDF·센서 Display·디버깅 — 이번 글
  • 3/6 RViz2 실습 — GCP VM 헤드리스 GUI + Publisher + 시각화
  • 4/6 좌표계와 동차 변환 행렬 ① — 좌표계·2D 변환·동차좌표
  • 5/6 좌표계와 동차 변환 행렬 ② — 3D·TF·Quaternion·기구학
  • 6/6 좌표 변환 실습 — Python 변환 + TF Publisher + RViz
저작자표시 (새창열림)

'피지컬AI' 카테고리의 다른 글

[Physical AI W2D1] 5/6 — 좌표계와 동차 변환 행렬 ②: 3D·TF·Quaternion·기구학  (0) 2026.06.20
[Physical AI W2D1] 4/6 — 좌표계와 동차 변환 행렬 ①: 좌표계·2D 변환·동차좌표  (0) 2026.06.20
[Physical AI W2D1] 1/6 — RViz로 로봇을 눈으로 보다: 시각화 흐름·Fixed Frame·Display  (0) 2026.06.20
[Physical AI W1D2] 6/6 — ROS 2 패키지 빌드 마스터: Python·C++·colcon  (0) 2026.06.14
[Physical AI W1D2] 5/6 — ROS 2 서비스·액션 구현: 요청/응답과 목표/피드백  (0) 2026.06.14
'피지컬AI' 카테고리의 다른 글
  • [Physical AI W2D1] 5/6 — 좌표계와 동차 변환 행렬 ②: 3D·TF·Quaternion·기구학
  • [Physical AI W2D1] 4/6 — 좌표계와 동차 변환 행렬 ①: 좌표계·2D 변환·동차좌표
  • [Physical AI W2D1] 1/6 — RViz로 로봇을 눈으로 보다: 시각화 흐름·Fixed Frame·Display
  • [Physical AI W1D2] 6/6 — ROS 2 패키지 빌드 마스터: Python·C++·colcon
hyeseong-dev
hyeseong-dev
안녕하세요. 백엔드 개발자 이혜성입니다.
  • hyeseong-dev
    어제 오늘 그리고 내일
    hyeseong-dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (342) N
      • 여러가지 (11) N
        • 알고리즘 & 자료구조 (73)
        • 오류 (4)
        • 이것저것 (29)
        • 일기 (1)
      • 프레임워크 (39)
        • 자바 스프링 (39)
        • React Native (0)
      • 프로그래밍 언어 (39)
        • 파이썬 (31)
        • 자바 (3)
        • 스프링부트 (5)
      • 컴퓨터 구조와 운영체제 (3)
      • DB (17)
        • SQL (0)
        • Redis (17)
      • 클라우드 컴퓨팅 (21)
        • 도커 (2)
        • AWS (19)
      • 스케쥴 (65)
        • 세미나 (0)
        • 수료 (0)
        • 스터디 (24)
        • 시험 (41)
      • 트러블슈팅 (1)
      • 자격증 (2) N
        • 정보처리기사 (0)
        • 정보보안기사 (1)
        • 네트워크관리사 (1) N
      • 재태크 (0)
        • 암호화폐 (0)
        • 기타 (0)
      • 피지컬AI (26)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    EC2
    moveit
    동차변환행렬
    Python
    클라우드
    완전탐색
    FastAPI
    로봇팔
    역운동학
    자바
    AWS
    운동학
    java
    TF
    피지컬ai
    취업리부트
    rclpy
    그리디
    Spring Boot
    Redis
    docker
    Spring WebFlux
    WebFlux
    항해99
    네트워크
    AWS네트워크계층으로읽기
    SAA
    ROS2
    프로그래머스
    celery
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
hyeseong-dev
[Physical AI W2D1] 2/6 — RViz 개념 ②: TF·좌표계·URDF·센서 Display·디버깅
상단으로

티스토리툴바