¡Codificadores giratorios para garantizar que el robot de 2 ruedas vaya recto!

1

He contado con éxito los codificadores giratorios en la rueda de mi robot, así que esto no es un problema.

Mi problema es qué hacer con este número.

Básicamente, el mayor problema es que necesito que mi robot siga recto y quiero hacerlo utilizando solo dos codificadores (uno en cada rueda).

Incluso si envío la misma cantidad de energía a ambos motores, el robot no funciona correctamente. Es por eso que decidí usar codificadores, así que no importa la potencia de las baterías o las condiciones de los motores; el robot irá recto.

Entonces, ahora que he contado con éxito los "clics" en el codificador, necesito saber qué hacer con el número para asegurarme de que las ruedas de arrastre estén sincronizadas.

Este es el código que estoy usando (Arduino):

  digitalWrite(dirMotO, HIGH);
  digitalWrite(dirMotE, HIGH);
  //digitalWrite(motO, HIGH);
  analogWrite(motO, 150);
  //digitalWrite(motE, HIGH);
  analogWrite(motE, 150);

  PololuWheelEncoders::getCountsAndResetM1();
  PololuWheelEncoders::getCountsAndResetM2();

  while(PololuWheelEncoders::getCountsM1()<clicks && PololuWheelEncoders::getCountsM1()<clicks){
    if(PololuWheelEncoders::getCountsM1()>=clicks){
      digitalWrite(motO, LOW);
    }
    if(PololuWheelEncoders::getCountsM2()>=clicks){
      digitalWrite(motE, LOW);
    }
  }

Pensé que este código aseguraría que si una rueda llega a los conteos antes que la otra, se detendría y esperaría a que la otra rueda, pero el robot no vaya recto.

Realmente agradecería alguna ayuda con esto.

¡Gracias!

    
pregunta Zebs

6 respuestas

5

Su lógica de bucle while es incompatible con las condiciones dentro de ella.

Tu bucle while está diciendo:

  

siempre que AMBOS codificadores de rueda lean   menos de clics, ejecute el codigo   dentro

y sus declaraciones if están diciendo:

  

si alguno de los codificadores de rueda es mayor o igual a los clics, deténgase   el motor correspondiente

Esto generalmente es falso, excepto por la rara condición en la que uno de los codificadores se incrementa entre el arduino que evalúa el while y las instrucciones if. En palabras de orden casi nunca.

Entonces, lo primero que debes hacer es arreglar tu lógica. Luego necesita investigar medios más sofisticados para mantener las ruedas sincronizadas, como calcular un término de error de los diferentes en tics, y emplear un PID algoritmo del controlador para ajustar la velocidad de ambos motores a través de analogWrite .

    
respondido por el freespace
2

Supongo que los clics son el número de tics de codificador que desea avanzar. Esta respuesta depende de que los clics sean un poco más grandes, más de unos pocos múltiplos del conteo de tics de las ruedas, por debajo de eso no estoy seguro del rendimiento de este método.

Parte del problema es que está corrigiendo apagando completamente un motor. Eso significa que esas ruedas están efectivamente atascadas y comienzan a actuar como un pivote. Quieres hacer correcciones con ambas ruedas moviéndose.

Lo que debe hacer es intentar mantener la diferencia entre los tics de los dos motores lo más pequeña posible mientras se ejecuta. Como ejemplo, si tiene 16 tics por revoluciones y desea realizar 100 tics, querrá mantener la diferencia de tics lo más cerca posible a 0, aplicando más potencia al motor más lento y menos al más rápido. Codifique el código como un ejercicio para el lector (depende de cómo desee gestionar la variabilidad: actualice el valor de analogWrite 10 veces por segundo? ¿20? 5?).

Esto probablemente no funcionará tan bien para un pequeño número de tics (1 rev.), y las diversas leyes de error acumulado significan que probablemente tampoco será perfectamente correcto para un gran número de tics; pero debería dar mejores resultados que lo que tienes ahora.

    
respondido por el CoderTao
1

¿Ha considerado cerrar un bucle de velocidad en lugar de un bucle de posición? Inicialmente, acelere a una velocidad razonablemente lenta, de modo que haya menos posibilidades de que las dos ruedas se desincronicen. Si ambas ruedas se mueven a la misma velocidad, entonces su robot debe moverse en línea recta, a menos que haya algún tipo de deslizamiento de acoplamiento o deslizamiento entre las ruedas y la superficie en la que se encuentra el robot.

    
respondido por el Dave
1

una forma sencilla en que logré que mi robot siguiera la línea recta fue usando tres bucles mientras que, mientras una rueda cuenta más lentamente, aumenta la velocidad en esa rueda. un bucle es para la izquierda, otro para la derecha y el último simplemente le dice al programa que escriba velocidades iguales si el conteo es igual pero puede omitirlo. espero que esto ayude. y no te olvides de inpu un descanso; comando al final opf cada bucle de otra manera, permanecerá en el bucle incluso después de que se haya cumplido la condición

    
respondido por el Eugene
0

Lo siento, llego un poco tarde a la fiesta, pero en caso de que alguien más quiera hacer algo similar, un enfoque simplista que vale la pena probar es calcular continuamente el número de tics que debe haber movido cada rueda y luego un tick temporizador hace algo como:

volatile unsigned long expected_left_distance, expected_right_distance;
volatile unsigned int left_speed, right_speed;
unsigned long left_distance, right_distance;

void timer_tick(void)  // Run this at a rate faster than once per encoder pulse
{
  int delta;

  Add or subtract 65536 from left_distance if encoder has moved +/- a click
  Add or subtract 65536 from right_distance if encoder has moved +/- a click
  expected_left_distance += left_speed;
  expected_right_distance += right_speed;
  if ((left_distance - expected_left_distance) & 0x80000000) // Assumes long is 32-bit
    left_motor_on();
  else
    left_motor_off();
  if ((right_distance - expected_right_distance) & 0x80000000)
    right_motor_on();
  else
    right_motor_off();
}

Un valor de velocidad de 1 moverá el robot a la velocidad de un impulso de codificador cada 65536 interrupciones; una velocidad de 64 lo movería 64 veces más rápido (una vez cada 1024 interrupciones), etc. Dependiendo del diseño de los motores, la masa del sistema y las tasas de conteo del codificador, este movimiento podría ser adecuadamente suave o podría ser inaceptablemente desigual y desigual. Puede valer la pena probar el enfoque, sin embargo, para ver si funciona.

    
respondido por el supercat
-2
 while (decimal0>decimal1)
  {
    analogWrite(pin1,(pulsewidth+1));
    analogWrite(pin0,pulsewidth);
    break;
  }

  while (decimal0<decimal1)
  {
    analogWrite(pin0,(pulsewidth+1));
    analogWrite(pin1,pulsewidth);
    break;
  }

 while (decimal0=decimal1)
  {
    analogWrite(pin1,(pulsewidth+1));
    analogWrite(pin0,pulsewidth);
    break; 
  }
    
respondido por el Eugene

Lea otras preguntas en las etiquetas