Cambot — робот-фотограф на Raspberry Pi

от автора

В прошлом году мне в руки попал миникомпьютер Raspberry Pi. Т.к. с Linux я никогда не сталкивался, он достаточно долго пролежал без движения в ящике стола, но, в конце концов, долежался… Один из последних экспериментов, который я выполнил с его помощью – изготовление робота фотографа – управляемой через web – интерфейс самодвижущейся платформы с возможность видео и фотосъемки.
Задачи для робота:

  • Управление по WiFi
  • Движение вперед-назад, повороты вправо-влево
  • Съемка видео в процессе движения и передача его на управляющий компьютер
  • Съемка фото с большим разрешением по команде с управляющего компьютера и передача этого снимка в web- интерфейс.


Конечно, робот взят просто как пример работы web интерфейса. Управлять можно и гораздо менее экзотическими устройствами – шторами, светом, нагревателями… Т.е. из Raspberry Pi можно, например, построить контроллер умного дома с web интерфейсом.

Для построения интерфейса я использовал webiopi, т.к. он позволяет запустить проект очень быстро с нулевым знанием php, apache и т.п. программ.
Что нужно знать для повторения проекта:

  • python (Уровень знания зависит от сложности планируемого алгоритма)
  • HTML
  • javascript, jquery
  • ну и нужно уметь паять, что бы собрать плату Raspirobot.

А теперь продолжим. Сначала пару слов о webiopi:

WebIOPi это законченный фреймворк для работы с портами ввода-вывода Raspberry Pi

WebIOPi позволяет контролировать состояние, и управлять всеми портами GPIO локально или удаленно, из браузера или любого приложения.
Возможности:
• REST API через HTTP и CoAP с поддержкой мультикаста
• Сервер написан на Python
• Работа с GPIO, Serial, I2C, SPI, 1-Wire
• Встроенная поддержка более чем 30 устройст, включая DAC, ADC, датчики…
• Совместимость с Python 2 и 3
• Великолепные возможности адаптации под нужды пользователей
• Защита логином-паролем
• Множество примеров

Установка WebIOPi

Для установки необходимо, что бы на Raspberry Pi был установлен Python, 2.7 или 3.2. Инсталяция выполняется четырьмя командами из терминала, локально или удаленно:

$ wget http://webiopi.googlecode.com/files/WebIOPi-0.6.0.tar.gz $ tar xvzf WebIOPi-0.6.0.tar.gz $ cd WebIOPi-0.6.0 $ sudo ./setup.sh 

Теперь можно запустить webiopi в командной строке:

$ sudo webiopi [-h] [-c config] [-l log] [-s script] [-d] [port]      Options:       -h, --help           Display this help       -c, --config  file   Load config from file       -l, --log     file   Log to file       -s, --script  file   Load script from file       -d, --debug          Enable DEBUG      Arguments:       port                 Port to bind the HTTP Server 

Правда сервер webiopi и состояние портов GPIO потеряются, как только вы завершите скрипт командой Ctrl-C или закроете окно терминала. Поэтому стоит запускать webiopi как сервис:

$ sudo /etc/init.d/webiopi start  и  $ sudo /etc/init.d/webiopi stop 

Если нужно, что бы webiopi стартовал автоматически при загрузке RPI, можно использовать следующую команду:

$ sudo update-rc.d webiopi defaults 

Пробуем

Теперь в локальной сети можно набрать http://[IP]:8000 на любом компьютере и получить доступ к web интерфейсу к RPI. [IP] надо заменить на IP Raspberry Pi. Логин по умолчанию «webiopi» и пароль «raspberry». Правда, автор программы говорит, что код работает не во всех браузерах. Рекомендую использовать Chrome.
Вот так, например, выглядит интерфейс для всех портов ввода-вывода:

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

WebCamBot – робот –фотограф

За основу проекта взят проект Cambot с некоторыми доработками. Драйвер моторов собирался не на макетке, а на плате Raspirobot, софт адаптирован под эту плату, добавлены web-кнопки управления web-камерой. На плате Raspirobot линейный регулятор заменен на импульсный.

Для управления электромоторами, подключенными к плате Raspirobot, используются четыре выхода RPI. Их назначение следующее:

# Left motor GPIOs LEFT_GO_PIN = 17 #PWM сигнал скорости LEFT_DIR_PIN = 4 #направление движения  # Right motor GPIOs RIGHT_GO_PIN = 10  #PWM RIGHT_DIR_PIN = 25 #направление движения 

Вебкамера работает в двух режимах – передача потокового видео с минимальным разрешением с помощью программы mjpg-streamer и фотографирование с максимальным разрешением. Выбор режима осуществляется запуском одного из скриптов: stream.sh, stream_stop.sh, photo.sh.

Как управлять web-камерой с помощью программ mjpg-streamer и fswebcam, вы наверняка знаете, поэтому комментировать содержимое скрипта не буду.
Скрипт фотографирования:

#!/bin/sh fswebcam -d /dev/video0 -p MJPEG -r 640x480  --jpeg 95 --shadow --title "cambot" --subtitle "Front camera" --info "" --save /usr/share/webiopi/htdocs/app/Raspirobot/ph.jpg -q 

