Modificacion de código del Robot Velocista (Mejorado para cualquier pista de competencia)
Para esta ocasión vamos a modificar el algoritmo de un velocista para que funcione en cualquier linea, pista, terreno, etc. Ya que hemos visto en el post anterior la utilizacion de la libreria que modifique para los sensores qtr y si llegaron a probarlos, supongo que ya habrán sacado sus propias conclusiones acerca de como afectan los valores de los parámetros que agregue a la función. Entonces ahora si estamos listos para lo bueno!
En este post esplique el funcionamiento de un "algoritmo pid para un robot velocista", y ademas puese un ejemplo de la utilizacion del programa de un velocista de competencia:
Robot Velocista de competencia: Algoritmo Pid - Programacion Robot velocista
Con las modificaciones respectivas el velocista esta listo para competir en cualquier pista y ya nunca mas tendremos el problema de que no sense bien el robot, este codio es robusto y lo he probado con el robot en anbientes donde hay mucha luz de sol , y el robot anda de maravilla, claro nunca esta de mas tratar de cubrir los sensores para que la interferencia de la luz no afecte.
El codigo final es este:
Con las modificaciones respectivas el velocista esta listo para competir en cualquier pista y ya nunca mas tendremos el problema de que no sense bien el robot, este codio es robusto y lo he probado con el robot en anbientes donde hay mucha luz de sol , y el robot anda de maravilla, claro nunca esta de mas tratar de cubrir los sensores para que la interferencia de la luz no afecte.
El codigo final es este:
#include <QTRSensors.h> ///////////////////////////////////////////////////////////////////////////////////// //************* Programa realizado por MARKO A. CABALLERO MORENO*************** // // Solo para fines educativos // // robot velocista mini FK BOT V 2.0 // // micro motores pololu MP 10:1, sensores qtr 8rc, driver drv8833, arduino nano // // // ACTUALIZADO 22/4/2015 // ///////////////////////////////////////////////////////////////////////////////////// #define NUM_SENSORS 8 //numero de sensores usados #define TIMEOUT 2500 // tiempo de espera para dar resultado en uS #define EMITTER_PIN 6 //pin led on ///////////////pines arduino a utilizar///////////////////// #define led1 13 #define led2 4 #define mot_i 7 #define mot_d 8 #define sensores 6 #define boton_1 2 //pin para boton #define pin_pwm_i 9 #define pin_pwm_d 10 QTRSensorsRC qtrrc((unsigned char[]) {19, 18, 17, 16,15,14,11,12} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN); //variables para almacenar valores de sensores y posicion unsigned int sensorValues[NUM_SENSORS]; unsigned int position=0; /// variables para el pid int derivativo=0, proporcional=0, integral=0; //parametros int salida_pwm=0, proporcional_pasado=0; //_______AQUI CAMBIEREMOS LOS PARAMETROS DE NUESTRO ROBOT_________________ int velocidad=70; //variable para la velocidad, el maximo es 255 float Kp=0.18; float Kd=2; float Ki=0.01; //constantes //variables para el control del sensado int linea=0; // 0 para lineas negra, 1 para lineas blancas int flanco_color =0; // aumenta o disminuye el valor del sensado int en_linea=500; //valor al que considerara si el sensor esta en linea o no int ruido= 50; //valor al cual el valor del sensor es considerado como ruido //________________________________________________________________________________ void setup() { delay(800); pinMode(mot_i, OUTPUT);//pin de direccion motor izquierdo pinMode(mot_d, OUTPUT);//pin de direccion motor derecho pinMode(led1, OUTPUT); //led1 pinMode(led2, OUTPUT); //led2 pinMode(boton_1, INPUT); //boton 1 como pull up for (int i = 0; i < 50; i++) //calibracion durante 2.5 segundos, { //para calibrar es necesario colocar los sensores sobre la superficie negra y luego digitalWrite(led1, HIGH); //la blanca delay(20); qtrrc.calibrate(); //funcion para calibrar sensores digitalWrite(led1, LOW); delay(20); } digitalWrite(led1, LOW); //apagar sensores para indicar fin //de calibracion delay(400); digitalWrite(led2,HIGH); //encender led 2 para indicar la // espera de pulsacion de boton while(true) { int x=digitalRead(boton_1); //leemos y guardamos el valor // del boton en variable x delay(100); if(x==0) //si se presiona boton { digitalWrite(led2,LOW); //indicamos que se presiono boton digitalWrite(led1,HIGH); //encendiendo led 1 delay(100); break; //saltamos hacia el bucle principal } } } void loop() { pid(linea, velocidad, Kp, Ki, Kd, flanco_color, en_linea, ruido); //funcion para algoritmo pid(modificado ) //(tipo_linea,velocidad,kp,ki,kd,flanco_color,en_linea,ruido) frenos_contorno(linea,700); //funcion para frenado en curvas tipo //flanco de comparación va desde 0 hasta 1000 , esto para ver //si esta en negro o blanco } ////////funciones para el control del robot//// //aqui esta modificado la funcion del pid para que reciba los nuevos parametros para la libreria modificada void pid(int linea, int velocidad, float Kp, float Ki, float Kd,int flanco_color, int en_linea,int ruido) { position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, linea,flanco_color, en_linea, ruido ); //0 para linea //negra, 1 para linea blanca proporcional = (position) - 3500; // set point es 3500, asi obtenemos el error integral=integral + proporcional_pasado; //obteniendo integral derivativo = (proporcional - proporcional_pasado); //obteniedo el derivativo if (integral>1000) integral=1000; //limitamos la integral para no causar problemas if (integral<-1000) integral=-1000; salida_pwm =( proporcional * Kp ) + ( derivativo * Kd )+(integral*Ki); if ( salida_pwm > velocidad ) salida_pwm = velocidad; //limitamos la salida de pwm if ( salida_pwm < -velocidad ) salida_pwm = -velocidad; if (salida_pwm < 0) { motores(velocidad+salida_pwm, velocidad); } if (salida_pwm >0) { motores(velocidad, velocidad-salida_pwm); } proporcional_pasado = proporcional; } void motores(int motor_izq, int motor_der) { if ( motor_izq >= 0 ) //motor izquierdo { digitalWrite(mot_i,HIGH); // con high avanza analogWrite(pin_pwm_i,255-motor_izq); //se controla de manera //inversa para mayor control } else { digitalWrite(mot_i,LOW); //con low retrocede motor_izq = motor_izq*(-1); //cambio de signo analogWrite(pin_pwm_i,motor_izq); } if ( motor_der >= 0 ) //motor derecho { digitalWrite(mot_d,HIGH); analogWrite(pin_pwm_d,255-motor_der); } else { digitalWrite(mot_d,LOW); motor_der= motor_der*(-1); analogWrite(pin_pwm_d,motor_der); } } void frenos_contorno(int tipo,int flanco_comparacion) { if(tipo==0) { if (position<=500) //si se salio por la parte derecha de la linea { motores(-80,90); //debido a la inercia, el motor //tendera a seguri girando //por eso le damos para atras , para que frene // lo mas rapido posible while(true) { qtrrc.read(sensorValues); //lectura en bruto de sensor if ( sensorValues[0]>flanco_comparacion || sensorValues[1]>flanco_comparacion ) //asegurar que esta en linea { break; } } } if (position>=6500) //si se salio por la parte izquierda de la linea { motores(90,-80); while(true) { qtrrc.read(sensorValues); if (sensorValues[7]>flanco_comparacion || sensorValues[6]>flanco_comparacion ) { break; } } } } //******* if(tipo==1) //para linea blanca con fondo negro { if (position<=500) //si se salio por la parte derecha de la linea { motores(-80,90); //debido a la inercia, el motor //tendera a seguri girando //por eso le damos para atras , //para que frene lo mas rapido posible while(true) { qtrrc.read(sensorValues); //lectura en bruto de sensor if ( sensorValues[0]<flanco_comparacion || sensorValues[1]<flanco_comparacion ) //asegurar que esta en linea { break; } } } if (position>=6500) //si se salio por la parte izquierda de la linea { motores(90,-80); while(true) { qtrrc.read(sensorValues); if (sensorValues[7]<flanco_comparacion || sensorValues[6]<flanco_comparacion) { break; } } } } }
31 comentarios:
hola disculpa me marca error al compilar que podría ser gracias
hola, si instalaste correctamente la libreria no deberias tener problemas, te dejo el link para que la instales:https://mega.co.nz/#!i8VQVBCY!1EshEtQ7qQQSOv001DZfFsZ-_Tdo9ykHoQvhgfzURjc , instalalo como una libreria convencional en el ide arduino, elimina la libreria anterior del qtrsensor. saludos
Hola una consulta para sensar en blanco pero en caso de los analógicos me podrías ayudar con la librería de agradecería mucho saludos
no compila marca un error no creo q sea la librería porque la programación anterior si compila, el error es en el void loop en esta línea:
void pid(int linea, int velocidad, float Kp, float Ki, float Kd,int flanco_color, int en_linea,int ruido)
{
position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, linea,flanco_color, en_linea, ruido );
tienes que descargar la libreria que modifique, la subi aqui https://mega.co.nz/#!i8VQVBCY!1EshEtQ7qQQSOv001DZfFsZ-_Tdo9ykHoQvhgfzURjc
desintala la anterior, y en su lugar pones esta.
funciona tambien para los analogicos, pero hay que cambiar algunas cosas cosas, haré un post con una programacion para analogico qtra.
hola podrias hacer un post para la libreria qtra? estoy teniendo muchos problemas, no la entiendo. graciassss!!
Amigo, en esta parte
position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, linea,flanco_color, en_linea, ruido ) , no deberia ir un 1 o 0, dependiendo de la linea a seguir??
ASI : position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, 1 ,linea,flanco_color, en_linea, ruido )
Hola Marko Caballero, una pregunta si quisiera usar tu codigo con un arduino Uno en vez de un Arduino Nano, puedo ocupar las entradas analogicas para los sensores?
O que mas modificaciones tendria que hacer para acoplarlo a un Arduino uno?
Agradeceria tu ayuda.
si es al reves linea negra y fondo blanco es "tipo==0"
en ves de la de "tipo==1"???
si es al reves linea negra y fondo blanco es "tipo==0"
en ves de la de "tipo==1"???
buenas disculpe, es que en el programa me aparece un error en esta parte " position = qtrrc.readLine(sensorValues, QTR_EMITTERS_ON, linea,flanco_color, en_linea, ruido );" en esa zona me marca un error, el error que me da es "no matching function for call to 'QTRSensorsRC::readLine(unsigned int [8], int, int&, int&, int&, int&)'" y pues nose que hacer ya lo cambie a como me dice ahi pero me da otros errores, tambien intente cambiando a la libreria que subio usted pero me da el mismo error, espero su respuesta lo mas pronto posible y gracias por su atencion
HOLA MARKO CABALLERO ME INTERESA MUCHO ESTE TEMA DE LOS ROBOTS VELOCISTAS COMO TE PUEDO CONTACTAR, PARA QUE ME PUDIERAS AYUDAR EN UN PROYECTO QUE TENGO ES URGENTE. ESPERO Y SI PUEDAS
Podrías de favor modificar el código para que funcione con el sensor 8qtra.
disculpa tengo un problema al subir a la placa el programa
buenas noches disculpa podrias poner una foto de como quedo ya todo el circuito armado por favor porque en la imagen que pones de las conecciones no se ve donde van los capacitores, o si usa un puente h, o cosas asi y de verdad me serviria que me pudieras apoyar con eso gracias (aunque ya todo lo que mostraste es un gran apoyo para alguien que apenas empieza en estos temas gracias).
hola buenas noche ...como estas me gustaria contactarme contigo por una consulta ...te paso mi correo valentinojorgeferro@gmail.com ...se puede hacer el control porpiden microcontroladores como picaxe??? ya que mi robot lo empese con eso estoy usando un picaxe 18m2 tiene puente h para cada motor 6 sensores cny70 que estan conectados analogicamente al micro..
Hola
Señores buenas noches para aquellos que desean utilizar el QTR 8RA deberán tener en cuenta que este entrega una salida lógica 1 si el voltaje es mayor 2.3 vol y 0 si es menor a 2.3 a través de los pines digitales, una vez entendido el tema lo que se requiere es realizar una tabla de verdad con los datos de los sensores para el color negro 1 y para el blanco 0 con esto solo es determinar los valores del error dependiendo de la posición del robot sobre la línea negra. ejemplo
00011000 aquí el error es cero
00110000 error = -1
01100000 error = -2
00001100 error = 1
00000110 error = 2
así sucesivamente espero les sirva de ayuda
Cómo debería de hacer para sensar correctamente si tengo 16 sensores a través de un multiplexor 4067 con una sola salida analógica
HOLA. amigo muy interesante tu trabajo sobre la librería intente poner tu código a mi seguidor pero no funciona bien leí este tutorial reemplace la librería y modifique el orden de pines y el numero de sensores pero no funciona también probé en mi pololu zumo shield y no funciona me fije bien en el orden de conexiones pero el código falla prendo el robot sdl e intento calibrar poniéndolo en negro y luego en blanco,sobre la linea y no calibra bien el botón a mi no me funciona
Hola como esta me gustó tu post pero yo quisiera usar los sensores tcrt5000 para este robot como tendría que modificar el código para estos sensores me podrías ayudar?
compañero estoy utilizando un l293d en vez de el dvr pero el carrito va lento no se por q en q lugar del codigo debo cambiar porfa es urge
Hola Sergio pudo solucionar el problema? a mi me pasa igual que a Ud. yo hice el cambio de libreria y todo lo que mis conocimientos da pero no compila, me sale su mismo error.
Gracias
ayudame amigo
hola amigo estuve observando tu código y esta genial el anterior, pero este nuevo cuando actualizo la librería que das, aun así me marca error en la parte que dice void setup(){"delay(800);" en donde están las comillas siempre me marca error.
AYUDA ESTE ERROR ME LO MARCA
avr-g++: error: missing filename after '-o'
exit status 1
Error de compilación
disculpa el boton del pin 2 para que lo utilizas?
amigos me aparece este error al compilarlo que sera? ayuda xfA
processing.app.debug.RunnerException
at cc.arduino.Compiler.callArduinoBuilder(Compiler.java:317)
at cc.arduino.Compiler.loadPreferences(Compiler.java:216)
at cc.arduino.Compiler.build(Compiler.java:175)
at processing.app.SketchController.build(SketchController.java:647)
at processing.app.Editor$BuildHandler.run(Editor.java:1758)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Cannot run program "C:\Program Files (x86)\Arduino\arduino-builder": CreateProcess error=2, El sistema no puede encontrar el archivo especificado
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:26)
at cc.arduino.Compiler.callArduinoBuilder(Compiler.java:297)
... 5 more
Caused by: java.io.IOException: CreateProcess error=2, El sistema no puede encontrar el archivo especificado
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:386)
at java.lang.ProcessImpl.start(ProcessImpl.java:137)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 7 more
He visto algunas pistas combinadas con lineas blancas y negras , este código no serviría verdad? debemos hacer el cambio manual de 0 y 1
estoy utilizando el puente h tb6612fgn .... cuales serian los cambios que tengo realizar en el codigo
tu pagina es increíble soy fan de los seguidores de linea
Publicar un comentario