Robot courier Lesson 5.2 All coursesFor teachersStudy in the app Student Arduino Uno + L298P motor shield
Topic 5 · Lesson 5.2

Gripper: pick up and place

The robot drives up to the load, grabs it, takes it away and places it in the right place.

2 × 45 min1–2 students per robotPractice

Lesson result

The robot approaches the load via ultrasound, picks it up, turns around, carries it along the line and places it at the other end. Actions are formalized by the functions pickUp() and putDown().

You will learn

  • Explain how a servo rotates through a given angle.
  • Find your gripper’s open and closed angles experimentally.
  • Follow the order: stop - close; open - wait - drive away.
  • Collect shipping from the functions of previous lessons.

Need to know

  • 5.1 Ultrasound: we see the load
  • 4.2 Turns at the intersection and route

Will need

Servo gripperUltrasonic distance sensorLine sensor (analog, Trema) × 2

Why this lesson

The robot can reach the cargo. The last skill left for the courier is to take the cargo, deliver it and carefully deliver it. Today the robot will put everything together: line, ultrasound and gripper.

Warm up · remember
  1. Which stopping condition in front of the load is correct and why?
  2. How does a robot turn around on a line?
  3. What does followLineFor(1500)?
Security

Keep your fingers out of the gripper while power is on. The servo may move suddenly when a program is uploaded.

1
Lesson 1 · 45 min
Servo and gripper
1

How a servo works

8 min

What should a robot do. The courier must take the cargo, hold it during transportation and release it at the right place. To do this, we will add a mechanical gripper with a servo drive. Ultrasound helps to drive up, but does not capture anything.

What we use and how it works. Inside a servo there is a motor, gearbox, position sensor and control circuitry. Based on control impulses, it receives the given position of the shaft and tries to hold it. The Servo library generates these pulses; gripper.write specifies the position, not the rotation speed. The lever turns the rotation of the shaft into the movement of the gripping jaws.

How to link a dimension to an action. We select the “open” and “closed” angles for our mechanics with small changes; other people's numbers can push the mechanism into a limiter. First we stop the wheels, then close the gripper and give it time. The closing command does not prove that the load is being held: this is verified by observation. We check the connection and power supply with the confirmed diagram of the kit.

A regular motor spins while it is turned on. Servo rotates at a given angle and holds it. Inside it has a motor, gears and a position sensor. We command the angle in degrees: gripper.write(90).

Predict

What will the servo do after gripper.write(90), and then gripper.write(40)?

It should work

Can you explain how a servo is different from a wheel motor?

A regular motor spins while it is turned on. Servo rotates at a given angle and holds it. We command the angle in degrees: gripper.write(90).

Predict

What will the servo do after gripper.write(90), and then gripper.write(40)? And the wheel motor after analogWrite(…, 90)?

  1. Write in the journal: how a command to the servo drive differs from a command to the wheel motor - what sets the number and when the movement ends.
It should work

Comparison of servo and wheel motor recorded.

Servo rotates to a given angle and holds it: inside there is a motor, gears and a position sensor.

  1. Look at the servo contact on the card on the robot and write it in the angle sample sketch.
  2. Do the experiment: gripper.write(40), pause, gripper.write(90), pause. Try pauses of 100, 300 and 600 ms. At what pause does the gripper have time to reach the angle?
  3. Write down approximately how long it takes for the servo to move 50° and why the program should wait after the command.
It should work

In the log - an experiment with pauses and the smallest pause at which the gripper reaches the angle.

2

Find the “open” and “closed” angles

22 min

Each gripper has its own angles. Let's find them by experience, like the turning time in lesson 2.2.

  1. Look at the servo contact on the robot's card and enter it instead -1.
Angle sampleL52_Servo_Test.ino.ino
#include <Servo.h> // Контакт сервопривода захвата: впиши номер из таблицы проводки своего робота.const int SERVO_PIN = -1; int angle = 90; // меняй понемногу, чтобы найти «открыто» и «закрыто» Servo gripper; void setup() {  if (SERVO_PIN < 0) {    while (true) {    }  }  gripper.attach(SERVO_PIN);  gripper.write(angle);} void loop() {}
  1. Start with angle = 90. Upload. Change the angle by 10°: find a position where the gripper is open so that the load enters freely.
  2. Find an angle where the gripper holds the load firmly, but does not press with all your might.
  3. Write both angles in a journal.
Hint: Servo is humming or shaking

The gripper has hit the load or its own stop and cannot reach the corner. Step back 5–10° from this position: the servo drive should not work point-blank.

It should work

