← BlogAMR Navigation Basics· 10/12

VFH+ Reactive Avoidance — Finding a Gap with a Polar Histogram, No Costmap Required

Vector Field Histogram reduces a dense occupancy grid to a polar density histogram and picks the most open steering direction. VFH+ adds robot-width compensation via angular enlargement — useful as a lightweight fallback when Nav2 is not running or dynamic obstacles dominate.

~5 min
Nav2VFHreactiveobstacle-avoidanceAMR

VFH+ Reactive Avoidance

The Nav2 planner → controller pipeline is powerful but heavyweight, and it depends on a global map. Sometimes all that is needed is a fast, lightweight reaction to the obstacle directly in front of the robot — when Nav2 is not running, or when the environment is filled with dynamic obstacles. That is where VFH+ (Vector Field Histogram) fits.

Three Stages of Data Reduction

The core insight of VFH is to progressively simplify a complex environment until only one question remains: which direction to steer.

Rendering diagram…
  1. Occupancy Grid — the obstacle grid around the robot (same concept as the occupancy grid covered earlier).
  2. Polar Histogram — the grid is converted into a bar chart around the robot's heading. Each angular sector shows how densely packed obstacles are in that direction.
  3. Steering Valley — the algorithm finds the sector with the lowest bar (least dense = most open) and picks the valley closest to the goal direction.

Visualized as a polar histogram:

Direction:  ←   ↖   ↑   ↗   →
Density:   ███  █   ·   ··  ████
                ↑
           valley here (open) → steer this way

In code, the data reduction is just picking the emptiest valley in a histogram.

# grid -> per-direction obstacle density (polar histogram) -> emptiest valley
def steer_vfh(grid, goal_dir, threshold):
    hist = [density(grid, s) for s in range(0, 360, 30)]   # 12 directions (30 deg)
    valleys = [s for s, d in enumerate(hist) if d < threshold]
    return min(valleys, key=lambda s: abs(s*30 - goal_dir))  # valley nearest the goal

Why the "+" — Robot Width Compensation

The original VFH treated the robot as a point. VFH+ compensates for the robot's physical width. As an obstacle gets closer, the angular sector it blocks is widened accordingly.

💡 Angular enlargement formula — the blocked angle is expanded by enlargement_angle = arcsin((r_robot + r_safety) / d_obstacle). This is the same concept as inflation bloating obstacles in costmap space, applied here in the angular domain. Closer obstacles (smaller d) block a wider arc, providing a larger safety margin.

⚠️ Sector resolution limits — with only 12 sectors (30° each), a narrow passage can be misread as "blocked." Increasing angular resolution or relying on VFH+'s compensation is key to threading tight corridors.

Where It Fits — Fallback Driving

VFH+ runs without a global planner, making it well-suited as a fallback driver when the full Nav2 stack is not active. A practical combination: a patrol controller provides the high-level waypoints while VFH+ handles instant obstacle avoidance. This gives you a choice between "heavy global planning" and "light reactive avoidance" depending on the situation.

▶ Simulation footage — a run through a warehouse aisle with Nav2 switched off and VFH+ alone doing the driving. A forklift and pallet jacks are parked on alternating sides, and the robot threads between them. The speed readout falling from 1.06 to 0.16 m/s and climbing back is the whole of the avoidance: pick a direction, slow down as things get closer. This run's VFH+ uses 72 sectors (5 degrees each) — six times finer than the 12-sector example above — and widens each blocked angle using a 0.49 m robot radius plus a 0.49 m safety margin. Result: zero collisions, 0.82 m minimum clearance, 33.5 m completed. Nav2 never came up.

In a nutshell

📌 VFH+ reduces data via occupancy grid → angular polar histogram → lowest-density steering valley to directly select a heading. It compensates for robot width through angular enlargement and is well-suited to fallback driving when Nav2 is unavailable.

See standard test results with videos and verdict evidence on the imSim Portal.

View public results →