Рейтинг@Mail.ru

Делаем управление Arduino-роботом от первого лица

Автор: Alex. Опубликовано в Копилка . просмотров: 386

Рейтинг:  0 / 5

Звезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активна
 

Последняя версия приложения RoboCam позволяет управлять не только роботами EV3, но и роботами, построенными на таких платформах, как Arduino, Raspberry Pi и других аналогичных, где имеется возможность напрямую работать с данными поступающими и отправляемыми через Bluetooth. Теперь команды приложения RoboCam, вы сможете обрабатывать так, как пожелаете.

Делаем управление Arduino-роботом от первого лица

Статья описывает новые возможности, появившиеся в приложении RoboCam в версии 1.3.1. Все статьи посвященные приложению RoboCam вы можете найти здесь. Приложение RoboCam можно установить из магазина Google Play.

Всё, что было сделано в предыдущих версиях для EV3, осталось без изменений. В новой версии добавлены только драйвер и настройки для взаимодействия с роботами, которые могут напрямую получать команды от приложения RoboCam через Bluetooth, обрабатывать их и возвращать ответы. Таких роботов можно делать с помощью различных платформ (Arduino, Raspberry Pi, PC) и управляться они могут различными прошивками и операционными системами (стандартная прошивка Arduino, Windows, Linux, Android и т.п.). Программа для взаимодействия с приложением RoboCam также может быть написана с помощью различных языков программирования.

Поскольку прошивка или операционная система робота может быть разная, то ниже я опишу только протокол взаимодействия с приложением RoboCam, появившиеся настройки и дам пример программы для управления колёсным роботом с управляемым держателем смартфона для платформы Arduino.

Роботов, описанных выше, здесь в статье и в настройках будем называть нестандартными.

Вот видео, на котором с помощью приложения RoboCam управляется Arduino-робот от первого лица. Ниже в статье будет описано, как и с помощью чего сделать такого робота.

Взаимодействие приложения RoboCam и робота

Первое, что нужно сделать, чтобы приложение RoboCam и робот начали взаимодействовать, это программно подключиться к Bluetooth-модулю и ждать, пока от него не начнут приходить данные. Во всех системах это происходит по-разному, и описать это в рамках одной статьи невозможно. Поэтому я буду приводить примеры только для платформы Arduino, и конкретно для конфигурации Arduino Uno + Bluetooth-модуль HC-06. При этом будем считать, что модуль HC-06 имеет настройки по умолчанию (скорость 9600 бод) и подключен стандартным образом (контакт RX модуля подключен к контакту TX Arduino Uno, а контакт TX модуля подключен к контакту RX Arduino Uno). В случае стандартного подключения, вся работа с Bluetooth в Arduno идёт через серийный порт с адресом 9600. Программно, инициализация порта выглядит так:

void setup()
{
    Serial.begin(9600);
}

Как видите всё просто. После этого вы можете считывать и отправлять данные через Bluetooth. В Arduino это делается с помощью функций класса Serial, таких как read(), write(),available() и др.

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

На каждое сообщение с командой ваша программа должна как можно быстрее ответить. Ведь чем дольше ваша программа отвечает, тем хуже в конечном итоге будет отклик вашего робота на действия пользователя.

Ответ на каждое сообщение ожидается в течении одной секунды. Задержку ответа более чем на секунду, приложение RoboCam приравнивает к ошибке.

Каждое сообщение – это определённый набор байт. В первых двух байтах содержится число, указывающее размер сообщения в байтах. При этом, эти первые два байта сообщением не считаются. Т.е. если в первых двух байтах указано число 5, то это значит, что за ними следуют ещё 5 байт, которые, как раз, и являются сообщением. Поэтому считывание сообщение делается следующим образом: сначала вы считываете первые 2 байта, преобразуете их в целое беззнаковое двухбайтное число, а затем считываете ещё столько байт, сколько указано в этом числе. Вот пример считывания размера сообщения в Ardiono:

//В переменной messageSize будем хранить размер сообщения.
unsigned int messageSize = 0;
//Проверяем, можно ли считать два байта из серийного порта.
if (Serial.available() > 1)
    //Считываем размер сообщения в переменную messageSize.
    messageSize = Serial.read() + (Serial.read() << 8);

После этого можно считать всё сообщение в массив, например, так:

//Переменную readMessageBytes будем использовать как счётчик считанных байт.
unsigned int readMessageBytes = 0;
//Проверяем, все ли байты сообщения считаны и есть ли данные в серийном порте.
while (readMessageBytes < messageSize && Serial.available() > 0)
{
    //Считываем один байт.
    message[readMessageBytes] = Serial.read();
    //Увеличиваем значение счётчика считанных байт на 1.
    readMessageBytes++;
}

