domingo, 19 de abril de 2015

MODIFICACION LIBRERIA "QTR SENSORS" PARA MEJOR SENSADO - Parte II

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:


#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..

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