The log records the “open” and “closed” angles at which the load enters freely and is held securely.

Each gripper has its own angles. Find them through experience - choose the method yourself, but only change angle and write down each attempt.

CommandWhat does
gripper.attach(контакт);Links a servo to a pin
gripper.write(угол);Rotates by an angle of 0...180 and holds it
  1. Create a sketch L52_Servo_Test according to the template. Look at the servo contact on the robot's card and enter it instead -1.
  2. Add it setup() himself: the gripper must turn to angle.
Template: angle sampleL52_Servo_Test_Gaps.ino.ino
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. #include <Servo.h> // Контакт сервопривода захвата: впиши номер из таблицы проводки своего робота.const int SERVO_PIN = -1;int angle = 90; // меняй понемногу, чтобы найти «открыто» и «закрыто» Servo gripper; // ===== Твоя часть: напиши сам ===== void setup() {  if (SERVO_PIN < 0) {    while (true) {    }  }   // Захват поворачивается на угол angle и держит его.} void loop() {}
  1. Find the “open” angle: the load enters the gripper freely.
  2. Find the "closed" angle: the load is held tightly and the servo does not buzz.
  3. Check “closed”: lift the robot with the load and tilt it slightly. Doesn't the load fall out?
AttemptangleWhat is visibleWhat to change and why
190
2
3
4
Hint: Servo is humming or shaking

The gripper is stuck and cannot reach the corner. What should you do with the corner?

It should work

In the logbook - attempts with explanations, angles “open” and “closed” and tilt testing.

Look at the servo contact on the card on the robot.

Requirement 1. Sketch L52_Servo_Test for selecting angles: the angle is entered as a number into the Serial Monitor, and the gripper is rotated immediately, without loading the program again.

  • Only numbers from 0 to 180 are accepted; to another number the program responds that this is not possible, and the gripper does not move.
  • After each rotation, the program prints what the angle is now.
  • Without a pin number, the program does not touch the servo.
How it works: Command help
CommandWhat does
#include <Servo.h>, Servo gripper;Connect the library and create a servo drive
gripper.attach(pin)Link servo to pin
gripper.write(angle)Rotate by angle 0…180
Serial.available()How many characters came from the Serial Monitor
Serial.parseInt()Read an integer from incoming characters

Requirement 2. The “open” and “closed” angles were found with a margin and checked:

  • “open” - the load enters the gripper, even if the robot has stopped 1 cm to the left or right of the middle;
  • “closed” — find the angle at which the gripper contacts the load, then back off the angle until the servo stops buzzing; record how many degrees you backed off;
  • the load does not fall out when the robot with the load is tilted 30° forward and backward.

Requirement 3. Function moveGripper(target) turns the gripper to the angle smoothly - in 2° steps - rather than in one jerk. Compare how the load behaves during sharp and smooth closing.

Hint: Idea (1 of 2)

Remember the current angle in the variable. While it is not equal to the target, move it one step towards the target and take a short pause.

Hint: Code snippet (2 of 2)

currentAngle += (target > currentAngle) ? 2 : -2; - what happens if the target differs by an odd number of degrees?

Hint: Nothing happens in the Serial Monitor

Check that the speed is 9600 and that the monitor sends the line via Enter.

It should work

The angle selection sketch fulfills requirement 1. In the log - angles, margin of “closed” in degrees, tilt check and comparison of sharp and smooth closing. moveGripper works.

3

The order of actions is important

15 min

Match functions pickUp() and putDown() in the final order rule sketch (next lesson):

  • Take: first stop, then close the gripper.
  • Put: open the grab, wait until it opens, and only then drive away.
Find the mistake · The cargo leaves with the robot

At the neighbors putDown() is like this: gripper.write(OPEN_ANGLE); and immediately drive(BACKWARD, …). The cargo falls in and out along with the robot. Why? How to fix it?

It should work

Can you explain why there is a pause after opening the gripper.

  1. Before looking at the code, write down in a log step by step: how to work the robot correctly take cargo and how put. What must happen first: stopping or gripping? Opening the gripper or driving away?
  2. Compare your order with the rule:
  • Take: first stop, then close the gripper.
  • Put: open the grab, wait until it opens, and only then drive away.
Find the mistake · The cargo leaves with the robot

At the neighbors putDown() is like this: gripper.write(OPEN_ANGLE); and immediately drive(BACKWARD, …). The cargo falls in and out along with the robot. Why? How to fix it?

It should work

Your order is written down and checked against the rule, the neighbors' mistake is explained.

Find the mistake · The cargo leaves with the robot

