|
| 1 | +# Hybrid A* + Pure Pursuit baseline |
| 2 | + |
| 3 | +A "global planner blind to dynamic obstacles" baseline added to |
| 4 | +`benchmark_diff_mppi` as `planner_kind=3`. The intent is to make the |
| 5 | +paradigm gap between global-plan-then-track and local replanning |
| 6 | +visible on the same scenario grid the local planners are evaluated |
| 7 | +against. |
| 8 | + |
| 9 | +## What it does |
| 10 | + |
| 11 | +`include/hybrid_astar_pp.h` is a header-only forward-only Hybrid A* |
| 12 | +search plus a pure pursuit tracker. The variant `hybrid_astar_pp` |
| 13 | +calls the search once per episode (at first `controller_update`) |
| 14 | +against the **static** obstacles only -- dynamic obstacles are |
| 15 | +deliberately not consulted -- and then pure-pursuit-tracks the |
| 16 | +returned path for the rest of the episode without replanning. |
| 17 | + |
| 18 | +Hybrid A* parameters: 1 m x 1 m x 10-degree lattice, 7 steering |
| 19 | +choices, 2.5 m per node expansion (so children land in distinct |
| 20 | +cells), Euclidean heuristic on arc-length cost. Forward-only -- |
| 21 | +Reeds-Shepp is not implemented, which matches the scenario geometry |
| 22 | +(the goal is reachable without reverse motions). Goal heading |
| 23 | +tolerance is left at pi so the position threshold is the binding |
| 24 | +constraint. |
| 25 | + |
| 26 | +Pure pursuit parameters: lookahead 4 m, target speed 5 m/s, linear |
| 27 | +speed gain 1.5. The goal_slowdown_radius brings the target speed |
| 28 | +linearly to 0 inside 5 m of the path's final waypoint. |
| 29 | + |
| 30 | +## Sweep result |
| 31 | + |
| 32 | +Same grid as `docs/local_planner_comparison.md`: 3 dynamic scenarios |
| 33 | +x 5 speed-scales x 2 radius-scales = 30 cells per planner, 4 seeds, |
| 34 | +K=4096 (`build/sweep_with_hap_summary.csv`). |
| 35 | + |
| 36 | +Per-planner summary across all 30 cells: |
| 37 | + |
| 38 | +| planner | family | cells | solved | mean succ | mean final_d | mean coll | mean ms | |
| 39 | +|--------------------|-----------|------:|-------:|----------:|-------------:|----------:|--------:| |
| 40 | +| hybrid_astar_pp | Hybrid-A* | 30 | 21 | 0.70 | 1.91 | 6.23 | 0.05 | |
| 41 | +| dwa_fast | DWA | 30 | 28 | 0.93 | 1.94 | 0.60 | 0.10 | |
| 42 | +| dwa_med | DWA | 30 | 30 | 1.00 | 1.91 | 0.00 | 0.11 | |
| 43 | +| dwa_fine | DWA | 30 | 30 | 1.00 | 1.92 | 0.00 | 0.11 | |
| 44 | +| stomp_3_smooth | STOMP | 30 | 18 | 0.60 | 2.84 | 0.00 | 1.50 | |
| 45 | +| diff_mppi_3_early8 | Diff-MPPI | 30 | 23 | 0.77 | 2.88 | 0.56 | 0.72 | |
| 46 | + |
| 47 | +Hard cells only (`dyn_speed_scale >= 1.5`): |
| 48 | + |
| 49 | +| planner | hard cells | solved | mean succ | mean final_d | mean coll | |
| 50 | +|--------------------|-----------:|-------:|----------:|-------------:|----------:| |
| 51 | +| hybrid_astar_pp | 12 | 3 | 0.25 | 1.91 | 15.58 | |
| 52 | +| dwa_med | 12 | 12 | 1.00 | 1.91 | 0.00 | |
| 53 | +| dwa_fine | 12 | 12 | 1.00 | 1.94 | 0.00 | |
| 54 | +| stomp_3_smooth | 12 | 6 | 0.50 | 3.00 | 0.00 | |
| 55 | +| diff_mppi_3_early8 | 12 | 5 | 0.42 | 4.38 | 1.42 | |
| 56 | + |
| 57 | +## Reading the numbers |
| 58 | + |
| 59 | +The Hybrid A* row is the headline: |
| 60 | + |
| 61 | +- `mean final_d = 1.91` -- the planner **does** drive the robot to |
| 62 | + within 2 m of the goal on every cell. The static-obstacle path is |
| 63 | + geometrically fine. |
| 64 | +- `mean coll = 6.23` overall and `15.58` on hard cells -- the robot |
| 65 | + collides with dynamic obstacles ~6 times per episode on average, |
| 66 | + 16 times when the obstacles are at 1.5x+ speed. The path is fixed |
| 67 | + at episode start; dynamic obstacles cross it. |
| 68 | +- `solved = 21/30` (and 3/12 hard) because the benchmark's success |
| 69 | + metric requires both goal reached AND collision-free. The |
| 70 | + collision counter is what differentiates Hybrid A* from the local |
| 71 | + planners here, not goal-reaching. |
| 72 | +- `mean ms = 0.05` -- pure pursuit at runtime is essentially free |
| 73 | + (Hybrid A* search runs once at episode start and is excluded from |
| 74 | + the per-step timing). |
| 75 | + |
| 76 | +For comparison, `dwa_med` and `dwa_fine` solve every cell collision- |
| 77 | +free; they re-evaluate the action grid at every step against the |
| 78 | +current dynamic-obstacle positions, so they sidestep the cross |
| 79 | +that's about to happen. |
| 80 | + |
| 81 | +This is not a fair fight on the dynamic grid -- Hybrid A* is the |
| 82 | +wrong tool. It is included to anchor the lower end of "what a global |
| 83 | +planner without re-planning can do" and to make the local-replanning |
| 84 | +value proposition explicit. |
| 85 | + |
| 86 | +## What would be needed to make Hybrid A* competitive |
| 87 | + |
| 88 | +- Replan from current pose every N steps (would push `mean ms` |
| 89 | + toward the millisecond range). |
| 90 | +- Include dynamic obstacles in the search by inflating predicted |
| 91 | + positions along the planned arc -- the time-aware Hybrid A* in |
| 92 | + the Karaman/Frazzoli line. |
| 93 | +- Hybrid A* + a local replanner (MPC or DWA) inside the planned |
| 94 | + corridor, which is the common production split. |
| 95 | + |
| 96 | +None of these are in scope for this PR. |
0 commit comments