Drehgeber, um sicherzustellen, dass der 2-Rad-Roboter geradeaus fährt!

Ich habe die Drehgeber am Rad meines Roboters erfolgreich gezählt, daher ist dies kein Problem.

Mein Problem ist, was ich mit dieser Nummer machen soll.

Grundsätzlich ist das größere Problem, dass mein Roboter geradeaus fahren muss und ich dies mit nur zwei Encodern tun möchte (einer an jedem Rad).

Selbst wenn ich die gleiche Kraft auf beide Motoren schicke, fährt der Roboter nicht geradeaus. Aus diesem Grund habe ich mich für die Verwendung von Encodern entschieden, unabhängig von der Leistung der Batterien oder den Bedingungen der Motoren. Der Roboter fährt geradeaus.

Nun, da ich die "Klicks" auf dem Encoder erfolgreich gezählt habe, muss ich wissen, was mit der Zahl zu tun ist, um sicherzustellen, dass die Schleppräder synchronisiert sind.

Dies ist der Code, den ich verwende (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);
    }
  }

Ich dachte, dieser Code würde sicherstellen, dass, wenn ein Rad vor dem anderen zählt, es anhalten und auf das andere Rad warten würde, aber der Roboter nicht geradeaus fährt.

Ich würde wirklich etwas Hilfe auf diesem schätzen.

Danke schön!

Ist auf jedem Rad das gleiche Gewicht, dh die Batterien befinden sich auf dem linken Stromkreis auf dem rechten, so dass es nicht im Gleichgewicht ist?
Ich habe darauf geachtet, dass es so ausgewogen wie möglich ist, aber ich dachte, dass ich durch die Verwendung von Encodern Verzerrungen durch externe Faktoren vermeiden könnte ... Vielleicht war es nicht der richtige Weg.
Ein Freund mit Robotik-Erfahrung sagte mir einmal, nur weil sich Ihr Rad um die gleiche Strecke "gedreht" hat, bedeutet das nicht, dass sich die Räder um die gleiche Strecke bewegt haben - insbesondere wenn Sie es mit potenziell unebenen, rutschigen oder widerstandsfähigen Oberflächen zu tun haben.
Um den Standpunkt von @Toybuilder zu veranschaulichen, stellen Sie sich einen Roboter auf einer reibungslosen Ebene vor. Die Rad-Encoder ticken weiter, aber der Roboter geht nirgendwo hin. Encoder können bei Schlupf oder unterschiedlichen Radradien usw. nicht helfen.

Antworten (6)

Ihre While-Schleifenlogik ist mit den darin enthaltenen Bedingungen nicht kompatibel.

Ihre While-Schleife sagt:

Solange BEIDE Rad-Encoder weniger als Klicks lesen, führen Sie den Code darin aus

und Ihre if-Anweisungen sagen:

Wenn einer der Rad-Encoder größer oder gleich Klicks ist, stoppen Sie den entsprechenden Motor

Dies ist im Allgemeinen falsch, außer in dem seltenen Fall, dass einer der Encoder zwischen dem Arduino, das die while- und if-Anweisungen auswertet, inkrementiert. Um es so gut wie nie auszudrücken.

Das erste, was Sie tun müssen, ist Ihre Logik zu korrigieren. Dann müssen Sie ausgeklügeltere Mittel untersuchen, um die Räder synchron zu halten, wie z. B. die Berechnung eines Fehlerterms aus den unterschiedlichen Ticks und die Verwendung eines PID- Regleralgorithmus, um die Geschwindigkeit beider Motoren über anzupassen analogWrite.

Ich nehme an, dass Klicks die Anzahl der Encoder-Ticks ist, die Sie vorwärts gehen möchten. Diese Antwort hängt davon ab, dass die Klicks etwas größer sind - mehr als ein paar Vielfache der Wheel Tick-Zählung - darunter bin ich mir der Leistung dieser Methode nicht sicher.

Ein Teil des Problems besteht darin, dass Sie korrigieren, indem Sie einen Motor vollständig ausschalten. Das bedeutet, dass diese Räder effektiv stecken bleiben und anfangen, als Drehpunkt zu fungieren. Sie möchten Korrekturen vornehmen, während sich beide Räder bewegen.

