RoboTIC Parte II

Vamos a continuar con el desarrollo de RoboTIC dejando a un lado la parte mecánica y electrónica para centrarnos en la Raspberry pi y la programación de la misma. Damos por hecho que se a realizado la instalación del sistema operativo Raspbian Wheezy en la tarjeta SD y la configuración de la conexión WIFI que nos permitirá conectarnos por SSH y controlar remotamente nuestro robot. La versión de Raspbian utilizada es la Raspbian GNU/Linux 7.8.

Tomaremos nota de la IP asignada en la conexión y a ser posible que sea estática. Puntualizar que al realizar la instalación del SO y reiniciar nos aparecerá la ventana de configuración donde, entre otras interesantes opciones, podremos habilitar el acceso SSH y expandir el sistema de archivos (recomendable). También podemos acceder a la ventana de configuración en cualquier momento con el comando:

~$ raspi-config

Si tienes problemas para configurar la conexión WIFI sigue las siguientes instrucciones

 

STREAMING VíDEO

Para el streaming de vídeo con la webcam USB utilizamos MJPG-streamer, una aplicación que captura JPG de webcams compatibles con Linux-UVC, sistema de archivos u otros plugins de entrada y los distribuye como M-JPEG a través de HTTP para navegadores web, VLC y otros programas. Es el sucesor de uvc-streamer, una aplicación de streaming de Linux-UVC con Pan/Tilt.

Estos son los pasos para realizar la instalación.

~$ sudo apt-get update
~$ sudo apt-get upgrade
~$ sudo apt-get install libjpeg8-dev imagemagick subversion
~$ cd /usr/src/
~$ sudo svn checkout svn://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code
~$ cd mjpg-streamer-code/mjpg-streamer
~$ sudo make

 

Para comprobar que todo está bien ejecutamos el siguiente comando que nos devolverá lo siguiente:

~$ cd /usr/src/mjpg-streamer-code/mjpg-streamer 
~$ sudo ./mjpg_streamer -i "./input_uvc.so -y -n " -o "./output_http.so -n -w ./www"
MJPG Streamer Version: svn rev: 3:172  i: Using V4L2 device.: /dev/video0  i: Desired Resolution: 640 x 480  i: Frames Per Second.: 5  i: Format............: YUV  i: JPEG Quality......: 80  o: www-folder-path...: ./www/  o: HTTP TCP port.....: 8080  o: username:password.: disabled  o: commands..........: disabled

 

Ahora creamos un script para cuando queramos lanzar el stream de vídeo. Crearemos en primer lugar en "/home/pi/" el directorio "cambot" y crearemos dentro el fichero "stream.sh" con el editor nano.

~$ sudo mkdir cambot

~$ cd cambot

~$ sudo nano stream.sh

 

Copiar y pegar el siguiente código en el fichero "stream.sh".

#!/bin/sh

PLUGINPATH=/usr/src/mjpg-streamer-code/mjpg-streamer
STREAMER=$PLUGINPATH/mjpg_streamer
DEVICE=/dev/video0
RESOLUTION=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=/usr/local/lib

$STREAMER -i "$PLUGINPATH/input_uvc.so -y -n -d $DEVICE -r $RESOLUTION -f $FRAMERATE" -o "$PLUGINPATH/output_http.so -n -p $HTTP_PORT" -b


 

INSTALACIÓN DE WEBIOPI

Webiopi es un API escrita en Python para controlar, depurar y utilizar la GPIO de la RPi localmente o de forma remota, desde un navegador o desde cualquier aplicación. 

Para instalarlo sólo necesitaremos como requisito Python. Aunque por defecto ya está instalada en la distribución de Raspbian evitaremos problemas instalando Phyton usando apt-get antes de iniciar la de Webiopi.

~$ sudo apt-get install python-dev
~$ 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
 

A continuación podemos iniciar el servicio webiopi directamente desde la línea de comando con lo siguiente:

~$ sudo /etc/init.d/webiopi start

