В прошлый раз, работая с OpenCV и ROS(robot operating system), используя всю мощь raspberry pi 3b+, удалось поездить по линии, разглядеть улыбки на лицах людей, печальные морды котов и даже поехать к ним навстречу.

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

1. Запустив все ноды (скрипты в ROS) из ранее собранного проекта, и начав работать с каскадами Хаара очень быстро выяснилось, что производительность одноплатного компьютера для таких задач пока слабовата. Несмотря на то, что нагрузка процессора не была пиковой и колебалась в пределах 80%, робот долго соображал, когда видел лицо человека или морду кота, к которым должен был следовать.

Самое грустное было то, что после того, как лицо или морда выходили из поля зрения камеры, робот начинал движение, «думая», что едет к объекту. Вообщем, как у М.Ю. Лермонтова:
«Давно отверженный блуждал
В пустыне мира без приюта...».
Первые попытки исправить ситуацию были следующие:
— в ноде запуска камеры (на raspberry pi) был уменьшен размер захватываемой картинки с 640x480 60fps, до 320x240 15 fps.

cd /home/pi/rosbots_catkin_ws/src/rosbots_driver/scripts/rosbots_driver
nano pi_camera_driver.py

Это дало определенный прирост производительности, но картина в целом осталась далека от идеальной.

Далее в самом скрипте запуска следования за лицом человека (follow_face.py) или кота(follow_cat2.py) были закомментированы выводы на экран самой opencv изображений. То есть все cv.imshow. Теперь при запуске поездки, нельзя было визуально наблюдать, видит ли робот картинку, к которой двигается или нет. Что ж пришлось принести в жертву наглядность.
Также подверглись комментированию info-выводы самой ROS в скриптах: #rospy.loginfo.
Это еще немного снизило нагрузку и увеличило скорость работы.
Но… надо было придумать что-то еще.

2. Кроме того робот был ужасно близорук. Следуя собственному прошлому опыту и рекомендациям в этой области, была использована камера fish-eye:



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

Однако, как выяснилось, ее результаты в области качества распознавания лица оказались не впечатляющими...Mckayla was not impressed… Из-за того же широкого угла обзора, который использует камера, она одновременно искажает сам распознаваемый объект. По этой причине, используемые каскады Хаара плохо работают. Также значительно влияет освещение, при затенении качество падает еще больше.

3. И в довершение — роботу не хватало угловой скорости для четких доворотов, а уж на порогах (не тех, через которые надо переступать) и коврах он и вовсе застревал. Здесь еще добавляла перцу разница мощности «одинаковых по мощности» моторов, которые практически никогда не бывают одинаковыми, даже выйдя из одной партии. Из-за этого робота значительно сносило влево.

Улучшение «производительности».


Что ж, с производительностью ситуация начала заметно выправляться, когда на помощь пришло главное преимущество ROS, как системы, а именно: возможность распределять нагрузку на разные машины.

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

В данной ситуации был выбран второй вариант.

Чтобы не описывать как установить Ubuntu, ROS на виртуальную машину, воспользуемся крылатой фразой Винни Джонса "нам нужен бездыханный доброволец". Мы подготовили его… — виртуальную машину со всей начинкой можно скачать здесь.

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



Подразумевается, что вы ее разворачиваете (запускаете) на VMware workstation.
Пароль: raspberry

Теперь можно оценить производительность при переваривании каскадов Хаара на железе, более мощном, чем raspberry pi!

Для того, чтобы запустить ROS систему, теперь уже разделенную на 2 части, надо указать виртуальной машине, где работает master-нода (а она запускается на raspberry сразу с загрузкой системы).

Для этого правим bashrc на виртуальной машине:

sudo nano ~/.bashrc

В строках в самом конце файла указываем ip адреса:

export ROS_MASTER_URI=http://192.168.1.120:11311
export ROS_HOSTNAME=192.168.1.114

Первый ip — это адрес raspberry pi, второй ip — адрес виртуальной машины.
*Виртуальная машина и raspberry должны быть в одной локальной сети.

На raspberry тот же bashrc будет другим:

<source lang="bash">export ROS_MASTER_URI=http://192.168.1.120:11311
export ROS_HOSTNAME=192.168.1.120

Два ip адреса на raspberry совпадают.
*Не забываем перезагружаться после изменения bashrc.

Как запустить распределнную ROS систему ?


На raspberry два терминала.

В 1-м движение:

rosrun rosbots_driver part2_cmr.py 

Во 2-м камера raspberry:

sudo modprobe bcm2835-v4l2
roslaunch usb_cam usb_cam-test.launch

Итого на raspberry будут работать 2 ноды: одна ждет команды для движения, вторая шлет видео с камеры в сеть.

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

rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/part2_cmr/cmd_vel 

Точно также вместо управления с виртуальной машины можно запустить ноду — следование за лицом человека:

cd /home/pi/rosbots_setup_tools/rpi_setup
python follow_face.py

Теперь немного сухой статистики о том, какие результаты с камерой fish-eye raspberry pi при разных настройках захватываемой картинки с камеры.

