Улучшаем дисциплину в офисе с помощью многофункционального робота

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

Робот Стив​
Робот Стив​

Как и у многих программистов, мой досуг иногда состоит из программирования «для души». То есть после 7-10 часов кодинга на своей любимой работе, я приходил домой и еще часа четыре с удовольствием погружался в мир подкормки собственного мозга и программирования каких-либо поделок.

Итак, все началось с ужасной скуки в один из вечеров и в последствии покупки Raspberry PI 3 Model B, стандартной камеры для него, парочки наборов StarterKit на AliExpress, а также нескольких шаговых моторов и драйверов к ним.

Изначально, хотелось сделать развлекательного робота, который просто следит глазами за лицом или за двумя лицами разными глазами. В качестве языка программирования я выбрал JavaScript (nodeJs), разработку вел в IDE PHPStorm.

Сперва я искал возможность программировать непосредственно на Raspberry, но не смог найти ни одной нормальной IDE для Raspbean, хотя бы близко похожей на привычные IDE от JetBrains. Пришлось создать проект на ноутбуке и настроить удаленный авто-Deployment.

Результат был отличный - пишешь в удобной IDE локально и при любом сохранении файла, он тут же доставляется на Raspberry по SFTP. Для запуска моей программы на Raspberry, я настроил кнопку быстрого запуска прямо в PHPStorm, которая запускала удаленную команду по SSH, прямо в консоли того же PHPStorm. С процессом разработки разобрались, возвращаемся к задаче.

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

Тестирование датчиков

Теперь нужно было собрать это все в связанное и идеально работающее приложение. Для определения координат лиц, попадающих в камеру, я выбрал стандартную библиотеку OpenCV. HelloWorld статья на хабре про OpenCV помогла быстро получить первые результаты и дальше становилось только интереснее.

Вот такие первые эксперименты я ставил для простого определения координат.

Определение координат лица в кадре​

Слежение глазами за объектами

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

Мой шаговый двигатель содержал 4 фазы, я использовал 4 тактовую модель (бывает еще 8 тактовая, где двигатель проворачивается полушагами) для прокручивания маховика. То есть для прокрутки маховика на один шаг (0.7 градуса – у меня по факту получалось. 512 шагов проворачивали на 360 градусов мотор, экспериментально было выявлено) нужно было подать напряжение последовательно на 4 пары обмоток.

4 тактовая модель поворота ротора
4 тактовая модель поворота ротора

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

Сигналы на катушки двигателя для поворота его на один шаг​

Научившись вращать мотор и получив координаты лиц, написать программу было делом времени. И вот я уже тестирую первую модель.

Слежение глазами за лицом

Мини-игры

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

Суть игры была в том, что нужно было пройти незамеченным в течении определенного времени (10, 20 или 30 сек) перед роботом, в то время как робот будет получать данные от датчика движения (который использует в своей основе тепловизионную матрицу) и при обнаружении движения – игра будет проиграна.

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

Информацию о текущем режиме я стал выводить на двухстрочном дисплее. Так как места было мало, использовал максимальное сокращение (M0, M1, … - где M – это Mode или режим). Также на дисплее выводил вспомогательную информацию, например обратный отсчет количества секунд.

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

Немного порывшись в интернете, нашел отличный сервис с отличным API – Amazon Polly. Просто отдаю ему строку на русском языке в запросе, а в ответ получаю готовый mp3 файл, который можно воспроизвести. Сервис требует привязки пластиковой карты, но стоит он сущие копейки 4$ за миллион символов. Но чтобы расходовать средства рационально, я немного поработал над кэшированием, чтобы одни и те же фразы не переводились внешним сервисом дважды.

Скажу честно, игру достаточно сложно пройти, нужно двигаться очень плавно и медленно, чтобы датчик не сработал, но тем не менее это реально. Вот как это работало:

Мини-игра №1

Чтобы робот мог повеселить и более старшее поколение, я решил сделать более простую игру на интуицию. Суть – робот загадывает один из двух цветов - синий или красный, а человек нажимая на соответствующую кнопку пытается отгадать. Для этого пришлось добавить еще две кнопки и занять еще 2 драгоценных пина на GPIO Raspberry, места под другие датчики оставалось все меньше… Вот как работала эта игра:

Мини-игра №2

Безопасность

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

В 21:00 ежедневно робот переходил автоматически в особый режим и при срабатывания датчика движения, отправлял мне SMS и матюкался. В 7:00 (когда приходит к нам в офис уборщица), робот должен переходить в обычный режим. Для отправки SMS, у меня уже был припасен аккаунт на одном из SMS агрегаторов, куда как обычно по API, я мог отправить запрос и SMS мне успешно доставлялось.

Также робот осуществляет фотосъемку со своей камеры раз в 10 секунд и складывает картинки за последние N дней в определенную папку на Raspberry Pi.

Режим безопасности

Контроль учета рабочего времени

Так как робот получился офисным, нужна была киллер-фича, обосновывающая важность его использования. Иначе робот был бы отвлекающим коллектив от работы. И такая фича была найдена – контроль учета времени прихода сотрудников. Я всегда выступал за жесткую дисциплину на работе. Считаю, что только так можно добиться действительно значимых результатов в любой сфере и ИТ сфера не является тут исключением.

