Atlas Robotics
Điều khiển RobotTrung bình

Trajectory: khác gì giữa một đường đi (path) và một quỹ đạo?

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

Trajectory: khác gì giữa một đường đi (path) và một quỹ đạo?
Path là chuỗi điểm trong không gian, Trajectory thêm chiều thời gian

Hai từ "path" và "trajectory" hay bị dùng lẫn lộn, nhưng trong robot học có ý nghĩa khác nhau rõ rệt — và sự khác biệt đó quan trọng thực sự, không chỉ là chơi chữ.

Khái niệm chính

Path (đường đi) chỉ là một chuỗi vị trí (x, y) nối tiếp nhau trong không gian — trả lời câu hỏi "robot cần đi qua những điểm nào để tới đích", không nói gì về khi nào robot ở điểm nào. Đây chính là kết quả của planner_server trong Nav2 — publish trên topic /plan.

path = [(0,0), (1,0), (2,0.5), (3,1), (4,1)]   # chỉ có vị trí, không có thời gian

Trajectory (quỹ đạo) là path cộng thêm thông tin robot sẽ ở mỗi điểm vào lúc nào:

trajectory = [(0,0,t=0), (1,0,t=1.2s), (2,0.5,t=2.8s), (3,1,t=4.1s), (4,1,t=5.5s)]

Tóm lại: Path trả lời "đi qua đâu", Trajectory trả lời "đi qua đâu và khi nào". Một path duy nhất có thể sinh ra vô số trajectory khác nhau — đi chậm rãi hay đi nhanh dọc theo đúng cùng một path vẫn là cùng một path, nhưng là hai trajectory khác nhau.

Nguyên lý hoạt động

Path tĩnh không đủ để né một vật cản đang di chuyển (người đi bộ cắt ngang) — cần biết khi nào robot ở một điểm để so sánh với dự đoán vị trí người đi bộ tại đúng thời điểm đó. Các bộ điều khiển hiện đại như MPPI làm việc trực tiếp trên trajectory — dự đoán nhiều trajectory khả dĩ trong vài giây tới, chấm điểm mỗi trajectory dựa trên khả năng va chạm với vật cản động, không chỉ dựa trên path tĩnh.

planner_server  →  path (chuỗi điểm tĩnh, tính 1 lần khi có goal mới)
controller_server → trajectory (vận tốc theo thời gian thực, tính lại mỗi chu kỳ)
                     bám theo path, tôn trọng giới hạn gia tốc, né vật cản động phát sinh

planner_server tính path một lần; controller_server liên tục tính lại trajectory theo thời gian thực để bám path đó.

Kiến thức kỹ thuật

Công thức

Vận tốc ngụ ý (implied velocity) giữa 2 điểm liên tiếp trên trajectory tính trực tiếp từ khoảng cách và chênh lệch thời gian — dùng để kiểm tra trajectory có khả thi về mặt động học hay không:

v = khoảng_cách(điểm_i, điểm_i+1) / (t_i+1 − t_i)

VD: từ (1,0,t=1.2s) tới (2,0.5,t=2.8s) trong ví dụ trajectory ở trên
khoảng cách = √((2−1)² + (0.5−0)²) ≈ 1.118m
Δt = 2.8 − 1.2 = 1.6s
v ≈ 1.118 / 1.6 ≈ 0.70 m/s

Tính tương tự cho mọi cặp điểm liên tiếp, rồi so sánh chênh lệch vận tốc giữa các đoạn với giới hạn gia tốc a_max (bài trước) để xác nhận trajectory có "khả thi" — không yêu cầu robot tăng/giảm tốc nhanh hơn khả năng vật lý cho phép.

Thông số

Bộ điều khiển MPPI (Model Predictive Path Integral, dùng trong Nav2 hiện đại) sinh và chấm điểm hàng loạt trajectory ứng viên mỗi chu kỳ:

Thông số MPPIGiá trị điển hình
Số trajectory ứng viên mỗi chu kỳVài trăm tới vài nghìn
Thời gian dự đoán trước (horizon)1 – 3 giây
Tần số tính lạiCùng tần số controller_server, thường 10-30Hz

Ứng dụng thực tế

