DDS Configuration — cấu hình thực tế cho robot nhiều máy
Atlasbot · 17/8/2026 · 11 phút đọc
Bài DDS là gì? đã giải thích RMW là lớp trừu tượng cho phép đổi triển khai DDS bên dưới. Bài này đi vào các biến môi trường và file cấu hình dùng thực tế khi triển khai robot nhiều máy — đúng tình huống một PC điều khiển và một máy tính nhúng trên robot (như kiến trúc Jetson Orin Nano + PC trong dự án Atlas A2) phải cùng nhìn thấy nhau qua mạng.
Khái niệm chính
echo $RMW_IMPLEMENTATION
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp # đổi từ Fast DDS (mặc định) sang Cyclone DDS
Đổi triển khai không cần build lại code — vì code ứng dụng chỉ gọi qua rclpy/rclcpp, không bao giờ gọi thẳng API của DDS cụ thể. Lý do hay cần đổi trong thực tế: Cyclone DDS thường ổn định hơn trên mạng WiFi không đáng tin cậy (robot di động), trong khi Fast DDS là mặc định và có cộng đồng lớn hơn khi cần tra cứu lỗi.
Nguyên lý hoạt động
Cô lập nhiều robot cùng mạng bằng ROS_DOMAIN_ID:
export ROS_DOMAIN_ID=42
Mỗi domain ID là một "kênh" DDS độc lập — node ở domain 42 không thấy node ở domain 0, dù chạy chung một mạng WiFi vật lý. Bắt buộc mọi máy tham gia cùng một hệ thống robot phải đặt cùng một domain ID — quên đồng bộ giá trị này là nguyên nhân phổ biến nhất của lỗi "topic list rỗng dù node rõ ràng đang chạy trên máy kia".
export ROS_LOCALHOST_ONLY=1
Biến này giới hạn discovery chỉ trong localhost — hữu ích khi chạy nhiều instance ROS2 test độc lập trên cùng một máy mà không muốn chúng vô tình nhìn thấy nhau.
Tóm lại:
RMW_IMPLEMENTATIONchọn loại DDS chạy bên dưới,ROS_DOMAIN_IDchọn kênh cô lập giữa các nhóm node — hai biến độc lập nhau, cả hai đều phải khớp giữa các máy tham gia cùng hệ thống mới giao tiếp được.
QoS Profile XML — khi API mặc định không đủ, dùng file XML riêng của từng triển khai DDS để khai discovery tường minh:
<!-- cyclonedds_config.xml -->
<CycloneDDS>
<Domain>
<General>
<NetworkInterfaceAddress>192.168.1.50</NetworkInterfaceAddress>
</General>
<Discovery>
<Peers>
<Peer Address="192.168.1.10"/> <!-- PC điều khiển -->
<Peer Address="192.168.1.50"/> <!-- Jetson trên robot -->
</Discovery>
</Domain>
</CycloneDDS>
</CycloneDDS>
export CYCLONEDDS_URI=file:///path/to/cyclonedds_config.xml
Kiến thức kỹ thuật
Thông số
Các biến môi trường DDS/ROS2 hay dùng nhất, gộp lại thành một bảng tra cứu nhanh:
| Biến môi trường | Tác dụng |
|---|---|
RMW_IMPLEMENTATION | Chọn triển khai DDS (rmw_fastrtps_cpp, rmw_cyclonedds_cpp...) |
ROS_DOMAIN_ID | Cô lập nhóm node (0-101), phải khớp giữa mọi máy cùng hệ thống |
ROS_LOCALHOST_ONLY | Giới hạn discovery trong máy hiện tại, không ra mạng ngoài |
CYCLONEDDS_URI | Đường dẫn file cấu hình XML chi tiết cho Cyclone DDS |
FASTRTPS_DEFAULT_PROFILES_FILE | Tương đương CYCLONEDDS_URI nhưng dành cho Fast DDS |
Ứng dụng thực tế
Quy trình triển khai DDS chuẩn cho một hệ thống robot nhiều máy (VD: PC điều khiển + Jetson trên robot) gồm 3 bước: (1) đặt cùng ROS_DOMAIN_ID trong file môi trường khởi động của cả 2 máy (.bashrc hoặc file môi trường của systemd service, không chỉ gõ tay trong 1 terminal); (2) kiểm tra tường lửa (firewall) cho phép đúng dải cổng UDP tính theo công thức 7400 + 250×domain_id đã học ở bài DDS; (3) nếu mạng chặn multicast (phổ biến ở mạng công ty/toà nhà), chuyển sang cấu hình Peers unicast tường minh như ví dụ XML ở trên — bỏ qua bước 3 là nguyên nhân phổ biến nhất khiến 2 máy "đặt đúng domain ID rồi mà vẫn không thấy nhau" trên mạng doanh nghiệp.
Ví dụ thực tế
$ ros2 multicast receive
# Terminal 1 (trên PC điều khiển)
Waiting for datagrams...
$ ros2 multicast send
# Terminal 2 (trên Jetson của robot)
Sending 1 bytes...
Nếu Terminal 1 nhận được gói tin: multicast hoạt động bình thường giữa 2 máy
Nếu không nhận được gì sau vài giây: mạng đang chặn multicast — cần chuyển
sang cấu hình unicast Peers tường minh như ví dụ XML đã nêu
ros2 multicast send/receive là công cụ chẩn đoán chính xác nhất để xác nhận vấn đề nằm ở tầng mạng (multicast bị chặn) hay ở tầng cấu hình ROS2 (ROS_DOMAIN_ID sai) — tách 2 khả năng này ra rõ ràng trước khi đi sâu debug thêm.
Lỗi thường gặp
- Quên đồng bộ
ROS_DOMAIN_IDgiữa các máy — như đã nói ở phần Nguyên lý hoạt động, đây là nguyên nhân phổ biến nhất của lỗi "không thấy node/topic của máy kia". - Đặt biến môi trường trong terminal nhưng không áp dụng cho systemd service — service chạy tự động lúc boot không tự kế thừa biến môi trường đã
exporttrong 1 phiên terminal thủ công — cần khai trong fileEnvironment=của service definition hoặc file môi trường riêng được service đó đọc. - Cấu hình unicast Peers nhưng quên mở tường lửa đúng cổng — chỉ khai
<Peers>trong XML chưa đủ nếu tường lửa hệ thống vẫn chặn dải cổng UDP tính theo công thức domain ID — kiểm tra cả 2 lớp (cấu hình DDS lẫn tường lửa hệ điều hành). - Trộn triển khai DDS khác nhau giữa các máy mà không kiểm tra tương thích — như đã nói ở bài DDS, dù cùng tuân theo chuẩn RTPS, một số phần mở rộng riêng của từng hãng đôi khi gây vấn đề tinh vi — nên đồng bộ 1 triển khai DDS cho toàn hệ thống nếu có thể.
Kết luận
Cấu hình DDS thực tế xoay quanh 2 lớp: chọn đúng triển khai (RMW_IMPLEMENTATION) và cô lập đúng kênh (ROS_DOMAIN_ID), với XML profile là công cụ dự phòng khi cần vượt qua giới hạn của multicast trên mạng doanh nghiệp. ros2 multicast send/receive là công cụ chẩn đoán nhanh nhất để tách vấn đề mạng khỏi vấn đề cấu hình ROS2. Đây cũng là bài cuối cùng của toàn bộ category ROS / ROS2 — từ khái niệm cơ bản (node, topic, service, action), cơ chế giao tiếp (message, QoS, DDS, TF2), đóng gói package, bộ công cụ CLI, tới các kỹ thuật nâng cao (lifecycle, composition, callback group, threading, executor, DDS) vừa học, đã đủ nền tảng toàn diện để xây dựng và vận hành một hệ thống phần mềm robot ROS2 hoàn chỉnh trong thực tế.