At the neighbors putDown() is like this: gripper.write(OPEN_ANGLE); and immediately drive(BACKWARD, …). The cargo falls in and out along with the robot. Why?

  1. Write down the order rules for “take” and “put.”
  2. Find with experience the smallest pause after opening, during which the load remains in place: 100, 200, 400, 600 ms, three times each.
  3. What kind of break will you take into the program and why not the shortest of the successful ones?
It should work

The rules are written down, the experience table and the selected pause with justification.

2
Lesson 2 · 45 min
Shipping
4

Take and put

20 min
  1. Create a sketch L52_Pick_Place. Transfer measurements kp, baseSpeed, sensor and servo contacts, their angles.
Take and putL52_Pick_Place.ino.ino
#include <Servo.h> 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);} // Контакты ультразвукового датчика: впиши номера из таблицы проводки своего робота.const int TRIG_PIN = -1;const int ECHO_PIN = -1; // Расстояние в сантиметрах или -1, если эхо не вернулось.int readDistanceCm() {  digitalWrite(TRIG_PIN, LOW);  delayMicroseconds(2);  digitalWrite(TRIG_PIN, HIGH);  delayMicroseconds(10);  digitalWrite(TRIG_PIN, LOW);  unsigned long echoUs = pulseIn(ECHO_PIN, HIGH, 25000);  if (echoUs == 0) {    return -1;  }  return echoUs / 58;} void setupSonar() {  // Без контактов датчика программа дальше не пойдёт.  if (TRIG_PIN < 0 || ECHO_PIN < 0) {    while (true) {    }  }  pinMode(TRIG_PIN, OUTPUT);  pinMode(ECHO_PIN, INPUT);} int turnSpeed = 100;int centerMs = 250; // подбираем: проехать от датчиков до центра перекрёсткаint leaveMs = 200;  // время, чтобы датчик ушёл со старой линии // Выехать на центр перекрёстка: датчики стоят впереди колёс.void toCenter() {  drive(FORWARD, baseSpeed, FORWARD, baseSpeed);  delay(centerMs);  stopMotors();} // Крутиться на месте, пока датчик со стороны поворота не найдёт новую линию.void turnUntilLine(bool left) {  if (left) {    drive(BACKWARD, turnSpeed, FORWARD, turnSpeed);  } else {    drive(FORWARD, turnSpeed, BACKWARD, turnSpeed);  }  delay(leaveMs);  do {    readSensors();  } while ((left ? leftLevel : rightLevel) > 30);  stopMotors();} void turnLeftAtCrossing() {  toCenter();  turnUntilLine(true);} void turnRightAtCrossing() {  toCenter();  turnUntilLine(false);} // Развернуться на линии: крутиться, пока линия снова не окажется под датчиком.void turnAroundOnLine() {  turnUntilLine(true);} // Ехать по линии заданное время.void followLineFor(unsigned long ms) {  unsigned long start = millis();  while (millis() - start < ms) {    readSensors();    followLineStep();  }  stopMotors();} // Сервопривод захвата: впиши контакт и свои углы из журнала.const int SERVO_PIN = -1;const int OPEN_ANGLE = 90;const int CLOSED_ANGLE = 40;const int STOP_CM = 5;Servo gripper; void setupGripper() {  // Без контакта сервопривода программа дальше не пойдёт.  if (SERVO_PIN < 0) {    while (true) {    }  }  gripper.attach(SERVO_PIN);  gripper.write(OPEN_ANGLE);  delay(500);} // Ехать по линии и остановиться перед грузом по ультразвуку.void approachCan() {  while (true) {    int distance = readDistanceCm();    if (distance > 0 && distance <= STOP_CM) {      break;    }    readSensors();    followLineStep();  }  stopMotors();} // Сначала остановиться, потом закрыть захват.void pickUp() {  stopMotors();  gripper.write(CLOSED_ANGLE);  delay(600);} // Открыть захват, подождать и только потом отъехать назад.void putDown() {  stopMotors();  gripper.write(OPEN_ANGLE);  delay(600);  drive(BACKWARD, baseSpeed, BACKWARD, baseSpeed);  delay(300);  stopMotors();} const unsigned long CARRY_MS = 1500; // сколько ехать по линии с грузом void setup() {  setupSonar();  setupGripper();  setupRobot();   approachCan();  pickUp();  turnAroundOnLine();  followLineFor(CARRY_MS);  putDown();} void loop() {}
  1. Place the load at the end of the line, the robot at the other end. Launch it.
Predict

Read setup() and tell me step by step what the robot will do.

It should work

