Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
ujio
Equation Chapter 1 Section 1
Trabajo Fin de Grado
Grado en Ingeniería en Tecnologías Industriales
Navegación en interiores con robots de servicios
Autor: Ana Rivas Real
Tutor: Jesús Capitán Fernández
Dept. Ingeniería de Sistemas y Automática
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2017
ii
iii
Trabajo Fin de Grado
Grado en Ingeniería en Tecnologías Industriales
NAVEGACIÓN EN INTERIORES CON ROBOTS
DE SERVICIOS
Autor:
Ana Rivas Real
Tutor:
Jesús Capitán Fernández
Profesor Ayudante Doctor
Dept. de Ingeniería de Sistemas y Automática
Escuela Técnica Superior de Ingeniería
Universidad de Sevilla
Sevilla, 2017
iv
v
Trabajo Fin de Grado: Navegación en interiores con robots de servicios
Autor: Ana Rivas Real
Tutor: Jesús Capitán Fernández
El tribunal nombrado para juzgar el Proyecto arriba indicado, compuesto por los siguientes miembros:
Presidente:
Vocales:
Secretario:
Acuerdan otorgarle la calificación de:
Sevilla, 2017
El Secretario del Tribunal
vi
vii
A mi familia
A mis maestros
viii
ix
Agradecimientos
Me gustaría darle las gracias en primer lugar a mis padres Mª Eugenia y César por hacer posible que haya
podido llegar a este punto de mi vida. A mis hermanos Pablo y Carlos que junto con mis padres han sufrido
conmigo cada año de mis estudios. También a mi familia por el apoyo y el interés que me han brindado
siempre. Y a ese pequeñito con plumas que ha estado a mi lado cada día de estudio en casa haciéndolo más
ameno.
A mis amigos, tanto a los de siempre cómo a los que han aparecido a lo largo de la carrera por todo lo que me
han enseñado y por ese apoyo mutuo de los que sabemos lo que es tener de primera casa la ETSI.
Especialmente a Prada el que ha sido un apoyo incondicional en esta recta final.
Quiero agradecerle también al mayor regalo que me ha dado la carrera, Cristian, esa persona que ha estado ahí
en las buenas, en las malas y en esos momentos en los que quieres tirarlo todo por la borda. Gracias por
ayudarme a ver la vida de otra forma, por ayudarme a seguir, por no rendirme por muchos palos que me de la
carrera.
Por último, quería darle las gracias a mi tutor por la ayuda que me ha brindado en este proyecto y a los
becarios y no tan becarios del laboratorio.
x
xi
Resumen
El objetivo de este proyecto es la navegación en interiores en la plataforma robótica Magabot. De esta forma el
robot será capaz de desplazarse de forma autónoma de un sitio a otro sin colisionar con obstáculos que pueda
encontrar. Para ello son necesarias cuatro características, el mapa del entorno que debe recorrer, la localización
en cada instante, la información del entorno y el objetivo al que debe llegar el robot.
La información del robot se obtendrá mediante el uso del sensor láser hokuyo, el cual tiene una amplitud de
barrido de 240º. Esta información se leerá a través de la ejecución del paquete de ROS urg_node que se
ejecutará mediante un launch con el que ejecutaremos todo el código.
El mapa del entorno se creará mediante un mapeado, para ello se usa los drivers de los que disponemos, un
teclado inalámbrico y el láser. Para ello desplazaremos el robot con el uso del teclado, este publica la velocidad
en el topic /cmd_vel que a su vez el driver la traduce en el movimiento de las ruedas. En todo este proceso el
láser irá mandando información de lo que detecta en cada posición.
La localización se llevará a cabo mediante el algoritmo AMCL (Adaptative Monte Carlo Localization). Este es
un método probabilístico en 2D. El robot usando el paquete AMCL, el láser y rviz, será capaz de localizarse en
el mapa.
Por último, usaremos la pila de navegación en 2D, para mandarle al robot un objetivo al que debe desplazarse
usando el mapa y la localización si no existen obstáculos y usando el láser para la detección de obstáculos
estáticos y móviles.
Todo esto se realizará con la ayuda de ROS, usando las librerías, visualizadores, paquetes de datos, etc. Este
entorno de trabajo nos facilita el trabajo al poder olvidarnos del hardware.
xii
xiii
Índice Agradecimientos ix
Resumen xi
Índice xiii
Índice de Figuras xv
Notación xvii
1 Introducción 1 1.1 Robots 2
1.1.1 Estructura de un robot 2 1.1.2 Tipos de robots 3
1.2 AGV (Automatic Guided Vehicle) 6 1.3 Magabot 7
1.3.1 Software 7 1.3.2 Hardware 8 1.3.3 Magabot vs TurtleBot 9
1.4 Hokuyo 9
2 Objetivo y plan de trabajo 13 2.1 Objetivo 13 2.2 Plan de Trabajo 13
3 ros 15 3.1 Concepto 16 3.2 Herramientas de ROS 17
3.2.1 Roscore 17 3.2.2 Roslaunch 17 3.2.3 Rosrun 18 3.2.4 Rostopic 18 3.2.5 Rosnode 18 3.2.6 Rviz 19 3.2.7 Rqt_graph 20
4 Driver 23
5 Mapeado 27 5.1 Lectura del sensor 27 5.2 Movimiento del robot 27 5.3 Creación de Mapa 29
6 Localización 33
7 Navegación 35
8 Conclusiones y desarrollos futuros 39
9 Bibliografía 41
ANEXO A. magabot_node 43
ANEXO B. magabot.launch 51
ANEXO C. magabot_2dnav.launch 53 12.1 Magabot_2dnav 53 12.2 Magabot_costmap_common_params 54 12.3 Magabot_local_costmap_params 54
xiv
12.4 Magabot_global_costmap_params 54 12.5 Magabot_base_local_planner_params 54 12.6 Magabot_move_base_params 55
xv
Índice de Figuras
Figura 1: Robots de películas de ciencia ficción, “El hombre bicentenario”, “Yo, robot”, “La guerra de las
galaxias” 1
Figura 2: Estructura general del robot y su interacción con el entorno 2
Figura 3: Robots de servicio, de derecha a izquierda. En la parte superior aparece un robot de uso doméstico y
uno de investigación, en la parte inferior uno de uso médico y otros de uso educativo. 4
Figura 4: Robots manipuladores 5
Figura 5: Robots móviles autoguiado y guiado por raíles 5
Figura 6: AGVs tipo vehículos de arrastre y montacargas de horquillas 7
Figura 7: Magabot, configuración básica. 8
Figura 8: Magabot, con estructura. 8
Figura 9: TurtleBot 9
Figura 10: Láser Hokuyo 9
Figura 11: Plano acotado del Hokuyo 10
Figura 12: Velodyne 11
Figura 13: Flujo de la información para la navegación autónoma 13
Figura 14: Esquema de comunicación a través de topics 16
Figura 15: Esquema de comunicación a través de servicios 16
Figura 16: Lanzamiento de un nodo 17
Figura 17: Establecimiento de parámetros 17
Figura 18: Ejecución de la herramienta roslaunch 17
Figura 19: Ejecución de una aplicación pasándole parámetros 18
Figura 20: Ejecución de una aplicación 18
Figura 21: Interfaz de rviz 19
Figura 22: Global Options de rviz 19
Figura 23: Barra de herramientas de rviz 20
Figura 24: Display de rviz 20
Figura 25: Ejecución de rqt_graph 21
Figura 26: Visualización de todos los nodos y topics en rqt_graph 21
Figura 27: Visualización de las conexiones entre nodos. 21
Figura 28: Algunas líneas del código de inicialización y conexión de arduino y ROS 23
Figura 29: Algunas líneas del código de asignación de parámetros a las variables 23
Figura 30: Algunas líneas del código de publicadores y subscriptores de ROS 23
Figura 31: Algunas líneas del código de traducción de velocidad a movimiento de rueda 24
Figura 32: Algunas líneas del código de cálculo de odometría 24
Figura 33: Algunas líneas del código de publicación de la transformada 24
Figura 34: Algunas líneas del código de la recepción de señales 25
xvi
Figura 35: Ejecución del láser 27
Figura 36: Ejecución de magabot_node y asignación de parámetros 28
Figura 37: Ejecución de la lectura de teclado 28
Figura 38: Relación de teclas con cada movimiento 28
Figura 39: Esquema de relaciones entre nodos magabot.launch y teleop_twist_keyboard 29
Figura 40: Valores del topic /láser 29
Figura 41: Ejecución de creación de mapa 29
Figura 42: Comienzo de creación de un mapa 30
Figura 43: Creación de mapa después del movimiento de robot 30
Figura 44: Código para guardar mapa 30
Figura 45: Archivo tipo yalm con los parámetros del mapa 31
Figura 46: Dos de los mapas de prueba 31
Figura 47: Mapa final 31
Figura 48: Código de ejecución del AMCL y asignación de parámetros 33
Figura 49: Visualización de rviv de la ejecución de magabot_2nav 33
Figura 50: Uso de 2D Pose Estimate para la aproximación de localización 34
Figura 51: Robot localizado 34
Figura 52: Código de ejecución de navigation y asignación de parámetros 35
Figura 53: Uso de 2D Nav Goal para la asignación de meta 35
Figura 54: Generación de trayectoria y navegación 36
Figura 55: Generación de trayectorias con obstáculos estáticos 36
Figura 56: Generación de trayectoria y modificación ante obstáculos móviles 37
xvii
Notación AGV
Vehículo automáticamente guiados
xviii
1
1 INTRODUCCIÓN
os seres humanos desde el inicio de los tiempos, han usado la tecnología como ayuda para sobrevivir o
para hacer la vida más fácil. Con el paso de los años, la tecnología se ha ido adaptando, comenzando por
la prehistoria en la que se comenzaron a usar utensilios para cazar, hacer ropa etc., hasta la actualidad.
Esta tecnología ha ido avanzando de forma exponencial, ya que al usar nuevas tecnologías facilitan el
descubrimiento de la siguiente, por ejemplo, el primer coche no se construyó hasta 1885, sin embargo el
primer hombre que llegó al espacio fue 76 años después.
Una rama de la tecnología que ha ido creciendo a lo largo de los años es la robótica, esta es una ciencia que
estudia el diseño y construcción de máquinas que son capaces de realizar trabajos productivos imitando los
movimientos y comportamientos del ser humano, o trabajos que requieran de uso de inteligencia. [1] Esta
ciencia, podría ser una derivación o una combinación: del álgebra, los autómatas programables, las máquinas
de estados, la mecánica o la informática. Esta ciencia, la robótica, por definición es considerada la ciencia que
estudia los robots, este término viene dado por Isaac Asimov. [2]
La idea de robots, se remonta a tiempos muy antiguos, hace muchos años en leyendas hindús sobre elefantes
mecánicos, sin embargo, no fue hasta 1921 cuando se usa por primera vez la palabra robot en una obra
llamada “Rossum’s Universal Robotsd/R.U.E”, haciendo alusión a la palabra checa “robota”, la cual significa
trabajo forzado o servidumbre. Se trataba de una obra de ficción, en la cual el protagonista, Rossum, utilizando
métodos biológicos inventa y produce en serie “hombres” que sirven a los humanos. Estos con el tiempo se
rebelan y someten a la humanidad. [3] Esta idea supuso la visión de los robots como humanoides, esto se ve
reflejado en posteriores películas, series de televisión etc. [4]
Los robots humanoides, son sólo una parte de la robótica, existen distintos tipos de robots cada uno con
funciones muy diferentes. Se han enunciado diversas definiciones en la que incluirlos a todos, una de ellas los
define como “Manipulador multifuncional y reprogramable, diseñado para mover materiales, piezas,
herramientas o dispositivos especiales, mediante movimientos programados y variables que permiten llevar a
cabo diversas tareas.” En resumen podríamos decir que los robots son dispositivos que realizan distintas tareas
de forma autónoma o semiautónoma, que facilitan el trabajo del ser humano y pueden relacionarse con el
entorno mediante sensores, para ello se programan mediante computadoras. [3]
L
Figura 1: Robots de películas de ciencia ficción, “El hombre bicentenario”, “Yo, robot”, “La guerra de las galaxias”
No es la especie más fuerte la que sobrevive, ni la más
inteligente, sino la que responde mejor al cambio
- Charles Darwin -
2
2 Navegación en interiores con robots de servicios
1.1 Robots
1.1.1 Estructura de un robot
Cómo se menciona anteriormente, los robots pueden relacionarse con el entorno, para ello todos con
independencia del tipo que sea, tienen la misma estructura. Esta estructura, se podría dividir en cuatro partes,
sistema mecánico, sensores, actuadores y sistema de control.
El sistema mecánico de un robot, es como “el esqueleto de un ser vivo”. Tiene como función soportar y unir
todos los componentes del mismo. Según las funciones que tenga el robot puede tener mayor o menor
robustez, existiendo robots educativos en el que la misma placa electrónica se usa como sistema mecánico. El
sistema mecánico puede llevar a cabo con una gran variedad de materiales por ejemplo, se pueden encontrar
en robots de competiciones materiales ligeros y en fábricas sin embargo, materiales resistentes y pesados que
puedan resistir grandes esfuerzos durante largos periodos de tiempo. También pueden contener diferentes
complementos como brazos articulados, ruedas o herramientas que permitan el desplazamiento del robot etc.
[1] [4] [5]
Los sensores, es muy difícil encontrar una definición que pueda abarcar la totalidad de los tipos de sensores,
ellos denominan un sensor como “al dispositivo analítico capaz de responder en continuo, in situ, en tiempo
real y de modo reversible a los cambios producidos en un parámetro físico o en la concentración de una
especie química”. [6] Los sensores que puede albergar un robot, se pueden dividir principalmente en dos
grupos:
Sensores internos, estos sensores llevan a cabo las mediciones y comprobaciones del estado del sistema
mecánico. Concretamente pueden comprobar el giro relativo entre articulaciones, desplazamientos relativos
entre articulaciones, velocidades etc. Esto sirve para un correcto control del sistema mecánico, podría
decirse que son el nexo de unión entre el sistema de control y el sistema mecánico. Se pueden encontrar
sensores de posición, de velocidad, de aceleración y de fuerza. [1]
Sensores externos, estos sensores son los que “humanizan” los robots, es decir, dotan a los robots de
sentidos. Esto permite que el sistema de control obtenga datos del entorno, los cuales usará para dar
órdenes a los actuadores. Podemos encontrar distintos tipos de sensores externos según la función del
robot. Algunos de los que pueden encontrarse son, sensores de contacto y presión, de proximidad, de
distancia (por ejemplo láser o ultrasonido), de presión o de visión. [1]
Los actuadores son dispositivos que llevan a cabo la transformación de las magnitudes recibidas por los
sensores en interacciones con el entorno, estas interacciones vienen comandadas por el sistema de control.
Para cada función pueden ser necesarios actuadores totalmente distintos, no se requiere el mismo actuador
para un robot que transporta cajas que para un robot que corta madera, por ejemplo. [7] Se pueden distinguir
tres tipos de actuadores según su funcionamiento:
Actuadores neumáticos, son dispositivos de potencia dadas por fluidos. Estos actuadores utilizan aire
comprimido y su principal función es realizar movimientos de apertura y cierre o accionamientos de brazos
robóticos sencillos. [3]
Actuadores hidráulicos, al igual que los actuadores neumáticos, se trata de un dispositivo de potencia
Figura 2: Estructura general del robot y su interacción con el entorno
3
3 Navegación en interiores con robots de servicios
de fluidos. A diferencia del anterior, en vez del agua usan fluidos a altas presiones, por ejemplo el aceite. Al
trabajar con fluidos de alta presión, permite que se pueda trabajar aplicando alta potencia. [3]
Actuadores eléctricos, su función es transformar la energía eléctrica en energía mecánica. Esto se
realiza mediante motores eléctricos, los cuales pueden ser de tres tipos principalmente, motores paso a
paso, motores de corriente continua (DC) o motores de corriente alterna (AC). También en algunos casos,
nos podemos encontrar servomotores, los cuales son un tipo especial de motor en que esta incluido a
diferencia del resto de motores una tarjeta de control. [7] [4] [5]
El sistema de control, es el cerebro del robot. Su principal función es comunicar los sentidos del robot
(sensores), con los movimientos y acciones que se llevaran a cabo sobre el entorno (actuadores). El sistema de
control puede componerse de diferentes elementos según el tipo de robot, para robots educativos o robots
simples se basa en microcontroladores. Para robots industriales el sistema de control es más complejo y se
trata de un ordenador industrial con elementos como, tarjetas convertidoras D/A, tarjetas de etapa de potencia,
tarjeta de adquisición de datos, tarjetas de entrada/salida digitales, tarjetas convertidoras D/A y A/D y tarjetas
de comunicación. En este sistema podemos trabajar de tres formas, puede ser de forma manual, automática y
semiautomática, según las funciones del robot. [4] [5]
Periféricos de salida, son dispositivos que permiten al robot otra forma de comunicarse con el entorno. A
diferencia de los actuadores, los periféricos no generan movimientos del robot, ni de pinzas, ni brazos etc. Se
usan principalmente a modo de comunicación con el usuario, por ello, no son una parte obligatoria en el robot
pero si una parte muy útil por su capacidad informativa. Hay diversos periféricos, cada uno con una función
que el programador asignará, de forma que cuando pase algún evento determinado el periférico se accionará
mediante señales enviadas por el microcontrolador. Algunos ejemplos son, diodos led, zumbadores, displays,
pantallas LCD, etc. [5]
1.1.2 Tipos de robots
Existen infinidad de robots con distintas formas, distintos componentes, distintas funciones, distintos tamaños,
etc. Por ello surge la necesidad de clasificarlos, hay distintas formas de agruparlos principalmente los robots
se dividen en dos grupos:
Robots de servicio
Robots industriales
1.2.1.1 Robots de servicio
Se pueden considerar robots de servicio a todos aquellos que no realizan tareas industriales, trabajan en
entornos no estructurados y normalmente desconocidos de forma parcial o total. [4]
Dentro de los robots de servicio pueden diferenciarse muchos robots con distintas funciones, algunas de ellas
son [4]:
Agricultura
Construcción
Entretenimiento y diversión
Industria nuclear
Medicina y servicios sanitarios
Educación
Rastreo, exploración e inspección
Servicios domésticos y generales
Vigilancia y seguridad
Etc.
4
4 Navegación en interiores con robots de servicios
1.2.1.2 Robots industriales
La definición de robot industrial puede diferir en el mercado japonés y en el mercado euro-americano.
Mientras que para el mercado japonés supone cualquier dispositivo mecánico con articulaciones móviles
destinado a la manipulación, el mercado euro-americano es más restrictivo exigiendo una mayor complejidad.
Con el paso de los años la robótica industrial ha ido evolucionando, lo que provoca que la definición, además
de difícil de enunciar, deba actualizarse en cortos periodos de tiempo. Una de las definiciones que se han dado,
es la de la norma ISO que enuncia lo siguiente “Manipulador multifuncional reprogramable con varios grados
de libertad, capaz de manipular materias, piezas, herramientas o dispositivos especiales según trayectorias
variables programadas para realizar tareas diversas.” [4] [8]
Existen distintas formas de clasificar a los robots industriales, clasificación temporal, clasificación funcional,
clasificación por su tipo de control, por su geometría y configuración, etc.
Según su tipo de control, podemos distinguir los siguientes tipos [4] [8]:
Teleoperados, son robots manipuladores con control manual o telemando.
Secuenciales, robots manipuladores con control automático.
Trayectoria controlable, robot programable con trayectoria continua o punto a punto. Tiene un
control semiautomático, ya que carece o sensores que interaccionen con el entorno, o no están
programados para interpretarlo.
Adaptativos, robot automático capaz de interactuar con el entorno y de adaptarse a él.
Según su geometría o configuración, nos encontramos con [4] [8]:
Robots manipuladores, según la Federación Internacional de Robótica (IFR) “por robot industrial de
manipulación se entiende una máquina de manipulación automática, reprogramable y multifuncional con tres
o más ejes que pueden posicionar y orientar materias, piezas, herramientas o dispositivos especiales para la
ejecución de trabajos diversos en las diferentes etapas de la producción industrial, ya sea en una posición fija o
en movimiento”.
La mayoría de los robots manipuladores se asemejan al brazo de un humano, por ello para hacer referencia a
este, se usan partes de la anatomía de un brazo. Al tener forma de brazo, es una cadena cinemática abierta
Figura 3: Robots de servicio, de derecha a izquierda. En la parte superior aparece un robot de uso
doméstico y uno de investigación, en la parte inferior uno de uso médico y otros de uso educativo.
5
5 Navegación en interiores con robots de servicios
compuesta por diferentes combinaciones de articulaciones, cuanto más complejo sea el movimiento que debe
realizar, más articulaciones serán necesarias. En el extremo del brazo, se posicionarán las herramientas que se
desean usar, pueden aparecer pinzas, destornilladores, etc., el movimiento de las articulaciones está orientado a
mover la extremidad a la posición adecuada para el correcto uso de la herramienta.
Los robots manipuladores están destinados fundamentalmente para realizar operaciones sencillas y repetitivas,
aunque se pueden reprogramar para ser usadas en secuencias variables o incluso que sea un operario el que
controle directamente el funcionamiento del mismo.
Robots móviles “son dispositivos mecánicos programables capaces de moverse por sí mismos con un cierto
grado de autonomía y sin el control directo de un ser humano a los que se les pueden encomendar tareas muy
específicas o generales, normalmente para el transporte de materiales”.
Por lo general, los robots industriales móviles trabajan en dos dimensiones, con 3 grados de libertad siendo dos
de posición y uno de orientación. Todos ellos suelen caracterizarse por el uso del motor eléctrico para llevar a
cabo el movimiento, sin embargo, hay tres formas de llevar a cabo el guiado del robot:
Robots guiados por raíles, siguen una trayectoria prefijada por carriles, análogo al comportamiento
de un tren.
Robots filoguiados, se desplazan siguiendo un cable enterrado, el cual produce un campo magnético.
Robots autoguiados, normalmente denominados AGVs (Autonomous Guiaded Vehicles) estos se
desplazan libremente con lo que son flexibles a diferencia de los dos anteriores.
Figura 4: Robots manipuladores
Figura 5: Robots móviles autoguiado y guiado por raíles
6
6 Navegación en interiores con robots de servicios
1.2 AGV (Automatic Guided Vehicle)
Los AGV, como se menciona en el apartado anterior, se tratan de vehículos automáticamente guiados, son un
tipo de robot móvil y automático, es decir, vehículos que no necesitan una persona para realizar las tareas
encomendadas para el mismo, ya que está controlado por un ordenador.
Estos robots suponen muchas ventajas y servicios que no pueden ofrecer otros robots no móviles y móviles
pero con otros métodos de movilidad. Sin embargo, el principal problema de los AGVs es la navegación del
robot y dentro de ella la localización, por ello se requiere un sistema de odometría, el cual cuenta las vueltas
que realiza cada rueda [4]. Otro de los problemas que surgen es el guiado, el robot necesita tener “ojos”, esto
se consigue mediante un sistema de sensorial, que debe ser lo suficientemente avanzado como para corregir
errores de cálculo de la odometría, los principales son [4]:
Láser
Cámara
Ultrasonido
Las características más significativas de los AGVs son [4]:
Disponen de un sistema de control de abordo normalmente comunicado con un sistema central que le
manda las tareas a realizar
La comunicación con el ordenador central normalmente, se realiza de forma inalámbrica.
Dispone de un sistema sensorial que le permite la navegación en su entorno
Al igual que el resto de los robots, estos tienen como objetivo mejorar la calidad de vida de los seres humanos
y mejorar su seguridad. Por ello existen diversos tipos de AGVs con distintas funciones, se pueden encontrar
tanto vehículos autoguiados industriales como de servicio, de forma que cada uno puede tener una función,
tamaño, actuadores, etc. muy diversos.
Los AGVs que se usan en las industrias, principalmente se usan para llevar a cabo el transporte de materiales.
Principalmente su objetivo es recudir tiempos y el coste del transporte de los materiales y reducir posibles
riesgos en los empleados, ya que evitan el transporte de materiales pesados y continuos lo que puede suponer
problemas futuros de salud para los mismos. Algunos tipos son [9]:
Vehículos de arrastre: Pueden llevar acoplados remolques con los que transportan materiales
voluminosos y muy pesados a grandes distancias.
Transportadores unitarios de cargas: Son utilizados en almacenamiento o distribución, ya que son
de cargas unitarias, voluminosas y trayecto corto.
Montacargas de horquillas: Recogen y descargan en tarimas.
Carretillas de tarimas: Cuya función es la distribución.
Transportadores de carga ligera: Carga menor de 230 kg.
Vehículos de línea de ensamble: Transporta las distintas partes de una estación de trabajo o los
productos terminados de la misma.
7
7 Navegación en interiores con robots de servicios
Los robots de servicio tienen una gama de funciones más variada, como hablamos en el apartado anterior, hay
diversos tipos de robots de servicio y muchos de ellos son robots móviles. En algunos casos que el robot sea
móvil y autónomo es un mero complemento, es el caso por ejemplo de robots de entretenimiento y educación.
Sin embargo, en algunos casos la capacidad del movimiento y el autoguiado es esencial para poder cumplir el
funcionamiento del robot y por tanto es necesario el uso de AGVs. Algunos de los usos de los AGVs
utilizados en el sector servicio son [4]:
Investigación, en este sector puede ser el aspecto más importante del robot. En esta época está en auge
las investigaciones del espacio y una de las mejores formas de investigar es mediante un AGV, el cuál
pueda ser nuestros ojos en un planeta al que no podemos acceder y en el que no podemos dar
directrices manuales al robot.
Intervención de desastres, hay momentos en los que ocurren desastres como un incendio, un
terremoto, etc. en el cual un AGV puede ser la razón de salvar vidas, ya que no es seguro para las
personas adentrarse en el incendio, en un edificio derruido, etc., sin embargo, un robot es capaz de
adentrarse y darte los detalles del entorno, del estado de las personas atrapadas, etc., y así poder salvar
a un mayor número de personas con el mínimo riesgo.
Servicios domésticos, en este sensor la función de los AGVs es simplemente el hecho de facilitar las
tareas domésticas, por ejemplo, cada vez es más habitual tener en casa un robot que el sólo limpia el
suelo y que la única función de la persona sea la de encenderlo, apagarlo y cargarlo.
1.3 Magabot
Un ejemplo de AGV, es el robot de servicio llamado Magabot, robot que se usara en el transcurso del
proyecto. Este es una plataforma de bajo coste, además de tener tanto software como hardware abierto. Está
diseñado pensando en la posibilidad de llevar un ordenador portátil y como robot educativo. Al llevar un
ordenador y estar directamente conectado a él en todo momento, lo hace más potente y no necesita tener tanta
memoria, ya que no necesita guardarla, si no, que se va ejecutando en el momento. Además puede dotar al
robot de más “sentidos” al incluir en los ordenadores, micrófonos, altavoces, interfaces USB, pantalla, etc. [10]
1.3.1 Software
El software de Magabot, como se menciona anteriormente es libre, es decir, todo el que lo desee puede tanto
usar los programas creados como editar, crear y subirlos a la red. Por ello existen muchas aplicaciones en
desarrollo, con distintas funciones. Unas hacen que el Magabot siga colores, otras que siga paredes, que
detecte rostros., etc. Estas se realiza con diversas interfaces, entre ellas c #, c ++, VisualStudio, Arduino, etc.
[10]
Figura 6: AGVs tipo vehículos de arrastre y montacargas de horquillas
8
8 Navegación en interiores con robots de servicios
1.3.2 Hardware
El hardware con una configuración básica que a la que opcionalmente se le pueden añadir distintos elementos
los cuales no todos los Magabot tienen.
Configuración básica [10]:
Se puede visualizar la configuración básica de un Magabot en la figura 8, esta se compone de:
Chasis de PVC con motores de corriente continua con codificadores.
Tres sensores de infrarrojos en la parte inferior para detectar escaleras o líneas.
Dos parachoques en el frente para detectar colisiones.
Tres RGB leds
Un sensor de batería para saber si necesita cargarla.
I2C1 en la parte superior para conectar cualquier dispositivo I2C.
Una batería de 7,2v y un cargador.
Paquete de 5 sensores de sonar con soportes de PVC para conectar al bus I2C superior.
Además de la configuración básica, se le suele añadir una estructura sobre el robot, como se muestra en la
figura 7. Se trata de una estructura de dos plantas, se asemeja a una estantería, la cual nos sirve para poder
posicionar el ordenador portátil, transportar materiales si fuese necesario y nos permite añadir sensores.
1 El I2C [16] es un bus con múltiples maestros, lo que significa que se pueden conectar varios chips al mismo bus y que todos ellos pueden actuar como maestro, sólo con iniciar la transferencia de datos.
Figura 8: Magabot, con estructura. Figura 7: Magabot, configuración básica.
9
9 Navegación en interiores con robots de servicios
1.3.3 Magabot vs TurtleBot
El robot Magabot, es un robot que está en plena investigación con lo que encontrar información sobre él o
encontrar programas e información de cómo trabajar con él es aún difícil. Sin embargo, existe un robot muy
similar y más conocido llamado TurtleBot.
El robot TurtleBot es un kit de robot personal de bajo costo con software de código abierto al igual que el
robot Magabot. El kit TurtleBot consta de una base móvil, sensor de distancia 2D / 3D, ordenador portátil
y el kit de hardware de montaje TurtleBot. [11]
Como se puede observar, el hardware del TurtleBot es muy similar al del Magabot. El software en ambos
casos es libre, sin embargo, como hemos comentado anteriormente hay mucha más variedad de software del
TurtleBot que del Magabot. Existe una plataforma web, la wiki de ROS2 donde se puede encontrar todo tipo
de información sobre programación en ROS, tutoriales, etc. En esta wiki se puede encontrar numerosas
páginas sobre el TurtleBot: cómo conectarlo, cómo navegar, cómo localizarlo, etc. sin embargo, a día de hoy
no existen reseñas en la wiki sobre el Magabot. Por esta razón y por las similitudes que existen entre estos dos
robots se usará como referencia al TurtleBot para la programación del Magabot.
1.4 Hokuyo
En los apartados anteriores hemos hablado de los sensores y la necesidad que tienen los robots de usarlos para
poder recibir información sobre el entorno en el que están.
Uno de ellos es el láser Hokuyo. En este proyecto será sensor utilizado para dotar de visión al robot y nos
ayudará a comunicarnos con su entorno.
2 ROS: Robot Operating System, es un entorno de trabajo para el desarrollo de software para robots.
Figura 9: TurtleBot
Figura 10: Láser Hokuyo
10
10 Navegación en interiores con robots de servicios
El láser Hokuyo, específicamente el modelo URG-04LX-UG01 es un escáner con un láser 2D, con las
siguientes especificaciones [12]:
Peso: 160gr.
Potencia: 2.5W.
Rango de trabajo 240º.
Precisión de 60 a 1000mm: ±30mm y de 1000 a 4095 mm:, precisión ±3%.
Resolución angular 0.352º.
Interfaz: USB 2.0
Luminosidad: 6k-10k Lux
Temperatura/humedad: -10 a +50ºC
Resistencia a vibración: 10 a 55 Hz, doble amplitud 1.5mm cada 2 horas en X, Y y Z.
Ambiente: Interiores
Distancia 5.6 m
Frecuencia de escaneo: 10 Hz
Medidas del escáner:
Figura 11: Plano acotado del Hokuyo
11
11 Navegación en interiores con robots de servicios
Existen otros sensores láser que son más precisos, como por ejemplo el Velodyne, el cuál lanza de 16 a 64
láseres según el modelo, tiene un ángulo de trabajo de 360º y al poseer más de un láser, es capaz de generar
imágenes en 3D. Sin embargo, el precio es muy elevado a diferencia del láser Hokuyo. Este tiene un ángulo
de barrido de 240º como se han mencionado en las especificaciones, lo cual para el proyecto que se va a
realizar es suficiente al igual que la generación de imágenes en 2D, en este se prima el bajo coste y la buena
relación calidad precio que nos ofrece.
Figura 12: Velodyne
12
12 Navegación en interiores con robots de servicios
13
2 OBJETIVO Y PLAN DE TRABAJO
2.1 Objetivo
Como se ha comentado anteriormente, la robótica es una ciencia que está en auge. A día de hoy se siguen
buscando mejoras y alternativas dentro de este campo. El objetivo de este proyecto es algo que ya existe, la
navegación autónoma de un robot. Lo novedoso del proyecto es la plataforma robótica Magabot, la cual está
muy poco desarrollada y no tiene mucho código compartido.
Ya se ha comentado con anterioridade que el hecho de que un robot tenga la capacidad de navegar de forma
autónoma es algo de gran utilidad. Esto da una gran independencia al mismo y consigue que pueda hacer
diversas tareas de forma eficaz evitando que una persona tenga que hacerlo o que tenga que estar pendiente de
cada movimiento que realice.
Una vez el robot consiga la movilidad autónoma, éste podrá transportar objetos, tanto el portátil que lleva,
como cualquier otro objeto (dentro de unos límites de peso, tamaño). Puede servirnos cómo sistema de prueba
para códigos de generación de trayectorias, cómo sistema de vigilancia, detectando si hay objetos o personas
que no estaban antes. Si damos uso al micrófono y a la cámara del portátil, podría servir para hacer algunas
reuniones a distancia que requieran movilidad, etc.
2.2 Plan de Trabajo
Para realizar este proyecto, debemos realizar una serie de pasos que se enunciaran y resumirán a continuación
y más adelante se irán explicando más específicamente en cada apartado de la memoria.
Anteriormente se menciona que vamos a usar la plataforma robótica Magabot añadiéndole el sensor hokuyo y
un ordenador que estará conectado en todo momento y que servirá para comunicar al Magabot y al hokuyo
además de mandar las instrucciones que se desea que realice el robot.
La programación se realizará mediante el uso de ROS, usando archivos con programación C++. Además de
esta programación, el robot tiene programación arduino en una placa que tendrá el mismo robot. Este
programa será el responsable de que el robot se mueva y nos da cierta información sobre el estado del mismo.
El programa consta de varias partes que se conectan mediante el siguiente flujo de información:
Figura 13: Flujo de la información para la navegación autónoma
14
14 Navegación en interiores con robots de servicios
Por ello, para realizar el proyecto se seguirán los siguientes pasos:
Primero se realizará una búsqueda de información y aprendizaje de ROS. En el capítulo 3 se explicará
básicamente en qué consiste este entorno de trabajo y las funciones principales que se han usado para la
realización de este proyecto.
Una vez realizado el aprendizaje de ROS, se debe conocer el robot, cómo funcionan los drivers, cómo se
mueve, etc. Esto se explicará en el capítulo 4.
A continuación, debemos hacer un mapeado del entorno en el que se quiere que el robot se desplace, para así
poder guardar el mapa que posteriormente usará el robot para localizarse y navegar. Se explicará en el
capítulo 5.
Cuando tengamos el mapa en el que vamos a mover al robot, debemos conseguir que este sea capaz de
localizarse dentro del mismo, ya que si no lo hace no podrá realizar el siguiente paso. Esto se comentará con
detallen en el capítulo 6.
La última parte del proyecto es la navegación del robot. Esta se divide en dos partes: otorgar al robot la
capacidad de que se mueva de un sitio a otro y que además, sea capaz de esquivar objetos que previamente no
se encuentran en el mapa, tanto objetos quietos como en movimiento. Capítulo 7.
Finalmente, una vez que se ha conseguido cumplir el objetivo del proyecto se enunciarán posibles mejoras
futuras. Capítulo 8.
15
3 ROS
Anteriormente se ha definido ROS como un entorno de trabajo para el desarrollo de software para robots. Este
entorno, es el que se va a usar en el transcurso del proyecto, por ello en este capítulo se explicará con detalle en
qué consiste este entorno y las principales herramientas que se han usado. [13] [14]
ROS (Robot Operating System) es un entorno que provee a los desarrolladores de software de librerías y
herramientas para la obtención, creación y ejecución de código orientados a los robots. Provee abstracción de
hardware, controladores de dispositivos, librerías, herramientas de visualización, comunicación por mensajes,
administración de paquetes, etc. No es un marco a tiempo real, aunque se puede integrar en el código que sí lo
sea. [13] [14]
A diferencia de otras plataformas de software de robótica, ROS no tiene como objetivo ser un marco. Su
objetivo es ayudar a la investigación y el desarrollo de la robótica. Esto se consigue con el software libre, de
forma que se puedan compartir los avances, librerías… [13] [14]
Como ayuda para conseguir la colaboración entre investigadores, ROS tiene otros objetivos [13] [14]:
Ros está diseñado para ser lo más ligero posible, para que se pueda usar con otros marcos de
software de robot de forma fácil.
La plataforma de ROS es fácil de implementar en otros lenguajes de programación, algunas de ellas
son Python y C ++.
Fácil de probar gracias a una unidad integrada llamada rostest.
Es apropiado para sistemas de tiempo de ejecución grandes y para grandes procesos de desarrollo
A día de hoy, ROS no se puede instalar en cualquier sistema operativo. Esta plataforma está limitada a
plataformas basadas en UNIX, es decir principalmente se usa en sistemas operativos Linux, específicamente
en Ubuntu. En este proyecto se ha utilizado el sistema operativo Ubuntu Xenial (16.04 LTS). [13] [14]
Dentro de esta plataforma, podemos encontrarnos distintas versiones. Estas pueden no ser compatibles las unas
con las otras, con lo que hay que tener especial cuidado de no mezclar librerías, ya que puede que algunas solo
sirvan para una versión concreta. Algunas de las versiones son [13] [14]:
Electric
Fuerte
Groovy
Hydro
Indigo
Jade
Kinetic
Lunar
Este proyecto está realizado en la versión Kinetic Kame, versión de mayo del 2016, la más actual en el
momento de la instalación. En este momento la versión más novedosa es Lunar. [13] [14]
16
16 Navegación en interiores con robots de servicios
3.1 Concepto
El software de ROS está organizado por paquetes. Un package (paquete) puede contener nodos, conjuntos de
datos, archivos de configuración, etc. Estos son el elemento de construcción más atómico y el elemento de
lanzamiento en ROS [13] [14].
Los procesos que realizan el cálculo se llaman nodos. El sistema de control de ROS se compone de muchos
nodos, cada uno con una función específica: controlar un movimiento, realizar la localización, controlar un
sensor, etc. Estos se combinan entre ellos, comparten información, a través de mensajes, para dar complejidad
a las ejecuciones. Un mensaje es una estructura de datos, que comprende los campos escritos. Los mensajes
pueden ser de muchos tipos, algunos de ellos son: enero, punto flotante, booleano, matrices de puntos
primitivos, etc [13] [14].
Para que los nodos puedan comunicarse necesitan encontrarse, para ello requieren del Master (Maestro). El
cuál almacena el registro de información donde se encuentran por ejemplo los nombres de los nodos. Una
parte del Master, es el servidor de parámetros, el cuál almacena datos clave en una ubicación central. El
conjunto de nodos que al estar junto tienen una función concreta se llama Pila (Stack) [13] [14].
Como cualquier método de comunicación, los mensajes necesitan una ruta y un canal de comunicación, por
ellos existe lo que llamamos topics (tópicos). Estos se encargan de la comunicación de los nodos, para que dos
se puedan comunicar, primero uno nodo debe enviar un mensaje y el receptor debe estar subscrito para poder
recibirlo. Cualquier nodo puede subscribirse a otro nodo, sin embargo el nodo al que se está subscrito no
controla quién se subscribe, es decir, tenemos un flujo unidireccional (asíncrono) [13] [14].
No siempre es apropiada la comunicación unidireccional para las interacciones de petición/respuesta. Por
ellos, a menudo es necesario un sistema distribuido. Esto se realiza a través de servicios, que están definidos
por un par de estructuras de mensajes: una para la solicitud y otra para la respuesta [13] [14].
Para el almacenamiento y reproducción de datos de mensajes, se usa un formato llamado las bolsas. Son un
mecanismo de almacenaje de datos que pueden ser difíciles de guardar pero necesarios para la posterior
manipulación. [13] [14]
Figura 14: Esquema de comunicación a través de topics
Figura 15: Esquema de comunicación a través de servicios
17
17 Navegación en interiores con robots de servicios
3.2 Herramientas de ROS
A continuación, se hablará de algunas de las herramientas de ROS, concretamente las que han sido necesarias
para la realización del proyecto.
3.2.1 Roscore
Roscore es una colección de nodos y programas que son requisitos previos de un sistema basado en ROS. Es
necesaria su ejecución para que los nodos puedan comunicarse. En el caso particular de la ejecución de
roslaunch, roscore se ejecutará automáticamente si no lo estaba previamente. [13]
Cuando roscore se ejecuta, pone en marcha [13]:
Un maestro ROS
Un servidor de parámetros ROS
Un nodo de registro llamado rosout
3.2.2 Roslaunch
Roslaunch es una herramienta para lanzar varios nodos de forma fácil, así como establecer parámetros en el
servidor de parámetros. Incluye la opción para los proceso de respawn3 automáticamente. Para la ejecución de
la herramienta, se tienen uno o más archivos XML (con la extensión .launch) en los que se configuran los
nodos a ejecutar y los parámetros que debemos establecer. [13] [14]
3 Respawn: es el lugar del escenario o mapeado donde aparecen espontáneamente el proceso muerto al regenerarse.
Figura 16: Lanzamiento de un nodo
Figura 17: Establecimiento de parámetros
Figura 18: Ejecución de la herramienta roslaunch
18
18 Navegación en interiores con robots de servicios
3.2.3 Rosrun
Rosrun es una parte de rosbash, un paquete que contiene algunas funciones tipo bash útiles. Rosrun permite
ejecutar cualquier aplicación de un paquete sin necesidad de hacerlo en el directorio. Al ejecutarlo podemos
pasarle parámetros necesarios. [13] [14]
3.2.4 Rostopic
Rostopic es una herramienta que muestra la información sobre los topics. Puede mostrar mucha información
sobre ellos, lista de topics activos, editores y subscriptores de un topic, tasa de publicación de un topic, etc.
Utiliza la sintaxis YAML en línea de comandos para representar el contenido de un mensaje [13] [14]. Dentro
de esta herramienta podemos usar los siguientes comandos para la extracción de información [13] [14]:
rostopic bw: muestra el ancho de banda consumido por un topic
rostopic echo: imprime datos del tópico por la salida estándar
rostopic find: encuentra un topic
rostopic info: imprime información de un topic
rostopic list: imprime información sobre los topics activos
rostopic pub: publica datos a un topic activo
rostopic type: imprime el tipo de información de un topic
3.2.5 Rosnode
Rosnode es una herramienta de línea de comandos que muestra la información de los nodos. Puede mostrar las
publicaciones, suscripciones, conexiones, etc. Tiene una biblioteca experimental, de uso interno, para
recuperar información del nodo [13] [14]. Dispone de las siguientes opciones [13] [14]:
rosnode info nodo: muestra información sobre el nodo
rosnode kill nodo: mata ese proceso
rosnode list: muestra los nodos ejecutándose
rosnode machine maquina: muestra los nodos que se están ejecutando en la máquina
rosnode ping nodo: comprueba la conectividad del nodo
Figura 20: Ejecución de una aplicación
Figura 19: Ejecución de una aplicación pasándole parámetros
19
19 Navegación en interiores con robots de servicios
3.2.6 Rviz
Rviz es un visualizador de datos muy completo y útil. Es un visualizador en 3D, aunque para este proyecto
sólo usaremos 2D del visualizador, lo que supone un gran ahorro de recursos. Rviz nos permite visualizar las
lecturas de sensores y permite la visualización de cálculos (en este caso sólo usaremos la visualización de
sensores). Se caracteriza por ser intuitivo y fácil de usar. Rviz nos muestra las lecturas de los distintos topic
activos que se quieran visualizar. Si alguno no está conectado correctamente o tiene algún error rviz no lo
muestra y simboliza el fallo con un símbolo junto al topic [13] [14].
Marcos de coordenadas:
Hay dos marcos (frame) de coordenadas importantes [13] [14]:
El marco fijo (fixed frame): Es el sistema de coordenadas que tomaremos como referencia para
mostrar todos los datos. Aparece en la parte izquierda en las opciones globales (Global option).
Debemos asignarlo a un punto estático como el mundo, el mapa o la odometría. No debemos
asignarlo a un marco en movimiento, como la base de un robot.
El marco objetivo (target frame). Es el sistema de coordenadas que asignamos a la vista. Este
debe estar asignado a un marco en movimiento cómo la base del robot, por ejemplo. Podemos
tener distintas vistas y así ir cambiando de una a otra en función de lo que queramos ver…
Figura 21: Interfaz de rviz
Figura 22: Global Options de rviz
20
20 Navegación en interiores con robots de servicios
Modo de operación:
Existen diversos modos de operación. Se pueden seleccionar en la parte superior. Por defecto está en
interactuar y podemos también mover la cámara, seleccionar elementos (y ver sus valores, por ejemplo
coordenadas de puntos), etc. [13] [14]
Hay que destacar dos de ellos [13] [14]:
2D Pose Estimate: Permite mandarle al robot una estimación de la posición en la que se
encuentra. Esto es muy útil a la hora de que el robot se localice.
2D Nav Goal: Permite mandarle al robot la posición a la que queremos que se dirija y la
orientación con la que debe acabar una vez llegue a la posición.
Monitor (display):
El monitor permite configurar la visualización. Permite elegir que topics se desean visualizar y configurar
la forma de visualizarse. [13] [14]
3.2.7 Rqt_graph
Rqt_graph es una aplicación que nos permite visualizar los nodos en ejecución y el paso de los topics entre
ellos. Su función es la de visualizar qué está pasando con nuestro programa. Nos muestra las relaciones entre
los nodos indicando cuales son los que publican, cuáles son los subscriptores y los topics a través de los que se
Figura 23: Barra de herramientas de rviz
Figura 24: Display de rviz
21
21 Navegación en interiores con robots de servicios
comunican [13] [14]. Hay distintos modos de visualización, puedes ver [13] [14]:
Sólo los nodos
Nodos y topics activos
Todos los nodos y topics
Figura 25: Ejecución de rqt_graph
Figura 26: Visualización de todos los nodos y topics en rqt_graph
Figura 27: Visualización de las conexiones entre nodos.
22
22 Navegación en interiores con robots de servicios
23
4 DRIVER
Como se menciona anteriormente, este proyecto se realizan con el uso del robot Magabot. Antes de realizar
cualquier paso, se debe conocer cómo llegará la información al robot.
El Magabot tiene dos placas con las que controlaremos los movimientos y que nos enviará la odometría. La
odometría es el estudio de la estimación de la posición de vehículos con ruedas durante la navegación. Para
realizar esta estimación se usa información sobre la rotación de las ruedas para estimar cambios en la posición
a lo largo del tiempo. Esta información nos la da un programa con el que nos comunicamos con el robot.
Este programa (magabot_node.cpp) está realizado en lenguaje C++ mezclado con funciones de ROS. El
código es anterior al proyecto, su función es simplemente la de comunicar el robot con ROS. Por ello, todas las
modificaciones y ejecuciones serán en ROS, con lo que este código no se modifica. El código completo se
puede visualizar en el Anexo A, en este capítulo sólo explicaremos lo más importante del código usando
algunas líneas para facilitar la búsqueda en el código.
Primero se comienza introduciendo parámetros de las dimensiones del robot e inicializando los que usaremos
para la odometría, velocidades, etc. todos ellos de forma global.
Lo primero que hace el main es inicializar y conectar el arduino con ROS.
Una vez conectado, se asignan los parámetros a las variables creadas.
Se define y configura que nodos van a ser los publicadores y cuales los subscriptores en ROS.
Figura 28: Algunas líneas del código de inicialización y conexión de arduino y ROS
Figura 29: Algunas líneas del código de asignación de parámetros a las variables
Figura 30: Algunas líneas del código de publicadores y subscriptores de ROS
24
24 Navegación en interiores con robots de servicios
Por último, se configura el puerto serie y la cantidad de señal por segundo con la que se van a comunicar el
ordenador y la controladora del magabot.
Además del main, hay varias funciones definidas, las más importantes son:
En la función drive se configuran la velocidad lineal y angular procedente del ordenador y se traduce para que
se pueda mandar a las ruedas delanteras del robot.
La función publish_odometry tiene como objetivo actualizar, obtener y publicar el valor de la odometría y la
transformada. La odometría se actualiza teniendo en cuenta el valor anterior, las medidas de la rueda y la
relación entre metros y vueltas de la rueda y el tiempo que está en marcha.
Primero se publica las transformaciones sobre tf y a continuación, se establecerá la velocidad y publicará
el mensaje de odometría sobre ROS.
Figura 31: Algunas líneas del código de traducción de velocidad a movimiento de rueda
Figura 32: Algunas líneas del código de cálculo de odometría
Figura 33: Algunas líneas del código de publicación de la transformada
25
25 Navegación en interiores con robots de servicios
Por último, la función getRPY tiene como función recibir señales del codificador y enviar la odometría, la
transformada y la velocidad al robot.
Figura 34: Algunas líneas del código de la recepción de señales
26
26 Navegación en interiores con robots de servicios
27
5 MAPEADO
El primer paso que se va a realizar, es crear un mapa que introducir al robot para que sea capaz de localizarse y
navegar en él. Para ello, lo primero que es necesario es tener un sensor adecuado para que reconozca el
entorno. Como se menciona anteriormente, usaremos un sensor láser, hokuyo.
5.1 Lectura del sensor
Anteriormente se ha explicado las características del hokuyo, sin embargo, no se ha comentado cómo vamos a
leer la información que lee. Lo primero que debemos es buscar los drivers, con los que poder comunicar el
ordenador con el láser.
Anteriormente se comentó que había que tener en cuenta la versión de ROS que se estaba utilizando ya que
existían funciones, paquetes, etc. que no eran compatibles con todas las versiones. Este es el caso del láser
hokuyo. Inicialmente el launch que ejecutaba el láser estaba escrito para la versión Indigo, con lo que al
instalar y ejecutar los drivers del láser lo hacía con el nombre de “hokuyo_node”. Sin embargo, la versión de
este proyecto es Kinetic, con lo que se debe usar “urg_node”. La ejecución del hokuyo se realizará a través de
un archivo launch, para poder ejecutar de esta forma más de un nodo.
Una vez se ha instalado, es importante indicar bien el puerto del ordenador por el que el láser va a mandar la
información. En este caso el puerto del que se lee la información es el puerto de entrada /dev/ttyACM0. Es
muy importante que esté bien puesto, ya que si no el programa no será capaz de leer correctamente los valores
del láser.
5.2 Movimiento del robot
Para poder realizar el mapeado, se necesita que el robot esté en movimiento, para poder desplazarse y leer de
forma correcta en qué posición está cada cosa que lee el láser.
Primero es necesaria la ejecución del driver, ya que sin él no se comunicará el ordenador con el robot y no
podrá realizar movimientos. Para ello se ejecuta un archivo tipo launch (magabot.launch) previamente creado.
En él se ejecuta el driver al que se le definen algunos parámetros, entre ellos los puertos por los que se
conectan el robot al ordenador. También se ejecuta el nodo del láser y el nodo de la transformada. Se puede
encontrar el código completo en el Anexo B.
Figura 35: Ejecución del láser
28
28 Navegación en interiores con robots de servicios
En este momento del proyecto, el robot no tiene autonomía para desplazarse con lo que es necesario que de
forma manual le enviemos en cada momento la velocidad a la que debe moverse. Esto se hace modificando el
topic encargado de la velocidad /cmd_vel.
Hay distintos métodos de cambiar el valor del topic para poder mover el robot, algunos de ellos son:
Manualmente usando la herramienta rostpic pub, la cual publica datos en topics.
Con el uso del teclado
Con el uso de un joystich
/cmd_vel es te tipo geometry/Twist, con lo que todos los métodos tienen que enviar al topic un mensaje del
mismo tipo. Si no lo es, nos dará error y no será un método válido.
En este proyecto la modificación del topics se llevó a cabo con dos de estos métodos. Primero, una vez el
programa se ejecutaba sin ningún error se comenzó a publicar en el topic manualmente. La única función de
este método era comprobar que los drivers y el programa estaban funcionando de forma correcta. Una vez
comprobado, se usó un teclado inalámbrico, para mayor comodidad y para dar libertad de movimiento al robot
al no necesitar estar pegado al Magabot para manejarlo.
Para el uso del teclado inalámbrico, existe un paquete llamado teleop_twist_keyboard. Este crea un nodo que
publica directamente en el topic /cmd_vel con lo que una vez ejecutado simplemente se deben seguir las
indicaciones de movimiento y automáticamente el robot recibirá las indicaciones del teclado.
Una vez se ejecutado el launch magabot y el teclado, podemos visualizar con rqt_graph y rviz las relaciones de
Figura 37: Ejecución de la lectura de teclado
Figura 38: Relación de teclas con cada movimiento
Figura 36: Ejecución de magabot_node y asignación de parámetros
29
29 Navegación en interiores con robots de servicios
los nodos y las lecturas de los topics:
5.3 Creación de Mapa
Una vez realizado los pasos anteriores, se debe mover el robot mientras se guarda crea un mapa. Para ello
existen distintas formas de hacerlo en ROS. En este proyecto usaremos el paquete gmapping:
Al ejecutar la creación del mapa automáticamente comenzará a crearse un mapa como se puede ver en rviz.
Figura 39: Esquema de relaciones entre nodos magabot.launch y teleop_twist_keyboard
Figura 40: Valores del topic /láser
Figura 41: Ejecución de creación de mapa
30
30 Navegación en interiores con robots de servicios
A medida que el robot se mueve, se va generando un mapa con más elementos y más tamaño.
Una vez finalizado el mapa se guarda para poder utilizarlo posteriormente. Esto se realizará mediante el
paquete map_server.
Al ejecutar la línea que se puede visualizar en la imagen, se generan dos archivos con nombre prueba9. Un
archivo tipo pgm (la imagen del mapa) y otro tipo yalm (con parámetros del mapa).
Figura 42: Comienzo de creación de un mapa
Figura 43: Creación de mapa después del movimiento de robot
Figura 44: Código para guardar mapa
31
31 Navegación en interiores con robots de servicios
Para este proyecto se han realizado distintos mapas de distintos entornos, hasta elegir el definitivo. Este
entorno se caracteriza por tener un suelo liso y sin excesivos obstáculos. El suelo liso evita tropiezos del robot,
ya que, además de poder ser peligroso para el hardware pierde la localización. La limitación de obstáculos
otorga libertad de movimiento al robot, también es necesario evitar obstáculos tipo mesas, sillas, etc. ya que el
sensor no sólo detecta las patas y puede chocarse.
Figura 45: Archivo tipo yalm con los parámetros del mapa
Figura 46: Dos de los mapas de prueba
Figura 47: Mapa final
32
32 Navegación en interiores con robots de servicios
33
6 LOCALIZACIÓN
Antes de que un robot sea capaz de moverse sólo, necesita tener la capacidad de encontrase dentro el
mapa (localización). La localización se puede llevara a cabo de distintas formas, en este proyecto
usaremos el AMCL (Adaptative Monte Carlo Localization). AMCL es un sistema de localización
probabilística para un robot que se mueve en 2D. Implementa el enfoque adaptativo, que utiliza un filtro
de partículas para realizar un seguimiento de la posición de un robot contra un mapa conocido [13].
Para la ejecución del paquete AMCL y la asignación de parámetros del mismo, se usa el archivo tipo
launch llamado magabot_2dnav (se puede visualizar el código completo en el Anexo C), a continuación
se muestra la parte de código referente a la localización.
Una vez se ejecuta el paquete AMCL, aparecerá una nube de puntos (particlecloud), topic en el que publica el
AMCL. Esta nube se extenderá o disminuirá según el robot esté más o menos seguro de su localización,
cuanto menos sea, mejor es su localización. A continuación se muestra en la figurala visualización en rviz de
la ejecución del launch magabot_2dnav.
Figura 48: Código de ejecución del AMCL y asignación de parámetros
Figura 49: Visualización de rviv de la ejecución de magabot_2nav
34
34 Navegación en interiores con robots de servicios
En la figura, se puede apreciar que el robot está totalmente fuera del mapa y no sabe en absoluto donde se
encuentra. Para ello usamos 2D Pose Estimate, herramienta de la barra de herramientas de rviz. Esto nos
permitirá indicarle al robot de forma aproximada donde se encuentra.
Una vez el robot tiene una posición aproximada, se debe mover para que sea capaz de localizarse sólo. Este
movimiento se puede llevar a cabo con el teclado inalámbrico anteriormente usado. Una vez el robot se
desplaza se puede observar que cada vez su localización es más exacta. La exactitud de la localización se
puede apreciar fácilmente gracias al láser, ya que las paredes que detecta deben coincidir con las guardadas en
el mapa anteriormente.
Figura 50: Uso de 2D Pose Estimate para la aproximación de localización
Figura 51: Robot localizado
35
7 NAVEGACIÓN
El último paso del proyecto es llevar a cabo la navegación. Esta se divide en dos partes, la posibilidad de
moverse de forma autónoma a la posición asignada y la capacidad de esquivar obstáculos que aparezcan
en el recorrido. Para realizar este paso se usará la pila navigation. Navigation es una pila de navegación
2D que recibe información de odometría, flujos de sensores y una meta plantean y emite comandos de
velocidad segura que se envían a una base móvil [13]. Para la ejecución de la pila, se requiere ejecutar el
nodo move_base y asignarle gran cantidad de parámetros. Cada parámetro sirve para la configuración de
la navegación, algunos de los parámetros definidos son la definición del tamaño del robot, la subscripción
al topic del láser, velocidades máximas y mínimas, etc. Se pueden encontrar todos los parámetros en los
distintos apartados del Anexo C.
Para la navegación es necesario que el robot esté bien localizado, una vez conseguido. Con la herramienta 2D
Nav Goal, de rviz se puede asignar al robot una meta. En ese instante, se genera un camino global que el robot
ha de seguir.
Figura 52: Código de ejecución de navigation y asignación de parámetros
Figura 53: Uso de 2D Nav Goal para la asignación de meta
36
36 Navegación en interiores con robots de servicios
Una vez lograda la navegación sin obstáculos, se configuran los parámetros correspondientes para el correcto
funcionamiento de la navegación con obstáculos. Para ello usamos lo que se denomina mapa de coste. Este
mapa crea un perímetro, establecido en los parámetros, alrededor del robot por el que si el láser detecta que
hay algo, el robot debe cambiar el camino y esquivarlo. Con la ayuda del mapa de coste (costmap) se irán
generando distintas trayectorias locales a las que el robot seguirá para esquivar los obstáculos que le aparezcan
por caminos, tanto estáticos como móviles. En los parámetros se podrá definir el tamaño del costmap, la
periodicidad de comprobación de la existencia o no de obstáculos, de la generación de nuevas trayectorias, etc.
Figura 54: Generación de trayectoria y navegación
Figura 55: Generación de trayectorias con obstáculos estáticos
37
37 Navegación en interiores con robots de servicios
Figura 56: Generación de trayectoria y modificación ante obstáculos móviles
38
39
8 CONCLUSIONES Y DESARROLLOS FUTUROS
El objetivo de este proyecta era la navegación en interiores con robots de servicio usando la plataforma
robótica Magabot. Para ello se partía de un código ya creado, que había que modificar para el correcto
funcionamiento. Es importante tener en cuenta al usar un código previamente creado que se debe usar
correctamente la versión de ROS y poner bien los topics y los puertos de entrada, ya que algunos pueden no
coincidir y aparecer problemas.
A la hora de elegir el entorno de experimentación es necesario conocer bien las características y las
posibilidades reales del robot. Para el Magabot el entorno no debe contener escalones o agujeros, ya que puede
perder la localización al colisionar o al hundirse.
En la navegación, se ponen en marcha todos los pasos que se han realizado juntos, con lo que puede ser uno de
los momentos más críticos ya que si falla algún paso supone el fallo completo. Por ello se deben tener en
cuenta lo siguiente: Se debe disminuir la velocidad del robot, para evitar posibles vuelcos o caídas de los
objetos transportado. Existe cierto error en la localización, es recomendable después de algunos navegaciones
comprobar la correcta navegación y en caso de no ser correcta volver a localizarlo adecuadamente. En algunas
ocasiones, para esquivar los obstáculos el robot se mueve hacia atrás y al carecer de datos en ese ángulo puede
sufrir colisiones, con lo que se debe buscar un entorno lo más amplio posible.
El trabajo realizado cumple con sus objetivos, siempre con la posibilidad de ser ampliado, modificado y
mejorado.
Tras la realización de este proyecto surgen cuestiones que solucionar y nuevas posibilidades que mejorar y
desarrollar en el futuro, algunas son:
El uso de distintos sensores con un ángulo de barrido mejor, por ejemplo velodyne. Con él se podrían
evitar las posibles colisiones en la marcha atrás.
En caso de usar el láser hokuyo, la posibilidad de darle cierta inclinación para poder generar un mapa
3D y así evitar posibles escalones o agujeros del terreno, además de poder detectar un mayor número
de objetos.
Mejora de la estructura, de forma que disminuya el riesgo de caída de los objetos en ella.
La comunicación e interacción entre más de un robot.
40
40 Navegación en interiores con robots de servicios
41
9 BIBLIOGRAFÍA
[1] A. O. Baturone, Robótica Manipuladores y robots móviles, Barcelona: Marcombo, 2001.
[2] «https://robotica.wordpress.com/about/,» [En línea].
[3] S. K. Saha, Introducción a la robótica, México: Mc Graw Hill, 2010.
[4] M. M. Arteche, Robótica, Valencia: Universidad Politécnica de Valencia, 2009.
[5] S. R. Y. e. I. A. M. José Mª Angulo Usategui, Introducción a la robótica. Principios teóricos, construcción
y, Madrid: THOMSON, 2005.
[6] G. O. M. Nelia Bustamante Álvarez, Sensores de temperatura, pH y detergentes para control
medioambiental en un prototipo que utiliza fibra optica y luminiscencia con resolucion defase, Madrid:
Universidad complutense de Madrid, 2001.
[7] G. S. A. J. &. J. M. C. Leonel German Corona Ramírez, Sensores y actuadores: aplicaciones con
Arduino, México: Grupo Editorial Patria, 2014.
[8] V. R. González, «http://platea.pntic.mec.es/vgonzale/cyr_0204/ctrl_rob/robotica/industrial.htm,» 2002-
03. [En línea].
[9] J. M. E. E. &. P. A. E. Murcia, Caracterización de un agv (vehículo guiado automáticamente) en el
sistema de manufactura flexible; caso centro tecnológico de automatización ctai de la pontificia
universidad javeriana, Bogotá, 2012.
[10] «http://artica.cc/projects/hardware/2013/12/02/magabot.html,» [En línea].
[11] «http://www.turtlebot.com/about/,» [En línea].
[12] «https://www.roscomponents.com/es/lidar-escaner-laser/83-urg-04lx-ug01.html,» [En línea].
[13] «http://wiki.ros.org,» [En línea].
[14] «https://moodle2015-16.ua.es/moodle/mod/book/view.php?id=82546,» [En línea].
[15] M. A. Martín, Robótica, Valencia: Universidad Politécnica de Valencia, 2009.
[16] «http://robots-argentina.com.ar/Comunicacion_busI2C.htm,» [En línea].
42
42 Navegación en interiores con robots de servicios
43
ANEXO A. MAGABOT_NODE
En este anexo se refleja el driver del que disponíamos al comienzo del proyecto. El código como se menciona
en al capítulo 4 está en lenguaje c++ mezclado con funciones de ROS.
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <ros/ros.h>
#include <ros/console.h>
#include <tf/transform_broadcaster.h>
#include <nav_msgs/Odometry.h> // odom
#include <geometry_msgs/Twist.h> // cmd_vel
#include <cereal_port/CerealPort.h>
// MAGABOT Dimensions
#ifndef NORMALIZE
#define NORMALIZE(z) atan2(sin(z), cos(z)) // Normalize angle to domain -pi, pi
#endif
double MAGABOT_WIDTH = 0.345; //m. Between wheels
double WHEEL_RADIUS = 0.043937; //m
double TICKS_PER_TURN_L = 3900;//2450;
double TICKS_PER_TURN_R = 2230;
//MAGABOT data for odometry
double TWOPI = 6.2831853070;
double PI = 3.1415926535;
const float K_MOTOR_RATIO = TICKS_PER_TURN_L * 0.00332 / ( PI * WHEEL_RADIUS);
ros::Publisher *odom_pub;
tf::TransformBroadcaster *odom_broadcaster;
cereal::CerealPort serial_port, serial_port_inertial;
ros::Time current_time, last_time;
std::string base_frame_id;
std::string odom_frame_id;
double last_time_pub = 0.0;
bool signof (int n) { return n >= 0; }
bool confirm_communication = true;
int ID_Robot = 0;
double odometry_x = 0.0;
double odometry_y = 0.0;
double odometry_yaw = 0.0;
double odometry_pitch = 0.0;
double odometry_roll = 0.0;
int right_encoder_prev = 0;
int left_encoder_prev = 0;
int n_inter = 0;
double dt = 0;
double vel_x = 0;
44
44 Navegación en interiores con robots de servicios
double vel_y = 0;
double vel_yaw = 0;
bool to_write = false;
double yaw_default = 0;
int left_encoder_count = 0;
int right_encoder_count = 0;
int left_encoder_acc = 0;
int right_encoder_acc = 0;
double x,y,th;
int n_iter = 0;
float correction = 0;
int lvel = 0;
int rvel = 0;
double last_yaw=0.0;
void drive(double linear_speed, double angular_speed)
{
float ang = angular_speed * MAGABOT_WIDTH/2;
int left_write = 0;
int right_write = 0;
if(linear_speed == 0 && angular_speed == 0)
{
left_write = 0;
right_write = 0;
}
else
{
float l_ratio = K_MOTOR_RATIO* 0.5543808461*pow(fabs(linear_speed - ang),-0.1423547731);
float r_ratio = K_MOTOR_RATIO* 0.5543808461*pow(fabs(linear_speed + ang),-0.1423547731);
right_write = (int)((linear_speed + (angular_speed * MAGABOT_WIDTH / 2)) * r_ratio);
left_write = (int)((linear_speed - (angular_speed * MAGABOT_WIDTH / 2)) * l_ratio);
}
ROS_FATAL("[ref_values]: Vl = %d ; Vr = %d",left_write, right_write);
if(left_write < 6 && left_write > 0)
{
left_write = 7;
}
if(left_write > -6 && left_write < 0)
{
left_write = -7;
}
if(right_write < 6 && right_write > 0)
{
right_write = 7;
}
if(right_write > -6 && right_write < 0)
{
right_write = -7;
}
lvel = left_write;
rvel = right_write;
}
void cmdVelReceived(const geometry_msgs::Twist::ConstPtr& cmd_vel)
{
//ROS_FATAL("[cmd_vel]: Vlinear = %f, Vangular = %f",cmd_vel->linear.x, cmd_vel->angular.z);
drive(cmd_vel->linear.x, cmd_vel->angular.z);
}
45
45 Navegación en interiores con robots de servicios
void getSonars()
{
char sonars_command[1];
sonars_command[0] = char(0x83);
serial_port.write(sonars_command,1);
char sonars_response[10];
serial_port.read(sonars_response, 10, 1000);
int sonars0 = ((int)(unsigned char)sonars_response[0] * 255 + (int)(unsigned char)sonars_response[1]);
int sonars1 = ((int)(unsigned char)sonars_response[2] * 255 + (int)(unsigned char)sonars_response[3]);
int sonars2 = ((int)(unsigned char)sonars_response[4] * 255 + (int)(unsigned char)sonars_response[5]);
int sonars3 = ((int)(unsigned char)sonars_response[6] * 255 + (int)(unsigned char)sonars_response[7]);
int sonars4 = ((int)(unsigned char)sonars_response[8] * 255 + (int)(unsigned char)sonars_response[9]);
// ROS_FATAL("SONARS:%d %d %d %d %d", sonars0, sonars1, sonars2, sonars3, sonars4);
}
void getIR()
{
char ir_command[1];
ir_command[0] = char(0x49);
serial_port.write(ir_command,1);
char ir_response[6];
serial_port.read(ir_response, 6, 1000);
int ir0 = ((int)(unsigned char)ir_response[0]*255 + (int)(unsigned char)ir_response[1]);
int ir1 = ((int)(unsigned char)ir_response[2]*255 + (int)(unsigned char)ir_response[3]);
int ir2 = ((int)(unsigned char)ir_response[4]*255 + (int)(unsigned char)ir_response[5]);
//ROS_FATAL("IRS:%d %d %d", ir0, ir1, ir2);
}
void getBattery()
{
char bat_command[1];
bat_command[0] = char(0x4B);
serial_port.write(bat_command,1);
char bat_response[2];
serial_port.read(bat_response, 2, 1000);
int bat_level = ((int)bat_response[0]*255 + (int)bat_response[1]);
//ROS_FATAL("BATTERY LEVEL %d", bat_level);
}
bool getBumpers()
{
bool _bump = false;
char bumper_command[1];
bumper_command[0] = char(0x66);
serial_port.write(bumper_command,1);
char bumper_response[2];
serial_port.read(bumper_response, 2, 1000);
if(bumper_response[0] == 1 || bumper_response[1] == 1)
{
_bump = true;
//ROS_FATAL("BUMP");
}
return _bump;
}
void publish_odometry(int l_ticks, int r_ticks)
{
double last_x = odometry_x;
double last_y = odometry_y;
46
46 Navegación en interiores con robots de servicios
//double last_yaw = odometry_yaw;
last_time = current_time;
current_time = ros::Time::now();
dt = (current_time - last_time).toSec();
bool publish_info = true;
//ROS_FATAL("Num ticks acumulados: %i , %i", l_ticks, r_ticks);
double dl = -(double)(l_ticks * 3.14 * 2 * WHEEL_RADIUS /TICKS_PER_TURN_L);
double dr = (double)(r_ticks * 3.14 * 2 * WHEEL_RADIUS / TICKS_PER_TURN_L);
double dx = (dr + dl) /2.0;
//double angle = (double)((dr - dl)/MAGABOT_WIDTH);
//odometry_yaw = -(ypr[0]); //rad
//odometry_yaw = atan2(sin(aux), cos(aux)); //rad
odometry_x += dx * cos((double) odometry_yaw); //m
odometry_y += dx * sin((double) odometry_yaw); //m
//odometry_yaw = odometry_yaw + angle;
//double dt = (current_time - last_time).toSec();
double vel_x = dx/dt;
double vel_y = 0;
double vel_yaw = (odometry_yaw - last_yaw)/dt;
last_yaw = odometry_yaw;
// if(vel_x != 0)
//ROS_FATAL("[odometry_vel]: vx = %f vrot = %f",vel_x, vel_yaw);
// ******************************************* //first, we'll publish the transforms over tf
geometry_msgs::TransformStamped odom_trans;
odom_trans.header.stamp = ros::Time::now();
odom_trans.header.frame_id = odom_frame_id;
odom_trans.child_frame_id = base_frame_id;
odom_trans.transform.translation.x = odometry_x;
odom_trans.transform.translation.y = odometry_y;
odom_trans.transform.translation.z = 0.0;
odom_trans.transform.rotation = tf::createQuaternionMsgFromYaw(odometry_yaw);
odom_broadcaster->sendTransform(odom_trans);
// ******************************************************************************************
//next, we'll publish the odometry message over ROS
nav_msgs::Odometry odom;
odom.header.stamp = ros::Time::now();
odom.header.frame_id = odom_frame_id;
//set the position
odom.pose.pose.position.x = odometry_x;
odom.pose.pose.position.y = odometry_y;
odom.pose.pose.position.z = 0.0;
odom.pose.pose.orientation = tf::createQuaternionMsgFromYaw(odometry_yaw);
//set the velocity
odom.child_frame_id = base_frame_id; //m1_base_link
odom.twist.twist.linear.x = vel_x;
odom.twist.twist.linear.y = vel_y;
odom.twist.twist.angular.z = vel_yaw;
/*odom.pose.covariance[0] = 0.001;
odom.pose.covariance[7] = 0.001;
odom.pose.covariance[14] = 0.001;
odom.pose.covariance[21] = 1000;
47
47 Navegación en interiores con robots de servicios
odom.pose.covariance[28] = 1000;
odom.pose.covariance[35] = 1000;
odom.twist.covariance = odom.pose.covariance; */
//publish the odometry
odom_pub->publish(odom);
}
//Receive encoder ticks and send 'odom' and 'tf'
int getRPY()
{
char command[1];
command[0] = (char)0x40;
try
{
serial_port_inertial.write(command, 1);
}
catch(cereal::Exception& e)
{
ROS_ERROR("ERROR writing INERTIAL_CMD in serial port");
return -1;
}
int Yaw_int, Pitch_int, Roll_int, Checksum_read,Checksum_Total ;
int size = 10;
char buffer[size];
try
{
serial_port_inertial.readBytes(buffer, size, 1000);
}
catch(cereal::Exception& e)
{
ROS_ERROR("ERROR reading INERTIAL from serial port");
return(-1);
}
Yaw_int = (int)((int)buffer[1] << 8) + (int)(buffer[2]);
if (Yaw_int > 32767)
Yaw_int = -(65535 - Yaw_int);
Pitch_int = (int)((int)buffer[3] << 8) + (int)(buffer[4]);
if (Pitch_int > 32767)
Pitch_int = -(65535 - Pitch_int);
Roll_int = (int)((int)buffer[5] << 8) + (int)(buffer[6]);
if (Roll_int > 32767)
Roll_int = -(65535 - Roll_int);
odometry_pitch = (double)Pitch_int / 100.0;
odometry_roll = (double)Roll_int / 100.0;
odometry_yaw = -(double)Yaw_int / 100.0; //yaw provided in angles
odometry_yaw *= M_PI / 180.0; //converted to rads
//ROS_FATAL("YAW:%f", odometry_yaw);
return 0;
}
void timerCallback(const ros::TimerEvent&)
{
getRPY();
48
48 Navegación en interiores con robots de servicios
getSonars();
//GET ODOMETRY
char tick_command[1];
tick_command[0] = char(0x74);
serial_port.write(tick_command,1);
char tick_response[4];
serial_port.read(tick_response, 4, 1000);
int _l_ticks = ((int)tick_response[0]*256 + (int)tick_response[1]);
int _r_ticks = ((int)tick_response[2]*256 + (int)tick_response[3]);
//ROS_FATAL("ODOM:%d %d", _l_ticks, _r_ticks);
publish_odometry(_l_ticks, _r_ticks);
getIR();
getBattery();
getBumpers();
//WRITE VELOCITIES
char vel_command[5];
vel_command[0] = (char)(0x86);
vel_command[1] = (char)((int)(abs(lvel)));
if(lvel > 0)
vel_command[2] = (char)(0);
else
vel_command[2] = (char)(1);
vel_command[3] = (char)((int)(abs(rvel)));
if(rvel > 0)
vel_command[4] = (char)(0);
else
vel_command[4] = (char)(1);
serial_port.write(vel_command,5);
//lvel = 0;
//rvel = 0;
//ROS_FATAL("%d %d", (int)(abs(lvel)), (int)(abs(rvel)));
//char vel_response[1];
//serial_port.read(vel_response, 1, 1000);
}
//receive cmds_vel from nav_stack
int main(int argc, char** argv){
ros::init(argc, argv, "magabotnode");
ros::NodeHandle n;
ros::NodeHandle pn("~");
ros::NodeHandle pni("~");
std::string port, portinertial,odom_topic_id,cmd_vel_topic_id;
/*
if (argc<2)
{
port="/dev/ttyACM0";
portinertial="/dev/ttyACM1";
49
49 Navegación en interiores con robots de servicios
ROS_WARN("No Serial Port defined, defaulting to \"%s\"",port.c_str());
ROS_WARN("Usage: \"rosrun [pkg] robot_node /serial_port\"");
}
else
{
port="/dev/ttyACM0";
portinertial="/dev/ttyACM1";
ROS_INFO("Serial port: %s",port.c_str());
}
*/
pn.param<std::string>("port",port,"/dev/ttyACM0");
pn.param<std::string>("port_inertial",portinertial,"/dev/ttyACM1");
pn.param<std::string>("base_frame_id", base_frame_id, "/base_link"); //change m1_base_link
pn.param<std::string>("odom_frame_id", odom_frame_id, "/odom"); //change m1_odom
pn.param<std::string>("odom_topic_id", odom_topic_id, "/odom");
pn.param<std::string>("cmd_vel_topic_id",cmd_vel_topic_id,"/cmd_vel");
// ROS publishers and subscribers
ros::Publisher odom_pub_ptr = n.advertise<nav_msgs::Odometry>(odom_topic_id, 1); //500 uin queue
tf::TransformBroadcaster odom_broadcaster_ptr;
ros::Subscriber cmd_vel_sub = n.subscribe<geometry_msgs::Twist>(cmd_vel_topic_id, 10, cmdVelReceived); //10
in queue
ros::Timer timer = n.createTimer(ros::Duration(0.1), timerCallback);
odom_pub = &odom_pub_ptr;
odom_broadcaster = &odom_broadcaster_ptr;
// baud_rate and serial port:
int baudrate;
pn.param<std::string>("port", port, port.c_str());
pn.param("baudrate", baudrate, 9600);
// Open the serial port to the robot
try
{
serial_port.open((char*)port.c_str(), baudrate);
}
catch(cereal::Exception& e)
{
ROS_FATAL("Robot -- Failed to open odometry serial port!");
ROS_BREAK();
}
ros::Duration(2.5).sleep();
int baudrate2;
pn.param<std::string>("port_inertial", portinertial, portinertial.c_str());
pn.param("baudrate2", baudrate2, 115200);
try
{
serial_port_inertial.open((char*)portinertial.c_str(), baudrate2);
char command[2];
command[0] = (char)0x50;
command[1] = (char)0x02;
serial_port_inertial.write(command, 2);
char buffer[4];
try
{
serial_port_inertial.readBytes(buffer, 4, 1000);
50
50 Navegación en interiores con robots de servicios
}
catch(cereal::Exception& e)
{
ROS_ERROR("ERROR writing INERTIAL_CMD in serial port");
}
}
catch(cereal::Exception& e)
{
ROS_FATAL("Robot -- Failed to open inertial serial port!");
//ROS_BREAK();
}
//wait (2.5 seconds) until serial port gets ready
ros::Duration(2.5).sleep();
ros::spin(); //trigger callbacks and prevents exiting
return(0);
}
51
ANEXO B. MAGABOT.LAUNCH
A continuación, se puede visualizar el archivo tipo launch llamado magabot. El cual ejecuta y asigna
parámetros a los drivers del Magabot, ejecuta el láser y la transformada.
<!-- -->
<launch>
# Magabot driver
<node name ="magabot_node" pkg="magabot" type="magabot_node" output="screen">
<param name="port" type="string" value="/dev/ttyACM1" />
<param name="port_inertial" type="string" value="/dev/ttyACM2" />
<param name="odom_frame_id" type="string" value="/odom"/>
<param name="base_frame_id" type="string" value="/base_link"/>
<param name="cmd_vel_topic_id" type="string" value="/cmd_vel" />
<param name="odom_topic_id" type="string" value="/odom"/>
</node>
# Láser driver
<node name="láser" pkg="urg_node" type="urg_node" output="screen">
<param name="serial_port" type="string" value="/dev/ttyACM0" />
<param name="frame_id" type="string" value="láser" />
</node>
# Static TF
<node pkg="tf" type="static_transform_publisher" name="static_láser_tf" args="0.0 0.0 0.15 0 0 0
base_link láser 10" />
</launch>
52
52 Navegación en interiores con robots de servicios
53
ANEXO C. MAGABOT_2DNAV.LAUNCH
En este anexo se podrá observar el archivo launch y los archivos tipo yalm, los cuales están creados para la
asignación de parámetros para el nodo de navegación.
12.1 Magabot_2dnav
<!--
Launch File for the navigation stack with a map.
-->
<launch>
<!-- Robot Driver -->
<!-- Láser Driver -->
<!-- Láser TF -->
<include file="$(find magabot)/launch/magabot.launch" />
<!-- Run the map server: HTS office -->
<node name="map_server" pkg="map_server" type="map_server" args="$(find magabot)/maps/prueba9.yaml"
required="true" respawn="false"/>
<!--- Run Adaptive Monte Carlo Localization (AMCL) -->
<node pkg="AMCL" type="AMCL" name="AMCL" >
<remap from="láser" to="base_scan"/>
<remap from="odom" to="map"/>
<param name="transform_tolerance" value="0.3"/>
<param name="min_particles" value="2000"/>
<param name="max_particles" value="5000"/>
<param name="transform_tolerance" value="0.3"/>
<param name="initial_pose_x" value="9.650" />
<param name="initial_pose_y" value="8.380" />
<param name="use_map_topic" value="true" />
</node>
<!--- Run Navigation -->
<node pkg="move_base" type="move_base" respawn="true" name="move_base" output="screen" >
<!--<param name="base_global_planner" value="carrot_planner/CarrotPlanner"/>--> <!-- use carrot
planner as the global planner! -->
<rosparam file="$(find magabot)/config_files/magabot_costmap_common_params.yaml"
command="load" ns="global_costmap" />
<rosparam file="$(find magabot)/config_files/magabot_costmap_common_params.yaml"
command="load" ns="local_costmap" />
<rosparam file="$(find magabot)/config_files/magabot_local_costmap_params.yaml" command="load"
/>
<rosparam file="$(find magabot)/config_files/magabot_global_costmap_params.yaml" command="load"
/>
<rosparam file="$(find magabot)/config_files/magabot_base_local_planner_params.yaml"
command="load" />
<rosparam file="$(find magabot)/config_files/magabot_move_base_params.yaml" command="load" />
</node>
54
54 Navegación en interiores con robots de servicios
<!--- Run rviz -->
<node name="rviz" pkg="rviz" type="rviz" respawn="false" output="screen" args="-d $(find
magabot)/config_files/rviz_magabot.rviz"/>
</launch>
12.2 Magabot_costmap_common_params
obstacle_range: 2.5 #1.5
raytrace_range: 3.0 #2.0
footprint: [[0.15,0.16],[0.15,-0.16],[-0.35,-0.16],[-0.35,0.16]] #original IDmind
#robot_radius: 0.2
inflation_radius: 0.20
observation_sources: láser_scan_sensor
láser_scan_sensor: {sensor_frame: láser, data_type: LáserScan, topic: scan , marking: true, clearing: true}
12.3 Magabot_local_costmap_params
local_costmap:
global_frame: odom
robot_base_frame: base_link
update_frequency: 0.25
publish_frequency: 2.0
static_map: false
rolling_window: true
width: 6.0
height: 6.0
resolution: 0.025
inflation_radius: 0.35
12.4 Magabot_global_costmap_params
global_costmap:
global_frame: map
robot_base_frame: base_link
update_frequency: 0.25
static_map: true
12.5 Magabot_base_local_planner_params
TrajectoryPlannerROS:
max_vel_x: 0.3
min_vel_x: 0.1
max_rotational_vel: 0.3
min_in_place_rotational_vel: 0.1
acc_lim_theta: 1
acc_lim_x: 0.1
holonomic_robot: false
55
55 Navegación en interiores con robots de servicios
sim_time: 1.4
sim_granularity: 0.025 #default 0.025
vx_samples: 5 #default 3
vtheta_samples: 10
meter_scoring: true #default false (idmind tinha isto em false)
yaw_goal_tolerance: 0.25 #default 0.05
xy_goal_tolerance: 0.30 #default 0.10
latch_xy_goal_tolerance: false #default false
goal_distance_bias: 0.6
path_distance_bias: 0.4 #1
occdist_scale: 0.05 #default 0.01
heading_lookahead: 0.325 #default 0.325
heading_scoring: false #default false
heading_scoring_timestep: 0.8 #default 0.8
dwa: false #default true
12.6 Magabot_move_base_params
controller_frequency: 10.0
controller_patience: 15.0
planner_patience: 5.0
clearing_radius: 0.59
footprint_padding: 0.015
planner_frequency: 2.0