For ENAE450: Robotics Programming at the University of Maryland, my team designed and implemented autonomous maze navigation on a TurtleBot4. The competition had two parts: navigating a known, pre-mapped maze using a saved SLAM map with Nav2, and autonomously exploring and escaping an unknown maze in real time using frontier-based exploration. Both approaches combined SLAM, the Nav2 stack, and custom ROS2 controller nodes.
The TurtleBot4 is built on an iRobot Create3 base with a Raspberry Pi 4 running ROS2 Humble. Its sensor suite includes a 2D LiDAR scanner, IMU, and wheel encoders. The LiDAR was the primary sensor for both obstacle detection and map generation. All ROS2 communication between the development laptop and the robot was handled over WiFi.
For the known environment, the approach was straightforward:
map_server_cli
The SLAM node, Nav2 stack, and RViz2 were all launched with a single launch file (full_pt1.launch.py).
For the novel environment, we developed a frontier-based exploration algorithm that autonomously navigated the robot through an unmapped maze:
OccupancyGrid where open cells are 0, walls are 100, and undiscovered areas are -1/odom is translated to a grid coordinatefind_nearest_frontier() — BFS from the robot's position to the nearest discovered cell bordering an unknown areacompute_open_space_score() — BFS-based flood fill counting reachable open cells within a radius; low score = corridor, high score = open area (maze exit)world_to_grid() / grid_to_world() — Coordinate transforms between world frame and OccupancyGrid indicestimer_callback() — Main loop: initial 360-degree spin for SLAM initialization, then frontier-navigate-score loop until maze exit detected