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; } } } } }