Как стать автором
Обновить
Selectel
IT-инфраструктура для бизнеса

Самодельная платформа для робототехники из бюджетного смартфона

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров15K

Привет, читатель!

С чем у вас ассоциируется современный смартфон? Производительное железо, много памяти, емкий аккумулятор и отличная камера. Все так. А еще у него есть множество датчиков для ориентирования в пространстве. По-моему, довольно странно не использовать относительно дешевое, доступное и популярное устройство в качестве платформы для роботов. В целях проверки гипотезы я решил собрать собственное устройство и рассказать, почему это круто.

Используйте навигацию, если не хотите читать текст полностью:

Введение
Элементарная схемотехника
Конструкция
Программное обеспечение
Заключение

Введение


Для создания небольших роботов существуют довольно популярные платформы. Они содержат минимальное количество датчиков, аккумуляторы и имеют собственное IDE. Вот некоторые наиболее известные.

Lego MindStorm


Это довольно известный набор, особенно в образовательных организациях. За счет самого конструктора позволяет собрать тысячи вариантов роботов, обвесить их различными исполнительными механизмами и датчиками (из стандартного набора), добавить контроллер и так далее. Так можно получить робота с уникальным дизайном и назначением. К сожалению, с 2022 года он снят с производства.

Забавный факт — на базе EV3 (последняя версия контроллера) запускали симуляцию мозга червя. Еще один факт — контроллеры MindStorm можно было программировать через LabVIEW.


Источник.

myRIO


Разработанная Texas Instruments отладочная плата для программируемой логической интегральной схемы (ПЛИС) с программированием на LabVIEW. Казалось бы, при чем здесь оценочная плата с ПЛИС? Однако, это долгое время было основной платформой для участия в WorldSkills Russia по мобильной робототехнике. В отличие от Lego здесь потребуются знания обработки сигналов и настройки различных регуляторов. Также плата позволяет реализовывать машинное зрение присоединением камеры по USB.


Пример робота на базе myRIO. Источник.

ROS


Не могу в рамках обзора обойти стороной операционную систему для роботов. Данная система (точнее, набор приложений) устанавливается на одноплатные компьютеры. Зачастую это Raspberry и другие pi. За счет ОС компьютеры управляют всей периферией. Операционка имеет огромный функционал и сопровождается мануалами, но все же необходимо потратить немало времени, чтобы все изучить.


Ровер под управлением ROS в Gazebo. Источник.

OpenBot


Также интересен OpenBot для самостоятельной сборки робота на базе Android-смартфона и Arduino. Приложение периодически обновляется. Текущая версия позволяет управлять небольшой машинкой с парой датчиков. Создавался как решение для автоматической навигации, использующей дешевый телефон в качестве «мозгов».


Вариант робота на базе телефона. Также есть пример из картона. Источник.

Мне нравится решение использовать телефон в качестве центральной платы для вычислений. Это компактное устройство для такого применения: он содержит датчики навигации и положения в пространстве, несколько интерфейсов связи и экран для отладки. Также можно использовать камеру для компьютерного зрения, распознавания кодов, езды по линии, определения препятствий и многого другого.

Основа новой платформы


Почему это будет не iPhone, думаю, понятно. Да, он обладает всеми теми же датчиками и средой разработки. Но стоимость телефона (даже б/у) будет значительно превосходить всю остальную рассыпуху. Телефоны на базе Android в этом плане отличная альтернатива: они простые и дешевые. Однако, я недостаточно погружен в Kotlin или Java, а последний опыт подключения телефона к внешним устройствам не увенчался у меня успехом.

В связи с этим мой выбор уже в который раз пал на ОС «Аврора»: доступна консоль, gcc, qt (со средой разработки от ОМП) и возможность подключения внешних устройств. Помимо запуска приложений на C++, на этом телефоне можно выполнять код Python, а также внедрена поддержка Kotlin и Rust.



Элементарная схемотехника


