Глава 20 з 27

Безкоштовно

5: Творчі проекти

⏱️ 70-85 хвилин
📊 intermediate

Розділ 20: "Програмуємо роботів"

Одного разу Аліса прийшла до Професора Біта раніше звичайного і застала його за роботою в дальньому куті лабораторії. Він схилився над дивним пристроєм, схожим на маленьку машинку з колесами.

— Доброго ранку, Професоре! Що це у вас? — запитала Аліса з цікавістю.

Професор обернувся і посміхнувся:
— А, Алісо! Радий тебе бачити. Це наша сьогоднішня тема — робототехніка!

Байт підкотився ближче, явно зацікавлений:
— Оце так! Моя далека родина!

— Абсолютно правильно, Байт, — кивнув Професор. — Цей робот набагато простіший за тебе, але принципи програмування роботів дуже важливі. Їх використовують в промисловості, медицині, дослідженнях космосу і навіть у повсякденному житті.

Железо, схемы, взгляд сенсора —
Не просто ящик на колёсах.
Ему даём мы роль актёра
В театре улиц, цехов, космоса.

Он едет там, где людям трудно,
Несёт лекарство, чинит мост.
Но без программы он как будто
Застывший в паузе вопрос.

Код — это воля и задача,
Сенсор — глаза, мотор — шаги.
Робот послушен, если чётко
Ему прописаны пути.

Професор обережно поставив маленького робота на підлогу. У нього було два колеса, кілька датчиків спереду і невелика панель управління зверху.

— Знайомся, це Робі, — представив Професор. — Він може рухатися вперед і назад, повертати, виявляти перешкоди і слідувати по лінії. Але найголовніше — ми можемо програмувати його поведінку!

Робі в лабораторії: блоки Scratch і програмування робота

— Як саме ми програмуємо роботів? — запитала Аліса, присідаючи біля Робі.

— Є різні способи, — відповів Професор. — Для простих роботів, як Робі, ми можемо використовувати візуальне програмування з блоками, схожими на Scratch. Для більш складних — спеціалізовані мови, такі як ROS (Robot Operating System) або стандартні мови програмування, такі як Python і C++.

Логік, що спостерігала з книжкової полиці, додала:
— Програмування роботів відрізняється від звичайного програмування тим, що тут код взаємодіє з фізичним світом через сенсори і мотори.

Професор кивнув і підключив Робі до комп'ютера:
— Давай почнемо з простої програми. Ми хочемо, щоб Робі рухався вперед доти, поки не виявить перешкоду, потім повернув і продовжив рух.

На екрані комп'ютера з'явився редактор блочного програмування. Професор перетягнув кілька блоків у робочу область:


ПОКИ Істина:
ЯКЩО датчик_відстані() > 10:
рухатися_вперед(50)
ІНАКШЕ:
зупинитись()
повернути_направо(90)

— Ця програма створює нескінченний цикл, — пояснив Професор. — Усередині циклу робот перевіряє показання датчика відстані. Якщо до перешкоди більше 10 сантиметрів, робот рухається вперед зі швидкістю 50 одиниць. Якщо перешкода ближче, робот зупиняється і повертає на 90 градусів направо.

— А чи можна завантажити програму в Робі? — нетерпляче запитала Аліса.

— Звичайно! — Професор натиснув кнопку "Завантажити", і маленькі вогники на панелі Робі заблимали. — Тепер поставимо його на підлогу і подивимось, як він справиться.

Робі ожив і почав рухатися по лабораторії. Він впевнено їхав вперед, але коли перед ним виник стіл, він зупинився, повернув направо і продовжив рух у новому напрямку.

— Він працює! — захопилась Аліса. — Але що, якщо ми хочемо, щоб він виконав певний маршрут?

— Добре питання, — посміхнувся Професор. — Для цього ми можемо використовувати послідовність команд замість реакції на датчики. Наприклад:


рухатися_вперед(50, 2) # рухатися вперед зі швидкістю 50 протягом 2 секунд
повернути_наліво(90) # повернути наліво на 90 градусів
рухатися_вперед(50, 1) # рухатися вперед ще 1 секунду
повернути_направо(90) # повернути направо на 90 градусів
рухатися_вперед(50, 3) # рухатися вперед 3 секунди

— Така програма змусить Робі виконати певну послідовність рухів, — пояснив Професор. — Але є проблема: якщо в процесі руху він зустріне перешкоду, він просто вріжеться в неї.

