Иногда, устроившись на мягком пуфике с книжкой, так и хочется скосплеить Громозеку из мультфильма Тайна третьей планеты, и сказать “Официант, 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() - Инициализировать подсистему GPIOGpioOpenPort(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.
Литература
Комментарии (13)
 - Zara650202.04.2023 22:30+1- мне кажется нет связи между начальной постановкой проблемы и мотивами при выборе инструментария. например нет описания того, как использовать камеры, но сохранять приватность. или как OS противостоит взлому по "воздуху" если такое предусмотрено (у вас как я понял всё доступно по кабелю).  - almaximort Автор02.04.2023 22:30- Более детально про использование камеры, распознавание внутри KasperskyOS и почему мы хотим его использовать, обеспечение приватности камер и противостояние взлому будет в следующей статье. 
 
 - akirsanov02.04.2023 22:30+3- Предлагаю переименовать статью в "Первые шаги работы с GPIO в Kaspersky OS". 
 Про прикладную безопасность в статье нет ничего, есть только медийный посев слова "кибериммунитет" в контексте робота и RPi, привить аудитории мысль "KOS по умолчанию безопасно, нет времени объяснять".
 Хотелось бы увидеть практические примеры эффективности KOS в сценариях типовых уязвимостей типичного устройства iot - проблемы логики на стороне робота, недокументированные сценарии, заложенные производителем, проблемы безопасности сторонних компонентов(библиотек, пакетов), отсутствие шифрования и контроля целостности при обновлении, сравнение решения с текущими многоуровневыми инструментами безопасности в Linux. - friend00100202.04.2023 22:30- Поддерживаю! Пока что безопасности в статье не увидел. Но если будет в следующей части -- почитаю! Только нужно помнить, что CE-версии разработчики уделяли меньше внимания, чем коммерческим версиям (по крайней мере у меня сложилось такое впечатление когда я работал в Kaspersky) Есть вероятность, что в CE-версии кибериммунности меньше, если вообще завезли. Ну и, конечно, нужно все по инструкции делать чтобы было безопасно.  - Indemsys02.04.2023 22:30+1- Если посмотреть на сайт KasperskyOS, то их способ получения кибериммунности заключается в особой архитектуре. - Сама OS не есть архитектура. Значит фокус в том что разработчики под эту OS должны сами создавать особую архитектуру. И эта особая архитектура, как я понял, не годится для риалтаймовых систем. Поэтому все изделия KasperskyOS относятся к классу коммуникационных шлюзов, но не самих исполнительных контроллеров. - Статья вводит в заблуждение тем что пытается положить на KasperskyOS несвойственные ей задачи риалтайма и утверждать что оно так и было задумано. - И кибериммунность не есть эквивалент функциональной надёжности, а скорее антагонист. - Т.е. этот робот может пообливать всех в офисе соком, но зато никакие хакеры его в этом не остановят.  - friend00100202.04.2023 22:30- Насколько я понимаю, смысл KasperskyOS в том, что писать приложения можно только на такой вот безопасной архитектуре. В старых версиях были способы писать "небезопасно" (всякие там mmap), поскольку иначе никак, но в новых должны были небезопасный функционал выпилить, заменив безопасным. Обновили ли именно CE-версии -- не знаю. - И да -- KasperskyOS топит за безопасность. Что там именно с надёжностью -- не знаю. Никогда про надёжность не слыхал обсуждений. - Про realtime были разговоры, но только про софт-realtime. Не знаю решили ли они его запилить. Всё зависит от потребностей коммерческих покупателей. Что-то в CE-версию перекочует.  - almaximort Автор02.04.2023 22:30- Мы хотели потрогать KasperskyOS CE вне стен ЛК в задаче, которая чуть сложнее, чем примеры из SDK. На текущий момент впечатления следующие: - Позитивное: 1. KasperskyOS компактная 2. Основная идея, которая заложена в KasperskyOS - что если разбить программу на части и контролировать взаимодействие частей, то при взломе одного компонента не будет компрометирована все система и дальше ломать будет по-прежнему сложно. 3. Есть POSIX и в версии SDK 1.1.1 появился свежий g++ 9.2, который поддерживает C++17/C++20. Это упрощает перенос библиотек. - Сложности: 1. Писать и отлаживать psl правила трудоемко. 2. Из коробки в SDK 1.1.1 нет ничего для фильтрациии сетевых пакетов 3. Поддержки WiFi - в SDK 1.1.1 еще нет. - Относительно real-time - мы еще не мерили параметры, скорее всего достижимо только мягкое реальное время. Планируем померить. Будут результаты - опубликуем. 
 
  - almaximort Автор02.04.2023 22:30- Относительно кибериммуитета - KasperskyOS CE предоставляет возможность разбивать приложение на сущности, обмениваться между сущностями 
 по IPC и контролировать при помощи psl правил какая сущеность к каким ресурсам имеет доступ (Собственно это и относится к кибериммунитету). Есть возможность
 писать более сложные правила. Например, в нашей текущей реализации communication, принимающая команды по MQTT не имеет доступа к файловой системе. Если сущность communication будет компрометирована, то это все равно получить доступ к ее конфигурации будет затруднительно. Есть отдельная сущность
 configuration_server, которая имеет доступ к конфигурации MQTT клиента, но она не имеет доступа к сети и доступна только через IPC. Детально будет в следующей статье.
 
 
 
 - DagothNik02.04.2023 22:30- Спасибо за статью. Но хотелось бы отметить, что робот-пылесос запечатлел хозяйку как раз таки в "удобном положении". "Неудобным" её положение стало после того, когда её фото попали в сеть. 
 
           
 
sdy
Робот по камере ориентируется в офисе или лидару?
almaximort Автор
На роботе нет ни камеры ни лидара. IP камеры на потолке. Программа распознавания и позиционирования на отдельном PC. Она же выдаёт на робот команды управления по MQTT. В следующей версии от PC избавимся и все будет на роботе.
sdy
Какие ещё платформы кроме RPi можно поднять на КОС из тех, что сейчас доступны?
almaximort Автор
В версии SDK 1.1.1 только Raspberry PI 4 и возможность запуска в QEMU.