The robot drives up, takes the load, turns around, carries it along the line and places it.

  1. Create a sketch L52_Pick_Place according to the template. Transfer measurements kp, baseSpeed, ​​sensor and servo contacts, their angles. Driving along the line, intersections and access to the cargo are already ready.
  2. Write the gripper setup yourself setupGripper(), pickUp(), putDown() and delivery to setup() - according to its order rules from the previous step.
Template: take and putL52_Pick_Place_Gaps.ino.ino
// Шаблон среднего уровня. Напиши код в разделе «Твоя часть» по целям в комментариях. #include <Servo.h>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 TRIG_PIN = -1;const int ECHO_PIN = -1;int turnSpeed = 100;int centerMs = 250; // подбираем: проехать от датчиков до центра перекрёсткаint leaveMs = 200;  // время, чтобы датчик ушёл со старой линии // Сервопривод захвата: впиши контакт и свои углы из журнала.const int SERVO_PIN = -1;const int OPEN_ANGLE = 90;const int CLOSED_ANGLE = 40;const int STOP_CM = 5; Servo gripper;const unsigned long CARRY_MS = 1500; // сколько ехать по линии с грузом // ===== Твоя часть: напиши сам ===== void setupGripper() {  // Без контакта сервопривода программа дальше не идёт.  // Захват подключён и открыт; дай ему время раскрыться.} void pickUp() {  // Взять груз: груз оказывается в захвате и не выталкивается.} void putDown() {  // Поставить груз: груз остаётся на месте, когда робот отъезжает назад на 300 мс; в конце колёса стоят.} void setup() {  setupSonar();  setupGripper();  setupRobot();   // Доставка: подъехать к грузу, взять, развернуться на линии, проехать с грузом CARRY_MS, поставить.} // ===== Готовое из уроков 3.2–5.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);} // Расстояние в сантиметрах или -1, если эхо не вернулось.int readDistanceCm() {  digitalWrite(TRIG_PIN, LOW);  delayMicroseconds(2);  digitalWrite(TRIG_PIN, HIGH);  delayMicroseconds(10);  digitalWrite(TRIG_PIN, LOW);  unsigned long echoUs = pulseIn(ECHO_PIN, HIGH, 25000);  if (echoUs == 0) {    return -1;  }  return echoUs / 58;} void setupSonar() {  // Без контактов датчика программа дальше не пойдёт.  if (TRIG_PIN < 0 || ECHO_PIN < 0) {    while (true) {    }  }  pinMode(TRIG_PIN, OUTPUT);  pinMode(ECHO_PIN, INPUT);} // Выехать на центр перекрёстка: датчики стоят впереди колёс.void toCenter() {  drive(FORWARD, baseSpeed, FORWARD, baseSpeed);  delay(centerMs);  stopMotors();} // Крутиться на месте, пока датчик со стороны поворота не найдёт новую линию.void turnUntilLine(bool left) {  if (left) {    drive(BACKWARD, turnSpeed, FORWARD, turnSpeed);  } else {    drive(FORWARD, turnSpeed, BACKWARD, turnSpeed);  }  delay(leaveMs);  do {    readSensors();  } while ((left ? leftLevel : rightLevel) > 30);  stopMotors();} void turnLeftAtCrossing() {  toCenter();  turnUntilLine(true);} void turnRightAtCrossing() {  toCenter();  turnUntilLine(false);} // Развернуться на линии: крутиться, пока линия снова не окажется под датчиком.void turnAroundOnLine() {  turnUntilLine(true);} // Ехать по линии заданное время.void followLineFor(unsigned long ms) {  unsigned long start = millis();  while (millis() - start < ms) {    readSensors();    followLineStep();  }  stopMotors();} // Ехать по линии и остановиться перед грузом по ультразвуку.void approachCan() {  while (true) {    int distance = readDistanceCm();    if (distance > 0 && distance <= STOP_CM) {      break;    }    readSensors();    followLineStep();  }  stopMotors();} void loop() {}
Predict

Read yours setup() and tell your partner step by step what the robot will do.

  1. Place the load at the end of the line, the robot at the other end. Launch it.
Hint: How long to wait

The grab takes time to reach the corner. Try a pause of 300 and 600 ms: does he have time?

Hint: No contact

You have already seen defense without contact in the angle sample sketch.

It should work

The robot drives up, takes the load, turns around, carries it along the line and places it.

Requirement 4. Continue with your program L51_Stop_At_Can and save as L52_Pick_Place. The robot delivers along the line:

  • pickUp() and putDown() follow the order: stop - close; open - wait - drive away;
  • your function moves the gripper moveGripper;
  • without servo contact the program does not start moving;
  • in setup(): drive up to the load, pick it up, turn around on the line, drive with the load, place it.