Так, на роботе появился еще один датчик – датчик RFID меток. ID каждой метки, ФИО сотрудника и согласованное для него время начала работы я заранее завожу в Mysql базу данных на Raspberry. При поступлении события с датчика, робот здоровается/прощается с сотрудником по имени, записывает время его прихода/ухода.

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

Вот как это работает:

Отметка о прибытии/убытии через RFID

Мониторинг серверов

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

Мы решили взять самый простой случай мониторинга – проверку доступности наших сайтов на 80 порту и реализовать их мониторинг прямо на нашем роботе с голосовым уведомлением, если какой-то из сайтов ложиться. Прямо вот так:”Тревога, сервер номер N лежит!” или «Тревога, демо сайт Гипермаркет лежит!».

Для исключения ложного срабатывания из-за проблем интернет-провайдера, робот определяет доступность интернета с помощью пинга к google.com. Только если google.com успешно пигуется, а наши сайты дважды показали недоступность – включается тревога.

Также информацию о мониторинге всех сервисов вывели на дисплей. Если там написано I – ON, RS – OK, значит интернет доступен и все наши сайты – в полном порядке.

Сообщение о неполадках

Веб-интерфейс

Робот уже владеет достаточно большой информацией и ее как-то нужно извлекать из него. Тут возникла необходимость реализовать веб-интерфейс для него, чтобы управлять всем этим добром. Для этого был выбран Express на nodejs + socket.io, чтобы мгновенно получать в режиме реального времени всю информацию от робота в браузере.

Вот как выглядит веб-интерфейс робота:

В интерфейсе присутствует:

  • Прямой эфир с камеры

  • Информация о текущих состояниях датчиков и моторов

  • Возможность произнести любую фразу роботом

  • Лог событий с датчиков

  • Лог фото фиксации за последние N дней

  • На отдельной странице присутствует табель учета рабочего времени с фильтром по диапазону дат

Внешний вид

Роботу требовался корупс, для этого были приобретены пластиковые прозрачные коробки из IKEA.

​Коробка из IKEA для корпуса робота<br />
​Коробка из IKEA для корпуса робота

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

​Первая сборка каркаса робота<br />
​Первая сборка каркаса робота

В процессе сборки робота и под влиянием популярности в те годы (2017) у детей игры Minecraft, был выбран стиль и имя будущего робота – Стив.

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

В итоге получился вот такой яркий робот.

Готовый офисный робот "Стив"<br />
Готовый офисный робот "Стив"

Доточка мелочей и сложности

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

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

Ввиду отсутствия у меня информации о текущем положении поворота глаз, и отсутствия свободных пинов GPIO для подключения датчика, пришлось сделать костыль, а именно – приспособить имеющиеся две кнопки (которые были добавлены для игр) для корректировки глаз. Нажимая на кнопку, глаз начинает вращаться по кругу. Необходимо отпустить кнопку, когда глаз будет смотреть четко прямо. Теперь нашего робота, как дорогие механические часы, нужно иногда подводить )

Вторая проблема, с которой я столкнулся – это разрешение изображения, с которым получалось работать в OpenCV на raspberry. Оно очень низкое – 320x240 px. Только при таком разрешении удавалось обрабатывать хотя бы 10 FPS, что было необходимо для плавности движения глаз робота. И это при том, что я собирал OpenCV с необходимыми флагами для оптимизации скорости обработки видеопотока на Raspberry (NEON, VFPV3).

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

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

Асинхронность вносила определенную сложность в разработку программы. Так например, при смене режима робота, нужно было резко оборвать все текущие действия, все текущие подписки на события датчиков, все незавершенные на текущий момент ожидания (Promise), чтобы создать новые подписки уже для новых обработчиков в другом режиме. По сравнению с синхронным программированием – это другой мир, где всегда нужно учитывать фактор параллельности, особенно когда каждая параллельная ветка работает с общим оборудованием.

Итоговый список устройств, примененных в роботе

  • Raspberry PI 3 Model B

  • Raspberry Pi Camera Module Rev 1.3

  • Датчик температуры и влажности DHT11

  • RFID датчик RC522

  • Двухстрочный дисплей LCD 1602

  • Датчик движения HC-SR501

  • Колонки активные с USB питанием

  • Шаговые двигатели 28BYJ-48

  • Драйверы для моторов – ULN2003

  • Кнопки обычные

  • Коробка из IKEA

Заключение

Процесс разработки данного робота составил примерно 6 месяцев, но они пролетели незаметно.

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

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

Или можно сделать внутренний учет книг в офисной библиотеке, наклеив на книги RFID метки и дописав еще один режим работы «библиотекарь» роботу.

Или можно сделать рандомное вытягивание какого-либо афоризма из интернета и произношение его в обеденное время.

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

Ну и самое главное – в офисе появился роботизированный контроль, опоздания стали частью формулы KPI сотрудников. При составлении табеля учета рабочего времени каждого сотрудника не нужно запоминать кто и когда не выходил на работу, Стив любезно предоставляет эти данные.

22
3 комментария

Осталось подключить его к мессенджеру, и будет чат-бот для автоматического общения с сотрудниками работающими вне офиса.

Ответить

Я практически уверен, что робот заставил вас написать эту статью для выполнения KPI.

Ответить

)) Интересная версия.

Ответить