Единственный минус смартфона — отсутствие пинов ввода-вывода (GPIO). Зачастую это буквально три кнопки, которые назначены в системе на управление громкостью и блокировкой. Придется немного читерить и взять любую отладочную плату с конвертером USB-UART или же микроконтроллер с интерфейсом USB. Также обратиться можно к старой доброй V-USB.

Почему не беспроводное соединение? Можно и так. Это позволит гальванически развязать «силовую» часть и телефон и иногда снимать его с платформы для беспроводного управления. В таком случае я бы предложил использовать Bluetooth вместо Wi-Fi. Это даст возможность подключать телефон к маршрутизатору или использовать его в режиме точки доступа.

Конструкция


Первый прототип робота был самым быстрым — немного проводов, пара плат, два мотора и шар для точки опоры. Таким нехитрым образом получил простейшую машинку для езды по линии, ведь камера смотрит строго вниз.


Практически из спичек и желудей.

Для следующей версии (на КДПВ) взял простенькую платформу для мобильных роботов. У нее больше площадь конструкции, что позволяет разместить аккумуляторы и сам телефон, а также дает потенциал к размещению различных датчиков, например, лидара.

Программное обеспечение


Для тестов накидал простое приложение, которое позволяет машине ехать по координатам GPS. Список точек задается в таблице, считывается приложением в вектор после запуска и по достижению точек удаляется из вектора и переходит к следующей точке.

Верхний уровень — основная логика


После запуска приложения выполняется инициализация — читается файл с координатами, подготавливается USB-устройство.

Для реализации алгоритма удобно использовать существующие функции опроса GPS в телефоне. В общем виде платформа запрашивает текущую координату и вычисляет расстояние между целевой и текущей позицией. Если расстояние меньше эмпирически выверенного расстояния в 0,5 метра, то инкрементируется счетчик позиций. Не достигнув цели, роботу необходимо вычислить азимут до следующей точки, скорректировать свое направление по компасу и направиться далее.

if (actualStep < navPoints.size())
       {
           QGeoCoordinate nextPoint = navPoints.at(actualStep);
           angle = (int)actualPoint.azimuthTo(nextPoint);
           int diff = angle - getCompas();
           qreal dist = actualPoint.distanceTo(nextPoint);
           if (dist < 0.5)
           {
               qDebug() << "Found point at"
                        << nextPoint.latitude() << " "
                        << nextPoint.altitude();
               actualStep++;
               return 0;
           }
           robotMovemant(diff);
       }
       else
       {
           qDebug() << "Mission Complete!";
           robotStop();
       }
       return 0;

Это достаточно простой робот, который игнорирует факт существования препятствий (у него нет датчиков). Если захотите повторить, то я бы предложил именно в этом месте добавить алгоритм обхода препятствий.

Полученный угол преобразуется в направление для машинки. Координаты преобразуются в скорости для двигателей в значении от 0 до 512. Значение записывается в uint16_t-переменную. В таком случае первый байт отвечает за направление, второй — за скорость.

Далее через протокол данные передаются в плату через ранее описанную библиотеку CDCConnector. Обмен максимально простой: три байта аргументов, один байт для команды, контрольная сумма и три байта для указания завершения передачи:

<arg2> <arg1> <arg0> <cmd> <crc> 0xFF 0xFF 0xFF

Например:

0x00 0x01 0xF0 0x01 0xCF 0xFF 0xFF 0xFF

передает команду движения (0x01) со скоростью (0xF0, ШИМ заполнение 240 из 255) не инвертировано (0x01) левому двигателю (0x00).

Это реализуется следующим кодом:

int error = 0;
unsigned char packet[8] = {0, 0, 0, 0x01, 0, 0xFF, 0xFF, 0xFF};
int pwrR = SPD_CONST + (int)val;
packet[2] = side;
packet[0] = pwrR >> 8;
packet[1] = pwrR & 0xFF;
packet[3] = calcCRC (packet);
error = uDev.sendBytes(packet, 8);

Нижний уровень — манипулирование электроникой


