Иногда, устроившись на мягком пуфике с книжкой, так и хочется скосплеить Громозеку из мультфильма Тайна третьей планеты, и сказать “Официант, 400 капель яблочного сока и печеньку”.
Мы решили реализовать такого робота на практике на платформе AlphaBot под управлением Raspberry PI 4 и назначить его официантом в нашем коворке.
Одна из важнейших и часто недооцененных задач при разработке «домашних» решений таких, как умные пылесосы, Smart TV и т. д. — обеспечение приватности пользователей. Для того, чтобы робот мог двигаться по квартире робот должен быть оснащен камерой, а камера потенциальный источник чувствительной информации. Совсем недавно широкую огласку получил случай, когда робот пылесос посылал в облако фото с камеры на котором была хозяйка в неудобном положении. Даже информации о траектории движении робота или информация о графике его раоты может быть интересной для недоброжелателей.
Поддействием весеннего солнца и хорошего настроения 1-го апреля мы решили
попробовать добавить роботу киберимунитет. Для этого в качестве операционной системы был использован KasperskyOS CE.
Начали мы с того, что проанализировали требования и составили список того, что должна делать система:
Предоставлять возможность передавать роботу высокоуровневые команды при помощи telegram сообщений («Привези сок», «Забрал напиток»)
Предоставлять механизм передачи роботу команд управления (вперед, назад, поворот налево, поворот направо, стоп)
Сок должен наливаться автоматическим дозатором
Автоматически определять положение робота
Знать положение дозатора
Автоматически определять позицию «студента‑клиента»
Предотвращать передачу команд от других студентов в процессе выполнения заказа
Робот должен прокладывать маршрут и автоматически приезжать к » студенту‑клиенту» из любой точки коворкинга и позволять поставить чашку на поднос
Робот должен прокладывать маршрут и автоматически приезжать от студента‑клиента к дозатору от «студенту‑клиенту»
Робот должен дождаться налива сока в стакан из дозатора
Робот должен прокладывать маршрут и автоматически возвращаться с чашкой сока к «студенту‑клиенту» от дозатора
Общая архитектура нашего решения получилось такая:
В этой статье мы расскажем о реализации программы управления роботом на KasperskyOS. Остальные компоненты системы будут описаны в последующих статьях.
Подготовка RaspberyPi 4 к работе
Для получения отладочной информации необходимо подключить к raspberry pi 4 преобразователь для работы с UART через USB. На плате Alphabot`а UART выведен на разъем в передней части платы. Для отладки программ, запущенных на роботе, удобно подключить преобразователь USB2UART к этому разъему.
Если робот Alphabot собран, то значительно удобнее подключить преобразователь к разъему UART на Alphabot, что позволит не разбирать робота при необходимости получить отладочную информацию. В качестве терминала, например, можно использовать Minicom.
Предварительно надо настроить minicom на работу с устройством /dev/ttyUSB0. Инструкция по настройке может быть найдена тут /6/. Необходимо отметить, что KasperksyOS CE 1.1.1 не включает привычного пользователям Linux командного терминала. В UART выдается только отладочная информация. Для вывода отладочной информации из своей программы разработчик должен осуществлять вывод в стандартный поток ошибок, например при помощи команды fprintf(stderr, “Some error \n").
Разработка программы в KasperskyOS
Установка KasperskyOS SDK
KasperskyOS SDK можно использовать Linux Debian 10 или Ubuntu 20 LTS. Подробная инструкция по установке приведена в руководстве /1/. KasperskyOS CE является встраиваемой системой и для ее запуска необходимо cформировать загрузочный образ с операционной системой и прикладными программами и записать его на MicroSD карту. Перед использованием необходимо провести первоначальную инициализацию MicroSD карты. Данная операция описана в руководстве по KasperskyOS /1/
Управление двигателями Alphabot при помощи GPIO в KasperskyOS
На Alphabot установлены моторы постоянного тока. IN1 и IN2 подключены к левому двигателю, IN3 и IN4 подключены к правому двигателю альфабота. ENA и ENB - это разрешающие контакты, высокоактивные. Чтобы отрегулировать скорость альфабота, возможно выводить ШИМ-сигнал на контакты IN1, IN2, IN3 и IN4. Управление моторами может осуществляться путем выдачи управляющих сигналов на GPIO.
Детальная информация Alphabot может быть найдена в руководстве пользователя Alphabot /5/ .
KasperskyOS API для работы с GPIO
Для работы с GPIO KasperskyOS SDK предоставляет системную сущность GPIO, которая включает драйвер. При работе с GPIO эту сущность необходимо добавить в проект. Прикладная программа может использовать специальное API для взаимодействия с этой сущностью.
API для работы с GPIO включает следующие функции:
GpioInit()
- Инициализировать подсистему GPIO
GpioOpenPort(char* name, GpioHandle *handle)
- открыть порт
GpioSetMode(GpioHandle h, uint32 pin_number, GpioMode mode)
- установить режим работы пина (GPIO_DIR_IN, GPIO_DIR_OUT, GPIO_EVENT_LOW_LEVEL, GPIO_EVENT_HIGH_LEVEL, GPIO_EVENT_RISE_EDGE, GPIO_EVENT_FALL_EDGE)
GpioOut(GpioHandle h, uint32 pin_number, uint32 signal)
- подать сигнал на пин
GpioIn(GpioHandle h, uint32 pin_number, uint32 &signal)
- считать сигнал
Проект в KasperskyOS CE имеет определенную структуру, информацию о которой можно найти в документации /1/. Структура минимального проекта для работы с GPIO показана на Рис.9.
В качестве основы для разработки своего проекта мы использовали пример gpio_output из SDK KasperskyOS, в который добавили функции для выдачи команд на двигатели Alpahot. Первоначальная инициализация GPIO может быть реализована следующим образом:
GpioHandle InitAlphabot() {
GpioHandle handle = NULL;
if (GpioInit()) {
fprintf(stderr, "GpioInit failed\n");
return EXIT_FAILURE;
}
if (GpioOpenPort("gpio0", &handle) || handle == GPIO_INVALID_HANDLE) {
fprintf(stderr, "GpioOpenPort failed\n");
return EXIT_FAILURE;
}
GpioSetMode(handle, GPIO_PIN_NUM_IN1, GPIO_DIR_OUT);
GpioSetMode(handle, GPIO_PIN_NUM_IN2, GPIO_DIR_OUT);
GpioSetMode(handle, GPIO_PIN_NUM_IN3, GPIO_DIR_OUT);
GpioSetMode(handle, GPIO_PIN_NUM_IN4, GPIO_DIR_OUT);
GpioSetMode(handle, GPIO_PIN_NUM_ENA, GPIO_DIR_OUT);
GpioSetMode(handle, GPIO_PIN_NUM_ENB, GPIO_DIR_OUT);
return handle;
}
Выдача команд управления "движением вперед" и "остановки" Alphabot может быть реализована так:void forward(GpioHandle* handle) {
fprintf(stderr, "forward\n");
GpioOut(*handle, GPIO_PIN_NUM_IN1, HIGH);
GpioOut(*handle, GPIO_PIN_NUM_IN2, LOW);
GpioOut(*handle, GPIO_PIN_NUM_IN3, LOW);
GpioOut(*handle, GPIO_PIN_NUM_IN4, HIGH);
GpioOut(*handle, GPIO_PIN_NUM_ENA, HIGH);
GpioOut(handle, GPIO_PIN_NUM_ENB, HIGH);
}
void stop(GpioHandlehandle) {
fprintf(stderr, "stop\n");
GpioOut(*handle, GPIO_PIN_NUM_IN1, LOW);
GpioOut(*handle, GPIO_PIN_NUM_IN2, LOW);
GpioOut(*handle, GPIO_PIN_NUM_IN3, LOW);
GpioOut(*handle, GPIO_PIN_NUM_IN4, LOW);
GpioOut(*handle, GPIO_PIN_NUM_ENA, LOW);
GpioOut(*handle, GPIO_PIN_NUM_ENB, LOW);
}
Для проверки работы GPIO мы разработали минимальное тестовое решение на Kaspersky OS, которое после старта посылает команды на вращение колес в разные стороны. Структура проекта в KasperskyOS CE обычно включает приложение, задачу инициализации einit и несколько конфигурационных фалов специфичных длял KasperskyOS . В нашем Проект для управления моторами Alphabot на KasperskyOS включает следующие задачи, разрабатываемы пользователем:
einit - отвечает за запуск приложений
client – собственно приложение для управление моторами через GPIO.
Необходимо отметить, что для работы задач управления моторами необходимы системные ресурсы сore, BSP и GPIO. Для доступа к системным ресурсам задача client и другие задачи обращаются к системным процессам при помощи посылки сообщений. KasperksyOS требует явно специфицировать разрешения на обмен сообщениями, которые будут происходить в процессе работы. Для этого необходимо задать правила передачи сообщений между задачами при помощи psl файлов. В правилах указываются разрешения на запуск приложения, передачи запроса и передачи ответа. Например, программа Client должна взаимодействовать с программой GPIO посредством API работы с gpio и должны быть выданы разрешения на отправку запроса и прием ответа:
request src=client.Client, dst=kl.drivers.GPIO
{
grant()
}
response src=kl.drivers.GPIO, dst=client.Client
{
grant()
}
Код минимального примера управления моторами Alphabot может быть найден в нашем репозитории с примерами.
Запрограммированный таким образом, бот движется с одной скоростью, причем достаточно резво. Было бы отлично научиться контролировать скорость робота. Для контроля скорости на Alphabot можно предназначены оптоэлектрические датчики числа оборотов WYC-H206 показанные на рис. 10. На оси моторов установлены диски с 20 щелями. С одной стороны от диска установлен светодиод, а со второй фотоприемник. Сигналы от этих датчиков приходят на GPIO7 и GPIO8 Raspberry Pi. Для подсчета числа оборотов колеса возможно подсчитать число прерываний от этих GPIO
В KasperskyOS есть возможность получать информацию о прерываниях в пользовательском приложении. В составе SDK KasperskyOS есть пример работы с прерываниями от GPIO gpio_interrupt. Для того, чтобы получить информацию о прерываниях в пользовательском приложении возможно:
1. Настроить отправку событий от программы GPIO в управляющую программу client в момент прихода прерывания от GPIO при помощи вызова GpioSetMode.
GpioSetMode(handle, 0x7, GPIO_DIR_IN | GPIO_EVENT_RISE_EDGE);
GpioSetMode(handle, 0x8, GPIO_DIR_IN | GPIO_EVENT_RISE_EDGE);
2. В цикле вызывать блокирующий вызов GpioGetEvent и анализировать параметры приходящего событий.
Полный пример работы с прерывания от датчика оборотов в KasperskyOS может быть найден по ссылке. К сожалению, нам не удалось заставить Alphabot генерировать правильное число событий.
Другим подходом к решению задачи плавного управления Alphabot является использование ШИМ контроллера. RaspberyPi 4 не имеет аппаратного ШИМа, и нам пришлось разработать программный. Для реализации ШИМ была замерена минимальная возможная величина, на которую может заснуть поток с помощью функции usleep(useconds_t usec). Этой величиной может характеризоваться максимальная частота работы контроллера. Данной величиной оказалось 50 микросекунд. При значениях меньше 50 поток не блокировался, и управление возвращалось моментально. Проведя некоторое количество экспериментов, выяснилось, что частота 200Гц является вполне достаточной для стабильной работы. За промежуток времени в 5000 микросекунд, необходимо осуществить переход с высокого уровня на низкий. Упрощенный график с результатами работы программного ШИМ выглядит следующим образом:
Программа управления на Alphabot получает по MQTT от сервера распознавания управления следующие команды:
Вперед заданное время
Назад заданное время
Назад влево заданное время
Вправо заданное время
Стоп
Прием управляющих команд по MQTT
Для добавления работы с сетью и MQTT в проект необходимо добавить сущность VFS, которая инкапсулирует работу с сетевым стеком, а также сконфигурировать разрешения на взаимодействие между сущностями VFS и client в psl файлах.
Программа client реализует прием сообщений по MQTT и управление моторами через GPIO. Исходный код программы доступен по ссылке.
Разбиение монолитной программы на сущности
Для увеличения защищенности возможно разделить обязанности программы client по сетевому взаимодействию по MQTT и алгоритмы управления в разные сущности KasperskyOS, которые взаимодействуют при помощи IPC. В качестве простой заготовкм, демонстрирующей работу с IPC в KasperskyOS можно взять пример echo, который входит в состав SDK.
Архитектура проекта с разделенными сущностями будет иметь следующий вид:
Полный исходный код проекта доступен в репозитории. Мы постарались рассмотреть в данной статье подход к реализации программы управления моторами Alphabot при помощи GPIO и получение команд по MQTT в KasperskyOS. На этом первая часть статьи завершается. В скором времени выйдет следующая часть, в которой будет рассказано, как реализовать в KasperskyOS обработку изображения при помощи OpenCV, телеграм бота для приема команд и управление дозатором в Eclipse 4diac.