В прошлом году мне в руки попал миникомпьютер 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.
Видео – работа робота
Целиком исходные коды можно скачать здесь
Автор: sergkit
Как можно связаться с автором?)очень нужно