Atlas Robotics
ROS2 cơ bảnCơ bản

Topic trong ROS2 là gì?

Atlasbot · 16/8/2026 · 11 phút đọc

Topic trong ROS2 là gì?
Publisher và Subscriber giao tiếp qua topic

Đọc dữ liệu LiDAR 10 lần mỗi giây, gửi vận tốc điều khiển động cơ liên tục, phát trạng thái pin định kỳ — đây đều là những luồng dữ liệu liên tục, lặp lại, khác hẳn kiểu "yêu cầu rồi chờ một câu trả lời duy nhất". Topic chính là cơ chế ROS2 dành riêng cho kiểu dữ liệu này.

Khái niệm chính

Topic là một kênh có tên, mang một kiểu dữ liệu (message type) cố định. Node muốn gửi dữ liệu tạo một Publisher gắn với topic đó; node muốn nhận dữ liệu tạo một Subscriber cũng gắn với đúng topic và kiểu dữ liệu đó. Cả hai bên không cần biết về nhau — publisher cứ gửi, không quan tâm có ai đang nghe hay không; subscriber cứ nhận, không quan tâm dữ liệu tới từ node nào.

Nhiều-nhiều (many-to-many), không phải một-một

Một topic có thể có nhiều publisher cùng gửi vào và nhiều subscriber cùng nhận — ví dụ, hai node camera khác nhau đều publish ảnh lên cùng một topic /image, và ba node khác nhau (một để hiển thị, một để lưu file, một để nhận diện vật thể) cùng subscribe topic đó, mỗi node nhận được đầy đủ mọi message publish lên.

Tóm lại: Topic phù hợp cho dữ liệu chảy liên tục, không cần phản hồi trực tiếp (fire-and-forget) — publisher không bao giờ biết chắc subscriber đã nhận được hay chưa. Khi cần một yêu cầu-một câu trả lời rõ ràng, đó là lúc dùng Service thay vì Topic.

Nguyên lý hoạt động

Publisher A ──┐
              ├──►  /cmd_vel (topic, kiểu Twist)  ──┬──► Subscriber X
Publisher B ──┘                                      └──► Subscriber Y

Quan sát và tương tác với topic trực tiếp từ dòng lệnh, không cần viết code (chi tiết đầy đủ về công cụ ros2 topic có ở bài riêng trong chuyên mục ROS2 Tools):

ros2 topic list                    # liệt kê mọi topic đang hoạt động
ros2 topic echo /cmd_vel           # in ra màn hình mọi message đang chảy qua topic

ros2 topic echo là công cụ debug được dùng nhiều nhất khi mới học ROS2 — muốn biết một node có đang thực sự gửi dữ liệu đúng như mong đợi hay không, chỉ cần echo trực tiếp topic đó mà không cần viết bất kỳ dòng code nào.

Kiến thức kỹ thuật

Công thức

Băng thông thực tế một topic chiếm dụng tính bằng tần suất publish nhân kích thước mỗi message — quan trọng khi nhiều topic dữ liệu lớn (ảnh, point cloud) cùng chạy trên 1 mạng:

Băng thông (byte/giây) = Tần suất publish (Hz) × Kích thước 1 message (byte)

VD: topic /scan (LaserScan 360°, độ phân giải 0.25°) publish ở 10Hz
Kích thước 1 message ≈ 1440 điểm × ~4 byte/điểm + overhead ≈ ~6KB
Băng thông ≈ 10 × 6KB = 60KB/s (~0.48Mbps) — nhỏ so với băng thông Ethernet

Với topic ảnh camera độ phân giải cao chạy ở 30fps, con số này có thể lên tới hàng chục Mbps — đây là lý do dữ liệu ảnh/point cloud thường cần Ethernet (đã nói ở chuyên mục Giao tiếp phần cứng) thay vì mạng WiFi băng thông thấp.

Thông số

Các topic và kiểu message chuẩn phổ biến nhất khi làm việc với robot di động — biết trước các tên/kiểu này giúp đọc hiểu code ROS2 có sẵn nhanh hơn nhiều:

