Preview only show first 10 pages with watermark. For full document please download

Manual 12326199

   EMBED


Share

Transcript

ii Universidad de Costa Rica Facultad de Ingeniería Escuela de Ingeniería Eléctrica IE – 0502 Proyecto Eléctrico Diseño e implementación de un vehículo no tripulado guiado por GPS y su controlador Por: Esteban J. Alvarado Sáenz Ciudad Universitaria Rodrigo Facio Julio del 2008 iii Diseño e implementación de un vehículo no tripulado guiado por GPS y su controlador Por: Esteban J. Alvarado Sáenz Sometido a la Escuela de Ingeniería Eléctrica de la Facultad de Ingeniería de la Universidad de Costa Rica como requisito parcial para optar por el grado de: BACHILLER EN INGENIERÍA ELÉCTRICA Aprobado por el Tribunal: _________________________________ Ing. Peter B. Zeledón Méndez Profesor Guía _________________________________ Ing. M.Sc. Ismael Mazón González Profesor lector _________________________________ Ing. M.Sc. Geovanny Delgado Profesor lector iv DEDICATORIA Quiero dedicar este proyecto en primera instancia a Dios todopodero so, quien me ha acompañado durante esta larga travesía; no sólo en lo que concierne al proyecto, sino en lo que representa, mi realización como Ingeniero Eléctrico. A mis padres, quienes sin cuestionamiento y con mucho sacrificio, me han apoyado durante toda mi vida, con tal de ayudarme a alcanzar mis metas. Papi, Mami, no existen palabras para manifestarles mi gratitud, ustedes me han concedido un regalo muy valioso, una gran disciplina en los estudios, la cual desde pequeño me fue inculcada y hoy en día muestra una vez más sus frutos. El inmenso amor que me tienen, me hace valorar lo privilegiado que soy de contar con unos padres admirables; por eso y más, esto es por ustedes. A mi familia en general, porque ninguno escapa de haberme brindado un enorme apoyo durante este proyecto. Pero quiero dedicárselo especialmente a mi abuelita Marielos, quien siempre estuvo atenta a las distintas dificultades que se afrontaron. A Laura Rodríguez Molina. Lau, el apoyo emocional que me diste a lo largo de todo este proyecto es invaluable y digno de identificar como una bendición más de Dios en mi vida. Me ayudaste a buscar al Padre en esos momentos difíciles que afronté, por ello mil gracias. v RECONOCIMIENTOS A mi tío Luis Fernando Sáenz Sánchez, por la orientación que me proporcionó acerca del funcionamiento del sistema de posicionamiento global y por todos los contactos y equipo electrónico que aportó al proyecto. A Mauricio Rodríguez Carvajal por la invaluable ayuda que me brindó durante todo el proyecto. Su guía y consejos fueron claves para poder superar los obstáculos que se me presentaron. Sin dejar de lado, todo el equipo y las herramientas que gustosamente aportó a la causa. A mi hermano Luis Diego Alvarado Sáenz, por su valiosa ayuda durante todas las pruebas de campo que se realizaron. Al señor Larry Stewart Postel, gerente general de la empresa Craisa S.A., quien muy amablemente prestó el sistema de posicionamiento global, elemento indispensable para el proyecto. Al Ingeniero Peter Zeledón Méndez, por la confianza puesta en mi persona, a la hora de aceptar el reto que representaba ser el profesor guía de un proyecto que le fue propuesto, así como por sus consejos y apoyo brindados. Al profesor Roberto Rodríguez Rodríguez por los consejos proporcionados respecto al manejo del puerto serial en Linux. vi ÍNDICE GENERAL ÍNDICE DE FIGURAS ................................ ................................ ................................ ........ix ÍNDICE DE TABLAS................................ ................................ ................................ ........... xi NOMENCLATURA ................................ ................................ ................................ ............ xii RESUMEN................................ ................................ ................................ ......................... xiii CAPÍTULO 1: Introducción................................ ................................ ................................ ..1 1.1 Objetivos ................................ ................................ ................................ ........................... 3 1.1.1 1.1.2 1.2 Objetivo general ..........................................................................................................................3 Objetivos específicos .................................................................................................................. 3 Levantamiento de requerimientos ................................ ................................ .................. 4 1.2.1 1.2.2 1.3 Requerimientos del vehículo ....................................................................................................... 4 Requerimientos del software a desarrollar .................................................................................. 6 Metodología ................................ ................................ ................................ ...................... 7 CAPÍTULO 2: Desarrollo teórico ................................ ................................ ....................... 10 2.1 Antecedentes históricos................................ ................................ ................................ .. 10 2.1.1 2.1.2 2.2 DARPA Autonomous Land Vehicle (ALV) ............................................................................. 11 Rovers planetarios..................................................................................................................... 13 Definición de robot ................................ ................................ ................................ ......... 14 2.2.1 Robots móviles..........................................................................................................................15 2.3 Elementos de un robot ................................ ................................ ................................ ... 16 2.4 Programación de un robot................................ ................................ ............................. 16 2.4.1 Programación por guiado .......................................................................................................... 17 2.4.2 Programación textual ................................................................................................................ 18 2.4.2.1 Nivel robot............................................................................................................................18 2.4.2.2 Nivel objeto ..........................................................................................................................18 2.4.2.3 Nivel tarea ............................................................................................................................18 2.5 Sistema de Posicionamiento Global (GPS) ................................ ................................ ... 19 2.5.1 2.5.1.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.7.1 2.5.7.2 2.5.7.3 2.5.7.4 Segmento espacial..................................................................................................................... 20 Señal GPS.............................................................................................................................21 Segmento de Control................................................................................................................. 21 Segmento de usuario ................................................................................................................. 22 Principios de Funcionamiento del GPS..................................................................................... 22 Medición de la Distancia........................................................................................................... 26 Sincronización del tiempo ......................................................................................................... 27 Fuentes de error.........................................................................................................................31 Relojes de los satélites.......................................................................................................... 31 Errores de órbita ................................................................................................................... 32 Atmósfera terrestre ............................................................................................................... 32 Multitrayectoria .................................................................................................................... 33 vii 2.5.7.5 Geometría satelital................................................................................................................ 33 2.5.7.6 Receptores de GPS ............................................................................................................... 34 2.5.7.7 Disponibilidad selectiva (Selective Availability S/A) ..........................................................35 2.5.8 Corrección diferencial ............................................................................................................... 35 2.5.9 Resumen de los factores que se deben considerar al utilizar un GPS ....................................... 37 2.5.9.1 Número de satélites visibles ................................................................................................. 37 2.5.9.2 Dilución de la Precisión Posicional (PDOP) ........................................................................ 38 2.5.9.3 Relación señal- ruido (S/N) .................................................................................................. 38 2.5.9.4 Elevación ..............................................................................................................................38 2.5.9.5 Factores ambientales ............................................................................................................ 39 CAPÍTULO 3: Diseño, construcción y descripción general del vehículo ......................... 40 3.1 Diseño y construcción del vehículo ................................ ................................ ............... 40 3.2 Descripción general del vehículo ................................ ................................ ................... 44 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 La estructura..............................................................................................................................44 Sistema de transmisión.............................................................................................................. 44 Sistema sensorial.......................................................................................................................45 Sistema de control ..................................................................................................................... 46 Sistema de alimentación............................................................................................................ 48 CAPÍTULO 4: Desarrollo de un algoritmo para la creación de rutinas de desplazamiento del vehículo................................. ................................ ................................ .......................... 49 4.1 Software desarrollado para el ajuste y mantenimiento del vehículo ......................... 49 4.2 Software desarrollado para el trazado de rutas al vehículo ................................ ....... 50 4.3 Resultados obtenidos durante la primera etapa de programación ............................ 56 CAPÍTULO 5: Desarrollo e implementación de un algoritmo de navegación para el vehículo basado en la información del punto destino y de la ubicación actual. ............... 57 5.1 Ubicación en un cuadrante imaginario ................................ ................................ ........ 57 5.2 Descripción del código fuente ................................ ................................ ........................ 68 5.3 Resultados obtenidos en la segunda etapa de desarrollo de softwar e........................ 71 CAPÍTULO 6: Conclusiones y recomendaciones ................................ .............................. 73 6.1 Conclusiones ................................ ................................ ................................ ................... 73 6.2 Recomendaciones ................................ ................................ ................................ ........... 75 6.2.1 Recomendaciones generales...................................................................................................... 76 BIBLIOGRAFÍA................................ ................................ ................................ .................. 78 APÉNDICES................................ ................................ ................................ ........................ 80 Apéndice 1: Planos de diseño del armazón del vehículo ................................ .......................... 81 Apéndice 2: Código ProyectoGPS.exe ................................ ................................ ....................... 88 Apéndice 3: Código Progps1 ................................ ................................ ................................ .... 100 Apéndice 4: Código ProGPSfinal................................ ................................ ............................. 118 viii Apéndice 5: Disco Compacto con los videos, planos de diseño y código fuente ................... 160 ANEXOS ................................ ................................ ................................ ............................ 162 Glosario ................................ ................................ ................................ ................................ ...... 163 Null Modem ................................ ................................ ................................ ............................... 165 RMC (Recommended Minimum Specific GPS/Transit Data) ................................ .............. 167 Hojas de Fabricante ................................ ................................ ................................ .................. 168 ix ÍNDICE DE FIGURAS Figura 2.1 Procedimiento para ubicar un bote en el mapa de un lago ............................. 24 Figura 2.2 Posibles dos ubicaciones del receptor a partir de 3 mediciones satelitales .....25 Figura 2.3 Señales de reloj del receptor y del satélite ................................ ........................ 26 Figura 2.4 Receptor sincronizado con los satélites genera una posición X ...................... 28 Figura 2.5 Receptor des-sincronizado con los satélites genera una posición XX ............. 28 Figura 2.6 Ejemplo en dos dimensiones de receptor sincronizado con los satélites ......... 29 Figura 2.7 Ejemplo de corrección de desincronización (Tanteo)................................ ......29 Figura 2.8 Ejemplo de multitrayectoria ................................ ................................ .............. 33 Figura 2.9 Geometría satelital (Los satélites deben estar lo más alejados posibl e para obtener una buena precisión) ................................ ................................ .............................. 34 Figura 2.10 Corrección diferencial................................ ................................ ..................... 36 Figura 2.11 Señal correctora Beacon ................................ ................................ ................. 37 Figura 2.12 Señal satelital (Satélite Geoestacionario) ................................ ....................... 37 Figura 3.1. Transformación sufrida por el vehículo 4X4 a escala donado al proyecto ....41 Figura 3.2. Foto del servo controlador utilizado en el proyecto. ................................ ....... 42 Figura 3.3 Fotografía de la antena y recibidor GPS utilizados en el proyecto ................. 45 Figura 4.1 Ventana del programa ProyectoGPS.exe (Escogiendo el puerto serial) ......... 49 Figura 4.2 Zoom a la ventana del programa ProyectoGPS.exe (Seleccionando COM1 como puerto serial) ................................ ................................ ................................ .............. 50 Figura 4.3 Fragmento de la ejecución de Progps1 (Rutina de apagado) .......................... 53 Figura 4.4 Inicio de la ejecución del programa Progps1 ................................ ................... 54 Figura 4.5 Ejecución del programa Progps1 (Opciones de ruta) ................................ ......55 Figura 4.6 Ejecución del programa Progps1 (Presentación de la ruta seleccionada y ejecución de la misma)................................ ................................ ................................ ......... 55 Figura 4.7 Ejecución del programa Progps1 (Rutina de apagado y fin d el programa) ...55 Figura 5.1 Principio del arco producto de un desplazamiento sobre una circunferencia 59 Figura 5.2 Mapamundi (Ubicación de América Central en el planeta Tierra) ................ 60 Figura 5.3 Cuadrante imaginario cuyo centro es el punto destino ................................ ...61 x Figura Apéndice 1-1 Vista superior del armazón utilizado para instalar los componentes electrónicos sobre el vehículo ................................ ................................ .............................. 82 Figura Apéndice 1-2 Vista lateral del armazón utilizado para instalar los componentes electrónicos sobre el vehículo ................................ ................................ .............................. 83 Figura Apéndice 1-3 Vista frontal del armazón utilizado para instalar los componentes electrónicos sobre el vehículo ................................ ................................ .............................. 83 Figura Apéndice 1-4 Vista superior del armazón utilizado para instalar los componentes electrónicos sobre el vehículo y de la unión al sistema de suspensión de los motores del vehículo ................................ ................................ ................................ ................................ 84 Figura Apéndice 1-5 Vista lateral del armazón utilizado para instalar los componentes electrónicos sobre el vehículo y de la unión al sistema de suspensión de los motores del vehículo ................................ ................................ ................................ ................................ 85 Figura Apéndice 1-6 Vista frontal del armazón utilizado para instalar los componentes electrónicos sobre el vehículo y de la unión al sistema de suspensión de los motores del vehículo ................................ ................................ ................................ ................................ 86 Figura Apéndice 1-7 Dimensiones de las piezas utilizadas para unir el armazón utilizado para instalar los componentes electrónicos sobre el vehículo y el sistema de suspensión de los motores del vehículo ................................ ................................ ................................ ..87 Figura A.1 DB-9 macho ................................ ................................ ................................ ....165 Figura A.2 DB-9 hembra................................ ................................ ................................ ...166 xi ÍNDICE DE TABLAS Tabla A.1 Conexión Null-Modem más común ................................ ................................ .165 Tabla A.2 Campos del mensaje RMC................................ ................................ ................ 167 xii NOMENCLATURA AgGPS® Familia de GPS fabricados por Trimble utilizados en agricultura de precisión (Agriculture GPS) BEC Battery Elminator Circuit DARPA Agencia de Investigación de Proyectos Avanzados de Defensa EGNOS European Geostationary Navigation Overlay Service ESC Control electrónico de velocidad ES Entrada/Salida GPS Sistema de posicionamiento global IA Inteligencia Artificial MSComm Microsoft Comm Control NAVSTAR Navigation System and Ranging NMEA National Marine Electronics Association PWM Pulse Wide Modulation RMC Recommended minimum data for gps TSIP Trimble Standard Interface Protocol UHF Frecuencia ultra alta UTP Par trenzado no reforzado WAAS Wide Area Augmentation System xiii RESUMEN El proyecto consistió en el diseño, construcción e implementación de un vehículo no tripulado guiado por GPS. La sección de programación del proyecto se dividió en dos módulos o etapas. La primera etapa consistió en desarrollar un software que permitiera al usuario asignarle rutinas al vehículo. Este programa luego fue utilizado para crear las 10 rutinas de desplazamiento que se utilizarían posteriormente. En la segunda etapa se realizó un manejo de la información que proporciona el sistema de posicionamiento global. Se desfragmentó la cadena de caracteres enviada, se almacenó la información y se aplicaron los cálculos necesarios para darle utilidad a la información. Además se desarrolló un algoritmo que permitiera a partir de las coordenadas de la ubicación anterior, la ubicación actual y el punto destino, determinar el cuadrante alrededor del destino en que se encontraba el vehículo, orientarlo y por último aproximarlo hasta alcanzar el objetivo. El proyecto concluye con la fusión de estos dos módulos, obteniendo así un vehículo capaz alcanzar su destino con una precisión de hasta 1m, y todo gracias a la teoría del nuevo cuadrante desarrollada durante este proyecto. 1 CAPÍTULO 1: Introducción A raíz de la latente necesidad en la que se ven inmersos diversos proyectos (infraestructura, energía, hidrocarburos y turismo) en Costa Rica de encontrar una alternativa nacional para realizar levantamientos tridimensionales de terreno y así reducir al mínimo los costos de este tipo de estudios, es que este proyecto nació como una posible solución. Dado que la meta a alcanzar poseía dimensiones fuera del alcance de un proyect o de bachillerato; como es el caso, se decidió plantear una propuesta en dos dimensiones (vehículo terrestre), la cual será útil para iniciar el desarrollo, además de que se podrá anticipar y solucionar posibles problemas que se puedan presentar también en tres dimensiones (vehículo aéreo). Se construyó un vehículo o “rover”; como también se le conoce a este tipo de robots, que satisficiera los siguientes requerimientos: capacidad de transporte de carga, cuatro ruedas que aportaran mayor estabilidad y agarre con el terreno, capacidad de avance y retroceso, capacidad de freno y por último tracción en las cuatro ruedas. El elemento principal en el sistema de navegación desarrollado es un sistema de posicionamiento global o GPS; por sus siglas en inglés, el cual hace uso de una constelación de satélites para determinar su posición actual. Para poder conducir a buen término este proyecto, se debió iniciar por una investigación profunda acerca de los vehículos no tripulados, así como del funcionamiento de un sistema de posicionamiento global. 2 Seguido a esto se establecieron los requerimientos y objetivos que se cumplirían en este trabajo. El proyecto se dividió en dos módulos o secciones. La primera etapa consistió en la construcción del armazón que soportaría todo el equipo de control y de medición, la unión del mismo a los motores y ruedas que le proporcionarían movimiento, la instalación del equipo de control del vehículo; así como del servomotor de la dirección del “rover”, y por último una investigación acerca del manejo del puerto serial, la cual culmina con la implementación de un algoritmo que permitiera trazar rutinas para el robot. En el segundo módulo se desarrolló un algoritmo que permitiera hacer uso de la cadena de caracteres que enviaba el sistema de posicionamiento global para determinar la posición actual, y que a partir de esta, la posición destino y la posición anterior, se determinara mediante una serie de posibilidades la rutina que se debía ejecutar para así alcanzar el objetivo. El proyecto concluye al fusionar estas dos etapas y realizar las correspondientes pruebas de campo que determinaron que en condiciones óptimas de clima y entorno, el vehículo es capaz de alcanzar su objetivo con una precisión de tres metros. De modo que haciendo entrega de las bases, se espera que tanto la investigación como el desarrollo, logren captar la atención de la comunidad estudiantil de la Escuela de Ingeniería Eléctrica como de personas en general inmersas en el campo de la robótica, para que en un futuro próximo se le de seguimiento y así materializar una idea; que como todas aquellas que llegaron a ser grandes inventos para la humanidad, al inicio parecían imposibles de realizar. 3 1.1 Objetivos 1.1.1 Objetivo general  1.1.2 Diseñar, construir e implementar un vehículo no tripula do guiado por GPS. Objetivos específicos  Realizar un levantamiento de requerimientos tanto para el vehículo como para el software a desarrollar.  Investigar sobre vehículos no tripulados, sus principales características y la evolución que han tenido.  Investigar acerca del funcionamiento del Sistema de Posicionamiento Global.  Diseñar y construir un vehículo de acuerdo a especificaciones.  Crear un medio de comunicación entre el vehículo y la computadora de mando, que permita adquirir la información del estado del robot y enviar instrucciones al mismo.  Desarrollar un algoritmo de comunicación entre la computadora de mando y el controlador del robot, así como una interfaz con el usuario que facilite la creación de rutinas para el vehículo.  Utilizar un sistema GPS como elemento básico en el sistema de navegación del vehículo.  Descargar la información del GPS para su procesamiento en una computadora de mando externa.  Desarrollar un algoritmo de navegación para el vehículo basado en la información del punto destino y de la ubicación actual.  Realizar pruebas de campo. 4 1.2 Levantamiento de requerimientos 1.2.1 Requerimientos del vehículo Una de las principales características que deberá poseer el vehículo es capacidad para transportar todo el equipo de control, alimentación y de posicionamiento global, por lo que su diseño girará en torno al peso del equipo de GPS y la alimentación, debido a que el peso del equipo de control generalmente resulta insignificante. Adicionalmente la potencia de los motores a escoger debe ser la adecuada para que el “rover” pueda desplazarse sin problemas. Con el objetivo de otorgarle al vehículo la mayor estabilidad y agarre al suelo posible; de modo que este pueda desplazarse casi por cualquier tipo de terreno, un diseño de cuatro ruedas es la mejor opción. Otro factor importante es que el vehículo debe ser capaz de circular en cualquier tipo de terreno, por lo que la altura de las llantas y de sus ejes, así como una tracción en las cuatro ruedas, debe ser tomada en cuenta a la hora del diseño del mismo. Debido a que el vehículo debe maniobrar para adoptar distintas orientaciones y posiciones; pero sin que esto altere su ubicación actual, deberá poseer capacidad de avance tanto en retroceso como hacia adelante. Adicionalmente, la presencia de un sistema de frenado; ya fuera inherente a los motores o un diseño propio, es imprescindible para que las rutinas de desplazamiento predefinidas, no dependan del tipo y/o inclinación del terreno en que navegue el vehículo. 5 Seguidamente, se debe diseñar o adquirir un pequeño y sencillo circuito que sea capaz de controlar la dirección del giro de los motores que mueven las llantas del vehículo, así como de proporcionar diferentes velocidades en ambos sentidos de giro. Una vez que el vehículo esté en capacidad de desplazarse se procede a colocar el servomotor de la dirección. Para esto se ajustará una barra al eje de las llantas frontales, el cual funcionará como un volante. El otro extremo de la barra se fijará al servomotor, de modo que se pueda cambiar la dirección del movimiento con gran precisión. Un detalle muy importante es la fuente de energía del vehículo, ya que debido a que la autonomía es primordial, una alimentación estacionaria, no es la mejor solución, en vista del futuro que se le depara a este proyecto. Es por esto que la alimentación debe ser portable, y liviana, por lo que se espera conseguir una batería de níquel-cadmio que satisfaga las necesidades de los motores presentes. Con el objetivo de controlar los servomotores, se debe encontrar algún tipo de controlador interfaz periférico, que permita manipularlos desde una computadora externa. Se espera que el mismo sea adquirido con algún tipo de software que facilite la comunicación entre la computadora y el procesador, evitando así problemas que puedan proceder a la hora del manejo de los puertos periféricos de la computadora. Luego se debe conseguir un receptor de señales satelitales de posicionamiento global, el cual debe ser capaz de realizar un procesamiento interno de datos en tiempo real, y entregar información de utilidad a la computadora de mando. Debido a posibles fluctuaciones de la carga que puedan afectar al sistema GPS, y al tamaño físico que debería tener una batería que sea capaz de alimentar a los motores y al 6 sistema de posicionamiento global al mismo tiempo, se recomienda seleccionar una fuente de alimentación independiente para este último. 1.2.2 Requerimientos del software a desarrollar Puesto que se espera que un gran porcentaje de este proyecto sea reutilizado en el desarrollo de una etapa aérea, el software desarrollado deberá procesar y almacenar toda la información proveniente del sistema de posicionamiento global, a pesar de que esta no tenga uso para este proyecto en particular. Además los cálculos realizados para averiguar distancias, deberán realizarse de modo que puedan ser utilizados en tres dimensiones también. La importancia de utilizar una computadora de mando externa y por lo tanto un software adecuado para esta, se debe a que se estima que la etapa aérea; dado que tiene que almacenar tanto los datos de posición como las características del suelo sobrevolado, necesitará de una gran capacidad de almacenamiento de datos. Tan pronto se haya instalado el controlador de los servomotores y este funcione correctamente, se deberá proceder a establecer una comunicación “One way” desde la computadora de mando hasta el “rover”; utilizando un lenguaje de programación flexible, y así crear la primera versión del programa de mando. Esta versión contendrá todas las clases y funciones necesarias para indicarle una ruta al vehículo, las cuales serán usadas más adelante en futuras versiones. Esta ruta deberá tener la característica de ser de un tamaño indefinido y funcionar como un “buffer”. 7 Después de instalar el receptor GPS, se debe asegurar una comunicación entre la computadora externa y el mismo, agregando nuevas funciones al programa de mando, con las que se pueda procesar la información suministrada por la unidad de posicionamiento global. Con la información de posicionamiento global disponible, se debe investigar y desarrollar una forma en la que a partir de la ubicación actual del vehículo y el punto destino, se pueda alcanzar este último de una forma práctica y sencilla. Una vez que se tenga cuente con el programa base completo, se deben realizar varias pruebas de campo, que permitan constatar el éxito del proyecto. 1.3 Metodología A continuación se enumeraran los pasos que se debieron tomar para alcanzar todos los objetivos del proyecto en discusión: 1. Se realizó una investigación acerca de los antecedentes de los vehículos terrestres no tripulados, con el objetivo de determinar cuáles eran las características esenciales de los mismos y poder aplicarlas luego en el diseño. 2. Seguidamente se efectuó otra investigación acerca del funcionamiento del sistema de posicionamiento global con el objetivo de comprender mejor su funcionamiento y así facilitar el desarrollo de un futuro algoritmo que utilice la información proveniente del GPS para determinar las rutinas que debe efectuar el vehículo para alcanzar el destino. 8 3. Luego se realizó un planteamiento de los requerimientos que debía satisfacer tanto el vehículo como el software a desarrollar, y a partir de esto se hizo un diseñó bastante simple de un “rover” que satisficiera todas las necesidades del proyecto. 4. Una vez que se contó con este diseño, se procedió a buscar distintas piezas; por medio de donaciones, que se apegaran a la idea original y que con simples modificaciones se pudieran satisfacer los ya mencionados requerimientos. 5. Tan pronto se construyó el marco que iba a soportar todo el equipo de alimentación, control y de GPS, se procedió a unirlo a los motores y ruedas que se encontraron . 6. Se aprovechó el sistema de dirección existente en las ruedas, por lo que sólo se debió instalar un servomotor y una barra que transmitiera la fuerza en forma horizontal a alguna rueda (aleatoriamente se escogió la izquierda). 7. Se instaló el ESC (Electronic Speed Control), conectándolo directamente a la alimentación de los motores de las ruedas. 8. La fuente de energía portátil (batería de Ni/Cd) se instaló en el “rover” y se conectó al regulador de voltaje del ESC. 9. El controlador de los servomotores se instaló y se le conectó la entrada de voltaje regulado proveniente del ESC, la salida PWM hacia el ESC, y el servomotor de la dirección. 10. Se realizó una investigación a fondo sobre el manejo del puerto serial, la cual determinó la necesidad de continuar todo desarrollo en una plataforma libre. 9 11. Se desarrolló un programa que por medio del puerto serial, se pudiera comunicar con el controlador de los servomotores y que además permitiera al usuario definir rutinas al robot. 12. Se instaló el Sistema de Posicionamiento Global. 13. Adicionalmente se tuvo que instalar una fuente de energía independiente para el GPS. 14. Se inició un desarrollo de software orientado a adquirir la información proveniente del GPS, desfragmentarla y almacenarla para su posterior uso. 15. Una vez que se contó con la información de posición geográfica, se desarrolló un algoritmo que a partir de la ubicación anterior, de la ubicación actual y del punto destino, permitiera al robot orientarse y aproximarse hacia el destino. 16. Luego se fusionó el programa que controlaba los motores del vehículo, con el programa que adquiría la información de posicionamiento global y que además permitía al “rover” tomar decisiones para aproximarse al destino. 17. Se definieron 10 rutinas de desplazamiento que permiten al robot orientarse y aproximarse hacia el destino. 18. Se realizaron distintas pruebas de campo. 10 CAPÍTULO 2: Desarrollo teórico 2.1 Antecedentes históricos La comunidad académica usualmente se refiere a los vehículos terrestres no tripulados que posean habilidades autónomas significativas, como robots móviles. Existe una cierta ironía en esta terminología, dado que muchas de estas investigaciones claves dirigidas a la robótica tradicional (orientada al control de manipuladores industriales) son completamente irrelevantes para los robots móviles. Poseen cierta similitud en temas relacionados al planeamiento de la trayectoria, evasión de obstáculos y control basado en sensores, pero los resultados han tendido a fluir más desde los robots móviles a los manipuladores, que en la otra dirección. De hecho, el énfasis de las investigaciones en robótica móvil ha evolucionado desde la disciplina de la inteligencia artificial (IA). El primer gran esfuerzo en el desarrollo de un robot móvil fue Shakey, el cual fue desarrollado a finales de 1960 para fungir como una plataforma de pruebas para las investigaciones sobre IA promovidas por DARPA en el Instituto de Investigación de Stanford. Shakey era una plataforma sobre ruedas equipada con una cámara de televisión giratoria, sensores sónicos de proximidad, sensores de contacto, conectados mediante un enlace RF a su computadora central (una SDS-940), la cual se encargaba de la navegación y de las tareas de exploración. Como plataforma de pruebas en IA, el sistema Shakey podía recibir varias instrucciones desde la terminal del operador, las cuales guiaban al robot para empujar largos bloques de madera alrededor del ambiente de su “mundo” laboratorio. A pesar de que fue considerado un fracaso en su época porque nunca logró una operación 11 autónoma, el proyecto estableció las bases funcionales y de desarrollo para los robots móviles, localizando las deficiencias tecnológicas, y contribuyendo a orientar la agenda de investigación de la IA en áreas como planeamiento, visión y procesamiento del lenguaje natural. Desde 1973 hasta 1981, Hans Moravec condujo el proyecto titulado “Vehículo Stanford”, en el laboratorio de Inteligencia Artificial de la Universidad de Stanford, donde se trató temas como la navegación de exploración y la evasión de obstáculos utilizando un sofisticado sistema de visión estéreo. La única cámara de televisión era girada a cualquiera de las 9 diferentes posiciones gracias a su base giratoria, y las imágenes obtenidas eran procesadas por la computadora central KL-10 que no viajaba en el carro por razones obvias de dimensión y peso de la misma. La extracción de objetos y la correlación entre las imágenes permitieron reconstruir un modelo de la imagen tridimensional, el cual fue utilizado para planear un camino libre de obstáculos hacia el destino. El sistema era increíblemente lento, tomaba 15 minutos para realizar un desplazamiento de un metro. Moravec se trasladó a la Universidad de Carnegie Mellon (CMU) en 1981 y continuó su trabajo en el pequeño CMU Rover. Esta universidad se convirtió en el principal líder en investigaciones sobre robots móviles; durante la década de los ochentas, con su vehículo Navlab el cual fue reflejo del arduo trabajo 2.1.1 DARPA Autonomous Land Vehicle (ALV) El desarrollo patrocinado por DARPA conocido como “Robots móviles como un campo de aplicación para la demostración de IA y alto rendimiento en técnicas de 12 procesamiento”, que fue iniciado al final de la década de los sesentas con Shakey, reemergió en los inicios de los ochentas como la DARPA Autonomous Land Vehicule (ALV). Bajo el procesamiento estratégico de DARPA (conocido como “SC” por sus siglas en inglés), el ALV funcionó como uno de varios proyectos cuya meta era “proveer un ambiente de tareas realistas para la investigación tecnológica”. Otras aplicaciones del SC incluyó la administración del centro de combate de una flota naval estadounidense (FCCBMP), la conducción de un combate aéreo-terrestre de la armada estadounidense (ALBM) y el conocido “Relación Piloto” (PA) que consistía en una especie de piloto automático para aeronaves de la fuerza aérea estadounidense que se dividió en dos objetivos: misiones aire-aire y misiones aire-tierra. El ALV se construyó sobre un vehículo de ocho ruedas dirigido hidrostáticamente, capaz de alcanzar velocidades de hasta 72 km/h en una autopista y de hasta 29 km/h en un terrero difícil. El ALV podía cargar seis estantes de equipo electrónico dentro de un ambiente con aire acondicionado libre de polvo y obtener energía desde su fuente auxiliar de energía diesel de 12 kW. El equipo de sensores consistía en una cámara de video a color y un escáner láser provisto por el Instituto de Investigaciones del Medio Ambiente de Michigan (ERIM), el cual devolvía una imagen de 64x256 píxeles a un intervalo de 1-2 segundos. Los módulos de procesamiento de información de video y de alcance producían información a nivel del borde del camino, que era utilizada para generar un modela de la escena en frente. Un mayor nivel de razonamiento fue desarrollado por los módulos de búsqueda de objetivos y de navegación, los cuales pasaban luego la ruta deseada al módulo del piloto que en realidad manejaba al vehículo. Martín Marieta; el contratista de 13 integración, incorporó módulos funcionales proporcionados por otros desarrolladores de tecnología de DARPA, incluyendo al Laboratorio de Investigación Hughes, la Universidad Carnegie-Mellon y la Universidad de Maryland. Las demostraciones del ALV; sobre el seguimiento de un camino, iniciaron en 1985 a 3km/h sobre un camino recto de 1 km, luego mejoraron en 1986 a 10 km/h sobre un camino de 4,5 km con curvas pronunciadas y con tipos variables de pavimento, y en 1987 a un promedio de 14,5 km/h (máximo 21 km/h) sobre un trayecto de 4,5 km a través de varios tipos de pavimentos, anchos de camino y sombras, mientras se evadían obstáculos. También en 1987, se demostró el tránsito guiado por visión sobre un camino de tierra, a lo largo de un trayecto de 0,6 km, a velocidades de 3 km/h, sobre terreno cambiante mientras se evadían zanjas, piedras, árboles y otros pequeños obstáculos. El enfoque del programa ALV fue modificado en 1988 de demostraciones íntegras de aplicaciones militares a soporte de experimentos científicos para la navegación en terrenos fuera de carretera. El programa de la división del ejército de los Estados Unidos de Norteamérica Tank-Automotive Command (TACOM)/ DARPA Advanced Ground Vehicle Techonology (AGVT), adaptó técnicas de navegación desarrolladas bajo el programa del ALV, a vehículos militares que estuvieran mejor capacitados para aplicaciones militares. 2.1.2 Rovers planetarios El uso de vehículos robóticos no tripulados reducen drásticamente el costo de la exploración espacial al ser comparados con viajes espaciales tripulados, dado que los robots pueden ser más pequeños que los humanos, y al eliminar a los humanos también se elimina 14 la necesidad tanto del pesado y complicado equipo de soporte de vida, como de la gran confiabilidad en todos los subsistemas críticos de seguridad. El desarrollo patrocinado por la NASA de vehículos no tripulados para explorar superficies planetarias inició con el JPL (Jet Propulsion Laboratory) Mars Rover, en los inicios de la década de los setenta. El programa fue clausurado en 1979 y luego retomado en 1986-1987. El objetivo era proveer una navegación sobre la superficie marciana de hasta 10km por día con una autonomía parcial, recolectando muestras mientras es dirigido desde la tierra. El retraso de la propagación de la velocidad de la luz inherente a las transmisiones interplanetarias reduce los tipos de estrategias de control que se pueden utilizar en estos sistemas. A pesar de que carecen de los recursos del gobierno estadounidense para poner hombres sobre la Luna, Rusia ha tenido un activo programa de “rovers” planetarios, por ejemplo en la Luna con el Lunokhod y en Marte con el Marsokhod. 2.2 Definición de robot De manera complementaria es importante establecer una definición de robot, la cual se encontrará de manera implícita cada vez que se haga referencia a dicho dispositivo y sobre la cual se establecerán todas las acciones a desarrollar. Por tanto, la definición de robot a utilizar es la suministrada por la Asociación Francesa de Normalización (AFNOR), la cual define primero el manipulador y luego al robot como sigue 1: 1 Barrientos A. Et al. “Fundamentos de robótica”. 1 ed. McGraw, Madrid, España, 1997, pág 10. 15  Manipulador: mecanismo formado generalmente por elementos en serie, articulados entre sí, destinado al agarre y desplazamiento de objetos. Es multifuncional y puede ser gobernado directamente por un operador humano o mediante un dispositivo lógico.  Robot: manipulador automático servocontrolado, reprogramable, polivalente, capaz de adoptar posiciones y orientar piezas útiles o dispositivos especiales, siguiendo trayectorias variables reprogramables, para la ejecución de tareas variadas. Normalmente tiene la forma de uno o varios brazos terminados en una muñeca. Su unidad de control incluye un dispositivo de memoria y ocasionalmente de percepción del entorno. Normalmente su uso es el de realizar una tarea de manera cíclica, pudiéndose adaptar a otra sin cambios permanentes en su material. 2.2.1 Robots móviles Los robots móviles son aquellos que están provistos de patas, ruedas u orugas que los capacitan para desplazarse de acuerdo a su programación. Elaboran la información que reciben a través de sus propios sistemas de sensores y se emplean en determinado tipo de instalaciones industriales, sobre todo para el transporte de mercancías en cadenas de producción y almacenes. También se utilizan robots de este tipo para la investigación en lugares de difícil acceso o muy distantes, como es el caso de la exploración espacial y de las investigaciones o rescates submarinos. 16 2.3 Elementos de un robot Todos los robots son sistemas, es decir, constan de componentes que forman un todo. El sistema robótico se puede analizar de lo general a lo particular utilizando el análisis sistemático. El primer paso es considerar al sistema como una "caja negra", no se sabe qué hay en su interior, pero se puede identificar la entrada y salida del sistema. La entrada genuina al robot está constituida por las órdenes humanas; la salida está formada por diversos tipos de trabajo realizado automáticamente. La segunda etapa o paso de análisis es mirar dentro de la caja negra donde encontramos los subsistemas o unidades funcionales del robot. Cada unidad funcional realiza una función específica y tiene su propia entrada y salida. Un robot está conformado por los siguientes elementos2: estructura mecánica, trasmisiones, sistema de accionamiento, sistema sensorial, sistema de control y elementos terminales. 2.4 Programación de un robot Para la entrada en funcionamiento de un determinado robot es necesario realizar una rutina que será la encargada de determinar los movimientos del mismo, siguiendo la tarea específica para la cual el robot fue diseñado. Por tanto, programar un robot consiste en la especificación paso a paso de dicha rutina, siguiendo un sistema de programación diseñado para ese fin. Los sistemas de programación existentes son tan variados como los robots que se pueden encontrar en la actualidad, es decir, no existe ningún tipo de normalización. Esto 2 Barrientos A. Et al. “Fundamentos de robótica”. 1 ed. McGraw, Madrid, España, 1997, pág 15. 17 implica la no existencia de un procedimiento estándar a la hora de programar las rutinas que se desea que realicen los robots en un determinado proceso. Por el contrario, cada fabricante desarrolla un método para sus propios robots. Sin embargo, los sistemas de programación pueden ser sujetos a una clasificación, la cual se basa en el sistema empleado al especificar la secuencia de acciones a realizar. En una el programador es el responsable de las acciones de control y de las instrucciones adecuadas que las implementan. En la otra se describe la tarea y el entorno, y el robot es el encargado de tomar sus propias decisiones. En este sentido se distinguen dos clases: programación por guiado y programación textual. 2.4.1 Programación por guiado Consiste en guiar al robot a lo largo de la trayectoria llevándolo hasta los puntos deseados. De esta manera la unidad de control del robot guarda en memoria todos los puntos de la trayectoria que han sido obtenidos a través de los sensores de posición. Si el guiado del robot se hace de manera manual, es decir, si el programador toma la estructura del robot guiándola a través de la trayectoria deseada se habla de programación por guiado pasivo. Existe además una programación guiada activa. Para esta se utiliza un dispositivo de enseñanza comprendido por un sistema de accionamiento del robot, el cual está formado por botones, teclas, bastones de mando, etc. que se utilizan para realizar los movimientos necesarios que debe ejecutar luego el robot. 18 2.4.2 Programación textual En este tipo de programación la tarea que el robot debe realizar se indica mediante un lenguaje de programación específico. La rutina queda establecida mediante un conjunto de textos de instrucciones o sentencias que son las encargadas de definir finalmente las acciones del robot. La programación textual se clasifica en tres niveles: robot, objeto y tarea. 2.4.2.1 Nivel robot En este nivel se requiere programar todas las acciones a realizar por el robot, en cuanto al movimiento de sus articulaciones, velocidad, acciones de los elementos finales, orientación espacial, etc. Para esto es necesario que la rutina total sea descompuesta en una serie de subrutinas de menor grado de complejidad. 2.4.2.2 Nivel objeto En este nivel de programación textual las instrucciones comprendidas en el programa son realizadas en función de los objetos que el robot va a manipular. Para que las rutinas puedan ser llevadas a cabo, es necesario que las instrucciones a nivel de objeto sean generadas posteriormente a nivel robot, puesto que éste es quien finalmente realiza las acciones pertinentes. 2.4.2.3 Nivel tarea Este es el nivel en el que las instrucciones de programa se reducen a una única sentencia, ya que lo que se hace es especificar cuál es la tarea a realizar por el robot. 19 2.5 Sistema de Posicionamiento Global (GPS) Un sistema de posicionamiento, como el nombre lo sugiere, es un método para identificar y grabar; generalmente en forma electrónica, la ubicación de un objeto o persona. Este sistema puede ser usado para registrar el recorrido de un vehículo a través de la superficie terrestre, en el aire o en el espacio. El sistema de posicionamiento global; mejor conocido por su acrónimo en inglés (GPS: “Global Positioning System”), es un sistema de navegación basado en satélites, creado y operado por el Departamento de Defensa de los Estados Unidos. Se inició a principios de los ochentas, pero fue declarado completamente operacional el 27 de Abril de 1995. Completamente operacional significa que el sistema puede ser usado para determinar la posición de un receptor las 24 horas del día, en cualquier parte de la tierra. El sistema fue concebido originalmente como un auxiliar para la navegación para las fuerzas militares de los Estados Unidos, pero hoy en día el GPS sirve también para fines industriales, comerciales y civiles. El servicio está disponible, en forma gratuita, las 24 horas del día y bajo cualquier condición meteorológica. Para describir mejor el sistema se lo puede dividir en tres partes:  Segmento espacial  Segmento de control  Segmento de usuario 20 2.5.1 Segmento espacial Este segmento consiste de una constelación de 24 satélites NAVSTAR (NAVigation by Satellite Timing and Ranging). Con una órbita de 20200 km de altura sobre la superficie terrestre, cada satélite orbita la tierra 2 veces al día, o sea una vez cada 12 horas. Los 24 satélites se dividen en 6 órbitas con 4 satélites cada una. Esta distribución particular garantiza que por lo menos 4 satélites estarán en línea de vista de un receptor de GPS en cualquier parte del mundo durante todo el día. Los receptores deben ser capaces de recoger la señal satelital enviada a la tierra. Los satélites cuya señal puede ser recibida son aquellos que están por sobre el horizonte. Cada satélite está equipado con receptores y emisores de ondas de radio que transmiten con una frecuencia de entre 1200-1600 MHz. Las ondas de radio viajan a la velocidad de la luz (300.000.000 m/s) en el vacío, y disminuyen su velocidad cuando atraviesan la atmósfera terrestre. Los satélites también están equipados con relojes atómicos, que mantienen el tiempo con base en vibraciones naturales periódicas dentro de los átomos. Estos relojes increíblemente precisos son un componente crítico que hacen posible el uso de satélites para navegación y mapeo. Cada satélite cuenta con cuatro relojes, 2 de cesio y 2 de rubidio, a pesar de que uno sería suficiente, de esta forma se evita el riesgo de rotura o pérdida de precisión por alguno de los relojes. 21 2.5.1.1 Señal GPS Los satélites GPS transmiten dos señales de radio de baja potencia, designadas L1 y L2. Los GPS civiles usan la frecuencia L1 de 1575.42 MHz en la banda UHF. L2 es utilizado por los militares y algunos receptores especializados de GPS y su frecuencia es de 1227.6 MHz. Las señales viajan a lo largo de la línea de visión, es decir, pasarán a través de nubes, vidrio y plástico pero no atravesarán la mayoría de objetos sólidos, tales como edificios y montañas. La señal GPS contiene tres bits diferentes de información: un código pseudo aleatorio, información efímera e información de almanaque. El código pseudo aleatorio es simplemente un código de identificación que identifica al satélite que está transmitiendo la información. La información efímera informa al receptor GPS la ubicación de cada satélite GPS en todo momento a lo largo del día. Cada satélite transmite información efímera mostrando la información orbital de ese satélite y de todos los otros satélites en el sistema. La información calendario, que es transmitida constantemente por cada satélite, contiene información importante sobre el estado del satélite (saludable o no saludable), fecha y hora actuales. Esta parte de la señal es esencial para determinar la posición . 2.5.2 Segmento de Control Los satélites son seguidos y monitoreados por varias estaciones ubicadas estratégicamente alrededor del mundo. Esta red de estaciones de monitoreo se denomina 22 generalmente segmento de control del GPS, y consta de 4 estaciones de monitoreo y una estación de control principal ubicada en la Base de la Fuerza Aérea Falcon en Colorado Springs, Colorado. La ubicación de las otras 4 estaciones es: Las estaciones de tierra se encuentran repartidas en cuatro puntos del globo: Hawai, Isla de Ascensión, Diego García y Atolón de Kwajalein. Las estaciones de monitoreo miden las señales de ondas de radio que son transmitidas continuamente por los satélites y pasan esa información a la estación de control principal. Ésta usa la información para determinar la órbita exacta de los satélites y para ajustar sus señales de navegación, por ejemplo: error de reloj, correcciones, estado del satélite, etc. 2.5.3 Segmento de usuario Las unidades o receptores GPS son el segmento de usuario, que computan la posición del usuario por medio de las señales recibidas. Los GPS de uso civil no requieren licencia para operar ya que no transmiten señales de radio, solamente las reciben. Hay una gran gama de receptores con distintas precisiones y por ende precio, cada uno se adapta a un uso en particular. 2.5.4 Principios de Funcionamiento del GPS El GPS se basa en las distancias entre el receptor y una serie de satélites para conocer su posición. El principio básico detrás del GPS es bastante simple, y lo vamos a ilustrar con un ejemplo: si se quiere ubicar un bote en el mapa de un lago, y se sabe que está ubicado a 10 minutos desde el puerto A, a 5 minutos desde el puerto B y a 15 minutos 23 desde el puerto C, asumiendo una velocidad constante de 10 km/h. El primer paso es calcular la distancia que separa cada puerto del lugar a ubicar. Para hacer esto se multiplica la velocidad 10 km/h (166 m/minuto) por el tiempo desde el punto hasta cada puerto. Distancia al puerto A 166 m/min x 10 min = 830 metros Distancia al puerto B 166 m/min x 5 min = 1660 metros Distancia al puerto C 166 m/min x 15 min = 2490 metros A continuación se debe dibujar un círculo con centro en el puerto A y un radio de 830 m. El punto a ubicar puede estar en cualquier parte sobre el perímetro de éste círculo. Luego se dibuja un segundo círculo con centro en el puerto B y un radio de 1660 m. Estos dos círculos se intersecan en solamente dos puntos, lo que indica que el punto a ubicar está en uno de esos dos puntos. Cuando se dibuja el tercer círculo con centro en el puerto C, con un radio de 2490 metros, los tres círculos se cruzan en un solo punto posible, y esa es la ubicación del bote. 24 Figura 2.1 Procedimiento para ubicar un bote en el mapa de un lago Estos son esencialmente los mismos pasos que usa un receptor de GPS para determinar su posición. En el ejemplo se usó éste método para determinar una posición en dos dimensiones a través de tres distancias. En un plano tres círculos intersecan en un único punto. Sin embargo el GPS provee la posición en tres dimensiones para lo que hace falta 25 cuatro (o más) mediciones de distancia. En tres dimensiones 4 esferas coinciden en un único punto. Cuando un receptor quiere averiguar su posición se comunica con un satélite (A en el ejemplo) y deduce que la distancia que los separa es de 20400 km. Esto significa que el receptor se encuentra en algún punto de la superficie de una esfera con centro en el satélite y un radio de 20400 km. Si simultáneamente se conoce la distancia a un segundo satélite (B), de por ejemplo 22200 km se reduce la localización del receptor a un círculo en la intersección de las 2 esferas. Si se realiza la medición de distancia desde un tercer satélite (C) se reduce la ubicación posible del receptor a 2 puntos en el espacio, dónde la tercer esfera interseca el círculo formado por la primera con la segunda. Para decidir cuál de esos dos puntos es la ubicación correcta hay dos opciones: o hacer una cuarta medición desde otro satélite o hacer una suposición. Generalmente uno de los dos puntos es una ubicación ridícula, o no se encuentra sobre la superficie terrestre o tiene una velocidad imposiblemente alta. Figura 2.2 Posibles dos ubicaciones del receptor a partir de 3 mediciones satelitales 26 Los programas dentro de los receptores de GPS tienen varias técnicas para distinguir el punto correcto del que no lo es. En sentido trigonométrico hacen falta cuatro distancias para determinar una posición en el espacio, pero en la práctica no es necesario por esta razón pero si por otra razón técnica que se discutirá más adelante. Todo lo demás sobre el sistema son los detalles técnicos de cómo se lleva a cabo el proceso de medición o para hacerlo más preciso. 2.5.5 Medición de la Distancia El principio básico de la medición de la distancia es el principio de "velocidad por tiempo". El sistema GPS funciona tomando el tiempo que tarda una señal de radio emitida por un satélite hasta llegar al receptor, y de esa forma calcular la distancia, sabiendo que las ondas de radio viajan a la velocidad de la luz (300.000.000 m/s). Si se conoce el tiempo exacto en que salió la señal del emisor y el tiempo de llegada al receptor, se puede calcular por diferencia el tiempo de viaje de la señal y por ende la distancia. De aquí se deduce que los relojes deben ser bastante precisos en tiempos pequeños, porque la señal de un satélite que esté perpendicular al receptor sólo tarda 6/100 de segundo en llegar. Figura 2.3 Señales de reloj del receptor y del satélite 27 Para poder calcular el tiempo de viaje de la señal de radio, tanto el satélite como el receptor generan códigos sincronizados. Esto es que ambos generan el mismo código al mismo tiempo. Entonces cuando llega una onda al receptor este determina el tiempo transcurrido desde que éste generó el mismo código. La diferencia de tiempo es lo que tardó la onda en llegar. Tanto el satélite como el receptor generan un juego de códigos digitales que responden a un criterio binario. Ese juego de códigos digitales llevan el nombre de “pseudo-random” (pseudo aleatorios) y están diseñados de forma tal que puedan ser fácilmente comparados, en forma rápida y sin ambigüedades. La secuencia pseudo aleatoria se repite en el orden de los milisegundos. 2.5.6 Sincronización del tiempo Como ya es conocido la luz viaja a 300.000.000 m/s, lo que implica que si los relojes del satélite y del receptor están desfasados tan solo 1/100 de segundo las medidas de distancia tendrían un error de 3000 km. Los relojes atómicos de los satélites son extremadamente precisos, pero tienen un costo de US $100.000 cada uno, que sería prohibitivo para un receptor de uso civil. Afortunadamente este problema se resolvió utilizando la medición desde un cuarto satélite. La trigonometría indica que se puede localizar un punto en el espacio mediante 3 medidas perfectas, y que cuatro medidas imperfectas pueden eliminar la desincronización del tiempo. 28 Figura 2.4 Receptor sincronizado con los satélites genera una posición X Figura 2.5 Receptor des-sincronizado con los satélites genera una posición XX El ejemplo posterior explicará cómo se resuelve la sincronización del tiempo, los diagramas están hechos en dos dimensiones a los fines explicativos, para entender como pasa en la realidad (tres dimensiones) solo hay que agregar una medida más. 29 Figura 2.6 Ejemplo en dos dimensiones de receptor sincronizado con los satélites Figura 2.7 Ejemplo de corrección de desincronización (Tanteo) Normalmente se habla de la distancia a los satélites en kilómetros o millas, que son deducidas a partir del tiempo de viaje de las ondas, para simplificar la explicación nos 30 referiremos a las distancias en segundos. Supongamos que el reloj de un receptor adelanta 1 segundo, entonces si nos encontramos a una distancia real de dos satélites A y B de 4 y 6 segundos respectivamente (punto X), el receptor interpretará que está a 5 y 7 segundos de distancia de ambos satélites A y B respectivamente, lo que resulta en una posición distinta que llamaremos XX. Esta posición sería incorrecta pero nada en el receptor haría sospechar que así fuera. Si agregamos un tercer satélite C (recuerde que el ejemplo es en dos dimensiones, sería el cuarto trabajando en tres dimensiones como es en la realidad), que se encuentra a una distancia real de 8 segundos, entonces el círculo con centro en el satélite y radio de 8 segundos pasa exactamente por el punto X, pero el receptor cree que se encuentra a 9 segundos del satélite. Estas tres distancias a los satélites no tienen forma de coincidir en un punto, pero si definen un área posible. Las computadoras en los receptores están programadas para que en el caso que obtengan una serie de medidas que no puedan intersecar en un único punto, reconozcan que hay algún error y asuman que su reloj interno está desfasado. Entonces las computadoras comienzan a sumar o a restar la misma cantidad de tiempo a cada medida hasta encontrar un punto en el que todas coincidan. En el ejemplo la computadora descubrirá que restando un segundo a cada medida está el único punto en que estas coinciden y asume que su reloj está un segundo adelantado. De hecho las computadoras no utilizan el método de prueba y error sino utilizan un sistema de cuatro ecuaciones con cuatro incógnitas, pero en esencia el proceso es el mismo. La conclusión es que para obtener medidas precisas en tres dimensiones se necesitan cuatro satélites. 31 Esto afecta el diseño de los receptores ya que si se necesitan medidas de posición precisas, continuas y en tiempo real, los receptores deben tener por lo menos cuatro canales para poder recibir cuatro satélites simultáneamente. 2.5.7 Fuentes de error A pesar de que el desarrollo del GPS se basó en tecnología muy sofisticada y con gran inversión de dinero, su precisión se ve degradada por una serie de fuentes de error. Algunas fuentes de error son inherentes al sistema e inevitables y otras son manejables por el usuario. Estas son:  Relojes de los satélites  Errores de órbita  Atmósfera terrestre  Multitrayectoria  Geometría satelital  Receptores de GPS  Disponibilidad selectiva (S/A) 2.5.7.1 Relojes de los satélites Como se vio anteriormente los relojes atómicos de los satélites son unos de los más precisos, pero no son perfectos. Pequeños e insignificantes errores en el tiempo pueden crear grandes errores en las medidas de posición. Justamente la función del segmento de 32 control terrestre es monitorear y ajustar los relojes para minimizar las pequeñas desviaciones. 2.5.7.2 Errores de órbita Las órbitas de los satélites son tan altas que la atmósfera terrestre no las afecta, sin embargo, algunos fenómenos naturales como las fuerzas gravitacionales de la luna y el sol, como así también la presión de la radiación solar, generan pequeños errores en la altitud, posición y velocidad de los satélites. Estos errores se acumulan acrecentando su efecto. Nuevamente el segmento de control terrestre ajusta las señales de los satélites para corregir los errores de órbita. 2.5.7.3 Atmósfera terrestre Las ondas de radio viajan a una velocidad constante en el vacío, sin embargo al entrar en la atmósfera terrestre se encuentran con la ionosfera, que es una capa de partículas cargadas que se encuentra de 80 a 400 km sobre la superficie terrestre. Esta demora en el tiempo de llegada de las ondas induce un error en los cálculos de distancia ya que este asume una velocidad constante de la luz. Las demoras producidas en esta capa dependen de la cantidad de iones/m3 y la actividad o perturbación ionosférica en dicho momento. Después de pasar a través de la ionosfera, las señales de los satélites deben pasar por la atmósfera baja, la troposfera, donde el vapor de agua incrementa un poco mas las demoras. La porción de error debida a esta capa de la atmósfera ha sido simulada con un alto grado de precisión, permitiendo de esta manera que los receptores lo tengan en cuenta y puedan minimizarlo. 33 2.5.7.4 Multitrayectoria Figura 2.8 Ejemplo de multitrayectoria Los errores debido a la multitrayectoria aparecen cuando la señal "rebota" antes de llegar al receptor, o sea que la señal llega a la antena del receptor por más de una trayectoria o camino. Parte de la onda llega en forma directa y parte realiza una trayectoria diferente, por ende causando diferencias en el tiempo de viaje. Hoy en día hay algunas antenas diseñadas para minimizar este efecto. 2.5.7.5 Geometría satelital Con todos los errores mencionados anteriormente, se puede imaginar que el círculo que define la distancia a cada satélite no se tiene un perímetro bien marcado sino es una línea difusa (figura). Dónde coinciden las distancias de dos satélites, en vez de ser un punto es una pequeña área. Como lo indica la figura cuanto mas juntos estén los satélites mayor será el área de incertidumbre donde podemos estar ubicados y por ende aumenta el error. 34 Esto significa que cuanto mas desparramados estén los satélites sobre el receptor mayor será la precisión. Figura 2.9 Geometría satelital (Los satélites deben estar lo más alejados posible par a obtener una buena precisión) 2.5.7.6 Receptores de GPS El ruido debido a interferencias eléctricas o el redondeo de las operaciones matemáticas llevan a errores en la medición de la posición. Los receptores de mayor calidad, y por lo tanto mas caros, están diseñados para disminuir el ruido interno y maximizar la precisión matemática. Otro elemento constitutivo importante de los receptores es el número de canales que poseen. Los hay de un solo canal hasta de 12. Para una aplicación de precisión son necesarios aquellos que tengan por lo menos 4 canales simultáneos, uno para cada uno de los cuatro satélites indispensables para tomar una posición en tres dimensiones, siendo ideales los de 12 canales. 35 Cuantos más satélites se estén recibiendo más precisa será la posición dada, debido a que el área de incertidumbre se disminuye sustancialmente y se minimiza el error. Esto está también ligado a la geometría satelital explicada anteriormente. 2.5.7.7 Disponibilidad selectiva (Selective Availability S/A) El Departamento de Defensa de los Estados Unidos agregaba un error intencional al sistema para restringir el uso a fuerzas hostiles en tiempo de guerra. Esto lo lograban introduciendo ruido digital a los relojes de los satélites. Esta disponibilidad selectiva no afecta la precisión de los receptores militares de GPS pero si a los de uso civil. Los errores introducidos cambian constantemente en magnitud y dirección. Esta era la mayor fuente de error de los receptores de uso común. A partir del 1° de Mayo de 2000, el gobierno estadounidense eliminó la disponibilidad selectiva, aumentando considerablemente la precisión de los receptores de uso común. 2.5.8 Corrección diferencial Todos estos errores enunciados anteriormente reducen la precisión del GPS, resultando en un error de entre 5 y 20 m (previo a la eliminación de la disponibilidad selectiva el error ascendía hasta los 100 m). Lo cual puede resultar útil para algunas actividades pero no en aplicaciones en las que la precisión sea un factor determinante. Por ende se requiere un método para mejorar sustancialmente la precisión. El método más usado hoy en día es la corrección diferencial (DGPS Sistema de Posicionamiento Global Diferencial). 36 Figura 2.10 Corrección diferencial El sistema funciona usando un receptor de referencia (que puede ser una antena Beacon o un satélite geoestacionario) ubicado en un lugar de coordenadas exactamente conocidas. Esta estación de referencia recibe las mismas señales que los receptores comunes, pero al conocer su posición exacta puede calcular el error que transmite cada satélite en magnitud y sentido, en ese momento. La diferencia entre la distancia real desde el receptor de referencia y cada satélite se denomina distancia de corrección diferencial. Este error es transmitido a través de señales de radio al móvil en tiempo real. Las señales de corrección diferencial pueden provenir de antenas Beacon o de satélites geoestacionarios. La señal Beacon proviene de antenas fijas, cada una que cubre un área comprendida dentro de un radio de 450 Km. Mediante la corrección satelital se logran precisiones submétricas, que oscilan en los 30 cm. 37 Figura 2.11 Señal correctora Beacon Figura 2.12 Señal satelital (Satélite Geoestacionario) 2.5.9 Resumen de los factores que se deben considerar al utilizar un GPS Algunos elementos que afectan la precisión del sistema de posicionamiento global y que pueden ser encontrados entre los datos que el receptor proporciona al usuario son: 2.5.9.1 Número de satélites visibles Como ya se explicó anteriormente cuantos más satélites esté recibiendo un receptor más precisa será su posición ya que se disminuye el área de incertidumbre de su posición posible. El mínimo de satélites para ubicar un receptor en tres dimensiones es de 4, cada satélite que se agregue a las mediciones mejora la precisión. El máximo teórico de satélites que se pueden recibir es 12, pero generalmente los que se encuentran demasiado cerca del 38 horizonte no se reciben. En la práctica se suele trabajar con un máximo de 8, lo que resulta en una muy buena precisión, se recomienda trabajar con por lo menos 5 o más. 2.5.9.2 Dilución de la Precisión Posicional (PDOP) PDOP es una medida sin unidades que indica cuando la geometría satelital provee los resultados más precisos. Cuando los satélites están desparramados por el espacio, el valor PDOP es bajo y las posiciones computadas son más precisas. Cuando los satélites están agrupados el valor PDOP es alto y las posiciones imprecisas. Para obtener precisiones submétricas el PDOP debe ser de 4 o menos. 2.5.9.3 Relación señal- ruido (S/N) La relación señal/ruido es una medida de la intensidad de la señal satelital. A medida que la intensidad aumenta la precisión también lo hace. A mayor señal y menor ruido la relación es mayor y la precisión aumenta. Para obtener posiciones con precisión esta relación (S/N) debe ser mayor de 6, con un ideal entre 12 y 15. 2.5.9.4 Elevación Cuando un satélite está bajo en el horizonte, la señal que emite debe atravesar una gran distancia de atmósfera, demorando la llegada al receptor. Se pueden eliminar estos datos configurando los receptores para que eliminen las señales de los satélites que están debajo de cierto ángulo por sobre el horizonte. Los satélites que estén por debajo de este ángulo son excluidos del cómputo de la posición. Para la mayor precisión se recomienda utilizar un ángulo mínimo de 15°. Al ser muy elevado este ángulo puede que se pierdan las 39 señales de algunos satélites y no se obtenga operación continua. Por eso una solución de compromiso es configurar este ángulo en por lo menos 7,5°. 2.5.9.5 Factores ambientales Como ya se sabe la señal GPS es reflejada por objetos cercanos, particularmente por objetos metálicos, creando resultados falsos o erróneos. Este fenómeno es conocido como multitrayectoria. La precisión óptima se obtiene recolectando datos lejos de superficies reflectoras, como edificios, galpones o árboles. Algunos receptores poseen distintas formas de minimizar el efecto de la multitrayectoria. Para lograr precisiones menores se deben cumplir las siguientes condiciones:  Número de satélites usados: > 5  PDOP: < 4  Relación señal / ruido (S/N): > 6  Elevación mínima: > 7,5°  Ambiente de reducida multitrayectoria 40 CAPÍTULO 3: Diseño, construcción y descripción general del vehículo Una vez presentados los aspectos de mayor relevancia en cuanto a los elementos constitutivos de un robot y a la programación de los mismos, se procede a introducir al “rover”, el cual corresponde al vehículo/robot sujeto a estudio y control en este proyecto. 3.1 Diseño y construcción del vehículo Cabe destacar que el GPS fue un préstamo; durante la duración del proyecto por parte de la empresa Craisa, con el cual se contó desde el inicio del mismo, por lo que el diseño del vehículo giró en torno a sus dimensiones y peso. El receptor GPS con que se contó tenía por dimensiones 14.5cm de ancho, 5.1cm de alto, 19.5cm de largo y un peso de 0,76 kg, mientras que la antena GPS tenía un diámetro de 15,5 cm, una altura de 14 cm y un peso de 0,55 kg. El consumo de potencia máximo de todo el equipo de posicionamiento global era de 7W, operando a un voltaje que podía oscilar entre 10 V y 32 V. Una donación importante en el proyecto fue la de un carro de control remoto a escala, llamado Scorpion 4X4, el cual es capaz hasta de escalar pequeñas rocas debido al torque de sus motores DC. Dado que los motores de este vehículo ya poseían suficiente potencia y por ende capacidad de carga, no fue necesario diseñar los motores, ruedas y ejes de dirección del “rover”, por lo que se pudo ahorrar tiempo en esta etapa y simplemente se separaron del vehículo original. La siguiente imagen permite tener una concepción mejor del proceso de transformación al que se vio expuesto este 4X4 a escala. 41 Figura 3.1. Transformación sufrida por el vehículo 4X4 a escala donado al proyecto. Como se mencionó anteriormente, tanto las ruedas, como la suspensión y los motores del Scorpion 4X4 están diseñados para ser utilizados en terrenos difíciles. Con esto se logró satisfacer los requerimientos de potencia de los motores, así como de la capacidad de circular en cualquier tipo de terreno. Debido a que el Scorpion 4X4 poseía; además de los motores de las ruedas, un servomotor que controlaba la dirección y un circuito que controlaba estos tres motores, y que estos eran a su vez alimentados mediante una batería de 7,2 V, se decidió que los cálculos de potencia no eran necesarios, dado que se tenía pensado seguir esa misma línea de componentes. De modo que sólo fue necesario encontrar una batería similar para alimentar al vehículo. Se eligió una batería de Níquel-Cadmio, por razones de seguridad y de peso, la cual entrega 7,2 V, con una capacidad en funcionamiento de 1,5 A/h. Se decidió que uno de los elementos esenciales en el proyecto era el controlador de los servomotores, por lo que después de una larga investigación acerca de este tipo de 42 microcontroladores se eligió el controlador de 8 servomotores de la empresa Servo City, debido a que provenía de una marca de renombre en lo que es el mercado del radio control y a que presentaba buenos comentarios en los foros indagados, aumentando así las probabilidades de que este cumpliera los requerimientos del proyecto. Las dimensiones de la cubierta del circuito son 7.1 x 5.7 x 2.4 cm, y posee un peso de 50g. Figura 3.2. Foto del servo controlador utilizado en el proyecto. Luego; paralelo a la búsqueda de un regulador de voltaje que evitara que una variación de voltaje en la batería dañara la tarjeta controladora de servomotores, se requería un circuito capaz de accionar los motores de las ruedas a distintas velocidades y en ambos sentidos por medio de una señal PWM enviada por el microcontrolador, por lo que investigando más a fondo acerca de los componente electrónicos de otros “rovers”, se encontró que existe un circuito que realiza ambas funciones. Este dispositivo electrónico se conoce como ESC, y dentro de sus partes básicas se encuentran un regulador de voltaje y un circuito digital que al recibir una señal PWM, funge como un puente H y energiza a los motores, con base al ancho de pulso de la señal recibida. 43 El ESC elegido para el proyecto fue un Novak Rooster 12T, el cual posee capacidad de corriente extra, previendo así un esfuerzo excesivo por parte de los motores en terrenos difíciles. Dentro de sus cualidades más importantes se encuentra: 1) Un BEC (Battery Eliminator Circuit), que permite resolver el problema de la ausencia de un voltaje regulado para el servo controlador, 2) Una protección térmica de sobrecarga, 3)Una cubierta resistente al agua, 4) Configuración por medio de un sistema “One Touch”, eliminando así la presencia de un potenciómetro de tornillo que puede dar problemas a la hora de ajustar la posición de neutro de los motores y 5) Permite el giro de los motores en ambos sentidos. También fue necesario buscar una fuente de alimentación adicional para el GPS, debido a que este funciona con un voltaje mayor al de los motores de las ruedas, y a que resultaba peligroso un consumo tan grande de corriente a partir de una única batería. La batería que se consiguió fue de gel ácido de 12 V, con una capacidad de 7AH/20HR. La misma tiene un gran peso a considerar de 15 kg. Resumiendo, el vehículo transporta una carga de 15 kg por parte del sistema de alimentación, y 1,31 kg por parte del sistema de posicionamiento global. Por lo que una vez teniendo presente el peso y las dimensiones del equipo que se debía transportar, se procedió a diseñar el marco o armazón del vehículo. En los apéndices es posible encontrar el diseño del marco diseñado para instalarse sobre el sistema de suspensión del Scorpion 4X4. 44 3.2 Descripción general del vehículo A continuación se ubicará cada parte del vehículo dentro de los elementos básicos de un robot mencionados en la nota teórica. 3.2.1 La estructura Está compuesta por las ruedas, las cuales van directamente unidas a los motores de corriente de directa, quienes fungen también como eje y soporte principal del “rover”. Adicionalmente y debido a que se quería otorgar un sistema de suspensión que permitiera al receptor GPS mantenerse; en la medida de lo posible, siempre sobre el mismo plano horizontal, se agregó sobre cada uno de estos dos motores, un eje rotatorio, con lo que sumado a los cuatro compensadores presentes, se logró obtener la función deseada. Por último los dos motores y sus respectivos sistemas de suspensión se encuentran conectados por medio de un marco que fue diseñado exclusivamente para transportar la carga estimada, tanto del sistema de alimentación, como el sensorial y el del control. 3.2.2 Sistema de transmisión Este sistema está presente únicamente en el control de dirección del vehículo. Está compuesto por una barra móvil en el “eje y”, la cual se encuentra dentro de la carcasa del motor frontal y enlaza directamente ambas ruedas, de modo que cualquier fuerza horizontal que se le aplique a una rueda, fluye por esta barra hasta la otra. Luego, hay una segunda barra, que une la rueda número dos con un adaptador que permite conectar esta barra al servomotor que controla la dirección. Este adaptador que se menciona no sólo permite 45 enlazar la segunda barra con el servomotor, sino que aumenta el par del servomotor, aprovechando la mayor distancia que se genera entre la segunda barra y el eje de rotación del servomotor. Debido a que los motores utilizados son de corriente directa, el par desarrollado por el eje del motor es directamente proporcional al flujo en el campo y a la corriente en la armadura. Es por esta razón que no fue necesario utilizar un sistema de transmisión para controlar la velocidad del vehículo, en su lugar se utilizó un controlador electrónico de velocidad. 3.2.3 Sistema sensorial Este puede ser localizado en el sistema GPS, el cual consiste de la antena, un cable coaxial, el recibidor y el cable “NULL MODEM” (se hicieron 20 m adicionales) que permite comunicar el receptor con la base. En la siguiente figura se pueden apreciar tanto el receptor como la antena utilizados en este proyecto. Figura 3.3 Fotografía de la antena y recibidor GPS utilizados en el proyecto 46 La antena se encarga de recibir la señal satelital y por medio del cable coaxial transmite estas señales en forma de corriente al recibidor; que en este caso es un AgGPS® 132 de Trimble, el cual utiliza la tecnología “The Choice”, que es una combinación de recibidores diferenciales “beacon”, satelitales y WAAS/EGNOS reunidos en un mismo recibidor, y que provee cobertura confiable DGPS en prácticamente cualquier región. Esto es un gran aporte para el proyecto, ya que se puede hacer uso en cualquier momento de esta característica, para hacer más confiables los datos proporcionados por este sistema. El AgGPS® 132 puede a su vez transmitir a un tercer equipo, mediante cualquiera de sus dos puertos RS-232, haciendo uso de los mensajes estandar NMEA (En el proyecto se usa el mensaje NMEA RMC), o del protocolo TSIP. Para esta tarea y dado que el cable de fábrica es muy corto, se utiliza un cable UTP categoría 5, en configuración “NULL MODEM”. 3.2.4 Sistema de control El sistema de control del “rover” se compone de lo que para efectos del proyecto denominaremos: computadora de mando. Esta puede ser cualquier computadora personal o de escritorio, que sea capaz de correr el programa de mando desarrollado. Dentro de esta, un proceso automatizado toma lugar, ya que se recibe la información que aporta el sistema sensorial, se procesa, se toma una decisión a partir de la misma, y por último se envía una orden a ser ejecutada por la tarjeta controladora de servos. La tarjeta contralodora de servos es una tarjeta integrada que puede controlar 8 servomotores, y que es capaz de comunicarse con cualquier equipo anfitrión que posea una 47 interfaz de puerto serial. El formato de comunicación es de 9600 baudios, sin paridad, 8 bits de datos y uno de parada (9600, n, 8, 1). La tarjeta no cuenta con un convertidor RS232 a TTL, pero esto es útil desde el punto de vista de que se puede comunicar con otros sistemas al sólo invertir la lógica TTL. El procesador PIC puede manejar los niveles estándar de RS232 directamente con sólo hacer uso de la resistencia limitadora de 22k  en el pin Rx. El programa de mando debe enviar 3 bytes de datos en el siguiente orden preestablecido: byte de sincronización (255), byte que corresponde al número de servomotor (0-7) y por último el byte de posición del servomotor (0 -254). El servocontrolador únicamente controla 2 unidades, la primera de ellas es el servomotor que guía la barra de dirección, el cual por conveniencia corresponde al espacio marcado como servo #1. La otra unidad es el control de velocidad electrónico, el cual a pesar de no ser propiamente un servomotor, está diseñado para trabajar como uno, y que dependiendo del valor asignado por la tarjeta, así variará el sentido y magnitud de la corriente directa que alimenta a los motores, y que por la misma razón indicada anteriormente este corresponde al servo #2. El ESC (por sus siglas en ingles “Electronic Speed Control”) o control de velocidad, a grandes rasgos se encarga de recibir una señal PWM, la cual dependiendo del ancho del pulso, corresponde a una cierta velocidad en reversa, al freno, o a una velocidad proporcional hacia delante. alimentación del vehículo Este cumple también un papel muy importante en la 48 3.2.5 Sistema de alimentación Aunque no se encuentra dentro de la clasificación que hace la bibliografía, se decidió incluirlo como un sistema aparte, dado el papel fundamental que juega dentro del funcionamiento del robot. Este sistema está compuesto por una batería de Níquel-Cadmio, la cual entrega 7,2 V, con una capacidad en funcionamiento de 1,5 A/h, el ESC y una segunda batería de gel ácido de 12 V, con una capacidad de 7AH/20HR. La batería de Níquel-Cadmio se encuentra alimentando directamente al ESC y como ya se mencionó, este es muy importante dentro del sistema en análisis, ya que funciona como un “puerto de alimentación”. Al mismo tiempo que controla los motores de corriente directa, los alimenta, y dado que posee un circuito conocido como eliminador de batería, que básicamente consiste en un regulador de voltaje que provee de un voltaje fijo al propio ESC y a la tarjeta de controladora de servos, quien controla y alimenta al servomotor de la dirección. Por último, la batería de gel ácido es utilizada únicamente para alimentar al sistema de posicionamiento global, debido a que la carga de la otra batería ya es bastante elevada y a que su voltaje no era el requerido. 49 CAPÍTULO 4: Desarrollo de un algoritmo para la creación de rutinas de desplazamiento del vehículo. 4.1 Software desarrollado para el ajuste y mantenimiento del vehículo Para constatar que tanto la tarjeta controladora como los motores funcionaban correctamente, fue que se decidió realizar un pequeño y simple programa utilizando Microsoft’s Visual Basic, que permitiera crear una interfaz serial desde la computadora hacia el microcontrolador. Este programa lleva por nombre ProyectoGPS.exe. A pesar de que se utilizó la herramienta de MSComm; que incluye la versión profesional de Visual Basic, la cual permite que la programación de aplicaciones seriales sea realmente simple, incursionar en esta herramienta fue de gran ayuda, ya que otorgó las bases de lo que es el desarrollo de un software para comunicaciones seriales. Figura 4.1 Ventana del programa ProyectoGPS.exe (Escogiendo el puerto serial) 50 ProyectoGPS.exe permite hacer un manejo sencillo de cualquiera de los ocho posibles servomotores, al desplazar su barra respectiva. Esta representa la posición actual del servomotor y el cuadro que se encuentra en la parte superior de cada barra, indica el valor numérico de esta posición (En la figura anterior todos los cuadros indican 127 que corresponde a la posición central de los servos). Debido a que el manejo es por medio del ratón, sólo se puede manipular un servo a la vez. Esta aplicación permite la variante de que en caso de que la computadora posea dos puertos seriales, poder escoger entre cualquiera de ellos. La siguiente figura permite explicar mejor esta situación. Figura 4.2 Zoom a la ventana del programa ProyectoGPS.exe (Seleccionando COM1 como puerto serial) Actualmente, el programa ProyectoGPS.exe es utilizado para labores muy sencillas de ajustes y mantenimiento al vehículo. 4.2 Software desarrollado para el trazado de rutas al vehículo Una vez que se estableció comunicación por medio del puerto serial con la tarjeta controladora de los servomotores, se procedió a utilizar un lenguaje de programación más 51 flexible y poderoso, de modo que se inició una nueva etapa en el proyecto al dar inicio al programa base, por medio del lenguaje C++. El programa lleva por nombre Progps1 y fue desarrollado baja la plataforma de Linux, debido a que este otorga un manejo puro al usuario de sus puertos de interfaz mediante el uso de ficheros, en contraste a Windows, que a pesar de que también maneja sus puertos como ficheros; debido a su mal diseño inicial que ha arrastrado con los años y a su intento por brindarle seguridad a la máquina, hace prácticamente imposible acceder a estos. Para iniciar el desarrollo de este programa se hizo uso de las clases de C++ llamadas libserial. Estas clases permiten; en sistemas POSIX, accesar al puerto serial como un objeto de iostream. Además se provee de varias funciones que permiten ajustar varios parámetros del puerto serial, como la tasa de baudios, el tamaño del carácter, el control de flujo, entre otros. La utilización de estas clases es un proceso poco común para la mayoría de los usuarios de computadoras; especialmente sino se está acostumbrado al entorno Linux, por lo que a continuación se explicará en detalle los pasos que se deben seguir para poder hacer uso de este código C++: 1. Se debe descargar desde la web el archivo libserial-0.5.0.tar.gz. 2. Luego se debe descomprimir el archivo en alguna carpeta de conocimiento previo. 52 3. Una vez descomprimido el archivo se debe abrir una terminal de usuario y como superusuario ejecutar los siguiente 3 comandos en el orden indicado: a. ./configure b. make c. make install 4. Luego se debe modificar el archivo de sistema /etc/bash.bashrc; el cual permite agregar variables de entorno generales para el sistema, añadiendo al final del mismo la siguiente línea: export LD_PRELOAD=$LD_PRELOAD:/usr/local/lib/libserial.so 5. Se debe verificar que el usuario pertenece al grupo dialout. Con el fin de chequear esto se puede ejecutar el siguiente comando en una terminal como superusuario: adduser usuario dialout 6. Por último, a la hora de compilar el código, se debe recordar agregar al final del comando de compilación la siguiente opción: -lserial En el desarrollo del código, el primer paso fue crear una clase que contuviera todas las funciones que serían utilizadas luego desde una función “main”. Esta clase se nombró 53 tipo “puertoserial”, y está compuesta por su constructor y tres funciones que son: escribir, ruta y cerrar. Este constructor es lo que en programación se conoce como un constructor por defecto, ya que se hace uso del mismo con tan sólo crear un objeto tipo la clase a la cual el constructor pertenece. Dentro de este se encuentran todas las funciones de la clase serial_port; la cual es una de las principales funciones obtenidas a partir de la librería libserial, con las que se puede abrir y configurar el puerto desea, tan sólo al crear un objeto tipo puertoserial. La función escribir permite enviar una sola instrucción a un único servomotor, al hacer uso de la función “write” de la clase serialport. Esta función fue creada con el objetivo de crear rutinas, como la rutina de apagado que contiene la función main de este programa. Figura 4.3 Fragmento de la ejecución de Progps1 (Rutina de apagado) La función ruta recibe una cadena de caracteres que representan una serie de instrucciones para el vehículo, y esta se encarga de discernir si corresponde a una instrucción válida o no. De ser válida; mediante la función write de la clase serialport, ejecuta la instrucción, en caso contrario, el vehículo se detiene y centra el servomotor de la dirección, mientras se obtiene una instrucción válida de la cadena de caracteres recibida. Desde que se creó esta función, se pensó en el futuro uso que tendría en el programa base, 54 ya que se esperaba que esta fuera el último eslabón del código entre la recepción de la información sensorial y la ejecución de instrucciones. La función cerrar fue creada con la intención de ser utilizada al final de cada ejecución, tanto de este programa como de cualquier otro que se desarrollara en el futuro. Hace uso de la función close de la clase serialport, por lo que se encarga de cerrar el fichero que corresponde al puerto serie en uso. Es una buena práctica cerrar la comunicación con el puerto una vez finalizado su uso, con el fin de evitar problemas con otras aplicaciones que hagan uso del puerto serial o con otra ejecución de este mismo programa . La función main de progps1, es simplemente una interfaz con el usuario, que permite hacer uso de las funciones explicadas anteriormente y fue creada exclusivamente con el objetivo de presentar un avance a los profesores lectores, por lo que no se profundizará en su código. En su lugar se presentan algunas capturas de la ejecución del programa. Figura 4.4 Inicio de la ejecución del programa Progps1 55 Figura 4.5 Ejecución del programa Progps1 (Opciones de ruta) Figura 4.6 Ejecución del programa Progps1 (Presentación de la ruta seleccionada y ejecución de la misma) Figura 4.7 Ejecución del programa Progps1 (Rutina de apagado y fin del programa) 56 4.3 Resultados obtenidos durante la primera etapa de programación El programa ProGPS.exe fue de gran utilidad a la hora de determinar el giro máximo y mínimo del servomotor de la dirección, así como a la hora de regular las diferentes velocidades de los motores de las ruedas. Su sencilla pero útil forma de enviar pulsos a la tarjeta controladora de servos, permitió conocer con exactitud el valor de la posición que se debía utilizar a la hora de establecer los pasos principales de las rutinas. El programa Progps1 dio excelentes resultados, ya que permitió constatar el buen desempeño del vehículo a la hora de seguir una ruta. En el disco compacto del apéndice es posible encontrar un video que muestra la interfaz del usuario y los resultados obtenidos. 57 CAPÍTULO 5: Desarrollo e implementación de un algoritmo de navegación para el vehículo basado en la información del punto destino y de la ubicación actual. Este es el último programa que se desarrolla, lleva por nombre ProGPSfinal, el cual reúne todos los objetivos planteados al inicio de este documento. El mismo ha tenido una base sólida gracias a los dos programas desarrollados anteriormente. A continuación se procederá a explicar los conceptos básicos de cómo se solucionó el problema de la determinación de la posición instantánea del vehículo y del trazo de la ruta hacia el objetivo, posteriormente se analizará con detalle el código fuente. 5.1 Ubicación en un cuadrante imaginario El sistema sensorial conformado por el GPS, dentro de la extensa información que puede proporcionar, se encuentran los datos de latitud y longitud. La latitud es enviada por el receptor hacia la base en el siguiente formato: “DDMM,MMMM”. Donde “DD” corresponde a los grados, “MM” corresponde a los minutos y “,MMMM”; que puede variar su número de cifras de cero a siete, corresponde a las décimas de minutos. La longitud es enviada en un formato similar, la única diferencia es que esta presenta una cifra más en los grados, así: “DDDMM,MMMM”. 58 Ambos formatos deben ser convertidos a uno que pueda ser útil. Por ello es que se escogió utilizar el formato “DD,DDDD” y “DDD,DDDD”, para la latitud y la longitud respectivamente. El procedimiento es el siguiente: Se debe almacenar los grados, ya sean “DD” o “DDD”. Luego se debe tomar la parte restante “MM.MMMM” y dividirla entre 60. El resultado tendrá un exponente cero, y formará una nueva mantisa de “0,DDDD”. Luego se suma las unidades de grados previamente almacenadas al valor obtenido en el paso anterior, y se obtiene la latitud o longitud en un formato conocido como grados y décimas de grados. Adicionalmente, se deben convertir los grados a radianes así: radianes  grados 180  (5.1-1) Una vez que se obtiene la ubicación en radianes, se puede utilizar el principio del arco producido por un desplazamiento, y que se explica a continuación: 59 Figura 5.1 Principio del arco producto de un desplazamiento sobre una circunferencia Si se dividiera en dos la tierra, ya sea por la línea del ecuador o paralelo cero (para la longitud), o por el meridiano Greenwich (para la latitud), como se aprecia en la figura anterior, donde el punto “C” corresponde al centro de la tierra, “A” al punto origen y “B” la localización actual, la distancia entre A y B representada por la línea roja, se encuentra haciendo uso de la siguiente ecuación: Dis tan cia[km]   [radianes ]  R[km] (5.1-2) Dado que Costa Rica se ubica en el hemisferio Nor-Oeste, una distancia calculada a partir del dato de longitud; proporcionado por el GPS, siempre va a corresponder a la distancia medida desde el meridiano 0º hacia el oeste. La siguiente figura puede ser de gran ayuda. 60 Figura 5.2 Mapamundi (Ubicación de América Central en el planeta Tierra) De igual forma una distancia calculada a partir del dato de latitud, corresponde a una distancia medida desde el paralelo 0º hacia el norte. Por lo tanto, un punto en el mapa, corresponde únicamente a dos distancias, una a partir de la latitud y otra a partir de la longitud. Y para los efectos del proyecto, se puede obviar la orientación de la latitud y de la longitud, dado que esta no va a variar. Como el destino es un punto fijo, resulta fácil tomarlo como nueva referencia, y así trazar alrededor de este un sistema nuevo de coordenadas, que permitan al vehículo conocer su ubicación respecto al destino, y así poder tomar una decisión acerca de su posible aproximación al mismo. La siguiente figura ilustra este hecho. 61 Figura 5.3 Cuadrante imaginario cuyo centro es el punto destino Una vez que se contó con una noción de la ubicación espacial, se procedió a relacionar la ubicación actual y la ubicación anterior, con el tipo de decisión que se debe tomar. El programa parte del supuesto de que siempre se ha avanzado anteriormente al menos una instrucción. Es por ello que al inicio de la búsqueda del destino, siempre se ejecuta la instrucción de avanzar. Esto no sólo le permite a la base conocer la ubicación de vehículo, sino la orientación de su movimiento respecto al destino. Durante el análisis realizado para determinar en qué forma se procedería en la toma de decisiones; a partir de la distancia tanto en latitud como en longitud del “rover” respecto 62 al origen, se encontró que las decisiones que deben tomarse en los cuadrantes 1 y 3 son las mismas bajo condiciones iguales, y que para los cuadrantes 2 y 4, las decisiones son inversas a las que se deberían tomar en los otros dos cuadrantes. De modo que el problema se reducía a analizar sólo un par de cuadrantes; sean el 1 y el 2, y proyectar los resultados a sus homólogos de 180º. Luego de analizar todos los posibles casos, se determinó que sólo eran necesarias diez decisiones o rutinas para poder llevar a cabo la búsqueda del destino. Estas se presentan a continuación, y se indicará con un ejemplo su posible uso en el cuadrante 1; que con las similitudes explicadas anteriormente, todos los cuadrantes quedan explicados. Para facilitar la explicación, se usarán cuatro variables que también son utilizadas en el código fuente: distlat2, distlat1, distlon2 y distlon1. La primera representa la distancia en latitud que existe entre la ubicación antes de ejecutar el último avance y el destino, la segunda corresponde a la distancia en latitud entre la ubicación actual y el destino y las dos restantes es la misma situación sólo que en lugar de distancia en latitud, es la distancia en longitud. Las rutinas son: a. Invertir dirección derecha: Se encarga de invertir en 180º la orientación del vehículo, pero haciendo el giro hacia al derecha. Si dstlat1 aumentó respecto a dstlat 2 y dstlon1 aumentó también respecto a dstlon 2 , esto implica que el vehículo se está alejando del punto destino, por lo que si se está en el cuadrante 1 y si hay más distancia entre el eje vertical y el vehículo, que entre el eje horizontal y este, o la 63 distancia es la misma, se debe hacer un giro a la derecha, para mantenerse dentro del mismo cuadrante, y así poder aproximarse al punto destino. b. Invertir dirección izquierda: Se encarga de invertir en 180º la orientación del vehículo, pero haciendo el giro hacia la izquierda. Si el vehículo se está alejando del punto destino, pero este se encuentra más cerca del eje horizontal que del vertical, el giro debe realizarse hacia la izquierda, con la intención de mantenerse en el mismo cuadrante. c. Medio giro derecha: Realiza un giro de 90º hacia la derecha. Si dstlat1 < dstlat 2 , pero dstlon1 > dstlon 2 , esto significa que el vehículo se está alejando horizontalmente del destino, pero se está acercando verticalmente. En otras palabras; visto desde el primer cuadrante, el “rover” tiene un sentido suroeste, lo cual lo aleja del punto y lo hará cambiar de cuadrante en un futuro. Para tratar de orientarlo hacia el destino, el robot deberá hacer un giro de 90º haci a la derecha. d. Medio giro izquierda: Realiza un giro de 90º hacia la izquierda. Si por el contrario el vehículo toma una dirección noreste, la acción que debe hacerse para corregir el rumbo, deberá ser un giro de 90º a la izquierda. e. Horizontal por la derecha: Alínea al vehículo con el eje horizontal, realizando pequeños ajustes en la dirección siempre hacia la derecha. Una vez que el “rover” tiene una orientación favorable hacia el punto destino, si la distancia con el eje vertical disminuye más que lo que disminuyó la distancia con el eje horizontal, entonces 64 es más fácil para el robot alinearse con el eje horizontal, de modo que esta rutina lo facilita. f. Horizontal por la izquierda: Alínea al vehículo con el eje horizontal, realizando pequeños ajustes en la dirección siempre hacia la izquierda. Esta rutina sólo es útil en los cuadrantes 2 y 4. g. Vertical por la derecha: Alínea al “rover” con el eje vertical, realizando pequeños ajustes en la dirección siempre hacia la derecha. Esta rutina sólo es útil en los cuadrantes 2 y 4. h. Vertical por la izquierda: Alínea al “rover” con el eje vertical, realizando pequeños ajustes en la dirección siempre hacia la izquierda. Una vez que el “rover” tiene una orientación favorable hacia el punto destino, si la distancia con el eje vertical disminuye menos que lo que disminuyó la distancia con el eje horizontal, entonces es más fácil para el robot alinearse con el eje vertical, y se logra por medio de esta rutina. i. Aproximación escalera derecha: Una vez que se ha alineado el vehículo con algún eje a su derecha, se inicia la aproximación al destino, describiendo una escalera. Esto se hace por dos razones, la primera se debe a que es una forma de reducir la distancia viajada, y la segunda porque una vez que se ha cumplido con la precisión solicitada respecto al eje al cual se está en paralelo; al aproximarse de esta forma, lo único que se debe hacer es continuar lentamente hacia delante, hasta que se cumpla con la precisión deseada en el otro eje. 65 j. Aproximación escalera izquierda: Una vez que se ha alineado el vehículo con algún eje a su derecha, se inicia la aproximación al destino, describiendo una escalera. Esto se hace por dos razones, la primera se debe a que es una forma de reducir la distancia viajada, y la segunda porque una vez que se ha cumplido con la precisión solicitada respecto al eje al cual se está en paralelo; al aproximarse de esta forma, lo único que se debe hacer es continuar lentamente hacia delante, hasta que se cumpla con la precisión deseada en el otro eje. Las rutinas anteriores hacen uso de la función ruta, descrita en el programa Progps1. A manera de resumen, se enumerarán los pasos que realiza el programa, en el supuesto caso de que se ubique el “rover” en el cuadrante número 1 respecto al destino y este quede orientado en la dirección noreste (alejándose del destino): 1. Se abren y configuran tanto el puerto que comunica la base con la tarjeta controladora de servos, como el puerto que recibe la información del sistema GPS. 2. Se hace un llamado a la función marcadestino, del objeto com1 tipo clase puertoserial, la cual guía al usuario para que pueda marcar el punto destino. Una vez que ha sido marcado, le indica al usuario que coloque al “rover” en el punto de partida. 3. El programa hace uso de la función escribir, del objeto com2 tipo clase puertoserial1, para centrar la dirección del vehículo, la cual durante la marcación del destino o la colocación en el punto de partida pudo ser alterada. 66 4. Luego se almacena la cadena de caracteres enviada por el receptor GPS, mediante la función leer del objeto com1 tipo clase puertoserial. 5. Seguidamente se utiliza la función desfragmentar; perteneciente al objeto com1, la cual separa la información útil enviada por el receptor GPS. 6. Después de tener la primera cadena de datos útiles, y de haberlos separado, mediante las funciones distlatitud y distlongitud; pertenecientes al objeto com1, se calcula la distancia vertical y horizontal que existe entre la ubicación actual y el punto destino. 7. Una vez que se han almacenado estas distancias, se utiliza la función escribir; del objeto com2, para generar un avance hacia delante en el vehículo durante 1 segundo, inmediatamente se vuelve a utilizar la misma función para detenerlo. 8. Mediante la función cuadrante; perteneciente al objeto com1, se almacena el cuadrante en que se encontraba el “rover” antes de realizar el avance. 9. Se repiten los pasos 4, 5 y 6, para determinar las nuevas distancias vertical y horizontal respecto al punto destino. 10. El paso 8 se repite para almacenar el cuadrante actual. 11. Por medio de la función distnav; perteneciente al objeto com1, se averigua la hipotenusa que se forma con las distancias en latitud y en longitud. 12. Se realizan dos comparaciones: la primera es entre el cuadrante actual y el anterior, y la segunda es un chequeo; a partir de la información obtenida en el punto 11, 67 para constatar si ya se cumplió con la precisión solicitada. En caso de que haya ocurrido un cambio de cuadrante y de que la distancia máxima solicitada respecto al punto destino no se haya alcanzado, se provoca un salto al paso 3 y se inicia el proceso. En caso contrario el programa sigue ejecutándose normalmente. Esto se debe a que al haber un cambio de cuadrante la toma de decisiones se imposibilita, ya que estas dependen del patrón que ha seguido el vehículo, y claramente del cuadrante en que esté ubicado. 13. Se vuelve a comparar si la separación máxima entre el punto destino y el “rover” se ha alcanzado, en caso contrario se ejecuta una decisión a partir del patrón de avance del vehículo. En este caso particular, dado que el vehículo se alejó del punto tanto en latitud como en longitud, dependiendo de cual variación fue mayor, así elegirá el programa hacia donde realizar el giro de 180º que le permita tomar rumbo hacia el destino. Luego de realizar la rutina, se indaga si se llegó al destino, en cuyo caso se provoca un salto al final del programa, sino se salta al paso 3 y así inicia de nuevo la aproximación al destino. Las siguientes decisiones que se tomen dependen de la distancia del punto de partida respecto al destino. Pero en caso de que esta haya sido suficiente, el “rover” una vez orientado hacia al destino, buscará el eje con el cual le sea más sencillo alinearse, y una vez alineado procederá a aproximarse describiendo un patrón de escalera o serpenteo hacia el destino. Tan pronto cumpla con la precisión solicitada respecto a alguno de los ejes, si el 68 eje es el correcto sólo tendrá que aproximarse mediante avances frontales, sino deberá ejecutar un giro de 90º y seguir avanzando hasta cumplir con la precisión solicitada. 5.2 Descripción del código fuente A continuación se presenta una descripción del código fuente, el cual puede ser encontrado en el apéndice. Lo primero que se puede encontrar en el código son las acostumbradas librerías que se han venido utilizando con anterioridad. Sólo se agregó una adicional que es la librería math.h, la cual entre otras cosas facilita la tarea de obtener la distancia del “rover” respecto al destino, ya que permite calcular el arco seno de una expresi ón. Seguidamente se pueden encontrar la definición de constantes utilizadas en las funciones escribir y ruta de la clase puertoserial1, así como constante que representa la precisión solicitada. Este proceder permite hacer cambios al programa de una manera sencilla, precisa y segura, sin afectar el código en si. Luego se definen las variables globales que pueden ser usadas tanto en el manejo de objetos tipo alguna de las clases como en la función main. Después se definen las dos clases que se van a utilizar posteriormente en la función main, las cuales son: puertoserial y puertoserial1. La primera está asignada específicamente al GPS, por lo que contiene todas las funciones que permite hacer un manejo de esta información. La segunda abarca el movimiento del “rover”, ya que se encarga de dirigir la tarjeta controladora de servomotores. Debido a que sólo se contaba 69 con un puerto serial en la computadora en la que se desarrolló básicamente todo el programa, fue que se adquirió un adaptador USB que permitiera simular un puerto serial extra. Por defecto la clase puertoserial hace uso directo del puerto serial existente, mientras que la clase puertoserial1 utiliza el adaptador. La elección se hizo por conveniencia, ya que la forma de comunicación con el GPS es más compleja que con la tarjeta de servomotores, y se prefirió darle la mayor transparencia posible. La clase puertoserial cuenta con siete funciones. La primera se llama leer y se encarga de tomar la cadena de caracteres enviada por el GPS, analizar que sea información válida y almacenarla en infogps. Luego se cuenta con la función desfragmentar, que se encarga de separar la información y almacenarla en variables que permitan su uso y modificación. Adicionalmente se tiene la función distnav, la cual realiza los cálculos necesarios para averiguar la distancia entre dos pares de latitudes y longitudes. Esta función hace uso de la siguiente ecuación: d  acos(sin(Lat1)  sin(Lat2)  cos(Lat1) cos(Lat2) cos(Lon1 Lon2)) (5.2-1) La razón del porque no se utilizó la ecuación de Pitágoras, donde “x” sería el valor absoluto de la diferencia de latitudes y “y” el valor absoluto de la diferencia de longitudes, 2 es porque este resultado es correcto únicamente en la cercanía de 300 , pero luego de eso se deteriora rápidamente. La ecuación de Pitágoras se muestra a continuación: d  x2  y2 (5.2-2) 70 Además, debido a que el Teorema de Pitágoras es útil sólo en dos dimensiones y dado que la perspectiva de este proyecto es ser la base de un vehículo aéreo, donde la tercera dimensión espacial juega un papel crucial en la navegación, el teorema no aplica en este caso. De modo que previendo esto es que se prefirió “dejar el camino preparado”. Luego se cuenta con las funciones distlatitud y distlongitud, las cuales se encargan de realizar la resta entre la latitud destino y la actual y la longitud destino y la actual, devolviendo así la distancia que existe entre el eje “x” y vehículo y el “y” y el vehículo, respectivamente. Esta clase también cuenta con la función marcadestino, la cual guía al usuario para marcar el punto destino, y almacena al mismo tiempo la información de latitud y longitud destino. Por último se cuenta con la función cuadrante, la cual permite averiguar en cual cuadrante; respecto al punto destino, se encuentra el “rover”. Para realizar esta función utiliza las distancias en latitud y longitud existentes entre el punto destino y el vehículo. La otra clase; puertoserial1, es la misma clase que se utiliza en el programa Progps1, y que ya fue explicada. Dado que en ese momento no se tenía la necesidad de un segundo puerto serial, la clase adoptó el nombre de puertoserial, lo cual se puede prestar a confusiones al tratar de asociar esta clase en ambos programas. Pero se espera que al aclarar este hecho, se pueda distinguir en que la única diferencia entre la clase del programa Progps1 y la clase puertoserial1 del programa ProGPSfinal, es simplemente su nombre. 71 El final del código está compuesto por la función main, la cual ya fue explicada al describir el método con el que el “rover” busca el destino. Esta función es sólo la puesta en práctica de las demás funciones pertenecientes a las dos clases mencionadas. 5.3 Resultados obtenidos en la segunda etapa de desarrollo de software Se realizaron varias pruebas de campo para este programa, en las cuales se alcanzó una precisión menor a los 3 metros, partiendo de una distancia respecto al punto destino de aproximadamente 25 m. Se habla de menor a los tres metros debido a que dependía de dos factores, el primero corresponde al tipo de rutina que era ejecutada por última vez, y el segundo; que está íntimamente relacionado con el primero, a la distancia existente entre el radio de precisión solicitado y la posición en la que se iniciaba la última rutina. Cuando se solicitaba una precisión menor, el vehículo giraba alrededor del punto destino. Esto se debió a que el servomotor de la dirección no permitía realizar giros de 180º exactos, sino giros de 170º; por ejemplo, de modo que el error era arrastrado y esto evitaba alcanzar el objetivo con una mayor precisión. Vale la pena destacar que cuando se realizaban pruebas a cortas distancias (alrededor de 5 metros) del punto de partida, el “rover” alcanzaba su destino con una precisión ligeramente mayor a 1 m. Se alargó la barra de la dirección que enlaza el servomotor de la dirección con la rueda izquierda delantera, permitiendo así obtener; partiendo del punto neutro del servomotor, un verdadero ángulo de 90º con el extensor del servomotor, aumentando así el par aplicado a las ruedas. Adicionalmente se cambió el servomotor de la dirección por uno 72 de mayor torque (2,33 Nm). Estas dos pequeñas variantes en el diseño original, permitieron programar rutinas de giros de exactamente 180º sobre el punto de inicio de la rutina, con lo cual se puede asegurar que la precisión del “rover”; partiendo de distancias de 25 m o mayores del punto de partida, puede llegar a ser tan buena como la obtenida a distancias alrededor de los 5 metros (precisión de 1 m). En el disco compacto de anexos se muestran videos de los resultados obtenidos en estas pruebas de campo. 73 CAPÍTULO 6: Conclusiones y recomendaciones 6.1 Conclusiones Dentro de las principales conclusiones obtenidas a partir del desarrollo del proyecto y de los resultados del mismo, se tiene:  Fue posible diseñar, construir e implementar un sistema de navegación a partir de un receptor GPS y un código que permitiera el manejo tanto de la información geoposicional como del robot objeto de control.  Se pudo realizar un levantamiento adecuado de los requerimientos del proyecto, lo cual permitió tener un horizonte claro durante todo el proyecto.  Las investigaciones realizadas permitieron adquirir conocimientos muy valiosos, los cuales fueron aplicados tanto en el diseño del vehículo, como el uso de la información geoposicional.  El diseño inicial del vehículo fue un éxito. Sólo una mejora en el sistema de dirección fue necesaria para aumentar la precisión del robot.  La elección del tipo de locomoción del vehículo depende de las características del proyecto a realizar tales como el tipo de terreno y la velocidad requerida.  Se logró realizar un manejo adecuado de la información proporcionada por el GPS, al desfragmentarla y almacenarla en varias variables para su posterior uso.  La mejor forma de trabajar las latitudes y las longitudes es en radianes. 74  Al restarle las coordenadas del punto destino a la ubicación actual del vehículo fue posible determinar; tanto la distancia respecto al punto destino como la ubicación en un “nuevo cuadrante”, facilitando así el planeamiento de la ruta de navegación del vehículo.  El vehículo puede alcanzar una precisión de hasta 1 m en la búsqueda del punto destino. Esta distancia se considera buena, pero puede mejorar al utilizar señales de corrección RTK.  Se comprendió que para el desarrollo de un proyecto el uso de plataformas libres siempre es la mejor ruta a seguir, debido a la flexibilidad y a la libertad que proporcionan.  Dado que el sistema de posicionamiento global satelital hace honor a su nombre al captar las señales que envían los satélites de la constelación NAVSTAR, el mismo no funciona bien en interiores, debido a que estas señales son microondas. Es por esto que el “rover” puede ser usado únicamente en exteriores.  El “rover” no funciona adecuadamente en días con mucha nubosidad y más bien presenta un comportamiento errático.  La base para un futuro proyecto que involucre la navegación de un vehículo aéreo se ha establecido.  La utilización de un receptor GPS con su respectiva antena; en lugar de un chip y una antena “hecha en casa”, fue determinante para cumplir con el plazo de tiempo 75 requerido, gracias a que eliminó posibles fuentes de error que pudieron haber retrasado al proyecto.  El control electrónico de velocidad (ESC) es una pieza clave en el sistema de alimentación del vehículo de este proyecto por dos razones: la primera es que controla los motores de las ruedas y la segunda está ligada a su regulador de voltaje, puesto que funge como la fuente de corriente directa que permite a la tarjeta controladora de servomotores crear las señales PWM. Juntas hacen posible la movilidad al vehículo. 6.2 Recomendaciones Gracias al conocimiento y a las experiencias adquiridas durante este proyecto, se desea agregar unas cuantas recomendaciones que pueden resultar útiles a la hora de realizar optimizaciones a este proyecto, o para otros que estén interesados en proyectos similares.  Dado que se comprobó que el proyecto funciona, ahora es más fácil implementar una etapa de comunicación inalámbrica que le permita más autonomía al vehículo y al mismo tiempo alcanzar mayores distancias.  También se sugiere agregar un sistema de evasión de obstáculos que combine sensores infrarrojos, sónicos y de video. La información que se adquiera deberá ser procesada y a partir de la misma se debe modificar la ruta establecida, permitiendo al vehículo evadir el obstáculo, pero a la vez desviándose lo menos posible, para así lograr siempre una ruta óptima. 76  Una vez que se hayan implementado la etapa inalámbrica y la de evasión de obstáculos, se debe sustituir el sistema GPS utilizado, por uno de menor peso. De modo que el primer vehículo aéreo no tripulado fabricado por la Universidad de Costa Rica sea una realidad. 6.2.1  Recomendaciones generales Con la intención de cumplir con el objetivo principal de un proyecto en general, es preferible reducir la complejidad de los pasos que se deben seguir, para así eliminar posibles fuentes de error, las cuales; a pesar de que su solución sea muy simple, a la hora de discriminarlas y encontrarlas pueden acaparar valioso tiempo del desarrollo del proyecto, y hasta cambiar la ruta del mismo.  Los sensores utilizados en un robot móvil dependen del tipo de obstáculos que se encuentren y las características del entorno donde se desplace el mismo. Los sensores infrarrojos se ven afectados por el sol o por las superficies opacas. Los sensores sónicos pueden resultar afectados de las frecuencias similares que circulen en el ambiente. Es por ello que para contar con un sistema de evasión de obstáculos confiable, la combinación de diferentes tipos de sensores es la clave.  Un proyecto como este puede resultar realmente costoso, especialmente si se ubica en una región como Costa Rica, donde la mayoría de las piezas electrónicas no se consiguen fácilmente y hay que acudir a intermediarios o comprarlas por Internet, por lo que se debe estar preparado para las demoras y contratiempos que este proceso puede representar. 77  El presupuesto de una universidad estatal; como lo es la Universidad de Costa Rica es muy reducido, por lo que no se debe esperar ayuda económica de la misma, ni dejar que esto sea un motivo para rechazar proyectos de desarrollo como este. La empresa privada de tecnología; aunque escasa en nuestro país, existe y recurrir a estas puede ser una forma de reducir costos para el desarrollo de un proyecto de calidad. 78 BIBLIOGRAFÍA Artículos de revistas: 1. Cerón Correa, A. “Sistemas Robóticas Teleoperador”, Ciencia e Ingeniería Neogranadina, Colombia, Vol [15], 2005. 2. Gage, D. “A Brief History of Unmanned Ground Vehicle (UGV) Development Efforts”, Unmanned Systems Magazine, Estados Unidos, Vol [13] Nº [3], 1995. Libros: 3. Barrientos, A. “Fundamentos de Robótica”, 1 edición, Mc Graw-Hill, España, 1997. 4. Jiménez Vega, N. “Software para procesamiento de datos GPS”. 1 edición, Universidad Politécnica de Cataluña, España, 2006. Manuales de operación: 5. Agriculture Business Area, T. (2004). NMEA-0183 Messages: Guide for AgGPS Receivers. Kansas: Trimble. 6. Trimble Navigation Limited, A. (2004). AgGPS 132: Combination DGPS receiver with The Choice technology. Dayton, Ohio: Trimble. 7. Trimble, T. (2001). AgGPS® 124/132: Manual de operación. Sunnyvale, CA: Trimble. Páginas Web: 8. “Build a Serial Interface for the Mini SSC II Servo Controller”. http://www.rentron.com/Mini-ssc.htm 79 9. Chauhan, D. “Writing a Serial Communication Library for Windows”. http://www.aspfree.com/c/a/Code-Examples/Writing-a-Serial-CommunicationLibrary-for-Windows 10. “GPS Tutorial”. http://www.trimble.com/gps/index.html 11. Pozo Coronado, S. “Con Clase”. http://www.conclase.net 12. Stefan, J. “Circuit Cellar - Digital Library - 123 Stefan”. http://www.circuitcellar.com/library/print/1000/Stefan123/4.htm 13. “Uso del GPS Parrte 1: mapas georeferenciadas y computador para el vuelo libre”. http://www.parapente-costarica.org/new/index.php?option=com_content&task=view&id=39&Itemid=89 14. Von Martini, A., Bragachini, M., & Bianchini, A. “Sistemas de Posicionamiento”. http://www.agriculturadeprecision.org/sistpos/SistemasPosicionamiento.htm 15. W, B. “Build a Serial Interface for the Mini SSC II Servo Controller”. Retrieved March 12, 2008, from http://www.rentron.com/Mini -ssc.htm. 16. “freshmeat.net: Project details for libserial”. http://freshmeat.net/projects/libserial/. 80 APÉNDICES 81 Apéndice 1: Planos de diseño del armazón del vehículo 82 Figura Apéndice 1-1 Vista superior del armazón utilizado para instalar los componentes electrónicos sobre el vehículo 83 Figura Apéndice 1-2 Vista lateral del armazón utilizado para instalar los componente s electrónicos sobre el vehículo Figura Apéndice 1-3 Vista frontal del armazón utilizado para instalar los componentes electrónicos sobre el vehículo 84 Figura Apéndice 1-4 Vista superior del armazón utilizado para instalar los componentes electrónicos sobre el vehículo y de la unión al sistema de suspensión de los motores del vehículo 85 Figura Apéndice 1-5 Vista lateral del armazón utilizado para instalar los componentes electrónicos sobre el vehículo y de la unión al sistema de suspensión de los motores del vehículo 86 Figura Apéndice 1-6 Vista frontal del armazón utilizado para instalar los componentes electrónicos sobre el vehículo y de la unión al sistema de suspensión de los motores del vehículo 87 Figura Apéndice 1-7 Dimensiones de las piezas utilizadas para unir el armazón utilizado para instalar los componentes electrónicos sobre el vehículo y el sistema de suspensión de los motores del vehículo 88 Apéndice 2: Código ProyectoGPS.exe 89 Private Sub Barra1_Change() Text1.Text = Str(Barra1.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(0) ' Selecciona el servo #1 MSComm1.Output = Chr$(Text1.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra1_Scroll() Barra1_Change End Sub Private Sub Barra2_Change() Text2.Text = Str(Barra2.Value) ' En vía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(1) ' Selecci ona el servo #2 90 MSComm1.Output = Chr$(Text2.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra2_Scroll() Barra2_Change End Sub Private Sub Barra3_Change() Text3.Text = Str(Barra3.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(2) ' Selecciona el servo #3 MSComm1.Output = Chr$(Text3.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra3_Scroll() Barra3_Change 91 End Sub Private Sub Barra4_Change() Text4.Text = Str(Barra4.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincro nización requerido por el controlador de los servos. MSComm1.Output = Chr$(3) ' Selecciona el servo #4 MSComm1.Output = Chr$(Text4.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra4_Scroll() Barra4_Change End Sub Private Sub Barra5_Change() Text5.Text = Str(Barra5.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(4) ' Selecciona el servo #5 92 MSComm1.Output = Chr$(Text5.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra5_Scroll() Barra5_Change End Sub Private Sub Barra6_Change() Text6.Text = Str(Barra6.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(5) ' Selecciona el servo #6 MSComm1.Output = Chr$(Text6.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra6_Scroll() Barra6_Change End Sub 93 Private Sub Barra7_Change() Text7.Text = Str(Barra7.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(6) ' Selecciona el servo #7 MSComm1.Output = Chr$(Text7.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra7_Scroll() Barra7_Change End Sub Private Sub Barra8_Change() Text8.Text = Str(Barra8.Value) ' Envía el valor que tenga la barra (0 a 254) al cuadro de texto MSComm1.Output = Chr$(255) ' Envía el Bit de sincronización requerido por el controlador de los servos. MSComm1.Output = Chr$(7) ' Selecciona el servo #8 94 MSComm1.Output = Chr$(Text8.Text) ' Envía el valor que se encuentra en el cuadro de texto (la posición) al controlador de los servos. End Sub Private Sub Barra8_Scroll() Barra8_Change End Sub Private Sub Command1_Click() End Sub Private Sub CentrarBar1_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(0) ' Envía el # del servo al servo controlador. MSComm1.Output = Chr$(127) Text1.Text = Str(127) Barra1.Value = Text1.Text End Sub Private Sub CentrarBar2_Click() ' Envía el valor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. ' Posiciona la barra en el centro. 95 MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(1) MSComm1.Output = Chr$(127) Text2.Text = Str(127) ' Envía el # del servo al servo controlador. ' Envía el valor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. Barra2.Value = Text2.Text ' Posiciona la barra en el centro. End Sub Private Sub CentrarBar3_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(2) ' Envía el # del servo al servo controlador. MSComm1.Output = Chr$(127) Text3.Text = Str(127) ' Envía el valor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. Barra3.Value = Text3.Text ' Posiciona la barra en el centro. End Sub Private Sub CentrarBar4_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(3) MSComm1.Output = Chr$(127) ' Envía el # del servo al servo controlador. ' Envía el valor de 127 al servo controlador. 96 Text4.Text = Str(127) ' Actualiza el valor del cuadro de texto con 127. Barra4.Value = Text4.Text ' Posiciona la barra en el centro. End Sub Private Sub CentrarBar5_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(4) ' Envía el # del servo al servo contr olador. MSComm1.Output = Chr$(127) Text5.Text = Str(127) ' Envía el valor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. Barra5.Value = Text5.Text ' Posiciona la barra en el centr o. End Sub Private Sub CentrarBar6_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(5) ' Envía el # del servo al servo controlador. MSComm1.Output = Chr$(127) Text6.Text = Str(127) Barra6.Value = Text6.Text End Sub ' Envía el valor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. ' Posiciona la barra en el centro. 97 Private Sub CentrarBar7_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(6) ' Envía el # del servo al servo controlador. MSComm1.Output = Chr$(127) Text7.Text = Str(127) ' Envía el valor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. Barra7.Value = Text7.Text ' Posiciona la barra en el centro. End Sub Private Sub CentrarBar8_Click() MSComm1.Output = Chr$(255) ' Envia el bit de sincronización requerido por el servo controlador. MSComm1.Output = Chr$(7) ' Envía el # del servo al servo controlador. MSComm1.Output = Chr$(127) Text8.Text = Str(127) Barra8.Value = Text8.Text ' Envía el v alor de 127 al servo controlador. ' Actualiza el valor del cuadro de texto con 127. ' Posiciona la barra en el centro. End Sub Private Sub Form_Load() MSComm1.Settings = "9600,N,8,1" ' Bits por segundo =9600, Sin paridad, 8 -bits de datos, 1 bit de parada. 98 MSComm1.CommPort = 1 ' Com1 será el puerto com predefinido. MSComm1.PortOpen = True ' Abriendo el puerto para ser usado. End Sub Private Sub Timer1_Timer() End Sub Private Sub mnuCom19600_Click() If MSComm1.PortOpen = True Then MSComm1.PortOpen = False End If MSComm1.Settings = "9600,N,8,1" MSComm1.CommPort = 1 MSComm1.PortOpen = True End Sub Private Sub mnuCom29600_Click() If MSComm1.PortOpen = True Then MSComm1.PortOpen = False End If MSComm1.Settings = "9600,N,8,1" 99 MSComm1.CommPort = 2 MSComm1.PortOpen = True End Sub Private Sub Salida_Click() If MSComm1.PortOpen = True Then MSComm1.PortOpen = False End If End End Sub Private Sub VScroll1_Change() End Sub 100 Apéndice 3: Código Progps1 101 #include #include #include #include #include #include using namespace std; using namespace LibSerial ; #define admin = 0; #define admed = 1; #define admax = 2; #define atmin = 3; #define atmed = 4; #define atmax = 5; #define demin = 6; #define demed = 7; #define decom = 8; #define izmin = 9; #define izmed = 10; #define izmax = 11; #define centro = 12; 102 #define freno = 13; class puertoserial { public: // Constructor puertoserial(); // Funciones miembro de la clase "puertoserial" void escribir(char servo, char desplazamiento); void ruta(int instruc[],int numinstruc); void cerrar(); private: // Datos miembro de la clase "puertoserial" SerialStream serial_port ; //const char* const SERIAL_PORT_DEVICE = "/dev/ttyS0" ; //char servo; //char desplazamiento; // protected: //using namespace LibSerial ; 103 public: //SerialStream serial_port ; //const char* const SERIAL_PORT_DEVICE = "/dev/ttyS0" ; }; puertoserial::puertoserial(){ const char* const SERIAL_PORT_DEVICE = "/dev/ttyUSB0" ; // Utilizando namespace LibSerial ; // SerialStream serial_port ; serial_port.Open( SERIAL_PORT_DEVICE ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not open serial port " << SERIAL_PORT_DEVICE << std::endl ; exit(1) ; } // 104 // Configurando la tasa de baudios del puerto serial // serial_port.SetBaudRate( SerialStreamBuf::BAUD_38400 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Coul d not set the baud rate." << std::endl ; exit(1) ; } // // Configurando el número de bits. // serial_port.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could no t set the character size." << std::endl ; exit(1) ; } // // Deshabilitando la paridad // serial_port.SetParity( SerialStreamBuf::PARITY_NONE ) ; if ( ! serial_port.good() ) 105 { std::cerr << "Error: Could not disab le the parity." << std::endl ; exit(1) ; } // // Configurando el bit de parada // serial_port.SetNumOfStopBits( 1 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the number of stop bits." << std::endl ; exit(1) ; } // // Iniciando el control de flujo del hardware // serial_port.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ; if ( ! serial_port.good() ) { std::cerr << "Error : Could not use hardware flow control." << std::endl ; 106 exit(1) ; } //return EXIT_SUCCESS ; } void puertoserial::escribir(char servo, char desplazamiento) { char info[] = {255,0,0}; info[1]=servo; info[2]=desplazamiento; serial_port.write(info,3 ) ; sleep(1); } void puertoserial::ruta(int instruc[],int numinstruc) 107 { int a = numinstruc; char info[3]; for(int i=0; i < a;i++) { switch( instruc[i]) { case 0:{ info[0]= 255; info[1]=0; info[2]=70; serial_port.write(info,3 ); break; } case 1:{ info[0]= 255; info[1]=0; info[2]=70; 108 serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=70; serial_port.write(info,3 ); break; } case 2:{ info[0]= 255; info[1]=0; info[2]=45; serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=45; serial_port.write(info,3 ); break; } case 3:{ info[0]= 255; 109 info[1]=0; info[2]=180; serial_port.write(info,3 ); break; } case 4:{ info[0]= 255; info[1]=0; info[2]=180; serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=180; serial_port.write(info,3 ); break; } case 5:{ info[0]= 255; info[1]=0; info[2]=215; serial_port.write(info,3 ); 110 sleep(1); info[0]= 255; info[1]=0; info[2]=215; serial_port.write(info,3 ); break; } case 6:{ info[0]= 255; info[1]=1; info[2]=93; serial_port.write(info,3 ); break; } case 7:{ info[0]= 255; info[1]=1; info[2]=71; serial_port.write(info,3 ); break; } case 8:{ 111 info[0]= 255; info[1]=1; info[2]=56; serial_port.write(info,3 ); break; } case 9:{ info[0]= 255; info[1]=1; info[2]=133; serial_port.write(info,3 ); break; } case 10:{ info[0]= 255; info[1]=1; info[2]=155; serial_port.write(info,3 ); break; } case 11:{ info[0]= 255; 112 info[1]=1; info[2]=170; serial_port.write(info,3 ); break; } case 12:{ info[0]= 255; info[1]=1; info[2]=114; serial_port.write(info,3 ); break; } case 13:{ info[0]= 255; info[1]=0; info[2]=127; serial_port.write(info,3 ); break; } default:{ cout<<"Instrucción inválida...Aplicando freno y centrando el steer..."<>opcion; if(opcion==14){ if(TAMARREGLO ==0){ 116 cout<<"Usted no trazó ninguna ruta.\n\n Finalizando el programa..."< #include #include #include #include #include #include #include /* Función strlen() */ #include /* Modos de apertura y función open()*/ #include /* Funciones write() y close() */ //Definición de constantes que permiten cambiar el valor de alguna definición, sin alterar al programa //para utilizarlas en la función ruta int invdirderecha[] = {8,1,13,12,11,4,13,12,8,1,13,12,11,4,13 ,9,4,13,12,8,1,13,12,11,4,13,12,8,1,13,12,11,4,13,9, 4,13,12};//Rutina de giro de 180º hacia la derecha #define invdird 38 int invdirizquierda[] = {11,1,13,12,8,4,13,12,11,1,13,1,13,12,6,4,3,13,12,11,1,13,12,8,4,13,12,11,1,13,1,13,12,6,4, 4,13,12};//Rutina de giro de 180º hacia la izquierda #define invdiri 38 int medgiroderecha[] = {8,1,13,12,11,4,13,12,8,1,13,12,11,4,13,9,4,13,12};//Rutina de giro de 90º hacia la derecha #define medgd 19 int medgiroizquierda[] = {11,1,13,12,8,4,13,12,11,1,13,1,13,12,6,4,3,13 ,12};//Rutina de giro de 90º hacia la izquierda #define medgi 19 int escalderecha[] = {11,4,13,12,8,2,13,12,11,1,1,13,12};//Rutina para la aproximación al punto deseado por medio de una ruta en forma de escalera hacia la derecha. #define escd 13 int escalizquierda[] = {8,4,13,12,11,2,13,12,8,1,1,0,13,12};//Rutina para la aproximación al punto deseado por medio de una ruta en forma de escalera hacia la izquierda. #define esci 14 //Definición de constantes que permiten cambiar el valor de alguna definición, sin alterar al programa //para utilizarlas en la función escribir #define izqmin 133 #define izqmed 155 #define izqmax 170 #define dermin 93 120 #define dermed 71 #define dermax 56 #define admin 70 #define admed 70 #define admax 45 #define atmin 180 #define atmed 180 #define atmax 215 #define freno 127 #define centro 114 #define steer 1 #define motor 0 //Precisión #define maxdist 1000 //Para utilizarlas en la función ruta #define advelmin 0 #define advelmed 1 #define advelmax 2 #define atvelmin 3 #define atvelmed 4 #define atvelmax 5 #define degirmin 6 #define degirmed 7 #define degirmax 8 #define izgirmin 9 #define izgirmed 10 #define izgirmax 11 #define centrar 12 #define frenar 13 using namespace std; using namespace LibSerial ; //Definición de variables globales char infogps[] = "$GPRMC,184804.00,A,3723.476543,N,12202.239745,W,000.0,0.0,051196,15.6,E*7C"; char infogpsdestino[] = "$GPRMC,184804.00,A,3723.476543,N,12202.239745,W,000.0,0.0,051196,15.6,E*7C"; char horaUTC[]= "hhmmss.ss"; char estadogps[]="X"; 121 char latitudGPS[] = "0dmm.0000000"; char latdegGPS[] = "dd"; char latminGPS[] = "mm.0000000"; char dlatitud[] = "X"; char longitudGPS[] = "0ddmm.0000000"; char londegGPS[] = "ddd"; char lonminGPS[] = "mm.0000000"; char dlongitud[] = "X"; char velsuelo[] = "000.00"; char pasadagrados[] = "0.0"; char fecha[] = "ddmmaa"; char variamag[] = "00.0"; char dvariamag[] = "X"; int latdeg, londeg, cuadranteactual; long double hora, latmin, lonmin, veloc, pasadgrad, varimagn, latituddeg, longituddeg,latitud,longitud, latdestino, londestino,latituddegdestino,longituddegdestino; //Definición de la clase puertoserial. Comunicación con el receptor GPS class puertoserial { public: // Constructor puertoserial(); // Funciones miembro de la clase "puertoserial" int leer(); void desfragmentar(char infgps[]); void marcadestino(); int cuadrante(long double distancialat, long double distancialon); long double distnav(long double latA = latitud, long double lonA = longitud, long double latB = latdestino, long double lonB = londestino); long double distlatitud(long double latA = latitud, long double latB = latdestino); long double distlongitud(long double lonA = longitud, long double lonB = londestino); 122 private: // Datos miembro de la clase "puertoserial" SerialStream serial_port ; }; puertoserial::puertoserial(){ const char* const SERIAL_PORT_DEVICE = "/dev/ttyUSB1" ; // Utilizando namespace LibSerial ; // SerialStream serial_port ; serial_port.Open( SERIAL_PORT_DEVICE ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not open serial port " << SERIAL_PORT_DEVICE << std::endl ; exit(1) ; } // // Configurando la tasa de baudios del puerto serial // serial_port.SetBaudRate( SerialStreamBuf::BAUD_38400 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the baud rate." << std::endl ; exit(1) ; } // // Configurando el número de bits. // serial_port.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the character size." << std::endl ; exit(1) ; } // // Deshabilitando la paridad // serial_port.SetParity( SerialStreamBuf::PARITY_NONE ) ; if ( ! serial_port.good() ) { 123 std::cerr << "Error: Could not disable the parity." << std::endl ; exit(1) ; } // // Configurando el bit de parada // serial_port.SetNumOfStopBits( 1 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the number of stop bits." << std::endl ; exit(1) ; } // // Iniciando el control de flujo del hardware // serial_port.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not use hardware flow control." << std::endl ; exit(1) ; } //return EXIT_SUCCESS ; } int puertoserial::leer() { Again: // esta es la etiqueta que permite iniciar el proceso en caso de que NO se haya obtenido una cadena de info valida char next_byte; int e=0; int i=1; int coma =0; int entre = 1; while(e==0) { cout<<"Entró al while"<in_avail() > 0 && entre == 1 ) { cout<<"hay info en el puerto"<in_avail() > 0 && entre == 1) { char next_byte; serial_port.get(next_byte); //std::cerr << std::hex << (int)next_byte;// << " "; cout<in_avail() > 0 && entre == 1 ) { cout<<"hay info en el puerto"<in_avail() > 0 && entre == 1) { char next_byte; serial_port.get(next_byte); cout<0) { a=1;//El rover se encuentra en el primer cuadrante } if(distancialat<0 && distancialon<0) { a=2;//El rover se encuentra en el segundo cuadrante } if(distancialat>0 && distancialon<0) { a=3;//El rover se encuentra en el tercer cuadrante 134 } if(distancialat>0 && distancialon>0) { a=4;//El rover se encuentra en el cuarto cuadrante } if(distancialat==0 && distancialon>0) { a=5;//El rover se encuentra en el eje x positivo } if(distancialat<0 && distancialon==0) { a=6;//El rover se encuentra en el eje y positivo } if(distancialat==0 && distancialon>0) { a=7;//El rover se encuentra en el eje x negativo } if(distancialat>0 && distancialon==0) { a=8;//El rover se encuentra en el eje y negativo } return a;//Permite almacenar el cuadrante desde la función principal } //Definición de la clase puertoserial1. Comunicación con la tarjeta controladora de servomotores class puertoserial1 { public: // Constructor puertoserial1(); // Funciones miembro de la clase "puertos erial" void escribir(char servo, char desplazamiento); void ruta(int instruc[],int numinstruc); void cerrar(); private: // Datos miembro de la clase "puertoserial" SerialStream serial_port ; //const char* const SERIAL_PORT_DEVICE = "/dev/ttyS0" ; //char servo; //char desplazamiento; 135 // protected: //using namespace LibSerial ; public: //SerialStream serial_port ; //const char* const SERIAL_PORT_DEVICE = "/dev/ttyS0" ; }; puertoserial1::puertoserial1(){ const char* const SERIAL_PORT_DEVICE = "/dev/ttyUSB0" ; // Utilizando namespace LibSerial ; // SerialStream serial_port ; serial_port.Open( SERIAL_PORT_DEVICE ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not open s erial port " << SERIAL_PORT_DEVICE << std::endl ; exit(1) ; } // // Configurando la tasa de baudios del puerto serial // serial_port.SetBaudRate( SerialStreamBuf::BAUD_38400 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the baud rate." << std::endl ; exit(1) ; } // // Configurando el número de bits. // serial_port.SetCharSize( SerialStreamBuf::CHAR_SIZE_8 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the character size." << std::endl ; exit(1) ; } 136 // // Deshabilitando la paridad // serial_port.SetParity( SerialStreamBuf::PARITY_NONE ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not disable the parity." << std::endl ; exit(1) ; } // // Configurando el bit de parada // serial_port.SetNumOfStopBits( 1 ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not set the number of stop bits." << std::endl ; exit(1) ; } // // Iniciando el control de flujo del hardware // serial_port.SetFlowControl( SerialStreamBuf::FLOW_CONTROL_NONE ) ; if ( ! serial_port.good() ) { std::cerr << "Error: Could not use hardware flow control." << std::endl ; exit(1) ; } //return EXIT_SUCCESS ; } void puertoserial1::escribir(char servo, char desplazamiento) { char info[] = {255,0,0}; info[1]=servo; info[2]=desplazamiento; serial_port.write(info,3 ) ; sleep(1); } 137 void puertoserial1::ruta(int instruc[],int numinstruc) { int a = numinstruc; char info[3]; for(int i=0; i < a;i++) { switch( instruc[i]) { case 0:{ info[0]= 255; info[1]=0; info[2]=70; serial_port.write(info,3 ); break; } case 1:{ info[0]= 255; info[1]=0; info[2]=70; serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=70; serial_port.write(info,3 ); break; } case 2:{ info[0]= 255; info[1]=0; info[2]=45; serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=45; serial_port.write(info,3 ); break; } case 3:{ info[0]= 255; info[1]=0; 138 info[2]=180; serial_port.write(info,3 ); break; } case 4:{ info[0]= 255; info[1]=0; info[2]=180; serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=180; serial_port.write(info,3 ); break; } case 5:{ info[0]= 255; info[1]=0; info[2]=215; serial_port.write(info,3 ); sleep(1); info[0]= 255; info[1]=0; info[2]=215; serial_port.write(info,3 ); break; } case 6:{ info[0]= 255; info[1]=1; info[2]=93; serial_port.write(info,3 ); break; } case 7:{ info[0]= 255; info[1]=1; info[2]=71; serial_port.write(info,3 ); break; } case 8:{ 139 info[0]= 255; info[1]=1; info[2]=56; serial_port.write(info,3 ); break; } case 9:{ info[0]= 255; info[1]=1; info[2]=133; serial_port.write(info,3 ); break; } case 10:{ info[0]= 255; info[1]=1; info[2]=155; serial_port.write(info,3 ); break; } case 11:{ info[0]= 255; info[1]=1; info[2]=170; serial_port.write(info,3 ); break; } case 12:{ info[0]= 255; info[1]=1; info[2]=114; serial_port.write(info,3 ); break; } case 13:{ info[0]= 255; info[1]=0; info[2]=127; serial_port.write(info,3 ); break; } default:{ 140 cout<<"Instrucción inválida...Aplicando freno y centrando el steer..."< maxdist)//Comprobando que no haya ocurrido un cambio de cuadrante { goto keepfor;//hubo un cambio de cuadrante, toma de decisiones no aplica. Avanzar hacia adelante para tomar datos válidos } if(hipotenusa > maxdist) { goto decision; //Salto a la toma de decisiones goto keepfor; } arrivo: // Etiqueta a la cual se llega si después de haber realizado una decisión se alcanzó la precisión solicitada //Presición alcanzada, fin de búsqueda de destino. Destino localizado 142 cout<< "Destino alcanzado"<fabs(distlon1)) { com2.ruta(invdirderecha,invdird);//invdirderecha;//Giro de 180º hacia la derecha goto keepfor; } if(fabs(distlat1)fabs(distlon1)) { 143 com2.ruta(invdirizquierda,invdiri);//invdirizquierda;//Giro de 180º hacia la izquierda goto keepfor; } if(fabs(distlat1)distlat1 && distlon2distlon1)//Si se alejó en latitud pero se acercó en longitud { if(cuadranteactual == 1 || cuadranteactual == 3) { com2.ruta(medgiroizquierda,medgi);//medgiroizquierda;//Giro de 90º hacia la izquierda goto keepfor; } if(cuadranteactual == 2 || cuadranteactual == 4) { com2.ruta(medgiroderecha,medgd);//medgiroderecha;//Giro de 90º hacia la derecha goto keepfor; } } if(distlat2>distlat1 && distlon2>distlon1)//Si se acercó en latitud y en longitud { if(cuadranteactual == 1 || cuadranteactual == 3) 145 { if(fabs(distlat2-distlat1)fabs(distlon2-distlon1)) { //verticalizquierda;//Buscando alinearse con el eje más próximo mediante pequeños y continuos ajustes en la dirección(el eje vertical aproximación por la izquierda) do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,izqmin);//Gira la dirección un poco a la izquierda sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admed);//Avance medio sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Freno sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat2 = com1.distlatitud();//cálculo de la distancia de latitud distlon2 = com1.distlongitud();//cálculo de la distancia de longitud com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,atmed);//Retrocede para determinar orientación y decidir la próxima acción sleep(1);//Acción de avanzar dura un segundo com2.escribir(motor,freno);//Detiene al rover sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM 147 cuadranteviejo = com1.cuadrante(distlat2,distlon2);//comprueba en que cuadrante se encontraba el rover antes de tomar decisión com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlon1 != distlon2); } goto keepfor; } if(cuadranteactual == 2 || cuadranteactual == 4) { if(fabs(distlat2-distlat1)fabs(distlon2-distlon1)) { //verticalderecha;//Buscando alinearse con el eje más próximo mediante pequeños y continuos ajustes en la dirección(el eje vertical aproximación por la derecha) do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,dermin);//Gira la dirección un poco a la izquierda sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM 149 com2.escribir(motor,admed);//Avance medio sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Freno sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat2 = com1.distlatitud();//cálculo de la distancia de latitud distlon2 = com1.distlongitud();//cálculo de la distancia de longitud com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,atmed);//Retrocede para determinar orientación y decidir la próxima acción sleep(1);//Acción de avanzar dura un segundo com2.escribir(motor,freno);//Detiene al rover sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM cuadranteviejo = com1.cuadrante(distlat2,distlon2);//comprueba en que cuadrante se encontraba el rover antes de tomar decisión com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlon1 != distlon2); } } goto keepfor; } 150 if(distlat2>distlat1 && distlon2==distlon1)//Si ya no hay variación en la longitud pero se está acercando en latitud { if(cuadranteactual == 1 || cuadranteactual == 3) { //aproxescderecha;//Aproximación al punto deseado por medio de una ruta en forma de escalera hasta cumplir con la precisión deseada alguno de los ejes. Una vez alcanzada la precisión deseada en algún eje, se busca alcanzar la precisión deseada en el otro, tan sólo avanzando hacia adelante o girando 90º a la derecha y continuando hacia adelante. do{//Escalera a la derecha hasta que se alcance la precisión en alguno de las coordenadas com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat2 = com1.distlatitud();//cálculo de la distancia de latitud distlon2 = com1.distlongitud();//cálculo de la distancia de longitud cuadranteviejo = com1.cuadrante(distlat2,distlon2);//comprueba en que cuadrante se encontraba el rover antes de tomar decisión com2.ruta(escalderecha,escd);//rutina de un escalón a la derecha com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; if(distlon1 < maxdist) { do{//Ya llegó en longitud, siga avanzando hasta encontrar el punto. 151 sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información út il de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlat1 > maxdist); } if(distlat1 < maxdist)//Ya llegó en latitud, gire a la derecha y siga directo hasta cumplir con la longitud { com2.ruta(medgiroderecha,medgd);//medgiroderecha;//Giro de 90º hacia la derecha do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza 152 sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlon1 > maxdist); } }while(hipotenusa > maxdist); if(hipotenusa < maxdist) goto arrivo; goto keepfor; } if(cuadranteactual == 2 || cuadranteactual == 4) { //aproxescizquierda;//Aproximación al punto deseado por medio de una ruta en forma de escalera hasta cumplir con la precisión deseada alguno de los ejes. Una vez alcanzada la precisión deseada en algún eje, se busca alcanzar la precisión deseada en el otro, tan sólo avanzando hacia adelante o girando 90º a la izquierda y continuando hacia adelante. do{ com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat2 = com1.distlatitud();//cálculo de la distancia de latitud distlon2 = com1.distlongitud();//cálculo de la distancia de longitud 153 cuadranteviejo = com1.cuadrante(distlat2,distlon2);//comprueba en que cuadrante se encontraba el rover antes de tomar decisión com2.ruta(escalizquierda,esci);//rutina de un escalón a la izquierda com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; if(distlon1 < maxdist) { do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil d e la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) 154 cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlat1 > maxdist); } if(distlat1 < maxdist) { com2.ruta(medgiroizquierda,medgi);//medgiroizquierda;//Giro de 90º hacia la izquierda do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlon1 > maxdist); 155 } }while(hipotenusa > maxdist); if(hipotenusa < maxdist) goto arrivo; } } if(distlat2==distlat1 && distlon2>distlon1)//Si ya no hay variación en la latitud pero se está acercando en longitud { if(cuadranteactual == 1 || cuadranteactual == 3) { //aproxescizquierda;//Aproximación al punto deseado por medio de una ruta en forma de escalera hasta cumplir con la precisión deseada alguno de los ejes. Una vez alcanzada la precisión deseada en algún eje, se busca alcanzar la precisión deseada en el otro, tan sólo avanzando hacia adelante o girando 90º a la izquierda y continuando hacia adelante. do{ com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat2 = com1.distlatitud();//cálculo de la distancia de latitud distlon2 = com1.distlongitud();//cálculo de la distancia de longitud cuadranteviejo = com1.cuadrante(distlat2,distlon2);//comprueba en que cuadrante se encontraba el rover antes de tomar decisión com2.ruta(escalizquierda,esci);//rutina de un escalón a la izquierda com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la inform ación útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; if(distlat1 < maxdist) 156 { do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlon1 > maxdist); } if(distlon1 < maxdist) { com2.ruta(medgiroizquierda,medgi);//medgiroizquierda;//Giro de 90º hacia la izquierda do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM 157 com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlat1 > maxdist); } }while(hipotenusa > maxdist); if(hipotenusa < maxdist) goto arrivo; goto keepfor; } if(cuadranteactual == 2 || cuadranteactual == 4) { //aproxescderecha;//Aproximación al punto deseado por medio de una ruta en forma de escalera hasta cumplir con la precisión deseada alguno de los ejes. Una vez alcanzada la precisión deseada en algún eje, se busca alcanzar la precisión deseada en el otro, tan sólo avanzando hacia adelante o girando 90º a la derecha y continuando hacia adelante. do{ com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat2 = com1.distlatitud();//cálculo de la distancia de latitud distlon2 = com1.distlongitud();//cálculo de la distancia de longitud cuadranteviejo = com1.cuadrante(distlat2,distlon2);//comprueba en que cuadrante se encontraba el rover antes de tomar decisión 158 com2.ruta(escalderecha,escd);//rutina de un escalón a la derecha com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; if(distlat1 < maxdist) { do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; 159 }while(distlon1 > maxdist); } if(distlon1 < maxdist) { com2.ruta(medgiroderecha,medgd);//medgiroderecha;//Giro de 90º hacia la derecha do{ sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(steer,centro);//Centra la dirección sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,admin);//Avanza sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com2.escribir(motor,freno);//Frena sleep(1);//Retardo necesario para que se reconozcan diferentes señales PWM com1.leer();//almacena la cadena de información enviada por el GPS com1.desfragmentar(infogps);//Separa la información útil de la cadena enviada por el GPS distlat1 = com1.distlatitud();//Calcula y almacena la latitud del punto B (latitud después de tomar nueva decisión) distlon1 = com1.distlongitud();//Calcula y almacena la longitud del punto B (longitud después de tomar nueva decisión) cuadranteactual = com1.cuadrante(distlat1,distlon1);//comprueba en que cuadrante respecto al punto destino se encuentra hipotenusa = com1.distnav();//Comprobando que no se haya superado la precisión solicitada (Evita búsqueda infinita del punto) if(hipotenusa < maxdist) goto arrivo; if(cuadranteviejo != cuadranteactual) goto keepfor; }while(distlat1 > maxdist); } }while(hipotenusa > maxdist); if(hipotenusa < maxdist) goto arrivo; } goto keepfor; } goto keepfor; } 160 Apéndice 5: Disco Compacto con los videos, planos de diseño y código fuente 161 162 ANEXOS 163 Glosario Iostream: Biblioteca de C++ con funciones que realizan operaciones de E/S. Es una implementación orientada a objetos y está basada, al igual que stdio, en el concepto de flujos. Cuando se introducen caracteres desde el teclado, puede pensarse en caracteres que fluyen desde el teclado a las estructuras de datos del programa. Cuando se escribe en un archivo, se piensa en un flujo de bytes que van del programa al disco. Para acceder a la biblioteca iostream se debe incluir el archivo iostream.h. Este archivo contiene información de diferentes funciones de E/S. Define también los objetos cin y cout. POSIX: Es el acrónimo de Portable Operating System Interface; la X viene de UNIX como seña de identidad de la API. El término POSIX fue sugerido por Richard Stallman en respuesta a la demanda de la IEEE, que buscaba un nombre fácil de recordar. Una traducción aproximada del acrónimo podría ser "Interfaz de Sistema Operativo Portátil basado en UNIX". Baud rate: La tasa de baudios (en inglés Baud Rate) es el número de unidades de señal por segundo. Un baudio puede contener varios bits. Root: En sistemas operativos del tipo Unix, root es el nombre convencional de la cuenta de usuario que posee todos los derechos en todos los modos (mono o multi usuario). root es también llamado superusuario. Normalmente esta es la cuenta de administrador. UHF: Por sus siglas en inglés: Ultra High Frequency, en español: frecuencia ultra alta. Es una banda del espectro electromagnético que ocupa el rango de frecuencias de 300 MHz a 3 GHz. 164 NMEA 0183 (o NMEA de forma abreviada): Es una especificación combinada eléctrica y de datos entre aparatos electrónicos marinos y receptores GPS. El protocolo NMEA 0183 es un medio a través del cual los instrumentos marítimos y también la mayoría de los receptores GPS pueden comunicarse los unos con los otros. Ha sido definido, y está controlado, por la organización estadounidense National Marine Electronics Association. RTK: Una estación de referencia geoposicional que provee correcciones instantáneas para estaciones móviles, lo que hace que con la precisión obtenida se llegue al nivel centimétrico. 165 Null Modem Es un método para conectar dos terminales usando un cable serie RS-232, sin la necesidad de utilizar modems u otros dispositivos de comunicación. Las líneas de transmisión y recepción están cruzadas. Existe más de una forma de realizar una conexión null módem ya que no hay ningún estándar que defina esta conexión. Estos cables son comúnmente usados para la transferencia de archivos. Tabla A.1 Conexión Null-Modem más común Signal Name DB-9 DB-25 Pin Pin DB-25 Pin DB-9 Pin FG (Frame Ground) 1 - X - 1 FG TD (Transmit Data) 2 3 - 2 3 RD RD (Receive Data) 3 2 - 3 2 TD RTS (Request To Send) 4 7 - 8 5 CTS CTS (Clear To Send) 5 8 - 7 4 RTS SG (Signal Ground) 7 5 - 5 7 SG DSR (Data Set Ready) 6 6 - 4 20 DTR CD (Carrier Detect) 8 1 - 4 20 DTR DTR (Data Terminal Ready) 20 4 - 1 8 CD DTR (Data Terminal Ready) 20 4 - 6 6 DSR A continuación se muestran las figuras de un conector DB-9 macho y hembra, vistos desde el lado de los pines (no el lado de la soldadura). Figura A.1 DB-9 macho 166 Figura A.2 DB-9 hembra 167 RMC (Recommended Minimum Specific GPS/Transit Data) El mensaje RMC identifica la hora UTC, el estado, la latitud, la longitud, la velocidad respecto al suelo (SGO), la fecha, y la variación magnética de la posición. La estructura del mensaje es la siguiente: $GPRMC,184804.00,A,3723.476543,N,12202.239745,W,000.0,0.0,051196,15.6,E*7C La siguiente tabla describe estos campos de datos. Tabla A.2 Campos del mensaje RMC Campo Descripción 1 Hora: UTC del fijo de posición en formato hhmmss.ss 2 Estado A: Válido V: Advertencia del receptor de navegación (V se saca siempre que el receptor sospeche que algo no va bien) 3 Coordenada de latitud (el número de decimales puede variar de 0 a 7) 4 Dirección de la latitud N = Norte, S = Sur 5 Coordenada de longitud (el número de decimales puede variar de 0 a 7) 6 Dirección de la longitud E = Este, O = Oeste 7 Velocidad respecto al suelo (SOG) en nudos (0–3 cifras decimales) 8 Pasada real en grados 9 Fecha en formato dd/mm/aa 10 Variación magnética en grados 11 Dirección de la variación magnética E: Variación hacia el este desde el rumbo real (se sustrae del rumbo real) W: Variación hacia el oeste desde el rumbo real (se agrega al rumbo real) 12 Indicación del modo A: Autónomo D: Diferencial N: Datos no válidos 168 Hojas de Fabricante