robot autónomo para recorrer un laberinto
Upload: extension-del-instituto-tecnologico-de-tuxtla-gutierrez-sede-bochil
Post on 13-Jan-2017
60 views
TRANSCRIPT
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
ROBOT AUTÓNOMO PARA RECORRER UN LABERINTO
Autores:
Moguel Jiménez, Luis Fernando [email protected]; Pérez Nango, Manuel de Jesús
[email protected]; Reyes Palacios, Shanel Daniela [email protected];
Molina Sosa, Benjamín [email protected].
Instituto Tecnológico de Tuxtla Gutiérrez, Carretera Panamericana Km. 1080, C.P. 29050, Apartado
Postal: 599, Tuxtla Gutiérrez, Chiapas.
Resumen--- El objetivo de este trabajo es presentar los detalles principales del diseño del
hardware y software de un robot autónomo que es capaz de desplazarse a través de un
laberinto prediseñado, siguiendo trayectorias rectilíneas con desviaciones a 90 o 180º ante
la detección de un borde o pared del laberinto, cuando se interpone en su camino recto.
El robot integra sensores de línea, con los cuales será capaz de seguir con autonomía un
laberinto de líneas negras sobre una superficie blanca, en este se mostrarán caminos
correctos e incorrectos, por eso mismo el robot debe corregirlo.
El diseño y la construcción de un prototipo de este robot se realizaron como parte del
proyecto de grado de la materia “Lenguaje de Interfaz” correspondiente al sexto semestre
de la carrera de Ingeniería en Sistemas Computacionales del Instituto Tecnológico de Tuxtla
Gutiérrez.
---------------------------------------------------------------------------------------------------------- -------------------------
Palabras clave: Robot autónomo, laberinto, sensores ultrasónicos, sensor de linea, placa
Arduino.
Abstract--- The objective of this document is to present the main details about the design of
hardware and software of an autonomous robot that is able to go over a predesign maze,
following rectilineals ways with 90 or 180° deflections, detecting edges and maze walls.
The prototype includes several line sensors in order to be able to follow with autonomy the
black lines in a maze with a white surface. Obviously there gonna be corrects an incorrects
ways that the robot should analyze.
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
The design and build of this prototype was a part of a final project in “Lenguaje de interfaz”,
that is a school subject in the sixth semester of Engineering on Computerized Systems in the
Tuxtla Gutierrez Institute of Technology.
----------------------------------------------------------------------------------------------------------------------------- -------
Keywords: Autonomous Robot, maze, ultrasonic sensors, line sensors, arduino board
I.- INTRODUCCIÓN
El proyecto para la creación de un robot
autónomo capaz de recorrer los pasillos
de un laberinto surgió como el desafío de
presentar un trabajo de desarrollo
novedoso y ambicioso para lo que es un
proyecto de una materia de semestre.
Se diseñó un prototipo basado en
“Arduino”, plataforma electrónica abierta
(código y hardware abiertos) que permite
la creación de prototipos basados en
software y hardware flexibles. (Arduino,
2016)
En particular, para la construcción del
sistema de control del robot se utilizó una
placa Arduino Uno, sensores de linea y
servomotores para lograr el
desplazamiento del robot dentro del
laberinto.
El prototipo emplea una serie de sensores
de luminosidad con los cuales es capaz
de seguir una línea. El sensor de luz emite
permanentemente una luz y recibe su
reflejo, con el cual midiendo la
luminosidad del reflejo, es capaz de
interpretar la luminosidad de la superficie
que está recibiendo, aquí el concepto
físico a resaltar es que los colores claros
reflejan más luz que los colores oscuros.
Siguiendo esta idea principal, nuestra
estrategia será que el robot sea capaz de
detectar contrastes, así cuando este
detecte zonas blancas no realizara
ninguna acción de corrección y así mismo
al toparse con la línea negra, sea capaz
de corregir su dirección y seguir con su
camino.
II.- DESARROLLO Y DISEÑO
Al momento del diseño del prototipo se
tuvieron en cuenta varias características
que afectarían a la implementación
exitosa del mismo. Entre las cuestiones
que se analizaron en la etapa de diseño
se pueden mencionar: el chasis, los
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
movimientos a realizar por el robot, los
tipos de sensores, y la alimentación
necesaria para el funcionamiento de los
componentes electrónicos.
A. Chasis
Para este caso se diseñó un chasis pre-
fabricado de forma alargada en forma de
“T”, acompañado con otras características
de implementación, que nos permitiría
realizar mejores movimientos.
B. Movimientos
La trayectoria que realiza el robot es en
línea recta con giros de 90º o 180°
cuando detecta un obstáculo.
La tracción (fig. 1) utilizada es diferencial
(se usan dos servomotores
independientes), lo que hace que los giros
sean más sencillos y además permite
realizar los movimientos sin más espacio
que el que está ocupando (gira sobre su
propio eje).
Fig. 1 Tracción diferencial
Otro aspecto del diseño que se definió fue
la ubicación de las ruedas, dado que esto
también impacta, en el prototipo se
ubicaron en la parte de adelante para una
mayor tracción.
Para las ruedas se utilizaron un par de
ruedas de plástico para servomotor y
como eje se le añadió uno de los brazos
que viene con el servo.
C. Sensores
Debido a que este sensor capta grados de
luminosidad, no es capaz de distinguir
colores, sólo captando la existencia del
blanco (claridad), negro (oscuridad) y los
tonos de grises que corresponden a los
distintos porcentajes de luz existentes en
el medio.
Para los sensores de línea (fig. 2), por
cada se sensor (en este caso se usaron
4), se usaron un LED ultra brillante verde
+ una fotorresistencia + 1 resistencias de
330 ohms + 1 resistencia de 10k.
Fig. 2 Sensores de línea
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
El diodo emisor de luz (LED) envía un
constante haz de luz (fig. 3) hacia el suelo.
Esta luz se refleja de nuevo a la LDR.
Dependiendo del color, la fotorresistencia
recibe cantidades variables de luz
reflejada.
Fig. 3 Reflejo de la luz
D. Motores
Para el movimiento de las ruedas se
usaron servomotores. El tamaño reducido
del servo MG90 (fig. 4) lo hace ideal para
la construcción del prototipo (Arduino,
2016)
Fig. 4 Servomotor MG90
Los servomotores hacen uso de la
modulación por ancho de pulsos (PWM)
para controlar la dirección o posición de
los motores de corriente continua. La
mayoría trabaja en la frecuencia de los
cincuenta hercios, así las señales PWM
tendrán un periodo de veinte
milisegundos.
E. Alimentación
Para lograr un prototipo autónomo se
utilizó una fuente de alimentación, en este
caso, se usó una batería LI-PO de 7.4v a
4500 mAh (fig. 5), la cual alimentaba a la
placa Arduino, los servos y los sensores
de línea.
Fig. 5 Batería LI-PO
La batería se ubicó en la parte de enfrente
del robot para que las llantas se acercaran
lo más posible al suelo, logrando así gran
estabilidad y mayor tracción.
III.- CONEXIONES
Se hicieron las conexiones
correspondientes de todos los elementos
anteriormente mencionados para el buen
funcionamiento del robot. Primeramente
hicimos las conexiones del puente H
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
(L298N) y de los servomotores con el
Arduino uno (fig. 6).
Fig. 6 Conexión de los motores y puente
H
Tabla 1. Pines usados en el Arduino
para la conexión del puente H
Tabla 2. Conexión de los Servos al
puente H
Después de hacer las conexiones del
puente H, procedimos a hacer las
conexiones de los sensores de línea al
Arduino, en este caso, fueron hechas con
LED´s ultrabrillantes y fotorresistencias
(fig. 7).
Fig. 7 Conexión de los sensores de línea
Tabla 3. Conexión de los Servos al
puente H
Una vez tenido todos las conexiones
hechas de nuestros componentes
pasamos a agregar la fuente de
Pines Arduino Pines Puente H
11 ENA
12 IN1
13 IN2
2 IN3
4 IN4
3 ENB
Salida Puente H Servomotores
OUT2 Servo Izquierdo
OUT3 Servo Derecho
Pines
Arduino
Salida de las
Fotorresistencias
A0 Salida
Fotorresistencias 1
A1 Salida
Fotorresistencias 2
A2 Salida
Fotorresistencias 3
A3 Salida
Fotorresistencias 4
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
alimentación que fue una batería LIPO de
7.4v a 450mAh (fig. 8) con su interruptor
correspondiente, y todo esto fue montado
al chasis de nuestro robot (fig. 9)
Fig. 8 Conexión completa del circuito
Fig. 9 Circuito montado al Chasis del
robot
Descripción de la lógica utilizada
Se añadió a nuestro código, una función
“calibrar” que se utilizaría para poder
obtener ciertos valores (muestreo) que
nos servirían para referencia a nuestros
sensores de línea y así poder tener un
mejor control en el robot, ya que en
algunas ocasiones, el color varía por la
cantidad de luz que incide en la superficie
en un momento determinado. Todos estos
valores de referencia se guardan en la
EEPROM para hacer uso de ellas cuando
el robot entre en funcionamiento.
Primeramente se colocó en el código
instrucciones para que el robot camine
hacia adelante mientras se encuentra
dentro de la zona de salida.
Tomamos de forma obvia, que el robot al
ser colocado correctamente, ira hacia
adelante sin ninguna desviación.
Después de ello, el robot se guiara por las
líneas del fondo del laberinto al igual que
los cruces.
Se consultó detalladamente el reglamento
de este concurso, y se observó que en
ninguno de sus puntos se prohibía la
programación de los cruces para que el
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
robot se guiara y llegara rápidamente a la
meta, es por ello que como equipo,
decidimos irnos por esta vía, y se le
programa al robot con números de cruces
y sentidos (derecha o izquierda).
Por lo anteriormente mencionado, se le
ingresa al código dos vectores, uno para
llevar el control de cruces y el otro para los
sentidos. Después de haber llegado a un
cruce, el robot se detiene y verifica en el
vector, si el número de cruce en el cual
esta, es igual al dato que esta contenido
dentro de esta fila el robot girara en el
sentido del dato correspondiente a su
vector.
Al llegar al número total de datos en el
vector, se le informa al robot para que este
se encuentre preparado para localizar la
meta y no seguir buscando cruces.
Aplicación en la vida real.
El prototipo que hemos desarrollado como
un robot de laberinto puede ser aplicado
en la vida real, con apenas algunas
modificaciones.
Un uso que podemos darle seria usarlo
como un detector de explosivos mediante
alguna situación de suma importancia o
que ponga en peligro vidas humanas.
Como ejemplo podemos mencionar las
minas, nuestro robot sería capaz de
detectar si hay explosivos dentro
mediante el uso de tecnologías como el
rayo X, que calcula la densidad de los
objetos que se encuentren dentro de la
mina, y leerá la radiación gama para
determinar la composición química
(MsRobotics, 2016) y de esta manera
identificar si existen o no explosivos y
enviará toda la información recabada al
encargado de la operación.
Código
Se declaran todas las variables que se
utilizaran y la librería correspondiente
para el uso de la EEPROM.
#include <EEPROM.h> // pines del puente H #define IN1 12 #define IN2 13 #define motorIzq 11 // viendo de frente al robot #define IN3 2 #define IN4 4 #define motorDer 3 #define minVelocidadIzq 38 // velocidad minima (pwm)
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
#define minVelocidadDer 38 // velocidad minima (pwm) #define velGiroIzq_Der 40 // velocidad GiroIzquierda (pwm) #define velGiroIzq_Izq 40 // velocidad GiroIzquierda (pwm) #define velGiroDer_Der 40 // velocidad GiroDerecha (pwm) #define velGiroDer_Izq 40 // velocidad GiroDerecha (pwm) #define velAtras 33 // velocidad atras (pwm) // pines de los sensores de line #define sensorLineaDer A0 // viendo de frente al robot #define sensorLineaIzq A1 #define sensorCruceDer A2 #define sensorCruceIzq A3 #define izquierda 1 #define derecha 0 #define timeInterrup 49535 // interrupcion cada 1ms int umb_crucemeta_Der, umb_crucemeta_Izq; int lineaDer, lineaIzq, promedioDer, promedioIzq; int sp_linea_Der, sp_linea_Izq, umb_linea_Der, umb_linea_Izq; int lineaCruceDer, lineaCruceIzq, promedioCruceDer, promedioCruceIzq; int sp_cruce_Der, sp_cruce_Izq, umb_cruce_Der, umb_cruce_Izq; int errorDer = 0, last_errorDer = 0, derivativoDer = 0, salida_pwm; int errorIzq = 0, last_errorIzq = 0, derivativoIzq = 0; float kpDer = 10.6, kdDer = 40.5 , kpIzq = 10.6, kdIzq = 40.5; byte i, muestras, cruce ,numeroCruces; char c; unsigned long duracion, timeout; // lectura max 30cm (1740us)
unsigned int distanciaIzq; unsigned int distanciaCentro; unsigned int distanciaDer; byte lineaCruces[] = {1,2}; byte lineaSentido[] = {izquierda,derecha}; // viendo de frente al robot
Después tenemos la función calibrar, que
nos sirve para realizar un muestreo de los
colores de la superficie y tener menos
probabilidad de error al momento de
analizar nuestro piso. También tenemos
la función sensores de líneas que nos va
tomando los valores actuales de la
superficie del robot. Y la función control
para hacer ciertos movimientos si se
detecta un cruce.
/*******************************************************************************************/ /*** CALIBRAR ***/ void calibrar(void) { while(c != 's') { Serial.println("1.-Calibrar linea (l)"); Serial.println("2.-Calibrar pista (p)"); Serial.println("3.-Calibrar inicio (i)"); Serial.println("4.-Calibrar meta (m)"); Serial.println("5.-Leer EEPROM (r)"); Serial.println("6.-Salir (s)");
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
while(!Serial.available()); c = 0; c = Serial.read(); if(c == 'l' || c == 'p' || c == 'i' || c == 'm' ) { promedioDer = 0; promedioIzq = 0; promedioCruceDer = 0; promedioCruceIzq = 0; for(i = 0; i < muestras; i++) { lineaDer = (analogRead(sensorLineaDer))/4; // valores de 0 - 255 lineaIzq = (analogRead(sensorLineaIzq))/4; // valores de 0 - 255 lineaCruceDer = (analogRead(sensorCruceDer))/4; lineaCruceIzq = (analogRead(sensorCruceIzq))/4; promedioDer += lineaDer; promedioIzq += lineaIzq; promedioCruceDer += lineaCruceDer; promedioCruceIzq += lineaCruceIzq; Serial.print("linea "); Serial.print(lineaIzq); Serial.print('\t'); Serial.println(lineaDer); Serial.print("cruce "); Serial.print(lineaCruceIzq); Serial.print('\t'); Serial.println(lineaCruceDer); delay(500); } Serial.print("promedioLinea "); Serial.print(promedioIzq/muestras); Serial.print('\t'); Serial.println(promedioDer/muestras); Serial.print("promedioCruce "); Serial.print(promedioCruceIzq/muest
ras); Serial.print('\t'); Serial.println(promedioCruceDer/muestras); if(c == 'l') { EEPROM.write(0, (byte) (promedioDer/muestras) ); EEPROM.write(1, (byte) (promedioIzq/muestras) ); EEPROM.write(4, (byte) (promedioCruceDer/muestras) ); EEPROM.write(5, (byte) (promedioCruceIzq/muestras) ); } if(c == 'p') { EEPROM.write(2, (byte) (promedioDer/muestras) ); EEPROM.write(3, (byte) (promedioIzq/muestras) ); EEPROM.write(6, (byte) (promedioCruceDer/muestras) ); EEPROM.write(7, (byte) (promedioCruceIzq/muestras) ); } if(c == 'm') { EEPROM.write(8, (byte) (promedioDer/muestras) ); EEPROM.write(9, (byte) (promedioIzq/muestras) ); EEPROM.write(10, (byte) (promedioCruceDer/muestras) ); EEPROM.write(11, (byte) (promedioCruceIzq/muestras) ); } Serial.println("*** echo ***"); } if(c == 'r') { Serial.println("Izquierda Derecha");
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
Serial.println("--- Linea ---"); Serial.print(EEPROM.read(1)); Serial.print('\t'); Serial.println(EEPROM.read(0)); Serial.println("--- Linea Cruce ---"); Serial.print(EEPROM.read(5)); Serial.print('\t'); Serial.println(EEPROM.read(4)); Serial.println("--- Pista ---"); Serial.print(EEPROM.read(3)); Serial.print('\t'); Serial.println(EEPROM.read(2)); Serial.println("--- Pista Cruce---"); Serial.print(EEPROM.read(7)); Serial.print('\t'); Serial.println(EEPROM.read(6)); Serial.println("--- Meta ---"); Serial.print(EEPROM.read(9)); Serial.print('\t'); Serial.println(EEPROM.read(8)); Serial.println("--- Meta Cruce---"); Serial.print(EEPROM.read(11)); Serial.print('\t'); Serial.println(EEPROM.read(10)); } } } /*******************************************************************************************/ /*** SENSORES LINEA ***/ void sensoresLinea(void) { lineaDer = analogRead(sensorLineaDer);
lineaIzq = analogRead(sensorLineaIzq); lineaCruceDer = analogRead(sensorCruceDer); lineaCruceIzq = analogRead(sensorCruceIzq); }
/*******************************************************************************************/ /*** CONTROL ***/ void control(void) { sensoresLinea(); if( lineaDer < umb_linea_Der && lineaIzq < umb_linea_Izq ) // sin linea { errorDer = 0; last_errorDer = 0; derivativoDer = 0; errorIzq = 0; last_errorIzq = 0; derivativoIzq = 0; adelante(); analogWrite(motorDer,minVelocidadDer); analogWrite(motorIzq,minVelocidadIzq); c = 'y'; // habilitar deteccion de cruce, despues de cada giro y deteccion sin linea linea do { lineaDer = analogRead(sensorLineaDer); lineaIzq = analogRead(sensorLineaIzq); }while(lineaDer < umb_linea_Der && lineaIzq < umb_linea_Izq); } else {
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
if( lineaDer < umb_linea_Der) controlDer(); // se inclina a la derecha if( lineaIzq < umb_linea_Izq) controlIzq(); // se inclina a la izquierda if( lineaDer > umb_linea_Der && lineaIzq > umb_linea_Izq ) // sobre la linea { errorDer = 0; last_errorDer = 0; derivativoDer = 0; errorIzq = 0; last_errorIzq = 0; derivativoIzq = 0; analogWrite(motorDer,minVelocidadDer); analogWrite(motorIzq,minVelocidadIzq); } if( (lineaCruceDer > umb_cruce_Der) && (lineaCruceIzq > umb_cruce_Izq) && (c == 'y') ) // cruce de linea { do // permitir k salga un tanto del cruce { lineaCruceDer = analogRead(sensorCruceDer); lineaCruceIzq = analogRead(sensorCruceIzq); }while( !(lineaCruceDer < umb_cruce_Der && lineaCruceIzq < umb_cruce_Izq) ); motoresApagados();cruce = 1; c = 'x'; } else { cruce = 0;} } }
Después de ello tenemos dos funciones
que hacen lo posible por corregir la mala
posición del prototipo.
/*** CONTROL DERECHA ***/ void controlDer() { lineaDer = analogRead(sensorLineaDer); errorDer = sp_linea_Der - lineaDer; derivativoDer = errorDer - last_errorDer; salida_pwm = (kpDer * errorDer) + ( kdDer * derivativoDer); last_errorDer = errorDer; if( salida_pwm > minVelocidadDer ) salida_pwm = minVelocidadDer; //limitamos la salida de pwm if( salida_pwm < -minVelocidadDer ) salida_pwm = -minVelocidadDer; if (salida_pwm > 0) { analogWrite(motorDer,salida_pwm); analogWrite(motorIzq,minVelocidadDer-salida_pwm); } if (salida_pwm < 0) { analogWrite(motorDer,minVelocidadDer+salida_pwm); analogWrite(motorIzq,-salida_pwm); } } /**********************************
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
*********************************************************/ /*** CONTROL IZQUIERDA ***/ void controlIzq() { lineaIzq = analogRead(sensorLineaIzq); errorIzq = sp_linea_Izq - lineaIzq; derivativoIzq = errorIzq - last_errorIzq; salida_pwm = (kpIzq * errorIzq) + ( kdIzq * derivativoIzq); last_errorIzq = errorIzq; if( salida_pwm > minVelocidadIzq ) salida_pwm = minVelocidadIzq; if( salida_pwm < -minVelocidadIzq ) salida_pwm = -minVelocidadIzq; if (salida_pwm > 0) { analogWrite(motorDer,minVelocidadIzq-salida_pwm); analogWrite(motorIzq,salida_pwm); } if (salida_pwm < 0) { analogWrite(motorDer,-salida_pwm); analogWrite(motorIzq,minVelocidadIzq+salida_pwm); } }
También se programó una función
denominada giro, la cual nos sirve para
controlar nuestro robot al momento del
cruce determinado para poder hacer
girarlo sobre su propio eje.
/*** GIRO ***/ void giro(byte sentido) { if(sentido == izquierda) { giroIzquierda(); analogWrite(motorDer, velGiroIzq_Der); // velocidades diferentes para analogWrite(motorIzq, velGiroIzq_Izq); // compensar el giro delay(500); do // permitir que los sensores salgan de la linea { lineaDer = analogRead(sensorLineaDer); }while(lineaDer > umb_linea_Der); // cruce de linea do { lineaIzq = analogRead(sensorLineaIzq); }while(lineaIzq < (umb_linea_Izq+10)); do { lineaDer = analogRead(sensorLineaDer); }while(lineaDer < (umb_linea_Der+10)); } if(sentido == derecha) { giroDerecha(); analogWrite(motorDer, velGiroDer_Der); // velocidades diferentes para
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
analogWrite(motorIzq, velGiroDer_Izq); // compensar el giro delay(500); do // permitir que los sensores salgan de la linea { lineaIzq = analogRead(sensorLineaIzq); }while(lineaIzq > umb_linea_Izq); // cruce de linea do { lineaDer = analogRead(sensorLineaDer); }while(lineaDer < (umb_linea_Der+10)); do { lineaIzq = analogRead(sensorLineaIzq); }while(lineaIzq < (umb_linea_Izq+10)); /* do // caso especial del giro a la derecha { lineaCruceDer = analogRead(sensorCruceDer); }while(lineaCruceDer < umb_cruce_Der); */ delay(200); } motoresApagados(); delay(500); }
La siguiente función es la que verifica si el
robot esta fuera de posición para mandar
a llamar a las funciones correspondientes
y corregirlo.
/*** CENTRAR SENSORES LINEA***/ void centrarSensoresLinea(void) { sensoresLinea(); if( !(lineaDer > umb_linea_Der && lineaIzq > umb_linea_Izq) ) { if( lineaDer < umb_linea_Der) { giroIzquierda(); delay(500); analogWrite(motorDer, velGiroIzq_Der); analogWrite(motorIzq, velGiroIzq_Izq); do { lineaDer = analogRead(sensorLineaDer); }while(lineaDer < umb_linea_Der); } else if( lineaIzq < umb_linea_Izq) { giroDerecha(); delay(500); analogWrite(motorDer, velGiroIzq_Der); analogWrite(motorIzq, velGiroIzq_Izq); do { lineaIzq = analogRead(sensorLineaIzq); }while(lineaIzq < umb_linea_Izq); }
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
motoresApagados(); delay(500); } } /*******************************************************************************************/ /*** CENTRAR SENSORES CRUCE***/ void centrarSensoresCruce(void) { sensoresLinea(); if( (lineaCruceDer < umb_cruce_Der) && (lineaCruceIzq < umb_cruce_Izq) ) { atras(); do { sensoresLinea(); }while( !(lineaCruceDer > umb_cruce_Der && lineaCruceIzq > umb_cruce_Izq) ); motoresApagados(); delay(500); } } /*******************************************************************************************/ /*** GIRO IZQUIERDA ***/ void giroIzquierda() { digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); } /*******************************************************************************************/
/*** GIRO DERECHA ***/ void giroDerecha() { digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); } /*******************************************************************************************/ /*** ADELANTE ***/ void adelante() { digitalWrite (IN1, HIGH); digitalWrite (IN2, LOW); digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); } /*******************************************************************************************/ /*** ATRAS ***/ void atras() { digitalWrite (IN1, LOW); digitalWrite (IN2, HIGH); digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); delay(300); analogWrite(motorDer, velAtras); analogWrite(motorIzq, velAtras); } /*******************************************************************************************/ /*** MOTORES APAGADOS ***/ void motoresApagados(void) { // Motores apagados digitalWrite (IN1, LOW); digitalWrite (IN2, LOW); analogWrite (motorIzq, 0);
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); analogWrite (motorDer, 0); }
Hay ciertas funciones en la parte anterior
que se usan para diversos objetivos
específicos ya que se desgloso
demasiado las partes de nuestra lógica
para tener un mejor control de
programación.
Aquí tenemos por fin la parte principal de
nuestro código.
void setup() { // PinMode para los ULtrasonicos pinMode(trigIzq,OUTPUT); pinMode(trigCentro,OUTPUT); pinMode(trigDer,OUTPUT); pinMode(echoIzq,INPUT); pinMode(echoCentro,INPUT); pinMode(echoDer,INPUT); // PinMode control Puente H motores pinMode (IN4, OUTPUT); pinMode (IN3, OUTPUT); pinMode (IN2, OUTPUT); pinMode (IN1, OUTPUT); muestras = 20; cruce = 0; numeroCruces = 0; c = 0; duracion = 0; timeout = 1740; // lectura max ultrasonicos 30cm (1740us) distanciaIzq = 0; distanciaCentro = 0; distanciaDer = 0; motoresApagados();
Serial.begin(9600); } void loop() { //calibrar(); //Serial.println("*** Preparado ***"); // valores de 0 - 1023 sp_linea_Der = EEPROM.read(0) * 4; // setpoint valor calibrado linea sp_linea_Izq = EEPROM.read(1) * 4; umb_linea_Der = ( sp_linea_Der + (EEPROM.read(2) * 4) )/2; // umbral de la linea lado derecho umb_linea_Izq = ( sp_linea_Izq + (EEPROM.read(3) * 4) )/2; sp_cruce_Der = EEPROM.read(4) * 4; // setpoint valor calibrado linea sp_cruce_Izq = EEPROM.read(5) * 4; umb_cruce_Der = ( sp_cruce_Der + (EEPROM.read(6) * 4) )/2; // umbral cruce linea lado derecho umb_cruce_Izq = ( sp_cruce_Izq + (EEPROM.read(7) * 4) )/2; umb_crucemeta_Der = ( EEPROM.read(10) + EEPROM.read(6) ) * 2 ; // umbral meta cruce / pista cruce umb_crucemeta_Izq = ( EEPROM.read(11) + EEPROM.read(7) ) * 2 ; for(i = 0; i < 5; i++) delay(1000); cruce = 0; muestras = 0; numeroCruces = 0; adelante();
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
while(1) { if(cruce == 1) { motoresApagados(); cruce = 0; numeroCruces++; delay(300); centrarSensoresLinea(); delay(300); if( lineaCruces[muestras] == numeroCruces) { if( lineaSentido[muestras] == izquierda) { centrarSensoresCruce(); for(i = 0; i < 2; i++) // pausas { digitalWrite(IN2,!digitalRead(IN2)); delay(500);} giro(izquierda); } else if( lineaSentido[muestras] == derecha ) { centrarSensoresCruce(); for(i = 0; i < 2; i++) // pausas { digitalWrite(IN2,!digitalRead(IN2)); delay(500);} giro(derecha); } for(i = 0; i < 2; i++) // pausas { digitalWrite(IN2,!digitalRead(IN2)); delay(500);} centrarSensoresLinea(); delay(300); muestras++; numeroCruces = 0;
} adelante(); control(); } else control(); if( muestras == sizeof(lineaCruces)) // buscando la meta { sensoresLinea(); // la condicional cambia segun el color meta / pista if( lineaCruceDer < umb_crucemeta_Der && lineaCruceIzq < umb_crucemeta_Izq ) { motoresApagados(); for(i = 0; i < 10; i++) // pausas { digitalWrite(IN2,!digitalRead(IN2)); delay(500);} } } } }
Resultados obtenidos
En la etapa final del proyecto, en la
creación de un robot autónomo capaz de
descifrar laberintos, se suscitaron
demasiados contratiempos para las
pruebas finales y el ir experimentando que
tanta inteligencia adquiría el robot de
acuerdo a las correcciones que
constantemente se le realizaban después
de cada prueba hecha en laberintos
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
provisionales ya que el final aún no estaba
disponible.
Existieron detalles como las pruebas en
laberintos no idóneos, es decir, se
hicieron pruebas en materiales como
azulejo, piso firme y terracería lo cual no
beneficio la adherencia de nuestras
llantas al piso por lo que por cada tipo de
piso, el robot se comportaba con distintas
velocidades lo cual nos causó
contratiempos.
Otro inconveniente fue lo de la
arquitectura del robot, al ser un poco
grande, necesitaba un poco más de
espacio que las distancias entre paredes
del laberinto, así que se tuvieron que
implementar nuevas llantas y motores
para un giro más rápido.
En algunas ocasiones los problemas eran
más técnicos, por ejemplo cuando se
prendía el robot a veces un motor prendía
y el otro no o viceversa, pero causaba
problemas ya que hacía falta una
coordinación para iniciar al mismo tiempo.
El problema más grande y grave al que
nuestro equipo se enfrentó fue a la
pérdida del robot dentro de la superficie
(en el cruce) cuando tenía cierta
desviación que ponía en riesgo muy alto
la lógica pensada para que el robot
pudiera resolver el laberinto, ya que al
salirse de las líneas, perdida totalmente el
control que se tenía sobre él.
Conclusión
Una de las mejores experiencias que
hemos tenido fue la realización de este
proyecto, ya que demando una exhausta
búsqueda de información acerca de cómo
armar y programar nuestro prototipo,
además de ser la primera vez en
adentrarnos en esta área.
Otro aspecto importante es que aunque
se tenga la mejor arquitectura, no
garantiza un óptimo funcionamiento del
robot, ya que el componente más
importante es el código lo que en realidad
controla a la parte mecánica.
Para finalizar, la placa arduino es un
componente muy básico pero con muchas
utilidades dentro de todos los ámbitos ya
que como vimos anteriormente tiene
aplicaciones prácticas que ayudan a
solucionar o servir como apoyo a una
necesidad que se tenga.
Instituto Tecnológico de Tuxtla Gutiérrez
Ciencia y Tecnología con sentido Humano
Ingeniería en Sistemas Computacionales
Referencias Arduino. (2016). Obtenido de https://www.arduino.cc/en/main/arduinoBoardUno
Arduino. (2016). Obtenido de Arduino: http://forum.arduino.cc/index.php?topic=157831.0
MsRobotics. (2016). Obtenido de http://msrobotics.net/index.php/laboratorio-ard/87-control-
remoto-infrarrojo-con-arduino