Wahrscheinlich kennen Sie Industrieroboter, die vorgefertigte Bewegungen durchführen und an einem Punkt fixiert sind. Was passiert, wenn wir einen Roboter konstruieren möchten, der sich von seinem Ort wegbewegen soll? Es kommen weitere Probleme hinzu, die gelöst werden müssen.
In diesem Projekt werden wir einen vierbeinigen, beweglichen Roboter bauen und damit zeigen, dass der Fantasie keine Grenzen gesetzt sind. Alles ist eine Frage der Beharrlichkeit und der Suche nach einem Weg, Ideen in die Realität umzusetzen.
Wir wollen die Basis der Konstruktion und der Programmierung der Bewegungen zeigen. Dann ist es eine Frage der Vorstellungskraft, wie wir die Bewegungen erweitern und welche zusätzlichen Module wir installieren können, um diesen Roboter zu verbessern.
Dieser Artikel ist in zwei Teile aufgeteilt. In Teil 1 werden wir den Roboter zusammenbauen und die ersten Bewegungen ausführen. In Teil 2 werden wir Befehle über eine Infrarot-Fernbedienung senden, eine Hinderniserkennung hinzufügen und eine Stromversorgung mit Batterien, um den Roboter frei bewegen zu lassen.
Benötigte Hardwarekomponenten
12 |
|
|
1 |
|
|
1 |
||
1 |
||
1 |
||
1 |
||
1 |
IR Fernbedienung |
|
diverse |
Benötigte Materialien
Benötigte Software und Sketches
- Arduino IDE
- I2C Library (Wire.h, integriert)
- PCA9685 Library (Adafruit_PWMServoDriver.h)
- IR remote control Library (IRremote.h)
- Ultrasonics sensor Library (SR04.h)
- quadruped_robot_home.ino
- quadruped_robot_pushups.ino
- quadruped_robot_shoulder.ino
- quadruped_robot_walk.ino
Schaltplan
Konstruktion und Montage
Für das Skelett unseres Roboters werden wir 3 mm dickes Balsaholz verwenden. Es hat ein geringes Gewicht und es ist damit einfacher, Änderungen an den Teilen vorzunehmen. Folgend finden Sie die Pläne der Teile mit ihren Maßen.
Bevor wir mit dem Zusammenbau des Roboters beginnen, müssen wir alle Servomotoren auf 90 Grad einstellen, da dies der Mittelpunkt ihrer Bewegung ist. Alle Teile werden in dieser Mitte zusammengebaut. Auf diese Weise haben wir eine erste visuelle Referenz des Zustands der Beine und es wird einfacher sein, die Einstellungen der Servomotoren vorzunehmen, um die Werte der Startposition des Roboters festzulegen, die wir im Sketch home.ino programmieren werden.
Wir fangen mit dem Schulterblatt an. Diese Teile sind ein Würfel mit 31 mm Kantenlänge. Eine der Seiten des Würfels ist unbedeckt, das ist die Seite, die zum Inneren des Körpers hin positioniert wird. Die obere und die untere Seite haben eine Wandstärke von 3 mm, während die beiden Seiten mit den Teilen, die mit der Servomotorwelle verschraubt werden, 6 mm dick sind. Die Fläche, die die Drehachse des Roboterkörpers enthält, ist ebenfalls 6 mm dick. Bevor wir die Teile des Servomotors anbringen, werden wir die Schulterblätter auf dem Körper anschauen. Wir wollen sicherstellen, dass wir sie richtig montieren, da die äußere Fläche jedes Schulterblattes das Teil enthalten muss, das an jedes obere Teil des Beins geschraubt wird.
Das Stück des Unterteils des Beins hat eine Dicke von 6 mm, im oberen Teil werden wir das Teil installieren, das an die Welle des Servomotors geschraubt wird. Im unteren Teil des Beins werden wir einige Gummistücke einkleben, damit es Halt auf dem Boden hat. Hier ist es auch notwendig, auf die Installation des Verbindungsstücks zum Servomotor zu achten, da es im unteren Beinteil auf der rechten Seite in einer Seite und in denen auf der linken Seite in der gegenüberliegenden Seite installiert wird.
Der obere Teil des Beins hat auch eine Dicke von 6 mm. Wir müssen eine Aussparung schneiden, um den Servomotor einfügen zu können. Wir müssen genau aufpassen, denn das Oberteil auf der rechten Seite hat die Aussparung auf einer Seite und die beiden auf der linken Seite auf der gegenüberliegenden Seite. Der obere Servomotor betätigt das Oberteil, während der untere Servomotor das untere Teil jedes Beins betätigt.
Der Körper des Roboters ist etwas komplizierter, da wir vier Servomotoren installieren müssen, auf deren Achse die Nabe des Schulterblattes geschraubt wird. Auf der gegenüberliegenden Seite des Servomotors, der das Schulterblatt bewegt, müssen wir eine Welle von der Nabe zum Loch in der Körperhalterung einführen, die mit der Servomotorwelle übereinstimmen muss, damit sich das Schulterblatt reibungslos bewegt. Die Welle muss eine geeignete Dicke haben, damit sie sich durch die Bewegung nicht verformt und das Gewicht des Roboters tragen kann. In unserem Prototyp hat diese Welle eine Dicke von 6 mm.
Nachdem alle Teile gebaut sind, beginnen wir mit dem Zusammenbau des Roboters. Als erstes werden wir zwei Servomotoren in jedes Oberteil und die vier Servomotoren in den Körper des Roboters einbauen. Sobald wir alle Servomotoren eingebaut haben, müssen wir jedes Bein in das entsprechende Schultergelenk einbauen. Wir haben zuvor eine Voreinstellung aller Servomotoren auf 90 Grad vorgenommen. Mit diesen Positionen müssen wir die Nabe auf den Körper montieren, indem wir sie auf die Welle des Servomotors setzen, so dass sie vollständig mit dem Körper übereinstimmt. Wir schrauben die Nabe auf die Welle des Servomotors und dann setzen wir die Welle ein, indem wir sie durch die Körperstütze und bis zur Nabe führen. Dieses Verfahren wird für die vier Schulterblätter unseres Roboters durchgeführt.
Nachdem wir die mechanischen Teile des Roboters zusammengebaut haben, installieren wir die Abdeckung des Körpers und darauf die PCA9685-Karte samt AZ-ATmega328-Mikrocontroller mit dem Shield. Mit dem Prototype Shield sind Sie auch in der Lage, Ihr Projekt nach Ihren Bedürfnissen zu erweitern. Sie sehen hier schon das installierte IR-Empfänger Modul, das wir in Teil 2 verwenden werden.
Wir stellen alle Verbindungen des Moduls und der Servomotoren her, wie sie oben im elektronischen Schaltplan dargestellt sind. Dann beginnen wir mit der Programmierung.
Funktionsweise und Programmierung des Sketches
Als Aktuatoren für die Bewegungen verwenden wir 12 MG90S-Servomotoren, deren Getriebe aus Metall bestehen und sie dadurch einen besseren mechanischen Widerstand haben. Zur Steuerung der Motoren verwenden wir das Modul "PCA9685 16 Channel 12 bit PWM Servo Driver", das zwei wichtige Funktionen hat: erstens die Versorgung der Servomotoren mit 5 Vdc von einer externen Stromversorgung und zweitens die Ansteuerung jedes Servomotors über den entsprechenden PWM-Pin mit den vom Mikrocontroller über den I2C-Port übermittelten Daten. Es werden nur zwei Pins für die Kommunikation zwischen dem Mikrocontroller und dem PCA9685-Modul verwendet, dadurch bleibt Platz für spätere Erweiterungen.
Im Sketch legen wir die Position fest, die jeder Servomotor einnehmen muss. Die kombinierten Drehungen der Motoren führen zur Bewegungssequenz des Roboters. Der Mikrocontroller sendet die jeweiligen Positionen der Servos an das Motortreiber Modul über die I2C-Schnittstelle.
Ein mühsamer Teil dieses Projekts ist die Einstellung der Werte für jede Position der Servomotoren jedes Beins für die koordinierte Bewegungssequenz und damit den Roboter zum Laufen zu bringen. In diesem Teil 1 des Projekts zeige ich drei Sketches mit einigen Grundbewegungen und einen weiteren Sketch mit der Ausgangsposition des Roboters.
Um die Roboterkomponenten in diesem Teil 1 des Projekts mit Spannung zu versorgen, verwenden wir eine feste 5-VDC-Quelle. Da der Mikrocontroller über die USB-Schnittstelle mit der Arduino IDE verbunden bleibt, erhält er darüber seine Spannung.
In Teil 2 des Artikels werden wir den HC-SR04-Ultraschallsensor hinzufügen, der die Entfernung zu jedem Hindernis vor dem Roboter misst. Außerdem werden wir das IR-Empfängermodul und eine IR-Sender-Fernbedienung verwenden, um Befehle zu erteilen und schließlich werden wir Batterien für die Stromversorgung installieren, damit sich der Roboter frei bewegen kann.
Beschreibung des Sketches quadruped_robot_home.ino
Dies ist die Anfangsposition des Roboters. Wie Sie sehen können, ist der Code dieses ersten Sketches sehr einfach und führt nur die anfängliche Positionierungsbewegung der Servomotoren aus. Die ersten beiden Zeilen des Codes sind die Bibliotheken, die wir benötigen, um den Sketch korrekt auszuführen. Wire.h ist die Bibliothek für die I2C-Kommunikation und Adafruit_PWMServoDriver.h ist für die Verwendung des PCA9685-Moduls notwendig.
#include <Wire.h> #include <Adafruit_PWMServoDriver.h>
Die nächsten drei Zeilen sind der Reihe nach die Implementierung eines Adafruit_PWMServoDriver-Objekts zur Steuerung der Servomotorpositionen und die Variablen SERVOMIN und SERVOMAX, die die Werte der steigenden und fallenden Flanke für die 0-Grad- bzw. 180-Grad-Positionen der Servomotoren darstellen.
Adafruit_PWMServoDriver servoDriver_module = Adafruit_PWMServoDriver(); #define SERVOMIN 100 #define SERVOMAX 500
In der setup()-Methode initialisieren wir zuerst den seriellen Monitor und in der nächsten Zeile das PCA9685-Modul durch sein zuvor implementiertes Objekt. Mit der Funktion begin() geben wir die Arbeitsfrequenz der Servomotoren mit dem Aufruf setPWMFreq(50) an, die 50Hz beträgt. In der letzten Zeile rufen wir die home()-Funktion auf.
void setup() { Serial.begin(9600); servoDriver_module.begin(); servoDriver_module.setPWMFreq(50); home(); }
Analysieren wir die erste Zeile der Funktion home(). Der erste Servomotor, der seine Position ändern wird, ist der mit der Nummer 0, der zum Unterteil des linken Vorderbeins gehört. Mit dem Aufruf setPWM(0, 0, 420) des Objekts servoDriver_module geben wir dem Modul PCA9685 an, dass es den an seinem Port 0 angeschlossenen Servomotor bewegt und ihn in die Position bringen soll, die sich aus der Subtraktion des Wertes der steigenden Flanke (0) von der fallenden Flanke (420) ergibt.
void home() { servoDriver_module.setPWM(0, 0, 420); servoDriver_module.setPWM(1, 0, 360); servoDriver_module.setPWM(2, 0, 350); servoDriver_module.setPWM(4, 0, 400); servoDriver_module.setPWM(5, 0, 440); servoDriver_module.setPWM(6, 0, 280); servoDriver_module.setPWM(8, 0, 240); servoDriver_module.setPWM(9, 0, 220); servoDriver_module.setPWM(10, 0, 340); servoDriver_module.setPWM(12, 0, 190); servoDriver_module.setPWM(13, 0, 260); servoDriver_module.setPWM(14, 0, 260); delay(10000); }
Die darauffolgenden Zeilen bewegen die anderen Motoren nach dem gleichen Prinzip. Im Quellcode ist beschrieben, welcher Motor für welches „Körperteil“ zuständig.
In diesem Sketch bleibt die loop()-Funktion leer, da nur die Startpositionen beim Aufruf der setup()-Funktion und damit beim Start des Mikrocontrollers, eingestellt werden.
Download quadruped_robot_home.ino
Beschreibung des Sketches quadruped_robot_pushups.ino
Mit diesem Sketch wird der Roboter einige kleine Bewegungen durchführen ausgelöst durch die Motoren an den unteren und oberen Beinteilen. In der loop() wird nun pushups() aufgerufen. Dadurch bewegt sich der Roboter immer wieder hoch und runter.
Die 12 Servomotoren ändern ihre Position und kehren dann in die Ausgangsposition von home() zurück. Die Codezeilen ähneln denen, die wir bereits gesehen haben. Die Funktion servoDriver_module.setPWM() hat als Parameter die Nummer des zu bewegenden Servomotors und die neue Position.
Download quadruped_robot_pushups.ino
Wie die Bewegungen der Beinteile in Abhängigkeit von der Veränderung der Position der Servomotoren funktioniert, zeigt die folgende Grafik.
Beschreibung des Sketches quadruped_robot_shoulder.ino
Mit diesem Sketch werden Bewegungen in den Servomotoren der Schulterblätter des Roboters ausgeführt. Die Codezeilen sind wieder sehr ähnlich. Von der loop() aus rufen wir dieses Mal kontinuierlich die shoulder()-Funktion auf. Sie führt eine Bewegung von den home()-Positionen der Schulter-Servomotoren zu den neuen Positionen aus. Auch hier sind diese Positionen mit dem Aufruf servoDriver_module.setPWM() vorgegeben.
Download quadruped_robot_shoulder.ino
Beschreibung des Sketches quadruped_robot_walk.ino
Der letzte Sketch in diesem ersten Teil ermöglicht es dem Roboter zu laufen. Dafür muss eine Sequenz programmiert werden, die einerseits die passenden Bewegungen der Beine durchführt und andererseits für das Halten des Gleichgewichts des Roboters sorgt.
Der erste Unterschied zu den anderen Sketches ist die Variablendeklaration namens int movement_speed mit einem Wert von 50. Dieser wird verwendet, um zwischen den Bewegungen der Servomotoren eine Pause von 50 Mikrosekunden einzulegen.
int movement_speed = 50;
Von der loop() aus rufen wir kontinuierlich die walk()-Funktion auf, die die Bewegungsbefehle an die Servomotoren über das PCA9685-Modul sendet. Mit servoDriver_module.setPWM() werden auch hier wieder die benötigten Parameter übergeben. Anhand des oben eingefügten Diagramms können Sie die Werte den Bewegungen besser zuordnen.
Wir beginnen in der Ausgangsposition home(), die in setup() aufgerufen wird. Dann machen wir mit dem linken Vorderbein einen Schritt nach vorne. Dazu müssen wir das untere Beinteil mit dem Servomotor 0 anheben, das obere Teil mit dem Servomotor 1 nach vorne bewegen und das untere Teil mit dem Servomotor 0 absenken, um das Bein auf dem Boden abzusetzen.
servoDriver_module.setPWM(0, 0, 450); delay(movement_speed); servoDriver_module.setPWM(1, 0, 330); delay(movement_speed); servoDriver_module.setPWM(0, 0, 420); delay(movement_speed);
Das nächste Bein, das einen Schritt nach vorne machen muss, ist das rechte Hinterbein, damit der Roboter das Gleichgewicht halten kann. Dazu führen wir die gleichen Bewegungen wie beim vorherigen Bein aus. Servomotor 8 wird angehoben, Servomotor 9 nach vorne bewegt und Servomotor 8 abgesenkt.
servoDriver_module.setPWM(8, 0, 210); delay(movement_speed); servoDriver_module.setPWM(9, 0, 250); delay(movement_speed); servoDriver_module.setPWM(8, 0, 240); delay(movement_speed);
Die nächste Aktion besteht darin, den Körper des Roboters vorwärts zu bewegen. Hier werden nur die Servos in den Schultern bewegt. Sie werden nach hinten bewegt, was dazu führt, dass sich der Körper des Roboters vorwärtsbewegt, während die Beine auf dem Boden ruhen.
servoDriver_module.setPWM(13, 0, 230); servoDriver_module.setPWM(1, 0, 360); servoDriver_module.setPWM(5, 0, 470); servoDriver_module.setPWM(9, 0, 220); delay(movement_speed);
Jetzt müssen wir die beiden anderen Beine, das linke Hinterbein und das rechte Vorderbein, vorwärtsbewegen. Wir beginnen mit dem rechten Vorderbein. Die Bewegungen sind die gleichen wie die beiden vorherigen. Wir heben mit Servomotor 12, wir schieben mit Servomotor 13 vor und wir senken mit Servomotor 12.
servoDriver_module.setPWM(12, 0, 140); delay(movement_speed); servoDriver_module.setPWM(13, 0, 260); delay(movement_speed); servoDriver_module.setPWM(12, 0, 190); delay(movement_speed);
Nun noch das linke Hinterbein. Anheben mit Servomotor 4, Vorschieben mit Servomotor 5 und Absenken mit Servomotor 4. Zwischen allen Bewegungen befindet sich eine Pause von 50 ms.
servoDriver_module.setPWM(4, 0, 450); delay(movement_speed); servoDriver_module.setPWM(5, 0, 440); delay(movement_speed); servoDriver_module.setPWM(4, 0, 400); delay(movement_speed);
Am Ende dieser Bewegungssequenz kehren die Motoren zu ihrer home()-Position zurück. Durch den wiederkehrenden Aufruf von walk() in der loop(), bewegt sich der Roboter dauerhaft vorwärts.
Das alles dient als Basis, um den Roboter wie gewünscht bewegen zu können.
Wenn Sie an dieser Stelle kein Video sehen, oder es nicht abspielen können, ändern Sie bitte die Cookieeinstellungen Ihres Browsers.
2 Kommentare
TheMediumIsPizza
Tolles Projekt! Muss ich unbedingt mal nachbauen … Euch fehlt aber definitiv jemand mit einem 3D-Drucker ;)
Michael
Hallo Miguel, ein schönes Projekt! ;-)