Robot Zero 2012. Frenos.

El otro día ponía un ejemplo de un driver para motores, un medio puente en H hecho con mosfets que se puede usar para pequeños robots/motores y que tenía la opción de frenar la rueda. Aunque lo de cómo controlar los motores en los robots puede ser algo básico para la mayoría de las personas que van a los concursos, subo una demostración donde se puede ver la importancia de usar el freno.

Cuando compramos una placa o un integrado de puente en H, todos suelen ofrecer cuatro opciones en función de sus entradas, en la imagen se ve las posibles combinaciones de el clásico L298:

  • Controlar el motor en velocidad en un sentido.
  • Controlar el motor en velocidad en el sentido contrario.
  • Frenar el motor si está girando.
  • Dejarlo el motor libre sin frenarlo.

Por lo que podemos controlar los motores de nuestro robot velocistas de varias formas distintas:

  • Podemos meter una señal PWM que active el motor durante el tiempo que esté a uno la señal y lo deje libre el resto del período en el que la señal PWM está a cero.
  • Podemos meter la misma señal PWM activando el motor durante el tiempo que esté a uno la señal, e intentar frenarlo durante el resto del período en que la señal está a cero (si la bobina del motor permite cambiar el sentido de la intensidad durante el Toff).
  • Controlar el motor con una señal PWM y para frenar invertir el sentido de giro del motor (he visto hacer ésto más de una vez en los concursos).

Desde mi punto de vista la que mejor resultados va a dar en un robot velocista es la segunda, intentar frenar el motor en la parte del período en el que la señal PWM está a cero nos permite tener un control más rápido de la velocidad que le damos a la rueda, además de comenzar a frenar cuando el ciclo de trabajo del pwm sea cero, lo que se traduce en una respuesta más rápida del robot. Este efecto puede que tengamos que considerarlo a la hora de elegir la frecuencia de PWM para el control del motor.

En la base del robot zero del Cosmobot 2011 he montado una electrónica nueva con el driver de la semana pasada, las ideas han sido dos, ver si aguanta el dc-dc de Pololu (su corriente máxima de entrada es sólo 2A) poniendo unos cuantos condensadores ante un ciclo de trabajo del 100%, en la versión anterior se reseteaba sobre el 80%. Y mostrar la importancia de frenar el motor cuando el PWM es cero frente a la opción de dejarlo libre.

La placa (para probar) como se puede ver tiene el dc-dc de Pololu, un ATmega328p @ 3.3V, un interruptor, un led y los dos medio puentes para controlar cada motor, más unos cuantos condensadores para ver si el dc-dc aguanta el pico de arranque de los motores (1.6A en stall cada uno) sin resetear el micro.

En unas primeras pruebas el dc-dc parece que aguanta el arranque del robot con un ciclo de trabajo del pwm del 100%, aunque todavía es pronto para decir si se puede usar ya que queda ver su comportamiento con el robot dando vueltas.

Pongo un video donde se puede ver el arranque del robot al 100% de PWM y con 200 gr de lastre, el robot comienza a andar 5 segundos después de pulsar el pulsador, por lo que no se resetea el micro en ningún momento.

Respecto a la parte de frenar, la prueba de frenar en el Toff del PWM no la he hecho. Pero si he probado a frenar cuando el ciclo de trabajo del PWM es del 0% y lo he comparado con dejar el motor libre en lugar de frenar, y se puede ver como incluso en un motor tan pequeño ésto supone una gran diferencia en la respuesta del robot.

Por ejemplo llevamos un regulador PD (mismo código que en el robot zero del Cosmobot):

