Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola pues me dispongo a desarrollar un velocista en un plazo de un año, es decir, para el próximo cosmobot si dios o la caixa quieren. Y me gustaría pedir consejo y escuchar opiniones sobre diferentes puntos.
La base va a ser un coche rc de escala 1/28, como el miniz del cosmobot, esta vez otro modelo de coche, al que he podido incorporar un microservo de 0.1 s 60 grados, para el giro.
Mi primera duda surge en que tipo de sensores para detectar la línea usar, o cuáles hay disponibles. Lo ideal es que cuanto más pequeños mejor, y probablemente haga lectura analógica sobre digital, ya veremos como afectan los cambios de luz.
Yo hasta ahora sólo conozco dos modelos de sensor, en CNY70 y el QRD1114 de fairchild que nunca he usado, en el cosmobot vi a gente que llevaba diversos tipos de sensores, algunos de ellos eran muy pequeños, a ver si alguien me puede indicar otro modelo de sensores distintos de los dos anteriores, o foto trt y foto diodo.
Segunda duda, es como colocar los sensores, mi idea inicial es volver a usar dos placas de sensores, una delante y otra detrás, la de detrás es muy útil para conocer la posición del robot respecto a la línea, para poder realizar cambios de carril y acelerar, cuando el robot está centrado.
En el cosmobot vi a un robot, este http://es.youtube.com/watch?v=IVLpgTclsrI que usaba esa técnica para seguir la línea, me comentaron que esta era la manera correcta de hacerlo, o como se debia hacer. Me gustaría saber que ventajas tiene de hacerlo de esta forma frente a la clásica placa de sensores fija en el coche. Supongo que de esta forma se podrá obtener un error mucho más exacto.
Y por último que microcontrolador usar, he estado leyendo y creo que la mejor elección para este tipo de proyecto es un DSP, además de un mayor número de MIPS llevas los multiplicadores por hard, bastante útil a la hora de realizar operaciones.
Las señales que habría que leer en principio serían los sensores y un encoder que lleve el coche, que aún no sé muy bien donde se lo voy a poder colocar, quizás en el piñon o en la corona, y luego por último leer la batería. Las salidas el motor y el servo.
Aunque con un micro de 8 bits bien programado se puede hacer todo esto y más, yo creo que es un buen proyecto para iniciarse con micros mayores (almenos para mi), aún no sé la cantidad de operaciones que habría que hacer por segundo, mi idea inicial siendo muy optimista, es alcanzar los 2 m/s de media.
Así que a ver si alguien me puede aconsejar un micro para empezar, de momento yo he pensado en el dsPIC del que ya tendría el programador, por lo que el coste sería cero. Pero puestos a aprender no sé si sería mejor irme al mayor fábricante, es decir texas instruments, lo que no sé es cuánto costaría un DSP de estos, y cuánto el material para el desarrollo. La idea es usar un micro smd frente a un kit, por razones de espacio.
Tb me estoy iniciando estos días con atmel, que supongo que tendrá su alternativa a usar.
Gracias. S2
hola chicos estoy apenas diseñando un robot velocista, anteriormente diseñe un seguidor de linea, peror era lento, pues con los videos en you tobe, me emocione en construir uno de estos, les agradezco si me pueden ayudar en este codigo que era del anterior seguidor, en ello que puede hacer para que sea mas eficiente en cuanto a su respuesta.............. 💡
este es mi pprograma , sera que lo puedo modificar mucho mas........es en c
gracias..........
//-ZERON=-
#include <18f452.h>
#device adc=10
#fuses XT, NOPROTECT, PUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
#use delay(clock=4000000)
void sensores(void);
float adc(char canal);
float muestreo(char canal);
void sigue_linea(void);
void adelante_traccion(void);
void atras_traccion(void);
void parar_traccion(void);
void izquierda_cabezal(void);
void derecha_cabezal(void);
void parar_cabezal(void);
void curvas (void);
void cruces(void);
void giro_izquierdo(void);
void giro_derecho(void);
void cruce_izquierdo(void);
void cruce_derecho(void);
void sensores_distancia(void);
unsigned char sensor_L_D,sensor_L_I,sensor_C_D,sensor_C_I,sensor_M_I,sensor_M_D,distanciaD, distanciaI;
long pwm_cabezal;
long pwm_traccion;
//PRINCIPAL
void main(void)
{
set_tris_d(0b11111111);
setup_adc(adc_clock_internal);
setup_adc_ports(all_analog);
setup_timer_2(T2_DIV_BY_16,249,1);
while(true)
{
sensores();
sigue_linea();
curvas();
cruces();
}
/* while(sensor_L_D == 1 && sensor_L_I == 1 && sensor_M_I == 1 && sensor_M_D == 1)
{
sensores_distancia();
sensores();
break;
}*/
}
//SUBPROGRAMAS DE LECTURA
//Lectura analoga de las puertas A
float adc(char canal)
{
float result;
set_adc_channel(canal);
delay_us(4);
result=read_adc();
return result;
}
//Promedio de 4 muestreos por canal analogo
float muestreo(char canal)
{
char k, ct=2, Q;
float sum=0, prom;
for(k=0; k<2; k++)
{sum=sum+adc(canal);}
prom=(sum/ct);
if(prom>690){Q=1;}
if(prom<690){Q=0;}
return Q;
}
//Lectura de las puertas ACD y Representacion visual
void sensores()
{
sensor_C_I = Muestreo(4);
output_bit (pin_c6, sensor_C_I) ;
sensor_M_I = Muestreo(7);
output_bit (pin_c7, sensor_M_I) ;
sensor_L_I = Muestreo(3);//sensor centro
output_bit (pin_d4, sensor_L_I) ;
sensor_L_D = Muestreo(2);//sensor centro
output_bit (pin_d5, sensor_L_D) ;
sensor_M_D = Muestreo(1);
output_bit (pin_d6, sensor_M_D) ;
sensor_C_D = Muestreo(0);
output_bit (pin_d7, sensor_C_D) ;
distanciad = muestreo(5);
distanciaI = muestreo(6);
}
//SUBPROGRAMAS DE CONTROL
void sigue_linea()
{
long pwm_cabezal;
long pwm_traccion;
//sigue linea total
if(sensor_L_D == 1&&sensor_L_I == 1)
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
setup_ccp2 (CCP_PWM);
pwm_traccion=700;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_L_D == 1&&sensor_L_I == 0)
{
derecha_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=650;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
setup_ccp2 (CCP_PWM);
pwm_traccion=700;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_L_D == 0&&sensor_L_I == 1)
{
izquierda_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=650;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
setup_ccp2 (CCP_PWM);
pwm_traccion=700;
set_PWM2_duty(pwm_traccion);
sensores();
}
}
void curvas()
{
if(sensor_M_D == 0&&sensor_L_D == 0&&sensor_L_I == 0&&sensor_M_I == 1)
{
izquierda_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=700;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
setup_ccp2 (CCP_PWM);
pwm_traccion=900;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_M_D == 1&&sensor_L_D == 0&&sensor_L_I == 0&&sensor_M_I == 0)
{
derecha_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=500;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
setup_ccp2 (CCP_PWM);
pwm_traccion=900;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 0&&sensor_M_I == 0)
{
derecha_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=400;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
delay_ms(300);
giro_derecho();
setup_ccp2 (CCP_PWM);
pwm_traccion=650;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_M_D == 0&&sensor_L_D == 0&&sensor_L_I == 1&&sensor_M_I == 1)
{
izquierda_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=400;
set_PWM1_duty(pwm_cabezal);
adelante_traccion();
delay_ms(600);
giro_izquierdo();
setup_ccp2 (CCP_PWM);
pwm_traccion=650;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 1 &&sensor_M_I == 0)
{
izquierda_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=700;
set_PWM1_duty(pwm_cabezal);
parar_traccion();
delay_ms(400);
giro_izquierdo();
setup_ccp2 (CCP_PWM);
pwm_traccion=650;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_M_D == 0&&sensor_L_D == 1&&sensor_L_I == 1 &&sensor_M_I == 1)
{
derecha_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=700;
set_PWM1_duty(pwm_cabezal);
parar_traccion();
delay_ms(300);
giro_derecho();
setup_ccp2 (CCP_PWM);
pwm_traccion=650;
set_PWM2_duty(pwm_traccion);
sensores();
}
}
void cruces()
{
if(sensor_C_D == 1&&sensor_M_D == 0&&sensor_L_D == 0&&sensor_L_I == 0&&sensor_M_I == 0&&sensor_C_I == 0)
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
giro_derecho();
setup_ccp2 (CCP_PWM);
pwm_traccion=750;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_C_D == 0&&sensor_M_D == 0&&sensor_L_D == 0&&sensor_L_I == 0&&sensor_M_I == 0&&sensor_C_I == 1)
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
giro_izquierdo();
setup_ccp2 (CCP_PWM);
pwm_traccion=750;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_C_D == 1&&sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 0&&sensor_M_I == 0&&sensor_C_I == 0)
{
derecha_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=300;
set_PWM1_duty(pwm_cabezal);
giro_derecho();
setup_ccp2 (CCP_PWM);
pwm_traccion=500;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_C_D == 0&&sensor_M_D == 0&&sensor_L_D == 0&&sensor_L_I == 1&&sensor_M_I == 1&&sensor_C_I == 1)
{
derecha_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=300;
set_PWM1_duty(pwm_cabezal);
giro_izquierdo();
setup_ccp2 (CCP_PWM);
pwm_traccion=750;
set_PWM2_duty(pwm_traccion);
sensores();
}
}
/*void sensores_distancia()
{
if(sensor_C_D == 1&&sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 1&&sensor_M_I == 1&&sensor_C_I == 1&& distanciaI == 1 && distanciaD == 1)//preguntar .............
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
adelante_traccion ();
setup_ccp2 (CCP_PWM);
pwm_traccion=250;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_C_D == 1&&sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 1&&sensor_M_I == 1&&sensor_C_I == 1&& distanciaI == 1 && distanciaD == 0)
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
cruce_izquierdo();
setup_ccp2 (CCP_PWM);
pwm_traccion=250;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_C_D == 1&&sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 1&&sensor_M_I == 1&&sensor_C_I == 1&& distanciaI == 0 && distanciaD == 1)
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
cruce_derecho();
setup_ccp2 (CCP_PWM);
pwm_traccion=250;
set_PWM2_duty(pwm_traccion);
sensores();
}
if(sensor_C_D == 1&&sensor_M_D == 1&&sensor_L_D == 1&&sensor_L_I == 1&&sensor_M_I == 1&&sensor_C_I == 1&& distanciaI == 1 && distanciaD == 0)
{
parar_cabezal();
setup_ccp1 (CCP_PWM);
pwm_cabezal=0;
set_PWM1_duty(pwm_cabezal);
cruce_izquierdo();
setup_ccp2 (CCP_PWM);
pwm_traccion=250;
set_PWM2_duty(pwm_traccion);
sensores();
}
}*/
void parar_cabezal()
{
output_low(pin_d0);
output_low(pin_d1);
}
void izquierda_cabezal()
{
output_high(pin_d0);
output_low(pin_d1);
}
void derecha_cabezal()
{
output_low(pin_d0);
output_high(pin_d1);
}
void adelante_traccion ()
{
output_low(pin_d2);
output_high(pin_d3);
output_low(pin_b0);
output_high(pin_b1);
}
void atras_traccion ()
{
output_high(pin_d2);
output_low(pin_d3);
output_high(pin_b0);
output_low(pin_b1);
}
void parar_traccion()
{
output_low(pin_d2);
output_low(pin_d3);
output_low(pin_b0);
output_low(pin_b1);
}
void giro_izquierdo()
{
output_low(pin_d2);//motor derecho
output_high(pin_d3);
output_high(pin_b0);//motor izquierdo
output_low(pin_b1);
}
void giro_derecho()
{
output_high(pin_d2);
output_low(pin_d3);
output_low(pin_b0);
output_high(pin_b1);
}
void cruce_derecho()
{
output_low(pin_d2);
output_low(pin_d3);
output_high(pin_b0);
output_low(pin_b1);
}
void cruce_izquierdo()
{
output_high(pin_d2);
output_low(pin_d3);
output_low(pin_b0);
output_low(pin_b1);
}
Estuve viendo tu codigo...
Una consulta tiene 8 sensores???? o me equivoco...
.....
saludos
No se como de activo esta este hilo pero bueno. Hay una cosa que he aprendido de los siguelineas y se llama basicamente control PD.
Te recomiendos que reestructures el codigo y montes con bucle de control PD.
Te ahorraras mucho codigo y ganaras mucha velocidad.