320х240, 30fps:
Лицо человека. 80-100 см. Влияет освещение, в тени практически не видит. Лучше на лицо направить лампу для улучшения. Улыбаться, с улыбкой быстрее распознает лицо.
Морда кошки на листе A4. 15-30 см.

При 800x600 и 60fps — лицо видит на расстоянии 2-3 м.

При 1280х720 и 60fps — лицо видит на расстоянии 3-4 м. Но появляются ложные срабатывания — видит в качестве лица настенные часы и т.п.

Кота на A4 распознает с задержкой 1-2 сек, расстояние 1-1,5 м.
Загрузка виртуальной машины 77-88%.


Как видно, при увеличении окна захватываемой картинки с камеры, увеличивается нагрузка на виртуальную машину и расстояние, на котором робот видит объект. Нагрузка на raspberry растет, но незначительно. Скорость распознавания в сравнении с работой всех нод только на raspberry заметно возросла.

Лечим близорукость


Статистика выше показала, что для улучшения зрения, необходимо увеличить разрешение и fps камеры, расплатившись производительностью виртуальной машины. Однако даже при 1280х720 и 60fps расстояние до объекта не слишком велико.

Решение этой задачи пришло неожиданно.

Как известно, для raspberry выпускается целая линейка камер. И для нашего случая отлично подошла одна из них, а именно:



Ее результаты следующие:

При искусственном освещении в комнате видит лицо на расстоянии 7-8 м! При этом даже не обязательно улыбаться )
800x600 и 60fps — загруз. виртуальной машины — 70-80%, raspberry — 21 % (там только ноды движения и запуска вещания камеры).
Кота на A4 распознает с задержкой 1-2 сек, расстояние 2-2,3 м.

Как видно опять страдают коты, которые определяются на меньших расстояниях. Но здесь причина скорее всего в настройках каскадов Хаара, а не камеры.
*Данная камера, как правило, идет в комплекте с «ушами» IR подсветки. Их при дневном освещении использовать не обязательно:



Таким образом, камера для raspberry pi, отличная от fish-eye, показала лучшие результаты при работе с объектами даже при некачественном искусственном освещении. Однако за увеличение расстояния от камеры пришлось расплатиться углами обзора и это необходимо учитывать.

Теперь об улучшении ходовой части и сносах робота в сторону


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

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

Однако, здесь можно все упростить и пойти на небольшую хитрость, поправив только лишь скрипт следования за лицом человека (follow_face.py) или кота (follow_cat2.py) на виртуальной машине.

Нас интересуют следующие строки:


#-0.013 - because right wheel is faster
                twist_msg.linear.x = 0.1
                twist_msg.angular.z = -0.013
            elif self.face_found["x"] < 0.0:
                # To the left
                cur_dir = "left"
                twist_msg.linear.x = 0.1
                twist_msg.angular.z = 0.016
            else:
                # To the right
                cur_dir = "right"
                twist_msg.linear.x = 0.1
                twist_msg.angular.z = -0.016

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

Увеличить ходовые характеристики робота (скорость и маневренность) можно подав на драйвер двигателя, который используется в проекте (L9110s) вместо 8 V — 12V. Но лучше этого не делать без установки стабилизатора питания или хотя бы конденсатора, т.к. чипы H-моста L9110s отлично горят, как выяснилось. Может быть от этого они такие дешевые. Тем не менее на 12 V робот ездит достаточно резво и легкомысленно.

Вместо заключения


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


Продолжение следует.

Комментарии (5)


  1. Newcss
    18.08.2019 05:44

    Не думали вместо виртуальной машины использовать intel neuro stick 2 с обученной нейронной сетью по детектированию лиц? Везде пишут что как раз для Raspberry самое оно.


    1. zoldaten Автор
      19.08.2019 08:49

      Да, это отличная идея. Но пока пришлось от нее отказаться в виду того, что по мере развития изделия приходится запускать графические редакторы (rviz, gazebo). Первый не так прожорлив, а вот gazebo с удовольствием ест ресурсы raspberry. Все равно приходится разворачивать VM или использовать laptop.


      1. Newcss
        19.08.2019 09:28

        Не могли бы рассказать больше для каких целей роботу требуются подобные редакторы? Я себе даже боюсь представить, т.к. считал, что робот это Конечный Автомат состояний, Зрение робота (если речь о камере) — классификатор помогающий роботу переходить из одного состояния в другое…


        1. zoldaten Автор
          19.08.2019 14:27

          Пока только кратко. Думаю в дальнейшем на примерах показать как с ними работать.
          — rviz в среде ROS — это визуальная среда состояния робота. Все, что шлют ноды в топиках, сервисах и т.п., «можно увидеть», как-то: изображение с камеры (камер), данные с энкодеров, с imu, датчиков и т.п.
          — gazebo — также визуальная среда, но для симуляции. То есть она не показывает как сейчас ведет себя робот, основываясь на данных, полученных с него, но рассчитывает, как он себя поведет при заранее заданных условиях (с учетом массы, ускорения, формы и т.п.)


  1. ShmelX
    19.08.2019 08:45

    Спасибо за статью. С нетерпением жду продолжения!