Comprobamos el funcionamiento abriendo nuestro navegador con la IP de la raspberry y el puerto 8000, algo como "192.168.1.50:8000". Nos solicitará usuario y contraseña que por defecto son "webiopi" y "raspberry" respectivamente.  Webiopi nos mostrará un menú con varias opciones en las que podemos interactuar con los puertos GPIO.

 

 

Hemos comprobado que funciona correctamente pero la consola queda ocupada y el servicio dejará de funcionar en cuanto pulsemos Ctrl+C o la cerremos. Tenemos la opción de arrancar, detener o reiniciar el servicio con los comandos:

~$ sudo /etc/init.d/webiopi start
~$ sudo /etc/init.d/webiopi stop
~$ sudo /etc/init.d/webiopi restart

 

Si queremos que webiopi se inicie automáticamente cuando arranque de la Rasperry podemos utilizar el siguiente comando: 

~$ sudo update-rc.d webiopi defaults

 

 

SCRIPT PYTHON PARA EL CONTROL DE LOS PUERTOS GPIO

La base del código fuente se basa en dos artículos publicados en la revista MagPI (Cambot). En primer lugar crearemos el script "cambot.py" en el que definiremos el estado inicial de los pines de la GPIO y las macros que podrán ser llamadas externamente para controlar los motores. Con el editor nano crearemos el script "cambot.py" en la ruta /home/pi/cambot y copiaremos el siguiente código:

#imports
import webiopi # Libreria GPIO GPIO = webiopi.GPIO # -------------------------------------------------- #
# Definicion constantes                           #
# -------------------------------------------------- #

# GPIOs motor izquierdo L1=17  # H-Bridge 1 L2=27 # H-Bridge 2

# GPIOs motor derecho R1=10 # H-Bridge 3 R2=9 # H-Bridge 4

# -------------------------------------------------- #
# Funciones motor izquierdo                           #
# -------------------------------------------------- #

def left_stop():     GPIO.output(L1, GPIO.LOW)     GPIO.output(L2, GPIO.LOW)      def left_forward():     GPIO.output(L1, GPIO.HIGH)     GPIO.output(L2, GPIO.LOW)      def left_backward():     GPIO.output(L1, GPIO.LOW)     GPIO.output(L2, GPIO.HIGH)

# -------------------------------------------------- #
# Funciones motor derecho                             #
# -------------------------------------------------- #

def right_stop():     GPIO.output(R1, GPIO.LOW)     GPIO.output(R2, GPIO.LOW)

def
right_forward():     GPIO.output(R1, GPIO.HIGH)     GPIO.output(R2, GPIO.LOW)

def
right_backward():     GPIO.output(R1, GPIO.LOW)     GPIO.output(R2, GPIO.HIGH)

# -------------------------------------------------- #
# Definicion macros                                #
# -------------------------------------------------- #

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

@webiopi.macro def go_backward():     left_backward()

@webiopi
.macro def turn_left():     right_forward()

@webiopi
.macro def turn_right():     right_backward()

@webiopi
.macro     def stop():     left_stop()     right_stop()      # -------------------------------------------------- #
# Iniciacializacion                                   #
# -------------------------------------------------- #

def setup():
# Instalacion GPIOs     GPIO.setFunction(L1, GPIO.OUT)     GPIO.setFunction(L2, GPIO.OUT)     GPIO.setFunction(R1, GPIO.OUT)     GPIO.setFunction(R2, GPIO.OUT)

def destroy():
# Resetea las funciones GPIO     GPIO.setFunction(L1, GPIO.IN)     GPIO.setFunction(L2, GPIO.IN)     GPIO.setFunction(R1, GPIO.IN)     GPIO.setFunction(R2, GPIO.IN) 

 

El código es bastante sencillo y se puede comprender la finalidad de cada bloque sin problemas. En primer lugar se asignan los puertos o pines GPIO de la raspberry a cada motor (L1,L2,R1,R2). Se crean las funciones de cada motor para avanzar, retroceder y paro y seguidamente las macros donde se concreta que funciones llamar en cada caso. Para que este script sea llamado al iniciar el servidor webiopi tendremos que especificarlo en el fichero de configuración "/etc/webiopi/config". Para ésto editaremos con nano el fichero config y especificaremos la ruta en la sección de scripts tal y como aparece a continuación:

