Робот для решения лабиринтов на Arduino с ИИ и Bluetooth
Компоненты и материалы
| Arduino Nano R3 | ×1 |
| Bluetooth-модуль HC-06 | ×1 |
| Модуль датчика линии TCRT5000 4-канальный | ×1 |
| Датчик линии SparkFun RedBot | ×1 |
| Рефлективные ИК-датчики ZX03 (на базе TCRT5000), аналоговые | ×2 |
| Android-устройство | ×1 |
| Сервоприводы непрерывного вращения RobotGeek | ×2 |
| Короб для 4×АА батареек | ×2 |
Приложения и онлайн-сервисы
- Arduino IDE
- MIT App Inventor 2
О проекте
Введение
Это руководство развивает мой предыдущий проект: «Робот слежения за линией — ПИД-управление — настройка через Android». Следующий логический шаг — наделить робота интеллектом. Наш «Рекс-робот» теперь будет искать выход из «лабиринта» по кратчайшему и быстрому пути (кстати, он ненавидит Минотавра).
В чем разница между лабиринтом (Maze) и логородом (Labyrinth)? По определению, лабиринт должен иметь выбор путей. Логород имеет единственный путь от входа к цели, как бы извилистым он ни был. Большинство лабиринтов формируются из одной непрерывной стены с множеством разветвлений. Если стена вокруг цели соединена с периметром у входа, лабиринт всегда решается правилом «левой руки» — держа руку на левой стене.
Проект состоит из двух проходов:
- Первый проход: Робот находит выход из неизвестного «идеального лабиринта» (без петель). Неважно, где он стартует — он найдет решение.
- Второй проход: После нахождения решения робот оптимизирует путь, движясь по кратчайшему маршруту от старта к финишу.
Шаг 1: Спецификация материалов
Список практически идентичен роботу слежения за линией, с добавлением 2 дополнительных датчиков для точного определения левых и правых поворотов. Итоговая стоимость ~$85.
Корпус: 2 деревянные планки 80×80 мм, 3 биндер-кліпса, 2 деревянных колеса (Ø50 мм), 1 опорное колесико, 9 резинок, крепеж 3M, пластиковые крепления для датчиков, макетная плата, проводка, 2 набора по 4 Ni-MH аккумулятора (по 5В), 2 сервопривода SM-S4303R, Arduino Nano, HC-06, 5 датчиков линии + 1 независимый, 2 датчика ZX03, 1 светодиод, 1 кнопка.
Примечание: использовал аналоговые датчики ZX03, так как не было цифровых. Идеально — иметь все датчики одинаковые. Протестировал с 5 датчиками — работает, но требует более тонкой настройки.
Шаг 2: Изменения в корпусе
Снимаем оригинальный набор из 5 датчиков и устанавливаем новые «дальние левый» и «дальний правый» рефлективных датчика по краям опорной планки. Желательно выровнять все 7 датчиков в одну линию.
Шаг 3: Установка и тест новых датчиков
Массив из 7 датчиков: 5 оригинальных — для ПИД-контроля и обнаружения «сплошной линии», 2 новых — исключительно для определения левых/правых поворотов.
Логика работы 5 цифровых датчиков: если датчик по центру черной линии — HIGH. Расчет расстояния между датчиками позволяет двум датчикам одновременно покрывать ширину линии.
2 новых аналоговых датчика: на черной линии вывод < 100 (АЦП 0–1023), на светлой поверхности — 500–600. Необходимо определить порог THRESHOLD для ваших условий.
Назначение пинов:
const int lineFollowSensor0 = 12; // Digital
const int lineFollowSensor1 = 18; // A4 as Digital
const int lineFollowSensor2 = 17; // A3 as Digital
const int lineFollowSensor3 = 16; // A2 as Digital
const int lineFollowSensor4 = 19; // A5 as Digital
const int farRightSensorPin = 0; // A0
const int farLeftSensorPin = 1; // A1
Чтение датчиков:
int LFSensor[5] = {0,0,0,0,0};
int farRightSensor = 0;
int farLeftSensor = 0;
LFSensor[0] = digitalRead(lineFollowSensor0);
LFSensor[1] = digitalRead(lineFollowSensor1);
LFSensor[2] = digitalRead(lineFollowSensor2);
LFSensor[3] = digitalRead(lineFollowSensor3);
LFSensor[4] = digitalRead(lineFollowSensor4);
farRightSensor = analogRead(farRightSensorPin);
farLeftSensor = analogRead(farLeftSensorPin);
Переменная mode определяет состояние: следование за линией, сплошная линия, поворот, отсутствие линии. Добавлены состояния дальних датчиков: H (выше порога), L (ниже порога), X (неважно).
Шаг 4: Решение лабиринта — правило левой руки
В 2D лабиринте существует 8 типов перекрестков. Применяя правило левой руки, действия сокращаются до одного варианта на каждый тип:
- Перекресток «Крест» → Налево
- Перекресток «T» → Налево
- Только направо → Направо
- Только налево → Налево
- Прямо или налево → Налево
- Прямо или направо → Прямо
- Тупик → Разворот (180°)
- Конец лабиринта → Стоп
Для точного определения типа перекрестка робот делает «дополнительный шаг» вперед и проверяет, есть ли линия дальше.
Шаг 5: Реализация алгоритма на Arduino
void loop() {
readLFSsensors();
switch (mode) {
case NO_LINE:
motorStop();
goAndTurn(LEFT, 180);
break;
case CONT_LINE:
runExtraInch();
readLFSsensors();
if (mode == CONT_LINE) mazeEnd();
else goAndTurn(LEFT, 90); // T или Cross
break;
case RIGHT_TURN:
runExtraInch();
readLFSsensors();
if (mode == NO_LINE) goAndTurn(RIGHT, 90);
break;
case LEFT_TURN:
goAndTurn(LEFT, 90);
break;
case FOLLOWING_LINE:
followingLine();
break;
}
}
void runExtraInch() {
motorPIDcontrol();
delay(extraInch);
motorStop();
}
void goAndTurn(int direction, int degrees) {
motorPIDcontrol();
delay(adjGoAndTurn);
motorTurn(direction, degrees);
}
На этом этапе робот уже решает лабиринт! Завершен «Первый проход».
Шаг 6: Запоминание пути
Пример: робот проходит 15 перекрестков: L, B, L, L, L, B, S, B, L, L, B, S, L, L, End.
Создаем массив для хранения пути:
char path[100] = "";
unsigned char pathLength = 0;
int pathIndex = 0;
Результат: path = [LBLLLBSBLLBSLL], pathLength = 14.
Шаг 7: Упрощение (оптимизация) пути
Анализ последовательностей с разворотом (B) показывает, что тройки «xBx» можно сократить до одного действия:
- LBR = B
- LBS = R
- RBL = B
- SBL = R
- SBS = B
- LBL = S
Применяя правила к примеру:
[LBLLLBSBLLBSLL] → LBL=S → [SLLBSBLLBSLL]
→ LBS=R → [SLRBLLBSLL] → RBL=B → [SLBLBSLL]
→ LBL=S → [SSBSLL] → SBS=B → [SBLL]
→ SBL=R → [RL]
Оптимизированный путь: Right, Left — робот доходит до цели за два поворота!
Функция simplifyPath() (автор Patrick McCabe) автоматически сокращает путь при каждом новом повороте.
Шаг 8: Второй проход — максимальная скорость
void loop() {
ledBlink(1);
readLFSsensors();
mazeSolve(); // Первый проход
ledBlink(2);
while (digitalRead(buttonPin)) {}
pathIndex = 0; status = 0;
mazeOptimization(); // Второй проход
ledBlink(3);
while (digitalRead(buttonPin)) {}
mode = STOPPED; status = 0;
pathIndex = 0; pathLength = 0;
}
void mazeOptimization() {
while (!status) {
readLFSsensors();
switch (mode) {
case FOLLOWING_LINE: followingLine(); break;
case CONT_LINE:
case LEFT_TURN:
case RIGHT_TURN:
if (pathIndex >= pathLength) mazeEnd();
else { mazeTurn(path[pathIndex]); pathIndex++; }
break;
}
}
}
void mazeTurn(char dir) {
switch(dir) {
case 'L': goAndTurn(LEFT, 90); break;
case 'R': goAndTurn(RIGHT, 90); break;
case 'B': goAndTurn(RIGHT, 800); break; // ~180°
case 'S': runExtraInch(); break;
}
}
Шаг 9: Настройка через Android
Приложение из проекта слежения за линией работает и здесь. Код прозрачен — можно не использовать приложение. Ключевые параметры для настройки:
const int adj = 0;
float adjTurn = 8;
int adjGoAndTurn = 800;
THRESHOLD = 150;
const int power = 250;
const int iniMotorPower = 250;
int extraInch = 200;
Шаг 10: Заключение
Вторая часть сложного проекта, исследующая потенциал робота-следопыта. Использованы базовые концепции ИИ для решения лабиринта. Файлы проекта на GitHub. Больше туториалов на MJRoBot.org.
Салудос из юга мира!
Marcelo
Код
Доступны фрагменты кода (12 штук) и полные файлы на GitHub. Основные функции: readLFSsensors(), mazeSolve(), simplifyPath(), mazeOptimization(), mazeTurn().
Схемы
Fritzing-файл схемы: z7IdLkxL1J66qOtphxqC.fzz
Производственный процесс
- Создание умного робота с Bridge Shield — интеграция Raspberry Pi и Arduino
- Жестово-управляемый робот на Raspberry Pi
- Построение Wi-Fi-управляемого робота на Raspberry Pi с Python — пошаговое руководство
- Интеграция Microsoft Kinect с Raspberry Pi для детекции людей в реальном времени на роботе Sonbi
- Bosch представляет ИИ‑решение для производства на Hannover Messe
- Искусственный интеллект в ритейле: доказанные выгоды, а не модная волна
- Kubernetes усиливает AI-стартапы масштабируемыми контейнеризированными решениями
- Роботы учатся узнавать 90+ объектов на ощупь: мультимодальный ИИ Berkeley
- ИИ для отслеживания вырубки лесов в Амазонке
- Робототехника на базе ИИ: передовая интеллектуальная машина