Скрипт включения web- камеры:

#!/bin/sh  STREAMER=mjpg_streamer DEVICE=/dev/video0 RESOLUTION=160x120        #320x240 FRAMERATE=25 HTTP_PORT=8001 # check for existing webcam device if [ ! -e "/dev/video0" ]; then   echo "stream.sh: Error - NO /dev/video0 device" 2>&1 | logger   exit 2 fi PLUGINPATH=/home/pi/mjpg-streamer-r63 "$PLUGINPATH/$STREAMER" -i  "$PLUGINPATH/input_uvc.so -n -d $DEVICE -r $RESOLUTION -f $FRAMERATE" -o "$PLUGINPATH/output_http.so -n  -p $HTTP_PORT" -b 

Скрипт отключения камеры:

#!/bin/sh kill -9 `pidof mjpg_streamer`  

Web- интерфейс

Написание web-интерфейса для WebIOPi максимально упрощено. По сути, надо после загрузки страницы с помощью вызова функций из javascript webiopi создать элементы управления, вызывающие макросы, написанные на Python и хранящиеся на RPI. Затем элементы управления нужно добавить в HTML код страницы с помощью jQuery. Делается это следующим образом:

button = webiopi().createButton("bt_up", "/\\", go_forward, stop); // создание кнопки с id bt_up, текстом /\, вызывающей функцию go_forward $("#up").append(button); // добавление кнопки в div с id=up  

Функция go_forward выглядит следующим образом:

function go_forward() { 	webiopi().callMacro("go_forward"); }  

т.е. она просто вызывает макрос go_forward.

Поскольку мышкой нажимать на кнопки интерфейса не всегда удобно, можно продублировать управление с клавиатуры:

$(document).keydown(function(e) { 	switch(e.which) 	 { 		case 37:turn_left(); break;  //key Arroy left 		case 38:go_forward(); break;  // key Arroy up 		case 39:turn_right(); break;  //key Arroy right 		case 40:go_backward(); break;  //key Arroy down 		case 32:stop(); break;  //key Space 		case 75:camera(); break; ..//key K 		case 80:photo(); break;  // key P 	} }); 

Видео и фото в интерфейсе загружаются в соответствующий div после выполнения макроса:

       function camera() { 		$("#vid").html(''); 		webiopi().callMacro("camera"); 		$("#vid").html('<img width="320" height="240" src="http://raspberrypi.local:8001/?action=stream">'); 	}  	function photo() { 		$("#ph").html(''); 		webiopi().callMacro("photo"); 		$("#ph").html('<img src="Raspirobot/ph.jpg">'); 	}  

Конфигурирование WebIOPi

Файл конфигурации находится в папке /etc/webiopi/
Он состоит из нескольких блоков наподобии ini файлов windows, интерес прежде всего представляет блок, описывающий макросы:

[SCRIPTS] # Load custom scripts syntax : # name = sourcefile #   each sourcefile may have setup, loop and destroy functions and macros cambot =/usr/share/webiopi/htdocs/app/Raspirobot/cambot.py  

В этот блок надо добавить строку в формате name = sourcefile со скриптом python, содержащим макросы.
И второй блок, представляющий интерес – конфигурация сервера. В нем можно задать номер порта, на котором будет работать сервер, путь к файлу с паролем и корневую директорию для сервера.

[HTTP] # HTTP Server configuration enabled = true port = 8000  # File containing sha256(base64("user:password")) # Use webiopi-passwd command to generate it passwd-file = /etc/webiopi/passwd  # Use doc-root to change default HTML and resource files location #doc-root = /home/pi/webiopi/examples/scripts/macros  # Use welcome-file to change the default "Welcome" file #welcome-file = index.html 

Написание скрипта на Python

Для WebIOPi скрипт должен содержать функции setup и destroy которые будут вызываться при запуске сервера и его выключении. Как правило, в этих функциях определяется режим работы и состояние портов ввода-вывода.
Функции, которые должны быть доступны в web интерфейсе, должны предваряться идентификатором @webiopi.macro. Например, так выглядит описание функции go_forward, вызывающей движение робота вперед:

@webiopi.macro def go_forward():     left_forward()     right_forward()  

Для управления web-камерой используется команда call, вызывающая соответствующий скрипт:

def camera_start():     return_code = call("/usr/share/webiopi/htdocs/app/Raspirobot/stream.sh", shell=True)  

В результате у меня получился следующий интерфейс:

Отладка приложения

Если страница на сервере с вашим приложением не открывается, скорее всего в коде скрипта есть ошибка. Что бы ее локализовать, нужно запустить написанный скрипт ( в моем случае, например, командой sudo python ./cambot.py и посмотреть на получившиеся ошибки и предупреждения. Так же стоит посмотреть на ошибки в лог-файле webiopi, расположенном в папке /var/log/webiopi
Если страница загружается, но реакции на нажатия на элементы интерфейса нет – стоит посмотреть ошибки в javascript.

Видео – работа робота

Целиком исходные коды можно скачать здесь

ссылка на оригинал статьи http://habrahabr.ru/post/181930/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *