# Kiến Trúc recovery_core ## Vị trí trong stack `recovery_core` nằm ở tầng `Navigations/Libraries`, cạnh `robot_clear_costmap_recovery`. Nó giữ vai trò interface tương tự `robot_nav_core::RecoveryBehavior` cho các recovery cần **trả về output** (path/vận tốc), đồng thời vẫn dùng global path/costmap/tf như bản gốc. ## Các thành phần - `RecoveryBehavior` (interface, template-method): API non-virtual `configure`/`start`/`update`/ `cancel`; plugin chỉ triển khai hook `onConfigure`/`onStart(goal)`/`onUpdate(dt)`. - `RecoveryContext`: gói con trỏ ngữ cảnh (tf/costmap/global_path) truyền một lần qua `configure`. - `RecoveryGoal`: mục tiêu RUNTIME mỗi lượt (angle/distance/target_pose/params). - `RecoveryResult` / `RecoveryStatus` / `RecoveryOutputType`: hợp đồng output hợp nhất 3 họ + rich feedback (`progress`/`remaining`/`elapsed`/`message`), thêm trạng thái `kCancelled`. - Plugin mẫu: - `ClearCostmapRecovery`: clear layer costmap theo tên, one-shot no-output. - `RotateRecovery`: quay tới `goal.angle` (rad); sinh `Twist.angular.z` mỗi cycle. - `BackUpRecovery`: lùi tới `goal.distance` (m); sinh `Twist.linear.x < 0` mỗi cycle. - `RegenPathRecovery`: trả lại `robot_nav_msgs::Path` từ `global_path` hiện tại. ## Luồng runtime ``` configure(name, ctx) // 1 lần: cache ctx, đọc config chung, onConfigure() │ start(goal) // mỗi lượt: chốt mục tiêu runtime, onStart() │ ├── one-shot (họ A/B): update(dt) 1 lần ─────────► RecoveryResult{status, path|none, msg} │ └── per-cycle (họ C): loop { update(dt) } ──────► RecoveryResult{status, velocity, (tới khi status != kRunning) progress, remaining} ``` ## Ghi chú thiết kế - Template-method: base xử lý guard vòng đời (configure→start→update), `dt<=0`, `timeout`, đo `elapsed`, và `cancel` một chỗ; plugin không lặp lại các guard này. - Mục tiêu là RUNTIME qua `RecoveryGoal` (không cố định trong config): cùng plugin phục vụ nhiều yêu cầu góc/khoảng khác nhau. Field = 0 → dùng default plugin đọc ở `onConfigure()`. - `onUpdate(dt)` lấy pose robot từ costmap/tf bên trong; không truyền pose qua tham số. - Sau `cancel()`, base tự trả stop output (Twist 0) + `kCancelled`. - Param chung duy nhất còn lại là `timeout` (s, 0 = không giới hạn), base đọc trong `configure()` từ `~//timeout`; giá trị `NaN/Inf/<0` bị thay bằng 0. Param RIÊNG của plugin đọc trong `onConfigure()`. - Interface KHÔNG include Boost.DLL; export/import là việc của plugin/loader. - Plugin mẫu có dùng Boost.DLL alias, nhưng core contract vẫn không biết loader/adaptor.