Atlas Robotics
AMR Software ArchitectureTrung bình

Navigation Layer trong AMR: global planner và local planner phối hợp ra sao

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

Navigation Layer trong AMR: global planner và local planner phối hợp ra sao
Global planner tính đường đi tổng thể, local planner né vật cản tức thời

Chuyên mục ROS2 Navigation đã có bài riêng về Path Planning và Path Following. Bài này không lặp lại thuật toán A*/DWB cụ thể — nó đứng đúng vị trí của Navigation Layer trong mô hình 5 tầng: nhận vị trí đáng tin cậy từ Localization Layer (bài trước), trả về lệnh /cmd_vel cho ROS2 Layer gửi xuống Driver Layer.

Khái niệm chính

Navigation Layer tách thành 2 planner chạy song song, khác nhau về phạm vi và tần số:

  • Global Planner — nhìn toàn bộ bản đồ tĩnh, tính đường đi tối ưu tổng thể, chỉ tính lại khi có goal mới hoặc đường đi hiện tại bị chặn hoàn toàn
  • Local Planner — chỉ nhìn vùng nhỏ quanh robot, tính lại liên tục (5-20Hz) để né vật cản động xuất hiện đột ngột mà bản đồ tĩnh không biết trước

Nguyên lý hoạt động

Cả hai planner đều đọc chung một cấu trúc dữ liệu gọi là costmap — không phải bản đồ đơn thuần, mà là bản đồ đã gán "chi phí" cho từng ô: ô càng gần vật cản, chi phí càng cao, robot càng nên tránh đi qua:

Costmap = Bản đồ tĩnh (từ SLAM/AMCL)
        + Lớp vật cản động (cập nhật liên tục từ /scan LiDAR)
        + Lớp inflation (vùng đệm an toàn quanh mỗi vật cản, chi phí giảm dần theo khoảng cách)

Global costmap dùng bản đồ tĩnh làm nền chính, ít cập nhật lớp vật cản động; local costmap ngược lại — ưu tiên cập nhật liên tục lớp vật cản động trong phạm vi hẹp quanh robot, vì đây chính là dữ liệu giúp né người/xe đẩy hàng vừa xuất hiện mà bản đồ tĩnh (dựng từ trước) không thể biết trước.

Tóm lại: Global planner trả lời "đường đi tổng thể tối ưu là gì", local planner trả lời "trong vài giây tới, cần né gì ngay lập tức". Hai câu hỏi khác nhau, chạy tần số khác nhau, nhưng luôn phối hợp — local planner luôn cố gắng bám theo đường đi global planner đã vạch ra, chỉ lệch khỏi nó khi thực sự cần né vật cản.

Kiến thức kỹ thuật

Công thức

Lớp inflation trong costmap gán chi phí giảm dần theo khoảng cách tới vật cản gần nhất — càng xa vật cản, chi phí càng thấp, tới một ngưỡng thì bằng 0:

Chi_phí(khoảng_cách) = Chi_phí_tối_đa × e^(−hệ_số_suy_giảm × khoảng_cách)
                        (dạng suy giảm hàm mũ, dùng phổ biến trong Nav2 costmap)

Bán_kính_inflation nên lớn hơn hoặc bằng bán kính robot + biên an toàn mong muốn,
để costmap không bao giờ coi một điểm quá sát vật cản là "chi phí 0" an toàn tuyệt đối

Thông số

PlannerTần số tính lạiPhạm vi nhìnViệc chính
Global PlannerKhi có goal mới / đường bị chặn hoàn toànToàn bộ bản đồTìm đường đi tối ưu tổng thể (thường thuật toán A*/Dijkstra)
Local Planner5-20Hz liên tụcVùng nhỏ quanh robot (vài mét)Bám đường global, né vật cản động tức thời (thường DWB/TEB)

Ứng dụng thực tế

Trong vận hành AMR thực tế ở kho hàng, tình huống điển hình thể hiện rõ phối hợp 2 tầng: global planner tính đường đi qua giữa 2 dãy kệ hàng dựa trên bản đồ tĩnh đã có; khi một người bất ngờ bước ra từ góc kệ, local planner phát hiện qua /scan (đã học ở bài LiDAR trong AMR) và điều chỉnh cục bộ để né, mà không cần tính lại toàn bộ đường đi từ đầu — global planner chỉ can thiệp lại nếu đường đi bị chặn hoàn toàn (VD: hành lang tắc nghẽn kéo dài), không phải mỗi khi có vật cản nhỏ thoáng qua.

Ví dụ thực tế

# Xem costmap dưới dạng ảnh trong RViz2 để debug trực quan
ros2 run nav2_costmap_2d nav2_costmap_2d_markers

# Kiểm tra tần số tính toán thực tế của local planner (nên khớp cấu hình, VD 10Hz)
ros2 topic hz /cmd_vel

# Gửi thử một goal để kích hoạt global planner
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose \
  "{pose: {header: {frame_id: 'map'}, pose: {position: {x: 2.0, y: 1.0}}}}"

Nếu robot dừng lại giữa đường không rõ lý do, kiểm tra trước tiên xem local planner có đang publish /cmd_vel liên tục hay không (ros2 topic hz) — tần số về 0 thường có nghĩa local planner "bí" đường (robot bị kẹt trong costmap), cần xem lại cấu hình bán kính inflation hoặc kiểm tra dữ liệu /scan có bất thường không.

Lỗi thường gặp

  • Đặt bán kính inflation quá nhỏ so với kích thước robot thực tế — như ở mục Công thức, costmap coi một số điểm quá sát vật cản là an toàn, robot có thể va chạm dù local planner hoạt động đúng logic.
  • Kỳ vọng global planner phản ứng tức thời với vật cản động — đây là nhiệm vụ của local planner; global planner chỉ tính lại khi cần thiết, không phải mỗi khi có vật cản nhỏ xuất hiện.
  • Không kiểm tra tần số /cmd_vel khi robot dừng bất thường — như ví dụ trên, đây nên là bước debug đầu tiên trước khi nghi ngờ thuật toán planner phức tạp hơn.
  • Cấu hình local costmap phạm vi quá hẹp — robot không kịp phát hiện vật cản đủ sớm để né mượt mà, dẫn tới né gấp hoặc dừng đột ngột thay vì điều chỉnh quỹ đạo từ từ.

Kết luận

Navigation Layer tách thành 2 planner tần số khác nhau vì cùng lý do đã thấy xuyên suốt kiến trúc AMR: không có thuật toán nào vừa nhìn xa (toàn bản đồ) vừa phản ứng tức thời (vài chục Hz) cùng lúc hiệu quả. Costmap là ngôn ngữ chung kết nối cả hai, với lớp inflation đảm bảo biên an toàn quanh mọi vật cản. Đây cũng là bài áp chót của chuyên mục — bài cuối đi vào Application Layer, nơi lệnh "đi tới điểm này" ban đầu thực sự bắt nguồn từ đâu.

Navigation Layer trong AMR: global planner và local planner phối hợp ra sao — Atlasbot