viernes, 26 de julio de 2013

Preparando ficheros stage... ya tenemos robot!!!

¿Para que tanto hablar de robots si después no ponemos los conocimientos en funcionamiento? Eso se preguntará mucha gente y para ellos es esta entrada.

Dado que no tenemos robots, lo lógico es que los simulemos. Para simular podemos usar tanto gazebo que realiza una simulación en 3D, como Stage que esta íntimamente ligado al middleware Player que es el que tomamos la decisión de utilizar. Por lo tanto explicar Stage es lo lógico además de que aunque no queramos usar Player también se puede usar con ROS (el RSF más potente y recomendable para grandes proyectos en la actualidad).

Lo primero de todo es tener en cuenta que vamos a trabajar en GNU/Linux como siempre hemos asumido hasta ahora, aunque Player existe también para Windows.

Pasemos a los ficheros. Para que Player sepa que proxies debe activar en el servidor del robot, para que nuestro software se pueda conectar como cliente, se requieren de un fichero de configuración con la extensión .cfg pero si ese robot no existe y va a ser simulado y mostrado con Stage, se requerirán los ficheros del mapa (una imagen con extensión la que se desee) el .world y algunos .inc

Los .inc son ficheros que describen fisicamente al robot, los componentes adicionales que se van a incluir (en el caso del turtlebot la Kinect) y el entorno donde se moverá. Solo son útiles para Stage por lo que cuando usemos Player en el robot real, no los necesitaremos. Es habitual usar los .inc que ya existen y no crear unos, por el engorro que supone crearlos.

Los .world son ficheros que describen también físicamente al robot. Normalmente solo se usa un .world en una simulación y dentro de este es donde se incluyen los .inc anteriormente mencionados. Un ejemplo de .world puede ser este:

# ejemplo.world
# Authors: Gabriel Núñez Guerrero
# $Id$

include "map.inc"
include "irobot.inc"
include "kinect.inc"

# time to pause (in GUI mode) or quit (in headless mode (-g)) the simulation
quit_time 3600 # 1 hour of simulated time
paused 0

resolution 0.02

# configure the GUI window
window
(
  size [ 851.000 721.000 ] # in pixels
  scale 0.02857   # pixels per meter
  center [ 0  0 ]
  rotate [ 0  0 ]           
  show_data 1              # 1=on 0=off
)

# load an environment bitmap
floorplan
(
  name "Mapa"
  size [23.9 20.3 1]
  pose [0 0 0 0]
  bitmap "mapa.png"
)

roomba
(         
  # can refer to the robot by this name
  name "roomba"
  pose [-2 -5 0 90.00 ]

  kinect( pose [ 0.1 0 0 0 ] )
  blobfinder( colors_count 6 colors [ "red" "blue" "green" "cyan" "yellow" "magenta" ] )
  fiducial( range_max 8 range_max_id 5 )
  fiducial_return 1 
           
  localization_origin [0 0 0 0 ]

#  Odometria con errores simples inyectados para simular perdida
  odom_error [ 0.2 0.2 0.1 ]       # Error  x y z
                               
)
Dado que desde el principio estamos describiendo la creación de un turtlebot, en este fichero .world hemos incluido los .inc correspondientes al irobot, a una kinect y al mapa donde se moverá. Dentro estamos generando un robot que llamaremos roomba (osea el turtlebot) con el accesorio de Microsoft.

También estamos describiendo como sera la planta del mapa donde se moverá nuestro aparatito. Dentro del floorplant se indica el nombre del mapa, de donde se sacara la imagen, las dimensiones en metros y la posición  donde se pondrá.

Por último se define la ventana de visualización que usara Stage para mostrarnos el escenario con nuestro robot. Esta ventana debe guardar unas proporciones con respecto a la imagen y al tamaño que se ha indicado que tiene el mapa en medida real.

Los .cfg son los ficheros donde se especifican que proxies debe lanzar el servidor de player. Es el fichero más importante, es el alma de nuestro robot y es el que con pequeñas modificaciones se usará para ser ejecutado en el robot real, no solo en la simulación de Stage.

Fichero ejemplo de .cfg:

driver
(       
  name "stage"
  provides [ "simulation:0" ]
  plugin "stageplugin"
  worldfile "prueba.world"   
)

# Create a Stage driver and attach position2d and laser interfaces
driver
(
  name "stage"
  provides [ "6665:position2d:0" ]
  model "roomba"
)

driver
(
  name "mapfile"
  provides ["6016:map:0"]
  resolution 0.02857
  filename "mapa.png"
)

#driver
#(
#  name "wavefront"
#  provides ["planner:0"]
#  requires ["output:::position2d:1" "input:::position2d:0" "map:0"]
#  safety_dist 0.15
#  distance_epsilon 0.4
#  angle_epsilon 10
#  replan_dist_thresh -1
#  replan_min_time -1
#  alwayson 1
#)

#driver
#(
#  name "kinect"
#  provides ["color:::camera:0" "depth:::camera:1" "ptz:0" "imu:0"]
#  heatmap 0
#  downsample 1
#  color_resolution 2
#  depth_resolution 1
#)
Las líneas que comienzan con el caracter # se interpretan como comentarios. Bien, dicha esta obviedad debeis tener en cuenta que lo comentado puede ser descomentado y el robot simulado debería funcionar igual, pero la kinect debería existir de forma real conectada a algún USB de vuestro equipo. Recomiendo dejarlo tal como esta de momento.

Para que podais hacer experimentos y pruebas, dejo los ficheros en el siguiente enlace, para que puedan ser descargados.

https://docs.google.com/file/d/0B0kz7LhqitgreS13RnFqT2JLVWc/edit?usp=sharing

Uso de Player/Stage

Una vez preparado todo, hay que saber como echar a andar a un robot (simulado o físico) . Esto se hace con un simple comando: player robot.cfg

Pero Player también viene acompañado de multitud de aplicaciones que sirven de apoyo para la experimentación. Por ello es interesante mencionar algunos que pueden tener un interés especial:

playernav

Muestra en una pantalla con el mapa del que esta provisto el fichero de configuración del que proveeremos a nuestro robot. De todas formas, no tiene porque existir un mapa, pero ayuda a la localización. Con este programa, podemos ver en 2D el robot en su posición actual en el mapa, y dar una serie de waypoints que el robot seguirá.  

Uso playernav localhost:6665

localhost puede ser cualquier IP donde se este ejecutando un servidor de player. El puerto por defecto es el 6665 pero puede ser cualquier otro, según la configuración del fichero del robot.


El control es algo extraño, porque debe pinchaser con el ratón sobre el robot que se representa con el circulo rojo, y arrastrar al punto donde quiere que sea el destino del movimiento, dejándole marcado este como goal.

playerv

Permite subscribirse a los dispositivos configurados en el robot relacionados con el posicionamiento aunque también al laser, y mapa pero apenas son útiles en este programa. Además es posible comandar el robot, usando un vector de velocidad y ángulo.

Uso  playerv -h localhost -p 6016 

-h para indicar la IP del servidor player que se esta ejecutando (simulación o real) -p puerto del servicio position2d (6665 habitualmente y por defecto si no se indica)


El vector de movimiento se obtiene al pinchar sobre la caja roja y moverla sin soltar.

playercam

Muestra en una ventana la imagen que devuelve la cámara que pudiera haber instalada en el robot. 

Uso  playercam localhost:6665

playerjoy

Únicamente permite mover el robot sin interfaz gráfica, usando el teclado actuando directamente sobre la odometría. Es muy similar a como funcionaría controlándose como un videojuego.

Uso playerjoy localhost:6665


jueves, 25 de julio de 2013

Instalando Player/Stage

Trás mucho hablar de middleware de robots, lo primero a parte de tener un ordenador con GNU/Linux preparado, es realizar una instalación del software necesario para comenzar con las simulaciones que nos permitán hacer nuestros experimentos. Posteriormente este mismo software desarrollado puede ser llevado a nuestro hardware y ejecutado de la misma forma que en simulación.

Para instalar Player/Stage recomiendo seguir la siguiente guia, ya que es algo problemático, y es la web mas completa que conozco sobre este tema.

http://www.cnblogs.com/kevinGuo/archive/2012/05/03/2480077.html

Como advertencia, recomiendo hacer uso de una versión de Linux de 32bits, para evitar problemas con localicación de las librerías a la hora de las compilaciones.

Otra recomendación es referente a Stage. En el proceso de compilación no es dificil que aparezca algo como esto:

Stage-3.2.2-Source/libstage/region.cc:10: error:  
reference to ?Region? is
ambiguous
/usr/include/X11/Xutil.h:267: error: candidates are: typedef struct  
_XRegion* Region 

 Si se da este caso, editar los ficheros region.hh y region.cc Del segundo debemos cortar (no copiar) el código correspondiente al constructor y el destructor de la clase Region, y en el primer archivo pegar dicho código dentro de la clase. Es algo muy sencillo que resuelve el problema.