This project converts 3D LiDAR point clouds (.pcd) into 2D occupancy grid maps (.pgm + .yaml) compatible with the ROS navigation stack.
The pipeline performs ground removal, obstacle extraction, grid projection, and map post-processing to generate a clean 2D map suitable for localization and navigation.
PCD → Ground Filtering → 2D Occupancy Grid Projection → Map Image (.pgm) → YAML Metadata → Post-Processing → Clean Navigation Map
Two ground filtering approaches are implemented:
- RANSAC-based ground removal
- Grid-based ground filtering
Both methods convert the filtered obstacle points into a 2D occupancy grid.
This approach removes the ground plane using the RANSAC plane segmentation algorithm.
- Load the
.pcdfile using Open3D. - Remove statistical outliers to reduce LiDAR noise.
- Use RANSAC plane segmentation to detect the dominant plane (floor).
- Remove ground points.
- Project remaining obstacle points onto a 2D XY grid.
- Convert the grid into an occupancy map.
- Apply Gaussian blur and dilation to improve map continuity.
- Save the final map as
.pgmand.yaml.
| Parameter | Value | Purpose |
|---|---|---|
nb_neighbors |
20 | Used in statistical outlier removal |
std_ratio |
2.0 | Removes noisy points |
distance_threshold |
0.02 | RANSAC plane fitting tolerance |
ransac_n |
3 | Number of points sampled per iteration |
num_iterations |
1000 | Improves plane detection robustness |
resolution |
0.05 m | Grid cell resolution |
GaussianBlur kernel |
5×5 | Smooths sparse obstacles |
dilation kernel |
3×3 | Expands obstacle regions |
- Statistical outlier removal reduces random LiDAR noise.
- RANSAC segmentation removes the floor plane effectively.
- Gaussian blur fills small gaps in obstacle clusters.
- Dilation strengthens obstacle boundaries for navigation safety.
Instead of fitting a global plane like RANSAC, this approach estimates ground height locally for each grid cell.
This method works better when the ground surface is uneven or sloped.
- Load the
.pcdfile. - Apply statistical outlier removal.
- Divide the XY space into grid cells.
- Store the minimum Z value per grid cell as the ground estimate.
- Classify points as obstacles if they lie above the ground threshold.
- Convert obstacle points into a 2D occupancy grid.
- Apply smoothing and dilation.
- Save the resulting map.
| Parameter | Value | Purpose |
|---|---|---|
ground_threshold |
0.15 m | Minimum height above ground to classify obstacle |
max_height |
5.0 m | Upper limit for obstacle height |
resolution |
0.05 m | Grid map resolution |
GaussianBlur kernel |
3×3 | Smooth obstacle clusters |
dilation kernel |
5×5 | Strengthens obstacle representation |
- Local ground estimation handles uneven floors better than RANSAC.
- Ground threshold filtering removes floor reflections.
- Height filtering avoids ceiling points or tall noise.
- Larger dilation kernel improves wall connectivity in the final map.
After generating the occupancy grid, small noisy clusters may still exist.
Post-processing performs:
- Binary obstacle mask generation
- Connected component analysis
- Removal of small obstacle clusters
- Reconstruction of a clean occupancy grid
This produces a smoother map suitable for robot navigation.
The final map is saved in the standard ROS map format:
Represents occupancy information:
| Value | Meaning |
|---|---|
| 0 | Occupied |
| 254 | Free |
| 205 | Unknown |
Example:
image: map.pgm
resolution: 0.05
origin: [x, y, 0.0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.196
This YAML file is used by the ROS map_server node.
For evaluation:
-
Screenshots of generated PGM maps were taken directly.
-
Each method was tested with tuned parameters.
-
Maps were compared based on:
- obstacle continuity
- noise reduction
- wall clarity
- navigable space quality
The tuned parameters improved map quality by:
- reducing ground artifacts
- eliminating small noise clusters
- improving obstacle boundary definition
(Insert PGM screenshots here)
ROS Noetic Python3 Open3D NumPy OpenCV
Install dependencies:
pip install open3d opencv-python numpy
rosrun <package_name> ransac_map_generator.py <input_pcd_file>
rosrun pcd_to_map ransac_map_generator.py map_radius_filter.pcd
map_radius_filter.pcd
3D LiDAR point cloud file.
map_name.pgm
map_name.yaml
These files represent the generated occupancy map.
Optionally the map can be launched using ROS:
map_server map_name.yaml
rosrun <package_name> grid_map_generator.py
pcd_files/map_radius_filter.pcd
- Occupancy Grid published to
/map - Saved
.pgmmap - Saved
.yamlmetadata
The map can be visualized in RViz.
Published Topic:
/map
Message Type:
nav_msgs/OccupancyGrid
Frame:
map
This project provides two different approaches for generating 2D occupancy maps from 3D LiDAR data:
| Method | Strength |
|---|---|
| RANSAC | Best for flat environments |
| Grid-Based | Handles uneven ground surfaces |
Both methods generate ROS-compatible navigation maps and allow parameter tuning to improve map quality.
This table compares the output maps generated from the same input PCD using two different approaches:
- GRID Mapping Algorithm
- RANSAC Algorithm
Each result is shown after post-processing (MPP) for both algorithms.




