В примере выше сделан выход из цикла, если в серийном порту нет доступных для считывания данных. Т.е. мы не ждём, пока сообщение будет полностью считано. При таком подходе мы будем считывать сообщение по мере поступления данных и параллельно делать что-то ещё в бесконечном цикле нашего Arduino-скетча в функции loop().

После того как сообщение считано (в примере выше это наступит если значение переменной readMessageBytes станет равным значению переменной messageSize) его можно разбирать, а после разбора и отправки ответа, снова считывать следующее сообщение и так далее.

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

//Допустим, в переменной replySize хранится размер сообщения с ответом.
unsigned int replySize = 0;
//А в массиве reply хранятся байты ответа.
byte reply[20]; 
//Формируем ответ и кладём его в массив reply.
//Параллельно считаем размер ответа в байтах и кладём его в переменную replySize.
...
//Сначала отправляем размер сообщения.
Serial.write(replySize & 0xFF);
Serial.write((replySize >> 8) & 0xFF);
//Затем отправляем заготовленное сообщение.
Serial.write(reply, replySize);

Содержимое сообщений

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

        • 0 – команда «Старт»;
        • 1 – команда «Позывной»;
        • 2 – команда «Контроллеры»;
        • 3 – команда «Тест»;
        • 255 – команда «Стоп».

Для удобства в вашей программе лучше сразу объявить константы для команд (дальше в статье я буду использовать имена этих констант для удобства):

const byte CMD_START = 0; 
const byte CMD_CALLSIGN = 1;
const byte CMD_CTRL = 2;
const byte CMD_TEST = 3;
const byte CMD_STOP = 255;

На каждую полученную команду робот должен ответить. Как уже была написано выше, ответ – это тоже сообщение. Первый байт сообщения (конечно же после двух байт с размером сообщения) - это результирующий код. Есть ли следующие байты и их содержимое зависит от команды, для которой делается ответ.

Результирующий байт может принимать всего два значения:

        • 0 – команда выполнена успешно;
        • 1 – ошибка при выполнении команды или команда не поддерживается.

Теперь рассмотрим команды и ответы на них подробнее.

Команда «Старт» (CMD_START)

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

Итак, вот какие байты приходят в сообщении с командой CMD_START:

SSCTV

Здесь одна буква обозначает один байт:

        • Первые два байта SS – это размер сообщения, т.е. количество байт идущих в сообщении, после этих двух байт.
        • Затем идёт байт C содержащий код команды. В нашем случае здесь будет 0, т.е. команда CMD_START.
        • Следующий байт T – это проверочный байт. Значение этого байта каждый раз будет разным в интервале от 0 до 254. Что делать с этим значением будет написано чуть ниже.
        • В самом конце идёт байт V с номером максимально поддерживаемой версии протокола взаимодействия со стороны приложения RoboCam. В настоящий момент – это 1.

Вот пример сообщения с командой CMD_START в восьмеричной системе счисления:

030000D101

Получив эту команду, ваш робот должен ответить в течении 1 секунды. Ответ тоже представляет собой массив байт и должен быть следующим:

SSRTVC

Здесь я также обозначил один байт одной буквой. Вот что передаётся в байтах:

        • Первые два байта SS – это размер сообщения. Ответ – это тоже сообщение, поэтому здесь тоже первые два байта содержат размер массива, который идёт за этими двумя байтами.
        • Следующий байт R – это тип результата. 0 – команда выполнена роботом успешно, 1 –ошибка. Если вы указываете здесь 1 (т.е. ошибка), то остальные байты в сообщении можно не передавать.
        • Байт T – это ответ на проверочный байт. Здесь должно быть число на 1 больше того, которое вы получили с командой CMD_START. В примере выше указано число D1 (209 в десятичной системе счисления), значит, в ответ на него, нужно прислать число D2 (210).
        • Следующий байт V – это версия протокола общения, которую будет использовать робот. Номер версии здесь не должен быть выше, чем номер версии, которую вы получили с командой CMD_START, иначе приложение RoboCam откажется работать с роботом и выдаст ошибку. В настоящий момент здесь нужно указать 1.
        • Последний байт C – это кодировка, в которой будут передаваться строки. Здесь есть всего два варианта: 0 – кодировка US-ASCII (нет русских букв) и 1 - кодировка UTF-8. Кодировка US-ASCII используется в Arduino.

