Finding and counting intersections
The robot notices an intersection, stops at it and does not count the same intersection twice.
Lesson result
The robot travels along the line with the P-controller and stops at the required intersection. Each intersection is counted once.
You will learn
- Describe what the sensors at the intersection show.
- Write down the intersection condition and explain the choice of threshold.
- Explain why one intersection can be counted many times, and correct it.
- Stop the robot at the intersection with the given number.
Need to know
- 3.2 P-controller: smooth and fast
Will need
Why this lesson
In the fields of the final task, branches from intersections lead to the loads. To turn into the right place, the robot must notice intersections and know which one is in front of it. Today the robot will learn to find, count and pass intersections.
- What is the error of the P-controller when the line is exactly in the middle?
- What does the sensor show on the 0-100 scale on black?
- What does
constrain?
What sensors see at an intersection
12 minWhat should a robot do. The courier must notice the intersection, drive to it and, if necessary, stop. A separate intersection sensor is not needed: we use both line sensors and their readings together.
What we use and how it works. On a regular narrow path, the sensors are located along its edges. On a wide transverse stripe, both can see black at the same time. The program checks this combination and decides whether to continue moving. As long as the sensors remain over one lane, multiple readings refer to one intersection rather than multiple ones.
How to link a dimension to an action. First, let's check the signs on a stationary robot, then entering and exiting the lane. To count, you need to separate the detection of an intersection from driving beyond its border. Otherwise, the fast loop will count the same strip over and over again. Another wide dark area can also give such a signal: the sensors do not know the geography of the field.
The robot approaches an intersection. What will both gauges show on the 0-100 scale when it is on the cross line?
- Upload sketch
L32_Errorfrom lesson 3.2. - Slowly move the robot with your hands along the training track through the intersection. Look at the Serial Monitor.
- Write down the readings in the journal: on the line in the middle, at the intersection, after the intersection.
At the intersection, both sensors show almost 0: there is a black transverse line under them.
The robot approaches an intersection. What will both gauges show on the 0-100 scale when it is on the cross line? And at the bend of the line?
- Upload the sketch with the scale from lesson 3.2 (
L32_Erroror your own template). - Slowly move the robot with your hands along the path through the bend and through the intersection. Look at the Serial Monitor.
- Fill out the table and answer: by what criteria can an intersection be distinguished from a bend?
| Position | leftLevel | rightLevel |
|---|---|---|
| Line in the middle | ||
| On the bend | ||
| At the crossroads | ||
| After the intersection |
The table is completed, the sign of the intersection is written down in words.
How many readings does the robot manage to get while driving along the transverse line?
- Add a repeat counter to your program from lesson 3.2
loop()and once a second print how many repetitions have passed. Record the number of repetitions per second at operating speed. - Take your speed in mm/s from lesson 2.1 or measure it again.
- Calculate: how many repetitions will there be on a transverse line 19 mm wide?
- Move the robot by hand through the intersection and compare the readings with your position table.
Hint: How to count
Line time is the line width divided by the speed. Repetitions are the time multiplied by the number of repetitions per second.
The log contains repetitions per second, speed, calculation of the number of repetitions on the line and readings at the intersection.
Intersection condition
10 minLet's write the rule: intersection - when both sensors see black. “Black” - the reading is less than the threshold of 30.
bool onCrossing() {
return leftLevel < 30 && rightLevel < 30;
}
&& is read as “and”: the condition is true only if both parts are true.
Hint: Why 30 and not 0
Even on black, the reading is rarely exactly 0, and when moving the robot sees the edge of the line. A threshold of 30 reliably separates the “black” from the “edge”, but it can be adjusted according to your measurements.
You can explain why the condition does not work at a bend in the line, but does work at an intersection.
Formulate the rule yourself using your notes from the previous step: what indications occur only at an intersection and never on a straight line or a bend?
- Write the rule in words in a journal: what should the left sensor have and what should the right sensor have.
- Select the “black” threshold according to your measurements. Explain why not 0 and why not 50.
- Write the condition in Arduino language. You will need the "and" sign:
&&.
Someone wrote a condition via || (“or”). Where will the robot then stop by mistake?
Hint: How to write “and”
a < 30 && b < 30 is true only if both parts are true.
In the journal - a rule in words, a threshold with an explanation, a condition and an answer about ||.
Requirement 1. Function onCrossing() replies true on the transverse line and false in all other robot positions.
Check the condition on paper before writing the code. For each position, write down the readings of the left and right sensors on a scale of 0–100 and the response of the function:
| Position | leftLevel | rightLevel | onCrossing() |
|---|---|---|---|
| Line in the middle | |||
| Line under one sensor on a steep arc of 125 mm | |||
| The line went behind both sensors | |||
| Transverse line |
- Choose a threshold based on your measurements and justify it: what is the margin to the darkest reading outside the intersection?
- Find the position where your condition might be wrong. What will the robot do then?
Hint: Where to look for the error
Move the robot with your hands in a 125mm arc from Lesson 3.2: How dark does the “edge” of the line under the sensor become?
The table is filled in according to measurements, the threshold is justified by the margin, the dangerous situation and its consequences are recorded.
Stop at the intersection
20 min- Create a sketch
L41_Crossing_Stop. Transfer measurementskpandbaseSpeedfrom the logbook.
const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5;const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH; // Измерения и настройки из журнала (уроки 3.1 и 3.2).const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0;float kp = 0.5;int baseSpeed = 100; int leftLevel = 100;int rightLevel = 100; int level(int value, int white, int black) { long result = (long)(value - black) * 100 / (white - black); return constrain(result, 0, 100);} void readSensors() { leftLevel = level(analogRead(LEFT_SENSOR_PIN), LEFT_WHITE, LEFT_BLACK); rightLevel = level(analogRead(RIGHT_SENSOR_PIN), RIGHT_WHITE, RIGHT_BLACK);} void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void stopMotors() { analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0);} void followLineStep() { int error = leftLevel - rightLevel; int correction = kp * error; drive(FORWARD, constrain(baseSpeed + correction, 0, 255), FORWARD, constrain(baseSpeed - correction, 0, 255));} void setupRobot() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); stopMotors(); // Без измерений робот не поедет. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { } } delay(2000);} // Перекрёсток: оба датчика видят чёрное.bool onCrossing() { return leftLevel < 30 && rightLevel < 30;} // Ехать по линии, пока не найдём перекрёсток.void followLineToCrossing() { while (true) { readSensors(); if (onCrossing()) { return; } followLineStep(); }} void setup() { setupRobot(); followLineToCrossing(); stopMotors();} void loop() {}
- Find the function
followLineToCrossing(). Explain to your partner how the program comes out of it. - Place the robot on the line in front of the intersection and start it.
The robot drives along the line and stops at the first intersection.
How it works: How followLineToCrossing works
while (true) - always repeat. Inside: read sensors; if the intersection is return, that is, exit the function; otherwise take the P-controller step. After exit, the program continues from the line stopMotors(); in setup().
| What do you see | What to do |
|---|---|
| A robot passes an intersection | Lower baseSpeed or raise the threshold to 40 |
| Robot stops at a bend | Threshold is too high, try 20 |
| The robot does not move | Are the measurements recorded from the log? |
- Create a sketch
L41_Crossing_Stopaccording to the template. Transfer measurementskpandbaseSpeedfrom the logbook. The line functions from Lesson 3.2 are already ready. - Write it yourself
onCrossing()according to its rule from the previous step,followLineToCrossing()and movement insetup(). ByeonCrossing()is not written, she always answers “crossroads”, and the robot does not move.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5;const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH; // Измерения и настройки из журнала (уроки 3.1 и 3.2).const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0;float kp = 0.5;int baseSpeed = 100;int leftLevel = 100;int rightLevel = 100; // ===== Твоя часть: напиши сам ===== bool onCrossing() { // true — только когда робот на поперечной линии; на прямой и на изгибе — false. return true;} void followLineToCrossing() { // Ехать по линии с П-регулятором, пока не найдёшь перекрёсток; на перекрёстке функция заканчивается.} void setup() { setupRobot(); // Доехать по линии до первого перекрёстка и остановиться.} // ===== Готовое из уроков 3.1–3.2 — не меняй ===== int level(int value, int white, int black) { long result = (long)(value - black) * 100 / (white - black); return constrain(result, 0, 100);} void readSensors() { leftLevel = level(analogRead(LEFT_SENSOR_PIN), LEFT_WHITE, LEFT_BLACK); rightLevel = level(analogRead(RIGHT_SENSOR_PIN), RIGHT_WHITE, RIGHT_BLACK);} void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void stopMotors() { analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0);} void followLineStep() { int error = leftLevel - rightLevel; int correction = kp * error; drive(FORWARD, constrain(baseSpeed + correction, 0, 255), FORWARD, constrain(baseSpeed - correction, 0, 255));} void setupRobot() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); stopMotors(); // Без измерений робот не поедет. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { } } delay(2000);} void loop() {}
What will the robot do if, after searching for an intersection, you forget to stop the motors?
- Place the robot on the line in front of the intersection and start it.
Hint: Drive while...
The function repeats the same thing - read the sensors, take a step along the line - and ends when an intersection is found. What loop repeats "always", and how do you exit the function in the middle of it?
Hint: How to exit a function
return inside a function ends it immediately. The program continues from the next line in setup().
The robot drives along the line and stops at the first intersection. The forecast is recorded.
| What do you see | What to do |
|---|---|
| A robot passes an intersection | Lower baseSpeed or raise the threshold |
| Robot stops at a bend | Threshold too high |
| The robot does not move | Are the measurements included? Is it written? onCrossing()? |
Requirement 2. Continue with your program L32_P_Line from lesson 3.2 and save as L41_Crossing_Stop:
- the step of the P-controller is moved to the function
followLineStep(), reading sensors - inreadSensors(); The P-controller works as before; - function
followLineToCrossing()leads the robot along the line and ends as soon asonCrossing()returnedtrue; - in
setup()the robot reaches the first intersection and stops; - protection without measurements and a pause at the start remain.
Acceptance. The robot stops at an intersection five times out of five and never at an arc of its level.
Hint: Idea (1 of 3)
The “drives until...” function is an infinite loop, from which there is a conditional exit.
Hint: Plan (2 of 3)
- Always repeat: read sensors.
- Crossroads - exit the function.
- Otherwise, the P-controller step.
Hint: Code snippet (3 of 3)
while (true) { readSensors(); if (onCrossing()) { return; } … }
The program fulfills requirements 1–2, five out of five stops are recorded in the log.
Find the counting error
8 minThe neighbors wanted to count intersections like this:
void loop() {
readSensors();
if (onCrossing()) {
count = count + 1;
}
followLineStep();
}
The robot drove through one intersection, and count became 40. Why?
You can explain: while the robot is driving along a wide black stripe, the condition is true many times in a row, and each time the counter grows.
The neighbors noticed the double count and added a pause after the count:
void loop() {
readSensors();
if (onCrossing()) {
count = count + 1;
delay(100);
}
followLineStep();
}
The robot drove through one intersection, and count became 3. Why didn't the pause help? How else is it dangerous for driving along the line?
- Write your answer in your journal.
- Suggest a correction in words: What should the program do after finding an intersection before looking for the next one?
You can explain why pausing doesn't help and suggest a fix.
The neighbors decided to count only the moment when the intersection appeared:
bool was = false;
void loop() {
readSensors();
bool now = onCrossing();
if (now && !was) {
count = count + 1;
}
followLineStep();
}
The robot drove through one intersection, and count still became 40. Where is the error?
- Find the error and log the corrected code.
- Compare 40 with your calculation of the number of repetitions on the line from the last step. It seems?
- Is the score at the moment of appearance worse or better than passing the intersection, which will be in the next step?
Hint: What was stored
When the value changes in this program was?
The error was found, the correction was written in code, the number 40 was explained by calculation, a comparison of the two methods was written down.
Pass the intersection
10 minTo count an intersection once, you need to pass: drive straight until the sensors go black.
void passCrossing() {
drive(FORWARD, baseSpeed, FORWARD, baseSpeed);
do {
readSensors();
} while (onCrossing());
delay(100);
}
do { … } while (условие) - do and repeat until the condition is true. A short pause at the end moves the sensors away from the edge of the transverse line.
Can you explain when the cycle ends in passCrossing().
To count an intersection once, you need to pass: drive straight until the sensors go black. Write a function passCrossing() in the log:
- Turn both motors forward at speed
baseSpeed. - Read the sensors, bye robot at a crossroads.
- After that, wait 100 ms.
do { … } while (условие); - do and repeat until the condition is true.
Hint: Why do and not while
Sensors must be read at least once before checking a condition.
Hint: Why the pause at the end
Immediately after black, the sensors see the edge of the transverse line. What happens if at this moment you look for the intersection again?
The function is logged. Can you explain when the cycle ends and why there is a pause.
Requirement 3. Function passCrossing() drives straight through the intersection and ends when the sensors are no longer on the cross line or at its edge.
- Write a function in your program.
- Explore the pause after leaving black: 0, 50, 100, 200 ms. For each, launch the robot through two intersections in a row (in
setup()—followLineToCrossing(),passCrossing(),followLineToCrossing(), stop) and mark at which intersection he stopped. - Write down what kind of pause is needed and what it depends on. What happens if you lift
baseSpeed?
| Pause, ms | Where did you stay? | What is visible |
|---|---|---|
| 0 | ||
| 50 | ||
| 100 | ||
| 200 |
Hint: Idea (1 of 2)
Drive straight and repeat reading the sensors until the intersection condition is true.
Hint: Code snippet (2 of 2)
do { readSensors(); } while (onCrossing()); - why here do, not while?
passCrossing() is working, the pause table is filled, the conclusion about the relationship between pause and speed is recorded.
Stop at the desired intersection
17 min- Create a sketch
L41_Count. BTARGETindicate which intersection to stop at.
const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5;const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH; // Измерения и настройки из журнала (уроки 3.1 и 3.2).const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0;float kp = 0.5;int baseSpeed = 100; int leftLevel = 100;int rightLevel = 100; int level(int value, int white, int black) { long result = (long)(value - black) * 100 / (white - black); return constrain(result, 0, 100);} void readSensors() { leftLevel = level(analogRead(LEFT_SENSOR_PIN), LEFT_WHITE, LEFT_BLACK); rightLevel = level(analogRead(RIGHT_SENSOR_PIN), RIGHT_WHITE, RIGHT_BLACK);} void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void stopMotors() { analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0);} void followLineStep() { int error = leftLevel - rightLevel; int correction = kp * error; drive(FORWARD, constrain(baseSpeed + correction, 0, 255), FORWARD, constrain(baseSpeed - correction, 0, 255));} void setupRobot() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); stopMotors(); // Без измерений робот не поедет. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { } } delay(2000);} // Перекрёсток: оба датчика видят чёрное.bool onCrossing() { return leftLevel < 30 && rightLevel < 30;} // Ехать по линии, пока не найдём перекрёсток.void followLineToCrossing() { while (true) { readSensors(); if (onCrossing()) { return; } followLineStep(); }} // Проехать перекрёсток прямо, пока датчики не съедут с чёрного.void passCrossing() { drive(FORWARD, baseSpeed, FORWARD, baseSpeed); do { readSensors(); } while (onCrossing()); delay(100);} const int TARGET = 1; // на каком перекрёстке остановиться void setup() { setupRobot(); for (int i = 1; i < TARGET; i++) { followLineToCrossing(); passCrossing(); } followLineToCrossing(); stopMotors();} void loop() {}
TARGET = 2. How many times will the loop be executed? for? What will the robot do at the first intersection?
- Check on a path with three intersections:
TARGET= 1, 2, 3.
The robot stops exactly at the intersection with the number TARGET.
- Create a sketch
L41_Countaccording to the template. BTARGETindicate which intersection to stop at. - Write it yourself
passCrossing()- according to its entry in the journal - and movement insetup(). Until your part is written, the robot does not move.
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. const int LEFT_SENSOR_PIN = A4;const int RIGHT_SENSOR_PIN = A5;const int LEFT_DIR_PIN = 7;const int LEFT_SPEED_PIN = 6;const int RIGHT_DIR_PIN = 4;const int RIGHT_SPEED_PIN = 5;const int FORWARD = HIGH;const int BACKWARD = (FORWARD == HIGH) ? LOW : HIGH; // Измерения и настройки из журнала (уроки 3.1 и 3.2).const int LEFT_WHITE = 0;const int LEFT_BLACK = 0;const int RIGHT_WHITE = 0;const int RIGHT_BLACK = 0;float kp = 0.5;int baseSpeed = 100;int leftLevel = 100;int rightLevel = 100;const int TARGET = 1; // на каком перекрёстке остановиться // ===== Твоя часть: напиши сам ===== void passCrossing() { // Проехать перекрёсток прямо. Функция заканчивается, когда датчики уже не на поперечной линии и не на её краю.} void setup() { setupRobot(); // Перекрёстки до TARGET — найти и проехать прямо; на перекрёстке номер TARGET остановиться.} // ===== Готовое из уроков 3.2 и 4.1 — не меняй ===== int level(int value, int white, int black) { long result = (long)(value - black) * 100 / (white - black); return constrain(result, 0, 100);} void readSensors() { leftLevel = level(analogRead(LEFT_SENSOR_PIN), LEFT_WHITE, LEFT_BLACK); rightLevel = level(analogRead(RIGHT_SENSOR_PIN), RIGHT_WHITE, RIGHT_BLACK);} void drive(int leftDir, int leftSpeed, int rightDir, int rightSpeed) { digitalWrite(LEFT_DIR_PIN, leftDir); digitalWrite(RIGHT_DIR_PIN, rightDir); analogWrite(LEFT_SPEED_PIN, leftSpeed); analogWrite(RIGHT_SPEED_PIN, rightSpeed);} void stopMotors() { analogWrite(LEFT_SPEED_PIN, 0); analogWrite(RIGHT_SPEED_PIN, 0);} void followLineStep() { int error = leftLevel - rightLevel; int correction = kp * error; drive(FORWARD, constrain(baseSpeed + correction, 0, 255), FORWARD, constrain(baseSpeed - correction, 0, 255));} void setupRobot() { pinMode(LEFT_DIR_PIN, OUTPUT); pinMode(LEFT_SPEED_PIN, OUTPUT); pinMode(RIGHT_DIR_PIN, OUTPUT); pinMode(RIGHT_SPEED_PIN, OUTPUT); stopMotors(); // Без измерений робот не поедет. if (LEFT_WHITE == LEFT_BLACK || RIGHT_WHITE == RIGHT_BLACK) { while (true) { } } delay(2000);} // Перекрёсток: оба датчика видят чёрное.bool onCrossing() { return leftLevel < 30 && rightLevel < 30;} // Ехать по линии, пока не найдём перекрёсток.void followLineToCrossing() { while (true) { readSensors(); if (onCrossing()) { return; } followLineStep(); }} void loop() {}
TARGET = 3. How many times must the robot drive straight through the intersection?
- Check on a path with three intersections:
TARGET= 1, 2, 3.
Hint: Repeat as many times as necessary
Loop for from Lesson 1.1 repeats commands a specified number of times. How many intersections do you need to go through before stopping at?
The robot stops exactly at the intersection with the number TARGET.
Requirement 4. Function goToCrossing(n) leads the robot along the line, passes straight through intersections to n-th and stops at n-m. Save the program as L41_Count.
Acceptance. A path with three intersections, n = 1, 2, 3, three runs each.
n | Launch 1 | Run 2 | Launch 3 |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 |
What should the function do when n = 0? Decide for yourself, write it down and check that the program does exactly that.
Hint: Plan (1 of 2)
n - 1 times: find an intersection and drive through it. Then find the last one and stop.
Hint: Code snippet (2 of 2)
for (int i = 1; i < n; i++) { … } - how many times the loop will be executed when n = 1?
Nine runs without an error in the table, behavior when n = 0 selected and verified.
Quests by level
10 minDrive along the line to the first intersection and stop at it.
Stop at the third intersection, after going straight through the first two. In the middle field of the final task, the robot passes through intersections without turning.
Make the robot pass all intersections without stopping and not lose the line after them. Hint: in loop() - if there is an intersection, passCrossing(), otherwise the P-controller step.
Test yourself
Select answers to prepare. They are not stored or evaluated on the site. Take the knowledge test in the course syllabus or discuss the answers with your instructor.
● Basic
★ Intermediate level
★★ Advanced level
Answer questions at your level. Correct answers needed: Beginner - 4 out of 5; Average - 4 out of 5; Advanced - 4 out of 5. Answers will be checked by the teacher or course program.
Summary
The robot finds intersections and counts them without repetitions. The next step is to turn in the right direction at the intersection and follow the route.
How to confirm the result
For each experiment, save the conditions, program version, observation and conclusion. When comparing attempts, change one reason at a time; unsuccessful attempts also remain in the log. Marking a result refers to actions that have already been completed; there is no need to repeat them for the sake of marking. If the result is not obtained, write down the discrepancy and the next hypothesis to be tested. A model, measurements of a real robot, and an explanation are different types of evidence.
Lesson vocabulary
| intersection | The place where a line is crossed by another line. Both sensors see black at the same time. |
| threshold | Number for comparison: a reading less than 30 on a scale of 0–100 is considered black. |
| while loop | Repeats commands as long as the condition is true. |
| return | Immediately terminates the function and returns the program to where the function was called. |