BalBot: Ein selbstbalancierender Roboter
Im Alltag wird im Gegensatz zu Technik und Wissenschaft häufig nicht zwischen Regelungen und Steuerungen unterschieden. Eine bloße Steuerung überwacht die Ausgangsgröße nicht, weshalb sie sich durch externe Störgrößen verändern kann. Ein einfaches und typisches Beispiel ist die Drehzahlsteuerung eines DC-Motors per PWM. Die Drehzahl des Motors wird hier auch von Lastschwankungen beeinflusst.
Nun zur Regelung: Soll eine Drehzahl konstant gehalten werden, ist eine Rückkopplung erforderlich, um etwa eine steuernde PWM bzw. Gleichspannung abhängig von der Drehzahlabweichung anzupassen. Ein so rückgekoppeltes System kennzeichnet einen Regelkreis.
Regeln bedeutet also, dass die Ausgangsgröße (z.B. Drehzahl) erfasst wird und bei einer Abweichung vom angepeilten Wert die Stellgröße (hier die PWM) passend verändert wird. Die zentralen Begriffe sind:
- Istwert: x
- Sollwert: w
- Regelabweichung: e = w – x
- Stellgröße: y
- Störgröße: z
Diese Größen reichen zur Beschreibung eines Reglers aus.
Weiter gibt es Reglertypen mit unterschiedlichen Regelungscharakteristiken. Sehr gebräuchlich und viele Fälle abdeckend ist der sogenannte PID-Regler. Er verfügt sowohl über einen proportionalen (P) als auch einen integralen (I) und einen differentiellen (D) Pfad. Durch Anpassung seiner Parameter können viele regelungstechnische Probleme mit hoher Präzision gelöst werden.
Balance auf einer Achse
Ein interessantes Beispiel für die Anwendung solcher Regelungen ist ein selbstbalancierender Roboter. Prinzipiell handelt es sich hierbei um ein inverses Pendel auf Rädern. Das inverse Pendel ist aufgrund seiner Instabilität ein klassisches Beispiel für die Anwendung eines aktiven Regelkreises.
Der bekannte Segway-Roller ist ein einachsiges, zweirädriges, elektrisches Transportmittel. Die zu befördernde Person steht zwischen den Rädern quasi auf der Achse. Einachsige Fahrzeuge sind prinzipiell instabil. Also sorgt eine Regelung für die nötige Balance. Damit zu fahren macht Spaß. Die Popularität solcher Roller triggerte dann die Entwicklung selbstbalancierender Roboter.
Einen Roller nach dem „Segway-Prinzip“ nachzubauen ist nicht wirklich schwierig. Es gibt sogar komplette Bausätze. Zur Beschäftigung mit der zugrunde liegenden Regelungstechnik muss es aber nicht zwingend ein solcher Roller sein: Hierfür genügt der Bau eines kleineren, selbstbalancierenden Roboters, wie er nachfolgend beschrieben wird.
Damit ein selbstbalancierender Roboter das Gleichgewicht halten kann, müssen seine Räder permanent der Kippneigung entgegenwirken. Dies erfordert einen geeigneten Regelkreis, einen Sensor und Stellglieder. Als Sensorelement eignet sich das IC MPU-6050 bestens, denn es enthält einen Beschleunigungssensor und ein Gyroskop. Damit kann man sehr präzise die Beschleunigung und die Drehung in den drei Raumachsen erfassen. Da solche Chips in vielen Geräten wie Kameras oder Smartphones eingesetzt werden, sind sie durch Massenproduktion sehr preisgünstig. Zur Verrechnung der Daten reicht schon ein Arduino Uno. Die mit den Rädern gekoppelten Motoren sind die Stellglieder.
Verbindet man den MPU6050 mit einem Arduino (siehe links unten in Bild 1), kann man die korrekte Funktion mit einem Testprogramm überprüfen. Im Download (siehe unten) ist hierfür „MPU6050_test“ enthalten. Nach dem Laden des Testprogramms kann der serielle Monitor der Arduino-IDE gestartet werden. Sechs Linien zeigen die Reaktion der Sensorwerte auf Drehung bzw. Bewegung. Werden korrekte Bewegungsdaten angezeigt, kann man den Motortreiber mit dem Arduino verbinden. Als Treiber für kleine DC-Motoren eignet sich der Typ L298N (das IC oder ein damit bestücktes Modul). Als Energiequelle dienen entweder sieben 1,2-V-NiMH- (= 8,4 V) oder zwei 3,7-V-LiPo-Akkus (= 7,4 V). Bild 1 zeigt, wie die einzelnen Komponenten und Module (siehe Stückliste) miteinander verbunden werden.
Balance-Algorithmen
Wie schon erwähnt, ist ein geeigneter Regelkreis erforderlich. Die Lage des Roboters entspricht der Istgröße. Sie soll möglichst wenig von der Senkrechten (Sollgröße) abweichen. Ein PID-Regler ist hierfür ideal. Unser Roboter namens BalBot erreicht mit optimal justierten Kp-, Ki- und Kd-Parametern ein erstaunlich stabiles dynamisches Gleichgewicht. Der Sollwert bzw. die Senkrechte wird zunächst fest in der Software eingestellt. Bild 2 veranschaulicht, wie das in der Praxis funktioniert.
Das MPU6050-Modul erfasst permanent die aktuelle Lage des Roboters. Seine Werte werden vom PID-Algorithmus im Arduino verarbeitet. Der Regelungs-Sketch führt die Berechnungen zur Steuerung der Motoren aus. Droht der Robot in eine Richtung umzukippen, wird das entstandene Kippmoment durch eine entsprechende Ausgleichsbewegung der Räder kompensiert. Der Roboter bleibt selbst dann senkrecht, wenn er leicht geschubst wird. Der zugehörige Sketch BalBot.ino ist ebenfalls im kostenlos erhältlichen Download-Archiv enthalten.
Sein Code gliedert sich in sechs Teile:
1. Zunächst werden die Bibliotheken geladen. Soweit nicht standardmäßig in der Arduino-IDE enthalten, können sie via Internet [2][3] bezogen werden. Dann werden die Motoranschlüsse festgelegt. Über EN (enable) und IN (input) können die Motoren sowohl vorwärts als auch rückwärts betrieben werden. Die Motorleistung wird per PWM gesteuert.
2. Anschließend werden die für den Betrieb des MPU6050 erforderlichen Werte festgelegt. Hierbei handelt es sich im Wesentlichen um die Standardeinstellungen. Details dazu finden sich im Datenblatt des ICs.
3. Nun folgt die Festlegung der PID-Parameter. Sie sind von zentraler Bedeutung. Die folgenden drei Werte definieren das Regelverhalten: Kp (Bereich 0...1000; Standardwert 400), Kd (Bereich 0...100; Standardwert 30) und Ki ( Bereich 0...500; Standardwert 200).
4. Diese Werte müssen an die realen Gegebenheiten der jeweiligen Hardware angepasst werden. Unterschiede beim mechanischen Aufbau (durch verschiedene Motoren, Radgrößen etc.) können hier ausgeglichen werden. Hinweise zur Justierung dieser Parameter finden sich im nächsten Abschnitt.
5. Im Setup werden jetzt die erforderlichen Schnittstellen aktiviert. Das serielle Interface dient lediglich zur Ausgabe von Debug-Infos. Dieser Code kann im „final release“ entfallen. Anschließend wird das MPU6050-Modul gestartet und auf Funktion geprüft - gegebenenfalls wird eine Fehlermeldung ausgegeben. Die angegebenen Offset-Werte können meist unverändert übernommen werden, da sich das Gyroskop automatisch kalibriert.
6. In der Hauptschleife wird lediglich das MPU-Signal ausgelesen sowie über den PID-Regler pid.Compute() das Steuersignal für die Motoren berechnet und an den Motortreiber mit folgendem Aufruf weitergeleitet:
motorController.move(PIDout, MIN_ABS_SPEED);
Darüber hinaus wird überprüft, ob der FIFO-Puffer des MPU6050 überläuft. Dies sollte im Normalbetrieb nicht passieren. Gegebenenfalls kann die Puffergröße angepasst werden.
Die Zeile:
Serial.println(ypr[1] * 180/M_PI); // actual tilt
gibt den Kippwinkel aus. Im seriellen Plotter der Arduino-IDE kann er kontinuierlich verfolgt werden. Falls regelmäßige, sinusförmige Werteverläufe auftauchen, ist dies ein klarer Hinweis für das Schwingen der Regelung. In diesem Fall müssen die Regelparameter angepasst werden. Meist ist es hilfreich, wenn der Kp-Wert reduziert wird. Im Idealfall sollte die Linie nur geringe, unregelmäßige Signalausschläge zeigen, wie sie durch zufällige Störeinflüsse (Luftbewegungen oder Bodenunebenheiten) entstehen. Bild 3 zeigt die zufälligen Ausgleichsbewegungen um die Ruhelage.
Parameteroptimierung und Justage
Die Optimierung der PID-Werte könnte auch über eine Simulation z.B. mit MATLAB erfolgen. Im professionellen Bereich ist dieses Vorgehen bei aufwändigen Reglern Standard.
Beim BalBot kommt man jedoch auch mit dem Klassiker „trial and error“ zum Ziel. Dabei werden die einzelnen Parameter nach und nach angepasst, bis eine möglichst optimale Regelung erreicht ist:
1. Zunächst werden die drei Parameter Kp, Ki und Kd auf null gesetzt.
2. Dann wird Kp langsam schrittweise erhöht. Bei zu geringem Kp wird der Roboter umkippen, da die Korrekturen nicht schnell oder groß genug sind. Ist Kp zu groß, führt der Roboter wilde Vor- und Zurückbewegungen aus, ohne dass sich ein Gleichgewichtszustand einstellt. Kp muss so eingestellt werden, dass sich der Roboter nur noch leicht hin und her bewegt.
3. Jetzt ist aufrechtes Stehen mit Ausgleichsbewegungen erreicht. Häufig tritt noch eine gewisse Schwingneigung auf: Der Roboter pendelt oder zittert rasch um die ideale Gleichgewichtslage.
4. Nun wird der Kd-Wert so eingestellt, dass sich die Schwingungen verringern. Im Idealfall verharrt der Roboter jetzt nahezu bewegungslos in aufrechter Position. Bei guter Einstellung von Kp und Kd bleibt er auch dann aufrecht, wenn er leicht angestoßen wird.
5. Abschließend wird der Ki-Parameter festgelegt. Auch bei optimalen Kp zeigt sich bei größeren Störungen noch eine gewisse Schwingneigung. Er kann dabei sogar sein Gleichgewicht verlieren. Ki ist dann ideal eingestellt, wenn die Lagestabilisierung nach einer Störung schnell erfolgt.
Sind alle drei Parameter optimal eingestellt, rastet der Roboter nahezu in senkrechter Position ein, sobald der Fangbereich des Reglers erreicht wird. Wie von Geisterhand gehalten steht er dann aufrecht da und gleicht selbst größere Störeinflüsse souverän aus.
Falls kein Gleichgewicht erreicht werden kann, sind eventuell die Motoranschlüsse vertauscht. Der Roboter beschleunigt dann nicht in die Richtung des Kippmoments, sondern in die entgegengesetzte Richtung. Bild 4 zeigt den fertigen Roboter in aufrechter, selbstbalancierender Position.
Da die Einstellung der Parameter per Software recht umständlich ist, gibt es auch eine einfachere Variante. Ein Arduino verfügt ja über mehrere analoge Eingänge. An diese können drei Potis angeschlossen werden, mit denen man die Werte für P, I und D direkt einstellen kann. Dazu muss die Software lediglich die Abfrage für die Poti-Werte enthalten (siehe Listing Potis).
{ int potKp = analogRead(A0);
int potKi = analogRead(A1);
int potKd = analogRead(A2);
kp = map(potKp, 0, 1023, MIN_P, MAX_P) / 100.0;
ki = map(potKi, 0, 1023, MIN_I, MAX_I) / 100.0;
kd = map(potKd, 0, 1023, MIN_D, MAX_D) / 100.0;
}
So können die Parameter im laufenden Betrieb über die Potis optimiert werden (siehe BalBot_Pots_BT.ino im Download). Der Anschluss der optionalen Potis ist in Bild 1 schon berücksichtigt.
Fernsteuerung per Smartphone
Der Bau eines selbstbalancierenden Roboters ist eine interessante Herausforderung. Funktioniert alles, ist dieses zunächst erfreuliche Ergebnis auf Dauer nicht mehr spannend. Eine Fernsteuerung könnte das ändern. Damit ließe sich BalBot drahtlos in alle Richtungen bewegen. Da jeder (Elektroniker) ein Smartphone mit Bluetooth-Interface hat und viele davon unter Android laufen, dient ein solches einfachheitshalber zur Steuerkonsole des Roboters.
Hierzu muss lediglich ein Bluetooth-Modul an den Arduino angeschlossen werden. Gut geeignet ist ein HC05/06-Receiver, der auch schon in Bild 1 enthalten ist.
Zu seiner Verwendung muss dann noch die Standard-Bluetooth-Library der Arduino-IDE eingebunden und der Sketch entsprechend ergänzt werden (Listing Bluetooth).
{ int potKp = analogRead(A0);
int potKi = analogRead(A1);
int potKd = analogRead(A2);
kp = map(potKp, 0, 1023, MIN_P, MAX_P) / 100.0;
ki = map(potKi, 0, 1023, MIN_I, MAX_I) / 100.0;
kd = map(potKd, 0, 1023, MIN_D, MAX_D) / 100.0;
}
content=blue.readString();
#if LOG_BT
Serial.print("content: ");Serial.print(content);
Serial.print(" - setpoint: "); Serial.print(setpoint);
Serial.print(" - rotation: "); Serial.println(rotate);
#endif
if(content[0]=='F')
{setpoint += d_speed; setpoint = constrain(setpoint, originalSetpoint-3, originalSetpoint+3);} // forward
else if(content[0]=='B')
{setpoint -= d_speed; setpoint = constrain(setpoint, originalSetpoint-3, originalSetpoint+3);} // backward
else if(content[0]=='L')
{rotate -= d_rot; rotate = constrain(rotate, -30, 30);} //left
else if(content[0]=='R')
{rotate += d_rot; rotate = constrain(rotate, -30, 30);} // right
Auch diese Erweiterung ist bereits im Sketch BalBot_Pots_BT.ino enthalten. Auf dem Smartphone wird dann lediglich die App „Arduino Bluetooth“ von Circuit Magic benötigt. Die App kann kostenlos aus dem Playstore geladen werden. Nach Installation und Verbindung mit dem HC05/06-Modul sendet die App die notwendigen Steuerbefehle an den Arduino. Bild 5 zeigt die Bedienungsoberfläche der App. Die Steuerung erfolgt über die Pfeiltasten auf der linken Bildschirmhälfte.
Fazit & Ausblick
Der hier vorgestellte Roboter lässt sich recht einfach aufbauen. Neben den Antriebsmotoren sind lediglich ein Arduino, ein Motortreiber und ein Beschleunigungs/Gyroskop-Modul erforderlich. Durch zusätzliche Potis wird die Justierung der Regelparameter deutlich vereinfacht. BalBot kann sogar per Bluetooth ferngesteuert durch die eigenen vier Wände bewegt werden.Eine weitere Verbesserung von Balance und Fahrverhalten besonders bei ferngesteuertem Betrieb ließe sich durch sogenannte Rotary-Encoder erreichen. Damit kann die Umdrehungsgeschwindigkeit der Räder erfasst werden. Mit dieser Information lässt sich die Stabilität beim Vor- und Zurückfahren nochmals deutlich verbessern. In der Praxis verliert der ferngesteuerte BalBot gelegentlich das Gleichgewicht, wenn nur die Werte des MPU6050 zur Verfügung stehen. Dieser Sensor kann nämlich leider nur Beschleunigung und Rotation, nicht aber die Geschwindigkeit direkt erfassen.
Eine andere Alternative besteht in der Verwendung von Schrittmotoren. Durch das Zählen der Schritte erhält man eine ähnliche Information wie durch Encoder. Neben dem Tausch der Motoren muss dann natürlich auch der L298 durch geeignete Stepper-Treiber (wie etwa den DRV8825-Treiber) ersetzt werden.
Im Buch „Robotik und Künstliche Intelligenz” des Autors findet man viele weitere Infos und Robotik-Projekte (siehe Kasten „Im Elektor-Store”).