A modular Python-based 2D robot simulation featuring a front-facing camera and frontier-based autonomous exploration. The robot can autonomously navigate through a maze-like environment using frontier detection and A* pathfinding.
- Frontier-Based Exploration: Autonomous navigation using frontier detection algorithm
- A Pathfinding*: Intelligent path planning to unexplored regions
- Line-of-Sight Path Smoothing: Automatically prunes unnecessary waypoints for fluid motion
- Front-Facing Camera: 60° field of view with 200-pixel range and ray-casting
- Real-Time Mapping: Tracks and visualizes explored areas with frontier boundaries
- Dual Mode Operation: Switch between autonomous and manual control
- Modular Architecture: Clean separation of concerns for easy extension
- Visual Feedback: Camera FOV, frontiers, planned paths, and exploration percentage
- Live Metrics & Logging: UI timer plus downloadable exploration graph and CSV history
Robot_Exploration/
├── main.py # Main simulation entry point
├── robot.py # Robot class with movement and sensing
├── environment.py # Environment and obstacle management
├── exploration.py # Shared exploration interfaces/utilities
├── basic_frontier.py # Default nearest-frontier strategy
├── greedy_frontier.py # Alternative greedy frontier explorer
├── renderer.py # All visualization and drawing
├── config.py # Configuration constants
├── requirements.txt # Python dependencies
└── README.md
Install the required dependencies:
pip install -r requirements.txtpython main.py| Key | Action |
|---|---|
SPACE |
Toggle Auto/Manual mode |
W or ↑ |
Move forward (manual) |
S or ↓ |
Move backward (manual) |
A or ← |
Rotate left (manual) |
D or → |
Rotate right (manual) |
V |
Toggle camera view rays |
F |
Toggle frontier visualization |
P |
Toggle path visualization |
R |
Reset simulation |
G |
Save exploration graph snapshot |
ESC |
Quit |
- Frontier Detection: Identifies boundary cells between explored and unexplored areas
- Target Selection: Chooses the closest frontier cluster
- Path Planning: Uses A* algorithm to find optimal path to target
- Navigation: Robot follows the path while continuously updating the map
- Blue circle with white direction indicator
- Front-facing camera with yellow FOV outline
- Collision detection with 9-point checking
- Smooth movement and rotation
- 30 rays cast within 60° FOV
- Ray-casting detects obstacles and boundaries
- Explored areas are marked in light gray
- Real-time visibility calculation
- Maze-like layout with walls and obstacles
- Grid-based representation (5x5 pixel cells)
- Obstacle detection and boundary enforcement
- Dynamic exploration tracking
- Robot movement and rotation
- Collision detection
- Camera ray generation
- Target-based navigation
- Obstacle management
- Grid-based space representation
- Ray-casting for visibility
- Exploration tracking
- Defines
ExplorationStrategy,ExplorationMap, and helper utilities - Provides reusable
detect_frontier_cellslogic for custom explorers
- Default strategy that prioritizes nearest frontier cells
- Tracks failed targets, clusters, and exposes multiple candidate waypoints
- Minimalist explorer that always picks the single closest frontier
- Useful for benchmarking or as a template for custom modules
- Explored area visualization
- Frontier cell rendering
- Path display
- UI overlay and information
- All configuration constants
- Color definitions
- Tunable parameters
You can modify parameters in config.py:
# Camera settings
CAMERA_FOV = 60 # Camera field of view (degrees)
CAMERA_RANGE = 200 # Camera range (pixels)
NUM_CAMERA_RAYS = 30 # Number of rays for detection
# Robot settings
ROBOT_SPEED = 3 # Movement speed
ROTATION_SPEED = 3 # Rotation speed (degrees/frame)
ROBOT_SIZE = 20 # Robot radius
# Grid settings
GRID_CELL_SIZE = 5 # Pixels per grid cell
# Exploration strategy
EXPLORER_CLASS = "basic_frontier.BasicFrontierExplorer" # Swap in custom explorers
# Logging and history
LOG_DIR = "logs"
HISTORY_SAMPLE_INTERVAL = 0.5
GRAPH_EXPORT_KEY = "G"Set EXPLORER_CLASS to any <module>.<ClassName> available in the project (e.g., greedy_frontier.GreedyFrontierExplorer or your own x_explorer.MyExplorer). The simulator dynamically imports the class, so adding new exploration behaviors is as simple as dropping in a new file and updating the config.
- Create a new file such as
my_strategy_explorer.py. - Implement a class that inherits from
exploration.ExplorationStrategy. - Use
self._require_map()to access the latest exploration snapshot and produce targets (similar tobasic_frontierorgreedy_frontier). - Update
EXPLORER_CLASSinconfig.pyto point to your class. - Run
python main.pyto try it out.
The modular structure makes it easy to test different exploration algorithms:
- Create a new explorer module: Subclass
ExplorationStrategyand drop it into the workspace - Point
EXPLORER_CLASSat it: Update the config string to"my_module.MyExplorer" - Adjust navigation: Try different heuristics or algorithms (A*, Dijkstra, RRT, etc.) inside
navigation.py - Tune parameters: Adjust camera range, FOV, or grid size in
config.py
The simulator now samples exploration percentage over time and stores it in /logs as CSV after each run (auto and manual). The sidebar displays:
- Timer showing elapsed session time
- Mini graph of exploration percentage vs. time
Press the configured GRAPH_EXPORT_KEY (default G) at any time to save a high-resolution PNG of the graph into the logs directory. Each run also creates a timestamped CSV (exploration_log_YYYYMMDD_HHMMSS.csv) containing time_seconds and explored_percent, making it easy to analyze or plot externally.
The simulation tracks:
- Exploration percentage: Amount of navigable space explored
- Frontier count: Number of boundary cells detected
- Path efficiency: Visual path from robot to target
- Python 3.7+
- pygame 2.5.0+
- numpy 1.24.0+