Atlas Robotics
Bài 3/6 · khoảng 10 phút

TF tree

TF tree là tập hợp mọi transform trong hệ thống, ghép lại thành một cây — không phải một đồ thị tùy ý. Mỗi frame có đúng một frame cha (trừ frame gốc), nhưng có thể có nhiều frame con.

Ràng buộc "đúng một cha" không phải giới hạn kỹ thuật cho vui — đó là điều làm TF luôn giải được. Muốn biết transform giữa hai frame bất kỳ, kể cả không nối trực tiếp, chỉ cần đi ngược lên tổ tiên chung rồi ghép các transform lại. Khai báo 2 frame cha cho cùng một frame con sẽ phá vỡ tính chất này — TF báo lỗi hoặc cho kết quả không xác định.

Xem tf2 "đi tìm" transform thế nào

Cây ví dụ dưới đây là một cánh tay robot chung chung — không phải cây thật của Atlas, để dành cho bài tập cuối module. Mỗi cạnh của cây có sẵn một transform cụ thể (x, y, yaw). "Ghép transform lại" ở trên không phải phép cộng — về mặt toán, mỗi transform 2D viết được dưới dạng một ma trận đồng nhất 3×3:

T = [ cosθ  -sinθ   x ]
    [ sinθ   cosθ   y ]
    [  0      0     1 ]

Ghép hai transform liên tiếp = nhân hai ma trận; đi ngược chiều (con → cha thay vì cha → con) = nhân với ma trận nghịch đảo. tf2 không làm gì khác hơn thế — chỉ là làm với ma trận 4×4 và quaternion cho đủ 3 chiều, thay vì 3×3 và góc yaw như ở đây. Chọn 2 frame không nối trực tiếp, bấm "Tìm transform", rồi theo dõi từng phép nhân:

Tắt ô "Hiện phép nhân ma trận" nếu chỉ muốn xem đường đi trực quan, không cần nhìn số.

Bên dưới chỉ là topic

TF không có cơ chế truyền tải gì đặc biệt — nó chỉ là 2 topic /tf (động, kiểu TFMessage) và /tf_static (tĩnh, publish một lần với QoS TRANSIENT_LOCAL — subscriber tới trễ vẫn nhận được). Thư viện tf2_ros tự gộp message từ nhiều node lại thành một cây hoàn chỉnh trong bộ nhớ (Buffer), kèm nội suy theo thời gian — không có gì bạn chưa học ở Module 1, chỉ là một lớp tiện ích xây trên pub/sub.

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_tf.launch.py
# Terminal 2 — nghe /tf + /tf_static trong 5 giây rồi tự thoát, xuất ra PDF
ros2 run tf2_tools view_frames

Mở file frames_<timestamp>.pdf vừa xuất ra — đúng cây 3 frame: world → static_frame (tĩnh) + world → moving_frame (động), minh họa "một cha, nhiều con".

Ví dụ trong dự án Atlas

Atlas hoàn chỉnh (từ Module 3 trở đi) có TF tree với gốc map, nhánh qua odom → base_link, rồi từ base_link tỏa ra nhiều frame con (bánh xe, caster, cảm biến — xem bài tập, cố tình chưa vẽ ở đây). Khi Nav2 chạy (Module 10) còn có thêm nhánh base_link → local_costmap… — cây TF thật của một robot hoàn chỉnh dễ có 10+ frame.

Hai lệnh sẽ dùng lại xuyên suốt các module sau để debug TF của Atlas:

ros2 run tf2_tools view_frames
ros2 run tf2_ros tf2_echo <frame_cha> <frame_con>