Робот, следующий вдоль линии (Line Follower Robot), является одним из самых популярных проектов для тех, кто только начал заниматься робототехникой. Данный робот способен самостоятельно передвигаться вдоль черной линии, используя для этого пару инфракрасных датчиков и пару электродвигателей постоянного тока. В данной статье мы рассмотрим создание подобного робота на основе платы Raspberry Pi.
Конечно, вычислительная мощность платы Raspberry Pi для этого проекта очень избыточна, такого робота, следующего вдоль линии, можно легко создать на основе платы Arduino или микроконтроллера AVR. Но данный проект имеет обучающий характер и преследует цель обучить вас начальным знаниям робототехники с реализацией на основе платы Raspberry Pi. Данный простейший робот может быть использован в качестве основы для создания значительно более "продвинутых" роботов (например, робот для уборки помещений), в которых вычислительные мощности и возможности платы Raspberry Pi можно будет использовать в полной мере.
Необходимые компоненты
- Плата Raspberry Pi (купить на AliExpress).
- Инфракрасный датчик – 2 шт. (купить на AliExpress).
- Электродвигатель постоянного тока – 2 шт.
- Микросхема драйвера двигателей L293D (купить на AliExpress).
- Шасси робота (можно сконструировать самому).
- Power bank или любой другой подходящий источник питания.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Принцип работы робота, следующего вдоль линии
Следующий вдоль линии робот способен обнаруживать/отслеживать линию с помощью пары инфракрасных датчиков. Каждый инфракрасный датчик имеет в своем составе инфракрасный передатчик (IR Transmitter) и инфракрасный приемник (IR receiver), роль которого выполняет фотодиод. Инфракрасный передатчик излучает инфракрасный свет, а инфракрасный приемник принимает эти отраженные от препятствия лучи (если оно есть). При этом не все поверхности способны хорошо отражать инфракрасные лучи, некоторые поверхности практически полностью поглощают эти лучи. К примеру, от светлой (белой) поверхности инфракрасные лучи отражаются хорошо, а вот черной поверхностью они полностью поглощаются как показано на рисунках ниже. На этих свойствах инфракрасного цвета и будет основан принцип работа нашего робота, следующего вдоль линии.
Внешний вид инфракрасного датчика показан на следующем рисунке. Более подробно о его подключении к плате Raspberry Pi можно посмотреть в следующей статье.
Таким образом, в составе нашего проекта будет два инфракрасных датчика, которые будут отслеживать местоположение линии и два двигателя, которые будут перемещать робота вдоль этой линии. Эти двигатели будут потреблять достаточно большой ток и должны быть двунаправленными, поэтому для управления ими в нашем проекте мы использовали микросхему драйвера двигателей L293D. Обрабатывать данные с инфракрасных датчиков и управлять работой двигателей в нашем проекте будет плата Raspberry Pi. Структурная схема работы проекта показан на следующем рисунке.
Если ни один из датчиков не будет обнаруживать черную линию, то робот будет двигаться прямо. Эта ситуация показана на нижеприведенном рисунке.
Если левый датчик обнаруживает черную линию, то робот поворачивает влево.
Если правый датчик обнаруживает черную линию, то робот поворачивает вправо.
Если оба датчика обнаруживают черную линию, робот останавливается.
В нашем проекте мы использовали два инфракрасных датчика (сенсора), которые мы назовем левым датчиком и правым датчиком. Когда оба датчика видят перед собой белый цвет робот движется прямо.
Схема проекта
Схема следующего вдоль линии робота на Raspberry Pi представлена на следующем рисунке.
Схема содержит плату Raspberry Pi и подключенные к ней инфракрасные датчики и микросхему L293D, к которой уже подключены двигатели. Схема запитывается от мобильного Power bank (на схеме он нарисован в виде батареи формата AAA).
Распиновка контактов ввода/вывода платы Raspberry Pi показана на следующем рисунке.
Плата Raspberry Pi запитывается от Power bank, а инфракрасные датчики – от контакта +5V платы (провода красного цвета на схеме). Общий провод (земля) на схеме обозначен линиями черного цвета. Провод желтого цвета используется для подключения выходных контактов инфракрасных датчиков к контактам GPIO платы Raspberry Pi.
Для управления двигателями нам необходимо четыре контакта (A,B,A,B). Эти контакты подключены к контактам GPIO 14, 4, 17 и 18 платы Raspberry Pi соответственно. Провода оранжевого и белого цвета вместе формируют соединение для подключения одного двигателя.
Двигатели подключены к микросхеме L293D, которая запитывается от power bank. Перед тестированием работы схемы убедитесь в том, что земля power bank подключена к земле платы Raspberry Pi, иначе схема работать не будет.
Объяснение программы для Raspberry Pi
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
После сборки проекта у вас должна получиться конструкция примерно следующего вида:
После этого можно приступать к написанию кода программы.
В программе нам первым делом необходимо подключить (импортировать) библиотеку для работы с контактами ввода/вывода. Также мы импортируем эту библиотеку RPi.GPIO под именем “IO” (то есть переименовываем ее для использования в программе), то есть далее в программе всегда, когда мы захотим обратиться к контактам ввода/вывода, мы будем использовать слово ‘IO’.
1 |
import RPi.GPIO as IO |
Иногда контакты ввода/вывода (GPIO pins), которые мы собираемся использовать в программе, могут выполнять другие функции. В этом случае во время исполнения программы мы будем получать предупреждения (warnings). Следующей командой мы укажем плате Raspberry Pi на то, чтобы она игнорировала эти предупреждения и продолжала исполнение программы.
1 |
IO.setwarnings(False) |
Мы можем обращаться к контактам ввода/вывода (GPIO pins) платы Raspberry Pi используя либо номер контакта на плате, либо его функциональный номер. В представленной выше распиновке контактов ввода/вывода можно увидеть, к примеру, что обозначение GPIO19 соответствует контакту PIN 35. То есть в зависимости от того, какой способ обращения к контактам мы выбрали, мы можем обращаться к рассмотренному контакту либо по номеру ‘35’, либо по номеру ‘19’. В данном проекте мы выберем способ обращения к контактам по их функциональным номерам, поэтому используем следующую команду:
1 |
IO.setmode (IO.BCM) |
Далее сконфигурируем 6 контактов в качестве цифровых входов/выходов. Первые два из этих контактов будут использоваться для считывания данных с инфракрасных датчиков. С остальных 4-х контактов будет осуществляться управление двигателями (по 2 контакта на каждый двигатель).
1 2 3 4 5 6 7 8 |
IO.setup(2,IO.IN) #GPIO 2 -> Left IR out IO.setup(3,IO.IN) #GPIO 3 -> Right IR out IO.setup(4,IO.OUT) #GPIO 4 -> Motor 1 terminal A IO.setup(14,IO.OUT) #GPIO 14 -> Motor 1 terminal B IO.setup(17,IO.OUT) #GPIO 17 -> Motor Left terminal A IO.setup(18,IO.OUT) #GPIO 18 -> Motor Left terminal B |
Если на выходе инфракрасного датчика “True”, это значит, что его сигнал отражается от белой поверхности, следовательно, робот может двигаться прямо.
1 2 3 4 5 6 |
if(IO.input(2)==True and IO.input(3)==True): #both white move forward IO.output(4,True) #1A+ IO.output(14,False) #1B- IO.output(17,True) #2A+ IO.output(18,False) #2B- |
Если первый инфракрасный датчик возвращает на своем выходе значение False, это значит что его сигнал отражается от черной линии – в этом случае мы должны остановить правый двигатель, при вращении одного левого двигателя робот будет поворачивать вправо.
1 2 3 4 5 6 |
elif(IO.input(2)==False and IO.input(3)==True): #turn right IO.output(4,True) #1A+ IO.output(14,True) #1B- IO.output(17,True) #2A+ IO.output(18,False) #2B- |
Если второй инфракрасный датчик обнаруживает под собой черную линию, мы должны начать поворот робота влево (останавливаем левый двигатель).
1 2 3 4 5 6 |
elif(IO.input(2)==True and IO.input(3)==False): #turn left IO.output(4,True) #1A+ IO.output(14,False) #1B- IO.output(17,True) #2A+ IO.output(18,True) #2B- |
Если оба инфракрасных датчика обнаруживают перед собой черную линию, это значит, что робот должен остановиться.
1 2 3 4 5 6 |
else: #stay still IO.output(4,True) #1A+ IO.output(14,True) #1B- IO.output(17,True) #2A+ IO.output(18,True) #2B- |
Тестирование работы проекта
После того как аппаратная часть проекта будет готова загрузите программу в Raspberry Pi и запустите ее на выполнение. Для работы робота нам будет необходим портативный источник питания – для этой цели хорошо подойдет power bank. Мы использовали power bank с двумя USB портами: один из них используется для подачи питания на плату Raspberry Pi, а второй – для подачи питания на микросхему драйвера двигателя как показано на следующем рисунке.
После этого все, что вам осталось сделать, это изготовить полосу черного цвета и поместить робота над ней. Мы для изготовления дорожки, вдоль которой будет двигаться робот, использовали черную изоляционную ленту. Вы можете использовать для ее изготовления любой другой темный материал, но убедитесь в том, что поверхность, на которой вы ее размещаете, будет достаточно светлой.
Исходный код программы на Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import RPi.GPIO as IO import time IO.setwarnings(False) IO.setmode(IO.BCM) IO.setup(2,IO.IN) #GPIO 2 -> левый инфракрасный датчик IO.setup(3,IO.IN) #GPIO 3 -> правый инфракрасный датчик IO.setup(4,IO.OUT) #GPIO 4 -> Motor 1 terminal A IO.setup(14,IO.OUT) #GPIO 14 -> Motor 1 terminal B IO.setup(17,IO.OUT) #GPIO 17 -> Motor Left terminal A IO.setup(18,IO.OUT) #GPIO 18 -> Motor Left terminal B while 1: if(IO.input(2)==True and IO.input(3)==True): # движение прямо IO.output(4,True) #1A+ IO.output(14,False) #1B- IO.output(17,True) #2A+ IO.output(18,False) #2B- elif(IO.input(2)==False and IO.input(3)==True): # поворот направо IO.output(4,True) #1A+ IO.output(14,True) #1B- IO.output(17,True) #2A+ IO.output(18,False) #2B- elif(IO.input(2)==True and IO.input(3)==False): # поворот налево IO.output(4,True) #1A+ IO.output(14,False) #1B- IO.output(17,True) #2A+ IO.output(18,True) #2B- else: # остановка робота IO.output(4,True) #1A+ IO.output(14,True) #1B- IO.output(17,True) #2A+ IO.output(18,True) #2B- |