1
Algoritmo de localización y
mapeo simultáneo con un robot
móvil utilizando ROS y Gazebo
Proyecto Fin de grado
Autor: Alejandro González González-Regueral
Tutor: Begoña C. Arrue Ullés
2
3
Proyecto Fin de Grado
Electrónica, Robótica y Mecatrónica
Algoritmo de localización y mapeo simultáneo con
un robot móvil utilizando ROS y Gazebo
Autor:
Alejandro González González-Regueral
Tutor:
Begoña C. Arrue Ullés
Profesor titular
Dep. de Automática
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2016
4
5
Proyecto Fin de Carrera: Algoritmo de localización y mapeo simultáneo con un robot móvil
utilizando ROS y Gazebo
Autor: Alejandro González González-Regueral
Tutor: Begoña C. Arrue Ullés
El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros:
Presidente:
Vocales:
Secretario:
Acuerdan otorgarle la calificación de:
6
Sevilla, 2013
El Secretario del Tribunal
7
A mi familia
A mis maestros
8
9
Agradecimientos
La ignorancia afirma o niega rotundamente; la ciencia duda.
Voltaire
ntes de acabar esta etapa de mi vida, concluyendo con esta serie de palabras que voy a
escribir a continuación me gustaría recordar a cada una de esas personas que han ejercido
un papel clave, no solo en mi enseñanza académica, si no en la enseñanza de la
personalidad.
Muchas de mis cualidades no nacieron de la nada, se potenciaron principalmente gracias a maestros y
familia. A mis padres les debo la mayor parte del trabajo.
Mi madre siempre confío en mí y aposto por potenciar mi personalidad. Me enseñó a ser una persona
luchadora, que persigue sus sueños sin descanso y que todo es posible digan lo que digan los demás.
A mi padre le debo la constancia, el buen hacer de las cosas y la sensatez, además de todo el cariño
recibido.
Estas son la serie de cualidades que hacen una buena persona y un buen ingeniero. No todos son
cálculos. Hay que saber cómo tratar a las personas, como llevar a cabo tus objetivos y como ser una
persona con determinación.
Agradecer a cada uno de mis maestros que mostro un interés especial por mi y también a los que no.
A veces no nos damos cuenta de la importancia que tiene el profesorado, pero sin ellos, muchos de
nosotros que ya estamos acabando, estaríamos mucho más perdidos en un mundo bastante difícil.
Ellos nos enseñan que siempre hay que intentar hacerlo mejor y que es necesario trabajar.
Por último, agradecer a mis amigos todos los ánimos en los momentos de más dificultad. Ellos te
ayudan a salir con más fuerza para saber hacerlo mejor.
Alejandro González González-Regueral
Sevilla, 2016
A
10
11
12
Resumen
l trabajo de divide en varias partes. Se va a desarrollar un robot en 3D de forma simulada
implementado a partir de la plataforma ROS. Una vez desarrollado el robot y representado
en el entorno de simulación Gazebo, se pasará a dotarle de propiedades dinámicas y
cinemáticas para dotarle de movimiento. Finalmente, se dotará al robot de la capacidad de
reconocimiento y mapeo en un entorno desconocido, técnica denominada SLAM (simultaneous
mapping and location) basada en el filtro de Kalman extendido. Como futuras aplicaciones se
propondrá una posible manera de implementación a nivel de hardware.
E
13
14
.
15
Índice
Agradecimientos .......................................................................................................................... 9
Resumen ..................................................................................................................................... 12
Índice .......................................................................................................................................... 15
Índice de Tablas .............................................................................. ¡Error! Marcador no definido.
Índice de Figuras ......................................................................................................................... 17
Notación ..................................................................................................................................... 20
1 introducción ....................................................................................................................... 22
1.1 Objetivo ....................................................................................................................... 22
1.2 Metodología ................................................................................................................ 22
2 SLAM (Simultaneous mapping and location) ................................................................. 24
2.1 Introducción ................................................................................................................ 24
2.2 Proceso SLAM ............................................................................................................ 24
2.3 Filtro Extendido de Kalman con SLAM ..................................................................... 26
2.3.1 Implementación SLAM en el Proyecto. .............................................................. 31
2.4 Hardware ..................................................................................................................... 32
2.4.1 Sensores de medida ............................................................................................. 32
2.4.1.1 Sonar ........................................................................................................................... 32
2.4.1.2 LIDAR ........................................................................................................................ 33
2.4.1.3 Cámaras ...................................................................................................................... 34
2.4.2 Sensores de odometría ......................................................................................... 34
3 Plataforma Software ......................................................................................................... 36
3.1 Introducción ................................................................................................................ 36
3.2 Sistema Operativo ....................................................................................................... 36
3.3 ROS (Robotic Operating System) ............................................................................... 37
3.3.1 Introducción ........................................................................................................ 37
3.3.2 Estructura ............................................................................................................ 37
3.3.3 Instalación de ROS e inicio ................................................................................. 39
3.3.4 Compilación ........................................................................................................ 41
16
3.3.5 Paquetes utilizados .............................................................................................. 42
3.3.6 Rviz ..................................................................................................................... 43
3.3.7 Gazebo ROS ........................................................................................................ 44
3.4 Gazebo ......................................................................................................................... 45
3.4.1 Introducción a Gazebo ........................................................................................ 45
3.5 FreeCad ....................................................................................................................... 46
4 Descripción del método implementado............................................................................ 48
4.1 Introducción ................................................................................................................ 48
4.2 Descripción de la solución adoptada ........................................................................... 48
4.2.1 Características ..................................................................................................... 48
4.3 Descripción general ..................................................................................................... 49
4.3.1 Creación del directorio de trabajo ....................................................................... 49
4.3.2 Construcción del robot en formato URDF .......................................................... 49
4.3.3 Testeo del robot ................................................................................................... 51
4.3.4 Aplicación del SLAM ......................................................................................... 52
5 Detalles de implementación .............................................................................................. 53
5.1 Introducción ................................................................................................................ 53
5.2 Preparando el entorno de trabajo ................................................................................. 53
5.3 Desarrollo del robot en URDF .................................................................................... 54
5.4 Localización y mapeo .................................................................................................. 64
6 conclusiones y trabajo futuro ........................................................................................... 70
7 Anexo .................................................................................................................................. 73
7.1 Codigos ....................................................................................................................... 73
7.1.1 CMakeFile ........................................................................................................... 73
7.1.2 Package.xml ........................................................................................................ 77
7.1.3 Modelo URDF ..................................................................................................... 78
7.1.4 robot_slam.launch ............................................................................................... 83
7.2 Enlaces ........................................................................................................................ 86
7.3 Mensajes ROS ............................................................................................................. 86
17
Índice de Figuras
FIGURA 1-DIAGRAMA EKF-SLAM ........................................................................................................................... 25
FIGURA 2: SLAM EN SUPERFICIES CURVAS .............................................................................................................. 25
FIGURA 3-ESTIMACIÓN DE RECTAS MEDIANTE RANSAC ....................................................................................... 26
FIGURA 4-MATRIZ DE COVARIANZA DEL EKF-SLAM ............................................................................................. 27
FIGURA 5-MATRIZ DEL MODELO DE MEDIDA ............................................................................................................. 28
FIGURA 6-MATRIZ H .................................................................................................................................................. 28
FIGURA 7- MATRIZ H COMPLETA ............................................................................................................................... 28
FIGURA 8-MODELO ROBOT MOVIL............................................................................................................................. 29
FIGURA 9-MODELO LINEALIZADO ............................................................................................................................. 29
FIGURA 10- JACOBIANA DEL LANDMARK .................................................................................................................. 29
FIGURA 11- JACOBIANA DEL LANDMARK PARA ÁNGULOS ....................................................................................... 29
FIGURA 12-MATRIZ DE RUIDO EN MODELO ............................................................................................................... 30
FIGURA 13-COMPORTAMIENTO DE UN SONAR SRF04 .............................................................................................. 32
FIGURA 14-DIMENSIONES Y EMISIÓN DE PULSO ........................................................................................................ 32
FIGURA 15-RANGO DEL LIDAR ................................................................................................................................ 33
FIGURA 16-DESCRIPCIÓN DE ADQUISIÓN DE UNA CÁMARA CON PROFUNDIDAD .................................................... 34
FIGURA 17-ORGANIZACIÓN EN ROS ......................................................................................................................... 38
FIGURA 18-LOGO DE LA DISTRIBUCIÓN INDIGO IGLOO ............................................................................................ 39
FIGURA 19-CÓDIGO CMAKEFILE ............................................................................................................................... 41
FIGURA 20-CÓDIGO CMAKEFILE ............................................................................................................................... 41
FIGURA 21-DEMOSTRACIÓN EN RVIZ ........................................................................................................................ 43
FIGURA 22-DIAGRAMA DE INTERCONEXIÓN ENTRE NODOS ..................................................................................... 45
FIGURA 23-DESCRIPCIÓN DIMENSIONAL DEL LÁSER HOKUYO ................................................................................ 47
FIGURA 24-DESARROLLO DE HOKUYO EN FREECAD ............................................................................................... 47
FIGURA 25- ROBOT MODELO ROOMBA ..................................................................................................................... 54
FIGURA 26-DEFINICIÓN DE VARIABLES MEDIANTE XACRO Y CABEZERAS PARA PLUGINS ..................................... 55
FIGURA 27-DEFINICIÓN DE UNA RUEDA MEDIANTE XACRO ..................................................................................... 56
FIGURA 28-DESCRIPCIÓN DE AMBAS RUEDAS USANDO XACRO ............................................................................... 56
FIGURA 29-DESCRIPCIÓN DEL LÁSER HOKUYO CON EL PLUGIN DE GAZEBO .......................................................... 57
FIGURA 30- ESTRUCTURA PARA EL LASER ................................................................................................................ 58
FIGURA 31- PLUGINS DE COLORES PARA GAZEBO .................................................................................................... 59
FIGURA 32-REPRESENTACIONES EN GAZEBO ........................................................................................................... 60
FIGURA 33-REPRESENTACIÓN EN RVIZ ..................................................................................................................... 60
18
FIGURA 34-DIAGRAMA ESTRUCTURAL DEL URDF .................................................................................................. 61
FIGURA 35-MENSAJE TIPO SENSOR_MSGS/LASERSCAN ........................................................................................... 62
FIGURA 36-MENSAJE TIPO GEOMETRY_MSGS/TWIST ............................................................................................... 63
FIGURA 37-MUESTRA DE TF EN RVIZ ....................................................................................................................... 63
FIGURA 38-MENSAJE TIPO TF .................................................................................................................................... 64
FIGURA 39-PARAMETROS DE CONFIGURACIÓN DE ROBOT_SLAM.LAUNCH ............................................................... 65
FIGURA 40-ASOCIACIÓN DE LOS EJES DE REFERENCIA ............................................................................................. 65
FIGURA 41- NODOS NECESARIOS QUE HAY QUE LANZAR ADEMÁS DE HECTOR_MAPPING ...................................... 66
FIGURA 42-SELECCIÓN DE MAPA ESTATICO .............................................................................................................. 67
FIGURA 43-DIBUJO DEL MAPA ELABORADO EN EL ESCENARIO SMALL_INDOOR MEDIANTE RVIZ .......................... 68
FIGURA 44-VISTA SUPERIOR DE SMALL_INDOOR EN GAZEBO ................................................................................. 69
19
20
Notación
URDF: Unified Robot Description Format
EKF: Extended Kalman Filter
SLAM: Simultaneous Mapping and Location
TCP: Transport Control Protocol
ROS: Robotic Operating System
21
22
1 INTRODUCCIÓN
oy en día cada vez es más común encontrarnos con entornos completamente o
parcialmente automatizados. Esto surge de las constantes necesidades e inquietudes del
ser humano por mejorar en el ámbito tecnológico, conseguir ejecuciones más repetitivas
y precisas y hacer la vida algo más fácil. Es por ello que aparecen los robots móviles. Estos necesitan
de conocimiento del entorno en el que se mueven. Resulta interesante ver los diferentes algoritmos y
aplicaciones que se dan para dotar al robot de un conocimiento fiel del mundo que le rodea.
Debido a estas inquietudes se decide hacer este trabajo en el que en un entorno simulado podremos
comprobar que conocimiento y como de bueno puede tener un robot móvil cualquiera. Cuáles son sus
ventajas y limitaciones.
1.1 Objetivo
on este trabajo se pretende desarrollar desde cero un robot móvil que aplique la técnica de
SLAM en un entorno simulado. Como herramienta software principal se usará ROS con
sus diferentes funcionalidades y Gazebo.
Se planteará una implementación en software la cual escapa al alcance de este documento.
1.2 Metodología
ara partir desde cero en la creación de nuestro robot móvil el primer paso consiste en crear la
estructura de nuestro robot. Dicha implementación se realiza con el lenguaje conocido como
URDF, derivado de SFD. Se compone de descripciones en lenguaje .xml las cuales son
interpretadas por el programa de simulación Gazebo para representar las características del robot, tanto
geométricas, como de aspecto y dinámicas. Es requisito necesario contar con la implantación de ROS
(Robotic Operating System) en nuestro S.O, en mi caso Ubuntu LTS 14.04. Gazebo funcionará como
un nodo asociado a ROS.
Una vez podemos representar la estructura del robot en Gazebo en ROS debemos rotarlo de capacidad
de movimiento y de sensores. Esto se realiza mediante la implementación de plugins que nos brinda
la plataforma Gazebo y sus usuarios.
Por último, debemos dotar al robot la capacidad de aplicar la técnica de SLAM para reconocer el
entorno. Esta implementación se realizará gracias a nodos facilitados por la comunidad ROS los cuales
concretaremos más adelante.
H
C
P
23
Por último, se han indicado las pautas para una implementación de bajo coste sobre la plataforma
Arduino con sensores tipo sonar y comunicaciones inalámbricas implementando protocolos de
comunicación servidor web implementados sobre una Raspberry pi.
24
2 SLAM (SIMULTANEOUS MAPPING AND
LOCATION)
2.1 Introducción
l término SLAM viene del acrónimo simultaneos mapping and location. Fue desarrollado
por primera vez por Hugh Durrant-Whyte and John J. Leonard. SLAM se centra en el
problema de construir un mapa en un entorno desconocido para un robot móvil.
Podemos dividir el problema SLAM en varias partes: la extracción de Landmarks, la asociación de
datos, la estimación del estado, la actualización del estado y la actualización de Landmarks. El método
más extendido para este cálculo es el EKF o filtro extendido de Kalman.
2.2 Proceso SLAM
l objetivo del proceso SLAM en definitiva es conseguir actualizar la posición del robot en
el entorno. La posición del robot normalmente viene dada por las medidas de odometría
pero estas suelen ser bastante erróneas. Para ello se equipa de medidas de distancia para
poder realizar una corrección de la posición. Conocida la posición de Landmarks o marcas somos
capaces de actualizar la posición calculando la distancia actual a estas marcas en cada instante de
tiempo
El corazón de este proceso es el EKF. El filtro primeramente se encarga de asignar fiabilidad a los
sensores de medida y odometría y al modelo mediante las matrices de covarianza del error. Cuanto
más preciso sea el sensor, menor serán los valores de la matriz. En cada instante de tiempo, el filtro se
encarga de medir la distancia a las landmarks y actualizar dicha posición.
Seguidamente, estima la posición actual del robot con las medidas adquiridas. El esquema de
funcionamiento del filtro es el siguiente:
E
E
25
Figura 1-Diagrama EKF-SLAM
Las landmarks deben ser figuras fácilmente reconocibles y sencillas geométricamente hablando. Por
ejemplo, en una habitación vacía, típicas landmarks son las paredes, líneas rectas con esquinas
definidas.
Cuando nos encontramos con superficies curvas se producen reflexiones que flaseran las medidas y
hacen que la estimación empeore.
Figura 2: SLAM en superficies curvas
Para conseguir que las landmarks en una habitación sean las paredes, se implementan técnicas como
RANSAC la cual consigue asociar paredes a líneas para el robot mediante un algoritmo el cual en una
medida del escáner laser elige aleatoriamente distintas medidas y realiza una aproximación de
mínimos cuadrados de las medidas aleatorias. Si estas forman una recta, toma esa zona como un
landmark.
26
Figura 3-Estimación de rectas mediante RANSAC
2.3 Filtro Extendido de Kalman con SLAM
l filtro SLAM se encarga de estimar la odometría del robot. Suponemos un mapa estático
en el que se encuetran una serie de landmarks. Básicamente el proceso que se realiza en el
EKF es el siguiente
1. Actualiza la posición con las medidas de odometría actuales
2. Actualiza la posición estimada reobserbando las landmarks
3. Añade nuevas landmarks al proceso actual
El proceso comienza de la siguiente manera. Inicialmente nuestro robot tiene una posición respecto al
sistema de referencia global x,y. Cuando el robot se desplaza y gira, este pasa a tener una posición
x+dx, y+dy con un angulo de giro theta+dtheta. A partir de aquí entran en juego las landmarks. Todos
estos datos deben ser almacenados en distintas matrices para realizar los cálculos pertinentes.
E
27
Matriz de estados X: Es una de las matrices más importantes a tener en cuenta. Se
trata de una matriz Nx1 en la cual se almacenan las posiciones del robot (incluyendo
posiciones angulares) en cada instante y la posición de las landmarks. Dicha matriz
tendrá más filas cuantas más landmarks tenga. Por cada landmark se añaden 2 filas
más.
Matriz de covarianza P: la covarianza define como de fuerte es la relación entre dos
variables, es decir, indica la fiabilidad entre la estimación de las posiciones y su posición real.
La matriz de covarianza P incluye la covarianza de la posición del robot, la covarianza de la
posición de las landmarks y la covarianza entre la posición del robot y la de las landmarks.
Para explicar la estructura de la matriz de covarianza nos basaremos en la siguiente imagen.
Figura 4-matriz de covarianza del EKF-SLAM
La matriz A pose la covarianza de la posición del robot en una matriz 3x3 con x,y,theta
B se corresponde con la covarianza de la pirmera landmark. Su dimensión es 2x2
C es la covarianza de la última landmark. Su dimensión es 2x2
D es la covarianza entre la posición del robot y la primera landmark. Su dimensión es 2x2
E es la covarianza entre la primera landmark y el estado del robot. E se puede deducir a partir
de D. Su dimensión es 2x2.
F posee la covarianza de la última landmark con la primera de forma que G tiene la covarianza
entre la primera landmark y la última.
A partir de aquí podemos deducir que la manera de construir la matriz es intuitiva. Inicialmente, al no
detectar landmarks, la matriz P es igual a la matriz A pues solo posee el estado del robot. A medida
que van apareciendo landmarks, la matriz va aumentando su dimensión por lo que el cálculo
computacional será mayor a medida que se encuentren mayor número de landmarks
Matriz de ganancia K: Dicha matriz proporciona las ganancias que aplicamos a cada uno
28
de los parámetros, es decir, si una landmark se encuentra a 10 cm pero su fiabilidad no es muy
alta, daremos una ganancia de 5 cm. Se trata de una matriz de Nx2 donde la primera columna
corresponde a que ganancia deberían de tener cada una de las posiciones en términos de rango
y la segunda columna en términos de transporte.
Jacobiano de la medida del modelo H: Esta matriz está íntimamente relacionada con la
matriz del modelo de medida la cual se define a partir de la siguiente formula
Figura 5-matriz del modelo de medida
Donde lambda x es la posición de una landmark y x la actual posición estimada del robot. De la misma
forma con y. Theta es la orientación estimada del robot. Vr es la velocidad lineal y 𝑣𝜃 es la velocidad
angular. Definimos entonces la matriz H como como
Figura 6-Matriz H
Esta matriz mide los cambios de bearing y range. Por ejemplo, el primer elemento mide el cambio de
rango respecto a la variación de posición en x con la landmark. Cuantas más landmarks hay, mayor es
la matriz para que haya compatibilidad siguiendo la siguiente estructura
Figura 7- Matriz H completa
Matriz del Jacobiano de la predicción del modelo A: Dicha matriz intenta predecir el
comportamiento del modelo. Originalmente definiríamos la matriz de predicción del modelo
como.
29
Figura 8-Modelo robot móvil
Con x la medida de la posición, theta el gire, incremento de t el desplazamiento diferencial en distancia
y termino de q el ruido. Si linealizamos el modelo y depreciamos los términos de ruido podemos
expresar nuestra matriz A como
Figura 9-Modelo linealizado
Matrices de Jacobianos específicos para SLAM Jx y Jz: El jacobiano de predicción Jx es
el que se aplica a las landmarks respecto al estado del robot y es muy similar al jacobiano de
predicción del modelo, pero sin el término de giro pues las landsmarks permanecen estáticas.
Figura 10- Jacobiana del landmark
El jacobiano de predicción Jz se aplica a las landmarks también pero referido al range, bearing y se
define como
Figura 11- Jacobiana del landmark para ángulos
Matrices de ruido Q y R: Una de las preposiciones del filtro de
Kalman es que el ruido es gaussiano. Por ello definimos la matriz
Q como una matriz 3x3 que representa la covarianza del ruido en
el modelo. Por otro lado, R es la matriz 2x2 que mide la covarianza
del ruido en la medida de los sensores respecto al range y el bearing.
30
Una vez explicada todas las matrices que entran en juego en la técnica de SLAM pasamos a explicar
los diferentes pasos.
Los pasos en un filtro EKF son dos: predicción y actualización.
1. En el primer paso trataremos de estimar la posición a través de nuestras medidas de odometría.
Para ello, se actualiza el vector de estado X con las nuevas medidas. También debemos
actualizar el jacobiano de predicción del modelo, A, con cada iteración
La matriz Q también tiene en cuenta los desplazamientos por lo que habrá que actualizarla.
Figura 12-Matriz de ruido en modelo
Por último, calculamos la nueva matriz de covarianza de la posición del robot como
Donde 𝑝𝑟𝑟 corresponde a la matriz 3x3 entre las primeras 3 filas y 3 columnas, las cuales dependen
solo del modelo. Las demás son las correlaciones entre landmarks.
2. En el segundo paso, actualizamos el estado tras la re-observación de landmarks. Este paso
es necesario, pues debemos corregir los errores producidos por la odometría. Estos errores
se calculan a partir de las medidas de distancia a las landmarks.
El primer paso en la fase de actualización es el cálculo de la ganancia del filtro. Este cálculo se
realiza con la siguiente fórmula.
31
El término 𝐻𝑃𝐻𝑇 + 𝑉𝑅𝑉𝑇es denominado covarianza de innovación o matriz S. Es usada en la
asociación de datos para la obtención de las landmarks.
Finalmente calculamos el nuevo vector de estados con la ecuación
Este proceso se repite para cada landmark asociada.
Cuando el robot descubre una nueva landmark, esta debe ser añadida y por tanto supone un
redimensionamiento de todas las matrices asociadas a los landmarks. Podemos traducir esto a que la
matriz de covarianza P añade una nueva submatriz asociada al nuevo landmark. El vector de estados
también añade una nueva fila reservada para la nueva landmark.
Es ahora cuando cobran importancia las matrices Jx y Jz puesto que en la nueva matriz de
covarianza P tenemos lo siguiente
2.3.1 Implementación SLAM en el Proyecto.
Gracias a la herramienta ROS, una vez que sabemos cómo funciona la técnica SLAM, podremos
situarnos en un nivel superior de abstracción y manipular los parámetros del filtro para comprobar los
distintos comportamientos.
El desarrollo de dicho filtro ya ha sido realizado y se implementará mediante el paquete hector_slam
desarrollado por Stefan Kohlbrecher.
Podremos variar los parámetros de covarianza en el error para ver cómo se comporta el filtro y la
adquisición.
32
2.4 Hardware
2.4.1 Sensores de medida
continuación mostraremos los sensores de medida de distancia más comunes aplicados
en la robótica movil
2.4.1.1 Sonar
El sonar es un dispositivo de medida que típicamente utiliza ondas sónicas para calcular la distancia a
un objeto. Su funcionamiento es sencillo: Se emite un pulso que dispara una onda. Esta rebota con un
objeto y vuelve a su origen. Durante todo este tiempo, un pulso a permanecido a nivel alto. A partir
de ese tiempo se mide la distancia al objetivo mediante una sencilla regla a partir de la velocidad del
sonido.
Figura 13-Comportamiento de un sonar SRF04
Figura 14-Dimensiones y emisión de pulso
El principal problema de los sonares es que suelen ser bastante imprecisos debidos a las reflexiones
A
33
con los objetos lo que hace que se falsen las medidas por ello hay que realizar filtros de medidas que
sumado a que no suelen ser muy rápidos, los convierten en unos sensores algo lentos respecto a las
demás opciones de mercado. Además, el disparo es en línea recta. Cuando el origen está en
movimiento las reflexiones son constantes y la eficacia disminuye aún más
Cabe decir que es una de las opciones más baratas.
2.4.1.2 LIDAR
La opción más utilizada hoy en día son los láseres LIDAR. Esto es debido a que son mucho más
fiables que los sonares. Tienen la capacidad de recibir medidas simultáneas en varias direcciones a la
vez con una alta tasa de muestreo
Figura 15-Rango del LIDAR
Al funcionar mediante láseres, la recepción es mucha más rápida, menos propensa a ruidos y por tanto
más precisa. Con un láser LIDAR podemos controlar el ángulo de separación entre cada una de las
medidas.
Típicamente se alrededor de 700 muestras por medida en un LIDAR convencional usado en un robot
móvil lo que nos da una precisión aproximada de:
180
700= 0.25º
Una de las marcas más usadas son los dispositivos Hokuyo. Es el implementado como ejemplo en la
plataforma ROS. El datasheet de uno de estos dispositivos se adjunta en el anexo.
34
Estos sensores son perfectos para realizar una medida de distancia precisa en 2D por ello son los más
usados a la hora de realizar SLAM 2D.
2.4.1.3 Cámaras
Una de las posibles opciones a la hora de adquisición de medidas de distancia son las cámaras. Esta
medida se realiza mediante la triangulación de la medida entre dos cámaras.
También existen cámaras de profundidad como Kinnect la cual es capaz de medir profundidad con
una sola cámara.
Figura 16-Descripción de adquisición de una cámara con profundidad
El principal problema de las cámaras es que el procesamiento de imagen conlleva mucho computo.
Sin embargo, las cámaras nos permiten realizar técnicas de SLAM en 3D, cosa que con otros sensores
no es posible.
2.4.2 Sensores de odometría
ara poder estimar la posición del robot, además de saber cómo hallar las distancias a las
landmarks, debemos tener conocimiento de la propia odometría del robot. Para ello es
necesario conseguir una IMU (Inertial Measurenmet unit) la cual es capaz de medirnos
aceleraciones producidas en cada uno de los ejes del sistema de referencia.
Son populares los acelerómetros. Estos son capaces de medir la aceleración en cada uno de los
ejes del sistema de referencia. Mediante la integración de estos parámetros somos capaces de
conseguir medidas de posición.
P
35
También son bastante utilizados los giróscopos los cuales nos dan aceleraciones angulares. A
partir de aquí podemos averiguar los ángulos que gira nuestro robot.
Por lo general, son dispositivos con bastante error por ello es preciso tenerlo en cuenta a la hora
de implementar nuestro EKF.
36
3 PLATAFORMA SOFTWARE
3.1 Introducción
n este capítulo se abordan todas las herramientas software que han sido necesarias para
desarrollar le trabajo. El elemento más importante es la plataforma ROS ya que todos los demás
elementos giraran en torno a este. Se comentará brevemente la jerarquía que sigue ROS para
posteriormente aplicar sus recursos.
Hablaremos del entorno de simulación 3D, Gazebo, el cual se relaciona directamente con ROS.
Por último, hablaremos del entorno desarrollador de Arduino para una futura aplicación.
3.2 Sistema Operativo
l Sistema operativo sobre el que se va a desarrollar nuestra
operación es Linux. Hemos elegido la plataforma Ubuntu LTS
14.04 ya que es fácil de descargar, libre y con buena compatibilidad para
todo aquello que necesitamos
La instalación del sistema operativo puede seguirse fácilmente en la
página oficial de Ubuntu la cual se añadirá al anexo de enlaces
La elección de Linux ante otros sistemas operativos es que contamos con que soporta la plataforma
ROS a diferencia de otros SS.OO. Además, este es un sistema de tiempo real, ideal para nuestra
aplicación.
Es necesario tener un cierto manejo y conocimiento de las órdenes Shell en Linux pues van a utilizarse
muchas de ellas para movernos por el entorno. Ordenes como:
ls: permite visualizar el contenido de un directorio.
cd: cambia el directorio actual de trabajo a la ruta que se le indique
source .bash: ejecuta archivos .bash. Por ejemplo, es necesario siempre que iniciemos nuestro
Proyecto en ROS para recuperar lo último que se realizo
cp: con este comando copiamos archivos de una ruta a otra de manera sencilla
E
E
37
mkdir: creamos carpetas únicamente ejecutando el código e indicando el nombre de la carpeta
rm: con dicho comando borramos archivos o incluso carpetas de manera recursiva si se aplica
la opción -r.
Es importante conocer el entorno Linux para entender cómo se realizan las compilaciones, como
mostrar resultados por consola y ejecutar comando con soltura por ella para manipular parámetros de
manera rápida
3.3 ROS (Robotic Operating System)
3.3.1 Introducción
ROS se define como un framework para el desarrollo software de robot que funciona como sistema
operativo en un clúster heterogéneo.
ROS provee los servicios que ofrece cualquier sistema operativo: abstracción del hardware, control de
dispositivos de bajo nivel, implementación de funcionalidades de uso común, paso de mensajes entre
procesos y mantenimiento de mensajes.
Esta soportado por sistemas UNIX y es software libre. Lo que hace de ROS una herramienta útil es
que toda la comunidad comparte sus creaciones de una manera sencilla. Además, cualquiera puede
implementar dichos desarrollos.
3.3.2 Estructura
ROS se basa en una estructura de grafos compuesta por nodos. Este nodo se corresponde con cada
uno de los procesos que se ejecutan. Estos procesos intercambian mensajes entre sí. Cada uno de estos
nodos es típicamente, un proceso POSIX y su socket conexiones TCP. Cada mensaje se compone de
una estructura concreta. Los nodos se comunican entre sí por topics los cuales hacen de canales de
forma que un nodo publica un mensaje en un topic para comunicarse con otro no.
En cuanto a la estructura ordena podemos decir que ROS se compone de los siguientes elementos
38
Figura 17-Organización en ROS
Stack: Las pilas o stacks contienen ciertos paquetes relacionados entre sí.
Packages: Los paquetes contienen dentro la definición de los mensajes que utilizan los
nodos asociados a estos.
Puede que algunos paquetes de una pila dependan de otra de forma que todos los paquetes están
interconectados.
Dentro de los paquetes encontramos los siguientes elementos
Package.xml: Este archivo contiene todos los paquetes de los que depende el paquete en
cuestión. Se definen aquellos que van a ser construidos y los que van a ejecutarse bajo las
etiquetas <build_depend/> y <run_depend/>
CMakeFile: este archivo se encarga de compilar el paquete. Deben incluirse todas las
dependencias y códigos que se hayan desarrollado si existiesen. Estos códigos tendrán
librerías específicas que hacen referencia a paquetes de ROS por ello es necesario definir
cada uno de estos paquetes para que el compilador lo tenga en cuenta
Carpetas: normalmente se designa las siguientes carpetas: src, launch, bag. En la carpeta
src se guarda el código que se desea compilar y ejecutar como nodo. En launch se guardan
los lanzadores. Estos lanzadores se encargan básicamente de ejecutar de manera automática
los nodos que indiquemos. También pueden ejecutar otros lanzadores.
Para movernos por ROS con fluidez se han desarrollado una serie de comandos Shell que
simplifican la búsqueda. Comentaremos a continuación los más relevantes
39
rosls: con esta orden podemos ver el contenido de la carpeta ROS que queramos cuando nos
encontremos en cualquier directorio. Como puede intuirse viene de unir ros+ls
roscd: al igual que el anterior comando hace que podamos cambiar de directorio fácilmente
rostopic [opción]: es utilizado para manejar los topics. Por ejemplo, rostopic list nos
muestra que topics están activos actualmente. Rostopic echo cmd_vel nos muestra que se
está publicando en el topic cmd_vel
rosrun [nodo]: Sirve para ejecutar un nodo.
rosmsg: Da información sobre los mensajes.
roslaunch: ejecuta archivos .launch
roscore: ejecuta el nodo principal de ROS. Es necesario ejecutar este nodo para que todos
los demás funcionen. Es el encargado de gestionar toda la comunicación entre los nodos.
3.3.3 Instalación de ROS e inicio
La curva de aprendizaje de ROS es algo difícil al principio, pero tenemos a nuestra disposición
multitud de recursos que nos brinda la propia comunidad de ROS como foros o la wiki de la propia
página. En dicha Wiki nos muestran los pasos necesarios para comenzar en ROS en la sección Getting
Started.
Lo primero que debemos hacer es instalar la distribución de ROS que deseemos. En nuestro caso
elegiremos la distribución Indigo.
Figura 18-Logo de la distribución Indigo Igloo
Esta reléase fue creada para Ubuntu LTS 14.04 por lo que es la más indicada para nuestra aplicación.
Se caracteriza entre otros aspectos por incluir catkin-based para construir paquetes en ROS.
40
El primer paso antes de la instalación de ROS es la actualización de los repositorios de Ubuntu
mediante el comando.
sudo apt-get update
Una vez actualizados los repositorios instalamos la distribución
sudo apt-get install ros-indigo-desktop-full
De esta forma además de instalar ROS estamos instalando algunos paquetes esenciales como son
Rviz, entornos de simulación 2D/3D. etc…
Ahora debemos crear nuestro directorio de trabajo o workspace. Típicamente en la carpeta de
nuestro usuario ejecutaremos le siguiente comando para crear el directorio
mkdir ~/catkin_ws/
Este será el nombre de nuestro directorio. Ahora es necesario crear un paquete. Para crear un paquete
catkin ejecutamos:
catkin_create_package robot_movil
Se creará un paquete con el nombre de robot_movil y contendrá un CMakeFile y un package.xml
que debemos modificar acuerdo con nuestras necesidades.
Crearemos a continuación las carpetas que necesitemos como src/ para los códigos y launch/ para
los archivos .launch.
41
3.3.4 Compilación
Todo paquete debe contener un archivo CMakefile.txt. En él se definen los elementos necesarios para
que nuestro paquete sea compilado correctamente. Hay varias funciones a tener en cuenta, pero en
nuestro caso vamos a centrarnos en las siguientes:
find_package: añade los paquetes necesarios para la compilación. Añadimos los mismo que
en las dependencias. En nuestro caso tendríamos el siguiente add_package:
Figura 19-Código CMakefile
Include_directories: Esta función incluye la ubicación de los directorios que se van a usar
Figura 20-Código CMakefile
Dicha macro indica la dirección de los directorios
El CMakefile incluye más funciones como libraries_target para señalar rutas de librerías creadas por
nosotros mismos necesarias para la compilación.
También posee funciones para crear nuestros propios tipos de mensajes y poder usarlos como
42
créate_msg. En nuestro caso no será necesario.
El resto del código se incluye en el anexo CMakeFile.
Para construir el paquete ejecutamos el comando en nuestro workspace
catkin_make
Si todo ha ido correctamente se habrá generado nuestro ejecutable.
3.3.5 Paquetes utilizados
Para llevar a cabo nuestro proyecto ha sido necesario descargar del repositorio de ROS una serie de
paquetes, los cuales describiremos a continuación y que papel desempeñan.
hector_slam: Esta pila contiene una serie de paquetes que hacen que podamos aplicar la
técnica SLAM en nuestro robot de manera sencilla. Este paquete fue desarrollado para crear
mapas de entornos aplicando EKF-SLAM con sensores laser tipo Hokuyo. Son importantes
nodos como hector_mapping el cual realiza el filtrado o hector_geotiff que crea un .tiff que
contiene el mapa.
Tf: Este paquete es uno de los más importantes. Es el encargado de realizar las
transformaciones de los ejes de referencia de nuestro robot con respecto un punto de
referencia global y entre las propias partes del robot.
Robot_state_publisher: Publica, gracias al paquete TF la posición del robot en cualquier
instante respecto a un sistema de referencia que se le marque. En nuestro caso, respecto a
odom el cual es el centro de odometría y es el punto de partida del robot
Joint_state_publisher: Al igual que robot_state_publisher, publica el estado de los ángulos de
las uniones del robot en cada instante. Ambos paquetes (robot_state_publisher y
joint_state_publisher) son necesarios para cuando creamos nuestro robot y lo representamos
en Rviz.
Gazebo_ros: Es la adaptación de Gazebo a ROS. Gracias a él podremos representar nuestro
robot en 3D y aplicarle movimiento. También podremos observar el rango que está aplicando
el láser.
43
Xacro: Como se explicó en la creación del robot, es necesario ejecutar xacro para que nuestro
código sea interpretable como un URDF.
Teleop_twist_keyboard: Este paquete permite que teleoperemos nuestro robot usando el
teclado. El funcionamiento básico es que asocia una tecla con un incremento de velocidad
angular o linear (o ambas) en un sentido. Las publicaciones son realizadas en el topic
/cmd_vel el cual a su vez publica en Gazebo para accionar las ruedas del robot. El tutorial
que explica su funcionamiento más detalladamente además de instalación y enlace al código
en github puede verse en el anexo en Enlaces.
3.3.6 Rviz
Rviz es una herramienta de visualización que nos brinda ROS. Su misión principal será la de
observador. El entorno de simulación 3D es Gazebo y Rviz visualiza lo que se está produciendo en
Gazebo.
Rviz nos permite añadir elementos de visualización como cámaras, sensores laser, transformaciones
de los ejes de referencia y un largo etc.
En nuestro caso guardaremos una configuración de .rviz la cual tiene los siguientes elementos.
Figura 21-Demostración en Rviz
44
Global options: aquí debemos colocar como frame nuestro sistema de referencia global. En
nuestro caso es el frame odom en el cual publica TF
Path: El frame /trayectory guarda la trayectoria que va realizando el robot
Pose: Muestra la posición respecto al sistema global del robot
Robot Model: Muestra si el modelo URDF se ha realizado correctamente y se han
conseguido enlazar cada uno de los sistemas de referencias locales correctamente.
LaserScan: Muestra el láser y publica en el topic /scan.
3.3.7 Gazebo ROS
Gazebo_ros es el nodo que implementa Gazebo en la plataforma ROS. Gracias a él conseguimos que
todo aquello que se produce en Gazebo tenga repercusión en ROS.
Por ejemplo, gracias al plugin para el driver diferencial, cuando activemos el plugin, este comenzará
a publicar en el nodo de ROS cmd_vel con mensajes tipo geometry_msgs/Twist. La estructura de
dichos mensajes puede observarse en el anexo Mensajes ROS. Este tipo de mensaje consta de dos
vectores de 3 componentes cada uno que definen la velocidad linear y angular en los distintos ejes de
referencia.
Para entenderlo todo de forma más clara, ROS tiene un nodo que nos muestra el modelo estructural
en cuanto a nodos, topics se refiere. Hay que ejecutar el siguiente comando
rosrun rqt_graph rqt_graph
45
Figura 22-Diagrama de interconexión entre nodos
Como podemos observar, el nodo teleop_twist_keyboard publica en el topic /cmd_vel con
mensajes tipo geometry_msgs/Twist en el nodo gazebo por lo que este último esta subscrito
al topic, mientras que teleop_twist_keyboard es el publicador.
De la misma forma vemos que Gazebo publica en robot_state_publisher, hector_mapping y
hector_trayectory_server mediante el topic /tf para actualizar la posición del robot en todo
momento.
Joint_state_publisher es otro plugin definido en la estructura URDF de gazebo el cual
publica la posición de cada articulación en robot_state_publisher.
Robot_state_publisher debe informar a hector_mapping y hector_trayectory_server de cuál
es la posición actual del robot en todo momento para que se pueda estimar la posición y
mostrar la trayectoria descrita.
3.4 Gazebo
3.4.1 Introducción a Gazebo
azebo es el entorno de simulación que utilizaremos para nuestro proyecto. Es una plataforma
que nos brinda infinidad de recursos muy útiles para un entorno robotizado. Tiene en cuenta
aspectos dinámicos como la inercia, masas, viscosidades y podemos combinar infinidad de
estructuras para construir el robot que deseamos dotándole de las necesidades que demande, tanto
sensores como accionamientos.
Además, podemos construir entornos para la simulación. La propia plataforma además nos brinda
G
46
entornos ya realizados para interiores y exteriores.
Otro punto interesante es que te permite implementar varios plugins para dotar de movimiento al robot
o para implementar los sensores.
El idioma que interpreta Gazebo en SDF. Nosotros escribiremos en URDF el cual es el idioma que
implementa ROS para su plataforma de visualización Rviz. Los archivos escritos en URDF se
interpretan como SDF en Gazebo para representar nuestro robot.
Debido a que solo podemos representar formas geométricas sencillas como cubos, esferas o conos,
existe la opción de añadir un mesh el cual sustituye una estructura sencilla como un cubo por un objeto
desarrollado en una herramienta CAD bajo el formato .dae.
3.5 FreeCad
reeCad es una herramienta de diseño CAD que se puede descargar de forma fácil del repositorio
de Ubuntu ejecutando el siguiente comando.
sudo apt-get install freecad
El objetivo es crear la estructura del láser para darle un aspecto más realista. Para basarnos en un
diseño se ha utilizado el láser hokuyo --- cuyas medidas pueden consultarse en la página oficial de
hokuyo. Se adjunta el enlace en anexo.
Mediante un cubo y un cono de dos bases obtenemos un diseño sencillo que simula nuestro laser. El
resultado podemos verlo a continuación.
F
47
Figura 23-Descripción dimensional del láser Hokuyo
Figura 24-Desarrollo de Hokuyo en FreeCad
Este archivo lo guardaremos en formato .dae para que pueda ser interpretado por Gazebo.
48
4 DESCRIPCIÓN DEL MÉTODO
IMPLEMENTADO
4.1 Introducción
ste capítulo trata de explicar detalladamente, sin entrar en configuraciones, como se ha
desarrollado el trabajo. Ya que toda la aplicación se desarrolla sobre software, se comentará
cada uno de los pasos que se ha seguido desde la construcción del modelo del robot, hasta
la aplicación de la técnica SLAM.
4.2 Descripción de la solución adoptada
4.2.1 Características
Al tratarse de un entorno simulado no poseemos restricciones hardware. A continuación, se exponen
las ventajas que nos proporciona el entorno de programación ROS para nuestra aplicación en concreto
Flexibilidad: El framework ROS nos brinda multitud de posibilidad y parámetros para
desarrollar nuestra aplicación. Se ha optado por aplicar el paquete hector_slam pero existen
otros para realizar aplicaciones más básicas o más específicas. Esta sirve como punto de
partida
Recursos: gracias a la comunidad activa de ROS y a sus tutoriales, resulta fácil aprender de
manera autodidacta a manejarse en la plataforma. Se resuelven muchas de las dudas que se
van planteando en la comunidad, además, cada paquete subido tiene asociado un tutorial que
muestra cómo usar dicho paquete. Se indica también quien es el mantenedor por si el usuario
está interesado en entrar en contacto para una duda especifica.
Realismo: la plataforma de simulación Gazebo brinda muchas características de
configuración que hacen de nuestro modelo un fiel reflejo de la realidad. Esto hace que
nuestra simulación sea mucho más realista y por tanto más fiable. Convierte nuestra
aplicación menos propensa a errores
A continuación, se va a proceder a realizar una descripción general para la implementación de dicho
proyecto
E
49
4.3 Descripción general
uestro objetivo principal, como bien hemos recalcado hasta ahora, es la aplicación de la
técnica SLAM en un robot construido desde cero, en un entorno de simulación 3D y
analizar el comportamiento. Por tanto, el primer paso será la construcción del robot.
4.3.1 Creación del directorio de trabajo
Lo primero que debemos hacer siempre al iniciarnos en ROS es crear un workspace tal y como se
definía en el capítulo Instalación de ROS e inicio.
Una vez nos situamos en nuestro workspace crearemos el paquete robot_movil mediante el comando
catkin_create_package y el nombre del paquete.
Dentro de la carpeta src se encontrará nuestro paquete robot_movil. Cuando ejecutemos en nuestro
workspace source devel/setup.bash nuestro paquete pasará a formar parte del directorio de carpetas de
ROS en nuestro sistema y podremos usar los comandos rápidos de ROS.
4.3.2 Construcción del robot en formato URDF
Antes de ponernos a programar, lo primero es saber cuál es el diseño de nuestro robot. Al basarse en
un robot comercial tipo Roomba como el de la figura, trataremos de aproximarlo a figuras geométricas
sencillas. Por ello contará de las siguientes partes:
Un cuerpo cilíndrico. La forma del cuerpo será un cilindro con el diámetro más grande que la
altura. Esto añade estabilidad a nuestro robot y hace sencilla la construcción.
Dos ruedas. Serán cuerpos cilíndricos que simularán las ruedas y estarán ubicadas en los
extremos del robot, situadas justo a la mitad.
Base de apoyo para el láser. La estructura del LIDAR será desarrollada con la herramienta
FreeCad y tiene que ir colocada en la parte superior del cuerpo, sin embargo, debe realizarse
una figura geométrica que lo simule antes de renderizarlo. Esta estructura será un pequeño
cuadrado.
Es necesario definir las uniones entre las distintas piezas por lo que contaremos con las siguientes:
Unión de las ruedas. Las ruedas estarán unidas al cuerpo principal del robot girando alrededor
del eje z de manera indefinida.
Unión del láser. Se unirá la superficie del LIDAR con el cuerpo del robot de manera fija. No
N
50
interesa que el láser este en movimiento respecto al robot.
Una vez tengamos claro el diseño pasaremos a implementarlo.
Para implementarlo, como se indicaba en el capítulo 3.4, se programará sobre URDF. URDF no es
más que una extensión de XML aplicada a la creación de robots. El primer paso es describir en dicho
idioma cada una de las piezas en una jerarquía estructural (igual que html) y comprobar que el diseño
está correcto.
ROS nos brinda un lanzador que nos permite ver de manera rápida si nuestro modelo está
correctamente construido en el visualizador de ROS, Rviz.
roslaunch urdf_tutorials display.launch model:=[nombre-del-modelo].urdf
Si todo ha ido correcto debemos añadir los campos necesarios para implementar nuestro modelo en la
plataforma Gazebo.
Para ello se añadirán algunas etiquetas como propiedades inerciales y superficies de colisión. Gazebo
necesita saber estos parámetros para dotar a nuestro robot de propiedades dinámicas y saber cómo
interactuar cuando choca con una superficie. Esto añade realismo a nuestro modelo.
También se añadirán plugins propios de Gazebo como un driver diferencial para dotar de actuación a
las ruedas de nuestro robot y conseguir desplazarnos por el mapa. Parece imprescindible también tener
un láser LIDAR con el que medir las distancias en el entorno, es por ello que ya ROS nos brinda un
plugin basado en el láser Hokuyo.
Por último, para simplificar nuestro modelo se hará uso de la herramienta xacro. Básicamente lo que
conseguimos con xacro es tener nuestro código más ordenado. Este nos permite definir variables
globales en nuestro diseño como el radio de las ruedas, el numero pi, etc… Además de poder definir
macros que harán que con la descripción de una instancia como es la rueda, podamos crear todas las
ruedas que queramos de una manera muy sencilla.
A la hora de implementarlo, xacro funciona como un nodo de ROS que se encarga de interpretar el
código xacro y convertirlo a URDF. A su vez, cuando el URDF se incluye en Gazebo este pasa a
interpretarse como SDF.
51
Para mostrar nuestro diseño con las descripciones xacro en Rviz al igual que se ha descrito antes
basta con ejecutar el código en la consola
roslaunch urdf_tutorials xacro.launch model:=[nombre-del-modelo].urdf
En este punto tendremos nuestro robot completamente construido. El siguiente paso será visualizar
que está pasando en ROS.
4.3.3 Testeo del robot
En este punto, ya hemos aplicado los distintos plugins a nuestro robot desde Gazebo pero ahora hace
falta probar que todo está funcionando correctamente antes de aplicar SLAM.
Nuestro objetivo es ver que somos capaces de accionar nuestro robot a partir de mensajes
geometry_msgs/Twist sobre el topic /cmd_vel tal como se indica en la documentación del plugin. Esta
documentación se puede consultar en el anexo Enlaces. También debemos visualizar que los mensajes
del láser LIDAR implementado se están publicando correctamente en el topic /scan con mensajes tipo
sensor_msgs/LaserScan.
Para ello debemos ejecutar los siguientes nodos:
Gazebo: realizamos un spawner para colocar nuestro modelo URDF en el simulador.
Xacro: es requisito necesario para que nuesrto código URDF sea interpretado correctamente
Robot_state_publisher y joint_state_publisher: deben ser incluidos para que Rviz pueda
visualizar el movimiento de las articulaciones y la posición del robot respecto a un punto de
referencia.
Keyboard_twist_teleop: Este paquete ha sido descargado del repositorio de ROS y hace que
podamos manejar nuestro robot con el teclado de nuestro ordenador. Este nodo está
programado en Python. Lo que hace básicamente es publicar mensajes geometry_msgs/Twist
en el topic /cmd_vel de forma que el plugin que hemos añadido en la descripción URDF de
Gazebo es capaz de interpretarlo y mover el robot.
Rviz: es necesario lanzar el nodo de la aplicación de visualización para comprobar que está
52
pasando cuando ejecutamos comandos en Gazebo.
Para dicha comprobación se va a crear un lanzador .launch bajo el nombre de testeo el cual
básicamente lanza todos los nodos nombrados.
Para verificarlo de manera gráfica se hará uso de la herramienta de ROS, Rqt, la cual nos da un
diagrama estructural de cómo están relacionados todos nuestros nodos con los distintos topics.
Por último, falta aplicar la técnica de SLAM. Para ello lo primero es descargar la stack de ROS,
hecto_slam. Una vez lo hemos descargado mediante el comando en consola.
4.3.4 Aplicación del SLAM
sudo apt-get install ros-indigo-hector-slam
Pasamos a incluirlo en nuestro lanzador que se llamará robot_slam.launch. En este fichero se añadirán
los siguientes nodos:
hector_mapping: se encarga de realizar la estimación de la posición del robot la cual podemos
visualizar en Rviz
hector_trayectory_server: guarda la trayectoria que hemos realizado en el reconocimiento del
mapa.
Hector_geotiff: crea una imagen del mapa que puede guardarse como .giff.
Una vez se han añadido al robot_slam.launch y representación.launch se ejecuta y tendremos
reconocimiento visual de la creación del mapa y la estimación de la posición del robot. Podremos
moverlo mediante la aplicación de teleoperación del teclado y describir un mapa estático. Se
variarán los parámetros que nos brinda el hector_slam y se expondrán distintos resultados en el
siguiente capítulo.
53
5 DETALLES DE IMPLEMENTACIÓN
5.1 Introducción
continuación, va a redactarse como se ha realizado el proceso de puesta en marcha de
manera detallada siguiendo el guion del capítulo anterior. Entraremos en más detalle
mostrando el funcionamiento del código y la variación de los parámetros.
5.2 Preparando el entorno de trabajo
o primero que debemos hacer es instalar ROS y los paquetes que vamos a necesitar. Para ello
ejecutamos los comandos
sudo apt-get install ros-indigo-full-desktop
sudo apt-get install ros-indigo-teleop-twist-keyboard
sudo apt-get install ros-indigo-hector-slam
sudo apt-get install ros-indigo-tf
Al igual que hemos explicado en el capítulo anterior, creamos el directorio de trabajo
mkdir ~/catkin_ws/
mkdir src
catkin_create:_package robot_movil
A continuación, para construir nuestro paquete, ejecutamos el comando
catkin_make
Una vez tenemos el workspace listo, pasamos a crear nuestro modelo URDF
A
L
54
5.3 Desarrollo del robot en URDF
omo hemos indicado, el idioma URDF se basa en .xml por lo que tenemos una estructura en
árbol donde las etiquetas más importantes tienen una serie de atributos.
Hay distintos elementos que debemos distinguir a la hora de desarrollar nuestro modelo.
Esencialmente vamos a definir los siguientes elementos: visual, collision, links y plugins
Visual: esta etiqueta define la forma de cada uno de los elementos del robot mediando el
atributo geometry. En nuestro caso, al ser un robot diferencial como el que se muestra en la
figura tendremos que definir una estructura cilíndrica para el cuerpo, dos estructuras
cilíndricas para las rudas y una estructura cúbica para el láser.
Figura 25- Robot modelo Roomba
Pueden añadirse otros atributos al campo geometry para añadirle color entre otros
Collision: Es necesario para poder representar nuestro robot en Gazebo. Define una superficie
de colisión que dota al robot de la capacidad de percepción de colisiones.
Inertial: También necesario para una estructura en Gazebo, definen las características
inerciales del robot.
Como ejemplo podemos ver la estructura del cuerpo en el siguiente código.
Links: Otra parte imprescindible de en la definición del robot son las uniones o links. Gracias
a ellas unimos partes visuales del robot. Las uniones pueden ser:
Continuous: La articulación gira alrededor de un eje sin límite.
Revolute: La articulación gira alrededor de un eje entre ciertas cotas definidas
Fixed: Configura una articulación fija.
C
55
Prismatic: articulación prismática en un eje. Consigue un movimiento longitudinal
De las cuales nosotros usaremos una unión fixed para añadir el láser al cuerpo y dos continuous para
las ruedas. Estas giran en torno al eje y de manera indefinida.
Al tener dos ruedas iguales, se ha utilizado la herramienta xacro para facilitar la definición. Xacro
permite definir macros y definiciones en el lenguaje URDF que simplifican las definiciones. Al poder
definir variables globales, definimos el ancho de las ruedas y el radio, por ejemplo, como una variable.
Además, definiremos como una instancia o macro la definición de la rueda pasando ciertos
parámetros. Esta definición nos recuerda a una función: definimos ciertos parámetros de entrada, los
cuales son características del modelo y nos devuelve dicho modelo con dichas características. De esta
forma, cambiando los parámetros de entrada, en una sola línea podemos definir una pieza visual, una
unión, colisión, etc..
A continuación, mostramos el uso de xacro para la definición de una rueda
Figura 26-Definición de variables mediante xacro y cabezeras para plugins
Como vemos con xacro:property definimos variables globales a las que daremos el valor que nos
convenga
56
Figura 27-Definición de una rueda mediante xacro
Podemos apreciar los parámetros de entrada que debemos introducir al invocar la macro.
Sufijo: Indica si es la rueda izquierda o la derecha
Parent: indica el padre para reflejarlo en el link
Reflect: variable que indica que se encuentra en el lado opuesto. Vale -1 para situar la rueda
reflejada respecto de su posición positiva en un eje
Offset xyz: Indica el desplazamiento respecto al sistema de referencia local de la pieza
Ancho: ancho de la rueda
Radio: radio de la rueda
Giro_x: radianes que tenemos que girar el eje x para que gire en la dirección que queremos
En este código observamos la llamada a la macro.
Figura 28-Descripción de ambas ruedas usando xacro
Vemos que de esta forma simplificamos gran parte del código
57
Cuando compilemos el código, se realizará una traducción de un archivo urdf.xacro a urdf.
Ahora es necesario añadir los colores a nuestro robot y los plugins
Gazebo plugins: La etiqueta plugin hace que podamos añadir códigos compilados que añaden
funcionalidades a nuestro robot. En nuestro caso hemos añadido dos plugins: un láser hoyuko
necesario para aplicar la técnica SLAM y un controlador de diferencial para accionar las
ruedas como robot diferencial.
A continuación, mostramos la definición del plugin para el láser hokuyo.
Figura 29-Descripción del láser Hokuyo con el plugin de Gazebo
Como podemos observar se pueden modificar una serie de campos para especificar como se
representará este en Gazebo. Entre ellos se encuentran los límites de alcance del láser, el rango angular,
el número de muestras que recogerá, el tipo de ruido que se le añade, la velocidad con la que se
actualiza la medida, la desviación estadística del error y el nombre del topic en el que publica.
Un parámetro no menos importante es visualize el cual hará que cuando representemos el robot en
Rviz podamos visualizar el campo de alcance del láser.
58
Figura 30- Estructura para el laser
Para incorporar el láser al robot es necesario añadir el soporte visual y la unión con el cuerpo
Uno de los parámetros más interesantes es el mesh el cual nos permite sustituir una forma sencilla de
geometry por un desarrollo CAD. El diseño del láser se ha desarrollado con la herramienta FreeCad
el cuál se explicará más adelante. Obtenemos un.dae que es capaz de interpretar Gazebo. La creación
del mesh se explicará más adelante
El código implementado desarrollado para el plugin puede verse en el Enlaces del anexo.
Para el plugin de control diferencial de las ruedas se definen una serie de parámetros al igual que el
láser que son necesarios como la distancia entre las ruedas o el radio de las mismas. Puede consultarse
el código en el anexo Modelo URDF.
De igual manera, para consultar el código implementado se adjunta el enlace de github en Enlaces
Para que los colores en Gazebo debemos añadir las siguientes etiquetas.
59
Figura 31- plugins de colores para Gazebo
Si representamos nuestro robot en Gazebo podemos observar el resultado definitivo. La
representación se realiza mediante ROS la cual se explicará más adelante
60
Figura 32-Representaciones en Gazebo
Figura 33-Representación en Rviz
61
Pueden apreciarse todos los elementos del robot. El cuerpo, el láser hokuyo, las ruedas y la
visualización del láser.
El código completo puede consultarse en el anexo Modelo URDF.
Entre las utilidades de ROS encontramos un comando que nos muestra directamente la estructura de
nuestro robot. El comando es el siguiente
urdf_to_graphiz [nombre del archivo.urdf]
Con el cual obtenemos el siguiente esquema.
Figura 34-Diagrama estructural del URDF
Con este útil grafico podemos observar la jerarquía que sigue nuestro robot. La pieza base_link es el
“padre” de las demás. Nos muestra también las uniones entre las distintas piezas, además de la
orientación y posición en el eje de referencia local.
En este punto podemos probar que se está publicando en los topics en los que publica el laser
(laser_scan) y cmd_vel que refleja las velocidades del robot.
Los comandos que se ejecutan son:
62
rostopic echo /laser_scan
rostopic echo /cmd_vel
Obteniendo el siguiente resultado
Figura 35-Mensaje tipo sensor_msgs/LaserScan
63
Figura 36-Mensaje tipo geometry_msgs/Twist
Como podemos observar, se publica cada uno de los campos que indicamos en el tipo de
mensaje adjuntado en el anexo
Al desplazar el robot, se experimenta un desplazamiento respecto del sistema de referencia global, lo
que hace que se publique en tf. Si representamos en Rviz los ejes de referencia
Figura 37-Muestra de TF en Rviz
Y ejecutamos el comando
rostopic echo /tf
64
Figura 38-Mensaje tipo TF
Podemos visualizar los campos del mensaje. Se adjunta la estructura del del mensaje en el anexo
Mensajes ROS
5.4 Localización y mapeo
n este punto se va a explicar cómo ejecutar todos los nodos de manera que consigamos
realizar un mapeo de un entorno en interior. Para ello se ha creado el archivo
robot_slam.launch.
E
65
Figura 39-Parametros de configuración de robot_slam.launch
En primer lugar, se definen una serie de argumentos que serán utilizados por los siguientes nodos que
lanzaremos. Es importante definir los frames para que tf puede realizar una correcta transformación.
En nuestro caso la referencia local va a ser base_link el cual era el cuerpo del robot y nuestra referencia
global será odom. Se define también el topic en el que se publican las adquisiciones del láser. Estos
son mensajes tipo laser_scan. Las definiciones de dichos mensajes pueden consultarse en el anexo
Mensajes ROS.
Es importante indicar que el escenario de prueba está definido por el parámetro
<include file="$(find hector_gazebo_worlds)/launch/small_indoor_scenario.launch"/>
Existen otra serie de escenarios en dicha ruta pero para nuestra aplicación es suficiente con un mapa
sencillo como small_indoor.world.
Figura 40-Asociación de los ejes de referencia
Tal y como indicábamos los argumentos definidos pasan como parámetros necesarios de los nodos.
En este caso, se le indica al nodo hector_mapping cuáles son los frames de referencia para poder
estimar la posición. Los demás parámetros de configuración pueden verse en el código adjuntado en
el anexo robot_slam.launch.
66
Seguidamente corremos más nodos
Figura 41- Nodos necesarios que hay que lanzar además de hector_mapping
Urdf_spawner es el encargado en cargar el modelo URDF que hemos definido en Gazebo.
Robot_state_publisher y joint_state_publisher son necesarios además de para que nuestro
robot se represente en Rviz, para publicar el estado constante de la posición y articulaciones
del robot.
Como podemos observar en las primeras líneas este launch invoca a otro mediante la línea
<include file="$(find robot_movil)/launch/representacion.launch">
<arg name="trajectory_publish_rate" value="4"/>
</include>
Dicho launch ejecuta una serie de nodos:
Rviz: Ejecuta rviz con la configuración que se explicó en el apartado Rviz. De esta forma
visualizamos la construcción del mapa 2D
Hector_trayectory_server: con este nodo obtenemos la trayectoria que va describiendo el
robot a medida que se va desplazando
Hector_geotiff: Es el encargado de dibujar el mapa en 2D. Tiene un argumento opcional para
guardar el mapa que se ha obtenido. En dicho nodo es importante tener en cuenta uno de los
parámetros
67
Figura 42-Selección de mapa estatico
Dicho parámetro hace que el mapa sea estático. Si se configura como dinámico, cada cierto tiempo
se borran los datos almacenados del mapa y se va creando otro. Este parámetro es de utilidad cuando
el robot solo quiere conocer su posición dentro de un entorno local. En nuestro caso, queremos que
reconozca todo el entorno de manera fiel para que cree un mapa global por esta razón, el mapa debe
ser estático. Esta opción consume más recursos, pero es más precisa.
Bastará entonces con ejecutar el siguiente comando para poner en funcionamiento nuestro robot.
roslaunch launch/robot_slam.launch model:=urdf/modelo2.xacro.urdf
Ejecutamos también la teleoperación del robot mediante el comando
rosrun teleop_twist_keyboard teleop_twist_keyboard
Tras manejar el robot y recorrer el escenario obtenemos el siguiente resultado.
68
Figura 43-Dibujo del mapa elaborado en el escenario Small_indoor mediante Rviz
69
Figura 44-Vista superior de Small_indoor en Gazebo
Podemos apreciar que se reconoce perfectamente el entorno del mapa. A partir de aquí el
robot tiene conocimiento del entorno.
La línea verde representa la trayectoria que ha seguido el robot.
70
6 CONCLUSIONES Y TRABAJO FUTURO
omo hemos podido observar, gracias a la plataforma ROS aprovechamos el trabajo que
otros ponen a nuestra disposición para que sirvan de base al nuestro. De una manera
relativamente sencilla hemos conseguido crear una simulación bastante fiel de lo que
tendríamos en un robot de servicio que tiene que recorrer el entorno doméstico para ubicarse
Se ha conseguido aprender a manejar la plataforma ROS la cual escapaba al temario impartido en el
grado. Se consiguen los objetivos propuestos en la introducción.
Como trabajo futuro se propone una implementación con hardware de la técnica SLAM. Para iniciar
dicha tarea se ha creado un sistema de adquisición con un sensor ultrasónico SR04 conectado a un
arduino. Este intentará simular un LIDAR girando sobre una base que gira gracias a un motor servo
recorriendo 180º en sentido positivo y negativo.
Para ello se ha creado un paquete en la carpeta ~/catkin_ws/src/ bajo el nombre de rosserial.
Seguidamente se ha descargado del repositorio el paquete
sudo apt-get install ros-indigo-rosserial-arduino
Seguidamente descargamos el IDE de Arduino
sudo apt-get install Arduino
Abrimos Arduino y borramos la librería de ros que podemos encontrar en la carpeta
scketchbook y creamos las nuevas mediando los siguientes comandos
cd <sketchbook>/libraries
rm -rf ros_lib
rosrun rosserial_arduino make_libraries.py
Partimos de los ejemplos dados para el tipo de sonar y cargamos y ejecutamos el programa
del anexo en nuestro Arduino. Obtendremos medidas de tipo range
C
71
El siguiente paso sería pasar los datos tipo range a laser_scan y adquirir datos a la vez que
gira el servo. Esta medida será bastante inexacta debido a la baja velocidad de adquisición y
al movimiento del sonar pero es una solución de bajo coste
Puede añadirse una unidad IMU en arduino y tomar medidas inerciales. Estas deberían
transmitirse a nuestro ordenador que funcionan como SCADA para una vez ahí, filtrar las
medias y obtener medidas de posición. Mediante TF estas medidas serán calculadas respecto
al eje global y podremos visualizar el idéntico movimiento que realiza nuestro robot móvil a
en nuestro Rviz.
Al ser una implementación real, olvidaríamos Gazebo.
Sería interesante implementar un protocolo de comunicación inalámbrico entre el robot y el
ordenador mediante un router por ejemplo. Una fácil implementación podría hacerse
mediante Raspberry Pi creando un servidor web el cual responda a las peticiones de mandar
datos cada vez que llegue un dato nuevo y las mande al Linux que está esperando datos
nuevos.
72
73
7 ANEXO
7.1 Codigos
7.1.1 CMakeFile
cmake_minimum_required(VERSION 2.8.3)
project(robot_movil)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS
xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
gazebo_ros
geometry_msgs
hector_mapping
joint_state_publisher
nav_msgs
robot_state_publisher
roscpp
rospy
tf
xacro
)
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See
http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within
this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you
use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs,
...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
74
## * add a build_depend and a run_depend tag for each package in
MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been
pulled in
## but can be declared for certainty nonetheless:
## * add a run_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to
generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
## Generate services in the 'srv' folder
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
## Generate actions in the 'action' folder
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )
## Generate added messages and services with any dependencies listed
here
# generate_messages(
# DEPENDENCIES
# geometry_msgs# nav_msgs
# )
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a run_depend tag for
"dynamic_reconfigure"
## * In this file (CMakeLists.txt):
75
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section
below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your
package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent
projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent
projects also need
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES robot_movil
# CATKIN_DEPENDS gazebo_ros geometry_msgs hector_mapping
joint_state_publisher nav_msgs robot_state_publisher roscpp rospy
tf xacro
# DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
# include_directories(include)
include_directories (
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(robot_movil
# src/${PROJECT_NAME}/robot_movil.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(robot_movil ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
76
## Declare a C++ executable
# add_executable(robot_movil_node src/robot_movil_node.cpp)
add_executable(Movimiento src/Movimiento.cpp)
#add_executable(Reconocimiento src/Reconocimiento.cpp)
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(robot_movil_node
${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(robot_movil_node
# ${catkin_LIBRARIES}
# )
target_link_libraries(Movimiento ${catkin_LIBRARIES})
#target_link_libraries(Reconocimiento ${catkin_LIBRARIES})
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See
http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# install(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables and/or libraries for installation
# install(TARGETS robot_movil robot_movil_node
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files,
etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
77
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_robot_movil.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)
7.1.2 Package.xml
<?xml version="1.0"?>
<package>
<name>robot_movil</name>
<version>0.0.0</version>
<description>The robot_movil package</description>
<!-- One maintainer tag required, multiple allowed, one person
per tag -->
<!-- Example: -->
<!-- <maintainer email="[email protected]">Jane
Doe</maintainer> -->
<maintainer email="[email protected]">alex</maintainer>
<!-- One license tag required, multiple allowed, one license
per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3,
LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but mutiple are allowed, one per
tag -->
<!-- Optional attribute type can be: website, bugtracker, or
repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/robot_movil</url>
-->
<!-- Author tags are optional, mutiple are allowed, one per
tag -->
<!-- Authors do not have to be maintianers, but could be -->
<!-- Example: -->
<!-- <author email="[email protected]">Jane Doe</author> --
>
<!-- The *_depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system
dependencies -->
78
<!-- Examples: -->
<!-- Use build_depend for packages you need at compile time: -
->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use run_depend for packages you need at runtime: -->
<!-- <run_depend>message_runtime</run_depend> -->
<!-- Use test_depend for packages you need only for testing: -
->
<!-- <test_depend>gtest</test_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>gazebo_ros</build_depend>
<build_depend>geometry_msgs</build_depend>
<build_depend>hector_mapping</build_depend>
<build_depend>joint_state_publisher</build_depend>
<build_depend>nav_msgs</build_depend>
<build_depend>robot_state_publisher</build_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>tf</build_depend>
<build_depend>xacro</build_depend>
<run_depend>gazebo_ros</run_depend>
<run_depend>geometry_msgs</run_depend>
<run_depend>hector_mapping</run_depend>
<run_depend>joint_state_publisher</run_depend>
<run_depend>nav_msgs</run_depend>
<run_depend>robot_state_publisher</run_depend>
<run_depend>roscpp</run_depend>
<run_depend>rospy</run_depend>
<run_depend>tf</run_depend>
<run_depend>xacro</run_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be
placed here -->
</export>
</package>
7.1.3 Modelo URDF
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro"
name="RobotMovil"
xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmls
chema/#sensor"
xmlns:controller="http://playerstage.sourceforge.net/gazebo/
xmlschema/#controller">
<xacro:property name="pi" value="3.1416"/> <!--Definiciones
xacro -->
79
<xacro:property name="radio_rueda" value="0.05"/>
<xacro:property name="ancho_rueda" value=".1"/>
<xacro:macro name="rueda" params="sufijo parent reflect
offset_x offset_y offset_z giro_x ancho radio">
<link name="rueda_${sufijo}">
<visual>
<geometry>
<cylinder length="${ancho}" radius="${radio}"/>
</geometry>
<material name="negro">
<color rgba="0 0 0 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="${ancho}" radius="${radio}"/>
</geometry>
</collision>
<inertial>
<mass value="1"/>
<inertia ixx="0.004" ixy="0.0" ixz="0.0" iyy="0.004"
iyz="0.0" izz="0.002"/>
</inertial>
</link>
<!--Union de las ruedas-->
<joint name="rueda_${sufijo}_joint" type="continuous">
<axis xyz="0 0 1"/>
<parent link="${parent}"/>
<child link="rueda_${sufijo}"/>
<origin rpy="${giro_x} 0 0" xyz="${offset_x}
${reflect*offset_y} ${offset_z}"/>
</joint>
</xacro:macro>
<link
name="base_link">
<!--Cuerpo del robot -->
<visual>
<geometry>
<box size="0.6 0.3 0.06"/>
</geometry>
<material name="white">
<color rgba="1 1 1 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="0.6 0.3 0.05"/>
</geometry>
</collision>
<inertial>
<mass value="10"/>
80
<inertia ixx="1.0" ixy="0.0" ixz="0.0" iyy="0.8"
iyz="0.0" izz="0.5"/>
</inertial>
</link>
<link name="parte_delantera"> <!--parte delantera del robot
-->
<visual>
<geometry>
<cylinder length="0.05" radius="0.2"/>
</geometry>
<material name="red">
<color rgba="1 0 0 1"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.05" radius="0.2"/>
</geometry>
</collision>
<inertial>
<mass value="4"/>
<inertia ixx="10e-4" ixy="0.0" ixz="0.0" iyy="10e-5"
iyz="0.0" izz="10e-5"/>
</inertial>
</link>
<joint name="parte_delantera_joint" type="continuous"> <!--
Union del cuerpo con la parte delantera del robot -->
<axis xyz="0 0 1"/>
<parent link="base_link"/>
<child link="parte_delantera"/>
<origin rpy="0 0 0" xyz="0.3 0 0"/>
</joint>
<!--rueda delantera del robot -->
<xacro:rueda sufijo="derecha" parent="base_link" reflect="-
1.0" offset_x="-.3" offset_y=".15" offset_z="-.05"
giro_x="${pi/2}" ancho="${ancho_rueda}"
radio="${radio_rueda}"/>
<xacro:rueda sufijo="izquierda" parent="base_link"
reflect="1" offset_x="-.3" offset_y=".15" offset_z="-.05"
giro_x="${pi/2}" ancho="${ancho_rueda}"
radio="${radio_rueda}"/>
<xacro:rueda sufijo="delantera" parent="parte_delantera"
reflect="1" offset_x="0.0" offset_y="0.0" offset_z="-.05"
giro_x="${pi/2}" ancho="${ancho_rueda}"
radio="${radio_rueda}"/>
<!-- Hokuyo Laser -->
<link name="hokuyo_link">
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
81
<geometry>
<box size="0.1 0.1 0.1"/>
</geometry>
</collision>
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size=".1 .1 .1"/>
</geometry>
</visual>
<inertial>
<mass value="1e-5" />
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="1e-6" ixy="0" ixz="0" iyy="1e-6" iyz="0"
izz="1e-6" />
</inertial>
</link>
<joint name="hokuyo_joint" type="fixed">
<axis xyz="0 1 0" />
<origin xyz="-.3 0 0.025" rpy="0 ${-1*pi} 0"/>
<parent link="base_link"/>
<child link="hokuyo_link"/>
</joint>
<!--Definicion de los plugins --
>
<gazebo>
<plugin name="differential_drive_controller"
filename="libgazebo_ros_diff_drive.so">
<leftJoint>rueda_izquierda_joint</leftJoint>
<rightJoint>rueda_derecha_joint</rightJoint>
<robotBaseFrame>base_link</robotBaseFrame>
<wheelSeparation>0.3</wheelSeparation>
<wheelDiametre>0.1</wheelDiametre>
<publishWheelJointState>True</publishWheelJointState>
</plugin>
</gazebo>
<!-- Publicación de los estados de las uniones traseras -
->
<gazebo>
<plugin name="joint_state_publisher"
filename="libgazebo_ros_joint_state_publisher.so">
<jointName>parte_delantera_joint,
rueda_delantera_joint</jointName>
</plugin>
</gazebo>
<!--Colores en Gazebo -->
<gazebo reference="base_link">
<material>Gazebo/Orange</material>
</gazebo>
<gazebo reference="parte_delantera">
<material>Gazebo/Black</material>
</gazebo>
82
<gazebo reference="rueda_delantera">
<material>Gazebo/Black</material>
</gazebo>
<gazebo reference="rueda_derecha">
<material>Gazebo/Black</material>
</gazebo>
<gazebo reference="rueda_izquierda">
<material>Gazebo/Black</material>
</gazebo>
<!-- hokuyo -->
<gazebo reference="hokuyo_link">
<sensor type="ray" name="head_hokuyo_sensor">
<pose>0 0 0 0 0 0</pose>
<visualize>true</visualize>
<update_rate>40</update_rate>
<ray>
<scan>
<horizontal>
<samples>720</samples>
<resolution>1</resolution>
<min_angle>${-pi/4}</min_angle>
<max_angle>${pi/4}</max_angle>
</horizontal>
</scan>
<range>
<min>0.10</min>
<max>30.0</max>
<resolution>0.01</resolution>
</range>
<noise>
<type>gaussian</type>
<mean>0.0</mean>
<stddev>0.01</stddev>
</noise>
</ray>
<plugin name="gazebo_ros_head_hokuyo_controller"
filename="libgazebo_ros_laser.so">
<topicName>/laser_scan</topicName>
<frameName>hokuyo_link</frameName>
</plugin>
</sensor>
</gazebo>
</robot>
83
7.1.4 robot_slam.launch
<?xml version="1.0"?>
<launch>
<!-- Aqui aplicamos el mapa que queremos colocar (en gazebo worls,
por ejemplo willow_garage -->
<include file="$(find
hector_gazebo_worlds)/launch/small_indoor_scenario.launch"/>
<param name="robot_description" command="$(find xacro)/xacro.py
$(arg model)" />
<arg name="model" />
<arg name="tf_map_scanmatch_transform_frame_name"
default="scanmatcher_frame"/>
<arg name="base_frame" default="base_link"/>
<arg name="odom_frame" default="odom"/>
<arg name="pub_map_odom_transform" default="true"/>
<arg name="scan_subscriber_queue_size" default="5"/>
<arg name="scan_topic" default="laser_scan"/>
<arg name="map_size" default="2048"/>
<!-- Dibuja con geotiff en rviz -->
<include file="$(find
robot_movil)/launch/representacion.launch">
<arg name="trajectory_publish_rate" value="4"/>
</include>
<node pkg="hector_mapping" type="hector_mapping"
name="hector_mapping" output="screen">
<!-- Frame names -->
<param name="map_frame" value="map" />
<param name="base_frame" value="$(arg base_frame)" />
<param name="odom_frame" value="$(arg odom_frame)" />
<!-- Tf use -->
<param name="use_tf_scan_transformation" value="true"/>
<param name="use_tf_pose_start_estimate" value="false"/>
<param name="pub_map_odom_transform" value="true"/>
<!-- Map size / start point -->
<param name="map_resolution" value="0.050"/>
<param name="map_size" value="$(arg map_size)"/>
<param name="map_start_x" value="0.5"/>
<param name="map_start_y" value="0.5" />
<param name="map_multi_res_levels" value="2" />
<!-- Map update parameters -->
<param name="update_factor_free" value="0.4"/>
<param name="update_factor_occupied" value="0.9" />
<param name="map_update_distance_thresh" value="0.4"/>
<param name="map_update_angle_thresh" value="0.06" />
<param name="laser_z_min_value" value = "-1.0" />
<param name="laser_z_max_value" value = "1.0" />
<!-- Advertising config -->
<param name="advertise_map_service" value="true"/>
84
<param name="scan_subscriber_queue_size" value="$(arg
scan_subscriber_queue_size)"/>
<param name="scan_topic" value="$(arg scan_topic)"/>
<!-- Debug parameters -->
<!--
<param name="output_timing" value="false"/>
<param name="pub_drawings" value="true"/>
<param name="pub_debug_output" value="true"/>
-->
<param name="tf_map_scanmatch_transform_frame_name"
value="$(arg tf_map_scanmatch_transform_frame_name)" />
</node>
<!-- run the geotiff map to represent the estimate position in
rviz-->
<!--<include file="$(find
robot_movil)/launch/representacion.launch"/>-->
<!-- Colocamos la descripcion del robot y lo colocamos en gazebo-
->
<node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model"
args="-z 1.0 -unpause -urdf -model robot -param
robot_description" respawn="false" output="screen" />
<!-- Lanzamos el nodo publicador del estado del robot necesario
para saber la posicion-->
<node pkg="robot_state_publisher" type="robot_state_publisher"
name="robot_state_publisher">
<param name="publish_frequency" type="double" value="30.0" />
</node>
<!-- Lanzamos el nodo publicador de articulaciones, necesario para
saber su estado-->
<node pkg="joint_state_publisher" type="joint_state_publisher"
name="joint_state_publisher">
<param name="publish_frequency" type="double" value="40.0" />
</node>
<!-- We also run this node in order to get movenments in our robot
but isn't ready yet -->
<!-- <node name="Movimiento" pkg="robot_movil"
type="Movimiento"/> -->
<!-- <param name="/use_sim_time" value="true"/>
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find
urdf_tutorial)/urdf.rviz" required="true" /> -->
</launch>
85
7.1.5 Representación launch
<?xml version="1.0"?>
<launch>
<arg name="geotiff_map_file_path" default="$(find
hector_geotiff)/maps"/>
<param name="/use_sim_time" value="true"/>
<!--<node pkg="rviz" type="rviz" name="rviz"
args="-d $(find
hector_slam_launch)/rviz_cfg/mapping_demo.rviz"/> -->
<node name="rviz" pkg="rviz" type="rviz"
args="-d $(find robot_movil)/rviz_cfg/slam.rviz"
required="true" />
<!--<include file="$(find
hector_mapping)/launch/mapping_default.launch"/> -->
<arg name="trajectory_source_frame_name" default="/map"/>
<arg name="trajectory_update_rate" default="4"/>
<arg name="trajectory_publish_rate" default="0.25"/>
<arg name="map_file_path" default="$(find
hector_geotiff)/maps"/>
<arg name="map_file_base_name" default="odom"/>
<node pkg="hector_trajectory_server"
type="hector_trajectory_server" name="hector_trajectory_server"
output="screen">
<param name="target_frame_name" type="string"
value="base_link" />
<param name="source_frame_name" type="string" value="$(arg
trajectory_source_frame_name)" />
<param name="trajectory_update_rate" type="double"
value="$(arg trajectory_update_rate)" />
<param name="trajectory_publish_rate" type="double"
value="$(arg trajectory_publish_rate)" />
</node>
<node pkg="hector_geotiff" type="geotiff_node"
name="hector_geotiff_node" output="screen" launch-prefix="nice -
n 15">
<remap from="map" to="/static_map" />
<param name="map_file_path" type="string" value="$(arg
map_file_path)" />
<param name="map_file_base_name" type="string" value="$(arg
map_file_base_name)" />
<param name="geotiff_save_period" type="double" value="0" />
<param name="draw_background_checkerboard" type="bool"
value="true" />
<param name="draw_free_space_grid" type="bool" value="true"
/>
86
<param name="plugins" type="string"
value="hector_geotiff_plugins/TrajectoryMapWriter" />
</node>
</launch>
7.2 Enlaces
http://www.ubuntu.com/download
http://wiki.ros.org/teleop_twist_keyboard
https://ocw.mit.edu/courses/aeronautics-and-astronautics/16-412j-cognitive-robotics-spring-
2005/projects/1aslam_blas_repo.pdf
http://gazebosim.org/
http://wiki.ros.org/diff_drive_controller
https://github.com/ros-drivers/hokuyo_node
http://www.hokuyo-aut.jp/02sensor/07scanner/download/products/urg-
04lx/
7.3 Mensajes ROS
87
Top Related