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

ROS 2 và kiến trúc DDS

ROS 2 không tự cài đặt cơ chế truyền dữ liệu qua mạng — phần đó do một chuẩn công nghiệp có tên DDS (Data Distribution Service) đảm nhiệm, vốn dùng từ trước trong hàng không, quốc phòng, tài chính vì độ tin cậy cao.

ROS 2 đứng trên DDS, cung cấp một lớp API quen thuộc (publisher, subscriber, service...) để bạn không phải làm việc trực tiếp với các khái niệm phức tạp bên dưới. Đây là khác biệt lớn nhất so với ROS 1 — vốn tự viết toàn bộ tầng giao tiếp riêng và cần một tiến trình trung tâm (roscore) để điều phối.

Vì sao ROS 2 không cần roscore?

ROS 1 có một máy chủ trung tâm (roscore) để các node tìm nhau. Nếu nó chết, cả hệ thống mất liên lạc. ROS 2 bỏ máy chủ đó: các node tự phát hiện nhau qua DDS. Đây gọi là discovery.

Mỗi node "phát thông báo" định kỳ. Node nào nhận thông báo có topic và kiểu message khớp với mình thì tự nối với nhau. Xem mô hình dưới.

Dữ liệu đi qua những tầng nào?

Bạn viết code ở tầng trên cùng. Mỗi tầng dưới làm một việc cụ thể hơn. Khi publish, dữ liệu đi xuống; khi nhận, đi lên.

Code dưới khung mô hình đổi theo đúng vị trí của chấm: chấm ở tầng nào, đoạn code của tầng đó hiện ra (đơn giản hóa để dễ hình dung, không phải chữ ký hàm thật của rcl/rmw). Bấm "Gửi 1 message" rồi theo dõi.

Bốn tầng, mỗi tầng một việc

TầngVai tròBạn gặp ở đâu
Code của bạnAPI: publisher, subscription, servicerclpy (Python), rclcpp (C++)
rclLõi C dùng chung cho mọi ngôn ngữKhông gọi trực tiếp
rmwLớp trung gian che DDS cụ thểBiến RMW_IMPLEMENTATION
DDSDiscovery, truyền dữ liệu, QoSFast DDS (mặc định Humble), Cyclone DDS

Cách cô lập mạng: ROS_DOMAIN_ID

Nhiều robot có thể chạy trên cùng một mạng. Để tránh node của robot này nói chuyện với robot kia, mỗi nhóm đặt một domain riêng bằng biến ROS_DOMAIN_ID. Thử đổi domain của từng node:

Hai node khác ROS_DOMAIN_ID sẽ không thấy nhau, dù chạy cùng máy. Khi "không thấy topic" trong terminal, hãy kiểm tra domain trước tiên.

Thử ngay

echo $ROS_DOMAIN_ID
echo $RMW_IMPLEMENTATION

Nếu biến trống, ROS 2 dùng giá trị mặc định: domain 0 và DDS mặc định của bản cài.