Challenge 1
Drive at a line straight on and stop when the sensor sees it. Note how far off square the robot ends up.
EV3 Robotics›Level 4 · WRO Prep›Lesson 6
Level 4 · Lesson 6 · EV3-L04-0660 minutes · Block 1 of 6 · Mat: WRO 2021 — POWERBOTS, Energy at Home
Give the robot a way to straighten itself out against a line, so mistakes stop piling up.
Every leg you drive is slightly off. A degree of turn error here, a millimetre of wheel slip there. On leg one it does not matter. By leg four the robot is 5 cm and 10 degrees away from where the program thinks it is, and the mission fails for no visible reason.
Squaring fixes that. Drive at a line, let both wheels find it independently, and the robot ends up perpendicular to it — whatever angle it arrived at. Its heading error is now zero, no matter what it was a second ago.
Any line crossing your path at roughly a right angle is a squaring opportunity. On the 2021 mat the useful ones are:
Plan squaring into the route, not into the panic. A squaring move costs about a second. A failed approach costs the mission.
Picture the robot arriving at a line at a slight angle. One side gets there first.
If both wheels stop together, the robot stays crooked. But if each wheel stops the moment its own sensor sees the line, the early wheel waits while the late wheel keeps driving — and the robot pivots until both are on the line. It is now square, and nothing had to know what angle it started at.
This is why the movement blocks will not do. start moving drives B and C as one unit and stops them together — exactly what we do not want. Squaring needs [B v] start motor and [C v] stop motor so the two wheels can be told apart.
The clean version needs two Colour Sensors, one on each side at the front. If your robot has only the one from lesson 2, use the fallback in the program section — it squares by approaching the line twice, and it is slower but it works.
The Colour Sensor looks down at a surface and can answer three quite different questions: what colour is this?, how bright is this? and how light is the room? Choosing the wrong one is the usual reason a line-following robot refuses to work.
| Block | What it does |
|---|---|
([3 v] color :: sensors) | Reports which colour it sees, from a short list — red, blue, green, black, white and a few more. |
([3 v] reflected light intensity :: sensors) | Reports how bright the surface is, as a number from 0 (black) to 100 (white). |
<[3 v] is color [red v]? :: sensors> | Reports true or false for one particular colour. |
([3 v] ambient light intensity :: sensors) | Reports how much light is falling on the sensor, 0 to 100, with its own lamp switched off. |
The sensor does not describe a colour — it picks one from a list of eight, and that list is the whole of what it can ever say:
| Reports | Means |
|---|---|
| 0 | no colour — too far away, or too dark to call |
| 1 · 2 · 3 | black, blue, green |
| 4 · 5 · 6 | yellow, red, white |
| 7 | brown |
Anything you put under it is forced into one of those eight. There is no orange and no purple: an orange brick comes back as red or as yellow, and often as red one moment and yellow the next as the robot creeps along. Light blue and grey are the other classic pair to avoid — grey is neither black nor white, so it flips between them.
This is why colour mode is a good fit for a task you control and a bad fit for one you do not. Sorting the LEGO bricks that come in the set works, because they are made in exactly these colours. Reading a printed sheet, a coloured tile from another set, or anything pastel is asking the sensor to answer a question it does not have a word for.
Two practical points follow from how it decides. It shines its own lamp and looks at how much red, green and blue comes back, so it must be close — about half a centimetre, and no more than a centimetre. Lift it and the answer decays to 0. And because it takes those three readings before it can answer, colour mode is the slowest thing this sensor does; a robot driving quickly can pass right over a small patch without ever reporting it.
When a colour must be recognised reliably, test it. Drive the robot slowly over the real surface with color shown on the screen and watch what it actually says — including what it says at the edges between two colours, which is where the wrong answers live.
Both questions are asked of the same surface at the same moment. Watch the two answers travel across a strip of colours and then over the edge of a black line.
Watch the two read-outs over the last third of the strip. One of them changes once. The other changes the whole way across.
Over the patches, both read-outs are useful. Over the edge of the line they part company: the colour name has only two answers to give and jumps between them, while the number slides smoothly from 88 down to 8. Every value in that slide tells you how far onto the line the sensor is — which is information the name simply does not carry.
A line follower built on colour names only knows “black” or “not black”, so it can only lurch. Built on reflected light it can tell how far onto the line it has drifted, which is what makes smooth following possible.
The first two modes both switch the sensor’s own lamp on and measure what bounces back off the surface. Ambient light intensity does the opposite: the lamp goes off, and the sensor simply reports how much light is arriving from wherever — 0 in the dark, up to 100 in bright light.
| Mode | Own lamp | Measures | Points |
|---|---|---|---|
| colour | on | which of eight colours the surface is | at the surface, very close |
| reflected light | on | how much of its own light comes back | at the surface, very close |
| ambient light | off | how bright the surroundings are | wherever you want to measure |
That makes it the only one of the three that is not really about the floor. A number between 0 and 100 means very little on its own, so watch the same sensor sit through five different rooms — nothing underneath it changes at any point.
the sensor’s own lamp is off — it is measuring the room
Nothing under the sensor changed at any point in this run. Ambient light is the one mode that is not asking about the surface at all.
Those are the shape of the scale rather than exact figures, but the shape is the useful part: a lit room is nowhere near 100, and the top of the range is reserved for a light pointed straight at the sensor. Cover it with your hand and the number drops to near zero — which is the easiest way to check the sensor is doing what you think.
Point it at the ceiling and it tells you whether the room lights are on; point it forwards and a torch will spike the reading, which is a way of signalling to a robot without touching it.
Do not reach for it as a substitute for reflected light. Room light falling on a black line and on white paper is almost the same, so ambient mode can barely tell them apart — the reason reflected light works is precisely that the sensor brings its own light and measures how much of it survives.
It is also the mode most at the mercy of the room. A reading taken by a window in the morning will not match the same spot in the afternoon, so anything built on ambient light needs measuring on the day, in the place, with the lights as they will be.
Even the two lamp-on modes are affected by room lighting — a reading taken by a sunny window differs from one taken in a corner. The sensor must also sit close to the surface and at a constant height, because lifting it changes the reading even though the surface has not changed.
Everything an EV3 does begins with a motor turning. Before worrying about how far or how fast, there are only two things to say to a motor: start and stop. The blocks are the same whichever motor you use — only the port letter changes.
| Block | What it does |
|---|---|
[A v] start motor [clockwise v] :: motors | Starts the motor and immediately carries on to the next block. The motor keeps turning on its own. |
[A v] stop motor :: motors | Stops the motor. |
wait (2) seconds | Holds the program here, which is how you control how long a motor runs. |
Because start motor does not wait, a motor started on its own would run until the program ended. The pattern that gives a motor a length is three blocks:
when program starts :: events hat [A v] start motor [clockwise v] :: motors wait (2) seconds [A v] stop motor :: motors
Read it aloud: start it, leave it two seconds, stop it. Change the wait and you change how far the motor gets.
The highlight below follows the block the Brick is running, and the shaft turns only while the program is between start motor and stop motor. Notice that the count keeps climbing all the way through the wait — the wait does not pause the motor, it pauses the program.
0.00rotations so farnoshaft turning
The count does not pause when the program does. A wait holds up the blocks, and the motor carries on turning underneath it.
This is the whole idea behind start motor: it hands the motor its instruction and moves on, leaving the motor running behind it. Nothing stops the shaft until a block tells it to.
The direction dropdown says clockwise or counterclockwise — but clockwise seen from where? Always from the axle end: look straight at the shaft coming towards you, and clockwise is the way a clock’s hands go.
Here the Medium Motor faces you, so its output axle points straight out of the page. This is the view to picture when you are choosing a direction.
when program starts :: events hat [A v] start motor [clockwise v] :: motors wait (2) seconds [A v] stop motor :: motors
A Medium Motor normally lives in port A or D.
The Large Motor is shown from the side, which is the face its axle comes out of — so once again you are looking straight down the shaft.
when program starts :: events hat [B v] start motor [clockwise v] :: motors wait (2) seconds [B v] stop motor :: motors
A Large Motor normally lives in port B or C. Compare the two programs: they are the same three blocks, and only A has become B.
A fan, a conveyor belt or a spinning ride does not need to stop at an exact position — it just needs to run while something is happening. For those, timing the motor is simpler and perfectly good enough.
A program does not have to be one long column of blocks. Several stacks can run at the same time, each doing its own job — one driving, one watching a sensor, one keeping the display up to date.
Give each stack its own hat block. Every stack beginning with when program starts starts at the same instant — not one after another — and from then on they run alongside each other.
Nor is it limited to two. Below, three stacks run together: a Medium Motor turning an attachment, the status light flashing, and the drive base rolling. Watch the arrows at the top — they all begin at once, and no stack waits for any other.
when program starts :: events hat [A v] start motor [clockwise v] :: motors when program starts :: events hat forever set status light to [green v] :: display wait (0.5) seconds set status light to [red v] :: display wait (0.5) seconds end when program starts :: events hat start moving [straight: 0] :: movement
Written down they have to go one under another, because a page is a column — but that is an accident of paper. On the Brick they sit side by side, and nothing in the first stack happens before anything in the third.
Parallel stacks go wrong when two of them try to control the same thing. Use the switch below to take the wheels away from the third stack and point it at motor A, which the first stack is already driving.
the program starts — all of these begin here
stack 1 · Medium Motor
stack 2 · status light
stack 3 · drive base
Every stack is highlighted at the same moment on purpose — that is what running in parallel looks like. The switch above changes only what the third stack controls.
With one owner each, all three stacks are highlighted at the same instant and all three jobs get done. With two owners, motor A is handed contradictory orders hundreds of times a second and shivers instead of turning — and notice the second cost, which is easy to miss: the wheels now have nobody driving them. A stack that goes to fight over someone else’s motor has abandoned its own job. Nothing reports an error either way; as far as the Brick is concerned every stack is working perfectly. The same happens to a display line or a variable that two stacks both write to.
The discipline is simple: give each stack sole ownership of what it controls. One stack owns the motors, another owns the screen, another watches the sensors and tells the others what it found — which is what broadcasting is for.
If your set has a second Colour Sensor, mount it now. This is the attachment-mount decision from lesson 2 paying off.
Both sensors must be calibrated the same. If port 1 reads white as 90 and port 3 reads it as 100, the robot will square to a crooked line and be confident about it.
when program starts :: events hat [B v] start motor [clockwise v] :: motors [C v] start motor [clockwise v] :: motors [1 v] wait until color is [black v] :: sensors [B v] stop motor :: motors [3 v] wait until color is [black v] :: sensors [C v] stop motor :: motors play beep (72) for (0.2) seconds :: sound
Read the middle four blocks carefully. They only work because wait until blocks the program while the motors keep running — the motor blocks start a motor and move on, they do not wait for it.
when program starts :: events hat set movement motors to [B v] and [C v] :: movement start moving [straight: 0] at (20) % speed :: movement [3 v] wait until color is [black v] :: sensors stop moving :: movement move [backward v] for (0.2) [rotations v] at (20) % speed :: movement turn [right v] for (0.15) [rotations v] at (15) % speed :: movement start moving [straight: 0] at (15) % speed :: movement [3 v] wait until color is [black v] :: sensors stop moving :: movement
Squaring once gets most of the error out. Squaring twice gets nearly all of it, and it is almost free.
The second pass usually halves whatever was left, because the robot starts the second approach much closer to perpendicular. Then try the approach speed: slower squares better, because a fast wheel overshoots past the line before the motor actually stops.
Do not square at speed. 15–20% is right. This is the one move in the level where being slow makes it work.
The experiment that shows squaring is worth its second:
Run 1 arrives about 15 degrees off, because nothing removed the error. Run 2 should arrive within a couple of degrees however badly it started. That is the whole point: squaring does not reduce the error, it deletes it.
Adapted from Squaring or Aligning on a Line by Sanjay and Arvind Seshan (ev3lessons.com), in docs/EV3 Lesson Planning/EV3lessons - reference (other creators)/Level 3/. Their deck also turns the routine into a My Block — we do that in lesson 13, once My Blocks have been taught.
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 2021 RoboMission Elementary — POWERBOTS — Energy at Home · official WRO game mat, 2362 × 1143 mm
The challenges name these places rather than distances, so the same challenge works on any mat:
Switch mats above and every route below is redrawn on the mat you chose.
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 at a line straight on and stop when the sensor sees it. Note how far off square the robot ends up.
Program each drive motor separately so each stops when its own sensor reaches the line. Watch the robot straighten itself.
Repeat the squaring move twice in a row and measure whether the second pass improves the alignment.
Square on a line, then drive to the kitchen at E and square again. Prove the second squaring cancelled the error from the first leg — show your angle measurements before and after.