Was Sie tun müssen, ist zu versuchen, den Unterschied zwischen den Ticks der beiden Motoren während des Betriebs so gering wie möglich zu halten. Wenn Sie beispielsweise 16 Ticks pro Umdrehung haben und 100 Ticks erreichen möchten, möchten Sie den Unterschied in den Ticks so nahe wie möglich bei 0 halten, indem Sie dem langsameren Motor mehr Leistung und dem schnelleren weniger Leistung zuführen. Code als Übung für den Leser überlassen (es hängt davon ab, wie Sie die Variabilität verwalten möchten: Aktualisieren Sie die analogWrite's 10 Mal pro Sekunde? 20? 5?).

Dies funktioniert wahrscheinlich nicht so gut für eine kleine Anzahl von Ticks (1 Umdrehung), und die verschiedenen Gesetze der Akkumulation von Fehlern bedeuten, dass es wahrscheinlich auch für eine große Anzahl von Ticks nicht perfekt gerade ist; aber es sollte bessere Ergebnisse liefern als das, was Sie jetzt haben.

Haben Sie darüber nachgedacht, anstelle einer Positionsschleife eine Geschwindigkeitsschleife zu schließen? Beschleunigen Sie zunächst mit einer angemessen langsamen Geschwindigkeit, damit die Wahrscheinlichkeit geringer ist, dass die beiden Räder nicht mehr synchron sind. Wenn sich beide Räder mit der gleichen Geschwindigkeit bewegen, muss sich Ihr Roboter geradeaus bewegen und jegliche Art von Kupplungsschlupf oder Rutschen zwischen den Rädern und der Oberfläche, auf der Ihr Roboter fährt, ausschließen.

Eine einfache Möglichkeit, meinen Roboter dazu zu bringen, geradeaus zu fahren, bestand darin, drei While-Schleifen zu verwenden, während ein Rad langsamer zählt, und die Geschwindigkeit auf diesem Rad erhöht. Eine Schleife ist für links, eine für rechts und die letzte sagt dem Programm nur, dass es gleiche Geschwindigkeiten schreiben soll, wenn die Anzahl gleich ist, aber Sie können es weglassen. hoffe das hilft. und vergessen Sie nicht, eine Pause einzugeben; Befehl am Ende jeder Schleife, andernfalls bleibt er in der Schleife, auch nachdem die Bedingung erfüllt wurde

Tut mir leid, dass ich etwas spät zur Party komme, aber falls jemand anderes etwas Ähnliches tun möchte, ist ein einfacher Ansatz, der einen Versuch wert sein könnte, die kontinuierliche Berechnung der Anzahl der Ticks, die sich jedes Rad bewegt haben sollte, und dann innerhalb eines Timer-Ticks mach sowas wie:

volatile unsigned long erwartete_linke_distanz, erwartete_rechte_distanz;
volatile unsigned int left_speed, right_speed;
unsigned long left_distance, right_distance;

void timer_tick(void) // Führen Sie dies schneller als einmal pro Encoderimpuls aus
{
  int Delta;

  Addiere oder subtrahiere 65536 von left_distance, wenn sich der Encoder um +/- einen Klick bewegt hat
  Addieren oder subtrahieren Sie 65536 von right_distance, wenn sich der Encoder um +/- einen Klick bewegt hat
  erwartete_linke_entfernung += linke_geschwindigkeit;
  erwartete_rechte_Entfernung += richtige_Geschwindigkeit;
  if ((left_distance - Expected_left_distance) & 0x80000000) // Geht davon aus, dass long 32-Bit ist
    left_motor_on();
  anders
    left_motor_off();
  if ((rechter_abstand - erwarteter_rechter_abstand) & 0x80000000)
    right_motor_on();
  anders
    rechter_motor_aus();
}

Ein Geschwindigkeitswert von 1 bewegt den Roboter mit einer Rate von einem Encoder-Impuls alle 65536 Interrupts; eine Geschwindigkeit von 64 würde es 64-mal so schnell bewegen (einmal alle 1024 Interrupts) usw. Abhängig von der Konstruktion der Motoren, der Masse des Systems und den Encoder-Zählraten kann diese Bewegung ausreichend glatt sein oder sie könnte unannehmbar ruckartig und uneben sein. Es kann sich jedoch lohnen, den Ansatz auszuprobieren, um zu sehen, ob er funktioniert.

 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 (Bedingung) { Anweisung; brechen; } ist äquivalent zu if (condition) { statement; } - und letzteres ist klarer.