Pull to refresh

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

Reading time6 min
Views61K
В прошлом году мне в руки попал миникомпьютер 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.

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




Целиком исходные коды можно скачать здесь
Tags:
Hubs:
+31
Comments20

Articles

Change theme settings