Skip to main content

Lesson 9 · Capstone Project

Module 5 · Dijkstra's Algorithm

Lesson 9 · Capstone Project

90+ minFull integrationYour graduation project
👩‍🏫

Teacher mode is on. Toggle it off (bottom-right) to preview the student view.

This is it — every piece you've built, assembled into one autonomous system. The robot visits several destinations, plans with Dijkstra, senses obstacles with the rangefinder, reroutes on the fly, and remembers what it learned in a file so the next run is smarter. You won't write much new code; the challenge is integration — making working parts work together. That's exactly what real software engineers do.

Learning Objectives

By the end of this project you will be able to:

  • Integrate Dijkstra, the Navigator, rangefinder detection, and file memory into one program
  • Visit four or more destinations while detecting and avoiding obstacles
  • Save and load obstacles so knowledge persists between runs
  • Demonstrate learning: Run 2 outperforms Run 1, with numbers to prove it
  • Debug integration issues where individually-working parts don't cooperate

The mission

Your robot is an autonomous delivery vehicle. It must visit four or more grid destinations in sequence, and for each leg: plan a path, drive it while watching for obstacles, and reroute whenever the rangefinder finds one. Everything you need already exists — Dijkstra (Lessons 4–5), the swap into Navigator (Lesson 6), detection (Lesson 7), and file memory (Lesson 8). Today you connect them.

You'll demonstrate with two runs: Run 1 (delete the obstacle file, discover obstacles the hard way, save them) and Run 2 (load the file, plan around known obstacles, reroute less). The drop in step count between runs is the learning.

Knowledge Check

What is the main challenge of the capstone?

Program structure

The whole program has a clear skeleton:

1. Load obstacles from file
2. Define destinations
3. For each destination:
While not arrived:
Compute a path with Dijkstra (from current position, current blocked list)
Walk the path, checking the rangefinder at each intersection
If obstacle: add to blocked list, recompute
If clear all the way: arrived
4. Save obstacles to file
5. Print results (steps, reroutes)

The blocked list is the thread tying it together: load_obstacles produces it, Dijkstra consumes it, detection appends to it, and save_obstacles writes it out.

Knowledge Check

What single data structure connects loading, pathfinding, detection, and saving?

The navigation loop

The core is a nested loop — destinations on the outside, rerouting in the middle, walking a single path on the inside:

for dest in destinations:
arrived = False
while not arrived:
pathfinder = Dijkstra(current, blocked)
path = pathfinder.compute_path(dest)
if len(path) == 0:
print("No path to", dest); break

rerouted = False
for i in range(len(path) - 1):
distance = rangefinder.distance() # or simulate
if distance < THRESHOLD:
blocked.append(path[i + 1]) # obstacle ahead
reroute_count += 1
rerouted = True
break
current = path[i + 1] # drive one intersection
step_count += 1

if not rerouted:
arrived = True

When an obstacle appears mid-path, you break out, having added it to blocked — and the while loop computes a fresh path from where you now stand.

Knowledge Check

When an obstacle is found partway along a path, why break out of the inner for loop?

Activity · Test in simulation, then drive

Get the whole thing working with a simulated rangefinder before the robot — verify paths compute, obstacles register, the blocked list grows, and obstacles.txt is written correctly. Then swap in the real sensor and the DifferentialDrive.

ACTUAL_OBSTACLES = [(1, 0), (2, 2), (1, 3)]
def simulate_rangefinder(next_pos):
return 8.0 if next_pos in ACTUAL_OBSTACLES else 50.0

Watch for the classic integration bugs: the blocked list getting reset between destinations (it must persist across all of them), current not updating after a move, or forgetting to make a new Dijkstra after the blocked list changes.

Knowledge Check

Which is a classic capstone integration bug to watch for?

The rubric and demo

You're graded on the integrated system, component by component:

CategoryPointsWhat it takes
Dijkstra pathfinding10Correct, shortest paths from the class
Navigator integration10Robot physically drives the computed paths
Obstacle detection10Rangefinder detects and updates the blocked list
Path recomputation10Reroutes correctly around discovered obstacles
Experience (file I/O)10Obstacles saved after Run 1, loaded for Run 2
Demonstration5Run 1 discovers & reroutes; Run 2 avoids known obstacles
Code quality5Readable, uses functions/classes, meaningful comments

For the demo, run twice and have your numbers ready: "Run 1 took X steps with Y reroutes; Run 2 took A steps with B reroutes." Finished early? Try an extension — live mid-segment detection, visiting the nearest destination next, obstacle expiration (re-check old obstacles after a few runs), or a text-grid map of the route.

Knowledge Check

In the demo, what evidence shows the robot 'learned'?

Real-world connections

You've built, in miniature, what real autonomous systems do:

Robotics

SLAM

Real robots build and reuse maps of their environment — the grown-up version of your obstacle memory.

Vehicles

Self-driving

Sense, plan, act, and learn from fleet data — the same loop at massive scale.

Engineering

System integration

Connecting tested components into a reliable whole is the core of professional software work.

Wrap-up

  • What connects all the components? (The blocked list flowing file → Dijkstra → detection → file.)
  • Why test in simulation before the robot? (Separate logic bugs from hardware bugs.)
  • What proves the robot learned? (Run 2's measured improvement over Run 1.)

Course wrap-up

Resources