Atlas Robotics
Bài 4/9 · khoảng 12 phút

Topic, Publisher/Subscriber, QoS

Topic là một kênh dữ liệu có tên và có kiểu message cố định (ví dụ /sensor_data mang std_msgs/Float64). Publisher đẩy message lên topic đó theo nhịp riêng của mình; subscriber nào đã đăng ký nghe topic đó thì tự động nhận.

Publisher không cần biết có ai đang nghe hay không, và một topic cũng không giới hạn số publisher/subscriber. Đây là mô hình giao tiếp phổ biến nhất trong ROS 2 vì phản ánh đúng bản chất robot: dữ liệu cảm biến, trạng thái, lệnh điều khiển đều là các luồng liên tục, không phải các yêu cầu rời rạc.

pub/subluồng liên tụcmột chiềuQoS

Kết nối được thiết lập như thế nào?

Publisher và subscriber khớp nhau bằng tên topic và kiểu message. Lệch một trong hai là không nối; ROS 2 chỉ ghi cảnh báo trong log. Một topic có thể có nhiều publisher và nhiều subscriber.

QoS: "chất lượng" của việc truyền

Mỗi bên đi kèm một bộ QoS. Hai trường quan trọng nhất:

TrườngGiá trịÝ nghĩa
ReliabilityRELIABLEMất gói thì gửi lại. Không mất dữ liệu, có thể trễ.
ReliabilityBEST_EFFORTMất là mất. Nhanh, phù hợp dữ liệu liên tục như cảm biến.
DurabilityVOLATILEChỉ nhận message phát sau khi kết nối (mặc định).
DurabilityTRANSIENT_LOCALNhận luôn message cuối, kể cả phát trước khi kết nối. Dùng cho trạng thái như bản đồ.

Thử: đổi QoS và đường truyền

Chọn RELIABLE rồi tăng tỷ lệ mất gói. Sau đó đổi sang BEST_EFFORT với cùng tỷ lệ và so sánh số liệu.

Quy tắc quan trọng: nếu publisher và subscriber có QoS không tương thích (ví dụ publisher BEST_EFFORT, subscriber RELIABLE), kết nối sẽ không được thiết lập. Thường chỉ có một dòng cảnh báo "incompatible QoS" trong log, dễ bỏ qua, và subscriber không nhận được gì.

Thử ngay

Cần 2 terminal (đã source install/setup.bash, xem Module 0):

# Terminal 1 — để chạy, đừng tắt
ros2 launch ros2_basics demo.launch.py
# Terminal 2
ros2 topic list
# Terminal 2 — lệnh này chạy liên tục, Ctrl+C để dừng
ros2 topic echo /sensor_data
# Terminal 2 — sau khi đã Ctrl+C lệnh echo ở trên
ros2 topic info /sensor_data --verbose

Lệnh --verbose hiện QoS của từng publisher và subscriber, giúp tìm lý do hai bên không nói chuyện được.