TopicKiểu messageNội dung
/cmd_velgeometry_msgs/msg/TwistLệnh vận tốc dài/góc gửi cho robot
/odomnav_msgs/msg/OdometryVị trí/vận tốc ước lượng từ encoder
/scansensor_msgs/msg/LaserScanDữ liệu quét LiDAR 2D
/image_rawsensor_msgs/msg/ImageẢnh thô từ camera

Protocol

Ở tầng dưới, mỗi cặp (tên topic + kiểu message) trong ROS2 ánh xạ trực tiếp thành một DDS Topic entity thật sự (đã nói ở bài ROS2 là gì) — publisher ROS2 chính là DDS DataWriter, subscriber ROS2 chính là DDS DataReader. Việc "publish" một message ROS2 thực chất là DDS tự động gửi dữ liệu qua mạng tới mọi DataReader đã đăng ký cùng Topic đó, dùng đúng cơ chế discovery và truyền dữ liệu chuẩn DDS — ROS2 chỉ thêm một lớp API thân thiện hơn bên trên.

Ứng dụng thực tế

Một node fusion (kết hợp dữ liệu cảm biến) trên AMR thường subscribe đồng thời nhiều topic khác nhau — VD: /scan (LiDAR), /imu/data (IMU), /odom (encoder) — để tính ra một ước lượng vị trí robot chính xác hơn từng cảm biến riêng lẻ. Mô hình many-to-many của topic cho phép node fusion này hoàn toàn độc lập với việc LiDAR/IMU/encoder cụ thể là loại nào — miễn đúng tên topic và kiểu message chuẩn, đổi cảm biến khác không cần sửa code node fusion.

Ví dụ thực tế

$ ros2 topic hz /scan
Output:
average rate: 10.021
	min: 0.095s max: 0.102s std dev: 0.00187s window: 50
$ ros2 topic bw /scan
Output:
Subscribed to [/scan]
6.02 KB/s from 10 messages
	Message size mean: 0.60 KB min: 0.60 KB max: 0.61 KB

Kết quả ros2 topic bw khớp gần đúng với phép tính ước lượng ở mục Công thức — xác nhận băng thông thực tế một topic đang chiếm dụng, hữu ích khi cần chẩn đoán mạng bị nghẽn do topic nào chiếm quá nhiều băng thông.

Lỗi thường gặp

  • Sai tên topic (typo) — publisher gửi lên /cmd_vel nhưng subscriber lại đăng ký nhầm /cmdvel — ROS2 không báo lỗi gì cả, cả 2 node vẫn chạy bình thường, chỉ đơn giản là không bao giờ nhận được dữ liệu của nhau — luôn dùng ros2 topic list để xác nhận đúng tên topic đang tồn tại.
  • Sai kiểu message giữa publisher và subscriber — 2 node khai cùng tên topic nhưng khác kiểu dữ liệu sẽ không kết nối được với nhau (dù cả 2 đều "chạy tốt" theo log riêng) — kiểm tra bằng ros2 topic info /ten_topic để xem đúng kiểu đang publish/subscribe.
  • QoS không khớp giữa publisher và subscriber — 2 bên cấu hình chính sách QoS (Quality of Service, xem bài riêng) không tương thích cũng khiến kết nối không thiết lập được, một nguyên nhân phổ biến nhưng khó nhận ra nếu chưa quen ROS2.
  • Publish quá nhanh vượt khả năng xử lý của subscriber — nếu subscriber xử lý mỗi message chậm hơn tần suất publish, message dồn ứ trong buffer nội bộ (kích thước buffer phụ thuộc cấu hình QoS) rồi bắt đầu bị rớt khi đầy, dữ liệu subscriber nhận được sẽ không liên tục dù publisher vẫn gửi đều.

Kết luận

Topic là cơ chế giao tiếp chủ đạo trong ROS2 cho dữ liệu chảy liên tục kiểu fire-and-forget, dựa trực tiếp trên mô hình publish-subscribe của DDS ở tầng dưới. Nắm vững cách tính băng thông và các lỗi kết nối thầm lặng (sai tên, sai kiểu, sai QoS) là kỹ năng debug nền tảng. Bài tiếp theo trong chuyên mục nói về Publisher — cách viết code phía gửi dữ liệu lên một topic.

Topic trong ROS2 là gì? — Atlasbot