Несмотря на то, что wiring arduino предоставляет широкие возможности для управления периферией и переносимый на множество платформ код, нередко лучше потратить время и изучить работу чипов на более низком уровне. Например, есть analogWrite. Зачастую эта функция формирует широтно-импульсно модулированный (ШИМ) сигнал, скважность которого определяет выходной уровень. Однако эта функция работает на относительно низкой частоте (490 Гц), так как жестко привязана ко времени. На такой частоте будет слышен неприятный писк от электродвигателей.

Во время подготовки статьи наткнулся в исходном коде Arduino на функцию работы analogWrite. Меня позабавило решение выставления минимального и максимального значения в Arduino:

void analogWrite(uint8_t pin, int val)
{
…
    pinMode(pin, OUTPUT);
    if (val == 0)
    {
        digitalWrite(pin, LOW);
    }
    else if (val == 255)
    {
        digitalWrite(pin, HIGH);
    }
    else
…

То есть вместо записи в регистр 0 или 255 контроллер просто выставляет сигнал 0 или 1 на контакт.

Избежать этих неприятных моментов можно, если использовать аппаратные возможности микроконтроллера. На эту тему написано множество статей. На тему ШИМ мне нравится инструкция от Алекс Гайвера — здесь даны минимальные конфигурации. Однако, для установки я предпочту запись в регистр напрямую:

TCCR2B = 0b00000001; //x1
TCCR2A = 0b10100001; // phase correct
OCR2A = 0; //запись значения 0 - двигатели стоят
OCR2B = 0;

После настройки регистров необходимо обработать полученное сообщение и задать уставку на ШИМ. Для этого в первую очередь определяем направление и, если необходимо ехать назад (значение скорости меньше 256), вычитаем константу для получения целевой скорости.

void move(uint8_t side, uint8_t dir, uint8_t val) {
    uint8_t speed = fast_map(dir ? val : 255 - val , 0, 255, 160, 255); //160 подобран для используемой микросхемы-драйвера
    uint8_t moveOption = side << 1 | dir;
    switch (moveOption) {
    case 0b00: //левый назад
        OCR0B = 0;
        OCR2B = speed;
        break;
    case 0b01: //левый вперед
        OCR0B = speed;
        OCR2B = 0;
        break;
…
}

После сборки всех частей в одно целое получился забавный, но функциональный прототип робота для навигации в пространстве. Именно он на КДПВ. Он не такой умный и «чувствительный», как робот-доставщик Яндекса, но тем не менее является основой, которую можно сильно прокачать.

Интерфейс управления



Когда тестировали подключение телефона к «тележке» в ИТМО, потребовался ручной режим для управления мощностью, остановки и включения автономного режима навигации, т. к. этот прототип тяжелее и просто поднять его не получится. Благодаря нативному QML весь интерфейс за 20 минут был готов и общался с роботом. Из нюансов — необходимо было передать ссылку на экземпляр робота:

view->rootContext()->setContextProperty("geoBot", &geoBot);

Заключение


Мы попробовали подключить телефон к прототипу разрабатываемой в ИТМО мобильной платформы. Чтобы адаптировать решение, достаточно переписать существующий микроконтроллер на получение команд от телефона. Сначала лениво и неохотно, но затем довольно шустро прототип поехал в указанном направлении.

Датчики телефона оказались очень чувствительными. Компас реагировал на железный каркас и сбивалась калибровка. Чтобы протестировать сам подход, пришлось поднять телефон и нести его над «машинкой».

Теоретически телефон в качестве «мозга» мобильной платформы — довольно эффективное и сравнительно дешевое решение, которое может быть подключено к существующим системам по распространенным интерфейсам. «Аврора» мне нравится за счет применения привычного ЯП, удобной среды, множества встроенных функций и API. Кажется, это может стать довольно удачным решением в образовательной среде. Если рассматривать ее как основную ОС для промышленных решений, то однозначный плюс — это использование центра и маркета приложений. Систему роботов можно будет централизованно обновлять и проверять, а встроенная защита не даст установить стороннее ПО с нарушенной целостностью.
Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
+74
Комментарии30

Публикации

Информация

Сайт
slc.tl
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия
Представитель
Влад Ефименко