— Чи можна поєднати обидва підходи? — запитала Аліса. — Виконувати маршрут, але при цьому реагувати на перешкоди?

— Відмінна думка! — похвалив Професор. — Це один з ключових принципів робототехніки — поєднання планової поведінки і реакції на навколишнє середовище. Ось як це може виглядати:


маршрут = [
{"дія": "вперед", "значення": 2},
{"дія": "поворот_наліво", "значення": 90},
{"дія": "вперед", "значення": 1},
{"дія": "поворот_направо", "значення": 90},
{"дія": "вперед", "значення": 3}
]

поточний_крок = 0

ПОКИ поточний_крок < довжина(маршрут):
крок = маршрут[поточний_крок]

ЯКЩО крок["дія"] == "вперед":
часпочатку = поточнийчас()
ПОКИ (поточнийчас() - часпочатку < крок["значення"]) І (датчик_відстані() > 10):
рухатися_вперед(50)

ЯКЩО датчик_відстані() <= 10:
# Виявлено перешкоду - реагуємо
зупинитись()
об'їхати_перешкоду()

ІНАКШЕ ЯКЩО крок["дія"] == "поворот_наліво":
повернути_наліво(крок["значення"])

ІНАКШЕ ЯКЩО крок["дія"] == "поворот_направо":
повернути_направо(крок["значення"])

поточнийкрок = поточнийкрок + 1

— Це вже виглядає складніше, — помітила Аліса, вивчаючи код.

— Так, роботи часто вимагають досить складних програм, — погодився Професор. — У цьому прикладі ми зберігаємо маршрут як список словників, де кожен крок має тип дії і значення. Потім ми виконуємо кожен крок по порядку, але при русі вперед постійно перевіряємо датчик відстані. Якщо виявляється перешкода, ми перериваємо поточний рух і викликаємо функцію для об'їзду перешкоди.

— А як працює функція об'їхати_перешкоду()? — запитала Аліса.

— Це може бути окрема підпрограма, — пояснив Професор. — Наприклад:


функція об'їхати_перешкоду():
повернути_направо(45)
рухатися_вперед(50, 0.5)
повернути_наліво(45)
ПОКИ датчик_відстані() > 10:
рухатися_вперед(30)
повернути_наліво(90)
рухатися_вперед(50, 1)
повернути_направо(90)

— Ця функція змушує робота відхилитися вправо, потім рухатися паралельно перешкоді, обійти її і повернутися до початкового напрямку, — пояснив Професор.

Байт продемонстрував цю послідовність рухів, імітуючи дії Робі:
— В робототехніці така поведінка називається "уникнення перешкод" і є одним з базових навичок для мобільних роботів.

— А якщо ми хочемо, щоб робот сам знайшов шлях до мети? — запитала Аліса.

— Тоді ми використовуємо алгоритми планування шляху, — відповів Професор. — Наприклад, алгоритм A* (А-зірка) або алгоритм Дейкстри. Вони дозволяють роботу знайти оптимальний шлях від поточної позиції до мети, враховуючи перешкоди на карті.

Професор показав на екрані іншу програму:


карта = [
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 1, 1, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 1, 1, 0],
[0, 1, 0, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]
] # 0 - вільний простір, 1 - перешкода

початок = (0, 0)
мета = (7, 7)

шлях = знайти_шлях(карта, початок, мета)

для кожної точки (x, y) в шляху:
рухатисядоточки(x, y)

— Тут ми представляємо навколишній простір як двовимірну сітку, — пояснив Професор. — Кожна комірка або вільна (0), або містить перешкоду (1). Функція знайти_шлях() використовує алгоритм пошуку шляху, щоб визначити послідовність точок від початку до мети. Потім робот послідовно рухається через ці точки.

— А що якщо карта заздалегідь невідома? — зацікавилась Аліса.

— Відмінне питання! — похвалив Професор. — В такому випадку робот повинен спочатку дослідити навколишнє середовище і побудувати карту за допомогою своїх датчиків. Це називається SLAM — Simultaneous Localization and Mapping (одночасна локалізація і картографування).

— Сучасні роботи-пилососи і безпілотні автомобілі використовують подібні алгоритми, — додала Логік. — Вони сканують навколишнє середовище за допомогою лідарів, камер і інших сенсорів, будують карту і планують свої дії на основі цієї інформації.