MPPI chấm điểm mỗi trajectory ứng viên dựa trên tổ hợp nhiều tiêu chí cùng lúc: khoảng cách còn lại tới goal (càng gần càng tốt), nguy cơ va chạm với vật cản tĩnh/động tại đúng thời điểm dự kiến trên trajectory đó (càng thấp càng tốt), và độ mượt của chuyển động (tránh đổi hướng/tốc độ đột ngột, tôn trọng giới hạn gia tốc đã học ở bài trước) — trajectory có điểm tổng hợp tốt nhất được chọn thực thi trong chu kỳ đó, rồi toàn bộ quá trình lặp lại ở chu kỳ tiếp theo với dữ liệu cảm biến mới nhất. Đây là lý do robot chạy Nav2/MPPI có thể né được người đi bộ đang di chuyển cắt ngang đường — nó không chỉ nhìn thấy vị trí hiện tại của người đó, mà đánh giá trước nhiều khả năng vị trí tương lai ứng với từng trajectory ứng viên của chính robot.

Ví dụ thực tế

import math

trajectory = [(0,0,0), (1,0,1.2), (2,0.5,2.8), (3,1,4.1), (4,1,5.5)]
a_max = 1.0  # m/s^2, gioi han da hoc bai truoc

velocities = []
for i in range(len(trajectory)-1):
    x1,y1,t1 = trajectory[i]
    x2,y2,t2 = trajectory[i+1]
    dist = math.sqrt((x2-x1)**2 + (y2-y1)**2)
    v = dist / (t2 - t1)
    velocities.append(v)
    print(f"Doan {i}: v={v:.2f} m/s")

for i in range(len(velocities)-1):
    dv = abs(velocities[i+1] - velocities[i])
    dt = trajectory[i+2][2] - trajectory[i][2]
    a_thuc_te = dv / dt
    trang_thai = "OK" if a_thuc_te <= a_max else "VUOT GIOI HAN"
    print(f"Gia toc doan {i}->{i+1}: {a_thuc_te:.2f} m/s^2 [{trang_thai}]")
Output:
Doan 0: v=0.83 m/s
Doan 1: v=0.70 m/s
Doan 2: v=0.77 m/s
Doan 3: v=0.71 m/s
Gia toc doan 0->1: 0.09 m/s^2 [OK]
Gia toc doan 1->2: 0.02 m/s^2 [OK]
Gia toc doan 2->3: 0.02 m/s^2 [OK]

Toàn bộ trajectory mẫu đều nằm trong giới hạn gia tốc 1.0 m/s² — nếu bất kỳ đoạn nào vượt ngưỡng, trajectory đó không khả thi về mặt động học, robot không thể thực sự bám theo đúng như kế hoạch dù path hình học có hợp lý tới đâu.

Lỗi thường gặp

  • Sinh trajectory vi phạm giới hạn gia tốc/vận tốc — như minh hoạ ở ví dụ trên, một trajectory "trông hợp lý" về mặt hình học vẫn có thể đòi hỏi gia tốc vượt quá khả năng thực tế của robot — luôn kiểm tra tính khả thi động học trước khi tin tưởng thực thi.
  • Tần số tính lại trajectory quá chậm so với tốc độ thay đổi môi trường — nếu vật cản động di chuyển nhanh hơn nhiều so với tần số controller_server tính lại trajectory, robot phản ứng trễ với thay đổi, tương tự vấn đề khoảng cách phản ứng đã học ở bài Sense-Think-Act.
  • Nhầm lẫn giữa tần số replan path và tần số tính trajectory — 2 tầng khác nhau: path (chậm, chỉ tính lại khi cần) và trajectory (nhanh, tính lại liên tục) — nhầm lẫn 2 khái niệm này khi cấu hình Nav2 gây kỳ vọng sai về tốc độ phản ứng thực tế.
  • Sai lệch mốc thời gian khi nội suy giữa các waypoint — nếu code tự nội suy vị trí giữa 2 điểm trajectory theo thời gian mà tính sai công thức nội suy tuyến tính theo t, robot có thể "tưởng" mình đang ở vị trí khác với vị trí trajectory thực sự dự kiến tại thời điểm đó.

Kết luận

Phân biệt rõ path (không gian thuần tuý) và trajectory (không gian + thời gian) là chìa khoá để hiểu vì sao robot hiện đại né được vật cản động — chỉ path tĩnh không đủ thông tin để biết "khi nào" cần né. Luôn kiểm tra trajectory khả thi về mặt động học (tôn trọng giới hạn gia tốc) trước khi thực thi. Bài tiếp theo trong chuyên mục, cũng là bài cuối, nói về Điều khiển vòng kín (Closed-loop Control) — nguyên lý tổng quát đứng sau PID, velocity control, và mọi cơ chế phản hồi đã học xuyên suốt chuyên mục này.

Trajectory: khác gì giữa một đường đi (path) và một quỹ đạo? — Atlasbot