Робот проходящий лабиринты
В статье описано создание робота, который ездит по линиям и может проехать через лабиринт, а потом кратчайшим путем вернутся в начало. Этот робот получился у меня с 3-ей попытки.
Для начала, видео работы робота:
Список деталей:
2 микродвигателя.
Пара кронштейнов для двигателя.
Пара колес.
Шарик и корпус.
Аналоговые датчики отражения.
Болты и гайки #2.
Arduino RBBB
Драйвер для моторов.
Держатель 4х AAA батарей.
4 аккумулятора AAA.
Болты, гайки, шайбы и стойки.
Провода.
Припой.
Инструменты:
Паяльник.
Отвертка.
Плоскогубцы.
Теория
Есть две задачи которые надо решить: найти выход и оптимизировать обратный путь.
Для обнаружения выхода я руководствовался методом левой руки. Представьте, что вы находитесь в лабиринте и постоянно держите левую руку на стене. В конце концов, это позволит вам выйти из незамкнутого лабиринта. Робот работает только с незамкнутыми лабиринтами.
Способ левой руки описывается простыми условиями:
— Если вы можете повернуть налево, поверните налево.
— Если вы можете двигаться прямо, то двигайтесь прямо.
— Если вы можете повернуть направо, поверните направо.
— Если вы в тупике, развернитесь.
Робот должен принимать решение на перекрестке. Если робот на повороте не поворачивает, то он движется прямо. Каждое решение принятое роботом записывается в его памяти для построения оптимального обратного маршрута
L = Левый поворот
R = Правый поворот
S = Пропуск поворота
B = Разворот.
На картинке выше показан этот метод в действии. Путь к выходу — это LBLLBSR.
Мы должны превратить путь LBLLBSR в оптимальный путь SRR. Для этого необходимо найти место где робот повернул не туда. «B» это разворот, который может произойти в тупике, т. е. на неверном пути.Чтобы
оптимизировать путь мы должны заменить «B» на что то другое.
Давайте рассмотрим первые 3 действия LBLLBSR — LBL. Вместо того, чтобы повернуть налево, развернуться и опять повернуть налево, робот должен был пойти прямо. Таким образом, мы можем сказать, что LBL = S.
Вот полный список подобных замен:
LBR = B
LBS = R
RBL = B
SBL = R
SBS = B
LBL = S
В лабиринте могут быть не все эти повороты, но они необходимы. Некоторые из них даже возвращают B обратно. Это необходимо для дальнейшей правильной оптимизации пути.
LBL = S, новый путь SLBSR. LBS = R, новый путь SRR. Как вы видите, мы получили оптимальный путь. Мой робот оптимизирует путь во время движения. Путь хранится в массиве, и каждый раз перед сохранением хода он проверяет, что предыдущий ход не B, а если В, то оптимизирует путь. Роботу необходимо знать по крайней мере 3 последних хода, для оптимизации алгоритма прохождения пути.
Рассмотрим другой пример.
Если использовать правило левой руки для вышеприведенного лабиринта, то получим следующий алгоритм: LLLBLLLRBLLBSRSRS
Начинаем сокращать:
LL (LBL = S) LL (RBL = B) (LBS = R) RSRS = LLSLLBRRSRS
Продолжаем:
LLSL(LBR = B)RSRS = LLSLBRSRS
Продолжаем:
LLSBSRS
Продолжаем:
LL (SBS = B)RS = LLBRS
Продолжаем:
L (LBR = B)S = LBS
Итого:
LBS = R
Шасси
Шасси робота сделано из акрила толщиной 0.8 и вырезано лазером. К статье прилагается файл AutoCAD с чертежом. Если у вас нет возможности точно повторить его, можете сделать его как вам удобно. На функционал это не повлияет, возможно придётся немного поправить код.
Нижняя часть имеет отверстия для крепежа двигателей, Arduino, металлического шарика, датчика и верхней части. В верхней части есть одно больше отверстие для проводов от аккумулятора, который крепится на липучки и отверстия для прикрепления низа.
Установка привода колес
Я просто прикрепил каждый двигатель при помощи двух болтов. После этого, я одел на ось колёса простым надавливанием. Совместите D образный вал с отверстием в центре колеса.
Arduino
Следуйте инструкциям по сборке Arduino RBBB. Вам нужно будет отрезать часть платы для уменьшения размеров. Если вы не нуждаетесь в разъеме питания и стабилизаторе просто отрежьте их. Для этого можно использовать ножницы по металлу, пилу по металлу или любой подобный инструмент. Не паяйте на плату разъёмы кроме тех, которые необходимы для программирования по порту FTDI. Потом припаяйте 9-контактный разъем на левой стороне платы на контакты от «5В» до «А0». Позже к ним будет подключен датчик. Припаяйте 4-контактный разъем на правую сторону платы на контакты от «D5″ до»D8». К ним будет присоединён контроллер двигателя. Припаяйте 2-контактный разъем к GND и 5V. На них будет подаваться питание.
Контроллер двигателя
Я разработал и приложил печатную плату в формате Eagle для контроллера двигателя.
Если вы не используете плату, вы можете сделать это навесным монтажом.
Первый двигатель подключается к контактам, которые я назвал «М1-А» и «M1-B». Второй двигатель подключается к «М2» и «М2-B». 7 вывод Arduino подключается к первому входу первого двигателя «В 1А». 6 вывод Arduino подключается к «В1B». 5 вывод Arduino подключается к первому входу второго двигателя «В2А». 8 вывод подключается к «В 2В». Питание и GND подключается к +5В и GND контактам Arduino.
Датчики
Изначально датчик продается в виде платы из 8 датчиков. Два датчик по краям могут быть удалены. 9-контактный разъем должен быть припаян к датчику от «GND» до «6». Потом к ним подключается ответная часть провода, от которой идут к Arduino.
Эти датчики уменьшают напряжение в зависимость от того, как сильно ИК-лучи отражаются от поверхности. Мы можем использовать их для обнаружения белых и черных участков лабиринта. Датчик выдает напряжение около 0В при обнаружении белой поверхности и напряжение около Vin при обнаружении тёмной поверхности.
Сборка верхней части
Прикрепите верхнюю часть к нижней, при помощи болтов и стоек. Аккумулятор прикрепите к ней при помощи липучки. Закрепите верхнюю палубу. Используйте липучку для крепления аккумулятора. Пропустите провода от него через большее отверстие в верхней части. Мой аккумулятор имеет встроенный выключатель питания. Я обнаружил, что проще не ставить винт на крышке аккумулятора. Она и так неплохо держится, а отсутствие винта позволяет быстро вынуть один из аккумуляторов.
Подключение и установка датчиков
Датчик крепится при помощи болтов к нижней части. Вывод GND на дальней левой части датчика подключается к GND Arduino. Следующий вывод это Vcc, который подключается к 5В Arduino. Контакты 6 — 1 аналоговых датчиков подключены к контактам АЦП 5 – 0 Arduino. Т.е. контакт 6 датчика подключен к контакту АЦП 5 Arduino, контакт 5 датчика подключен к 4 Arduino, и т.д
Подключение питания
Просто припаяйте провода от аккумулятора к Arduino. Аккумулятор имеет встроенный выключатель, поэтому можно просто припаять их. Аппаратная часть робота завершена!
Программа
Программа состоит из нескольких функций, которые отвечают за алгоритм прохождения лабиринта. Функция «левой руки» считывает показания датчиков и управляет перемещением робота по вышеизложенным правилам. Функция поворотов сделана так, что робот продолжает поворачиваться, пока не заметит чёрную линию, а когда он её заметит, он поедет по ней. Также есть функция измерения длины линии и скорости робота.
Более подробно следует описать функцию оптимизации пути. На каждом перекрёстке записывается куда повернул робот, и если этот поворот привел к развороту «B», то эти 3 буквы заменяются одной как описано выше.
Также есть функция отправки робота обратно по кратчайшему пути, когда он был сначала убран, а потом возвращен назад в лабиринт.
Скачать код для Arduino, шаблон Autocad и файл плат в Eagle вы можете ниже
Оригинал статьи
Теги:
- Робот
- Eagle
- Перевод
- Arduino
Электронная игра «лабиринт» на сервоприводах. Никаких arduino, только жесткая логика / Хабр
Устройство представляет собой площадку-лабиринт, балансирующую на сервоприводах. Цель игры: закатить шарик в центр диска. Когда-то разработал его для факультатива по электронике. Схема сделана из того, что в буквальном смысле было под рукой. А что еще нужно для детей? Немного поработать, а потом поиграть.
Схема не содержит микроконтроллеров, а схемотехника рассчитана на то, чтобы поломать над ней голову. Немного микросхем 74 серии, сдобренных диодно-резисторной логикой, пару операционников, и получился вполне завершенный и функциональный игровой автомат.
Преимущество схемы в том, что она полностью моделируется в ISIS Proteus. Это удобно для анализа принципа ее работы.
❯ Описание устройства
Принцип работы устройства можно посмотреть в ролике. Для начала игры необходимо установить металлический шарик в стартовую позицию на внешнем радиусе лабиринта, это активирует сервоприводы и позволит управлять ими с помощью двухосевого аналогового джойстика. Отклонение рукоятки джойстика пропорционально наклоняет площадку лабиринта, что позволяет перемещать по нему шарик.
При смещении шарика со стартовой позиции запускается обратный отсчет игрового времени. Индикация времени осуществляется шкалой из десяти светодиодов, которые последовательно гаснут по мере уменьшения времени игры.
Время игры задается перемещением перемычки на штыревом разъеме с интервалом десять секунд. Интервал установки от 10 до 90 секунд.
Если шарик попадет в финальную позицию до окончания игрового времени, то шкала обратного отсчета времени останавливается и раздается прерывистый звуковой сигнал, оповещающий игрока о победе в игре.
Если игровое время заканчивается до того, как шарик попал в финишную позицию, то издается короткий звуковой сигнал, светодиодная шкала восстанавливается и сервоприводы отключаются.
Для повторного запуска игры необходимо снова переместить шарик в стартовую позицию, при этом схема управления перезапустится и позволит вновь управлять лабиринтом.
По задумке, на месте старта и финиша должны быть размещены проволочные контакты, которые будет замыкать шарик. Эти контакты дублируются кнопками на плате управления. На финише в поле лабиринта установлен небольшой магнит, чтобы надежно фиксировать шарик и замыкать контакты, это оповещает схему об окончании игры.
Механическая часть изготовлена на 3D принтере. Предполагается, что игровое поле может быть сменным. Устройство механической части вы можете посмотреть в ролике.
❯ Электрическая схема
Электрическая схема игрового автомата выполнена по структурной схеме, представленной на рисунке.
Когда металлический шарик покидает стартовую позицию, блок запуска игры формирует сигнал «startGame», который разрешает работу делителя тактовой частоты. Вместе с этим сигналом формируется сигнал разрешения работы сервоприводов «servoEnable», который также перезапускает работу шкалы обратного отсчета времени игры.
Если металлический шарик попадает в финишную позицию, формируются инверсные друг к другу сигналы «soundOFF» и «soundEnable». «soundOFF» запрещает работу делителя тактовой частоты и отсчет игрового времени останавливается. «soundEnable» запускает формирование звукового сигнала. Звуковые импульсы прекращаются, когда металлический шарик покидает финишную позицию.
Схема управления звуковым сигналом производит запуск генератора звуковой частоты в зависимости от комбинации сигналов на ее входе. Звуковые импульсы усиливаются транзисторным каскадом и поступают на пьезоизлучатель.
Сигнал «timeCLK» на выходе делителя частоты имеет частоту 1Гц и используется для подсчета игрового времени.
Отсчет игрового времени производит блок шкалы обратного отсчета времени, выполненный на основе сдвигового регистра. Когда последний из десяти светодиодов гаснет, формируется сигнал «gameOver», который перезапускает блок запуска игры и формирует короткий звуковой импульс.
Регулировать продолжительность игры позволяет настраиваемый делитель частоты. В зависимости от положения джампера, схема делит тактовый сигнал с коэффициентами от одного до девяти. В результате игровое время может составлять от 10 до 90 секунд.
В основе устройства использован аналоговый джойстик и два сервопривода. Для реализации управления сервоприводами на основе сигналов джойстика электрическая схема должна производить преобразования, как показано на графике. Графики на рисунке демонстрируют управление наклоном лабиринта по оси Х. Для оси Y управление осуществляется аналогично. Управление сервоприводом осуществляется ШИМ сигналом.
Пилообразный сигнал «sawtooth pulse» для формирование импульсов управления сервоприводами генерирует ГЛИН на основе таймера NE555.
Джойстик представляет собой делители напряжения для каждой оси. Напряжение джойстика сравнивается с пилообразным сигналом «sawtooth pulse», формируя ШИМ сигнал, который определяет положение сервоприводов. Сигнал «servoEnable» отключает подачу управляющих импульсов, когда игра окончена.
Регулируемый стабилизатор напряжения на LM317 позволяет ограничить угол поворота сервоприводов так, чтобы добиться плавного движения площадки лабиринта. А П-образный фильтр необходим для того, чтобы помехи от сервоприводов не мешали работать схеме управления.
В результате получилась забавная игрушка, которая вполне может стать для вас проектом «выходного дня». Файлы проекта вы можете скачать по этой ссылке. Там вы найдете: проект печатной платы в Игл, герберы для заказа печатных плат, полную модель для протеуса.
Если вам понравился этот проект, загляните в мой предыдущий пост, там представлен подстаканник со светодиодной индикацией температуры. Также предлагаю посмотреть статью о том, с чего началось мое увлечение схемами на жесткой логике.
лучших проектов Arduino для начинающих делают игру Arduino Maze
Сегодня я покажу один из новых и лучших проектов Arduino, то есть игру Arduino Maze с нуля до конца. Это может быть лучшая идея научного проекта или лучший проект для мини-инженерии, и это может быть назван лучшими проектами Arduino на 2021 год.
Управление сервоприводом с помощью джойстика в …
Пожалуйста, включите JavaScript
Управление сервоприводом с помощью джойстика в Arduino с кодом и диаграммой | Проект Arduino с исходным кодом
Здесь движения доски лабиринта полностью контролируются модулем джойстика Arduino, этот многоосевой модуль очень похож на кнопки управления джойстиком, когда стик перемещается вверх, вся доска лабиринта перемещается вверх, когда стик перемещается вниз, доска перемещается вниз аналогично элементы управления предназначены для движений влево и вправо
Итак, мы начнем делать этот захватывающий проект Arduino, начиная с материалов, необходимых для создания этого проекта. 0017 Раскрытие информации: Это партнерские ссылки. Как партнер Amazon, я зарабатываю кредиты за соответствующие покупки. После того, как мы соберем все вышеперечисленные материалы, можно будет собрать схему. См. приведенную ниже схему
Список материалов Наименование компонента Купить в Индии Купить в США 0 Arduino Uno 00034 https://amzn.to/3kbjZL2 https://amzn.to/3buKSoW Микро сервопривод https://amzn.to/3uj9fyH https://amzn5i.to/3pF Модуль джойстика https://amzn. to/2nszmsd https://amzn.to/3ahhhbcd и Jumper Wires HTTTPN. ://amzn.to/2OPKmu6 Схема схемы для игры Arduino
Схема схемы игры Arduino диаграмма, но не все такие профессионалы, как другие, ну, это подробное объяснение для начинающих!
Модуль джойстика имеет 4 контакта
Gnd идет на отрицательную шину на макетной плате, +5 В на положительную шину питания на макетной плате
Vrx к контакту A0 платы Uno, а Vry к контакту A1 платы Uno
Микроподключения сервоприводов
Для простоты понимания я переименовал сервоприводы как сервопривод 1 и сервопривод 2
Сервопривод номер 1 должен быть основным сервоприводом, отвечающим за движение вперед и движения назад
Сервопривод 2 для правостороннего и левостороннего движения
Сервоприводы имеют 3 штифта, как все это знают!
Сигнальный контакт будет подключен к D3 Uno в случае сервопривода 1, где сервопривод 2 будет подключен к D5 Uno, а плюс и земля должны быть подключены к + и — шинам питания на макетной плате
Источник питания Arduino для макетной платы
Для подачи питания на макетную плату от Uno подключите контакт Gnd Uno к отрицательной шине питания макетной платы, а контакт +5 В — к положительной шине питания макетной платы
Примечание : вы можете использовать другой также цифровые контакты, убедитесь, что вы ввели тот же номер контакта в коде Arduino
. После того, как все соединения схемы выполнены, загрузите код и проверьте, все ли работает нормально, здесь проект не будет работать от источника питания USB с платы, поэтому предпочтительнее использовать внешний источник питания постоянного тока
Код для проекта Arduino Maze Game Project
Скачать игру Arduino maze
После подачи питания на плату arduino слегка переместите джойстик, когда вы перемещаете его вверх, сервопривод 1 должен реагировать, когда вы перемещаете его влево/вправо, сервопривод 2 должен совершать движения, если У вас есть обратный ответ, попробуйте заменить штифты сервоприводов. После того, как компоненты будут работать идеально, необходимо собрать все это в раму. сделать
Нарисуйте круг на листе бумаги, затем нарисуйте лабиринты в соответствии с вашими требованиями. Чем сложнее лабиринт, тем игра будет
Круглый кусок картона в соответствии с размером бумаги Приклейте нарисованный на бумаге лабиринт к картону
Дайте ему высохнуть, Тем временем нарежьте полоски картона и покрасьте их соответствующим образом. Нарезанные и окрашенные полоски наклейте на линии лабиринта
Я приклеил эти полоски суперклеем.0002 Чтобы сделать базовую опору, я использовал дерево МДФ, так как в нем есть место для размещения всех моих электронных компонентов. Поместите все компоненты и прикрепите к плате с помощью двустороннего скотча.
микросервопривод с горячим клеем на верхней части колесаПоскольку вал сервопривода маленький, я увеличил его с помощью палочки от мороженого, чтобы он мог поддерживать всю доску лабиринта
Пожалуйста, следуйте инструкциям, как показано на рисунке для крепления сервопривода Центральная часть доски лабиринта приклеивается горячим клеем и прикрепите к сервоприводу
Обратитесь к изображениям, если возникнет путаница. После того, как это будет завершено, проект лабиринта Arduino готов к работе
Как играть в игру лабиринта Arduino
Включите питание Arduino uno с помощью адаптера постоянного тока 6 В, затем поместите маленький шарик на доску лабиринта, используя джойстик, переместите этот шарик в центр доска
Это лучшая идея для вечеринок. Тот, кто первым доберется до середины, станет победителем игры
Видеоссылка для лучших проектов Arduino
Рабочий проект игры Arduino Maze и видеоурок Здесь
Это все об игровом проекте Arduino, это, безусловно, один из лучших проектов Arduino для начинающих, и если вы ищете какой-либо научный проект, мини-инженерию или идеи для хобби на выходных, это может быть один
Как обычно если у вас есть какие-либо вопросы относительно этого игрового проекта arduino или какие-либо предложения по улучшению , дайте мне знать в поле для комментариев ниже, также ознакомьтесь с другими моими лучшими проектами arduino в моих предыдущих сообщениях, спасибо и хорошего дня.
Теги: игры arduino, проекты arduino, arduino uno, лучшие проекты arduino, лучшие проекты arduino
Настройка и калибровка лабиринта | LEARN.PARALLAX.COM
Circuit
Следуйте инструкциям, прилагаемым к набору приложений QTI Line Follower (№ 28108) (цифровую копию см. в разделе «Загрузки и ресурсы» на странице продукта). Для этого приложения необходимы некоторые аппаратные модификации. В инструкциях AppKit каждый QTI монтируется от края до края, но в этом приложении потребуется большее расстояние между QTI, чтобы Boe-Bot мог обнаруживать повороты и другие препятствия. Используйте рисунок 1 в качестве руководства и установите QTI так, чтобы два центральных QTI находились на расстоянии 0,8 см друг от друга, а крайние датчики находились на расстоянии 2 см от центра QTI.
Рисунок 1 — Установленные датчики QTI
Лабиринт
На рисунке 2 показан лабиринт с различными препятствиями, по которым Boe-Bot должен пройти, включая короткие и длинные прямые пути, повороты на 90° влево и вправо, букву T -перекресток и тупик. Эти препятствия создают ряд навигационных проблем, которые вы можете решить, тем самым улучшив производительность вашего Boe-Bot в более крупных и сложных лабиринтах. При построении лабиринта используйте большой кусок картона и убедитесь, что каждая полоса дорожки имеет ширину 1,5 дюйма из черной ленты. На рис. 2 показан лабиринт, предназначенный для этого занятия (не в масштабе).
Рисунок 2 — Boe-Bot Electrical Tape Maze
Прежде чем мы начнем, вы должны знать, что последняя программа в этом проекте может быть больше, чем примеры программ, которые вы, возможно, пробовали в Робототехника с Boe- Бот . Это потому, что есть много условий, которые должны быть приняты во внимание! Этот «мини-проект» демонстрирует, как взять сложную проблему и разбить ее на мелкие части, чтобы успешно решить ее. Для этого нам нужно откалибровать нашего Boe-Bot, чтобы он маневрировал в каждом состоянии, прежде чем собирать все вместе. Это сэкономит нам время при устранении неполадок, если мы будем знать, что каждая отдельная часть работает должным образом.
Убедитесь, что вы выполнили каждый шаг калибровки!
Очень важно следовать всем инструкциям по калибровке вашего Boe-Bot и обновлять значения в коде, которые они определяют экспериментально. Если вы пропустите какие-либо шаги или попытаетесь запустить код примера как есть, он, вероятно, не сработает.
Имейте в виду, что ценность Boe-Bot заключается в том, что с ним интересно играть, но он не является игрушечным роботом с ограниченным набором функций. Это робот с платформой для прототипирования, который может быть таким, каким вы его создадите. То есть, если вы готовы немного поработать и кое-чему научиться!
Движение вперед
Так как Boe-Bot должен двигаться медленно в некоторых точках лабиринта, нам придется замедлить сервоприводы от обычных 850, 650 PUSLOUT. Это поможет гарантировать, что показания QTI не будут пропущены, когда Boe-Bot перемещается по лабиринту, и вы можете использовать ту же процедуру тестирования, представленную в Robotics, с Boe-Bot Глава 4, Упражнение № 2.
Чтобы замедлить движение вперед, помните, что значение PULSOUT, равное 750, останавливает серводвигатели. Поэтому мы хотим выбрать значения ближе к 750, чтобы Boe-Bot медленно продвигался вперед.
Ниже представлена версия BoeBotForwardTenSeconds.bs2, которую можно использовать для калибровки Boe-Bot.
' SlowlyForward.bs2 ' Откалибруйте Boe-Bot так, чтобы он медленно двигался вперед по прямой. ' {$ШТАМП БС2} ' {$PBASIC 2.5} счетчик VAR Word ДЛЯ счетчика = от 1 до 407 ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ КОНЕЦ
Калибровка левого поворота на 90°
После калибровки кода замедленной перемотки следующим шагом будет калибровка поворотов на 90°. В лабиринте их много, так что постарайтесь здесь хорошо. Это просто, и вы уже откалибровали свой Boe-Bot для выполнения одного из заданий Robotics с Boe-Bot . Глава 4, задание № 2… верно? Если нет, не продолжайте, пока не закончите этот важный шаг! Теперь все, что нам нужно сделать, это запрограммировать Boe-Bot, чтобы он поворачивал налево, когда лабиринт поворачивает. Вы можете установить условия, которым должен следовать Boe-Bot, используя операторы SELECT…CASE. Таким образом, если QTI отправляют показания, которые сообщают BASIC Stamp, что Boe-Bot должен повернуть налево, BASIC Stamp затем может отправлять импульсы сервоприводам для выполнения 90° левый поворот.
Запутались?
Если вы не понимаете операторы SELECT…CASE и то, как они здесь применяются, вернитесь и посетите страницу Boe-Bot Line Following with Four QTI Sensors, чтобы получить подробную информацию о том, как работает следование по линии с помощью QTI.
Используйте приведенный ниже пример кода и измените значения по мере необходимости, чтобы ваш Boe-Bot выполнял повороты на 90° влево, оставаясь в центре пути лабиринта.
' MazeNavigation_LeftTurn. bs2 ' Boe-Bot поворачивает налево на основе значений QTI. ' {$ШТАМП БС2} ' {$PBASIC 2.5} qtis VAR Nib ' qti черно-белые состояния pulseCount VAR Byte ' FOR..NEXT счетчик цикла для поворота OUTB = %1111 ' Установить биты OUTB в 1 DO ' Main DO...LOOP GOSUB Check_Qtis ' Получить состояния QTI SELECT qtis ' Управление скоростью/направлением сервопривода CASE %0110 ' Прямо вперед ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛУЧАЙ %1110 GOSUB Turn_Left CASE ELSE ' Ничего не делать ПАУЗА 3 КОНЕЦВЫБОР ПЕТЛЯ Check_Qtis: ' Проверяет состояние каждого датчика QTI. 0 означает белую поверхность, 1 означает черную. DIRB = %1111 ' P7..P4 -> вывод ПАУЗА 0 ' Задержка = 230 мкс DIRB = %0000 ' P7..P4 -> ввод ПАУЗА 0 ' Задержка = 230 мкс qtis = INB ' Сохранение выходных данных QTI в INB ВОЗВРАЩАТЬСЯ Поверните налево: FOR pulseCount = 0 TO 15 ' Продвиньтесь немного вперед, чтобы Boe-Bot PULSOUT 13, 770 ' держит курс ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ FORpulseCount = 0 TO 24 ' Поверните налево, около 90 градусов ПУЛЬСАУТ 13, 650 ПУЛЬСАУТ 12, 650 ПАУЗА 20 СЛЕДУЮЩИЙ ВОЗВРАЩАТЬСЯ
Калибровка правого поворота на 90°
Калибровка Boe-Bot для выполнения правого поворота на 90° работает так же, как и калибровка левого поворота.
' MazeNavigation_LeftTurn.bs2 ' Boe-Bot поворачивает налево на основе значений QTI. ' {$ШТАМП БС2} ' {$PBASIC 2.5} qtis VAR Nib ' qti черно-белые состояния pulseCount VAR Byte ' FOR..NEXT счетчик цикла для поворота OUTB = %1111 ' Установить биты OUTB в 1 DO ' Main DO...LOOP GOSUB Check_Qtis ' Получить состояния QTI SELECT qtis ' Управление скоростью/направлением сервопривода CASE %0110 ' Прямо вперед ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛУЧАЙ %0111 GOSUB Turn_Right CASE ELSE ' Ничего не делать ПАУЗА 3 КОНЕЦВЫБОР ПЕТЛЯ Check_Qtis: ' Проверяет состояние каждого датчика QTI. 0 означает белую поверхность, 1 означает черную DIRB = %1111 ' P7..P4 -> вывод ПАУЗА 0 ' Задержка = 230 мкс DIRB = %0000 ' P7..P4 -> ввод ПАУЗА 0 ' Задержка = 230 мкс qtis = INB ' Сохранение выходных данных QTI в INB ВОЗВРАЩАТЬСЯ Поверните направо: FOR pulseCount = 0 TO 15 ' Продвиньтесь немного вперед, чтобы Boe-Bot PULSOUT 13, 770 ' держит курс ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ FORpulseCount = 0 TO 24 ' Поверните направо, около 90 градусов ПУЛЬСАУТ 13, 850 ПУЛЬСАУТ 12, 850 ПАУЗА 20 СЛЕДУЮЩИЙ ВОЗВРАЩАТЬСЯ
Калибровка Т-образного пересечения
Итак, что происходит, когда Boe-Bot сталкивается с Т-образным пересечением? Одно из решений, которое мы будем здесь использовать, состоит в том, чтобы запрограммировать Boe-Bot на принятие случайного решения, когда он достигает Т-образного перекрестка. Мы можем сделать это, сгенерировав псевдослучайное число, а затем повернув его влево или вправо на основе одного бита этого случайного числа (0 или 1).
В MazeNavigation_TIntersection.bs2 псевдослучайное число в диапазоне от 0 до 65535 генерируется каждый раз в основном цикле с помощью команды RANDOM. Взглянув на один бит этого числа, Boe-Bot может повернуться влево или вправо в зависимости от того, равно ли значение этого бита 0 или 1.
Зачем использовать команду RANDOM в основном цикле, а не в подпрограмме T_Intersection?
При каждом использовании команды RANDOM создается псевдослучайное число. Это означает, что даже если сгенерированное число кажется случайным, на самом деле оно генерируется с помощью логической операции, использующей начальное значение («начальное число») в переменной с именем rng для «подключения» к последовательности из 65535 по существу случайных чисел. Таким образом, если бы команда RANDOM rng была помещена в подпрограмму T_Intersection, использовалось бы одно и то же значение rng, каждый раз генерируя одну и ту же последовательность значений. Однако если поместить эту команду в процедуру Main, значение rng будет меняться каждый раз в цикле, создавая более желательный набор псевдослучайных чисел.
Для получения дополнительной информации см. команду RANDOM в BASIC Stamp Syntax and Reference Manual или в справке BASIC Stamp Editor.
Используя MazeNavigation_TIntersection.bs2, выполните следующие тесты:
- Запустите код и используйте терминал отладки, чтобы убедиться, что вы каждый раз получаете псевдослучайные результаты.
- Нажмите кнопку сброса и двигайте Boe-Bot по прямой, пока он не достигнет Т-образного перекрестка
- Повторите этот процесс несколько раз и убедитесь, что результаты поворота меняются каждый раз при достижении Т-образного перекрестка.
' MazeNavigation_TIntersection.bs2 ' Когда все датчики QTI обнаруживают черную линию, Boe-Bot случайным образом решает 'повернуться налево или направо. Этот код имитирует решение, печатая «Turn ' Левый!" или "Поверни направо!" к терминалу отладки. ' {$ШТАМП БС2} ' {$PBASIC 2.5} rng VAR Word 'случайное число turnDecision VAR rng.BIT0 ' Bit0 случайного числа qtis VAR Nib ' qti черно-белые состояния OUTB = %1111 ' Установить биты OUTB в 1 DEBUG CLS ' Очистить экран отладки DO ' Main DO...LOOP GOSUB Check_Qtis ' Получить состояния QTI RANDOM rng ' Создать случайное число SELECT qtis ' Управление скоростью/направлением сервопривода CASE %0110 ' Прямо вперед ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛУЧАЙ %1111 GOSUB T_Intersection CASE ELSE ' Ничего не делать ПАУЗА 3 КОНЕЦВЫБОР ПЕТЛЯ Check_Qtis: ' Проверяет состояние каждого датчика QTI. 0 означает белую поверхность, 1 означает черную DIRB = %1111 ' P7..P4 -> вывод ПАУЗА 0 ' Задержка = 230 мкс DIRB = %0000 ' P7. .P4 -> ввод ПАУЗА 0 ' Задержка = 230 мкс qtis = INB ' Сохранение выходных данных QTI в INB ВОЗВРАЩАТЬСЯ T_Intersection: ЕСЛИ (turnDecision = 0), ТО ОТЛАДКА "Поверни направо!", CR ПАУЗА 100 ИНАЧЕ ЕСЛИ (turnDecision = 1) ТО ОТЛАДКА "Поверни налево!", CR ПАУЗА 100 КОНЕЦ ВОЗВРАЩАТЬСЯ
Навигация в тупике и «искусственный интеллект»
Тупик — еще одно распространенное препятствие в лабиринтах, и существует множество различных подходов к решению этой проблемы. Приведенная ниже программа обрабатывает это следующим образом: Boe-Bot будет пятиться назад, пока не достигнет поворота, ведущего в тупик, а затем выполнит поворот на 90°, чтобы вернуться на путь лабиринта.
А что тогда? Boe-Bot все же сделал еще один поворот, который привел его в тупик, и если он снова сделает этот поворот, он вернется к началу, а не продолжит движение до конца. Одним из способов решения этой проблемы было бы создание новой переменной. Назовем его «ИИ». Когда эта переменная равна 1, Boe-Bot будет игнорировать левый поворот, который вернет его в начало. Создав новую подпрограмму с именем AI_Decision, Boe-Bot может выполнять левые повороты на основе значения переменной AI.
Используйте следующий код, чтобы убедиться, что ваш Boe-Bot может успешно выйти из тупика. Помните, что может потребоваться некоторая настройка!
' MazeNavigation_DeadEnd.bs2 Boe-Bot отступает назад, пока не заметит поворот, а затем снова движется вперед. ' {$ШТАМП БС2} ' {$PBASIC 2.5} qtis VAR Nib ' qti черно-белые состояния AI VAR Byte ' "Искусственный интеллект" ' помнит тупики pulseCount VAR Byte ' FOR..NEXT счетчик цикла для поворота OUTB = %1111 ' Установить биты OUTB в 1 DO ' Main DO...LOOP GOSUB Check_Qtis ' Получить состояния QTI SELECT qtis ' Управление скоростью/направлением сервопривода CASE %0110 ' Прямо вперед ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛУЧАЙ %1110 GOSUB AI_Decision CASE %0000 ' Резервное копирование до следующего хода GOSUB Тупик CASE ELSE ' Ничего не делать ПАУЗА 3 КОНЕЦВЫБОР ПЕТЛЯ Check_Qtis: ' Проверяет состояние каждого датчика QTI. 0 означает белую поверхность, 1 означает черную DIRB = %1111 ' P7..P4 -> вывод ПАУЗА 0 ' Задержка = 230 мкс DIRB = %0000 ' P7..P4 -> ввод ПАУЗА 0 ' Задержка = 230 мкс qtis = INB ' Сохранение выходных данных QTI в INB ВОЗВРАЩАТЬСЯ AI_Decision: IF (AI = 1) THEN ' Если AI = 1, Boe-Bot оказался в тупике AI = 0 ' Установить для переменной AI значение 0 GOSUB Ignore_Turn ' Игнорировать поворот, который ведет к Start ELSEIF (AI = 0) THEN ' Если AI = 0, Boe-Bot не GOSUB Turn_Left ' тупик, так что можно повернуть налево. КОНЕЦ ВОЗВРАЩАТЬСЯ Игнорировать_поворот: FORpulseCount = от 0 до 50 ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ ВОЗВРАЩАТЬСЯ Поверните налево: FOR pulseCount = 0 TO 15 ' Продвиньтесь немного вперед, чтобы Boe-Bot остался PULSOUT 13, 770 ' на курсе. ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ FORpulseCount = 0 TO 17 ' Поверните налево, около 90 градусов ПУЛЬСАУТ 13, 650 ПУЛЬСАУТ 12, 650 ПАУЗА 20 СЛЕДУЮЩИЙ ВОЗВРАЩАТЬСЯ Тупик: ДЕЛАТЬ GOSUB Check_Qtis ПУЛЬСАУТ 13, 730 ПУЛЬСАУТ 12, 770 ПАУЗА 20 LOOP ДО (qtis = %0111) ЕСЛИ (qtis = %0111) ТО ПАУЗА 20 FORpulseCount = от 0 до 15 ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ FORpulseCount = от 0 до 17 ПУЛЬСАУТ 13, 850 ПУЛЬСАУТ 12, 850 ПАУЗА 20 СЛЕДУЮЩИЙ КОНЕЦ ИИ = 1 ВОЗВРАЩАТЬСЯ
Держите Boe-Bot на ходу!
Последним этапом калибровки будет написание кода, который удерживает Boe-Bot по центру изоленты, поскольку есть несколько факторов, которые могут сбить его с курса: не идеально прямая лента, проскальзывание во время поворотов и т. д. Имейте в виду, что коррекция линии может быть затруднена при навигации по лабиринтам, поскольку существует множество различных способов, которыми Boe-Bot может сбиться с пути, и каждый ответ будет другим. В приведенном ниже решении всякий раз, когда Boe-Bot обнаруживает, что он сбился с курса, он реагирует следующим образом:
- Стоп.
- Медленно вращайте, пока оба средних датчика не вернутся на линию.
- Слегка поверните влево/вправо в зависимости от того, в какую сторону Boe-Bot сбился с пути.
- Слегка поверните в другом направлении, чтобы Boe-Bot снова отцентрировался на линии.
Этот код прошел несколько итераций калибровки, тестирования, повторной калибровки, повторной проверки и т. д. Поскольку значения могут быть совершенно разными, вам также может потребоваться пройти несколько итераций проверки и повторной калибровки. Имейте в виду, что эти шаги необходимы для успешного прохождения линии через лабиринт, поскольку центральные датчики должны быть на линии при движении вперед. Выполните следующие шаги, чтобы убедиться, что Boe-Bot может оставаться в центре пути лабиринта:
- Начните с крайнего левого датчика на изоленте и посмотрите, сколько времени потребуется Boe-Bot, чтобы отцентрироваться на линии.
- Если вы обнаружите, что Boe-Bot корректирует недостаточно быстро, попробуйте увеличить продолжительность импульса в циклах FOR. ..NEXT.
- С другой стороны, если вы обнаружите, что Boe-Bot поворачивается слишком далеко, попробуйте уменьшить продолжительность импульса в циклах FOR…NEXT.
- Повторите действия с крайним правым датчиком, крайним левым и средним левым датчиками, а также крайним правым и средним правым датчиками.
- Когда эти значения кажутся приемлемыми, попробуйте сдвинуть плакат, чтобы Boe-Bot сбился с пути, и посмотрите, как быстро он отреагирует.
' MazeNavigation_StayOnStripe.bs2 Программа калибровки для удержания Boe-Bot на пути изоленты. ' {$ШТАМП БС2} ' {$PBASIC 2.5} qtis VAR Nib ' qti черно-белые состояния pulseCount VAR Word ' FOR...NEXT счетчик циклов для плавного ' превращение. OUTB = %1111 ' Установить биты OUTB в 1 DO ' Main DO...LOOP GOSUB Check_Qtis ' Получить состояния QTI SELECT qtis ' Управление скоростью/направлением сервопривода CASE %0110 ' Обнаружены средние левый и правый датчики, идите вперед ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 730 ПАУЗА 20 CASE %1000 ' Обнаружен крайний левый датчик GOSUB BackOnTrack_OneSensorLeft CASE %1100 ' Обнаружены дальний и средний левый датчики GOSUB BackOnTrack_TwoSensorsLeft CASE %0001 ' Обнаружен крайний правый датчик GOSUB BackOnTrack_OneSensorRight CASE %0011 ' Обнаружен дальний и средний правый датчик GOSUB BackOnTrack_TwoSensorsRight CASE ELSE ' Ничего не делать ПАУЗА 3 КОНЕЦВЫБОР ПЕТЛЯ Check_Qtis: ' Проверяет состояние каждого датчика QTI. 0 означает белую поверхность, 1 означает черную DIRB = %1111 ' P7..P4 -> вывод ПАУЗА 0 ' Задержка = 230 мкс DIRB = %0000 ' P7..P4 -> ввод ПАУЗА 0 ' Задержка = 230 мкс qtis = INB ' Сохранение выходных данных QTI в INB ВОЗВРАЩАТЬСЯ BackOnTrack_OneSensorLeft: PULSOUT 13, 750 ' Стоп ПУЛЬСАУТ 12, 750 DO ' Медленно вращайте до середины GOSUB Check_Qtis ' QTI снова в деле ПУЛЬСАУТ 13, 750 ПУЛЬСАУТ 12, 740 ПАУЗА 20 LOOP ДО (qtis = %0110) IF (qtis = %0110) THEN ' Когда вернутся средние QTI FOR pulseCount = 1 TO 20 ' в строке, поверните влево для PULSOUT 13, 750 ' 20 импульсов, а затем повернуть вправо PULSOUT 12, 740 ' для 10 импульсов для центрирования Boe- ПАУЗА 20 ' Бот на линии. СЛЕДУЮЩИЙ FORpulseCount = от 0 до 10 ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 750 ПАУЗА 20 СЛЕДУЮЩИЙ КОНЕЦ ВОЗВРАЩАТЬСЯ BackOnTrack_TwoSensorsLeft: PULSOUT 13, 750 ' Стоп ПУЛЬСАУТ 12, 750 ДЕЛАТЬ GOSUB Check_Qtis ' Медленно вращайте до середины PULSOUT 13, 750 ' QTI снова в деле ПУЛЬСАУТ 12, 740 ПАУЗА 20 LOOP ДО (qtis = %0110) IF (qtis = %0110) THEN ' Когда вернутся средние QTI FOR pulseCount = 1 TO 20 ' в строке, поверните влево для PULSOUT 13, 750 ' 20 импульсов, а затем повернуть вправо PULSOUT 12, 730 ' для 10 импульсов для центрирования Boe- ПАУЗА 20 ' Бот на линии. СЛЕДУЮЩИЙ FORpulseCount = от 0 до 10 ПУЛЬСАУТ 13, 770 ПУЛЬСАУТ 12, 750 ПАУЗА 20 СЛЕДУЮЩИЙ КОНЕЦ ВОЗВРАЩАТЬСЯ BackOnTrack_OneSensorRight: PULSOUT 13, 750 ' Стоп ПУЛЬСАУТ 12, 750 ДЕЛАТЬ GOSUB Check_Qtis ' Медленно вращайте до середины PULSOUT 13, 760 QTI снова в деле ПУЛЬСАУТ 12, 750 ПАУЗА 20 LOOP ДО (qtis = %0110) IF (qtis = %0110) THEN ' Когда вернутся средние QTI FOR pulseCount = 1 TO 20 ' в строке, поверните вправо для PULSOUT 13, 760 ' 20 импульсов, а затем повернуть влево PULSOUT 12, 750 ' для 10 импульсов для центрирования Boe- ПАУЗА 20 ' Бот на линии. СЛЕДУЮЩИЙ FORpulseCount = от 0 до 10 ПУЛЬСАУТ 13, 750 ПУЛЬСАУТ 12, 730 ПАУЗА 20 СЛЕДУЮЩИЙ КОНЕЦ ВОЗВРАЩАТЬСЯ BackOnTrack_TwoSensorsRight: PULSOUT 13, 750 ' Стоп ПУЛЬСАУТ 12, 750 ДЕЛАТЬ GOSUB Check_Qtis ' Медленно вращайте до середины PULSOUT 13, 760 QTI снова в деле ПУЛЬСАУТ 12, 750 ПАУЗА 20 LOOP ДО (qtis = %0110) IF (qtis = %0110) THEN ' Когда вернутся средние QTI FOR pulseCount = 1 TO 20 ' в строке, поверните вправо для PULSOUT 13, 770 ' 20 импульсов, а затем повернуть влево PULSOUT 12, 750 ' для 10 импульсов для центрирования Boe- ПАУЗА 20 ' Бот на линии.