*********** Ajuste comportamiento robot *********/
//Constantes Regulador PD.
int Kp = 9;  // 
int Kd = 0; //
volatile int velocidad = 75; 
/*************************************************/</p>
ISR(TIMER1_COMPA_vect)
{
 
	int errort=0;
	int proporcional = obtener_errorp();
	int derivativo = obtener_errord();
 
	errort = proporcional + derivativo;
 
 
	if(errort > velocidad)
		errort = velocidad;
	else if(errort < - velocidad)
		errort = - velocidad;
 
 
	if(errort>0)
	{
    	OCR0A = velocidad - errort;     //Motor derecho.
         OCR0B = velocidad;              //Motor izquierdo.
	}
	else if(errort<0)
	{
    	OCR0A = velocidad;              //Motor derecho.  
        OCR0B = velocidad + errort;     //Motor izquierdo. 
	}
 
	else
	{
    	OCR0A = velocidad;
		OCR0B = velocidad;
	}
 
 
    TIFR1 |= (1<<OCF1A);
}

Con el código anterior donde cuando el PWM es cero, el motor se deja libre en lugar de frenarlo, a una velocidad de tan sólo el 30% de la máxima y una Kp de 9 que pone el pwm a cero cuando la línea alcanza el último sensor, el resultado es el siguiente:

/*********** Ajuste comportamiento robot *********/
//Constantes Regulador PD.
int Kp = 75;  // 
int Kd = 0; // 425
volatile int velocidad = 75; 
/*************************************************/

Si intentamos subir la Kp, por ejemplo ponemos un valor muy grande en el que ya nada más que la línea se sale de los sensores centrales una de las ruedas se para, obtenemos un resultado bastante similar.

La poca inercia de este robot es suficiente para que la rueda no se pare y el robot acabe fuera de la pista en la primera curva.

Ahora en lugar de dejar el motor libre se va a activar el freno del driver cuando el pwm del motor sea cero, obteniendo una respuesta mucho mejor para una Kp mínima de 9.

/*********** Ajuste comportamiento robot *********/
//Constantes Regulador PD.
int Kp = 9;  // 
int Kd = 0; //
volatile int velocidad = 75; 
/*************************************************/
 
ISR(TIMER1_COMPA_vect)
{
 
	int errort=0;
	int proporcional = obtener_errorp();
	int derivativo = obtener_errord();
 
	errort = proporcional + derivativo;
 
	if(errort > velocidad) //poner mayor o igual
	{
		errort = velocidad;
		OCR0A = 0;
		_delay_us(200);
		PORTD |= (1<<FRENO2);
	}
	else if(errort < - velocidad)
	{
		errort = - velocidad;
		OCR0B = 0;
		_delay_us(200);
		PORTD |= (1<<FRENO1);
	}
 
	else
	{
		PORTD &= ~(1<<FRENO1);
		PORTD &= ~(1<<FRENO2);
		_delay_us(200);
	}
 
	if(errort>0)
	{
    	OCR0A = velocidad - errort;     //Motor derecho.
        OCR0B = velocidad;              //Motor izquierdo.
	}
	else if(errort<0)
	{
    	OCR0A = velocidad;              //Motor derecho.  
        OCR0B = velocidad + errort;     //Motor izquierdo. 
	}
 
	else
	{
    	OCR0A = velocidad;
		OCR0B = velocidad;
	}
 
 
    TIFR1 |= (1<<OCF1A);
}

Como se puede ver la respuesta del robot es mucho más rápida evitando que se salga en la curva con la Kp mínima que para el motor.

Para quitar la oscilación del robot nada como poner un poco de derivativa al programa anterior, como bien explican aquí.

/*********** Ajuste comportamiento robot *********/
//Constantes Regulador PD.
int Kp = 9;  // 
int Kd = 425; //
volatile int velocidad = 75; 
/*************************************************/

Obteniendo un robot que sigue la línea sin oscilar.

Para no hacer esto más largo abro un hilo en el foro donde esta semana intentaré poner alguna conclusión y podamos discutirlas, y a ver que electrónica vamos haciendo para este año.

Visitas :9617
Both comments and pings are currently closed.

Comments are closed.

Subscribe to RSS Feed Follow me on Twitter!