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

He contado con éxito los codificadores rotatorios 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 vaya en línea recta y quiero hacerlo usando solo dos codificadores (uno en cada rueda).

Incluso si envío la misma cantidad de energía a ambos motores, el robot no va en línea recta. 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á derecho.

Entonces, ahora que conté con éxito los "clics" en el codificador, necesito saber qué hacer con el número para asegurarme de que las ruedas de remolque 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 contar antes que la otra, se detendría y esperaría a la otra rueda, pero el robot no avanza en línea recta.

Realmente agradecería alguna ayuda en esto.

¡Gracias!

¿Hay la misma cantidad de peso en cada rueda, es decir, las baterías están en el circuito izquierdo y en el derecho, por lo que está desequilibrado?
Me aseguré de que estuviera lo más balanceado posible, pero pensé que con el uso de codificadores podría evitar cualquier distorsión causada por factores externos... Tal vez no era el camino a seguir.
Un amigo con experiencia en robótica me dijo una vez que solo porque su rueda "giró" la misma distancia, no significa que las ruedas se movieron la misma distancia, especialmente cuando se trata de superficies potencialmente irregulares, resbaladizas o resistentes.
Para ilustrar el punto de @Toybuilder, imagine un robot en un plano sin fricción. Los codificadores de rueda siguen funcionando, pero el robot no va a ninguna parte. Los codificadores no pueden ayudar con el deslizamiento o el radio diferente de la rueda, etc.

Respuestas (6)

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

Su bucle while está diciendo:

siempre que AMBOS codificadores de rueda lean menos de clics, ejecute el código dentro

y sus declaraciones if están diciendo:

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

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

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

Supongo que los clics son la cantidad de tics del codificador que desea avanzar. Esta respuesta depende de que los clics sean un poco grandes, más que unos pocos múltiplos del recuento de tic de la rueda, 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. Quiere hacer correcciones con ambas ruedas en movimiento.

Lo que debe hacer es tratar de mantener la diferencia entre las marcas de los dos motores lo más pequeña posible mientras está en funcionamiento. Como ejemplo, si tiene 16 tics por revoluciones y quiere ir a 100 tics, desea mantener la diferencia de tics lo más cerca posible de 0, aplicando más potencia al motor más lento y menos al más rápido. El código se deja como ejercicio para el lector (depende de cómo quieras manejar la variabilidad: actualizar el analogWrite's 10 veces por segundo? ¿20? ¿5?).

Esto probablemente no funcionará tan bien para una pequeña cantidad de tics (1 rev), y las diversas leyes de acumulación de errores significan que probablemente tampoco sea perfectamente recto para una gran cantidad de tics; pero debería dar mejores resultados que los que tienes ahora.

¿Ha considerado cerrar un bucle de velocidad en lugar de un bucle de posición? Inicialmente, acelere a un ritmo razonablemente lento para 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, salvo cualquier tipo de deslizamiento del acoplamiento o deslizamiento entre las ruedas y la superficie sobre la que se desplaza su robot.

una manera simple de hacer que mi robot fuera recto fue usando tres bucles while, mientras una rueda cuenta más despacio, aumente la velocidad en esa rueda. un ciclo 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 olvides ingresar un descanso; comando al final de cada bucle; de ​​lo contrario, permanecerá en el bucle incluso después de que se haya cumplido la condición

Lo siento, llegué un poco tarde a la fiesta, pero en caso de que alguien más quiera hacer algo similar, un enfoque simplista que puede valer la pena probar es calcular continuamente la cantidad de tics que debería haberse movido cada rueda, y luego dentro de un tic del temporizador. hacer algo como:

volátil sin firmar largo esperado_distancia_izquierda, esperado_distancia_derecha;
volátil sin firmar int left_speed, right_speed;
distancia_izquierda larga sin signo, distancia_derecha;

void timer_tick(void) // Ejecuta esto a una velocidad mayor que una vez por pulso del codificador
{
  delta int;

  Sume o reste 65536 de left_distance si el codificador se ha movido +/- un clic
  Sume o reste 65536 de right_distance si el codificador se ha movido +/- un clic
  distancia_izquierda_esperada += velocidad_izquierda;
  distancia_derecha_esperada += velocidad_derecha;
  si ((distancia_izquierda - distancia_izquierda_esperada) & 0x80000000) // Supone que el largo es de 32 bits
    motor_izquierdo_encendido();
  demás
    motor_izquierdo_apagado();
  si ((distancia_derecha - distancia_derecha_esperada) & 0x80000000)
    motor_derecho_encendido();
  demás
    motor_derecho_apagado();
}

Un valor de velocidad de 1 moverá el robot a una velocidad de un pulso 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. Sin embargo, puede valer la pena probar el enfoque para ver si funciona.

 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; 
  }
while (condición) { instrucción; romper; } es equivalente a if (condición) { sentencia; } -- y el último es más claro.