Вот пример ответа на команду CMD_START:

040000D20100

Команда «Позывной» (CMD_CALLSIGN)

После того как в ответ на команду CMD_START приложение RoboCam получит ответ без ошибки, в котором будет правильно указаны проверочный байт, номер версии протокола и кодировка, начнётся дальнейшее общение между роботом и приложением RoboCam. А именно сразу после этого роботу придёт команда CMD_CALLSIGN. Правда это случится только в том случае, если в настройках RoboCam указан позывной и ответ на него. Если позывной или ответ не указан, то эта команда не придёт. На картинке снизу, для примера, в настройках указан позывной «RoboCam» и ответ «Researcher».

Настройка позывного и ответа для робота

Выглядит сообщение с командой CMD_CALLSIGN так:

SSСAAA…0

        • В первых двух байтах SS содержится размер сообщения, как и для остальных команд.
        • Следующим байтом C идёт код команды. Для команды CMD_CALLSIGN здесь будет 1.
        • В остальных байтах AAA…0 идёт строка с завершающим 0, содержащая позывной, который вы указали в настройках. Кодировка строки будет соответствовать той, что вы указали в ответе на команду CMD_START.

Пример команды CMD_CALLSIGN с позывным «RoboCam» в кодировке US-ASCII выглядит так:

090001526F626F43616D00

В ответ на эту команду нужно послать строку с ответом на позывной, которая указана в настройках RoboCam. Если в ответ придёт какая-то другая строка, то RoboCam разорвёт подключение. Ответное сообщение выглядит следующим образом:

SSRAAA…0

        • Первые два байта SS как и для других ответов – это размер сообщения.
        • Следующий байт R – это тип результата: 0 – позывной принят, 1 – ошибка. Если вы вернёте здесь 1, то остальные байты в сообщении можно не передавать.
        • В остальных байтах AAA…0 идёт строка с завершающим 0, содержащая ответ на позывной. Кодировка строки соответствует той, что вы указали в ответе на команду CMD_START.

Пример с ответом «Researcher»на позывной выглядит так:

0C00005265736561726368657200

Команда «Контроллеры» (CMD_CTRL)

После того как произошло подключение приложения RoboCam к вашей программе и после команд CMD_START и CMD_CALLSIGN, начнут приходить команды CMD_CTRL. Это команды от контроллеров, с помощью которых пользователь управляет роботом, т.е. джойстики и клавиатура. Команды будут приходить каждый раз, когда меняется координата точки прикосновения пальца пользователя к джойстику или статус клавиши (нажата/не нажата), т.е. когда пользователь управляет роботом. Команды будут приходить только, если координаты изменились или изменился статус клавиши (нажата/отпущена) на клавиатуре.

Сообщение с командой CMD_CTRL выглядит следующим образом:

SSCJVJVJV…

        • Первые два байта SS – размер сообщения.
        • Байт C – это команда. Для команды CMD_CTRL здесь будет 2.
        • Следующих байты JVJVJV… - это информация об изменении состояния контроллеров. Здесь может идти одна и более пар байт. Вот что значат байты в паре:
          • Байт J – это идентификатор контроллера. Вот какие значения может принимать этот байт, и что это значение обозначает:
            • 0 – ось X (горизонтальная ось 1-го джойстика);
            • 1 – ось Y (вертикальная ось 1-го джойстика);
            • 2 – ось W (горизонтальная ось 2-го джойстика);
            • 3 – ось Z (вертикальная ось 2-го джойстика);
            • 4 – ось A (горизонтальная ось 3-го джойстика);
            • 5 – ось B (вертикальная ось 3-го джойстика);
            • 6 – ось C (горизонтальная ось 4-го джойстика);
            • 7 – ось D (вертикальная ось 4-го джойстика);
            • 255 – нажатая клавиша;
            • 254 – не нажатая клавиша.
          • Байт V принимает значение в зависимости от байта J:

Пример команды CMD_CTRL (команда означает, что по оси X координата приняла значение 90, по оси Y – значение -100 и нажалась клавиша с кодом 89, т.е. клавиша Y):

060002005A019CFF59

Для удобства в коде программы лучше сразу определить константы для идентификаторов контроллеров:

//Оси джойстиков.
const byte AXIS_X = 0;
const byte AXIS_Y = 1;
const byte AXIS_W = 2;
const byte AXIS_Z = 3;
const byte AXIS_A = 4;
const byte AXIS_B = 5;
const byte AXIS_C = 6;
const byte AXIS_D = 7;
 
