View
14
Download
0
Category
Preview:
Citation preview
RECONOCIMIENTO DE AMBIENTES DESCONOCIDOS EN ROBÓTICA MÓVIL
GERMÁN ROJAS GÓNGORA
UNIVERSIDAD DE LOS ANDES FACULTAD DE INGENIERIA
DEPARTAMENTO DE SISTEMAS Y COMPUTACIÓN GRUPO DE INFORMÁTICA GRÁFICA
BOGOTÁ DC. MAYO DE 2003
RECONOCIMIENTO DE AMBIENTES DESCONOCIDOS EN ROBÓTICA MÓVIL: CASO DE ESTUDIO
GERMÁN ROJAS GÓNGORA
Tesis para optar al título de
Ingeniero de Sistemas y Computación
Profesor Asesor
FERNANDO DE LA ROSA R.
UNIVERSIDAD DE LOS ANDES FACULTAD DE INGENIERIA
DEPARTAMENTO DE SISTEMAS Y COMPUTACIÓN GRUPO DE INFORMÁTICA GRÁFICA
BOGOTÁ DC. MAYO DE 2003
Este proyecto fue desarrol lado para optar por el t í tulo como ingeniero de s istemas y computación en la Universidad de los Andes, entre los meses de agosto de 2002 y junio de 2003. Quiero agradecer a las personas que de una u otra manera colaboraron durante el desarrol lo de este proyecto. Para preguntas y comentarios favor contactarme por correo e lectrónico. Dedicado a mis padres, mis hermanos, a mi abuelita Rosa y a Patricia.
Germán Rojas Góngoragerogo@yahoo.com
ISC-2003-1-47
i
TABLA DE CONTENIDO
TABLA DE CONTENIDO i
TABLA DE FIGURAS ii i
INTRODUCCION 1
1. OBJETIVOS 3
1.1 General 3 1.2 Específicos 3
2. METODOLOGÍA 5
3. MARCO TEORICO 6
3.1 Conceptos Básicos 6 3.2 Descripción Del Hardware 9 3.2.1 El RCX 10 3.2.1.1 Puertos De Entrada: 13 3.2.1.2 Sensores: 13 3.2.1.3 Puertos De Salida: 20 3.2.1.4 Motores 22 3.2.1.5 Pantalla De Cristal Líquido (LCD): 22 3.2.1.6 Parlante: 23 3.2.1.7 Puerto Serial De Comunicaciones Infrarrojo 23 3.3 Programación Del RCX 26 3.3.1 Programación Con El Firmware Estándar 28 3.3.1.1 NQC 29 3.3.2 Programación Con Versiones No Estándar Del Firmware 37 3.3.2.1 LeJOS 39 3.3.2.2 LegOS 54 3.4 Aplicaciones: 67 3.5 Trabajos Relacionados 69
4. PROBLEMA A RESOLVER Y PROPUESTA DE SOLUCION 75
4.1 Descripción General 75 4.2 Propuesta General De Solución 75 4.2.1 Diseño Del Robot Móvil 77 4.2.1.1 Descripción De La Odometría Del Robot 79 4.2.2 Calibración Y Estimación De Errores 81 4.2.2.1 Medición De Los Errores De Odometría 82
ISC-2003-1-47
ii
4.2.2.2 Calibración Odometría Del Robot 86 4.2.2.3 Calibración Del Sensor De Ultrasonido 97 4.2.3 Software 113 4.2.4 Pruebas Experimentales 117
5. CONCLUSIONES Y TRABAJOS FUTUROS 124
5.1 Conclusiones 124 5.2 Trabajos Futuros 125
BIBLIOGRAFIA 127
ANEXO 1. RESUMEN API ’S DE PROGRAMACIÓN 129
ANEXO 2. EJEMPLO PROGRAMA COMUNICACIÓN NQC Y JAV A 130
ANEXO 3. DIAGRAMA DE CLASES DEL SOFTWARE RCX 133
ANEXO 4. DIAGRAMA DE CLASES DEL SOFTWARE HOST 134
ANEXO 5. DISEÑO DEL ROBOT MÓVIL 141
ANEXO 6. AMBIENTE DE PRUEBA 142
ISC-2003-1-47
iii
TABLA DE FIGURAS
F IGURA 1. ESTRUCTURA LÓGICA DEL RCX _____________________________ 12 F IGURA 2. LOCALIZACIÓN DE LOS PUERTOS DEL RCX_____________________ 13 F IGURA 3. SENSOR DE CONTACTO____________________________________ 14 F IGURA 4. SENSOR DE LUZ _________________________________________ 16 F IGURA 5. SENSOR DE ROTACIÓN ____________________________________ 16 F IGURA 6. USO DEL SENSOR DE ROTACIÓN _____________________________ 17 F IGURA 7. SENSOR DE ULTRASONIDO CONECTADO AL RCX ________________ 18 F IGURA 8. LOCALIZACIÓN DE LOS PUERTOS DE SALIDA EN EL RCX __________ 21 F IGURA 9. ESTADOS DE POTENCIA Q UE ALIMENTAN LOS MOTORES ___________ 21 F IGURA 10. MOTOR DE 9 VOLTIOS ___________________________________ 22 F IGURA 11. PANTALLA DE CRISTAL LIQUIDO ____________________________ 23 F IGURA 12. U BICACIÓN DEL PUERTO INFRARROJO _______________________ 23 F IGURA 13. INTERCAMBIO DE DATOS PC- RCX _________________________ 26 F IGURA 14. A RQUITECTURA DEL RCX CON EL FIRMWARE ESTÁNDAR _________ 30 F IGURA 15. MODOS DE CONFIGURACIÓ N DE LOS SENSORES EN NQC _________ 31 F IGURA 16. D ISTRIBUCIÓN DE LA MEMORIA EN LEJOS ____________________ 39 F IGURA 17. D IAGRAMA DEL COMPORTAMIENTO EN UNA COLISIÓN ___________ 45 F IGURA 18. J ERARQUÍA DEL COMPORTAMIENTO EN UNA COLIS IÓN ___________ 46 F IGURA 19. A RQUITECTURA DE CREAC IÓN DE SOFTWARE EN LEGOS _________ 55 F IGURA 20. T IPOS Y TAMAÑOS DE NUMERACIÓN SOPORTADO POR LEGOS _____ 61 F IGURA 21. CAPAS IMPLEMENTADAS EN LNP ___________________________ 62 F IGURA 22. PROBLEMAS A RESOLVER _________________________________ 77 F IGURA 23. D ISEÑO DE LA CONFIGURACIÓN DEL ROBOT MÓVIL _____________ 78 F IGURA 25. ELIPSES DE ACUMULAMIENTO DE ERROR _____________________ 81 F IGURA 26. U BICACIÓN DEL PARÁMETRO nominalb EN EL ROBOT ______________ 83 F IGURA 27. V ISUALIZACIÓN DEL ERROR DE ODOMETRÍA ___________________ 84 F IGURA 28. GRILLA UTILIZADA PARA HACER LAS MEDICIONES . _____________ 85 F IGURA 29. ERRORES TIPO A Y TIPO B, EN DIRECCIÓN CCW Y CW _________ 88 F IGURA 30. ERRORES EN LAS POSICIONES ABSOLUTAS EN EL SENTIDO CCW___ 91 F IGURA 31. ERRORES EN LAS POSICIONES ABSOLUTAS EN EL SENTIDO CW ____ 92 F IGURA 32. CORRECCIÓN DE ERROR EN POSICIONES ABSOLUTAS CCW _______ 95 F IGURA 33. CORRECCIÓN DE ERROR EN POSICIONES ABSOLUTAS CW ________ 96 F IGURA 34. FRENTE DE ONDA EMITIDO POR UN SENSOR DE ULTRASONIDO ____ 98 F IGURA 35. PRECISIÓN EN MEDIDAS HECHAS POR EL SENSOR DE ULTRASONIDO 99 F IGURA 36. N O HAY REFLEJO DE LA ONDA EN EL SENSOR __________________ 99 F IGURA 37. REFLEJO DE LA ONDA EN UNA SUPERFICIE CÓNC AVA ___________ 100 F IGURA 38. GRILLA PARA LA CALIBR ACIÓN DEL SENSOR DE ULTRASONIDO ____ 101 F IGURA 39. MEDIDAS OBTENIDAS POR EL SENSOR DE ULTRAS ONIDO ________ 103 F IGURA 40. GRÁFICA DE LAS MEDIDA S HECHAS A OBJETOS PLANOS _________ 104 F IGURA 41. MEDIDAS OBTENIDAS POR EL SENSOR DE ULTRAS ONIDO ________ 106 F IGURA 42. GRAFICA DE LAS MEDIDA S HECHAS A OBJETOS C ILÍNDRICOS _____ 107
ISC-2003-1-47
iv
F IGURA 43. MEDIDAS OBTENIDAS POR EL SENSOR DE ULTRAS ONIDO ________ 108 F IGURA 44. GRÁFICA DE LAS MEDIDA S HECHAS A OBJETOS CONVEXOS _______ 108 F IGURA 45. MEDIDAS OBTENIDAS POR EL SENSOR DE ULTRAS ONIDO ________ 110 F IGURA 46. GRAFICA DE LAS MEDIDA S HECHAS A OBJETOS CÓNCAVOS_______ 111 F IGURA 47. FLUJO DE DATOS ENTRE LOS DOS COMPONENTES DE SOFTWARE __ 113 F IGURA 48. INTERFAZ GRÁFICA DE LA APLICACIÓN IMPLEME NTADA _________ 116 F IGURA 49. A MBIENTE DE PRUEBA __________________________________ 118 F IGURA 50. MAPA CALCULADO POR EL SISTEMA EN LA PRIMERA PRUEBA _____ 119 F IGURA 51. MAPA CALCULADO POR EL SISTEMA EN LA SEGUNDA PRUEBA _____ 120 F IGURA 52. MAPA CALCULADO POR EL SISTEMA EN LA TERCERA PRUEBA _____ 121 F IGURA 53. MAPA CALCULADO POR EL SISTEMA EN LA CUARTA PRUEBA ______ 122 F IGURA 54. MAPA CALCULADO POR EL SISTEMA EN LA QUINT A PRUEBA ______ 123
ISC-2003-1-47
1
INTRODUCCION
Debido a la curiosidad innata del ser humano en conocer el medio
ambiente que lo rodea, lo ha llevado a idear tecnologías que le
ayuden en este proceso. Una de estas tecnologías es la robótica y en
especial la robótica móvil, la cual le ayuda al ser humano a tener
acceso a áreas de difícil acceso ó que pueden afectar nuestra
integridad física.
Por otro lado este tipo de tecnologías han tenido un gran auge, a tal
punto que se están llevando a los hogares en diferentes formas. Esto
me despertó curiosidad y por ello adquirí un kit de robótica, de ahí
surgió la idea de hacer un proyecto relacionado con robótica móvil.
En la Universidad de los Andes son muy pocos los trabajos que se han
hecho sobre reconocimiento de ambientes desconocidos. Hasta el
momento dichos trabajos han sido realizados por el Departamento de
Ingeniería Eléctrica. En el departamento de Ingeniería de Sistemas no
se han realizado trabajos referentes a este tema, por ello seria
interesante abordar este problema desde otras disciplinas, ya que
como bien sabemos el campo de la robótica es de un alto grado
interdisciplinario. Los pocos estudios acerca de este tema en la
universidad y la poca bibliografía existente en nuestro medio hacen
que este tema no sea muy fácil de abordar.
En este documento se presenta una propuesta para el reconocimiento
de ambientes desconocidos utilizando un robot LEGO de la línea
Mindstorms, equipado con un sensor de ultrasonido y sensores de
ISC-2003-1-47
2
rotación. La idea de esta propuesta es que sea aplicable a robots
móviles en general.
El documento está organizado en 5 capítulos. En el primer capítulo se
dan a conocer los objetivos que se lograron con este trabajo. En el
segundo capítulo se describe brevemente la metodología empleada en
la realización de este proyecto. En el tercer capitulo se hace una
investigación teórica acerca de los conceptos tratados además de los
trabajos relevantes hechos en la universidad de los andes. En el
cuarto capitulo se describe el problema a resolver y una propuesta de
solución. En el quinto capitulo se exponen las conclusiones obtenidas
con este proyecto y se proponen temáticas acerca de la continuación
del mismo.
ISC-2003-1-47
3
1. OBJETIVOS
1.1 General
Investigar y aplicar los aspectos básicos que se deben tener en
cuenta, en el desarrollo de una aplicación informática/computacional
de reconocimiento de ambientes con un robot móvil.
1.2 Específicos
• Diseñar e implementar un modelo de software como solución
general al problema de reconocimiento de ambientes con un robot
real.
• Evaluar el kit de robótica LEGO Mindstorms para su aplicación
académica en el campo de la programación en robótica móvil.
• Evaluar los mas importantes API’s de programación que podrían
ser de mayor utilidad en el desarrollo de software para este tipo
de robot.
• Aplicar el Lenguaje Java en el campo de la robótica móvil, y
aprovechar sus características como lenguaje orientado a objetos.
• Diseñar e implementar un modelo de software bajo el paradigma
orientado a objetos en el que se puedan implementar diferentes
estrategias de navegación en el problema de reconocimiento de
ambientes.
ISC-2003-1-47
4
• Investigar y evaluar una metodología para la calibración por
software de la odometría del robot.
• Evaluar una metodología con el fin de evaluar el comportamiento
de un sensor de ultrasonido.
• Implementar una aplicación informática/computacional gráfica que
me permita visualizar los datos capturados por el robot.
• Validar diferentes estrategias de navegación con un robot móvil
real.
• Obtener una cuantificación del nivel de precisión de los mapas
construidos.
ISC-2003-1-47
5
2. METODOLOGÍA
La primera parte de la investigación consiste en conocer las
diferentes plataformas de programación soportadas por el robot y su
relación con los diferentes dispositivos de hardware disponibles en el
mismo. A continuación se hizo una evaluación de estos API’s con el
fin escoger el más indicado, de acuerdo al problema que se quiere
resolver. Posteriormente se hizo la investigación sobre las variables
cinemáticas del robot, que se consideraron como las más importantes,
con el fin de aumentar el grado de precisión a sus movimientos.
Además se hizo un análisis estadístico con el fin de conocer el
comportamiento del sensor de ultrasonido, con lo cual se estima el
grado de precisión de los datos provenientes del robot.
Posteriormente se implementó una aplicación gráfica en lenguaje Java
sobre plataforma Windows en la cual se aborda una aproximación
inicial a la solución del problema. Esta aplicación interactúa
estrechamente con otra aplicación Java a ejecutarse en el robot.
En este trabajo se pretendió entender los principios básicos a tener
en cuenta cuando se trabaja en el desarrollo de software con un
robot real con bastantes limitaciones, en un ambiente todavía muy
ideal. De esta manera se espera que este estudio sirva como punto de
inicio a estudios posteriores más específicos sobre las generalidades
expuestas.
ISC-2003-1-47
6
3. MARCO TEORICO
3.1 Conceptos Básicos
Algunas de las siguientes definiciones fueron tomadas de [7].
• Robot: Manipulador multifuncional y programable, diseñado para
mover materiales, piezas, herramientas o dispositivos
especiales, mediante movimientos variables programados que
permiten llevar a cabo diversas tareas.
• Morfología: Un robot está formado principalmente por una
estructura mecánica, transmisiones, sistema de accionamiento,
sistema sensorial, sistema de control y elementos terminales.
• Estructura mecánica: Mecánicamente un robot móvil está
formado por una serie de elementos que unidos entre si hacen
que el robot pueda cambiar su posición. Principalmente
mediante el uso de piñones se transmite la cantidad de
movimiento deseada entre los motores y las ruedas o efectores.
• Transmisiones o reductores: Las transmisiones son los
elementos encargados de transmitir el movimiento desde los
actuadores hasta las articulaciones. Los reductores son los
encargados de adaptar la velocidad de salida del actuador a los
valores adecuados para el movimiento de los elementos del
robot, por ejemplo los piñones.
ISC-2003-1-47
7
• Actuadores: Los actuadores tienen por misión generar el
movimiento de los elementos del robot según las ordenes dadas
por la unidad de control. Los actuadores utilizados en robótica
pueden emplear energía neumática, hidráulica o eléctrica. Un
ejemplo de actuador es un motor.
• Sensores: Los robots usan sensores para así tener información
sobre su estado interno y su estado en un ambiente. En
general, un sensor mide una característica del ambiente o
espacio en el que está y proporciona señales eléctricas. El robot
va a percibir campos magnéticos o corrientes ultrasónicas, que
proveen información. Para conseguir que un robot realice una
tarea con adecuada precisión, velocidad e inteligencia seria
preciso que tenga conocimiento tanto de su propio estado como
del estado de su entorno. La información relacionada con su
estado (fundamentalmente el estado de sus
posición/orientación) la consigue con los denominados sensores
internos, mientras que la que se refiere al estado de su entorno
se adquiere con los sensores externos.
Sensores internos:
o Sensores de posición/orientación.
o Sensores de velocidad.
o Sensores de presencia.
Sensores externos:
o Sensores de luz: Los sensores de luz para la robótica
vienen en diferentes formas. Estos se pueden usar para
navegación. Por ejemplo, un robot puede usarlo para
ISC-2003-1-47
8
seguir en una línea recta blanca. Otros pueden usar visión
infrarroja.
o Sensores de ultrasonido: La “visión” robótica es uno de los
grandes retos para los ingenieros. Es difícil programar un
robot para que sepa que ignorar y que no. Un robot tiene
problemas de interpretar sombras, cambio de luces o
brillo. Algunos robots pueden "ver" mediante el uso de
sonidos ultrasónicos, muy parecido al sistema que usa los
murciélagos. Estos robots emiten 40 kilo hertz de ondas
sonoras, y luego detectan los ecos. Midiendo la demora
del tiempo de las ondas en devolverse, el tiempo
transcurrido da una distancia hacia un objeto (o sea en
donde reboto el sonido).
o Sensores de temperatura: Dispositivo electrónico diseñado
para permitir la lectura digital de la temperatura.
o Sensores de tacto: Dispositivo diseñado para detectar
colisiones, y de esta manera tomar decisiones acerca de la
trayectoria que debe seguir el robot.
o Sensores Láser: Estos sensores sirven para obtener la
localización de obstáculos, al igual que los sensores de
ultrasonido con un grado de precisión superior pero a un
costo mucho mas elevado.
• Elementos terminales: Los elementos terminales, también
llamados efectores finales son los encargados de interactuar
directamente con el entorno del robot, como por ejemplo
pinzas, herramientas, o ruedas en el caso de los robots móviles,
etc.
ISC-2003-1-47
9
• Odometría: Es un método que usa encoders (sensores de
rotación en este caso) para medir la posición relativa de un
robot, basado en el número de rotaciones que dan las ruedas.
Presenta la ventaja de que la información esta auto contenida,
es decir que en cualquier momento el robot puede estimar su
posición/orientación. La desventaja radica en que el error
aumenta sin límite a menos de que se use periódicamente una
referencia independiente con el fin de reducir el error [9].
• Errores a tener en cuenta: En robótica he encontrado que se
habla de dos tipos de errores: sistemáticos y no sistemáticos
[9]. Los sistemáticos provienen del diseño del robot y sus
componentes como por ejemplo: la resolución del sensor de
rotación, que dos ruedas no tengan el mismo diámetro o que
éstas estén desalineadas, o también pueden provenir de las
imprecisiones de parámetros utilizados en el software. Los
errores no sistemáticos son introducidos a causa del medio
ambiente en donde se encuentra el robot, como ejemplos de
estos podemos tener: el deslizamiento de una rueda en el piso
debido a suelo resbaloso o a que no hay contacto entre todos
los puntos de la rueda y el piso o a que se encontró un objeto
inesperado durante el movimiento, etc. Estos errores necesitan
de un manejo muy cuidadoso ya que tienen una gran influencia
en el desempeño de los robots.
3.2 Descripción Del Hardware
Lego® Mindstorms [1] es el nombre de una línea de productos
desarrollados por Lego Group y “The Epistemology and Learning
ISC-2003-1-47
10
Group” en el Media Lab del MIT, en un principio con fin recreativo, el
cual posteriormente se extendió a nivel educativo bajo la línea Lego®
Dacta. El producto que fué utilizado en este trabajo es el RIS 1.5
(Robotics Invention System, por sus siglas en inglés) de la línea Lego
Mindstorms, el cual está dirigido a un público de 12 años en adelante.
Este kit hace posible al usuario convencional acercarse al mundo de
la robótica a un bajo costo, además de presentar una gran
versatilidad debido a que se pueden construir diversas
configuraciones de robots, limitadas a la imaginación del usuario y
por supuesto a los recursos de hardware Lego disponibles. Este kit
viene con 727 piezas, entre ladrillos, ruedas, piñones, etc. (si se
necesita información mas específica recomiendo ver [1]).
Las piezas más importantes y que vale la pena hacer una descripción
detallada para efectos de programación son: el RCX1, el cual es un
pequeño computador que actúa como el “cerebro” del robot; los
diferentes tipos de sensores (rotación y ultrasonido) y los actuadores
(motores). Es de anotar que el funcionamiento de estas partes
depende en algunos casos del tipo o versión de firmware2 que se
tenga instalado en el RCX, el cual está directamente relacionado al
lenguaje y/o ambiente de programación que se utilice.
3.2.1 El RCX
El RCX tiene dimensiones 6 cm. X 10 cm. X 4 cm., pesa
aproximadamente 280 gramos incluyendo las seis pilas AA. Cabe
anotar que en la versión 1.0 el RCX posee una entrada de corriente 1 Robotics Command Explorer, de acuerdo al sitio oficial de Lego® [1]
2 Se llama así a una memoria programada permanentemente e imborrable usada para almacenar monitores y controladores de E/S.
ISC-2003-1-47
11
AC-DC, lo cual puede ser útil para el ahorro de baterías en una
configuración de robot estático. El RCX tiene un microcontrolador
Hitachi H8/3292, el cual posee un reloj que oscila entre 10 MHz y 16
MHz, el RCX utiliza los 16 MHz. El tamaño de palabra de este
procesador es de 8 bits, lo cual quiere decir que el procesador solicita
8 bits de memoria en cada acceso a memoria [4]. Si se necesita
información más específica acerca de la arquitectura del procesador
es posible obtener los manuales técnicos en el sitio Web de Hitachi
(http://semiconductor.hitachi.com/products/pdf/h33th014d2.pdf).
El microcontrolador contiene 16 KB de memoria de lectura (ROM) y
512 bytes de memoria de acceso aleatorio (RAM). La memoria ROM
contiene las rutinas (ó controladores) necesarias para interactuar con
los dispositivos que conforman el RCX, por ejemplo para cambiar el
firmware, para desplegar información en la pantalla de cristal liquido
(LCD), comunicarse con motores y sensores, además comunicarse con
el puerto infrarrojo (IR). Hay que aclarar que Lego llama Firmware a
la capa de software que interactúa entre las rutinas escritas por el
usuario y las que se encuentran en la memoria ROM. Desde este
punto de vista el firmware se puede ver como una extensión de las
rutinas que hay en la memoria ROM; dicho firmware se puede cambiar
o actualizar, dependiendo el lenguaje o ambiente de programación
que se desee utilizar, lo cual le da mas versatilidad. El sistema tiene
un reloj interno el cual lleva la cuenta del número de minutos desde
que se encendió el RCX, este tiempo puede ser accesado desde un
programa. El RCX además posee 4 temporizadores los cuales miden el
tiempo en incrementos de 100 ms (1/10 de segundo); éstos empiezan
desde que el RCX es encendido. Los programas pueden re-inicializar
cualquier temporizador independientemente del tiempo. El RCX
contiene 32 kb de memoria RAM, la cual esta en un chip externo al
microprocesador debido a que la memoria RAM que posee el
ISC-2003-1-47
12
procesador resulta muy poca para el programador, ya que en esta se
almacena tanto el firmware como el software escrito por el usuario.
En un principio pensé que 32 KB de memoria no representaban mucho
espacio para el programador, pero en [3] encontré dos anécdotas
importantes que me hicieron reflexionar al respecto: El RCX contiene
mas memoria que la usada por el lunar landing module en las
misiones a la luna, y la otra, que el Sojourner Mars rover tenia 160 kb
de memoria RAM disponibles, pero su software solo utilizaba 16 kb de
memoria. En la figura 1 se muestra la estructura lógica del RCX.
Si se requiere información mas detallada acerca del RCX sugiero
visitar http://graphics.standford.edu/~kekoa/rcx/, donde el autor de
está página hizo los trabajos de ingeniería inversa para descifrar el
funcionamiento al detalle del RCX, ya que estos no son divulgados
oficialmente por el Lego® Group y sin los cuales no seria posible
tener los desarrollos para la gran gama de plataformas soportadas
actualmente por el RCX.
Figura 1. Estructura lógica del RCX.
Programas de Usuario
Firmware
ROM
Procesador H8/3292
ISC-2003-1-47
13
3.2.1.1 Puertos De Entrada:
Como se puede observar en la Figura 2 el RCX tiene tres puertos de
entrada en los cuales se conectan los sensores. Estos puertos están
diseñados para que puedan ser conectados de cualquier manera y sin
embargo funcionen correctamente.
Lego tiene varios tipos de sensores: contacto, luz, temperatura y
rotación (figuras 3, 4, 5 y 6), los cuales usan el mismo tipo de cable
que utilizan los motores para ser conectados al RCX. Cada tipo de
sensor tiene sus propios requerimientos para leer e interpretar la
información, lo cual quiere decir que hay que configurar cada puerto
de entrada antes de ser usado. Además el RCX no tiene implementada
la manera de saber que tipo de sensor esta conectado en determinado
puerto.
Figura 2. Localización de los puertos del RCX.
3.2.1.2 Sensores:
Los sensores son utilizados por el robot tanto para conocer el estado
del ambiente que lo rodea, como para conocer su propio estado.
Desde este punto de vista los sensores se pueden clasificar como
Entrada 2
Entrada 3 Entrada 1
ISC-2003-1-47
14
internos y externos. Los internos para saber de su estado interno,
como por ejemplo el reloj de la CPU, y los externos para conocer
variantes del medio ambiente como un sensor de luz.
Hay dos clases de sensores desde el punto de vista de su
funcionamiento: pasivos y activos. Los pasivos operan como simples
resistencias y no requieren de flujo eléctrico para funcionar, como por
ejemplo el sensor de contacto y el sensor de temperatura. Los
sensores activos por el contrario si necesitan del flujo de corriente
que les provee el RCX, entre estos tenemos el sensor de rotación y el
sensor de luz.
3.2.1.2.1 Sensor De Contacto:
Este sensor es el sensor básico (figura 3), es utilizado generalmente
para detectar cuando el robot hace contacto con un objeto. También
puede ser usado como un botón dándole la funcionalidad respectiva.
Este sensor da un valor booleano, 0 en su posición normal y 1 cuando
el interruptor esta oprimido. Este sensor se puede conectar de
cualquier manera, siempre y cuando se abarquen los 4 contactos
metálicos.
Figura 3. Sensor de Contacto.
Contactos Metálicos
Interruptor
ISC-2003-1-47
15
3.2.1.2.2 Sensor De Luz:
El sensor de luz consiste de un diodo emisor de luz (LED por sus
siglas en ingles) y de un fototransistor, el cual capta la luz del medio
en que se encuentre. El LED como su nombre lo indica emite luz
visible para nosotros, el cual sirve para iluminar cualquier superficie
que esté al frente, esto con el fin de que el fototransistor capture luz
sin depender de la luz del medioambiente. Cuando el medioambiente
está muy oscuro, éste capta la luz reflejada por la superficie que se
encuentre al frente y a muy poca distancia (más o menos 3 o 4 cms).
Cuando el medio tiene bastante luz este puede influenciar la lectura
del fototransistor (figura 4). Este sensor se puede utilizar por ejemplo
para distinguir algún color a corta distancia (para minimizar la luz
externa), ó para medir la luz de su ambiente si se habla de una
distancia mayor. Las lecturas pueden variar entre dos sensores
diferentes ó en un mismo sensor bajo diferentes condiciones. Este
sensor posee una característica importante y es que percibe la
frecuencia emitida por la luz infrarroja, con lo cual junto con el
puerto infrarrojo se puede utilizar como sensor de proximidad, es
decir detectar obstáculos sin hacer contacto con ellos. El
inconveniente consiste en que el rayo infrarrojo solo es captado por
el sensor de luz si este es refractado de frente, lo cual quiere decir
que la superficie a detectar debe estar ubicada casi
perpendicularmente a la trayectoria del robot para poder ser
detectada.
Si se requiere conocer detalles del funcionamiento interno de este
sensor se puede visitar:
http://www.plazaearth.com/usr/gasperi/light.htm.
ISC-2003-1-47
16
Figura 4. Sensor de luz.
3.2.1.2.3 Sensor De Rotación:
Este es un sensor que a diferencia de los otros, mide valores no solo
en una escala absoluta sino también en una escala relativa, de
acuerdo a las necesidades del programador. Por defecto el valor
mostrado es 0 cuando empieza a ejecutar un programa, pero una
instrucción específica a cada lenguaje de programación puede ser
usada como valor de referencia a la medida relativa. El sensor sirve
únicamente para medir el número de rotaciones que da el eje al
interior de la cavidad del sensor (figura 5). Si el eje introducido en el
sensor rota en una dirección éste aumenta su valor y si por el
contrario se gira en la dirección opuesta este disminuye su valor.
Figura 5. Sensor de rotación.
Este sensor mide en incrementos de 22.5 grados, lo cual quiere decir
que una rotación de 360 grados es representada por un valor del
sensor de 16. Se puede pensar que la resolución del sensor no es
muy buena, ¿que pasaría si se quiere medir una rotación menor a
LED Fototransistor
Eje de rotación.
ISC-2003-1-47
17
22.5 grados? , para poder hacer esto se puede pensar en una
solución mecánica. Por ejemplo una reducción de engranajes
aumentaría la precisión de las medidas (figura 6):
Figura 6. Uso del sensor de rotación.
En este caso si queremos medir el número de revoluciones del piñón
de 24 dientes, éste está en contacto con un engranaje sin fin, lo cual
nos da una reducción en escala de 24:1, es decir que el engranaje sin
fin rota 24 veces por cada vuelta completa del piñón de 24 dientes.
Desde el punto de vista del sensor de rotación este marcará un valor
de 16x24 = 384 por cada vuelta completa del piñón de 24 dientes, lo
cual nos indica que la precisión es de más de 1 grado, ya que
sabemos que la circunferencia tiene 360 grados. Así para calcular la
distancia recorrida nos faltaría por conocer el diámetro de la rueda, el
cual está impreso en el borde de cada una de las ruedas. Por ejemplo
suponiendo que en cualquiera de los extremos del eje que esta dentro
del sensor de rotación hay un motor conectado, y en cualquiera de
los extremos del eje respecto al cual gira el piñón de 24 dientes hay
una rueda (esto es utilizado en odometría3), ésta tiene un perímetro
Π×= DC
(donde D es el diámetro de la rueda y 3,14=Π ) luego para obtener la
distancia recorridaI
CST
×= , donde S es la lectura del sensor,
3 Odometría es un método utilizado para medir la rotación de una rueda y/o su orientación, la cual necesita periódicamente una
corrección de error.
Engranaje sin fin
Piñón de 24 dientes
Sensor de Rotación
ISC-2003-1-47
18
16GI ×= siendo G el factor de reducción de escala entre el sensor y el
eje en donde esta conectada la rueda. G=24, para nuestro ejemplo
entonces 3842416I =×= . La distancia T resulta medida con las mismas
unidades con que se midió el diámetro de la rueda, las ruedas Lego
están medidas en centímetros.
Es importante mencionar que el RCX tiene problemas al contar
rotaciones a muy baja o muy alta velocidad, más precisamente
menores a 12 rpm ó mayores a 1400 rpm, casos en los cuales el RCX
puede ignorar algunas rotaciones.
Para conocer detalles específicos acerca del funcionamiento interno
de este sensor sugiero visitar:
http://philohome.free.fr/sensors/legorot.htm.
3.2.1.2.4 Sensor De Ultrasonido:
Este sensor no hace parte del hardware oficial producido por el LEGO
Group. Si se requiere información adicional recomiendo visitar el
sitio: http://www.hitechnicstuff.com/URpage.htm.
Figura 7. Sensor de Ultrasonido conectado al RCX.
ISC-2003-1-47
19
Este sensor emite ondas de sonido a una frecuencia de 40 Khz., las
cuales no son percibidas por el oído humano. Estas ondas después de
ser emitidas por un transductor4 y al entrar en contacto con un objeto
hacen que parte de su energía sea reflejada y retorne de nuevo al
sensor. Dicha energía es captada en el sensor por otro transductor.
Dicho transductor receptor amplifica estas señales o “ecos” y las
envía a un microcontrolador el cual calcula que tan lejos se encuentra
el objeto causante de la reflexión de la onda. Esto lo hace utilizando
la velocidad del sonido en el aire que es de 330m/s y el tiempo de
vuelo (TOF por sus siglas en inglés) que se demora en llegar las
ondas reflejadas de nuevo al sensor. Para ello se utiliza la siguiente
ecuación cinemática para movimiento con velocidad constante:
tV X2 ⋅=⋅
Donde X es el rango ó distancia del objeto que se quiere medir, V es
la velocidad del sonido y t el tiempo que se demora en captar la onda
reflejada. El valor de X luego de ser calculado es convertido por una
señal y enviado al RCX. Para utilizar correctamente este sensor en el
RCX éste se configura como si fuera un sensor de luz (según la
especificación del fabricante) y la escala de valores en modo
porcentaje. De esta manera el RCX recibe un valor en el intervalo
[0,100]. Dicho valor recibido y que lo vamos a llamar “Lectura”, hay
que aprender a interpretarlo. Para ello hay que convertirlo a una
escala de valores que tenga mas significado para nosotros.
Originalmente este valor se convierte a pulgadas con la siguiente
ecuación:
62
lectura pulgadasen Rango +
=
4 Transductor: Aparato electromecánico vibratorio, capaz de transformar la potencia de una corriente alterna en potencia
mecánica o acústica, o bien, a la inversa, la presión de una onda sonora o de una vibración en señal eléctrica.
ISC-2003-1-47
20
Pero para nosotros es más natural el sistema métrico decimal, así que
necesitamos convertir dicho valor a centímetros con la siguiente
ecuación:
cms 2.54pulgadasen Rango cmsen Rango ×=
Debido a que el valor “Lectura” esta en un rango entre 0 y 100
entonces podemos determinar que las distancias que puede captar
con cierta precisión el sensor se encuentra en el rango [15.24cms
,142.24cms]. Las distancias fuera de este rango no pueden ser
medidas con este sensor, lo cual produce limitaciones al realizar
experimentación con él.
3.2.1.3 Puertos De Salida: El RCX tiene tres puertos de salida (A, B y C) como se puede observar
en la figura 8, cada una de las cuales tiene tres estados posibles:
encendido (on), apagado (off) y suspendido (floating). El estado de
encendido hace que el motor conectado empiece a rotar, el estado de
apagado actúa como un freno y hace que el motor deje de rotar, el
estado de suspendido hace que el RCX suspenda el flujo de corriente,
puede entenderse como el estado “neutro” en un automóvil en donde
las ruedas siguen girando con un impulso.
ISC-2003-1-47
21
Figura 8. Localización de los puertos de salida en el RCX.
Cada puerto tiene asociada una dirección, la cual hace rotar el motor
hacia delante o hacia atrás. Esta dirección es efectiva únicamente en
el modo de encendido, pero también puede ser cambiada desde el
modo apagado o suspendido ya que dicha dirección es recordada
siempre por el RCX. La dirección de giro del motor depende de cómo
se conecte este con el RCX. Además cada puerto de salida tiene
asociado un nivel de potencia, de los 8 posibles (entre 0 y 7); éste
puede ser modificado únicamente cuando el estado de la salida es
apagado. Debido a que el RCX es un dispositivo digital los 8
diferentes estados de potencia difieren únicamente en modulación de
los pulsos generados ya que los pulsos en el RCX son enviados cada 8
ms, es decir que el pulso con menos potencia tiene una longitud de 1
ms, y el pulso con mas potencia tiene una duración de 8 ms el cual es
continuo.
Figura 9. Estados de potencia que alimentan los motores.
Nivel de potencia 2 (20%)
Nivel de potencia 6 (90%)
Salida B
Salida C Salida A
ISC-2003-1-47
22
3.2.1.4 Motores
El RCX le suministra al motor un máximo de 9 voltios, y su consumo
de corriente es de 10 mA si está libre, y 259 mA si tiene interacción
con un mecanismo. Este motor no presenta ningún problema si se
conecta directamente a un sensor de rotación ya que su máxima
velocidad es de 350 rpm, y de 200 rpm si interactúa con algún
mecanismo por lo tanto el sensor de rotación es capaz de captar
todas las vueltas. Al conectar un motor con el RCX hay que tener en
cuenta la dirección de conector del cable ya sea en el RCX o en el
motor, ya que este determina si el motor se mueve o no en dirección
de las manecillas del reloj, aunque esta dirección también es
determinada por ciertas instrucciones cuando se programa.
Figura 10. Motor de 9 voltios.
3.2.1.5 Pantalla De Cristal Líquido (LCD): Esta pantalla contiene 43 segmentos, los cuales pueden ser
accionados individualmente únicamente con las herramientas de
programación que no interactúen con el firmware provisto por Lego,
ya que estos segmentos fueron diseñados para dicho firmware y
tienen un significado especial. Esta pantalla puede utilizarse para
mostrar algún tipo de información importante o como marca para
hacer depuración de código.
ISC-2003-1-47
23
Figura 11. Pantalla de cristal liquido.
3.2.1.6 Parlante:
El RCX incluye un parlante en su interior, el cual está localizado en
una de las esquinas, éste tiene un diámetro de 15mm y una
profundidad de 4mm. Con éste se pueden generar sonidos simples de
frecuencia variable y duración. Este también puede ser utilizado para
probar y depurar software.
3.2.1.7 Puerto Serial De Comunicaciones Infrarrojo:
El principal propósito de este dispositivo es bajar programas al RCX.
Este puerto además de recibir datos, también es capaz de enviarlos
ya sea con la torre infrarroja conectada a un PC ó a otro RCX (figura
12). Este puerto tiene dos tipos de emisiones de luz infrarroja: a
corta distancia, es decir un alcance hasta 2.5 metros y menor
consumo de energía, y a larga distancia hasta aproximadamente 8
metros y mayor consumo de energía.
Figura 12. Ubicación del puerto infrarrojo.
La capa de software que se encuentra en la memoria ROM y que
llamaré ejecutivo (también llamado supervisor o monitor debido a que
Puerto infrarrojo
ISC-2003-1-47
24
no es un sistema operacional porque está en la memoria ROM) se
comunica con un computador externo mediante un protocolo
solicitud/respuesta: donde el computador envía una solicitud y el
ejecutivo se encarga de ejecutar dicha solicitud y envía una
respuesta. Esta respuesta puede contener datos solicitados, además
posee información de control que indica si se ejecutó bien la solicitud
(la siguiente descripción esta basada en [8]).
Las siguientes tipos de solicitudes pueden ser enviadas al ejecutivo:
• Alive: Mira si el ejecutivo esta corriendo y si se tiene una buena
conexión con el RCX.
• GetVersions: Este sirve para obtener la versión del ejecutivo y
de la aplicación que está corriendo sobre el ejecutivo
(firmware).
• EnterDownloadMode: Si alguna aplicación esta corriendo sobre
el ejecutivo ésta es detenida. En ese momento el ejecutivo
queda listo en un modo para bajar un programa.
• BeginDownload: Prepara el ejecutivo para bajar un programa.
• DownloadBlock: Este baja un bloque de bytes a la memoria del
RCX.
• RunProgram: Empieza la ejecución de un programa previamente
bajado al RCX.
Cada solicitud/respuesta es enviada como un paquete de bytes. Cada
paquete contiene un encabezado, seguido por la solicitud/respuesta
actual junto con una cola adicionada al final del paquete.
Paquete = encabezado + solicitud/respuesta + cola
Donde:
Encabezado = 0x55 0xff
ISC-2003-1-47
25
Solicitud/respuesta = secuencia de bytes
Cola = suma de verificación (checksum5)
Este checksum se obtiene en este caso sumando el valor binario de
los bytes que forman solicitud/respuesta y tomando el byte menos
significativo que resulte de esta suma.
La solicitud también es representada por una secuencia de bytes. El
primer byte es el código de la solicitud, seguido por los bytes que
contienen los datos solicitados. La respuesta tiene una estructura
muy similar donde el primer byte empieza con el código de la
respuesta seguido por los datos de respuesta. Estos códigos de
solicitud y respuesta están detalladamente explicados en [8], en caso
de que se necesite conocerlos. Cada solicitud/respuesta es enviada
como paquetes de bytes en una línea de comunicación serial entre el
computador y el RCX ó entre dos RCX, lo que en definitiva es
representado por dos pares emisor/transmisor infrarrojos, si uno de
los dos está conectado al computador este lo hace mediante la torre
infrarroja conectada a un puerto serial con interfase RS232 en un
puerto de 9 o de 25 pines (para este último se necesita un
convertidor). Esta transmisión se hace a una velocidad de 2400
baudios (bits por segundo). Para marcar el comienzo y el final de
cada byte, este es enviado entre un bit de arranque y un bit de
finalización. También un bit de paridad es adicionado a cada byte.
Entonces concluimos que cada byte es enviado como 11 bits. Además
cada byte enviado (excepto el encabezado 0x55) es enviado como dos
bytes: el byte a enviar y el complemento bit a bit del byte a enviar
que forma otro byte, luego el paquete entonces es enviado con un
numero igual de bits en cero y de bits en uno, esto con el fin de
compensar la interferencia de la luz del medio ambiente. En resumen
5 Valor utilizado para garantizar que los datos se transmiten sin error.
ISC-2003-1-47
26
cada valor de 8 bits en un paquete es enviado como 22 bits
exceptuando el encabezado, a una velocidad de 2400 bits por
segundo lo que es equivalente a 9 milisegundos para transmitir cada
byte aproximadamente.
Vale la pena mencionar que actualmente la torre infrarroja que se
conecta al PC tiene una interfase USB6 la cual presenta algunas
ventajas ya que no requiere baterías, usa tecnología mas reciente y
para un usuario final es fácil de configurar, pero también presenta
algunas desventajas ya que no esta soportada por muchos sistemas
operativos actualmente y por equipos que no tengan este tipo de
puerto. A diferencia de la torre que se comunica por puerto serial y
que es soportado por la mayoría de sistemas operativos, además de
encontrarse en la mayoría de modelos de computadores.
Figura 13. Intercambio de datos PC- RCX.
3.3 Programación Del RCX
Un robot se puede programar para que sea autónomo ó controlado a
distancia, esto lo determina el tipo de problema a resolver, por lo
tanto sería muy interesante poder programar el RCX para que pueda
ejecutar estos dos tipos de control. Además si tenemos en cuenta las
limitaciones de memoria del RCX (tan solo 32 kb) nos veríamos
obligados a hacer que el mayor flujo de información sea procesado
6 Universal Serial Bus.
ISC-2003-1-47
27
por un PC (host), el cual solo le enviaría al RCX información ya
procesada para que el ejecute una pequeña tarea. En resumen la
escogencia del tipo de control para el robot depende de la cantidad
de información involucrada en la resolución del problema, por ello
seria necesario contar con API’s no solo para programar el RCX sino
también para hacer que el host se pueda comunicar con el robot.
El RCX se puede programar bajo diferentes lenguajes, los cuales
necesitan de un firmware especial para cada uno de ellos. El firmware
es el encargado de hacer la interfaz entre las primitivas contenidas en
la memoria ROM y los programas hechos por el usuario.
Para construir un nuevo firmware se necesitan conocimientos en
software embebido, los detalles técnicos a bajo nivel del RCX y
compilación cruzada, este ultimo consiste en configurar un compilador
para que produzca código que se ejecutará en una arquitectura de
hardware diferente, por ejemplo el firmware hecho para programar en
legOS (nombre del API para programar el RCX en lenguaje C) fue
hecho en un PC Intel el cual mediante compilación cruzada produce el
código para el procesador Hitachi H8/3292 que es el que posee el
RCX. LEGO hasta el momento ha sacado al público dos versiones de
firmware (las cuales se conocen como versiones de firmware oficiales
o estándar), el las cuales fueron diseñadas para sus ambientes
gráficos de programación, los cuales poseen varias limitaciones
funcionales, además de ser comerciales y de arquitectura cerrada. Por
ello algunos entusiastas vieron la necesidad de crear sus propias
versiones para poder explotar el potencial del RCX.
ISC-2003-1-47
28
3.3.1 Programación Con El Firmware Estándar
Existen dos versiones del firmware oficial: la primera es la versión
cuyo nombre de archivo es FIRM0309.LGO y viene con los kits RIS 1.0
y 1.5, y el nombre de archivo de la versión más reciente es llamada
FIRM0328.LGO y viene con el RIS 2.0. Dichas versiones son
compatibles con cualquiera de las versiones de RCX conocidas. La
primera versión tiene varias limitaciones como por ejemplo que no
existe la posibilidad de declarar arreglos, y solo se pueden declarar
32 variab les, etc. Por ello me centraré en la segunda versión que es
un poco mas poderosa ya que los diferentes API’s de programación
para comunicar el PC con el RCX son compatibles con cualquier
versión de firmware.
El software de programación gráfica que provee LEGO está diseñado
para público sin conocimientos en programación lo cual hace que el
ambiente de programación se torne un poco incomodo a la hora de
hacer programas extensos. Además no es tan fácil darse cuenta como
funciona el flujo de los programas ya que hace transparente al
usuario muchas características como por ejemplo el hacer programas
multitarea. Bajo la línea Dacta existe otro ambiente gráfico mucho
mas poderoso dirigido a un público que tiene conocimientos en
programación y permite trabajar con problemas más complejos. Dicho
producto se llama Robolab (programado con LabView de Nacional
Instruments) el cual es de carácter comercial lo que lo hace algo
restringido al público. Sin embargo existe un lenguaje llamado NQC
(Not quite C) cuyo compilador fue inventado para producir bytecodes
que son interpretados por el firmware estándar. Este compilador
además es de libre distribución, su página Web oficial es:
http://www.baumfamily.com/nqc en donde se puede obtener un
ISC-2003-1-47
29
manual. Vale la pena mencionar que este lenguaje fue diseñado para
utilizarlo por consola, sin embargo programadores han construido
IDE(s) (Interface Development Environment) para facilitar su uso. En
este proyecto se usó Bricx Command Center el cual es desarrollado
para ejecutarse en Windows cuya página Web oficial es:
http://members.aol.com/johnbinder/bricxcc.htm. Las versiones del
compilador cruzado NQC también están disponibles para macOS y
Linux.
3.3.1.1 NQC
Para la evaluación de este lenguaje voy a explicar las características
que me parecieron mas importantes para programar el RCX (con
algunas funciones de este lenguaje también se puede programar el
scout) ó que no son muy habituales en los lenguajes de
programación. Si se necesita saber mas detalles de este lenguaje se
puede referir al manual publicado en la página Web de NQC y a [6]
de donde me he basado para entender la funcionalidad de dicho
lenguaje. Además en la página Web http://mindstorms.lego.com/sdk
se encuentra el RIS 2.0 SDK el cual contiene un documento con todos
los comandos y bytecodes soportados por el firmware, ya que éste es
quien determina la funcionalidad de este lenguaje.
ISC-2003-1-47
30
Figura 14. Arquitectura del RCX con el firmware
estándar.
Como su nombre lo indica su sintaxis es parecida a la del lenguaje C,
lo cual facilita su aprendizaje desde el punto de vista de un
conocedor de dicho lenguaje. Con éste se pueden declarar hasta 32
variables globales, y 16 variables locales a cada tarea; esto significa
que para cada una de las 10 tareas que se pueden ejecutar
simultáneamente en un programa NQC se pueden declarar 16
variables locales a ésta, lo que nos da 32 + (16X10) = 192 variables
en total, que son únicamente de tipo entero. En este lenguaje se
pueden declarar arreglos, los cuales tienen una longitud fija según
como se declaren, dicha longitud tiene como longitud máxima 32
posiciones, sin embargo se pueden aumentar, utilizando el espacio de
las 32 variables globales. Es muy importante aclarar que NQC no
soporta variables de punto flotante, lo cual puede ser restrictivo para
la solución de determinado tipo de problemas en NQC. Otra
característica importante de este lenguaje es que no hay manera de
declarar estructuras de datos por parte del usuario. Sin embargo
existe la capacidad de data logging que consiste en reservar un
NQC
Puerto Serial ó USB Torre Infrarroja
Hardware
Rutinas en ROM
Firmware Estándar
Programas de usuario
Máquina Host RCX
RAM
ROM
ISC-2003-1-47
31
espacio de memoria (llamado datalog) cuya longitud es determinada
por el usuario en el cual se van almacenando datos en forma de pila,
dichos datos pueden ser lecturas de los sensores, variables, valores
de tiempo, etc. La estructura de datos se podría simular de acuerdo
al orden en que se vayan ingresando los datos, para de esa misma
manera interpretarlos cuando se soliciten en la máquina host, esto
debido a que el RCX no tiene acceso al datalog.
El manejo de las configuraciones de los sensores es interesante en
este lenguaje debido a que se hace una distinción entre los tipos de
sensores y los modos de los sensores. Como ya sabemos los tipos de
los sensores son de contacto, temperatura, luz y rotación, pero
además en NQC existe el sensor nulo, esto porque dependiendo del
tipo de sensor éstos quedan configurados en un modo por defecto
como lo observamos en la siguiente tabla:
Tipo de Sensor
Código Clase Modo por defecto
Nombre en NQC
Nulo 0 Pasivo Raw SENSOR_TYPE_NONE Contacto 1 Pasivo Boolean SENSOR_TYPE_TOUCH Temperatura 2 Pasivo Celsius SENSOR_TYPE_TEMPERATURE Luz 3 Activo Percentage SENSOR_TYPE_LIGHT Rotación 4 Active Rotation SENSOR_TYPE_ROTATION
Figura 15. Modos de configuración de los sensores en NQC.
El modo raw, es el más simple de todos y representa el valor del nivel
de voltaje leído en el sensor y convertido en un número entero entre
0 y 1023. El modo rotación marca un valor de 16 por cada revolución
de su eje. El modo porcentaje no es más que el valor raw convertido
a un valor entre 0 y 100 en donde un valor raw alto corresponde un
bajo valor en porcentaje. Adicionalmente existen otros modos como el
Edge Count el cual sirve para contar los cambios del valor booleano
ISC-2003-1-47
32
de 0 a 1 o viceversa; el modo Pulse count mode es muy parecido al
edge count excepto porque únicamente cuenta los valores que van de
1 a 0 y el modo Fahrenheit que nos muestra el valor de la
temperatura en grados Fahrenheit. Estos modos se pueden utilizar
con cualquier combinación sensor dependiendo de que tipo de
información necesitemos conocer por parte del sensor.
Las tareas son la unidad mínima de ejecución, cada programa debe
tener al menos una tarea la cual es llamada task main, sin embargo
puede haber mas tareas, las cuales se ejecutaran concurrentemente,
lo cual representa una ventaja ya que se ejecutaran al “mismo
tiempo”7. Desde el punto de vista de la ejecución de una tarea esta
puede verse como una secuencia de bytecodes los cuales son una
serie de instrucciones interpretadas por el firmware. Estas tareas
tienen dos estados principales: activas o inactivas, lo cual hace que
estas se puedan ejecutar concurrentemente como ya se había dicho
anteriormente, lo cual tiene la ventaja de que se ejecutan
independientemente y así hacer un código mas claro. Sin embargo en
la primera versión del firmware toca aprender a sincronizar las tareas
debido a que ellas pueden tener acceso al mismo recurso y causar
errores que son difíciles de encontrar debido a que son semánticos.
Este problema del control de acceso a recursos fue tratado en la
segunda versión del firmware. En términos generales el control de
acceso deja a una tarea hacer solicitudes al dueño del recurso, si el
recurso no es de alguna tarea en ese momento la solicitud es exitosa.
Si el recurso es de una tarea con mayor prioridad que la tarea que
hace la solicitud entonces la solicitud falla. En contraste si el recurso
es de una tarea con igual o menor prioridad que la tarea que realiza
7 En realidad sabemos que esto no es cierto, pero la velocidad del procesador lo hace ver así.
ISC-2003-1-47
33
la solicitud, entonces la solicitud es exitosa lo cual nos indica que el
recurso cambia de dueño. Además es importante dejar libre cada
recurso una vez se utilice. Como recursos en el RCX tenemos: motor
A, motor B, motor C y el Sonido, los cuales en la sintaxis de NQC son
representados por las siguientes constantes respectivamente:
ACQUIRE_OUT_A , ACQUIRE_OUT_B, ACQUIRE_OUT_C y
ACQUIRE_SOUND. También existen los recursos definidos por el
usuario: ACQUIRE_USER_1, ACQUIRE_USER_2, ACQUIRE_USER_3 y
ACQUIRE_USER_4. La única diferencia entre los recursos físicos y los
definidos por el usuario es que cuando la tarea dueña de un recurso
físico se pierde entre los cambios de tareas el firmware ejecuta una
acción por defecto la cual en los motores es apagarlos (OFF) y en el
sonido consiste en detener los sonidos que se estén ejecutando en
dicho momento y eliminar los sonidos pendientes en la solicitud del
recurso. Además se ejecuta una acción de reestablecimiento definida
por la tarea que pierde el recurso. Cada tarea tiene una prioridad
entre 0 y 255, siendo 0 la prioridad más alta, es importante definirla
para evitar comportamientos no deseados. Un ejemplo de su
estructura es la siguiente:
acquire(ACQUIRE_OUT_A+ ACQUIRE_OUT_C) //se solicita acceso a los motores A y C {
wait(1000) //espera 10 segundos si se tiene el control de los motores } catch //si la solicitud hacia los recursos falla es llamado Playsound {
Playsound(SONIDO) } ClearTimer(0) //esta instrucción siempre es llamada Esta segunda versión del firmware provee un mecanismo nuevo para
reaccionar frente a estímulos: los eventos. Estos surgieron debido a
las limitaciones de los condicionales como if, while ó until para
ISC-2003-1-47
34
observar la información provista por los sensores. Por ejemplo si se
requiere el estado inmediato de un sensor: ¿el sensor esta
presionado?, o responder a estímulos mas complicados: ¿el sensor
estuvo detenido menos de un segundo? ó ¿el sensor fue presionado
dos veces? Entonces se necesitaría escribir código para manejar
dichos requerimientos con condicionales, pero para ello escribieron
las rutinas para el manejo de eventos.
El firmware puede monitorear hasta 16 eventos independientes,
numerados entre 0 y 15 además cada uno está representado por un
bit en la lista de eventos la cual es llamada Event Mask. Cada evento
tiene un número de parámetros que determinan como y cuando éstos
van a ser disparados. El primer parámetro es el event source el cual
determina la fuente del estímulo que el evento va a monitorear, éste
puede ser un sensor, un temporizador, un contador ó el buffer de
mensajes. El segundo parámetro es el event type el cual define la
condición a monitorear en la fuente del estímulo.
La siguiente es la estructura de los eventos:
monitor(MI_NUMERO_DE_EVENTO) //se define el numero de evento a monitorear {
//código a ejecutar si no ocurre el evento } catch() {
//código que se ejecuta si se dispara el evento } Tipos de Eventos:
Los eventos pueden ser clasificados en eventos booleanos: presionar
(pressed), soltar (released), pulso (pulse) y caída (edge) los cuales
ISC-2003-1-47
35
son utilizados para monitorear el sensor de contacto, el cual presenta
dos estados: encendido y apagado. La clasificación continúa con los
eventos sobre algún rango de valores, para lo cual toca definir los
parámetros de límite inferior (lower l imit) y el l ímite superior (upper
l imit). Nos interesa en este caso que se dispare una acción si el valor
de el sensor monitoreado esta dentro del rango previamente definido.
Hay otros eventos llamados Click Events los cuales consisten en
capturar si hubo un cambio abrupto en el valor de un sensor: de alto
a bajo ó de bajo a alto, como por ejemplo cuando el sensor de
contacto es oprimido y soltado o viceversa (si solo se oprime, el
evento no es disparado, para que ello ocurra toca soltarlo). Las
palabras reservadas para este tipo de eventos son Event_Type_Click y
Event_Type_DoubleClick, También es importante saber que el tiempo
que se demoró el clic puede ser leído y modificado con las funciones
ClickTime(evento) y SetClickTime(evento, valor). Otro evento ocurre
cuando un mensaje llega al RCX, este es del tipo
EVENT_TYPE_MESSAGE.
Gran parte de la funcionalidad del RCX está implementada en el
firmware, gracias a que éste puede interpretar una serie de
instrucciones (opcodes) que son ejecutados simultáneamente sin
necesidad de escribir software adicional en el RCX. Esta serie de
instrucciones pueden ser enviadas al RCX desde otro RCX o bien
desde un PC que hace las veces de host. Para programar el envío de
estas instrucciones hacia el RCX se pueden utilizar varias API’s
alternativas, las oficiales son una serie de librerías que se encuentran
disponibles al público en http://mindstorms.lego.com/sdk en donde
hay dos versiones de sdk: la versión mas antigua solo soporta la torre
infrarroja por puerto serial, mientras que la mas reciente soporta
también la torre USB, la cual además tiene mas funcionalidad debido
ISC-2003-1-47
36
a que está diseñada para interactuar con la versión mas reciente de
firmware. Aunque son compatibles con los dos tipos de firmware que
existen, estas pueden ser utilizadas desde ambientes de programación
Win32 como Visual Basic, Visual C++ ó Delphi debido a que vienen
como librerías DLL, OCX u objetos COM. Existen otras API alternativas
para la comunicación desde el host con el RCX (funcionan con los dos
tipos de firmware oficial) las cuales están desar rolladas en Java. Una
es llamada RCXPort la cual puede encontrarse en
www.slewis.com/rcxport la cual tiene ciertas posibilidades de
comunicación con el RCX muy similares a las que tienen los sdk
oficiales. La otra alternativa con mas funcionalidades la constituye
RCXJava que puede ser adquirida junto con su código fuente bajo
licencia LGPL en el siguiente URL:
http://www.escape.com/~dario/Java/rcx/rcxJava2.1.zip, la cual tiene
una característica interesante y es la posibilidad de comunicarse con
un RCX a través de una red bajo protocolo TCP-IP si se programa un
servidor PROXY utilizando algunas de sus clases. Además según su
autor se puede utilizar bajo ambientes MacOS, Linux y Win32
utilizando puertos seriales y USB.
En conclusión desde el punto de vista de robots autónomos, NQC
puede ser útil para resolver tareas que no necesiten un uso extensivo
de memoria ya que se tiene limitaciones de espacio. Como ejemplo de
estas aplicaciones podrían considerarse como navegación con marcas
en el suelo o navegación buscando fuentes de luz ó resolución de
laberintos muy simples bajo estrategias poco complejas como
siguiendo paredes, etc. La contraparte radica en que tiene mucha
funcionalidad implementada en el Firmware para ejecutar ordenes
enviadas desde un host lo cual hace que esta sea su principal
característica, esta la hace ideal para aplicaciones de tele-operación
con control manual [10] ya que la utilización del API seria basada en
ISC-2003-1-47
37
el envío de ordenes desde el host, además también se podría utilizar
en tareas de tele-operación con control Supervisor sencillo [10] es
decir en donde el control es compartido entre un operador humano y
el mismo robot, aunque este último con una autonomía muy limitada
a la hora de realizar la tarea asignada.
En el anexo 2 en la parte final de este documento se encuentra un
ejemplo de un programa en NQC, el cual hace que el robot siga una
línea negra hasta cuando recibe un mensaje enviado desde el PC cuyo
contenido sea el número 3, esto hace que el robot se detenga y envié
un mensaje hacia el PC el cual contiene el numero 5. El programa que
se ejecuta desde el computador fue hecho en Java utilizando el API
RCXPort.
3.3.2 Programación Con Versiones No Estándar Del Firmware
Hay varias versiones de firmware no oficiales, las cuales surgieron
debido a la necesidad de programar el RCX en lenguajes de
programación reconocidos, ya que no es posible hacer esto con la
versión oficial del firmware. Por ello surgieron diferentes versiones
que soportan los diferentes lenguajes de programación. Estas
herramientas no han sido revisadas pero a continuación se enumeran
debido a que pueden ser interesantes, pero sin mucha difusión en la
comunidad de desarrolladores de software.
• FORTH
http://www.hempeldesigngroup.com/lego/pbforth
ISC-2003-1-47
38
• LISP
http://www.csc.villanova.edu/~klassner/csc4500/resources.html
• Lenguajes sincrónicos: Lustre, Esterel
http://www.emn.fr/x-info/lego/
• TCL
http://www.linux.org/docs/ldp/howto/mini/Lego/tcl.html
• ADA
http://www.usafa.af.mil/dfcs/adamindstorms.htm
• Brick Command
http://www.geocities.com/Area51/Nebula/8488/lego.html
• QC
http://digilander.libero.it/ferrarafrancesco/lego/qc/index.html
• Preprocesador en ADA para NQC
http://www.faginfamily.net/barry/Papers/AdaLetters.htm
• Bot Kit (Dolphin Smalltalk)
http://www.objectarts.com/Bower/Bot-Kit/Bot-Kit.htm
• Gordon Brick Programmer
http://www.umbra.demon.co.uk/gbp.html
En esta evaluación se estudian las herramientas para lenguajes mas
ampliamente conocidos. Gracias a Internet se han difundido API’s que
hacen posible programar el RCX con lenguajes como Java (lejOS) y C
ó C++ (legOS). Cada una de estas librerías cuenta también con su
ISC-2003-1-47
39
respectiva versión de firmware, además de las herramientas para
compilar código escrito en estas sintaxis para que corra en el CPU del
RCX y sus respectivas librerías para el desarrollo de aplicaciones.
3.3.2.1 LeJOS LejOS (LEGO Java Operating System) es el nombre que su autor le dio
a la máquina virtual de Java (JVM) para el RCX, la cual es el pequeño
interpretador que lee los Byte-code y ejecuta las instrucciones en la
CPU, ésta se conoce también como Firmware para Java. El API para
LejOS se puede encontrar en versiones para Windows y Linux, con su
código fuente disponible, además de la documentación (Java docs) en
su sitio oficial: http://lejos.sourceforge.net, aunque en este momento
los voluntarios encargados de este proyecto están migrando el sitio a
un dominio propio cuya URL es www.lejos.org. La versión evaluada es
la 2.0.0, la cual necesita del Java 2 SDK debido a que sus
herramientas de compilación por debajo corren el compilador
estándar de Java. Su autor explica que fue necesario hacer una nueva
máquina virtual de Java debido a que la versión J2ME (Java 2 micro
edición) fue diseñada para ser ejecutada en teléfonos celulares y
computadores de mano con mas de 128 kb en memoria RAM. Además
el propósito del RCX es completamente diferente al de un celular.
Figura 16. Distribución de la memoria en leJOS.
Programas De Usuario
Libre (4 kb)
LeJOS JVM (16 kb)
ROM (16 kb)
Clases básicas De leJOS
RAM
(32
kb)
RO
M
(16
kb)
ISC-2003-1-47
40
Como se mencionó anteriormente el RCX tiene 32 kb de RAM (Figura
2.2), de estos cerca de 4kb hay que dejarlos siempre libres debido a
que son utilizados por las rutinas del ROM, lo que deja cerca de 28
kb, de los cuales 16 kb son utilizados por la versión actual de JVM
para el RCX, lo cual significa que solo quedan 12 kb de memoria libre
para los programas de usuario. Sin embargo hay que tener en cuenta
que las clases básicas del API que son utilizadas en los programas de
usuar io (import) también son almacenadas debido a que son
encadenadas cuando se genera el archivo .class el cual es el que se
va a almacenar y posteriormente a ejecutar en el RCX. Teniendo en
cuenta lo anterior nos damos cuenta que no hay mucha memoria
disponible para un programa, sin embargo esto depende de la
cantidad de memoria que necesite el programa para que se pueda
ejecutar. Por esta razón es crítico tratar de escribir código muy
eficiente. Si necesitamos ampliar la memoria disponible para el
usuario se podría pensar en disminuir el tamaño del firmware (JVM)
y/ó en disminuir el tamaño de las clases que se importan en nuestros
programas, sin embargo la tarea de construir o recompilar para
modificar ó crear un nuevo firmware es una tarea difícil debido a que
se necesitan conocimientos muy específicos acerca del hardware. En
especial del compilador en lenguaje de máquina para el procesador
(estas herramientas solo están disponibles para ambientes Unix,
Linux, Irix, etc.). Además de conocimientos sobre como construir una
máquina virtual de Java y conocimientos sobre compilación cruzada.
Por ello es más fácil aumentar la memoria de usuario si se compila el
API de nuevo debido a que estas clases están escritas en Java,
eliminando aquellos métodos ó atributos que no utilicemos en las
clases que importemos en nuestro programa. Otra alternativa posible
es utilizar otra versión del firmware que se conoce como TinyVM la
cual es mucho mas pequeña, su API tiene menos funcionalidad
ISC-2003-1-47
41
implementada y solo funciona en Linux o en Windows bajo Cygwin, su
dirección electrónica es: http://tinyvm.sourceforge.net/,
lamentablemente este proyecto actualmente está inactivo.
A continuación hago un recuento de algunos de los paquetes que
componen el API y sus clases que en mi concepto lo hacen
interesante.
• Java.lang.Math: En esta clase se encuentran implementadas
funciones trigonométricas, raíz cuadrada, potenciación,
números aleatorios, entre otras. Estas funciones son útiles
para la navegación, además hacen que el RCX soporte
números con punto flotante y así darle cierta precisión a los
cálculos.
• Java.lang.String: Esta clase implementa el soporte de
caracteres y cadenas en el RCX, estas pueden ser útiles para
desplegar información en la pantalla LCD, ó para hacer
debug, sin embargo en robótica no tienen un uso práctico,
además de consumir recursos del RCX.
• Java.lang.StringBuffer : Tiene implementado funciones para el
manejo de cadenas, tales como append.
• Java.lang.System : Esta clase se usa para interactuar con la
máquina virtual de Java y tiene métodos para tener acceso a
los temporizadores, tener acceso a Runtime para calcular el
espacio de memoria libre.
• Java.lang.thread : Esta clase tiene implementados métodos
para manejar hilos de ejecución.
ISC-2003-1-47
42
• Java.util.Bitset: Esta es utilizada para representar series de
bits, las cuales son creadas con una longitud específica,
además hay métodos para cambiar el estado de cada bit, sin
embargo no existe un método para obtener la representación
de esta ser ie de bits en forma de cadena.
• Java.util.random: Esta es utilizada para generar números
aleatorios, sin embargo es mas fácil utilizar el método
math.random().
• Java.Util.Vector: Esta es muy útil si se quiere hacer un
arreglo de objetos con el fin de hacer una estructura de
datos, trae métodos para adicionar elementos al arreglo, etc.
• Java.io: Este paquete contiene la interfase de serialización,
además contiene los métodos InputStream, OutputStream,
DataInputStream y DataOutputStream que son utilizados para
la comunicación del RCX a través del puerto infrarrojo.
• Josx.Robotics: Este es uno de los paquetes más interesantes,
debido a que se encuentran clases genéricas (patrones) para
aplicar con diferentes configuraciones de robots. Existe una
interfase llamada Behavior, la cual como su nombre lo indica
se encarga del comportamiento del robot. Esta interfase
posee 3 métodos a implementar:
§ boolean takeControl(): Este método indica si determinado
comportamiento empieza a ser activo, por ejemplo si un
sensor de contacto ha tropezado con un obstáculo,
entonces este método retorna verdadero.
ISC-2003-1-47
43
§ void action(): Este método inicializa la acción programada
cuando determinado comportamiento empieza a ser activo,
por ejemplo si takeControl() detecta una colisión con un
objeto, entonces el código contenido en el método action
es ejecutado. En este caso podría ser que el robot
cambiara la dirección de desplazamiento (hacia atrás) y
cambiara su orientación para así evitar el obstáculo.
§ void supress(): Este método puede ser usado para
terminar el código que se ejecuta en action o bien para
actualizar algún dato antes de que el comportamiento
termine. Por ejemplo si en action se le cambió el sentido
de giro de los motores, en supress se podría cambiar de
nuevo para que siga hacia adelante. Estos tres métodos
de la interface Behavior hace que sea más simple pensar
en el comportamiento del robot, ya que si por ejemplo se
necesitan implementar 3 comportamientos diferentes,
entonces se necesitan implementar estos tres métodos
para cada clase de comportamiento.
En el caso en que se tengan implementados varios comportamientos,
se necesitaría adicionalmente un mecanismo para coordinarlos, esto
se puede hacer con la clase Arbitrador, su constructor tiene el
siguiente prototipo:
public A rbitrador (Behavior [] comportamientos)
El cual recibe un arreglo de comportamientos para decidir entre ellos
cual está activo en determinado momento. Las prioridades entre estos
son establecidas de acuerdo al índice en el arreglo, entre mas alto
ISC-2003-1-47
44
sea el índice en el arreglo, dicho comportamiento tiene la prioridad
mayor.
El otro método que tiene dicha clase es start() el cual activa el
sistema de manejo de comportamiento (Arbitrator).
Este sistema de control de comportamiento esta basado en el trabajo
hecho por Rodney Brooks [12], el cual originalmente se llamó
subsumption architecture (actualmente es mas conocido como
behavior control). El se basó principalmente del comportamiento de
los insectos, representándolo en un modelo computacional que mas
tarde se convirtió en un patrón muy utilizado en robótica. El observó
que los insectos se desenvuelven exitosamente en el mundo real a
pesar de que poseen un muy pequeño cerebro. Al comparar un
insecto con un computador él concluyó que el insecto tiene una muy
pequeña capacidad de memoria ya que no recuerda cosas del pasado,
además no tiene capacidad de aprendizaje. Él concluyo que la
estrategia de comportamiento de los insectos consiste en dividir su
comportamiento general en varios comportamientos muy simples los
cuales en conjunto pueden reaccionar rápidamente a los cambios.
Para la descripción de cada comportamiento existen dos estructuras
básicas: sensores (entradas) y actuadores (salidas). Esto no solo es
cierto para los robots sino para ciertos organismos, como por ejemplo
un mosquito, el cual todo el tiempo está monitoreando sus
condiciones actuales a través de diferentes “sensores”, si alguno de
éstos es estimulado éste hace que el mosquito reaccione de alguna
manera, dependiendo del “sensor” él va a reaccionar de una manera
diferente. De esta manera se puede entender el comportamiento
como un par condición-acción, esto se ilustra en la figura 17 donde se
hace un ejemplo de comportamiento. En este caso se muestra una
posible acción cuando se detecta una colisión.
ISC-2003-1-47
45
Figura 17. Diagrama del comportamiento en una colisión
[3].
En ocasiones mas de un comportamiento puede solicitar ser activado
en determinado momento (cuando se satisfacen las condiciones de
diferentes comportamientos) y como no se pueden ejecutar acciones
distintas simultáneamente sobre un actuador (como un motor) ya que
dichos comportamientos son el resultado de la discretización del
comportamiento general del robot entonces se hace necesario que
cada uno de estos comportamientos tenga una prioridad. Por ejemplo
un animal puede tener diferentes comportamientos básicos como
proteger a sus crías, alimentarse, defenderse, etc. Entre estos
comportamientos de los animales existe alguno que es mas
importante que los otros así todos alguna vez sean necesarios, en
este caso alimentarse seria mas importante pero si este es atacado en
ese mismo momento el dejaría de comer y se defendería. Rodney
Brooks se ideó unos diagramas como manera de representar esta
jerarquía de comportamientos, en donde se muestra el orden de las
prioridades. En la figura 18 se puede observar un ejemplo, en donde
se representa el caso que se ha venido tratando acerca del manejo
sencillo de una colisión. Basado en [3] y [12].
Comportamiento en una colisión
Acción Retroceder y cambiar
orientación
Condición Sensor de Contacto
oprimido
ISC-2003-1-47
46
Figura 18. Jerarquía del comportamiento en una colisión.
En este diagrama el círculo con la “s” indica que el comportamiento
de retroceder y cambiar la orientación (acción 2) puede
eventualmente tomar el control de los motores. El comportamiento
representado en el nivel mas bajo representa la mayor prioridad, en
este ejemplo lo constituye el comportamiento de seguir hacia delante
(Acción 1). Se podría pensar que con esta arquitectura el robot
siempre ejecuta un solo comportamiento al tiempo, sin embargo si se
desean ejecutar varios comportamientos al tiempo entonces bastaría
con adicionarle mas funcionalidad a dicho comportamiento.
§ Josx.Robotics.Navigator: Esta interfase Java posee métodos muy
interesantes para la navegación de robots móviles. Si se
necesita información detallada acerca de su implementación,
ésta puede ser consultada en los Java-docs u observando el
código fuente. Esta interfase tiene los siguientes métodos:
• public void forward(): Este método hace que el robot se
mueva hacia adelante, hasta que el método stop() es
invocado.
• public void backward(): Este método hace que el robot se
mueva hacia atrás, hasta que el método stop() es invocado.
Sensor de contacto
S
Retroceder y cambiar
orientación (Acción 2)
Seguir hacia delante
(Acción 1) Motores
ISC-2003-1-47
47
• public void travel(int distancia): Este hace que el robot se
mueva una distancia específica; un valor positivo de distancia
hace que éste se mueva hacia delante si; el valor de
distancia es negativo éste retrocede, el parámetro distancia
puede estar en centímetros ó pulgadas. Este movimiento
retorna cuando el movimiento esta completo.
• public void stop(): Hace que el robot se detenga, además
calcula el valor actual de las coordenadas X y Y que indican
la posición del robot.
• public void rotate(float ángulo): Rota el robot un número
positivo o negativo de grados, un valor positivo hace que la
rotación sea en el sentido contrario de las manecillas del
reloj.
• public void gotoAngle(float ángulo): Hace que el robot llegue
a una orientación determinada. Esta función toma el camino
mas corto para llegar al ángulo deseado.
• public void gotoPoint(float x, float y): Hace que el robot se
mueva al punto con las coordenadas indicadas.
• public float getX(): retorna la coordenada X, puede invocarse
si el robot está en movimiento.
• public float getY(): retorna la coordenada Y, puede invocarse
si el robot está en movimiento.
• public float getAngle(): retorna la orientación del robot, este
método solo se puede invocar si el robot está detenido.
La interfase Navigator es implementada por las clases
TimingNavigator y RotationNavigator las cuales fueron diseñadas para
un robot que tenga un motor a la izquierda y otro a la derecha. La
clase TimingNavigator mide el movimiento (translación o rotación) en
unidades de tiempo (segundos). Como los robots pueden diferir en el
ISC-2003-1-47
48
radio de las ruedas, utilización de diferentes engranajes, diferentes
longitudes de los ejes, etc. hace que los parámetros de tiempo
utilizados en esta clase sean diferentes para cada robot, además se
necesita de un proceso para calibrar dichos parámetros con el fin de
aumentar la precisión en los movimientos. El prototipo del constructor
de esta clase es el siguiente:
• public TimingNavigator(Motor derecha, Motor Izquierda, float
Tiempo-Un-Metro, float Tiempo-Rotación)
el cual crea un objeto de tipo Navigator y lo inicializa con los valores
de las coordenadas X y Y en 0, y el ángulo de orientación en 0
grados. El parámetro derecha indica el motor utilizado para mover la
rueda derecha, por ejemplo Motor.C. Análogamente ocurre con el
parámetro Izquierda. El parámetro Tiempo-Un-Metro indica el número
de segundos que se demora el robot en recorrer 100 centímetros o
100 pulgadas. El parámetro Tiempo-Rotación indica el número de
segundos que el robot toma para rotar 360 grados.
public void setMomentumDelay(short retardo)
Este método hace que se le adicione un tiempo extra a cada rotación
debido a que el robot no empieza a rotar instantáneamente debido a
la inercia, el parámetro retardo se pasa en unidades de milésimas de
segundo. Al usar TimingNavigator se introducen errores que se
propagan y por lo tanto esto afecta la precisión de los movimientos.
En cuanto a los errores sistemáticos éstos son introducidos en los dos
parámetros de tiempo que se le pasan al constructor ya que estos se
van acumulando en cada movimiento. Para manejar el error en el
parámetro de rotación se podría pensar en hacer las mediciones
ISC-2003-1-47
49
experimentales para estimar el valor del tiempo de retardo y utilizar
el método setMomentumDelay. Para el otro parámetro se hace
necesario hacer también las mediciones experimentales con el fin de
obtener el valor que satisfaga los requerimientos de precisión ya que
estos errores siempre estarán presentes. Sin embargo esta tarea de
medir experimentalmente el tiempo de retardo tiene otro
inconveniente, el cual consiste en que el voltaje del RCX cambia
durante la ejecución de una tarea. Esto tiene como consecuencia que
el trabajo de calibración no sea siempre válido. En cuanto a los
errores no sistemáticos hay que tener en cuenta que los motores no
siempre rotan a la misma velocidad, así estén configurados con los
mismos parámetros. Por ello se hace necesario un trabajo de
calibración experimental para hallar los valores de los parámetros
individuales para cada motor con el fin de que los dos se comporten
lo mas parecido posible. También otra fuente de estos errores es el
tipo de superficie donde el robot se encuentre, como por ejemplo un
tapete o una superficie rugosa introduce más error que una superficie
mucho más uniforme.
La clase RotationNavigator implementa todos los métodos de la
interfase Navigator. Su uso es muy parecido a la clase
TimingNavigator y difiere en que el control del movimiento no se hace
por tiempo sino utilizando los sensores de rotación lo cual hace que
aumente la precisión en las medidas. Esta clase es útil únicamente en
una configuración específica del robot ya que asume ciertos
parámetros en la construcción del mismo. Primero que todo se asume
que cuando los motores rotan hacia delante, también hacen girar
hacia adelante las ruedas, aquí toca tener en cuenta la orientación de
las conexiones entre cada motor y el RCX. Además de esto hay que
asegurarse que cuando los motores y el robot se muevan hacia
ISC-2003-1-47
50
adelante los dos sensores de rotación cuentan incrementos positivos
(aquí se tiene en cuenta la orientación de los sensores de rotación).
El constructor de esta clase tiene diferentes prototipos, ya que este
aprovecha el polimorfismo como característica de la tecnología
orientada a objetos de Java:
• public RotationNavigator(float diametroRueda, float
longitudEntreRuedas, float radio, Motor Izquierda, Motor
derecha, Sensor sensorIzquierda, Sensor sensorDerecha)
• public RotationNavigator(float diametroRueda, float
longitudEntreRuedas, float radio)
Este último constructor presenta las mismas características que el
primero solo que asume que el motor de la izquierda es Motor.A , el
motor de la derecha es Motor.B, el sensor de rotación de la izquierda
es Sensor.S1, y el sensor de rotación de la derecha es Sensor.S3. Los
otros tres parámetros son los que necesita la clase para poder
calcular los movimientos del robot. El parámetro diametroRueda es el
diámetro de la cara externa de la rueda, la cual está en contacto con
el suelo. Esta clase multiplica dicho diámetro por el valor de PI para
así obtener la longitud de la circunferencia. El parámetro
longitudEntreRuedas es la longitud del eje de rotación de las ruedas;
sin embargo este parámetro puede variar sobretodo al usar ruedas
anchas, debido a que dicho parámetro lo determina la distancia entre
los puntos de contacto de cada rueda con el suelo. El parámetro radio
indica el número de rotaciones que da el sensor de rotación por cada
revolución completa de la rueda, por ejemplo si el sensor de rotación
está directamente conectado a la rueda este parámetro es 1.
ISC-2003-1-47
51
En cuanto a los errores sistemáticos que toca manejar al utilizar esta
clase lo constituye la medición de la orientación inicial del robot, lo
cual hace que se propague el error proporcionalmente a la longitud
de sus movimientos. En cuanto a la translación toca tener en cuenta
que los sensores de rotación marcan un valor de 16 por cada rotación
completa de su eje. Por ejemplo, si el parámetro radio de un robot es
3 quiere decir que por cada rotación de las ruedas el sensor de
rotación debe marcar 48, pero no se puede estar seguro de esto
porque el valor podría estar en el intervalo [48 49) en el mejor de los
casos, por ello toca hacer un análisis mas profundo en cada caso para
estimar los errores. Además de esto toca tener en cuenta la medición
del parámetro diametroRueda (distancia de los puntos de contacto de
las ruedas con el suelo). Este varía para cada tipo de superficie y de
la anchura de las ruedas. Por ejemplo en una superficie rugosa el
punto de contacto con las ruedas puede variar: a menor o mayor
escala según la anchura de las ruedas, además es difícil de hablar de
superficies y ruedas perfectas para un kit de robot de bajo precio. En
cuanto a los errores no sistemáticos se encuentran varios como por
ejemplo los debidos a la rugosidad de la superficie en donde se está
desplazando el robot, además de los ocasionados al colisionar
elásticamente con algún objeto. Por ello en robótica son utilizados
sensores que tienen mayor precisión y que resuelvan de cierta
manera los errores no sistemáticos como por ejemplo sensores
infrarrojos o de sonido para detectar obstáculos sin colisionar con
ellos y/o conocer la distancia a que se encuentran, sensores que
hacen las veces de brújula (compass sensor) para conocer su
orientación independientemente de las características del ambiente en
que se desenvuelva el robot.
Buscando en Internet he encontrado los planos de los circuitos de
sensores de este tipo adaptados para que funcionen con el RCX, estos
ISC-2003-1-47
52
se encuentran en: www.philomone.com/sensors ó
www.convict.lu/jeunes/CompassSensor2.htm , los cuales se pueden
programar con leJOS, y en general con cualquier API para el RCX.
El RCX como ya se sabe tiene limitaciones en cuanto a su cantidad de
memoria que es de tan solo 32kb. En el caso leJOS es fácil quedarse
sin memoria suficiente para nuestro software debido a que el código
Java es interpretado y además el API de leJOS tiene bastante
funcionalidad, la cual muchas veces no se puede utilizar en toda su
dimensión debido a las limitaciones antes mencionadas. Si se necesita
experimentar con un robot completamente autónomo habría que
establecer claramente límites para el tipo de tareas a resolver ya que
no es posible utilizar exhaustivamente todas las clases disponibles en
el API. Vale la pena mencionar que el API de leJOS también posee
clases para la comunicación entre una máquina Host y el RCX ó bien
entre uno o varios RCX. Esta parte es muy interesante si se quiere
utilizar el RCX para aplicaciones de tele operación, tele-robótica ó
ambientes colaborativos entre robots. En cuanto a la programación
desde el lado del host estas clases se encuentran en el paquete
pc.irtower.comm. Estas clases necesitan del Javacomm 2.0 API el cual
puede ser bajado desde el sitio oficial de SUN. La comunicación entre
el host y el RCX es algo complicada debido a que la torre infrarroja
puede recibir datos únicamente cuando su LED está encendido, es
decir que desde el lado del host no hay manera de detectar cuando le
están llegando datos, debido a que la torre infrarroja permanece
apagada si no está enviando datos. En conclusión se puede decir que
el PC es el que inicializa las transferencias de datos con el RCX.
Desde el lado del RCX la comunicación se puede hacer utilizando el
API que tiene leJOS para este propósito, el cual se encuentra en los
paquetes Java.io y josx.platform.rcx.comm. Hay que aclarar que
ISC-2003-1-47
53
aunque la sintaxis de los programas para el host y el RCX es similar
debido a que su sintaxis es de Java, estas aplicaciones se compilan
de una manera muy diferente ya que cada una utiliza API’s diferentes
(así coincidan con el nombre de algunos de sus paquetes) hechas
para diferente máquina virtual de Java.
Para concluir se puede decir que leJOS es un API de alto nivel muy
completo que sigue una sintaxis del lenguaje Java estándar y que
posee ciertos patrones utilizados tradicionalmente en robótica, lo cual
evita estar pensando en detalles de bajo nivel para interactuar con el
hardware. Con éste se podría experimentar programando el RCX en la
resolución de tareas sencillas en robótica móvil que involucren cierto
nivel de precisión en sus movimientos, bajo nivel de procesamiento y
almacenamiento de datos. Para la resolución de tareas un poco más
complejas se podría utilizar la intercomunicación con el host para que
éste procese la información y sea enviada al RCX con el fin de que
éste desarrolle tareas más sencillas. Sin embargo el robot en este
caso ya no seria totalmente autónomo. Debido a las capacidades de
intercomunicación entre el RCX con una máquina host se podría
pensar en experimentar con el desarrollo de aplicaciones para el
control remoto de un Robot ya sea aplicando una arquitectura de
comunicación cliente/servidor ó tal vez vía un navegador de Internet
interactuando con un servidor Web y un Proxy con el fin de tener
acceso al puerto serial, para esto tocaría establecer muy bien el tipo
de control que se desea implementar. En mi opinión podría ser
principalmente control manual o control supervisor, aunque no se
podría descartar un nivel de control automático [10] para la
resolución de una tarea muy sencilla.
ISC-2003-1-47
54
3.3.2.2 LegOS
LegOS es actualmente la herramienta más poderosa para programar
el RCX. Este consta de un nuevo firmware y de un API que junto con
el compilador cruzado Hitachi H8 se puede construir software para el
RCX. Su página oficial es: http://legos.sourceforge.net, aunque
actualmente la están migrando a: http://brickos.sourceforge.net
debido a que por razones de marca registrada se le cambió el nombre
a brickos. Este trabajo está basado en [6], [13] y en [14] además de
los documentos generados como documentación del API publicados en
la URL antes mencionada.
Con esta herramienta (a diferencia de las existentes) se produce
código en el lenguaje de máquina propio del CPU del RCX, esto
debido a que utiliza el compilador cruzado creado por el fabricante
del procesador. Por lo tanto su código no es interpretado lo cual
presenta beneficios al ejecutarlo, como por ejemplo es mucho más
rápido y consume menos recursos. El lenguaje que soporta el
compilador es C ó C++ bajo ambientes Linux ó Unix (debido a que el
compilador fue creado para esta plataforma), aunque también hay
casos de gente que lo ha instalado exitosamente bajo plataforma
Solaris. Bajo Windows es posible instalarlo usando Cygwin que es una
especie de emulador de la consola Linux desarrollado con
herramientas GNU. Sin embargo la instalación de estas herramientas
es una tarea difícil para los que no tenemos experiencia de
programación bajo ambientes Linux con herramientas GNU. En mi
caso he podido instalar exitosamente las versiones 0.2.4 y 0.2.5 bajo
Windows siguiendo las instrucciones que se encuentran en el sitio
oficial. La versión 0.2.5 es fácil de instalar en la distribución Red Hat
debido a que es posible encontrar un instalador en formato RPM. Sin
embargo con la versión más reciente 0.2.6 he necesitado de un poco
ISC-2003-1-47
55
de paciencia y tiempo para su instalación en Windows. Gracias a la
ayuda del grupo de noticias lugnet.robotics.rcx.legos la pude instalar
exitosamente; esta última versión bajo Linux no la he intentado
instalar. Una de las principales razones por lo que su proceso de
instalación no es una tarea fácil, lo constituye la falta de
documentación para su instalación y uso de esta herramienta, ya que
la poca que se encuentra es algo confusa y supone que el lector
posee de antemano cierta experiencia en este tipo de ambientes de
desarrollo.
Figura 19. Arquitectura de creación de software en
legOS.
LegOS está compuesto por varias partes: el sistema operativo (SO), el
compilador y el cargador de los programas al RCX. El compilador es
una versión recompilada del GNU C Compiler (gcc). Este es usado
para compilar legOS y los programas de usuario en código de
máquina (ensamblador para los procesadores H8) que el RCX pueda
ejecutar. El programa firmdl3 es utilizado para cargar el firmware de
legOS en el RCX, y el programa dll es usado para cargar en el RCX los
programas de usuario en formato .lx (binario) previamente
compilados.
Puerto Serial ó USB Torre Infrarroja
Hardware
Rutinas en ROM
LegOS Firmware (SO)
Programas de usuario
Máquina Host RCX
RAM
ROM
Compilador cruzado Hitachi H8
Cargador de Programas (dll)
ISC-2003-1-47
56
El API de legos en un conjunto de librerías con sus respectivos
archivos encabezado escritos en C para darle funcionalidad al
hardware del RCX, esta librería contiene una funcionalidad muy básica
y a bajo nivel en contraste con leJOS. La funcionalidad de legOS
puede ser dividida en tres categorías principales: funciones de salida,
funciones de entrada y funciones de control de programas.
• Funciones de Salida: Las funciones de salida sirven para
programar los dispositivos del RCX que interactúan con el
mundo exterior, como la pantalla de cristal líquido y los
motores. Para programar los movimientos de los motores
existen dos tipos de funciones, una con el fin de controlar la
dirección de rotación de los motores y otra con el fin de
controlar la velocidad. Estas funciones se encuentran en la
librería <dmotor.h>. El prototipo de la función para controlar la
dirección de un motor es de la siguiente forma: void
motor_x_dir(MotorDirection dirección), donde x es la letra del
motor a configurar (a, b ó c) y dirección es una de las
siguientes cadenas de caracteres: off, fwd, rev ó brake; cada
una de estas tiene su propio significado: off le quita la
alimentación de corriente a los motores únicamente, así que
estos siguen rotando a causa del impulso que llevan; fwd hace
que los motores giren en dirección hacia delante, rev invierte la
dirección de giro con la que está configurado actualmente el
motor y brake como su nombre lo indica hace las veces de
freno, ya que suspende la alimentación de energía hacia el
motor y no lo deja seguir rotando a diferencia de off. El
prototipo de la función velocidad es similar: void
motor_x_speed(unsigned char velocidad), donde x es a, b ó c y
velocidad es un numero entre 0 y 255.
ISC-2003-1-47
57
Las funciones para desplegar la pantalla se encuentran en
<rom/lcd.h> y las que involucran funciones de cadenas se
encuentran en <conio.h>. Estas son importantes debido a que
pueden ser utilizadas para desplegar información importante en
la pantalla ó como herramienta de depuración. La descripción de
estas se encuentra en [6] y en [13] de donde me he basado
para hacer esta descripción.
• Funciones de dispositivos de entrada: Estas sirven para
programar los botones y los sensores. La librería en donde se
encuentran las funciones para el manejo de los sensores es
llamada <dsensor.h>. El valor original que es generado por los
sensores (raw value) al cual se puede tener acceso
directamente por las macros definidas para cada puerto de
entrada donde se conectan los sensores: SENSOR_1, SENSOR_2
y SENSOR_3. El kernel 8 de legOS actualiza el valor proveniente
de los sensores continuamente, esto lo hace diferente al
firmware oficial el cual actualiza este valor a una rata fija de
intervalos de tiempo, lo cual hace que legOS pueda responder o
reaccionar más rápido a los cambios en el ambiente. En [6]
nombran un ejemplo de esta característica con los sensores de
rotación el cual consiste en que legOS puede leer los sensores
de rotación con una precisión razonable hasta cerca de 5000
rpm, mientras que el Firmware estándar únicamente lo puede
hacer hasta 1250 rpm debido a que la frecuencia en monitorear
los valores en los sensores es menor.
Mediante las constantes TOUCH_1, TOUCH_2, TOUCH_3 se
puede tener acceso a los valores de los sensores de contacto
8 También llamado núcleo, el cual es el componente de software principal detrás de un sistema operativo.
ISC-2003-1-47
58
que como ya se había dicho corresponden a valores booleanos 1
ó 0, sin embargo estas constantes también se pueden utilizar
con otro tipo de sensores. Un ejemplo de su uso podría ser:
if(TOUCH_1) {
//ejecutar alguna acción
}
Las macros utilizadas para leer los valores de los sensores de
luz son LIGHT_1, LIGHT_2 y LIGHT_3. El valor original generado
por estos es escalado en un valor entero entre 50 y 300 en el
modo pasivo, donde un valor menor indica oscuridad y un valor
alrededor de 300 indica que se capta más cantidad de luz por
parte del sensor. Los sensores de luz en legOS pueden
configurarse como activos o pasivos. Los siguientes son los
prototipos de estas funciones respectivamente:
void ds_active(volatile unsigned *sensor)
void ds_passive(volatile unsigned *sensor)
Donde sensor representa un apuntador al sensor que se desea
configurar, por ejemplo: ds_active(&SENSOR_1) configura el
sensor conectado al puerto de entrada 1 como activo. El modo
pasivo configura el sensor de luz de manera que desactiva el
diodo emisor de luz, dejando activado únicamente el
fototransistor con el fin de captar únicamente la luz del
ambiente, mientras que en el modo activo si se habilita el diodo
emisor de luz.
En cuanto a los sensores de rotación hay que recordar que estos
se configuran como activos, además existen 3 funciones que son
útiles para el manejo de estos sensores:
void ds_rotation_on(volatile unsigned *sensor)
void ds_rotation_off(volatile unsigned *sensor)
ISC-2003-1-47
59
void ds_rotation_set(volatile unsigned *sensor, int posición)
La función ds_rotation_on enciende el sensor apuntado por
*sensor, la función ds_rotation_off hace la acción contraria, ya
que apaga el sensor apuntado por *sensor. La función
ds_rotation_set cambia el valor actual del sensor apuntado por
*sensor con el valor del parámetro posición.
• Funciones de control de programas: Estas funciones se
encuentran principalmente en <unistd.h>, y sirven para
programar el control del flujo de los programas, ya que en este
ambiente esto se programa a un nivel relativamente bajo si se
compara con los otros ambientes estudiados.
Las funciones de control de tiempo, se utilizan especialmente
para detener el hilo de ejecución (thread) de un programa por
cierta cantidad de tiempo:
int msleep(unsigned int milisegundos)
int sleep(unsigned int segundos)
La diferencia entre estas dos funciones radica en la unidad en
que se pasan el parámetro de entrada, a msleep se le pasa en
mil isegundos mientras que a sleep se le pasa en segundos.
Algunas de las siguientes funciones son muy parecidas a las que
hay en Unix, pero antes de describirlas hay que tener en cuenta
algunas constantes que se utilizan en ellas.
DEFAULT_STACK_SIZE esta definida por defecto en 512,
PRIO_NORMAL, PRIO_HIGHEST y PRIO_LOWEST están definidas
por defecto con los valores 10, 20 y 1 respectivamente.
pid=Pid_t execi (int(*empezar_codigo) (int,char**), int argc, char **argv, priority_t prioridad, size_t tamaño_pila)
ISC-2003-1-47
60
La función execi empieza un nuevo hilo de ejecución con la
función apuntada por *empezar_codigo pasándole a dicha
función los parámetros int argc y char *argv[], los cuales no
son muy utilizados. El parámetro prioridad indica como su
nombre lo sugiere la prioridad de la tarea que se está
ejecutando, (se pueden utilizar las constantes definidas
anteriormente) lo importante es definir una prioridad única a
cada tarea debido a que es difícil predecir la decisión tomada
por el kernel de legOS en caso de que mas de dos tareas tengan
la misma prioridad. El último argumento tamaño_pila indica el
tamaño de la pila en bytes que utiliza el thread o tarea que se
quiere ejecutar, pienso que este valor es difícil de estimar, así
que utilizar la constante definida anteriormente puede funcionar
en muchos casos. El parámetro de salida pid retorna un
identificador del nuevo proceso a ejecutar el cual es de tipo
pid_t, el cual generalmente se almacena como variable global.
La función void kil l(pid_t id_Proceso) se utiliza para “matar” un
proceso que se este ejecutando, y se le pasa como parámetro el
identificador de proceso que devuelve la función execi al
crearlo. Sin embargo legOS tiene un planificador de ejecución
de tareas basadas en prioridades por lo cual este puede
encargarse del control de éstas, para ello existe la función void
yield (void). LegOS en su librería <semaphore.h> contiene
funciones para manejar semáforos, los cuales son utilizados
para la sincronización y comunicación entre procesos y cuya
implementación cumple con el estándar POSIX.
Como es sabido el RCX no tiene registros especializados para
representar y operar números de punto flotante, sin embargo
este API contiene el soporte necesario para su emulación en el
ISC-2003-1-47
61
RCX. Esta librería es encadenada automáticamente en el archivo
binario .lx si es usada, debido a que no hace parte del kernel de
legOS, esto con el fin de que sea mas flexible en el manejo de
la memoria. Otro aspecto a tener en cuenta además del
encadenamiento de dicha librería es la velocidad de ejecución
en operaciones con números con punto flotante ya que esta es
un poco mas lenta y en algunos casos hay que tenerla en
cuenta. En la siguiente tabla se encuentran los tipos de
números soportados con sus respectivos tamaños:
Tipo Tamaño en Bytes int 2
Unsigned int 2 Long int 4
float 4 double 4
Figura 20. Tipos y tamaños de numeración soportado por legOS.
Además de proporcionar el soporte a estos tipos, la librería
posee dos funciones:
void srandom(unsigned int numero_base)
long int random ()
La función random genera de manera aleatoria un número entre
0 y 1231 − .
La función srandom se utiliza para cambiar el número base, el
cual es el punto de partida para que la función random genere
números aleatorios a partir de él, por ello conviene llamar la
función srandom antes de utilizar random.
Otra librería importante del API de legOS es LNP (Layered
Network Protocol) mediante la cual se pueden enviar o recibir
ISC-2003-1-47
62
información en forma de paquetes por el puer to infrarrojo.
Estos paquetes pueden ser Broadcast ó punto a punto, lo cual
quiere decir que con esta librería se pueden enviar la misma
información a varios RCX simultáneamente con el envío de un
solo paquete (Broadcast), ó también es posible enviar
información específicamente a un RCX el cual tiene una
dirección única configurada previamente (punto a punto). En la
siguiente tabla se muestra las capas que componen el protocolo
de comunicación LNP:
Capa Nombre Propósito
3 direccionamiento Identificar el receptor del mensaje y
el puerto
2 integridad Verificar la integridad del mensaje
recibido
1 lógica Flujo de bytes en el orden correcto
0 física Transporte de la señal infrarroja
modulada
Figura 21. Capas implementadas en LNP.
La capa física y lógica fueron programados en lenguaje
ensamblador a bajo nivel. Para efectos prácticos en la
programación usando la librería donde se encuentra
implementado LNP <lnp.h> vale la pena entender un poco más
detalladamente las capas 2 y 3. Como se dijo anteriormente un
mensaje broadcast es recibido por todos los RCX o máquinas
host que se encuentren en el rango de alcance de la señal
infrarroja. No hay manera de saber el origen de un paquete de
integridad broadcast, sin embargo si es colocada la dirección de
origen junto con la parte de datos se puede saber que máquina
ISC-2003-1-47
63
emitió dicho paquete. Este paquete de integridad tiene la
siguiente estructura:
F0~LEN~IDATA~CHK
Donde F0 es el encabezado utilizado como convención para un
paquete de integridad, LEN es la longitud de los datos a
transmitir, IDATA son los datos que se quieren transmitir y CHK
es el checksum utilizado para verificar que los datos se
transmitieron correctamente. Para enviar paquetes de integridad
se utiliza la función:
int lnp_integrity_write(char* datos, unsigned char
longitud_datos)
Donde datos es un apuntador a la cadena que contiene los
datos a transmitir y longitud_datos representa la longitud de la
cadena de los datos a enviar. Esta función retorna un valor
diferente de cero si una colisión es detectada.
Un paquete de integridad puede ser recibido por algún host que
tiene registrado una función que hace las veces de manejador.
Para hacer este registro se usa la siguiente función:
lnp_integrity_set_handler(nombre_funcion_manejadora_de_integridad)
Donde la función manejadora de integridad debe ser declarada
previamente con cualquier nombre, para este ejemplo:
void nombre_funcion_manejadora_de_integridad (const unsigned char*
datos, unsigned char longitud) { //funcionalidad}
Los paquetes de direccionamiento los son usados para enviar
mensajes a un host específico. Estos paquetes son recibidos
ISC-2003-1-47
64
únicamente por el host con una dirección específica únicamente
si dicho host tiene un manejador registrado en el puerto
especificado. Hay que aclarar que dicha dirección es única para
cada RCX y es especificada en el firmware. Es decir que si
queremos utilizar paquetes punto a punto debemos especificar
la dirección, compilar el firmware y luego si descargar el
firmware al RCX, ya que no es posible cambiar esta dirección
después de que el firmware este en el RCX. La estructura de los
paquetes de direccionamiento es la siguiente:
F1~LEN~DEST~SRC~ADATA~CHK
Donde F1 es el encabezado utilizado como convención para un
paquete con direccionamiento, LEN representa la longitud de los
datos y por ser de tipo char no puede ser mayor de 255, DEST
representa la dirección del host al cual se le envían los datos
esta es de 2 bytes, SRC representa la dirección de 2 bytes de la
máquina que envía el paquete, ADATA son los datos que se
desean transmitir y CHK es el checksum.
La función:
lnp_addressing_set_handler(unsigned charpuerto, lnp_addressing_handler_t
manejador)
es utilizada para establecer la función que maneja este tipo de
paquetes, donde puerto es el número de puerto asignado por
donde escuchara la llegada de los mensajes y manejador es un
apuntador a la función que manejara estos paquetes. Esta
función se declara de la siguiente manera:
void manejador (const unsigned char *datos, unsigned char longitud,
unsigned char direccionOrigen ){ //funcionalidad}
ISC-2003-1-47
65
*datos es un apuntador a la cadena donde quedan almacenados
los datos que se reciben, longitud es la longitud de los datos
recibidos y direccionOrigen es la dirección LNP de la máquina
desde donde fueron enviados los datos.
Los paquetes direccionados se envían llamando la siguiente
función:
int lnp_addressing_write(const unsigned char *datos, unsigned char
longitud, unsigned char direccionDestino, unsigned char puerto_Origen)
*datos es un apuntador a los datos que se quieren enviar,
longitud es el valor que representa la longitud de la cadena que
contiene los datos a enviar y puerto_Origen es una convención
que representa el puerto de origen de la máquina que quiere
enviar los datos.
Para el envío de paquetes desde el host hay varias librerías.
Para Linux se encuentra libLNP y LNP Daemon las cuales pueden
ser descargadas desde:
http://legos.sourceforge.net/files/linux/LNPD/. Para Windows se
encuentra la librería WinLNP la cual puede ser utilizada desde
VisualC++ y puede ser descargada desde
http://legos.sourceforge.net/files/windows/winLNP/, sin
embargo no tiene documentación y el código no es fácil de
entender. Existe otro API llamado JavaLNP el cual es mucho mas
fácil de entender debido a que esta estructurado en clases Java.
En conclusión legOS es la herramienta mas poderosa para programar
el RCX debido a que es la única que genera los ejecutables en
lenguaje de máquina esto la hace que la ejecución de los programas
sea mucho mas veloz que con los otros API’s. Además se programa en
ISC-2003-1-47
66
lenguaje estándar C, lo cual hace que se pueda administrar de
manera precisa por parte del desarrollador los recursos tales como la
memoria ya que no tiene restricciones sobre número de variables,
además se pueden declarar estructuras de datos, etc. Otra
característica importante es que tiene soporte para operar con
números de punto flotante, lo cual es útil para tener una mayor
precisión en las tareas a ejecutar por el robot. Su protocolo de
intercambio de datos por el puerto infrarrojo es más rápido que en
los otros ambientes y además integra la característica de envió de
paquetes con direccionamiento, lo cual puede ser bastante útil si se
trabaja con varios RCX. En contra se tiene que esta herramienta no es
fácil de instalar y modificar; en comparación con leJOS su
programación es todavía a muy bajo nivel. No hay implementación de
funciones tr igonométricas las cuales son muy útiles en robótica móvil
por ende no posee herramientas de software específicas para robótica
móvil pero es posible desarrollarlas debido al soporte de números
flotantes. No tiene un ambiente gráfico para el desarrollo de
programas lo cual en algunos casos hace más lento el proceso de
desarrollo, además la poca documentación no es muy buena para los
que no tienen experiencia en ambientes de programación Linux y con
software embebido bajo este ambiente. Esta herramienta es la ideal si
se quiere hacer un robot totalmente autónomo que involucre tareas
complejas o si se necesita implementar un algoritmo de redes
neuronales, genéticos, de aprendizaje o que necesite total control
sobre cualquiera de los recursos principalmente la memoria. Si lo que
se desea es tele-operar el robot manualmente, tal vez es mas fácil
hacerlo desde otros API’s, si se desea tele-operar a un nivel
supervisor legOS puede ser útil debido a que puede hacer tareas mas
complejas desde el lado del RCX pero la programación vista del lado
del host puede ser un poco mas compleja que con leJOS. Un problema
ISC-2003-1-47
67
que si es algo crítico y que está presente en todos los ambientes de
desarrollo para el RCX es la ausencia de herramientas para la
depuración de programas lo cual aumenta el grado de dificultad en el
proceso de desarrollo de software para sistemas embebidos, ya que
las únicas herramientas que podrían utilizarse para este fin y que
están presentes en el RCX son la pantalla de cristal líquido y la
emisión de sonidos que sin embargo siguen siendo herramientas muy
precarias.
En el anexo 1 se puede observar una tabla que resume las principales
características de los API’s evaluados.
3.4 Aplicaciones
En la actualidad, en la industria, robots realizan tareas que antes
estaban reservadas para los operarios humanos. Estos dispositivos
realizan sus tareas con mayor exactitud y velocidad, son incansables,
realizan trabajos peligrosos y hasta inaccesibles para una persona y
hasta son más económicos que sus "contrapartes" humanos. En la
siguiente lista de aplicaciones algunas de estas fueron tomadas de
[7]. Entre las aplicaciones más frecuentes en la industria están:
• Manipulación en fundición (moldes y otros)
• Manipulación en moldeo de plásticos
• Manipulación en tratamientos térmicos
• Manipulación en forja y estampación
• Soldadura (Al arco, por puntos, por gas, por láser, otros)
• Aplicación de materiales (Pintura, adhesivos y secantes, otros)
• Mecanización (Carga y descarga de maquinas, corte mecánico,
desbarbado y pulido)
ISC-2003-1-47
68
• Otros procesos (Láser, Chorro de Agua)
• Montaje (montaje mecánico, Inserción, Unión por adhesivos)
• Palatización
• Medición, inspección, control de calidad
• Manipulación de materiales
• Industria Nuclear: Por sus especiales características, el sector
nuclear es uno de los mas susceptibles de utilizar robots de
diseño especifico. Entre estas aplicaciones se encuentran las
relativas a operaciones de mantenimiento en zonas
contaminadas y de manipulación de residuos.
• Medicina: Entre las aplicaciones mas importantes se destaca la
cirugía, tele diagnostico y tele cirugía, la cual consiste en la
operación remota de un paciente mediante un tele manipulador.
• Construcción: Este sector es, en la mayoría de los países
industrializados, uno de los que moviliza mayor numero de
recursos económicos y humanos. En este tipo de aplicaciones de
la robótica, como en otros muchos el Japón es el que cuenta
con un mayor numero de sistemas en funcionamiento. En
algunos casos se trata de robots parcialmente tele-operados,
construidos a partir de maquinas convencionales (grúas,
excavadoras, etc.). En otros casos es maquinaria
específicamente construida para resolver un proceso concreto.
Por ejemplo: operaciones de colocación de elementos,
operaciones de tratamiento de superficies u operaciones de
rellenado.
• Exploración del Espacio
• Exploraciones Marinas: El desarrollo de vehículos tele-operados
submarinos serán muy importantes en el futuro de la
exploración de recursos minerales, en el control y monitoreo del
medioambiente y en la agricultura acuática.
ISC-2003-1-47
69
• Agricultura: En la agricultura la tele-operación es una atractiva
aproximación para el manejo de cultivos a gran escala. Esta
seria útil en el manejo de uno o varios tractores, ya sea para
arados, recolección de cosechas, sembrar, etc.
• Minería: Las minas siempre han sido un ambiente muy hostil
que ha dejado muchas perdidas humanas. En la grafica se
observa un robot para la carga y transporte de maquinaria. La
tele-operación en este campo se utiliza más que todo en
observar las concentraciones de gas metano, temperaturas, etc.
3.5 Trabajos Relacionados
A continuación se hace un breve resumen de los trabajos
relacionados realizados en la Universidad de Los Andes.
“Reconocimiento de Ambiente por un Robot Móvil” [15].
Este trabajo se encuentra dividido en cinco par tes:
• Estructura mecánica del robot.
• Componentes de Hardware del Robot.
• Herramientas de software con que cuenta el robot.
• Explicación e implementación de las estrategias de navegación
Implementadas.
• Métodos utilizados para la reconstrucción de mapas.
En las primeras dos partes se explica la configuración física del robot,
el tipo de motores utilizados, el funcionamiento del sensor de
ultrasonido y se hace un recuento de algunas consideraciones físicas
ISC-2003-1-47
70
a tener en cuenta en la calibración de dicho sensor. En la parte de
hardware se hace un recuento de los microcontroladores utilizados en
la construcción del robot, así como de otros componentes y su detalle
de funcionamiento a bajo nivel.
En la tercera parte se hace referencia a las herramientas de software,
estas son de dos clases: los programas a bajo nivel que fueron
utilizados para programar los microcontroladores, y la otra clase son
los programas encargados de ejecutar las estrategias de navegación,
la cartografía, el modelo del ambiente y la interfaz de usuario. Estos
programas algunos funcionan con el robot y otros fueron
implementados únicamente bajo simulación. Los de manejo real son
los encargados de adquirir los datos de posición y orientación del
robot. Los de simulación se encargan como su nombre lo indica de
simular las estrategias de navegación debido a que estas no fueron
implementadas a causa de la falta de un sistema motriz en el robot.
En la cuarta parte se encuentra la explicación de las estrategias de
navegación y un análisis de los resultados obtenidos en la simulación,
además de ciertas consideraciones conceptuales a tener en cuenta en
la realización de dichas estrategias, entre las cuales cito textualmente
las que considero más importantes:
“Una buena estrategia de navegación debe permitirle al robot hacer
un recorrido inteligente por el cuarto sin pasar ningún inconveniente,
es decir sortear todos los obstáculos que el robot se pueda encontrar
en su camino y de esta forma encontrar la mayor cantidad de
información posible sin necesidad de recorrer centímetro a centímetro
todo el lugar”.
ISC-2003-1-47
71
“La estrategia de navegación en si no es una ruta ya trazada sino un
conjunto de criterios que le permite tomar decisiones al robot, para
lograr su objetivo, el de dar al usuario. Aunque si debe tener algún
punto en el que se acabe esta exploración porque sino seria un ciclo
infinito”.
En dicho trabajo se implementaron bajo simulación cuatro estrategias
de navegación. Antes hay que aclarar que los autores llaman
cartografía al proceso de construcción del mapa del ambiente a partir
de las mediciones hechas con el sensor de ultrasonido.
• Máxima Distancia: “A partir de un punto de partida se hacen
mediciones en diferentes direcciones y se busca cual es la mayor
distancia, entonces el robot se mueve en esa dirección una
distancia aleatoria entre 30 y 50 cm. (si puede) sino
recursivamente busca la distancia siguiente, cuando ya esta en el
nuevo punto realiza el mismo procedimiento”.
Según sus autores esta estrategia presenta el problema que el
robot se queda encasillado en el centro del cuarto y por eso no
visitará sitios desconocidos, además afirman: “Para obtener una
cartografía útil con este método es necesario que por cada
desplazamiento realice mediciones en todas las direcciones y así
obtener una mayor cantidad de información sobre el lugar, pero
aun así la información resulta insuficiente”.
• Movimiento Browniano: Esta estrategia plantea movimientos
completamente aleatorios tanto para la orientación, como para la
distancia a recorrer. Según sus autores “En la mayoría de los casos
no se obtendrá los resultados esperados ya que algunas veces
recorrerá gran parte del lugar, pero en otros casos puede quedarse
ISC-2003-1-47
72
en un área muy reducida del cuarto”. En mi opinión pienso que
esta afirmación depende del algoritmo que se use para generar los
valores aleatorios.
• Seguimiento de Pared:”Es mucho mas eficiente en el
reconocimiento de ambiente ya que por lo menos bordeará el
ambiente en el cual se encuentra el robot. Se implementó en este
caso seguimiento a la izquierda, pero se obtendrán los mismos
resultados con seguimiento a la derecha. Debido a que la toma de
decisiones en esta estrategia se hace con base en mediciones al
frente y a la derecha se podrán tener problemas si hay obstáculos
en el centro ó en el interior del ambiente, por esta razón se
decidió seguir la pared pero realizando mediciones en diferentes
direcciones.”
• Líneas Base: “Para esta estrategia se modela el ambiente con una
grilla en la que cada celda representa un área del ambiente, para
facilidad se toma como celda base el área del robot. Cada celda
puede tener tres valores 0, 1 ó 2 que indica si está vacía, si es
desconocida ó si está ocupada respectivamente. Con las
mediciones que se van obteniendo se va modificando un mapa para
saber porque sitios puede transitar el robot. La idea de la
estrategia implementada recursivamente es ir definiendo líneas
base, lo que me delimita regiones e ir bordeando estas mismas, en
busca de nuevas o con el fin de llegar a su punto final. Debido a
las características de dicha estrategia solo es necesario tomar
medidas a la izquierda y se obtiene una información del lugar muy
completa.”
ISC-2003-1-47
73
En la quinta parte se hace una descripción de los dos tipos de
cartografías implementadas:
• Cartografía puntual: La cual consiste en tomar las medidas
hechas por el sensor de ultrasonido conociendo de antemano la
posición y orientación desde donde fueron realizadas las
mediciones, respecto a un sistema de referencia, y de esta
manera localizar los obstáculos respecto al mismo sistema de
referencia.
• cartografía Histográmica: Está basada en el hecho de que cerca
de las paredes y obstáculos habrá una gran concentración de
puntos, la idea es manejar óptimamente dichas concentraciones
de puntos.
Observaciones relevantes:
• Debido a que las estrategias de navegación fueron
implementadas por simulación, no se conoce su impacto en un
sistema real.
• Debido a la carencia de locomoción del robot no se tiene en
cuenta la calibración de su sistema odométrico.
• No hay un proceso automatizado para la calibración del sensor
de ultrasonido.
• Desde el punto de vista de software, éste no posee una
documentación clara.
• Existe un proceso claramente segmentado acerca de cómo
abordar el problema.
• Presenta definiciones claras acerca de los resultados
esperados de una estrategia de navegación.
ISC-2003-1-47
74
Vale la pena mencionar que en nuestro medio no es fácil encontrar
bibliografía específica sobre este tema.
ISC-2003-1-47
75
4. PROBLEMA A RESOLVER Y PROPUESTA DE SOLUCION
4.1 Descripción General
El problema que se quiere resolver con el presente trabajo es diseñar
e implementar un sistema de software que aborde el problema de
reconocimiento de ambiente con un robot móvil real. Dicho problema
consiste en construir el mapa geométrico, correspondiente al espacio
de trabajo desconocido en el cual esta confinado un robot móvil
holonómico, a partir del análisis de la información sensorial provista
por el robot. Dicho mapa geométrico consiste en la ubicación en
coordenadas cartesianas de los objetos presentes dentro de la
frontera del espacio de trabajo del robot en un plano de dos
dimensiones.
4.2 Propuesta General De Solución
Para la solución de dicho problema me he basado en la estructura de
solución planteada en [15], la cual ha sido adaptada para este trabajo
de acuerdo a los recursos de hardware y software con que se cuenta
para la realización del mismo.
• Diseño de un robot móvil: Se diseñó un robot móvil, que de
acuerdo a los resultados experimentales obtenidos en la
medición de errores odométricos presentó los mejores
resultados. Una vez obtenido este diseño con la menor
propagación de errores posible se procedió a hacer la
ISC-2003-1-47
76
cuantificación y corrección de los errores con el fin de calibrar
el sistema odométrico del robot lo mejor posible.
• Calibración del sensor de ultrasonido: El procedimiento para la
cal ibración de este sensor se hizo experimentalmente,
detectando objetos convexos y cóncavos, superficies planas y
redondas a diferentes distancias y ángulos.
• Implementación de las Estrategias de navegación a utilizar: En
este caso se implementó la estrategia de escoger el camino más
largo.
• Construcción del mapa geométrico: Este se construye a partir
del análisis de la información provista por el sistema de
odometría y del sensor de ultrasonido con su respectivo manejo
de error de acuerdo a la correspondiente estrategia de
navegación.
La siguiente figura ilustra los diferentes aspectos considerados en
la solución propuesta:
ISC-2003-1-47
77
Figura 22. Problemas a resolver.
4.2.1 Diseño Del Robot Móvil
A continuación se pueden observar diferentes vistas del diseño del
robot con el cual se realizó las diferentes etapas experimentales de
este trabajo, en el anexo 5 se encuentra una foto real del robot. El
diseño está basado, en el modelo que se puede observar en la
referencia [16].
Dise
ño
Rob
ot m
óvi
l D
iseño
e
Imp
lem
en
tac
ión
SW
PRECISION MOVIMIENTOS
DISEÑO ODOMETRIA
ROBOT HOLONOMICO
CALIBRACION POSICION
ORIENTACION
CALIBRACION SENSOR
ULTRASONIDO
ESTRATEGIA DE
NAVEGACION
DESCRIPCION DE AMBIENTE
CONSTRUCCION MAPA
GEOMETRICO
EVALUACION ESTRATEGIA NAVEGACION
PRECISION DISTANCIAS A OBSTACULOS
ISC-2003-1-47
78
Figura 23. Diseño de la configuración del robot móvil.
El diseño del robot se hizo de acuerdo a los parámetros que se
requieren para la solución del problema. El principal requerimiento es
la alta precisión en los movimientos, para ello se buscó siempre tratar
de utilizar ruedas delgadas, esto con el fin de reducir el número de
puntos de contacto entre los bordes (externo e interno) de la rueda y
el piso. Otro aspecto que se tuvo en cuenta consistió en utilizar
piñones y ruedas con el mayor diámetro posible, con el objetivo de
lograr una velocidad tal que las ruedas del robot no resbalaran en el
piso. Y por último, otro aspecto relevante que se tuvo en cuenta, fue
el hecho de tratar de disminuir la fricción entre el eje en torno al cual
rotan las ruedas y la estructura que las sostiene. Para ello se tomó la
ISC-2003-1-47
79
decisión de sostener cada eje con una estructura a cada lado de la
rueda. Otro aspecto importante en el diseño del robot lo constituye la
plataforma sobre la cual rota el sensor de ultrasonido. Dicha
plataforma esta constituida por un motor y un simple sistema de
engranajes. Para controlar con precisión el número de vueltas del
motor no fue posible adaptarle un encoder debido a que el RCX no
disponía de un puerto de entrada disponible. Es por ello que se tomó
la decisión de controlar los movimientos del motor por medio de un
temporizador en el software de control, lo cual para este tipo de
robot produce mucho error, principalmente debido a la poca
uniformidad en el comportamiento de la carga de las baterías.
4.2.1.1 Descripción De La Odometría Del Robot
El primer aspecto a tener en cuenta para calibrar la odometría del
robot es calcular varios valores útiles de su morfología, que sirven
como parámetros para que el software de control del robot pueda
hacer movimientos más precisos. Anteriormente vimos que LEJOS
necesita de ciertos parámetros para configurar la clase
RotationNavigator (sección 3.3.2.1). A continuación se calculan estos
valores. Para calcular el valor radio, basta con hacer la relación de
número de dientes entre los piñones que se relacionan entre si. En la
figura 24 se puede observar la distribución de los piñones del
mecanismo que tiene el robot en cada una de sus ruedas. Los piñones
están marcados con diferentes letras, con el fin de hacer distinciones
entre ellos.
Los piñones A, C y E tienen 8 dientes, los B y D tienen 24 dientes y el
piñón F tiene 40 dientes. Las ruedas del robot giran en torno al
mismo eje de rotación del piñón F, el motor transmite el movimiento
ISC-2003-1-47
80
por el piñón A y el sensor de rotación recibe el movimiento por
intermedio del piñón C. Por ello llegamos a la siguiente relación cuya
unidad es el número de vueltas:
513113
FECDBA =====
53
FA =
FAC 11515 ==
Figura 24. Distribución de piñones.
Tres revoluciones completas del piñón A equivalen a 1 revolución del
piñón B, lo cual hace que le transmita la misma cantidad de
movimiento al piñón D y este a su vez al piñón C y E. Tres
revoluciones del piñón A hace que el piñón C haga también tres
revoluciones, y el piñón E haga entonces una revolución. El piñón E al
dar 5 vueltas hace que el piñón F haga una revolución completa; el
eje de rotación del piñón F es también el eje de rotación de las
A
B
C D
E
F
ISC-2003-1-47
81
ruedas. Por lo cual concluimos que 15 vueltas del motor (piñón A)
equivalen a una vuelta de las ruedas (piñón F) y a 15 vueltas del
sensor de rotación (piñón C), con lo cual deducimos que el valor del
parámetro ratio es 15 ya que 15 vueltas del motor equivalen a una
vuelta de la rueda.
El otro valor importante que sirve como parámetro para el software
es la distancia entre los puntos de contacto entre las ruedas y el piso.
En este caso se hizo la medición con un calibrador.
4.2.2 Calibración Y Est imación De Errores
La odometría es un método de navegación muy utilizado para el
posicionamiento de robots móviles. El principio fundamental de este
método consiste en la integración de la información de los
movimientos en forma incremental, lo cual hace que inevitablemente
se presenten errores. Los errores en orientación son los que más se
propagan, ya que estos crecen proporcionalmente con la distancia
recorrida por el robot.
Figura 25. Elipses de acumulamiento de error. [9]
Algunos investigadores han desarrollado algoritmos para estimar la
incertidumbre en la posición del robot calculada con ayuda de
encoders [9]. Con esta aproximación cada posición calculada tiene
ISC-2003-1-47
82
una elipse de error como se puede apreciar en la figura anterior.
Dicha elipse muestra la región de incertidumbre de la posición actual
del robot. Generalmente el área de estas elipses crece a través del
tiempo hasta que una medición absoluta de la posición reduce el
tamaño de esta elipse de incertidumbre. La técnica de estimación de
error utilizada se basa en los parámetros anteriormente calculados
para su utilización con el software de control del robot. Estos
parámetros solo tienen en cuenta los errores sistemáticos, debido a
que los errores no sistemáticos son impredecibles.
4.2.2.1 Medición De Los Errores De Odometría
Para la medición de estos errores se siguió el método propuesto en
[9] l lamado UMBmark (University of Michigan Benchmark). El método
aborda únicamente dos tipos de errores que son considerados como
dominantes:
• Error debido a la diferencia de diámetros de las ruedas.
LRd D / D =Ε
donde RD y LD son los diámetros de las ruedas derecha e izquierda
respectivamente, medidos antes del experimento.
• Error debido a la incertidumbre en la medición de la distancia
entre los puntos de contacto de cada una de las ruedas con el
suelo.
nominalactualb b / b E =
donde actualb es la distancia medida mediante el método que se expone
a continuación y nominalb es la distancia medida teóricamente. En este
caso se midió esta longitud con un calibrador. En la figura 26 se
puede observar la localización de este parámetro en el robot.
ISC-2003-1-47
83
Figura 26. Ubicación del parámetro nominalb en el robot.
(Vista inferior)
El método para reducir el error bE esta basado principalmente en la
idea de recorrer una trayectoria en forma de cuadrado, tanto en el
sentido de las manecillas del reloj como en sentido contrario. El robot
parte de una posición/orientación inicial conocida 0X , 0Y , 0θ . Dicha
posición es necesaria medirla respecto a algún marco de referencia lo
mas preciso posible, con el fin de que el método funcione mejor. El
robot debe ser programado para seguir la trayectoria definida por los
cuatro lados del cuadrado. Una vez completada una trayectoria
definida por el cuadrado se debe medir la posición absoluta del robot
nuevamente respecto al marco de referencia escogido. Estas
mediciones absolutas son comparadas con la posición y orientación
del vehículo calculados por el software de control del robot. Como
resultado de esta comparación nos queda un conjunto de valores de
error causados por la odometría del robot. Estos errores son
denotados de la siguiente manera:
calc- abs
Y-Y X-X
calc absy
calcabsx
θθθ =Ε
=Ε=Ε
nominalb =13,75 cm.
ISC-2003-1-47
84
Figura 27. Visualización del error de odometría. [9]
Donde xΕ , yΕ , θΕ representan los errores de posición y orientación
debidos a la odometría del robot. absX , absY , absθ representan la posición
y orientación absoluta del robot, es decir la posición medida respecto
al marco de referencia. calcX , calcY , calcθ Representan la posición y
orientación calculadas por la odometría del robot, en este caso esta
información es calculada por el software de control.
En este experimento se hicieron las mediciones en un cuadrado de 1
metro de lado, el cual se dibujó sobre papel junto con otro cuadrado
de 150 centímetros de lado, además de una grilla en centímetros para
facilitar las mediciones absolutas. La figura que se observa como un
asterisco en el centro se utilizó para calibrar los movimientos de
orientación, como se puede observar en la figura 28.
ISC-2003-1-47
85
Figura 28. Grilla utilizada para hacer las mediciones.
Según su autor para que el método entregue datos mas fiables toca
realizar el experimento al menos 5 veces en cada una de las
direcciones (en dirección de las manecillas del reloj: CW, y en
dirección contraria de las manecillas del reloj: CCW). Una vez
realizadas al menos 5 mediciones se procede a hallar el promedio de
las mediciones realizadas que el autor llama “centro de gravedad”,
pero en mi opinión lo que se halla es un centro geométrico de una
serie de medidas, ya que no se involucra la masa ni otras
características dinámicas del robot. Las ecuaciones para hallar dicho
centro geométrico se muestran a continuación con su notación
original:
• ∑=
Ε=n
icwxicwcg n
X1
,,1
y ∑=
Ε=n
icwyicwcg n
Y1
,,1
• ∑=
Ε=n
iccwxiccwcg n
X1
,,1
y ∑=
Ε=n
iccwyiccwcg n
Y1
,,1
100 cm.
150 cm.
ISC-2003-1-47
86
Donde n representa el número de mediciones hechas. La distancia
entre los dos centros de gravedad y el origen son dados por las
siguientes ecuaciones:
• 2,
2,, )()( cwcgcwcgcwcg YXr +=
• 2,
2,, )()( ccwcgccwcgccwcg YXr +=
El mayor valor entre cwcgr , y ccwcgr , es definido como “la medición de la
precisión odométrica para los errores sistemáticos” [9].
• );max( .,max, ccwcgcwcgsyst rr=Ε
Según sus autores la razón para no usar el promedio de los dos
centros de gravedad consiste en que para aplicaciones prácticas
únicamente se tiene en cuenta el error mayor. También vale la pena
mencionar que el error en orientación no es tenido en cuenta
explícitamente por la ecuación de estimación del error máximo, esto
es debido a que los errores sistemáticos en orientación se traducen
en errores de su posición final.
4.2.2.2 Calibración Odometría Del Robot
La aplicación de esta metodología para calibrar el robot hace que de
cierta manera se aborde el problema de reducir los errores
sistemáticos. Hay que tener en cuenta que es muy difícil llegar a un
funcionamiento perfecto de la odometría del robot porque hay muchas
ISC-2003-1-47
87
características que son difíciles de cuantificar como por ejemplo las
desviaciones geométricas de las partes del vehículo, etc.
Según la metodología expuesta en [9], la cal ibración del robot
requiere de la realización previa del UMBmark, ya que parte de sus
resultados.
Para seguir con el procedimiento, sus autores definen dos errores
característicos, los cuales tienen significado solo en el contexto del
UMBmark. Estos son llamados como Tipo A y Tipo B, que representan
errores en orientación. Los tipo A son definidos como errores de
orientación que reducen (o incrementan) la cantidad total de
rotaciones del robot mientras se realiza el UMBmark en las dos
direcciones. Los tipo B son definidos como errores de orientación que
reducen (o incrementan) el total de rotaciones del robot siguiendo la
trayectoria cuadrada en una sola dirección, pero incrementa (o
reduce) la cantidad de rotaciones cuando va en la otra dirección. La
figura 29 ejemplifica estos dos tipos de errores.
En ella se puede observar un ejemplo en el que el robot rota cuatro
veces una cantidad nominal de 90 grados por cada esquina. Sin
embargo el valor de la distancia entre los puntos de contacto de las
ruedas con el suelo es mayor que su valor nominal (error bE ), por ello
el robot únicamente rota un total de 4 X 85 grados = 340 grados, en
lugar de los 360 grados que se requieren, como se puede apreciar en
la figura 29a.
ISC-2003-1-47
88
Figura 29. Errores tipo A y tipo B, en dirección CCW y CW,
[9].
Se puede observar entonces que en las dos direcciones, el robot rotó
menos de la cantidad deseada. Entonces si nomiccwtotalnomicwtotal θθθθ <∧< ,,
el error es de tipo A y es denotado con la letra alfa (α ).
Por otro lado como se puede observar en la figura 29b se muestra la
trayectoria de un robot que tiene una diferencia entre los diámetros
de sus ruedas (error dΕ ). Este error se muestra en el ejemplo como
una trayectoria curva la cual le adiciona unos grados a la orientación
final del robot en dirección ccw, pero reduce en algunos grados la
ISC-2003-1-47
89
orientación final en la dirección cw. Es decir se cumple que
nomiccwtotal θθ >, pero nomicwtotal θθ <, , lo cual es llamado como error de
orientación tipo B y es denotado con la letra beta ( β ).
Estos dos tipos de errores ocurren generalmente al mismo tiempo.
Entonces el problema a resolver es como distinguir entre los errores
tipo A y tipo B y cómo calcular factores de corrección para las
pruebas hechas en el UMBmark.
A continuación se presentan expresiones para hallar α y β en grados
sexagesimales. Si se requiere mas detalles acerca de la derivación
geométrica de estas expresiones se sugiere consultar [9], de donde
fueron tomadas.
πα
o1804
,,
L
XX ccwcgcwcg
−
+=
πβ
o1804
,,
L
XX ccwcgcwcg
−
−=
donde L es la longitud del lado del cuadrado de prueba.
A partir de relaciones geométricas y con los valores anteriormente
calculados, se puede hallar el radio de curvatura R de la figura 29b,
con la siguiente ecuación:
)2/(2/
βSinL
R =
Luego a partir del valor calculado de R se puede determinar la
diferencia de radios entre las dos ruedas con la siguiente ecuación:
( )( )2/b
2/b
nominal
nominal
−+
==RR
DD
EL
Rd
Para calcular el error debido a la longitud entre los puntos de
contacto de las ruedas con el piso se utiliza la siguiente ecuación:
ISC-2003-1-47
90
α−=
o
o
9090
bE
Como nominalbactual
b
bE = se puede encontrar el valor de actualb con la expresión:
nominalactual b90
90 b
α−=
o
o
Una vez calculados los errores bE y dE se pueden utilizar estos valores
para corregir los parámetros que utiliza el software. Sin embargo en
nuestro caso solo se utilizará bE debido a que LeJOS solo permite
cambiar el parámetro actualb ya que asume que los diámetros de las
ruedas son iguales y solo se pasa un parámetro para las dos ruedas y
no por separado como seria lo ideal.
A continuación se muestra la aplicación del UMBmark al robot
utilizado en las experimentaciones de este proyecto. Como unidad
para hacer la medición de las coordenadas se usaron milímetros. Se
utilizó un cuadrado cuyo lado L mide 1 metro (1000 milímetros). Se
hicieron 6 mediciones en cada una de las direcciones cw y ccw. El
valor de nominalb para nuestro robot es 137,5 mm (figura 26).
Medición en sentido contrario a las manecillas del reloj ccw:
ccwx ,Ε ccwabs,X ccwCalc,X ccwy ,Ε ccwabs,Y ccwCalc,Y
31 31 0 32 32 0 2 2 0 -2 -2 0
-14 -14 0 9 9 0 -4 -4 0 14 14 0 -18 -18 0 7 7 0 -10 -10 0 3 3 0
-2,1667, =ccwcgX
ISC-2003-1-47
91
10,5000, =ccwcgY
10,7212, =ccwcgr
CCW
-5
0
5
10
15
20
25
30
35
-30 -20 -10 0 10 20 30 40
mm
mm
ccwy ,Ε
Figura 30. Errores en las posiciones absolutas en el sentido CCW.
Como se puede observar en la gráfica los puntos de llegada (de color
rojo), se dispersan alrededor del punto de partida que es la
coordenada (0,0). Sin embargo hay un punto con un grado de
dispersión mayor, esto puede ser debido no solo a los errores de
odometría sino también a errores en la posición y orientación del
robot en el punto de salida. El punto marcado con un triángulo azul
corresponde al centro geométrico de todos los seis puntos medidos
( ccwcgX , , ccwcgY , ).
ISC-2003-1-47
92
Medición en el sentido de las manecillas del reloj cw:
cwx ,ε cwabs,X cwCalc,X cwy ,ε cwabs,Y cwCalc,Y
-47 -47 0 35 35 0 -36 -36 0 37 37 0 -45 -45 0 35 35 0 -46 -46 0 45 45 0 -55 -55 0 52 52 0 -47 -47 0 44 44 0
-46,0000, =cwcgX
41,3333, =cwcgY
61,8421, =cwcgr
CW
0
10
20
30
40
50
60
-60 -50 -40 -30 -20 -10 0
mm
mm
Figura 31. Errores en las posiciones absolutas en el
sentido CW.
En la gráfica 31 se puede observar que los puntos de llegada (rojos)
tienen una tendencia a concentrarse en cierta región. El punto
marcado con un triangulo azul nos muestra el centro geométrico de
ISC-2003-1-47
93
estos puntos de llegada ( cwcgX , , cwcgY , ). Sin embargo dicho centro
geométrico se encuentra a una distancia considerable del punto de
partida ( 61,8421, =cwcgr mm.) por lo cual concluimos que el robot tiene
un error de odometría, sobre el cual se debe trabajar para tratar de
reducirlo.
Error sistemático máximo:
61.8421)8421.61,7212.10max(max, ==systE
Además si se tiene en cuenta que en circunstancias ideales dicho
error sistemático máximo debería ser muy aproximado a 0, con el fin
de que el robot llegue lo más cerca posible al punto de partida. A
continuación calculamos los siguientes parámetros para continuar con
el UMBmark:
°= 830,68993667α
°= 050,62786625β
mm 61619,16094=R
61,18560251=dE
mm 8138,562212=actualb
41,00772518=bE
474,6704850=LD
688,5295149=RD
Después de calcular estos valores, solo nos interesaría en nuestro
software de control el parámetro actualb . Sin embargo según los
cálculos, la diferencia entre el diámetro de las ruedas es muy grande.
ISC-2003-1-47
94
Luego de ajustar el parámetro actualb en el software de control del
robot, se procedió nuevamente a realizar el anterior procedimiento
para verificar que el error haya disminuido. A continuación se
muestran los resultados:
Medición en sentido contrario a las manecillas del reloj ccw:
ccwx ,ε ccwabs,X ccwCalc,X ccwy ,ε ccwabs,Y ccwCalc,Y
26 26 0 25 25 0 0 0 0 -6 -6 0 2 2 0 -5 -5 0 -2 -2 0 -3 -3 0 -5 -5 0 -5 -5 0 7 7 0 -3 -3 0
4,6667, =ccwcgX
0,5000, =ccwcgY
4,6934, =ccwcgr
ISC-2003-1-47
95
CCW
-10
-5
0
5
10
15
20
25
30
-10 -5 0 5 10 15 20 25 30
mm
mm
Figura 32. Error en las posiciones absolutas en sentido CCW, después de la corrección del error.
Medición en el sentido de las manecillas del reloj cw:
cwx ,ε cwabs,X cwCalc,X cwy ,ε cwabs,Y cwCalc,Y
-19 -19 0 8 8 0 -17 -17 0 36 36 0 -16 -16 0 12 12 0 -15 -15 0 5 5 0 -14 -14 0 5 5 0 -5 -5 0 10 10 0
-14,3333, =cwcgX
12,6667, =cwcgY
19,1282, =cwcgr
ISC-2003-1-47
96
CW
0
5
10
15
20
25
30
35
40
-20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0
mm
mm
Figura 33. Error en las posiciones absolutas en sentido CW, después de la corrección del error.
Error sistemático máximo:
19,1282)191282,6934.4max(max, ==systE
Como puede observarse las escalas de valores de los puntos de
llegada (puntos azules) tanto en la dirección ccw como en la cw
disminuyeron en sus dos dimensiones. En consecuencia los centros
geométricos en ambas direcciones (puntos marcados con triángulos
rojos) están mas próximos al punto de partida (0,0).
En definitiva se ve una reducción bastante significativa del error
sistemático máximo con el cambio de este parámetro en el software.
El error pasó de 61,8421mm a 19,1282 mm lo cual muestra una
reducción de un 69% aproximadamente. El error obtenido después de
la corrección pasó a ser el 30.9% del error original.
ISC-2003-1-47
97
Pienso que este error se podría reducir un poco más si se hace un
número mayor de mediciones ya que en este caso tan solo se
utilizaron seis. Además si se contara con un software que permitiera
manejar los parámetros de los diámetros de la ruedas por separado
también podría se podría reducir un poco más el error.
Recalco nuevamente la importancia de posicionar el robot
correctamente en su punto de partida. Con esto me refiero a que el
posicionamiento en la coordenada de partida sea lo mas exacta
posible en cada prueba, al igual que su orientación. En el caso del
robot utilizado en este trabajo, el posicionamiento se hizo de acuerdo
al centro de rotación del robot. Este punto no es más que la mitad de
la longitud de los puntos de contacto de las dos ruedas con el suelo.
Como ayuda para la correcta orientación del robot utilicé una brújula
adherida a él, además de las líneas de la grilla de prueba, que uso
como guía.
En este trabajo se ha omitido la corrección de errores no
sistemáticos, debido a que las pruebas se han realizado en un espacio
que no incluye obstáculos o muy poca rugosidad en el suelo. Sin
embargo para robots que se desenvuelvan en el mundo real se
necesita tener estos errores en cuenta. En [9] se puede encontrar
una metodología para abordar este tipo de errores.
4.2.2.3 Calibración Del Sensor De Ultrasonido
Hay que tener en cuenta ciertas complicaciones inherentes a la
interpretación de la información suministrada por el sensor de
ultrasonido. Si la cara frontal del sensor es paralela a la superficie del
objeto más cercano, y esta superficie es además plana y de un
material reflexivo y relativamente grande y rígido como por ejemplo
ISC-2003-1-47
98
un bloque de madera, entonces la información retornada por el sensor
puede interpretarse como la distancia al objeto más cercano en frente
del sensor. Sin embargo si el objeto se encuentra en condiciones
diferentes a las condiciones ideales anteriormente descritas, entonces
la interpretación del valor retornado puede ser un poco diferente,
debido a que tiene involucrado muy posiblemente un error. Las ondas
emitidas por el sensor se confinan en forma de un cono de
aproximadamente 30 grados. Sin embargo ese frente de onda que se
forma no tiene una forma perfectamente cónica, lo que complica un
poco mas las cosas.
Figura 34. Forma aproximada del frente de onda emitido
por un sensor de ultrasonido [17].
En la figura 34 la curva más oscura representa los equipotenciales del
nivel de energía del sonido.
ISC-2003-1-47
99
Figura 35. Falta de precisión en las medidas realizadas
por el sensor de ultrasonido [17].
En la figura 35 se muestra un ejemplo en la inexactitud de las
medidas. La línea roja representa la distancia al muro, que es la que
queremos medir. Sin embargo la distancia medida por el sensor es la
representada por la línea azul. Esto es causado por la siguiente
razón: como bien sabemos el cono de la onda es de aproximadamente
30 grados, entonces en este caso el ángulo de incidencia de la onda
como no es perpendicular, cierta parte del frente de onda hace
contacto con el muro en el punto azul debido a que se encuentra más
cerca.
Figura 36. No hay reflejo de la onda en el sensor [17].
ISC-2003-1-47
100
En la figura 36 se puede observar otro caso especial a tener en
cuenta. Esta vez la onda emitida desde el sensor no es reflejada hacia
el mismo. En este caso el sensor nos entregaría información errónea,
debido a que retornaría el máximo valor posible, que como se dijo
anteriormente este valor es de 142,24 cm. Interpretando este valor
creeríamos que a esa distancia hay un obstáculo, lo cual seria
erróneo, ya que el obstáculo se encuentra mas cerca. Por ello se hace
necesario que se hagan mediciones desde diferentes puntos a
diferentes ángulos y distancias a los mismos obstáculos con el fin de
confirmar la información proveniente del sensor. Este caso aplica
también para las superficies convexas, que no permiten que el reflejo
de la onda llegue de nuevo al sensor.
Figura 37. Reflejo de la onda en una superficie cóncava
[17].
En el caso del reflejo de la onda en superficies cóncavas el caso
también es bastante particular. Esta vez la onda si se refleja de
nuevo en el sensor emisor, pero recorre un trayecto adicional, lo cual
hace que se demore mas tiempo en llegar al sensor de nuevo
teniendo como consecuencia una medición sobreestimada de la
distancia hacia el obstáculo, como se puede observar en la figura 37.
Por estas razones se hace necesario un proceso de calibración previa
del sensor, para conocer el comportamiento de este frente a los
diferentes tipos de obstáculos a diferentes posiciones y ángulos.
ISC-2003-1-47
101
Para esta tarea de calibración se diseño la siguiente grilla (figura 38):
Figura 38. Grilla utilizada en la calibración del sensor de
ultrasonido.
La grilla tiene unas dimensiones de 150 centímetros de largo por 90
centímetros de ancho. Esta tiene dibujadas una serie de semicírculos
concéntricos cuyo radio se incrementa en 5 centímetros, desde los 15
centímetros hasta los 150 centímetros. Adicionalmente los
semicírculos se encuentran divididos con líneas rectas que parten del
centro, separadas cada una de la otra a un ángulo de 15 grados. De
esta manera se asemeja un poco al sistema de coordenadas polares.
Para realizar las pruebas el sensor se colocaría en el centro de los
semicírculos. Los objetos u obstáculos a probar serian colocados en
cada una de las coordenadas (intersecciones entre los semicírculos y
las rectas) que se pueden observar en la figura 38. A partir de ahí se
150 cm.
90 cm.
ISC-2003-1-47
102
comparan los valores medidos por el sensor, con los valores absolutos
que obtenemos a partir de la grilla y de esta manera tratar de estimar
el comportamiento particular del sensor con cada objeto.
A continuación se describen las pruebas hechas con el fin de conocer
el comportamiento de los valores que nos da el sensor, con objetos
de diferentes formas.
4.2.2.3.1 Mediciones A Objetos Planos
Como objeto plano se utilizó una caja de cartón cuya superficie
frontal (la que se espera refleje la señal emitida por el sensor) tiene
unas dimensiones de 25.2 centímetros de alto por 10 centímetros de
ancho. Dicho objeto se colocó en cada coordenada dibujada en la
grilla de prueba, orientada siempre en dirección del sensor, es decir
en el centro de las semicircunferencias. La co lumna de la izquierda
muestra el valor de las distancias absolutas a las que se colocó el
objeto, las cuales están medidas en centímetros. De esta manera en
cada fila se agrupó la información de las variaciones en la medición
de las distancias medidas por el sensor a una misma distancia y
variando únicamente el ángulo al cual se encuentra el objeto respecto
al sensor, el cual se encuentra entre -15 y 15 grados sexagesimales.
Las celdas en blanco nos indican que en esa respectiva distancia y
ángulo, el sensor no pudo detectar el objeto.
Luego de hacer las mediciones se obtuvieron los siguientes
resultados:
ISC-2003-1-47
103
o15- o0 o15 o15-∆ o0∆ o15∆ MEDIA VARIANZA
ERROR MAX
0 5
10 15,24 15,24 15 15,24 15,24 15,24 0,24 0,24 0,24 0,24 0,00 0,2 20 20,32 20,33 22,86 0,32 0,33 2,86 1,17 1,43 2,9 25 27,94 25,40 27,90 2,94 0,40 2,90 2,08 1,41 2,9 30 33,08 30,48 33,02 3,08 0,48 3,02 2,19 1,47 3,1 35 35,56 35,56 38,01 0,56 0,56 3,01 1,38 1,33 3,0 40 40,64 40,65 43,18 0,64 0,65 3,18 1,49 1,43 3,2 45 45,72 45,72 48,26 0,72 0,72 3,26 1,57 1,43 3,3 50 50,80 50,80 53,34 0,80 0,80 3,34 1,65 1,43 3,3 55 55,87 55,87 55,87 0,87 0,87 0,87 0,87 0,00 0,9 60 60,96 60,96 63,50 0,96 0,96 3,50 1,81 1,43 3,5 65 66,04 66,04 66,04 1,04 1,04 1,04 1,04 0,00 1,0 70 71,11 71,11 71,11 1,11 1,11 1,11 1,11 0,00 1,1 75 76,20 76,20 76,20 1,20 1,20 1,20 1,20 0,00 1,2 80 81,28 81,28 81,28 1,28 1,28 1,28 1,28 0,00 1,3 85 86,36 86,36 86,36 1,36 1,36 1,36 1,36 0,00 1,4 90 91,44 91,44 91,44 1,44 1,44 1,44 1,44 0,00 1,4 95 96,52 96,52 96,52 1,52 1,52 1,52 1,52 0,00 1,5
100 101,60 101,60 101,60 1,60 1,60 1,60 1,60 0,00 1,6 105 106,68 106,68 106,68 1,68 1,68 1,68 1,68 0,00 1,7 110 111,75 111,75 111,75 1,75 1,75 1,75 1,75 0,00 1,8 115 116,84 116,84 116,84 1,84 1,84 1,84 1,84 0,00 1,8 120 121,92 121,92 121,92 1,92 1,92 1,92 1,92 0,00 1,9 125 124,46 124,46 127,00 -0,54 -0,54 2,00 0,31 1,43 2,0 130 129,54 129,54 132,00 -0,46 -0,46 2,00 0,36 1,34 2,0 135 134,62 134,62 137,16 -0,38 -0,38 2,16 0,47 1,43 2,2 140 142,24 142,24 142,24 2,24 2,24 2,24 2,24 0,00 2,2 145 150
Figura 39. Medidas obtenidas por el sensor de ultrasonido.
ISC-2003-1-47
104
Objeto Plano
10 10 10 1015
15 15 15
2020 20
2020
25 2525
25
3030
3030
35 3535
4040 40
4045
45 4545
5050 50
50 5055
55 55 5560 60
6065 65 65
6570 70 70
7075 75 7580 80 8085 85 8590 90 9095 95 95100 100 100105 105 105110 110 110115 115 115120 120 120125 125
125130 130
130135 135
135140 140 140
05
101520253035404550556065707580859095
100105110115120125130135140145150
-30 -15 0 15 30
Angulo en Grados
Dis
tanc
ia e
n cm
Figura 40. Gráfica de las medidas hechas a objetos
planos.
En la tabla de datos las columnas marcadas de color azul, se
encuentra la diferencia entre cada medición del sensor con su
respectiva medida absoluta. Dicha diferencia nos indica el valor del
ISC-2003-1-47
105
error para cada medición. En la siguiente columna se encuentra
calculado el promedio o media de dicho error. En la siguiente columna
se encuentra calculada la varianza para cada distancia. Y por ultimo
se encuentra la medición del error máximo para cada medición.
Los valores que se encuentran sobre cada curva en la gráfica son los
que representan las mediciones hechas por el sensor.
En la figura 40 adicionalmente se puede observar que se hace
referencia a mediciones hechas entre -30 y 30 grados. Dichos valores
se descartaron debido a que aumentaba la dispersión de las medidas
en cada distancia, y además como se dijo anteriormente el cono de
acción del sensor tan solo tiene 30 grados, es decir entre el intervalo
[-15 grados,15 grados]. En la gráfica se puede ver que el objeto se
ve “plano” por parte del sensor generalmente en este intervalo
(principalmente entre las distancias [55cms ,120cms]), ya que en los
intervalos [-30 grados, -15 grados] y [15 grados, 30 grados] se ven
algunas desviaciones.
En el software implementado se tuvo en cuenta los valores de error
máximo para cada distancia y no su promedio, esto con el fin de
evitar al máximo posibles colisiones con los obstáculos. Para ello toca
tener en cuenta el valor del error máximo en cada distancia, debido a
que estos valores no tienen un comportamiento uniforme.
ISC-2003-1-47
106
4.2.2.3.2 Mediciones Con Objetos Cilíndricos
o15- o0 o15 o15-∆ o0∆ o15∆ VARIANZA
ERROR MAX MEDIA
0 5
10 15,24 15,24 15,24 5,24 5,24 5,24 0,00 5,2 5,24 15 17,78 17,78 17,78 2,78 2,78 2,78 0,00 2,8 2,78 20 22,86 22,86 22,86 2,86 2,86 2,86 0,00 2,9 2,86 25 27,94 27,94 30,48 2,94 2,94 5,48 1,43 5,5 3,79 30 33,02 33,02 35,56 3,02 3,02 5,56 1,43 5,6 3,87 35 38,10 38,10 40,64 3,10 3,10 5,64 1,43 5,6 3,95 40 45,72 43,18 45,72 5,72 3,18 5,72 1,43 5,7 4,87 45 48,26 48,26 50,80 3,26 3,26 5,80 1,43 5,8 4,11 50 53,34 3,34 0,00 3,3 3,34 55 60,96 5,96 0,00 6,0 5,96 60 63,50 3,50 0,00 3,5 3,50 65 68,58 3,58 0,00 3,6 3,58 70 73,66 3,66 0,00 3,7 3,66 75 142,24 67,24 0,00 67,2 67,24 80 86,36 6,36 0,00 6,4 6,36 85 88,90 3,90 0,00 3,9 3,90 90 93,98 3,98 0,00 4,0 3,98 95
100 Figura 41. Medidas obtenidas por el sensor de
ultrasonido.
Las mediciones se hicieron con un objeto cilíndrico metálico de 10.2
cm. de diámetro y 23 cm. de altura. Entre los 15 cm. y los 50 cm. de
distancia se puede observar que el sensor detecta el objeto
parcialmente entre los o15− y los o15 , pero a partir de los 50 cm. de
distancia solo es detectado si esta frente a él, es decir a los 0 grados.
Además a partir de los 100 cm. de distancia no es detectado a ningún
ángulo. De acuerdo con las figuras 42 se puede confiar en las
medidas obtenidas entre el intervalo [10cm. , 45 cm.] en un rango de
orientaciones [ oo 15,15− ]
ISC-2003-1-47
107
Objeto Cilindrico
10 10 10 10 1015 15 15
20 20 20
25 2525
30 3030
35 3535
4040
4045 45
4550
5560
65
70
8085
90
0
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
-30 -15 0 15 30
Angulo en grados
dis
tan
cia
en c
m
Figura 42. Grafica de las medidas hechas a objetos
cilíndricos.
ISC-2003-1-47
108
4.2.2.3.3 Mediciones Con Objetos Convexos
o15- o0 o15 o15-∆ o0∆ o15∆ VARIANZA
ERROR MAX MEDIA
0 5
10 15,24 15,24 5,24 5,24 0,00 5,2 5,24 15 17,78 119,38 2,78 104,38 2580,64 104,4 53,58 20 25,40 124,46 5,40 104,46 2453,22 104,5 54,93 25 134,62 127,00 109,62 102,00 14,52 109,6 105,81 30 139,70 109,70 0,00 109,7 109,70
Figura 43. Medidas obtenidas por el sensor de ultrasonido.
Objeto Convexo
10 1015
15
20
20
25
25
30
05
101520253035404550556065707580859095
100105110115120125130135140145150
-15 0 15
Angulo en grados
Dis
tan
cia
en c
m
Figura 44. Gráfica de las medidas hechas a objetos
convexos.
ISC-2003-1-47
109
Como objeto convexo se utilizó una esquina convexa o “vista desde
afuera”, (no confundir con una esquina cóncava o “vista desde
adentro” como se puede observar en la figura 37 la cual como su
nombre lo indica describe una concavidad). Como se puede observar,
experimentalmente con este tipo de sensor en muy difícil detectar
este tipo de objetos, solo basta con observar la gran magnitud de la
dispersión de los datos y las cantidades de error en un rango tan
pequeño de distancias a los cuales es detectado el objeto. Este
aspecto puede traernos bastantes consecuencias, debido a que un
objeto con caras planas desde algún punto de vista se podrá ver
como una esquina convexa. Por ello se tomo la decisión de
experimentar con un ambiente en el cual las caras planas que forman
los objetos y sus paredes sean paralelos o perpendiculares entre si,
con el fin de evitar al máximo la detección de esquinas convexas.
ISC-2003-1-47
110
4.2.2.3.4 Mediciones Con Objetos Cóncavos
o15- o0 o15 o15-∆ o0∆ o15∆ VARIANZA
ERROR MAX MEDIA
0 5
10 15,24 15,24 15,24 5,24 5,24 5,24 0,00 5,2 5,24 15 15,24 15,24 15,24 0,24 0,24 0,24 0,00 0,2 0,24
20 15,24 17,78 17,78 -4,76 -
2,22 -2,22 1,55 4,8 -3,07 25 20,32 25,40 20,32 -4,68 0,40 -4,68 6,19 4,7 -2,99 30 22,86 30,48 25,40 -7,14 0,48 -4,60 8,77 7,1 -3,75 35 35,56 35,60 38,10 0,56 0,60 3,10 24,31 3,1 1,42 40 40,64 40,64 33,02 0,64 0,64 -6,98 27,35 7,0 -1,90 45 35,56 45,72 38,10 -9,44 0,72 -6,90 19,10 9,4 -5,21 50 38,10 50,80 40,64 -11,90 0,80 -9,36 28,39 11,9 -6,82 55 43,18 55,88 58,42 -11,82 0,88 3,42 59,35 11,8 -2,51 60 45,72 63,50 63,50 -14,28 3,50 3,50 141,94 14,3 -2,43 65 50,80 66,04 68,58 -14,20 1,04 3,58 126,34 14,2 -3,19 70 73,66 71,12 73,66 3,66 1,12 3,66 2,15 3,7 2,81 75 78,74 78,74 81,28 3,74 3,74 6,28 2,15 6,3 4,59 80 83,82 83,82 83,82 3,82 3,82 3,82 0,00 3,8 3,82 85 88,90 88,90 3,90 3,90 0,00 3,9 3,90 90 93,98 91,44 3,98 1,44 1,61 4,0 2,71 95 99,06 99,06 4,06 4,06 0,00 4,1 4,06
100 101,60 104,14 1,60 4,14 1,61 4,1 2,87 105 109,22 109,22 4,22 4,22 0,00 4,2 4,22 110 114,30 114,30 4,30 4,30 0,00 4,3 4,30 115 119,38 119,38 4,38 4,38 0,00 4,4 4,38 120 124,46 121,92 4,46 1,92 1,61 4,5 3,19 125 129,54 4,54 0,00 4,5 4,54 130 134,62 4,62 0,00 4,6 4,62 135 139,70 4,70 0,00 4,7 4,70 140 142,24 2,24 0,00 2,2 2,24 145 150
Figura 45. Medidas obtenidas por el sensor de ultrasonido.
ISC-2003-1-47
111
Objeto Concavo
10 10 10 10 1015 15 15 15 1520 2020 20 2025
25
25
25 2530 30
30
3030
35
35 3535
3540
40 40
4040
4545
45
454550
50
50
505055
55
5555
55
60
60
60 60
65
65
6565
7070
70
75 7575
80 80 80
85 85
9090
95 95100
100
105 105
110 110
115 115
120120
125
130
135140
0
5
10
15
20
25
30
35
40
45
50
55
60
65
70
75
80
85
90
95
100
105
110
115
120
125
130
135
140
145
150
-30 -15 0 15 30
Angulo en grados
Dis
tanc
ia e
n cm
Figura 46. Grafica de las medidas hechas a objetos
cóncavos.
ISC-2003-1-47
112
Como objeto cóncavo, se utilizó la misma esquina convexa, pero en
este caso la parte enfrentada al sensor es el vértice que describe la
concavidad (figura 37). Este caso también es muy frecuente en el
ambiente que pensamos reconocer, debido a que se escogieron
paredes perpendiculares entre si que describen una esquina cóncava.
Para las mediciones experimentales el vértice se ubicó siempre en los
puntos de intersección de la grilla de prueba y orientado siempre en
dirección hacia el sensor (origen de la grilla). En esta ocasión el
sensor pudo detectar el vértice de dicha esquina casi el la mayoría de
las distancias a 0 grados. A los -15 y a los 15 grados se puede
observar que no hay uniformidad en los valores observados, ya que
fluctúan mucho, algunas veces por exceso y otras veces por defecto.
Este fenómeno parece ser producido porque los transductores (tanto
el emisor como el receptor) están posicionados en diferentes lados
del sensor. Algunas veces es más común encontrar sensores cuyos
transductores están posicionados en la misma parte. En cuanto a las
restricciones del ambiente a las que nos hemos referido, en un
principio se tendrá en cuenta solo objetos con caras planas y
paralelas y/o perpendiculares a las paredes del ambiente, por lo cual
esperamos que el robot también se dirija bajo estos mismos
parámetros: paralela o perpendicularmente a los objetos y paredes
del ambiente. Observando más cuidadosamente desde este punto de
vista, las mediciones hechas a las esquinas cóncavas no se tendrían
muy en cuenta porque estas esquinas no se detectarían haciendo
mediciones al vértice sino haciendo mediciones perpendicularmente a
las dos paredes que la componen. Sin embargo se hizo las mediciones
porque pueden ser útiles en el caso en que no se consideren el tipo
de restricciones antes mencionadas.
ISC-2003-1-47
113
4.2.3 Software
El software implementado, tiene dos componentes principales. La
primera componente la constituye el software que se ejecuta en el
robot. Este software fue desarrollado en leJOS, bajo ambiente
Windows XP. El segundo componente fue desarrollado en JAVA con el
IDE Netbeans versión 3.4 también bajo el ambiente Windows XP,
utilizando las librerías estándar de JAVA2D y la librería de
comunicaciones JAVA para leJOS principalmente.
Estas componentes de software relacionan los elementos
anteriormente estudiados aplicando los resultados hasta aquí
obtenidos.
4.2.3.1 Descripción Y Funcionamiento Del Sistema
Desde el punto de vista de flujo de datos entre el robot y la máquina
host, los datos que se intercambian son los siguientes:
Figura 47. Flujo de datos entre los dos componentes de
software.
En la figura 47 se observa que la máquina host le envía al robot una
coordenada (x,y) en centímetros o bien un ángulo en grados y una
distancia (d,?). Esta coordenada es leída por el puerto del robot, el
cual la interpreta y hace los movimientos necesarios para alcanzar
Máquina Host (Java) (GUI)
(pcrcxcomm.jar)
(x,y) ó (d,?)
(x,y) y ( )54,321 ,,, ddddd
ROBOT (LeJOS)
ISC-2003-1-47
114
dicha posición. Si el robot recibió el par ángulo-distancia, el robot
primero rota el ángulo indicado y luego recorre la distancia recibida.
El software del robot está compuesto básicamente por 3 tareas que
ejecuta una seguida de otra. La primera tarea consiste en rotar el
sensor de ultrasonido y hacer las 5 mediciones ( ooooo 90,45,0,45,90 −− ) en
la posición respectiva. La segunda consiste en enviar esas 5
mediciones al host ( )54,321 ,,, ddddd , y la tercera consiste en leer el par
de coordenadas ó el par ángulo-distancia y realizar los movimientos
respectivos. El diagrama de la clase que ejecuta el robot se puede
observar en el anexo 3.
El host recibe del robot la información actualizada de su posición
(x,y), al igual que la información proveniente del sensor, que consiste
en las medidas tomadas desde el sensor rotado respecto a la posición
actual del robot ooooo 90,45,0,45,90 −− respectivamente ( )54,321 ,,, ddddd . El
software que se ejecuta desde el host requiere de un parámetro
inicial, el cual es preguntado al usuario. Dicho parámetro es el
número de posiciones del robot desde las cuales se realizaran las
medidas sobre el ambiente. El diagrama de clases del software que se
ejecuta desde el host se puede observar en el anexo 4. Una vez el
programa cuenta con la información proveniente del robot, se
procede ha desplegarla gráficamente, en forma de arcos de 30 grados
que representan el área en la que el sensor puede obtener datos con
cierto grado de precisión. Esta información es analizada para tomar la
decisión siguiente, la cual consiste en enviarle una coordenada o un
par ángulo-distancia, a donde se desea que el robot cambie su
posición. Esta decisión la toma el algoritmo encargado de la
estrategia de navegación. En el primer caso se implementó la
estrategia que envía coordenadas (x,y) aleatoreamente sin tener en
cuenta los datos provenientes del robot. La otra estrategia que se
ISC-2003-1-47
115
implementó consiste en escoger el camino más largo que el robot
pueda seguir sin colisionar con algún obstáculo, en este caso es
cuando se le envía al robot el par ángulo-distancia.
Una vez se tengan los datos de las posiciones, el software procede a
desplegar el mapa de las áreas libres de colisión. Este mapa es
calculado por geometría constructiva, que en este caso consiste en
hacer la unión de las áreas libres de colisión que como se dijo
anteriormente son representadas por arcos. Una vez construido el
mapa, se calcula el rectángulo envolvente más pequeño para así tener
una aproximación de las dimensiones del mapa que representa el
ambiente. Para la implementación del software todos los cálculos
fueron realizados respecto al sistema de coordenadas del robot, cuyo
origen es el punto de partida del robot antes de hacer cualquier
movimiento. Para el despliegue de la información en pantalla, es decir
tanto la información proveniente del sensor como para el mapa
calculado, se utilizaron transformadas geométricas homogéneas en 2D
para llevar puntos del sistema de coordenadas del robot al sistema de
coordenadas de los componentes de JAVA2D, pero para el usuario
esto es transparente porque el sistema de coordenadas desplegado en
el panel representa el origen del sistema de coordenadas del robot. A
continuación se puede observar la interfaz gráfica de la aplicación.
ISC-2003-1-47
116
Figura 48. Interfaz gráfica de la aplicación
implementada.
La interfaz gráfica está compuesta por dos paneles principales. Como
se puede observar en la figura 48, en uno se despliegan los datos
provenientes del robot (lado derecho), y en el otro se despliega el
mapa calculado (lado izquierdo). Para empezar a usar la aplicación
hay que escoger la opción de los datos con los que se quiere
construir el mapa, esto se hace escogiendo la opción “Todo” ó la
opción “Perpendicular”. Con la opción Todo se tiene en cuenta las
cinco distancias enviadas por el robot en la estrategia de navegación.
Si se escoge la opción Perpendicular únicamente se tienen en cuenta
3 de los 5 valores, es decir los que están a -90, 0 y 90 grados. Los
otros dos valores se descartan debido a que las medidas no son
confiables, como se observó en el proceso de calibración del sensor
de ultrasonido (sección 4.2.2.3). En la parte derecha se puede
ISC-2003-1-47
117
escoger la estrategia que se quiere siga el robot para sus
desplazamientos. Una vez escogida la estrategia se activa el botón
que empieza a ejecutar el algoritmo de comunicación con el robot y
así empezar el intercambio de datos. Si se quieren observar los datos
enviados por el robot numéricamente, estos se pueden visualizar
escogiendo la opción recorrido. Los datos son desplegados en los
paneles una vez finalice la comunicación con el robot.
4.2.4 Pruebas Experimentales
En esta sección se hace una evaluación de los mapas elaborados por
el sistema. El ambiente utilizado para la experimentación puede
observarse en la figura 49 y en el anexo 6. Los cuadrados rellenos de
negro representan los dos obstáculos, los cuales tienen. Los ejes
coordenados verdes representan la posición/orientación del robot
para cada prueba, de modo que el frente del robot está coincide con
el eje X y las ruedas coinciden con el eje Y. Dicho ambiente que se
utilizará como prueba tiene varias restricciones. Las paredes de los
obstáculos siempre serán paralelas a las paredes del robot, con el fin
de que puedan ser detectados por el sensor de ultrasonido. La otra
restricción es impuesta a los movimientos del robot, el cual solo
podrá hacer giros en ángulos múltiplos de 90 grados, con el fin de
que los objetos y paredes puedan ser detectados. El ambiente que se
utilizó para probar tiene 2 obstáculos cuadrados de 25 cm. de lado,
ambos están colocados a 40 cm. de las paredes, tal y como lo indica
la figura 49. La experimentación se hizo utilizando únicamente la
información en ángulos de 90 grados (opción perpendicular) y la
estrategia de la distancia mas larga.
ISC-2003-1-47
118
Figura 49. Ambiente de prueba.
La primera prueba se hizo con el robot partiendo en la coordenada
denotada en la figura 49 como 1, y utilizando como parámetro de
número de coordenadas a visitar 5. El mapa calculado por el sistema
se puede observar en la figura 50. En éste se puede observar que la
parte central del ambiente reconocido hay un obstáculo muy grande,
que al compararlo con el ambiente original representa el cuadrado
envolvente de los dos obstáculos aproximadamente. En cuanto a las
medidas calculadas del rectángulo envolvente se nota una diferencia
apreciable respecto a las medidas reales. Esto puede deberse a que
las paredes del ambiente real no son del todo rígidas y perfectamente
perpendiculares entre si, ya que tienen cierto nivel de curvatura. El
principal aspecto que vale la pena destacar lo constituye el que las
medidas de los lados del rectángulo calculado son iguales, tal y como
lo es en realidad.
150 cm.
25cm
25cm
25cm
25cm
40 cm.
40 cm.
40 cm.
40 cm.
12
18.5 cm. 25 cm.
25 cm.
3
50 cm.
50 cm.
16.5 cm.
X
Y
X
YX
Y
150 cm.
ISC-2003-1-47
119
Figura 50. Mapa calculado por el sistema en la primera
prueba.
Como segundo experimento se situó el robot en el punto marcado
como 2, en la figura 49, el cual esta ubicado a 25 cm. de las dos
paredes mas cercanas. El mapa correspondiente a esta segunda
prueba se encuentra en la figura 51. Se puede observar que el mapa
es bastante parecido al anterior, con la diferencia que esta vez las
medidas aumentaron un poco más, lo cual confirma que la curvatura
de las paredes afecta significativamente las medidas del sensor,
aumentando su nivel de error. En cuanto a la forma del mapa, es muy
parecida lo cual nos indica que obtuvimos casi la misma información
desde estas dos posiciones.
ISC-2003-1-47
120
Figura 51. Mapa calculado por el sistema en la segunda
prueba.
En la tercera prueba el robot parte del punto marcado como 3 en la
figura 49, el cual se encuentra a 50 cm. de las paredes. Al partir
desde esta posición hace un recorrido un poco diferente a los
anteriores, lo cual nos muestra un poco mas de información que en
las dos pruebas anteriores, ya que hay un poco más de detalles si se
compara con el ambiente original. El aporte mas importante que nos
da esta prueba son las medidas del rectángulo envolvente, las cuales
son mucho mas precisas que en las ocasiones anteriores. En la figura
52 se puede observar que las medidas están alrededor 160 cm.
aproximadamente, lo cual nos lleva a deducir que la posición desde
donde se hagan las medidas hace que se tenga mejor calidad en la
información.
ISC-2003-1-47
121
Figura 52. Mapa calculado por el sistema en la tercera
prueba.
Para la cuarta prueba la posición inicial fue la misma que en la
prueba 3, pero ahora se van ha visitar 7 puntos diferentes en lugar
de los 5 que se hicieron anteriormente. Los resultados se pueden
apreciar en la figura 53. Esta vez se hacen un poco mas notables las
deficiencias de la estrategia de navegación, debido a que así se
aumente el número de coordenadas a visitar, no aporta mas
información debido a que siempre tiende a irse por la misma ruta.
Esto implica además que el error en odometría del robot aumente, al
aumentar el número de puntos visitados, lo cual tiene implicaciones
en la confiabilidad de la coordenada de origen de las medidas.
ISC-2003-1-47
122
Figura 53. Mapa calculado por el sistema en la cuarta
prueba.
Como última prueba se retiraron los obstáculos del ambiente, y se
visitaron 10 coordenadas partiendo del centro del habitáculo. La
figura 54 muestra el mapa calculado. Esta vez si aportó más
información el hecho de visitar un mayor número de coordenadas.
Como se puede observar la mayoría del área es pintada como área
libre de colisión. Las medidas desplegadas aparecen un poco
sobreestimadas respecto al ambiente real, pero si observamos
cuidadosamente estas medidas se deben a las esquinas de los arcos
que son puntos extremos, las cuales en cada lado también tienen un
punto extremo mínimo el cual refleja datos más precisos. La parte
central sin embargo no es visitada, nuevamente se evidencia un poco
las limitaciones de la estrategia implementada.
ISC-2003-1-47
123
Figura 54. Mapa calculado por el sistema en la quinta
prueba.
ISC-2003-1-47
124
5. CONCLUSIONES Y TRABAJOS FUTUROS
5.1 Conclusiones
La solución del problema de reconstrucción de ambientes para robots
móviles debe incluir unas fases de análisis, diseño y evaluación de la
estructura del robot y su relación con los sensores (odometría).
Se puede afirmar que la técnica de calibración de la odometría del
robot hizo que el robot mejorara bastante la precisión en sus
movimientos, lo cual implica mejoras en el desempeño general del
sistema.
En el caso del sensor de ultrasonido se puede afirmar que es
impreciso y funciona en condiciones muy ideales, lo que limita el
trabajo con este tipo de sensor.
El éxito de la técnica de navegación depende de la calidad y
confiabilidad de los datos adquiridos por los sensores. En el caso de 1
sensor de ultrasonido tiene muchas limitaciones.
La técnica utilizada para construir el mapa geométrico muestra
buenos resultados, aunque nuevamente la dependencia con los datos
capturados por el sensor de ultrasonido hace que se dificulte la
evaluación de dicha técnica de una manera más objetiva.
El API de JAVA 2D, es una buena opción para trabajar con gráficas,
gracias a que es a alto nivel y con funciones avanzadas que son
ISC-2003-1-47
125
fácilmente extensibles. Además gracias a las librerías Java existentes
que facilitan la comunicación de información con el RCX (LeJOS) hace
que se pueda desarrollar proyectos en robótica móvil con alto grado
de procesamiento de información.
LeJOS es un API de programación del robot bastante sencillo de
utilizar y con la funcionalidad requerida para trabajar en robótica
móvil. Este API además es extensible lo que amplia las posibilidades
al usuario.
El kit de robótica Lego® Mindstorms es una buena herramienta para
el aprendizaje de los conceptos básicos de la robótica. Sin embargo
para proyectos que exijan alto nivel de precisión este kit no es una
buena opción debido a la gran cantidad de limitaciones que éste
presenta.
5.2 Trabajos Futuros
En esta área de la robótica móvil se puede investigar en cualquiera de
los aspectos aquí tratados, ya que estos fueron tratados con cierto
grado de generalidad. Por ejemplo respecto a las técnicas de
corrección de error de odometría por software se podría pensar en un
algoritmo que hiciera una correlación entre los datos del sensor de
ultrasonido y los encoders, para ir corrigiendo la posición/orientación
del robot en cada movimiento.
Respecto a las estrategias de navegación se podría pensar en
implementar técnicas un poco más inteligentes y robustas de la
ISC-2003-1-47
126
trabajada aquí, por ejemplo a partir de las diferentes técnicas de
planificación de trayectorias libres de colisión para ambientes
conocidos ó bien con técnicas de inteligencia artificial, redes
neuronales o lógica difusa.
Respecto al tema de la elaboración del mapa del ambiente se podría
pensar en algoritmos que sean más precisos. Para esto se podría
pensar en trabajar más conjuntamente con los otros departamentos
de ingeniería, para de esta manera contar con hardware mas preciso
a nivel electrónico y mecánico.
Se podría trabajar con diferentes tipos de sensores tales como láser o
con cámaras de video, o también con anillos de sensores de
ultrasonido más precisos lo cual mejoraría la cantidad y calidad de la
información requerida.
ISC-2003-1-47
127
BIBLIOGRAFIA
[1] http://mindstorms.lego.com [2] The unofficial guide to LEGO® MINDSTORMS Robots, Jonathan B. Knudsen. O’Reilly & Associates 1999. [3] Core Lego® Mindstorms programming, Brian Bagnall. Prentice Hall PTR, 2002. [4] Ensambladores y Procesadores. Notas de clase, Rafael Gómez D. Universidad de los Andes, facultad de ingeniería, Departamento de Sistemas y Computación 1994. [5] Programming Lego® Mindstorms with Java, Darío Laverde. Syngress Publishing, Inc. 2002. [6] Extreme Mindstorms: An Advanced Guide to Lego® Mindstorms, Dave Baum, Michael Gaspieri, Ralph Hempel, Luis Villa. Apress, 2000. [7] Fundamentos de Robótica, A. Barrientos. McGraw Hill, 1997. [8] RCX Manual, University of Aarhus, Department of Computer Science. http://legolab.daimi.au.dk/CSaEA/RCX/Manual.dir/RCXManual.htm l, 2002. [9] Where am I?, University of Michigan, J. Borenstein, H. R. Everett and L. Feng. http://www-personal.umich.edu/~johannb/shared/pos96rep.pdf [10] Telerobotics, automation, and human supervisory control. Sheridan Thomas B. Massachusetts Institute of Technology, 1992. [11] Advanced programming of the LEGO RCX for education, Technical University of Denmark, Niels S. Andersen Mathias N. Kjergaard, 2001. http://www.iau.dtu.dk/ lego/lego3 [12] A Robust layered control system for a mobile robot. (A.I. Memo 864), Massachusetts Institute of Technology, Rodney A. Brooks, Septiembre de 1985. http://www.ai.mit.edu/people/brooks/papers
ISC-2003-1-47
128
[13] LegOS Howto, Luis Villa. http://legOS.sourceforge.net [14] SDL Programming of LEGO robots. Department of automatic control, Lund Insti tute of Technology. Ervasti, Tomi and Niklasson, Torkel. Septiembre de 2000. http://www.efd.lth.se/~d94tn/exjobb/rapport.pdf [15] Reconocimiento de ambiente por un robot móvil. Tesis de pregrado, Departamento de Ingeniería Eléctrica, Universidad de los Andes. Lina Maria Amézquita Bastidas, Víctor Ojeda Pineda. 1995.
[16] Mario Ferrari personal Web page. Mayo de 2003.
http://www.marioferrari.org/s7/s7.html
[17] Seattle Robotics Organization. Mayo de 2003.
http://www.seattlerobotics.org/encoder/may97/sonar2.html
ISC-2003-1-47
129
ANEXO 1. Resumen API’s de programación
API Característica NQC leJOS legOS Versión evaluada 2.4r3 2.0 0.2.6 Cambio de Firmware NO S I S I Tamaño del Firmware 26KB 16 KB
Cantidad de memoria l ibre para el programador
6KB Depende de las clases
usadas
Depende de las clases
usadas Limite en el Numero de Variables SI (192) NO NO Arreglos S I S I S I Sistema Operativo del Host
Win32,MacOS Linux
Win32,Linux Unix
Win32, Linux Unix
Ejecución del código Interpretado Interpretado Nativo Codificación en Lenguaje estándar NO Java C, C++ Números Flotantes NO S I S I Funciones trigonométricas implementadas NO S I NO API para navegación NO S I NO API para comunicación externa S I S I S I API para comunicación desde el Host S I S I NO Multita tarea Preemtiva S I S I S I
ISC-2003-1-47
130
ANEXO 2. Ejemplo programa comunicación NQC y Java
/****************************************** * Código NQC ejecutado por el robot * *******************************************/ int estado; int mensaje; #define IZQUIERDA 0 #define DERECHA 1 #def ine OSCURO 37 #def ine CLARO 43 #def ine VELOCIDAD 5 #def ine TIMEOUT 50 //t iempo en mi lés imas de segundo #def ine MOTOR_IZQUIERDO OUT_A #def ine MOTOR_DERECHO OUT_C task main() { SetPr ior i ty(0); estado=IZQUIERDA; SetSensor(SENSOR_2,SENSOR_LIGHT); SetPower(MOTOR_IZQUIERDO + MOTOR_DERECHO,VELOCIDAD); Se tEvent(0,Message() ,EVENT_TYPE_MESSAGE); start mirarLuz; whi le ( true){ monitor (EVENT_MASK (0)) { i f(SENSOR_2 < OSCURO) //el sensor esta sobre la l inea OnFwd(MOTOR_IZQUIERDO + MOTOR_DERECHO); //avanzo }
catch //codigo a ejecutar si l lega algun mensaje { PlaySound(SOUND_CLICK); mensaje=Message(); i f (mensaje==3){ //se verif ica que el mensaje sea el numero 3
Off(MOTOR_IZQUIERDO + MOTOR_DERECHO);//detengo los motores SendMessage(5); //envio el numero 5 como mensaje StopAl lTasks (); //detengo todas las tareas
} } } }
ISC-2003-1-47
131
task mirarLuz(){ SetPr ior i ty(1);
whi le ( true) { i f (SENSOR_2 > CLARO){ //el sensor esta fuera de la l inea
buscarLinea(); Wai t(TIMEOUT);
i f (SENSOR_2 > CLARO){ buscarLinea(); Wai t (TIMEOUT*2);
} } } } sub buscarLinea(){ //el robot busca la l inea
if(estado == IZQUIERDA){ //busca girando hacia la derecha OnRev(MOTOR_IZQUIERDO); OnFwd(MOTOR_DERECHO); estado = DERECHA;
} else{
OnRev(MOTOR_DERECHO); //busca girando hacia la izquierda OnFwd(MOTOR_IZQUIERDO); estado = IZQUIERDA;
} }
/************************************* *código Java que se ejecuta en el PC* ************************************/ package rcxport; import rcxport.RCXPort; import rcxport.RCXCmd; public class pcRCX {
RCXPort rcxp; RCXResult res;
publ ic pcRCX (Str ing puerto) throws Except ion { rcxp = new RCXPort (puerto); }
publ ic stat ic void main (Str ing [] args) throws Exception { byte mensaje = (byte) 0x03; //numero 3 en Hexadecimal a enviar como mensaje
ISC-2003-1-47
132
String respuesta = null; Str ing nombrePuerto = nul l; RCXResult resultado = null;
nombrePuerto = obtenerPuerto(args);
pcRCX rcx=new pcRCX(nombrePuerto);
resultado = rcx.enviarDatos(RCXCmd.set(RCXCmd.Message,mensaje));
respuesta = resultado.toStr ing();
System.out.pr int ln("\n enviado y recibida la respuesta"); System.out.pr int ln("\n valor: " + respuesta); }
publ ic RCXResult enviarDatos(byte [] mensaje) throws Exception RCXResult res = null; try
{ res = rcxp.sendData(mensaje); }
catch (Except ion e) { }
return res; }
pr ivate stat ic Str ing obtenerPuerto(Str ing [] args) { Str ing puerto = "COM1"; i f (args. length > 0)
{ puerto = args[0]; }
return puerto; }
}
ISC-2003-1-47
133
ANEXO 3. Diagrama de clases del software RCX
rcxExploradorbyte NUM_LECTURASfloat drivelenghtbyte intervaloshort retornoboolean flagfloat xfloat yfloat angulofloat anguloINint distanciaINbyte[ ] lecturasDataInputStream entradaDataOutputStream salidaNavigator robot
rcxExplorador()static void main(String [ ] args)void leerCoordenada()void enviarLecturas()void recogerValores()
SensorConstants<<Interface>>
Navigator<<Interface>>
Object
InputStream
OutputStream
RotationNavigator
DataInputStream
<<extends>>
DataOutputStream
<<extends>>
11
11
11
<<extends>>
<<extends>>
ISC-2003-1-47
134
ANEXO 4. Diagrama De Clases Del Software Host (Clases y relaciones)
estrategia
JPanel<<from javax.swing>>
josx.rcxcomm<<from leJOS>>
java.awt.*
javax.swing.*
javax.swing.tree.*
Informacion
java.awt.geom.*
java.awt.Graphics.*
java.util.*
java.io.*
java.lang.*
AbsoluteLayout.jar<<from NetBeans IDE>>
panelM
0..*1
+Contiene
0..*
+Es contenido por
1
panelMapa0..* 1
+Contiene
0..*
+Es contenido por
1
caminoLargoaleatoria
aplicacion
robot
comunicacion
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
ISC-2003-1-47
135
Diagrama De Clases Del Software Host (Atributos y métodos)
aplicacionprivate UIManager.LookAndFeelInfo diferentesLF[]private comunicacion comunicaJTree arbolJButton botonConectarJCheckBoxMenuItem checkMetalJCheckBoxMenuItem checkMotifJCheckBoxMenuItem checkWindowsButtonGroup grupoEstrategiasButtonGroup grupoInformacionJMenuBar jMenuBar1JSeparator jSeparator1JSeparator jSeparator2JLabel labelDatosJLabel labelMapaJMenu menuAcercaDeJMenu menuAparienciaJMenu menuArchivoJPanel panelAbajoJPanel panelArbolJPanel panelBotonesDatosJPanel panelBotonesMapaJPanel panelDatosJPanel panelEstrategiaJPanel panelInfoMapaJPanel panelMapaJRadioButton radioAleatoriaJRadioButton radioDistanciaLargaJRadioButton radioOtroJRadioButton radioPerpendicularJRadioButton radioTodoJScrollPane scrollArbolJScrollPane scrollPanelDatosJScrollPane scrollPanelMapaJTabbedPane tabbedPaneRobotJTextField textoNumeroPosicionesJTextField textoNumeroPuntos
aplicacion()void botonConectarActionPerformed(java.awt.event.ActionEvent evt)void checkMetalActionPerformed(java.awt.event.ActionEvent evt)void checkMotifActionPerformed(java.awt.event.ActionEvent evt)void checkWindowsActionPerformed(java.awt.event.ActionEvent evt)void exitForm(java.awt.event.WindowEvent evt)void initComponents()static void main(String args[])void radioAleatoriaActionPerformed(java.awt.event.ActionEvent evt)void radioDistanciaLargaActionPerformed(java.awt.event.ActionEvent evt)void radioOtroActionPerformed(java.awt.event.ActionEvent evt)void radioPerpendicularActionPerformed(java.awt.event.ActionEvent evt)void radioTodoActionPerformed(java.awt.event.ActionEvent evt)
ISC-2003-1-47
136
comunicacionboolean escucharboolean aleatorioboolean distanciaLargaboolean otraboolean perpendicularint numPosicionesint numPosActualint indiceRCXPort puertoDataInputStream disDataOutputStream dosInformacion recorrido[]aleatoria AleatoriacaminoLargo CaminoLargoPoint2D.Float coordenadapanelMapa panelMapaColor colores[]Arc2D.Float arcos[]DefaultMutableTreeNode raizDefaultMutableTreeNode hijoDefaultMutableTreeNode nietorobot miRobot
comunicacion()void setEscuchar(RCXPort puerto, boolean Escuchar, panelMapa panelMapa, panelM panelDatos, JTree arbol)void setNumPosiciones(int numeroTotalPosiciones)int getNumPosiciones()void setNumPosActual(int numPos)int getNumPosActual()boolean getEscuchar()RCXPort getPuerto()boolean getAleatorio()void setAleatorio(boolean estado)boolean getDistanciaLarga()void setDistanciaLarga(boolean estado)boolean getOtra()void setOtra(boolean estado)void setPerpendicular(boolean estado)panelMapa getPanelMapa()int getNumeroPuntos()
ISC-2003-1-47
137
InformacionPoint2D.Float coordenadafloat orientacionfloat distancias[5]final float angulosSensor[] = {-90,-45,0,45,90};
Informacion(float X, float Y, float Orientacion)Point2D.Float getCoordenada()void setCoordenada(float X, float Y)float getOrientacion()void setOrientacion(float Orientacion)float[] getDistancias()void setDistanciasI(int i, float Distancia)float getDistanciaI(int i)
estrategia
abstract Point2D.Float calcularCoordenada()
aleatoriafloat Xfloat YPoint2D.Float coordenada;
aleatoria(float x, float y)Point2D.Float calcularCoordenada()
caminoLargoPoint2D.Float coordenadaInformacion informacionint indiceDistanciaMaxima
caminoLargo()Point2D.Float calcularCoordenada()void setCoordenada(Point2D.Float Coordenada)Point2D.Float getCoordenada()void setInformacion(Informacion info)int encontrarMaximo(float[] Dist)int getIndiceDistanciaMaxima()
ISC-2003-1-47
138
panelMapaboolean perpendicularint centroXint centroYint numPosicionesint ifloat alphafloat xfloat ydouble DeltaArc2D.Float arcoArc2D.Float arcos[]Informacion recorrido[]PathIterator piAffineTransform TrotacionSCAffineTransform TtranslacionSCAffineTransform TreflejoYSCAffineTransform TrotacionAffineTransform Ttranslacionname
panelMapa()void initComponents()void paintComponent(Graphics g)AlphaComposite cambiarAlpha(float alpha)void addInfoI(int i, Informacion informacion)void adicionarArcoI(int i, Arc2D.Float Arco)void setNumPosiciones(int NumPosiciones)void setPerpendicular(boolean estado)int getNumeroPuntos()
ISC-2003-1-47
139
panelMint numPosicionesint centroXint centroYint condicionPoint2D.Float coordenadafloat angulofloat distanciafloat xfloat yfloat alphaColor colores[]Arc2D.Float arcos[]Informacion recorrido[]AffineTransform TrotacionSCAffineTransform TtranslacionSCAffineTransform TreflejoYSCAffineTransform TrotacionAffineTransform Ttranslacionname
panelM()initComponents()void paintComponent(Graphics g)AlphaComposite cambiarAlpha(float alpha)void setCentroX(int x)int getCentroX()void setCentroY(int y)int getCentroY()float getAlpha()void setAlpha(float Alpha)float getAngulo()void setAngulo(float Angulo)int getCondicion()void setCondicion(int Condicion)float getDistancia()void setDistancia(float Distancia)Point2D.Float getCoordenada()void setCoordenada(Point2D.Float Coordenada)void adicionarArcoI(int i, Arc2D.Float Arco)void addInfoI(int i, Informacion informacion)void setColores(Color[] Colores)void addColorI(int i, Color colorNuevo)void setNumPosiciones(int NumPosiciones)opname2()
ISC-2003-1-47
140
robotDISTANCIA_CENTRO_SENSOR : floatfloat DISTANCIA_CENTRO_FRENTEfloat DISTANCIA_CENTRO_ATRAZfloat DISTANCIA_MINIMAfloat DISTANCIA_MAXIMAfloat ERROR_SYSTEMATICOboolean flagfloat xfloat yfloat xINfloat yINfloat angulofloat anguloSalidaint distanciaSalidafloat distancias[]
robot()void llenarDistancias(DataInputStream dis)void enviarCoordenadas(DataOutputStream dos)void setX(float nuevaX)void setY(float nuevaY)void setXiN(float nuevaX)void setYiN(float nuevaY)void setDistancias(float nuevasDistancias[])float getX()float getY()float getXiN()float getYiN()float getAngulo()void setAngulo(float Angulo)boolean getFlag()void setFlag(boolean Flag)float getAnguloSalida()void setAnguloSalida(float AnguloSalida)float getDistanciaSalida()void setLongitudSalida(int DistanciaSalida)float[] getDistancias()float correccionError(float Dato)
ISC-2003-1-47
141
ANEXO 5. Diseño Del Robot Móvil
ISC-2003-1-47
142
ANEXO 6. Ambiente De Prueba
Recommended