Acceptance. Cargo at the end of the line, robot at the other end: hands-free delivery.

Hint: Idea (1 of 2)

Each delivery action is a ready-made function from previous lessons or this lesson. All that remains is to connect them in order.

Hint: Plan (2 of 2)
  1. followLineToCan(STOP_CM).
  2. pickUp().
  3. turnAroundOnLine().
  4. Drive along the line CARRY_MS.
  5. putDown().
It should work

The program fulfills requirements 1-4, delivery is hands-free.

5

Reliability

12 min
  1. Repeat the transportation three times in a row. Where does a robot make mistakes most often?
  2. Pick up STOP_CM so that the load is in the middle of the gripper.
  3. Pick up CARRY_MS, so that the load is placed in the right place.
It should work

Three transfers in a row without using your hands. The values ​​are written to the log.

  1. Repeat the transportation five times in a row. Write down each failure: at what stage and what happened.
Check-inEntranceCaptureTransportationProductionWhat happened
1
2
3
4
5
  1. Find the stage where there are the most errors. What one number should I change to fix this? Change and repeat three times.
Hint: What numbers are there

STOP_CM - where the robot stands in front of the load, CARRY_MS - where he puts it, gripper angles - how he holds it.

It should work

Five-race table, corrected leg and three straight hands-free hauls.

Measure delivery reliability and improve it according to.

  1. Make 10 deliveries in a row. For each, record the stage where it failed: approach, gripping, turning around, transport or placement.
  2. Count how many deliveries out of 10 were completed. Which stage gives you the most breakdowns?
  3. Fix only this stage and make 10 deliveries again. Has it gotten better? How long?
SeriesSuccessful out of 10EntranceCaptureReversalTransportationProduction
Before
After
Hint: If there are no breakdowns

Make the conditions more difficult: place the weight 1 cm to the side of the line or lift it baseSpeed. Where will it break first?

It should work

Two series of 10 deliveries, the stage with the most failures, what has changed and how much reliability has increased.

6

Quests by level

13 min
General · Line transportation

Take a weight from the end of the line and place it at the other end of the same line.

Middle level · Through the intersection

The cargo is on one branch, the delivery point is on another. Transport the cargo through the intersection using the functions of lesson 4.2.

Advanced level · The deliver function

Write the function deliver(маршрут до груза, маршрут до места, время до места), which handles all the delivery. Pass routes using decision lines, for example "LS". Then in the final task the delivery will be one line of the program.

Test yourself

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

1.How is a servo different from a wheel motor?
2.In what order is it correct to take the load?
3.Why is there a pause after opening the gripper in putDown()?
4.The servo hums, the gripper shakes at the load. What to do?
5.Why are gripper angles selected by experience?

★ Intermediate level

1.The cargo is on one branch, the delivery point is on another. What should be added to the line transportation?
2.In what order is delivery carried out?
3.The pickUp() function is left empty. What will the robot do at the cargo?
4.When checking by tilting, the load falls out of the gripper. What should I change?
5.Three out of five runs went wrong due to placement: the load was placed incorrectly. Which one number should you change first?

★★ Advanced level

1.What does the string "LS" mean in this call?
deliver("LS", "R", 1500);
2.Why use the deliver() function to arrange delivery?
3.currentAngle = 90, target = 41. What will happen?
void moveGripper(int target) {  while (currentAngle != target) {    currentAngle += (target > currentAngle) ? 2 : -2;    gripper.write(currentAngle);    delay(15);  }}
4.A series of 10 deliveries: approach failures — 0; gripping — 1; turning around — 4; transport — 1; placement — 0. What should you improve first?
5.After correcting the reversal, successful deliveries became 7 out of 10 instead of 4. How to make sure that it was the correction that helped?

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 has all the skills of the final task: driving, turning, staying in line, finding intersections, seeing cargo and transporting it. Next is the final project.

How to confirm the result

The result of the experiment relates the conditions, program version, observation and conclusion. Comparing attempts with one change helps verify the cause, including failed attempts. The mark refers to practice already completed; repetition for the sake of marking is not necessary. The discrepancy with the forecast sets the next hypothesis to be tested. A model, measurements of a real robot, and an explanation are different types of evidence.

Lesson vocabulary

servoA motor that turns at a given angle and holds it.
anglePosition of the servo arm in degrees, usually from 0 to 180.
libraryA ready-made set of commands, which is connected with the #include line. Servo is a library for servos.