//Состояние клавиши.
const byte KEY_PRESSED = 255; //Клавиша нажата.
const byte KEY_RELEASED = 254; //Клавиша не нажата.

Когда ваша программа получает команду CMD_CTRL, вы сразу узнаёте что произошло с джойстиками и клавишами. При этом вы можете сразу поменять направление движения робота, повернуть на нужный угол сервопривод и т.п. После обработки команды вы обязательно должны отправить ответ, это следующие байты:

SSR

        • SS – это размер сообщения. Здесь всегда будет 1, т.к. в ответе всегда только один байт.
        • R – результат: 0 – ошибки нет, 1 – ошибка. На самом деле команда CMD_CTRL игнорирует результат, но всё равно ждёт сообщение с ответом. Тем не менее, здесь рекомендуется всегда возвращать 0.

Вот так будет выглядеть ответ:

010000

Команда «Тест» (CMD_TEST)

Команда CMD_TEST присылается с периодичностью примерно в 1 секунду, для проверки соединения. Если робот не отвечает на эту команду, то приложение RoboCam считает, что связь с роботом потеряна. Сот как выглядит сообщение с командой CMD_TEST:

SSC

        • Байты SS – это размер сообщения. Для команды CMD_TEST размер всегда будет 1.
        • Байт C – это код команды, в данном случае – 3.

Вот пример сообщения с командой CMD_TEST:

010003

Ответить на команду CMD_TEST вы должны в течении 1 секунды, иначе приложение RoboCam посчитает, что связь с роботом потеряна. Формат ответа должен быть следующим:

SSR

        • Байты SS – это размер сообщения.
        • Байт R – это результат: 0 – команда успешно обработана, 1 – ошибка. Если вы вернёте здесь 1, то приложение RoboCam посчитает, что соединение разорвано.

Вот пример ответа на команду CMD_TEST:

010000

Команда «Стоп» (CMD_STOP)

Команда CMD_STOP присылается роботу, когда требуется остановить робота и вернуть его в исходное положение. Команда присылается, если пропало соединение между смартфоном с джойстиками и приложением RoboCam или если вы рвёте соединение, нажав на среднюю пурпурную кнопку в приложении RoboCam. По этой команде робот должен остановить движение, вернуть сервомоторы в исходное положение. Формат команды следующий:

SSC

        • Байты SS – это размер сообщения. Для команды CMD_STOP размер всегда будет 1.
        • Байт C – это код команды, в данном случае – 255.

Вот пример сообщения с командой CMD_STOP:

0100FF

Ответ на команду ожидается следующий:

SSR

        • Байты SS – это размер сообщения.
        • Байт R – это результат: 0 – команда успешно обработана, 1 – ошибка. Результат ответа на эту команду игнорируется, но ожидается. Рекомендуется всегда возвращать здесь 0.

Вот пример ответа на команду CMD_STOP:

010000

Настройки роботов

После того как с протоколом взаимодействия мы разобрались, можно посмотреть, какие настройки появились для нестандартных роботов. Перейдите в приложении RoboCam в настройки (серая круглая кнопка справа),

Кнопка настроек RoboCam

затем выберите «Робот».

Настройки роботов в приложении RoboCam

Откроются настройки роботов. Как видите, здесь в списке появляются как настройки для роботов EV3, так и для нестандартных роботов.

Список настроек роботов RoboCam

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

Пункт меню "Нестандартный робот" в приложении RoboCam

Если вы решили создать новые настройки, то перед вами появятся пустые настройки.

Пустые настройки нестандартного робота в приложении RoboCam

Я же буду в статье описывать настройки, приводя в пример, уже ранее созданные настройки, для управления роботом, которого вы видели на видео вверху статьи. Итак, в самом начале указывается имя робота, которое будет видно в списке настроек и на главном экране приложения RoboCam, если настройки выбраны текущими. Далее идёт описание, которое будет видно только в списке настроек.

Настройки Arduino-робота в приложении RoboCam

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

Если установлена галочка «Скрывать джойстики при использовании клавиатуры», то, как и для настроек EV3, джойстики на клиенте исчезнут, как только будет нажата любая клавиша на клиенте. Как только вы щёлкните мышкой по экрану, джойстики появятся снова.

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

Ниже идут настройки 4-х джойстиков RoboCam. Для всех джойстиков настройки одинаковы, поэтому рассмотрим их на примере первого джойстика. Первая галка «Видимость» управляет видимостью джойстика, если галка снята, то джойстик на клиенте не показывается и не работает.