Професор дістав з шафи ще одного робота, більш складного, з маніпулятором-рукою:
— А це Армі. Крім переміщення, він може взаємодіяти з предметами за допомогою маніпулятора. Це додає новий рівень складності в програмування.

Він продемонстрував просту програму для Армі:


Під'їхати до кубика


рухатисядокоординат(x, y)

Опустити маніпулятор


встановитивисотуманіпулятора(5)

Захопити кубик


закрити_захват()

Підняти маніпулятор


встановитивисотуманіпулятора(20)

Перевезти кубик в інше місце


рухатисядокоординат(новийx, новийy)

Опустити маніпулятор


встановитивисотуманіпулятора(5)

Відпустити кубик


відкрити_захват()

Підняти маніпулятор


встановитивисотуманіпулятора(20)

— Для програмування роботів-маніпуляторів використовуються спеціальні підходи, — пояснив Професор. — Наприклад, кінематика — математичний опис руху, що не враховує сили, які викликають цей рух. Є пряма кінематика (розрахунок положення захвату за кутами суглобів) і обернена кінематика (розрахунок необхідних кутів суглобів для досягнення заданого положення захвату).

— Звучить складно, — помітила Аліса.

— Насправді, основні принципи програмування роботів ті самі, що ми вже вивчали, — заспокоїв її Професор. — Змінні зберігають інформацію про стан робота і навколишнього середовища, умови допомагають приймати рішення на основі цієї інформації, цикли дозволяють повторювати дії, а функції організовують код у логічні блоки.

— Але в робототехніці є і особливості, — додала Логік. — Наприклад, паралельне виконання задач. Робот може одночасно рухатися, сканувати оточення і обробляти команди користувача. Для цього використовуються багатопоточність або асинхронне програмування.

— Ще одна важлива концепція — це зворотний зв'язок, — продовжив Професор. — Робот постійно перевіряє, чи досяг він бажаного стану, і корегує свої дії. Наприклад:


бажаний_кут = 90
поточнийкут = отриматикут_повороту()

ПОКИ абсолютнезначення(бажанийкут - поточний_кут) > 1:
якщо бажанийкут > поточнийкут:
повернути_направо(10)
інакше:
повернути_наліво(10)

поточнийкут = отриматикут_повороту()

— Цей код змушує робота повертатися, поки він не досягне бажаного кута з точністю до 1 градуса, — пояснив Професор. — Такі контури зворотного зв'язку дозволяють роботам точно виконувати команди, незважаючи на недосконалість механіки і зовнішні фактори.

— А що щодо штучного інтелекту в роботах? — запитала Аліса. — Чи можуть роботи вчитися і приймати рішення самостійно?

— Абсолютно! — кивнув Професор. — Сучасні роботи часто використовують методи машинного навчання. Наприклад, робот може навчитися розпізнавати об'єкти на зображеннях з камери або оптимізувати свої рухи для економії енергії.

— Один з підходів — це навчання з підкріпленням, — додав Байт. — Робот отримує "нагороду" за правильні дії і "покарання" за неправильні. З часом він вчиться вибирати дії, які максимізують нагороду.

Професор кивнув:
— В цьому суть сучасної робототехніки — створення систем, які можуть сприймати навколишній світ, приймати рішення на основі цієї інформації і діяти, щоб досягти поставлених цілей.

— А які бувають види роботів? — запитала Аліса.

— Їх дуже багато, — відповів Професор. — Промислові роботи на заводах, сервісні роботи в готелях і лікарнях, дослідницькі роботи в космосі і під водою, сільськогосподарські роботи на фермах, військові роботи, домашні роботи-помічники, освітні роботи і багато інших.

— Робототехніка — це міждисциплінарна область, що об'єднує механіку, електроніку, комп'ютерні науки, теорію управління і безліч інших дисциплін, — підсумувала Логік. — І програмування — найважливіша частина цієї області, адже саме програми роблять роботів "розумними".

Завдання

Уяви, що в тебе є простий робот, який може рухатися вперед/назад, повертати вліво/вправо, і має датчики відстані та світла. Напиши програму (використовуючи псевдокод або блочне програмування), яка б змусила цього робота: 1) Знайти джерело світла і під'їхати до нього; 2) Уникати перешкод на шляху; 3) Коли він досягне світла, відтворити звук і повернутися до початкової позиції. Опиши, які виклики ти можеш зустріти і як би ти їх вирішив(ла).