Click & WhirrAll lessons

Motion · Lesson 01

Differential drive

This is the written walk-through of the lesson: the idea, stage by stage, plus the deeper asides. The interactive version, where you write real Python in the browser and drive a simulated robot, lives on the lesson page.

A two-wheeled robot steers by spinning each wheel at a different speed. Match the speeds and it rolls dead straight; speed up one wheel and it arcs toward the slower side; spin the wheels in opposite directions and it pirouettes in place. Feel it with the sliders, then make it code: your drive function gets the clock and the goal bearing, and owns the wheels.

How two wheels steer

Your robot has two wheels and no idea how to use them. Over this lesson you teach it to roll, spin, and park, the three moves every later lesson stands on.

There is no steering wheel here, just the two wheels. Match their speeds and the robot rolls dead straight. Speed up one wheel and it arcs toward the slower side. Spin the wheels in opposite directions and it pirouettes on the spot. Every path the robot ever drives is some mix of those.

The two sliders below the sim are a sandbox: drag them and feel the mapping before you write a line. They drive the robot until your code compiles, and then your code owns the wheels. Checkpoints only count for the code. Your drive function gets the clock and the bearing to the goal, and returns a (left, right) speed each tick.

Go deeper: how two wheels are enough

A car needs a steering rack because its wheels only ever point the same way. This robot does not: each wheel spins on its own, so the two speeds already carry both things you want. Their average is how fast the body goes forward, and their difference is how fast it turns. Feed in any forward speed and any turn rate, and there is exactly one pair of wheel speeds that produces it.

left wheel: fasterright wheel: slowerforward + turn

That is the whole trick, and it is why every phase in this lesson is just a choice of those two numbers. Straight is all average, no difference. A spin is all difference, no average. Parking on the goal is a steady average with a difference that leans on the bearing. Every controller you write after this, all the way to the capstone, is still just picking a forward speed and a turn.

Make it roll

First move: roll dead straight. The starter already lays out three time windows for you (the first three seconds, the next three, then the rest of the run) and each one returns (0, 0), so the robot just sits there. Fill in the first window.

Equal speed on both wheels means no turn, only forward. Return one matched (left, right) tuple in the t < 3.0 window, press Run, and watch it roll straight off the mark.

Make it spin

Next move: spin on the spot. If matched speeds cancel out to a straight line, equal and opposite speeds cancel the other way: no forward motion at all, just rotation. One wheel drives ahead while the other drives back, and the robot pivots around its own center.

Fill in the t < 6.0 window with an equal-and-opposite pair and Run. Your bot should roll straight for three seconds, then stop and turn in place.

Head for the goal

Last move: actually go somewhere. The green pad is the goal, and goal_bearing is the angle to it (positive when the goal is off to your left, zero when it is dead ahead). Steering is just a turn laid on top of a forward roll: bias the two wheels by an amount that grows with the bearing, so the robot leans harder the more it is pointed away.

Wire up the last window, then tinker. Push the turn bias up and the bot whips around and overshoots the pad. Ease it down and it drifts in lazy. Find the amount that curves it in and parks it on the green. That park finishes the lesson.

Ready to build it? The interactive lesson is where you write the code and watch the robot run.