Настройки джойстиков в приложении RoboCam

Из списка «Форма» вы можете выбрать форму джойстика. Формы могут быть следующими: вертикальная, горизонтальная, круглая, квадратная, стрелки, вертикальные стрелки и горизонтальные стрелки. Вот как выглядят джойстики описанных форм:

Джойстики приложения RoboCam

Принцип работы джойстиков зависит от формы и уже описан в статье «Управление роботом LEGO Mindstorms EV3 от первого лица».

В следующих двух списках выбирается поведение джойстиков при окончании прикосновения к ним. Здесь есть всего два варианта: «Возвращаться к нулю» и «Сохранять позицию». В первом случае, если вы «отпустили» джойстик, он возвращается к исходному состоянию, т.е. возвращается к нулю, а во втором случае остаётся на месте. Поведение можно указать отдельно для вертикальной оси джойстика и отдельно для горизонтальной.

В самом низу настраиваются клавиши. Галочка «Активность» включает или отключает восприимчивость клиента RoboCam к нажатию клавиш. Если вы не планируете использовать для управления клавиатуру, то рекомендуется убрать эту галочку для экономии заряда батареи на клиентском устройстве.

Чуть ниже, если вы нажмёте на настройку «Клавиши» вы сможете выбрать клавиши, состояние которых вы собираетесь отслеживать.

Настройка клавиш для нестандартного робота RoboCam

В общем и целом, настроек для нестандартного робота гораздо меньше, чем настроек для робота EV3, но те настройки что есть, аналогичны настройкам для робота EV3, потому читайте предыдущие статьи о приложении RoboCam, чтобы получить больше подробной информации.

Сборка Arduino-робота

Для создания Arduino-робота, управляемого от первого лица с помощью приложения RoboCam, которого вы можете видеть на видео ниже, был использован образовательный набор «Амперка» и дополнительные компоненты и детали: Bluetooth-модуль HC-06, дополнительные пластиковые стойки, гайки и шайбы, две распечатанные на 3D-принтере детали для удержания сервомотора, скрепка и две резинки для денег.

В принципе, процесс сборки в ускоренном режиме показан на видео. Ничего сложного в нём нет. Если вы будете собирать подобного робота из образовательного набора «Амперка», то вместе с ним идёт книжка, в которой описано, как подключать моторы и как собирать робота, который следует по линии. У меня робот такой же, как описано в этой книге, но без датчиков линии.

Смартфон я решил закрепить самым простым способом: снизу прикручены две стойки с винтами и смартфон держится за них с помощью резинки. Сверху смартфон держится за рейку, к которой он прикреплён опять же с помощью резинки. Вторым концом рейка прикреплена к сервоприводу. На видео видно, что смартфон наклоняется на небольшие углы, но увеличив рычаг, вы можете, при желании, увеличить углы наклона смартфона.

Готовую модель для 3D-печати держателя сервопривода и рейки можете скачать по ссылкам ниже:

Файлы:
Держатель сервопривода (3D-модель)

Держатель сервопривода (3D-модель) для робота, собранного из образовательного набора «Амперка».

Держатель сервопривода

Дата 06.10.2017 Размер файла 76.41 KB Закачек 23

Рейка (3D-модель)

Рейка (3D-модель) для робота, собранного из образовательного набора «Амперка».

Рейка для робота, собранного из образовательного набора

Дата 06.10.2017 Размер файла 56.08 KB Закачек 22

Если платформа для создания робота у вас другая, то и держатель смартфона у вас будет каким-то другим. В этом случае, если у вас есть возможность печати на 3D-принтере, то соорудить свой держатель не проблема. Свои 3D-модельки держателя сервопривода и рейки я создавал в облачном 3D-редакторе Tinkercad. Я уже описывал, как с ним работать в статье «Tinkercad – простой веб-инструмент для 3D-проектирования и 3D-печати».

Ещё чтобы повторить мой эксперимент, вам понадобятся скетч для Arduino и настройки для RoboCam:

Исследователь Arduino Версия:от 10.09.2017

Скетч для управления колёсным Arduino-роботом с управляемым держателем смартфона с помощью приложения RoboCam.

Дата 10.09.2017 Размер файла 15.07 KB Закачек 44

Настройки RoboCam для управления Исследователем Arduino Версия:от 10.09.2017

Настройки RoboCam для управления Исследователем Arduino.

Дата 11.09.2017 Размер файла 448 B Закачек 24

Tags: RoboCam Учебники по использованию программ Обзоры программ

Добавить комментарий


Защитный код
Обновить