기본 모바일 로봇 구조 이해: cmd_vel, odom, tf, sensor 토픽 흐름

대상: ROS로 자율주행 로봇을 개발하거나, 센서·제어 노드 간의 데이터 흐름을 이해하고 싶은 개발자
환경: Ubuntu 20.04 + ROS Noetic (Melodic 동일)
적용 예시: 차륜형 이동 로봇 (differential drive, Ackermann 등)


1. 문제/주제 요약

ROS 기반 모바일 로봇을 처음 다루면 아래와 같은 의문이 생깁니다:

  • cmd_vel은 어디서 오고, 누가 구독하나?
  • odom은 어떻게 계산되고, 어디에 쓰이는가?
  • tf 트리와 odom, base_link의 관계는?
  • LiDAR, IMU 등 센서 데이터는 어디로 연결되는가?

이 글에서는 기본적인 ROS 모바일 로봇 시스템 구조를 한눈에 정리합니다.
RViz나 시뮬레이터(Gazebo)에서 동작을 이해하기 전, 이 흐름을 정확히 아는 것이 중요합니다.


2. ROS 모바일 로봇의 핵심 구성도

ROS에서 차륜형 로봇의 일반적인 데이터 흐름은 다음과 같습니다:

 ┌────────────────────┐
 │     Navigation     │  ←  move_base / path planner
 │ (cmd_vel publisher)│
 └─────────┬──────────┘
           │
           ▼
 ┌────────────────────┐
 │   Base Controller  │  ←  실제 모터 명령 제어
 │ (cmd_vel subscriber│
 │  odom publisher)   │
 └─────────┬──────────┘
           │
           │  odometry data (/odom)
           ▼
 ┌────────────────────┐
 │ Localization / TF  │  ←  odom → base_link 변환
 └─────────┬──────────┘
           │
           │  sensor data (/scan, /imu)
           ▼
 ┌────────────────────┐
 │   Sensors (Lidar,  │
 │   IMU, Camera 등)  │
 └────────────────────┘

3. 주요 토픽 및 역할 정리

토픽 이름발행자(pub)구독자(sub)설명
/cmd_velteleop, move_base로봇 하위 제어 노드로봇 속도 명령 (geometry_msgs/Twist)
/odom로봇 제어 노드localization, EKF 등로봇의 이동 추정 (nav_msgs/Odometry)
/tf각 센서 및 로봇 프레임 노드RViz, TF listener좌표계 간 변환 관계
/scanLiDAR 드라이버SLAM, obstacle detection거리 센서 데이터 (sensor_msgs/LaserScan)
/imu/dataIMU 드라이버EKF, localization관성 센서 데이터 (sensor_msgs/Imu)

4. 토픽 흐름 상세 분석


(1) cmd_vel — 속도 명령 (Velocity Command)

  • 메시지 타입: geometry_msgs/Twist
  • 단위: m/s, rad/s
rostopic echo /cmd_vel

출력 예시:

linear:
  x: 0.2
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.5

발행자(Publisher)

  • teleop_twist_keyboard
  • move_base
  • 자율주행 알고리즘

구독자(Subscriber)

  • 모터 제어 노드 (예: diff_drive_controller, ackermann_steering_controller)

💡 로봇의 실제 움직임은 이 cmd_vel 명령을 받아 속도 제어기로 전달되는 것으로 시작됩니다.


(2) odom — 주행 거리 및 자세 추정 (Odometry)

  • 메시지 타입: nav_msgs/Odometry
  • 주로 엔코더 기반 계산
rostopic echo /odom

출력 예시:

pose:
  pose:
    position: {x: 1.23, y: 0.45, z: 0.0}
    orientation: {x: 0, y: 0, z: 0.382, w: 0.924}
twist:
  twist:
    linear: {x: 0.1, y: 0.0, z: 0.0}
    angular: {x: 0.0, y: 0.0, z: 0.1}

발행자(Publisher)

  • 로봇 베이스 제어 노드 (예: diff_drive_controller, wheel_odom_node)

구독자(Subscriber)

  • robot_localization (EKF 필터)
  • amcl (지도 기반 위치 추정)
  • RViz (로봇 위치 표시)

⚙️ odom은 로봇 내부 기준에서 계산된 상대 위치입니다.
외부 지도 좌표와 연결하려면 map → odom 변환이 추가로 필요합니다.


(3) tf — 좌표계 변환 관계

TF는 ROS에서 모든 센서, 로봇 부품의 위치 관계를 관리합니다.

예시 프레임 트리:

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

주요 변환:

변환의미생성 노드
odom → base_link로봇 주행 이동량odometry node
base_link → laser센서 장착 위치static_transform_publisher
map → odom지도 기반 위치 보정localization node (예: amcl)

시각화:

rosrun tf view_frames
evince frames.pdf

💡 TF 관계가 잘못 설정되면 RViz에서 센서와 로봇이 엉뚱한 위치에 나타납니다.


(4) sensor — LiDAR, IMU, Camera

  • LiDAR: /scan (sensor_msgs/LaserScan)
  • IMU: /imu/data (sensor_msgs/Imu)
  • Camera: /camera/image_raw, /camera_info

센서 데이터는 SLAM, Localization, Obstacle Detection 등 상위 노드에서 사용됩니다.

예시:

rostopic echo /scan | head

→ 거리값 배열이 출력

RViz에서 시각화:

rosrun rviz rviz
  • LaserScan: /scan
  • TF: odom → base_link → laser

5. 전체 데이터 흐름 요약

[ teleop / move_base ]  →  /cmd_vel  →  [ motor controller ]
                                      ↓
                                 publishes
                                      ↓
                                   /odom
                                      ↓
                              [ localization ]
                                      ↓
                                   /tf tree
                                      ↓
                                [ sensors (LiDAR, IMU) ]
                                      ↓
                                   /scan, /imu/data

즉, 명령(cmd_vel) → 이동(odom) → 위치(tf) → 센서 피드백(sensor)의 닫힌 루프 구조로 동작합니다.


6. 자주 하는 실수 & 디버깅 팁

증상원인해결 방법
RViz에서 로봇이 안 보임TF 프레임 불일치fixed_frameodom으로 맞추기
/odom이 안 뜸하위 제어 노드 미실행controller_manager list로 노드 확인
/cmd_vel 발행해도 움직이지 않음구독자 없음rostopic info /cmd_vel로 확인
/scan은 뜨는데 RViz에서 안 보임frame_id mismatch센서 launch 파일에서 frame_id 수정
Localization 오차 누적map → odom 보정 없음amcl 또는 ekf_localization 추가

7. 정리

구성 요소주요 역할핵심 토픽
제어 명령속도 지시/cmd_vel
주행 추정오도메트리 계산/odom
좌표계 변환프레임 관계 관리/tf
센서 피드백외부 정보 제공/scan, /imu/data

📌 요약

  • ROS 모바일 로봇의 기본 루프는 cmd_vel → odom → tf → sensor 순환 구조
  • cmd_vel: 제어 명령, odom: 이동 결과, tf: 좌표계 연결, sensor: 외부 피드백
  • 각 노드는 퍼블리셔-서브스크라이버 패턴으로 연결되어 있고, RViz에서 모두 시각화 가능

댓글 남기기