Challenge 1
Drive a square that finishes within a hand's width of its start, showing the measured angle after each turn.
EV3 Robotics›Level 1 · Beginner›Lesson 48
Level 1 · Lesson 48 · EV3-L01-4860 minutes · Ages 9–16 · Model: Tank Bot
The Tank Bot: a low, heavy vehicle running on two rubber tracks, with a Gyro Sensor bolted flat to the chassis.
It has no steering. Like every tracked machine, it turns by running one track forward and the other back — dragging itself round sideways. That is called skid steering, and it is why this model needs the Gyro.
By the end of the lesson the Tank Bot will drive the outline of a square, a pentagon or a hexagon — turning to a real angle each time, and coming back to where it started.
An excavator on a building site sits on two steel tracks. To swing the whole machine round it drives one track forward and one back, and the tracks grind sideways across the ground.

Tracks spread the machine’s weight over a huge area, so it does not sink into mud. The price is that it cannot steer like a car — there is nothing to point.
And here is the part that matters today. A skid steer depends entirely on what the ground does back. On wet clay the tracks slide and the machine barely turns. On dry gravel they bite and it spins round fast. The same track movement gives a different angle, and the driver corrects by eye every time.
Big machines that must be precise carry a gyroscope instead of an eye. A phone knows which way you have rotated it, an aeroplane holds a heading in cloud, and a mining excavator digs to a survey line — all from the same kind of chip that is sitting on your chassis.
Count track rotations and your square will be a square on the table you tested on, and a wonky quadrilateral on the mat. Nothing in the program will have changed. The floor will have.
Commanding a turn is not the same as achieving one. Only a sensor knows the difference.
Every turn you have programmed so far has been open-loop: command the motors, and hope. Lesson 30’s Racecar ended by proving that hope is not reliable.
[2 v] reset angle :: sensors start moving [straight: 100] at (25) % speed :: movement wait until <([2 v] angle :: sensors) > (85)> stop moving :: movement
Three things are doing real work in those four blocks.
The Gyro counts total rotation since it was last reset — keep turning right and it goes 90, 180, 270, 360, 450. If you do not reset it, the second turn of a square has to wait for 180, the third for 270, and you have to do sums.
Reset it and every turn is measured from zero. The condition is then the same number in every turn, which is easier to read and much easier to tune.
This is Lesson 35’s idea again. start moving [straight: 100] does not wait, so the very next block can watch the Gyro while the tracks are turning. A move for block would blind the program for the whole turn.
A robot does not stop the instant you tell it to. Between the Gyro reading 85 and the tracks actually standing still, the Tank Bot keeps rotating — a few degrees at 25% speed, a lot more at 75%. That extra is called overshoot.
| You want | Turn speed | Put in the condition |
|---|---|---|
| 90° | 25% | about 85 |
| 90° | 50% | about 78 — and less repeatable |
| 90° | 75% | don’t. The overshoot is bigger than the accuracy you were trying to buy |
Those numbers are a starting point, not an answer. Your robot’s weight, your tracks and your floor all change them, which is why step 10 is a measurement rather than a list.
The robot must be completely still when the angle is reset. A Gyro reset while moving starts out wrong and stays wrong — and worse, drifts, so it gets more wrong the longer the program runs. If your turns are consistently off by a growing amount, this is why.
The Gyro Sensor measures how far the robot has turned, in degrees. Wheels slip and floors vary, so counting wheel rotations is a poor way to turn accurately — the gyro measures the turn itself rather than inferring it.
| Block | What it does |
|---|---|
([2 v] angle :: sensors) | Reports how far the robot has turned since the angle was last reset. |
[2 v] reset angle :: sensors | Sets the current heading as zero. |
The angle is measured from wherever it was last zeroed — not from where this turn started. Here are two robots given the same instruction, one with a reset block and one without.
reset first
no reset
Both programs are correct about what they asked for. Only the left one asked the question from a known starting point.
Both programs did exactly what they said. Both gyros stopped at 90. But the robot on the right had 34 degrees already on the clock, so it only turned 55 — and nothing about the program looks wrong. Watch the first step too: neither robot is moving and the reading is still climbing. That is drift, and it is why the reset belongs immediately before the turn.
Reset with the robot completely still, as late as you can.
when program starts :: events hat [2 v] reset angle :: sensors start moving [straight: 0] :: movement wait until <([2 v] angle :: sensors) > (90)> stop moving :: movement
That program is the obvious one to write, and it will not give you a 90 degree turn. The next section is why.
Asking to stop at 90 does not stop the robot at 90. Between the gyro reaching 90 and the wheels actually standing still there is a delay — the sensor has to be read, the next block has to run, and the motors have to physically brake. The robot is still turning through all of it, so it ends up past where you asked.
The fix is to ask for less than you want. Aim for a 90 degree turn by waiting for 86: the robot coasts the last few degrees on its own and settles at roughly 89 to 91.
ask for exactly 90
stop 4° early
The tolerance has to match the speed. At 50°/s the number that lands this turn on 90° is 86 — let it loop, and watch that number change when the speed does.
The size of that gap is not a fixed property of the robot — it is the delay multiplied by how fast you are turning. The delay stays about the same whatever you do, so a turn at double the speed carries you about double the distance past the mark.
| Turn speed | Carried past the stop | Wait for | Ends up at |
|---|---|---|---|
| slow | about 4° | 86 | about 90° |
| fast | about 10° | 80 | about 90° |
So the tolerance and the speed have to be chosen together. Turn faster and you must give up more; if you speed a turn up and forget to lower the number, the robot starts overshooting every corner and the program that worked last week no longer does.
when program starts :: events hat [2 v] reset angle :: sensors start moving [right: 30] :: movement wait until <([2 v] angle :: sensors) > (86)> stop moving :: movement
Find your own number rather than copying this one — it depends on your robot’s weight, its wheels and the speed you turn at. Run the turn, measure where it actually stops, and move the number by however far it missed. Two or three tries is usually enough.
The other half of the answer is to slow down. A slower turn overshoots less, so it needs less guessing and repeats more reliably — which is why a turn worth getting right is rarely worth rushing.
A gyro slowly loses its zero even when nothing is moving. Leave a robot sitting still for a minute and the angle may have wandered several degrees all by itself. That is drift, and it is a property of the hardware, not a bug in your program.
Two habits deal with it: reset the angle as late as possible before a turn, and keep the robot dead still while the reset happens. Resetting while the robot is rolling bakes the error in permanently.
Aircraft, ships and phones all use gyros to know their orientation — it is how a phone knows you have turned it sideways. A robot that can turn exactly 90 degrees on any surface is far more reliable than one that guesses with wheel rotations.
A driving base has two Large Motors, one per wheel. You could drive them with two separate motor blocks — but they would never start at quite the same instant, and the robot would curve away. EV3 has a separate family of Movement blocks that treat the pair as a single driving base.
| Block | What it does |
|---|---|
set movement motors to [B v] and [C v] :: movement | Tells the Movement blocks which two ports are the driving wheels. Put it at the top of the program, before any movement. |
move [forward v] for (2) [rotations v] :: movement | Drives both wheels together, so the robot travels in a straight line. |
move for (1) [rotations v] at (75) (25) % speed :: movement | Drives the two wheels at different speeds, which makes the robot curve. |
set movement speed to (50) % :: movement | Sets how fast the driving base travels from now on. |
set movement motors to [B] and [C] is the block that decides which two motors every Movement block after it will drive. It does not look at the robot. It drives the two ports you name, whether or not there is a motor in them — so those two letters have to be the two sockets the cables are actually in.
This is the single commonest reason a driving base does nothing, and it is invisible in the program: every block is spelled correctly and the robot still will not go.
the same program on both robots
The yellow outline marks the two ports the block is driving. A robot only goes straight when both of them have a motor in them.
Both robots run the identical program. The left one has its motors in B and C, so both named ports have a motor and the robot drives straight. The right one is plugged into A and B: the block drives B, finds nothing in C, and never mentions the motor in A at all — so one wheel turns, one wheel sits there, and the robot swings round the dead one instead of driving.
If neither named port has a motor in it — cables in A and D, say, with the block still set to B and C — the robot does not move at all. The program runs happily to the end and the Brick reports nothing wrong, because as far as it is concerned it did exactly what it was told.
So before you look for a bug in the program, look at the cables: read the port letters off the Brick, then make the block say those two. B and C are only the usual choice, not a rule — if your build has the driving motors in A and D, set the block to A and D and everything works.
Everything a driving base can do comes from those two speed numbers. Try each button below and watch the trail the robot leaves.
The path is worked out from the two wheel speeds in the block, not drawn by hand — so changing the preset changes the numbers and the shape together.
Notice there is no steering block anywhere in that program, and no steering part anywhere on the robot. The turn is made entirely by driving the two wheels different amounts.
when program starts :: events hat set movement motors to [B v] and [C v] :: movement move [forward v] for (2) [rotations v] :: movement move for (1) [rotations v] at (50) (-50) % speed :: movement
“Move forward 2 rotations” says nothing about the floor — it says how many times the wheels go round. How far the robot actually travels depends on how big the wheels are, and once round a standard EV3 driving wheel is about 17.5 cm.
Before doing any sums, get a feel for it. Drag the robot along and watch both scales at once — rotations on top, centimetres underneath, the same line. Land on the half marks: there is a number between 1 and 2, and it is 1.5.
Drag the robot, or use the arrow keys — it moves in half rotations. Rotations above the line, centimetres below.
1.5 — a half rotation past 1. Half a turn of the wheels is 8.75 cm, so halves matter.
35 ÷ 17.5 = 2. That is a number you can type straight into the block.
set movement motors to [B v] and [C v] :: movement set movement speed to (30) % :: movement move [forward v] for (2) [rotations v] :: movement
Steering at right 100 or left 100 drives the two wheels in opposite directions, so the base stops travelling and pivots where it stands. The angle it sweeps is a simple doubling of the rotations:
Half a rotation is the one worth remembering: a square corner, 90°.
| Rotations | The robot turns |
|---|---|
| 0.25 | 45° — half a corner |
| 0.5 | 90° — a square corner |
| 1 | 180° — turn round and face back |
| 2 | 360° — all the way round |
The one to memorise is 0.5 rotations = 90°. Everything else follows from doubling or halving it.
set movement speed to (20) % :: movement move [right: 100] for (0.5) [rotations v] :: movement
Turn slowly. The wheels on a driving base are big and the robot carries a lot of weight, so at full speed it keeps going after the motors stop and lands past the angle you asked for. Somewhere between 15% and 30% speed is where turns become repeatable. A turn that overshoots is almost always a turn taken too fast, not a wrong number.
These figures belong to your robot. The distance depends on the wheels and the angle depends on how far apart they are, so a wider base needs a different number for 90°. Test it, measure what actually happened, and adjust — the same discipline as the Gyro Sensor tolerance.
Every wheeled vehicle steers this way — a tank, a digger, an office chair with two driven castors. Cars use a steering rack instead, but a robot that turns by driving its wheels at different speeds needs no steering mechanism at all.
Reset, turn, watch, stop early. The number in the condition is your overshoot, measured.
The Gyro Sensor measures how far the robot has turned, in degrees. Wheels slip and floors vary, so counting wheel rotations is a poor way to turn accurately — the gyro measures the turn itself rather than inferring it.
| Block | What it does |
|---|---|
([2 v] angle :: sensors) | Reports how far the robot has turned since the angle was last reset. |
[2 v] reset angle :: sensors | Sets the current heading as zero. |
The angle is measured from wherever it was last zeroed — not from where this turn started. Here are two robots given the same instruction, one with a reset block and one without.
reset first
no reset
Both programs are correct about what they asked for. Only the left one asked the question from a known starting point.
Both programs did exactly what they said. Both gyros stopped at 90. But the robot on the right had 34 degrees already on the clock, so it only turned 55 — and nothing about the program looks wrong. Watch the first step too: neither robot is moving and the reading is still climbing. That is drift, and it is why the reset belongs immediately before the turn.
Reset with the robot completely still, as late as you can.
when program starts :: events hat [2 v] reset angle :: sensors start moving [straight: 0] :: movement wait until <([2 v] angle :: sensors) > (90)> stop moving :: movement
That program is the obvious one to write, and it will not give you a 90 degree turn. The next section is why.
Asking to stop at 90 does not stop the robot at 90. Between the gyro reaching 90 and the wheels actually standing still there is a delay — the sensor has to be read, the next block has to run, and the motors have to physically brake. The robot is still turning through all of it, so it ends up past where you asked.
The fix is to ask for less than you want. Aim for a 90 degree turn by waiting for 86: the robot coasts the last few degrees on its own and settles at roughly 89 to 91.
ask for exactly 90
stop 4° early
The tolerance has to match the speed. At 50°/s the number that lands this turn on 90° is 86 — let it loop, and watch that number change when the speed does.
The size of that gap is not a fixed property of the robot — it is the delay multiplied by how fast you are turning. The delay stays about the same whatever you do, so a turn at double the speed carries you about double the distance past the mark.
| Turn speed | Carried past the stop | Wait for | Ends up at |
|---|---|---|---|
| slow | about 4° | 86 | about 90° |
| fast | about 10° | 80 | about 90° |
So the tolerance and the speed have to be chosen together. Turn faster and you must give up more; if you speed a turn up and forget to lower the number, the robot starts overshooting every corner and the program that worked last week no longer does.
when program starts :: events hat [2 v] reset angle :: sensors start moving [right: 30] :: movement wait until <([2 v] angle :: sensors) > (86)> stop moving :: movement
Find your own number rather than copying this one — it depends on your robot’s weight, its wheels and the speed you turn at. Run the turn, measure where it actually stops, and move the number by however far it missed. Two or three tries is usually enough.
The other half of the answer is to slow down. A slower turn overshoots less, so it needs less guessing and repeats more reliably — which is why a turn worth getting right is rarely worth rushing.
A gyro slowly loses its zero even when nothing is moving. Leave a robot sitting still for a minute and the angle may have wandered several degrees all by itself. That is drift, and it is a property of the hardware, not a bug in your program.
Two habits deal with it: reset the angle as late as possible before a turn, and keep the robot dead still while the reset happens. Resetting while the robot is rolling bakes the error in permanently.
Aircraft, ships and phones all use gyros to know their orientation — it is how a phone knows you have turned it sideways. A robot that can turn exactly 90 degrees on any surface is far more reliable than one that guesses with wheel rotations.
Say this back before moving on: “Ask for 85 if you want 90, and measure why.”
Look at your Tank Bot. Where exactly is the Gyro, and which way up is it? On this model that is not a detail.
| Part | What it is doing here |
|---|---|
| EV3 Intelligent Brick | Sits low and central over the tracks. Its weight is what makes them grip. |
| Large Motor ×2 — the tracks | Large because tracks are hard work: they are dragging rubber sideways across the floor for the whole turn. |
| Gyro Sensor | Measures rotation about one axis only — the one sticking straight up out of its flat face. Mount it flat and level or it will measure a fraction of the turn. |
| The rubber tracks (not electronic) | Grip and scrub. Their tension changes how the robot turns, so a loose track is a slow, unrepeatable turn. |
Sensors go in ports 1, 2, 3, 4. Motors go in ports A, B, C, D. They are not interchangeable, and nothing will tell you politely if you swap them.
| Part | Port | Why this one |
|---|---|---|
| Left track (Large) | B | The pair. Two motors, one job. |
| Right track (Large) | C | The other half. Swapped, every turn goes the wrong way and the Gyro reads negative. |
| Gyro Sensor | 2 | The Gyro’s own home port — the one Lessons 31 and 32 borrowed because their models had no Gyro. This one does. |
Check your own wiring now:
Two routes, and either is fine. USB is the reliable one and the one to fall back on when a room’s Bluetooth is busy; Bluetooth leaves the robot free to move, which some models need.
Do these in order. Naming the Brick after you go looking for it in the list is how groups end up driving each other’s robots.
EV3 until somebody changes it.EV3.The two failures, every class, every time. The Brick has gone to sleep while you were building — press the centre button to wake it. Or you have paired with the group at the next table, which is why the name matters.
The long version, including Port View and how to read the port tiles, is in the Brick & Bluetooth guide.
Bluetooth, and this time it is not optional. A cable pulling on a skid-steering robot changes the very thing you are measuring. It will add a few degrees to every turn and you will chase the error in your program for twenty minutes.
Stuck? The long version, with a photograph of every screen, is in the Brick & Bluetooth guide.
A square: drive a side, turn a real 90°, four times. It should finish where it started, facing the way it began.
when program starts :: events hat set movement motors to [B v] and [C v] :: movement clear display :: display write [SEGI EMPAT] at line (1) :: display repeat (4) move [forward v] for (2) [rotations v] at (40) % speed :: movement wait (0.3) seconds [2 v] reset angle :: sensors start moving [straight: 100] at (25) % speed :: movement wait until <([2 v] angle :: sensors) > (85)> stop moving :: movement write ([2 v] angle) at line (3) :: display end play sound [Communication / Goodbye v] until done :: sound
wait (0.3) seconds before the reset. This is not padding. It lets the robot come to a genuine standstill, so the Gyro is zeroed while still. Delete it and the turns get worse every lap.What success looks like: the Tank Bot drives a square you would recognise as a square. It finishes within a few centimetres of its start and pointing roughly the original way, and the screen has been showing you numbers a little above 85 all along.
If it spins for ever, it is turning the way that makes the angle go negative — the condition asks for greater than 85 and the reading is heading to −85. Swap the steering sign to −100, or use < (−85).
One change at a time. Mark the start with tape and put a line on the floor showing the way the robot faces, so you can see both errors.
> (90) and run one turn. Read line 3 — say it says 96. Your overshoot is 6, so your target is 84. Put that in and run the square.repeat (4) to repeat (6) and the target to 55 (60° minus overshoot). A hexagon. Then a pentagon: 5 turns of 72°.reset angle and run the square. The first turn is right and the rest never happen, because the angle is already past 85.Steps 3 and 4 are the argument for the Gyro, and they are worth doing properly. The rotation-counted turn is not less accurate — on the surface you tuned it for, it is excellent. It is less portable. It encodes an assumption about the floor, and it does not tell you when that assumption stops being true.
A counted turn describes the motors. A Gyro turn describes the robot.
Build the model before you read any further. Everything after this is about making it do something, and none of it will make much sense with nothing on the table in front of you.
Use the viewer's own controls to zoom and turn pages. Fullscreen makes it big enough to build from.
The same build on Google Drive — sometimes a video, sometimes a scan:
Use the viewer's own controls to zoom and turn pages. Fullscreen makes it big enough to build from.
Check the finished build against the picture before you switch anything on. A motor mounted the wrong way round is far easier to spot now than it is to debug later, when it looks like a program fault.

This model drives, so its challenges are run on a mat. Mats differ between branches — check you are looking at the one in your room.

WRO 2026 RoboMission Elementary — Robot Rockstars · official WRO game mat, 2362 × 1143 mm
The challenges name these places rather than distances, so the same challenge works on any mat:
Work through the challenges in order — each is harder than the last. The mission comes after all three, and it is meant to make you plan before you build.
Drive a square that finishes within a hand's width of its start, showing the measured angle after each turn.
Run the same square on a different surface without changing a number. Then do it with a rotation-counted turn instead, and compare the two.
Let the Brick buttons choose between a triangle, a square, a pentagon and a hexagon, each one closing properly.
Drive from the station your teacher names to a second station and back, turning only with the Gyro, and finish facing the way you started. Plan the whole route as a written list of drives and headings before you run it, and get it right in two runs or fewer.