Occupancy Grid Mapping
An occupancy grid discretizes space into cells (2D squares or 3D voxels) and stores, for each cell , the probability that it is occupied by an obstacle. Given known robot poses (from SLAM) and range measurements (LiDAR, sonar, depth camera), occupancy grid mapping fuses many noisy observations of each cell into a stable free/occupied/unknown classification — the map format that path planners actually consume.
The binary Bayes filter per cell
The key modeling assumptions: each cell is a binary, static random variable (occupied or free, not changing over time), and cells are independent of each other. Under these assumptions the posterior over the whole map factorizes into per-cell posteriors, each updated with a binary Bayes filter as measurements arrive.
Working with probabilities directly requires renormalizing every update. The standard trick is the log-odds representation:
Log-odds maps to : means unknown (), positive means likely occupied, negative means likely free. In log-odds form the Bayesian update becomes a simple addition:
where:
- — the cell’s log-odds after incorporating measurement ,
- — the inverse sensor model: the occupancy probability suggested by the current measurement alone,
- — the prior log-odds (zero for an uninformative prior of ).
No renormalization, no products — each observation just adds a constant increment. This is why occupancy mapping is cheap enough to run on embedded robots.
The inverse sensor model and ray casting
For a range sensor, each beam is processed by ray casting the measured ray through the grid (e.g. with Bresenham line traversal):
- Cells along the beam before the hit were seen through, so they receive a miss update: a negative increment (e.g. inverse-model probability around ).
- The cell at the measured range reflected the beam: a positive hit increment (e.g. probability around ).
- Cells beyond the hit are occluded — no information, no update.
Repeated agreeing observations accumulate, so a cell touched by twenty misses and one spurious hit still reads clearly free; a moving person leaves a temporary streak that later misses erase. Implementations typically clamp log-odds to a min/max range so cells stay updatable (this bounded-confidence clamping is what OctoMap does), and threshold (e.g. at ) to classify cells for planning.
2D grids, octrees, and voxels
A flat 2D grid is the classic representation for indoor mobile robots (ROS nav_msgs/OccupancyGrid). In 3D, dense grids cost memory, so practical systems use hierarchical or sparse structures: OctoMap stores probabilistic occupancy in an octree that subdivides only where geometry exists and can prune uniform regions, while hash-based voxel maps trade the hierarchy for O(1) access. The per-cell log-odds math is identical in all of them.
Why it matters for SLAM
SLAM gives you a trajectory and a landmark/point map — but a sparse point cloud cannot answer “is this space safe to drive through?”, because it says nothing about free space. Occupancy grids explicitly represent free, occupied, and unknown volumes, which is what collision checking, frontier-based exploration, and path planning need. In practice the SLAM system supplies poses, and an occupancy mapper turns the posed scans into the costmap the navigation stack runs on; the log-odds filter also provides natural robustness to dynamic objects and sensor noise that raw geometric maps lack.