И прежде, чем поставить датчики на робота, давайте снова вернемся к нашей схеме,
где зафиксируем, что у нас теперь в качестве устройства восприятия
есть датчик линии, который отличает белое, черное и все промежуточные оттенки,
которые он воспринимает серыми, который считывается как обычный аналоговый сигнал.
И у нас будет функция, которая будет сообщать,
черное или белое сейчас находится под данным датчиком.
И тот алгоритм, который мы представили когда рассуждали о езде по линии,
мы реализуем: свяжем вот эту и вот эту функции.
Итак, мы снова в студии, и мы знаем все, что нужно для того чтобы робот поехал.
Теперь нам нужно доработать робота, нам нужна трасса и нам нужен код.
Что касается робота.
Я просто установил 2 датчика линии таким образом,
чтобы они были как можно ближе к краям линии,
потому что если мы их разнесем далеко, вспомните, как он будет ехать: он будет
ехать пока не упрется одним из датчиков в линию, да, он вот так вот перекосится.
Зачем нам это?
Потом он перекосится обратно, и так вот он зигзагами будет ехать.
Не надо.
Поэтому они располагаются рядом с линией.
Что касается трассы.
Я нарисовал вот такую вот трассу в обычном графическом редакторе.
Мне хотелось, чтобы она была похожа на гоночную трассу с прямым отрезком,
с плавными поворотами, с крутыми поворотами и так далее.
Вы можете взять этот макет в дополнительных материалах или нарисовать
свою трассу, а затем забить в поисковике «широкоформатная печать»,
найти типографию, позвонить им, спросить, печатают ли они на баннерной ткани.
Они напечатают, и у вас будет трасса.
Теперь давайте разберемся с кодом.
За основу я взял один из скетчей, где мы экспериментировали с ездой,
и стал редактировать.
Во-первых, добавил макроопределения для пинов датчиков и несколько
еще макроопределений, которые сделают код более читаемым.
Вот эти мы будем передавать в качестве параметров в функцию чтения датчиков,
это у нас обозначает границу между черным и белым,
а вот это — заданные скорости, возможные скорости для моторов вперед и назад.
Помните, как у нас было на схеме?
Затем я определил функцию для чтения датчиков.
Конечно, могли бы обойтись и без нее, но при дальнейшем развитии программы,
код стал бы нечитаемым, поэтому я решил вынести это в отдельную функцию.
Вот она.
Она будет возвращать "булево" значение, истину или ложь,
в зависимости от того, черное или белое сейчас находится под датчиком.
В качестве параметра она принимает те самые left и right для определения того,
какой датчик сейчас нужно считывать.
Что, собственно,
и происходит: если пришло left — будем считывать значение с того пина,
куда подключен левый датчик, и, если оно больше порогового значения,
возвращать «ложь», а в противном случае — «истину».
И ровно то же самое происходит,
если пришло right, только для правого датчика.
Теперь, у нас есть функция для управления моторами, функция для чтения датчиков,
у нас есть представление о том, как их связать, и мы реализуем это в коде.
Согласно нашей табличке, если оба датчика показывают «белое»,
то есть функция lineSensor возвращает «истину»,
мы просто едем вперед.
В противном случае, если под правым датчиком «черное»,
то есть lineSensor (right) возвращает «ложь», мы будем поворачивать направо,
крутить правое колесо назад, а левое — вперед.
И третий случай, который мы рассмотрели: когда правый
датчик показывает «белое», а левый — «черное».
В этом случае мы поворачиваем влево.
Ну, и если каким-то чудесным образом под обоими датчиками оказалось «черное»,
или случилась еще какая-то непредвиденная ситуация, то мы просто останавливаемся.
Вот и все.
Давайте смотреть, как это работает, только прежде почитаем еще
раз датчик чтобы определить ту самую границу между черным и белым.
Посмотрим, что мы видим.
В моей программке для визуализации есть удобные поля «минимум» и «максимум»,
поэтому я вижу, что здесь значения изменяются от 37 до 485.
Я даже не буду работать с подстроечными резисторами, а просто буду считать,
что переход между белым и черным случается в районе 200,
собственно, как в коде и было написано.
Если бы у меня получилось 400, я бы заменил одно из макроопределений.
Теперь давайте посмотрим, действительно ли робот поедет, как мы задумывали.
Перед загрузкой программы с ездой не забудьте закрыть монитор порта или
визуализатор монитора порта, потому что иначе у вас будут проблемы с загрузкой.
[МУЗЫКА] Посмотрим,
что получилось.
[МУЗЫКА] [МУЗЫКА]
[МУЗЫКА] [МУЗЫКА]
[МУЗЫКА] Итак,
задача езды по линии в первом приближении решена.
Однако, мы у данного способа видим ряд недостатков.
Во-первых, на поворотах робот совершает порывистые движения.
Во-вторых, очевидно,
что при разном уровне заряда батарей одни и те же
жестко заданные значения будут приводить к различному результату, то
есть придется постоянно менять константы, определяющие скорости, к примеру.
Ну, а кроме этого, у другого способа, о котором мы будем говорить далее,
есть свои отдельные преимущества.
[КОНЕЦ]
[КОНЕЦ]
[КОНЕЦ]