[SCRIPTS]
# Load custom scripts syntax :
# name = sourcefile
#   each sourcefile may have setup, loop and destroy functions and macros
#myscript = /home/pi/webiopi/examples/scripts/macros/script.py
cambot = /home/pi/cambot/cambot.py

 

Aprovechando en este mismo fichero revisaremos la línea "doc-root" y "welcome-file" e indicaremos que se utilicen las credenciales del fichero "passwd" por lo que tendrá que quedar así:

[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
doc-root = /home/pi/cambot

# Use welcome-file to change the default "Welcome" file
welcome-file = index.html

 

Guardamos los cambios del fichero, salimos y cambiamos el usuario y contraseña de acceso por unos propios generando un fichero passwd mediante el comando "webiopi-passwd":

~$ sudo webiopi-passwd
WebIOPi passwd file generator
Enter Login: webiopi
Enter Password: 
Confirm password: 

Hash: e70c940a189251e9cd4515b3a1a6c6f02aa05c744a456ce360fe14bf2c5c0353
Saved to /etc/webiopi/passwd

 

Para terminar es necesario crear en la misma ruta /home/pi/cambot el fichero "index.html" que se a especificado en el "doc-root" del archivo de configuración anterior. En este fichero crearemos la interfaz web y los controles correspondientes usando jQuery y todas las funciones de javascript para a llamar a las macros escritas en Python. También incrustaremos el streaming de vídeo y por lo tanto tenemos que especificar correctamente la IP del servidor (Raspberry):

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="height = device-height, width = 420, user-scalable = no"/>
<title>CamBot</title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
function init(){
var button; button = webiopi().createButton("bt_up", "/\\", go_forward, stop); $("#up").append(button); button = webiopi().createButton("bt_left", "<", turn_left, stop); $("#middle").append(button); button = webiopi().createButton("bt_stop", "X", stop); $("#middle").append(button); button = webiopi().createButton("bt_right", ">", turn_right, stop); $("#middle").append(button); button = webiopi().createButton("bt_down", "\\/", go_backward, stop); $("#down").append(button);
}
function go_forward(){ webiopi().callMacro("go_forward");
}
function go_backward(){ webiopi().callMacro("go_backward");
}
function turn_right(){ webiopi().callMacro("turn_right");
}
function turn_left(){ webiopi().callMacro("turn_left");
}
function stop(){ webiopi().callMacro("stop");
} webiopi().ready(init);
</script>
<style type="text/css"> button {
margin:5px5px5px5px;
width:50px;
height:50px;
font-size:24pt;
font-weight: bold;
color: black;
}
</style>
</head>
<body>
<div id="content" align="center">
<img width="320" height="240" src="http://192.168.1.50:8001/?action=stream"><br/>
<div id="up"></div>
<div id="middle"></div>
<div id="down"></div>
</div>
</body>
</html>

 

En principio está todo listo y sólo nos queda reiniciar el servidor webiopi para cargar la nueva configuración y lanzar el script de streaming:

~$ sudo /etc/init.d/webiopi restart
~$ sudo sh /home/pi/cambot/stream.sh

 

Accedemos con el navegador a la IP correspondiente y el puerto 8000 y si todo está correctamente conectado y configurado podremos disfrutar manejando el robot por casa.

PD: No desesperes si algo no funciona a la primera pues es lo mas habitual. 


 

BIBLIOGRAFIA

http://www.bot-thoughts.com/2013/04/raspberry-pi-telepresence-rover.html

http://raspberryparatorpes.net/empezando/raspi-config-configuracion-inicial-de-raspbian/

https://learn.adafruit.com/adafruits-raspberry-pi-lesson-3-network-setup/setting-up-wifi-with-occidentalis

https://code.google.com/p/webiopi/wiki/INSTALL

http://www.hackplayers.com/2013/12/construye-tu-propio-rover-teledirigido-con-rpi-webiopi.html

http://www.instructables.com/id/Create-an-internet-controlled-robot-using-Livebots/step5/Get-the-webcam-streamer-for-Raspberry-Pi/