ROS Crashkurs 013
Wie steuert man mit rosserial einen Schrittmotor an? Das schauen wir uns heute an und lassen dabei die Idee des Getränke-Nachfüll oder auch Durstlösch-Roboters Wirklichkeit werden.
Schau dir das Video zu dem Tutorial hier oder ganz unten auf der Seite an! Abonnier meinen Kanal, um kein Tutorial mehr zu verpassen
Verkabelung
Um einen Schrittmotor mit ROS und dem Paket rosserial anzusteuern, benötigen wir hier folgende Dinge:
Einen Arduino Uno: https://amzn.to/3Dg2iDC
Eine kleine Motortreiberplatine wie diese: https://amzn.to/3iDCIi9 (eine andere wird es auch tun)
Einen Schrittmotor, wie die, die man hier bekommen kann: https://amzn.to/383ckfH
Und ein paar Kabel: https://amzn.to/3Dbebuq
Den Schrittmotor verbinden wir mit der Schrittmotortreiberplatine. Die Treiberplatine versorgen wir mit 5V von unserem Arduino. GND verbinden wir mit GND. Hier nutzen wir die Pins 3, 4, 5 und 6 zur Ansteuerung des Motors und verbinden diese dafür mit IN1 - IN4 der Treiberplatine. Das sollte dann in etwa so aussehen:
Schrittmotor ansteuern (ohne rosserial - mit Arduino)
Zuerst wollen wir den Schrittmotor mit unserem Arduino ansteuern. Und zwar ohne ROS. Wenn ihr das schonmal gemacht habt, könnt ihr dieses Kapitel überspringen. Um die Stepper-Bibliothek zu inkludieren, könnt ihr auch in der Arduino IDE auf Sketch->Bibliothek einbinden klicken und dann Stepper auswählen. Ihr seht nun den Beispielcode für die Steuerung eines Steppermotors (Schrittmotors). Der Schrittmotor braucht 2048 Schritte für eine volle Umdrehung und steckt an den Arduino Pins 3, 4, 5 und 6.
In der setup()
-Methode geben wir eine Geschwindigkeit in rpm (rotations per minute) an, die der Schrittmotor erreichen soll. Wählt ihr einen zu großen Wert, wird sich euer Motor nicht mehr bewegen. Die maximale Geschwindigkeit, die euer Schrittmotor erreichen kann, hängt von verschiedenen Faktoren, wie der Qualität des Motors, der Treiberplatine oder der Eingangsspannung ab. Verwenden wir einen Schrittmotor an unserem Roboter geht es uns jedoch meist vor allem um eine Positionsansteuerung. Um einem Motor eine gewünschte Geschwindigkeit vorzugeben, wäre ein gewöhnlicher Gleichstrommotor sicherlich besser geeignet. Wie man den mit ROS verbindet sehen wir in einem späteren Tutorial (hier kommt dann der Link hin, wenn es das Tutorial gibt. Ein wenig Geduld noch. 😉 )
In der loop()
-Methode wird festgelegt, dass sich der Motor nun um 2048 Schritte (entspricht einer Umdrehung) drehen soll. Daraufhin soll er sich eine Sekunde ausruhen und dann erneut eine Umdrehung drehen.
#include <Stepper.h>
Stepper Schrittmotor(2048, 3, 5, 4, 6); // 2048 Schritte, Pins 3-6
void setup() {
Schrittmotor.setSpeed(15);
}
void loop() {
Schrittmotor.step(2048);
delay(1000);
}
Klickt nun auf Übertragen, dann sollte sich der Motor schonmal drehen. Jetzt seid ihr bereit, euch mit dem ROS-Teil zu befassen.
Schrittmotor mit rosserial
Um ROS mit unserer bisherigen Programmierung des Schrittmotors zu verbinden, laden wir aus den Beispielen der ros_lib erneut das Beispiel Blink. Darin müssen wir nun lediglich ein paar Zeilen abändern und unseren Code aus unserem Schrittmotorprogramm ergänzen. Wenn ihr das Blink-Beispiel nicht vollständig durchschaut, schaut euch doch kurz das rosserial Einstiegstutorial an, indem wir die interne LED des Arduinos blinken lassen und
Wir benötigen einen Subscriber der auf die Topic horcht, über die wir die neuen Positionsbefehle schicken. In unserem Beispiel refillrobot_joint1_controller/command
. Passt den Namen der Topic für euch entsprechend an.
In der include
-Sektion finden ergänzen wir nun die Stepper-Bibliothek. Wir verwenden keine Nachrichten mehr vom Typ Empty
, sondern Nachrichten mit "richtigem" Inhalt, nämlich einem Float64
. Daher ändern wir alle Vorkommen von Empty
zu Float64
. Neben dem NodeHandle
legen wir auch wieder eine Schrittmotor-
Instanz Schrittmotor an. Der Subscriber führt immer dann seine Callback-Methode messageCb
aus, wenn eine neue Nachricht empfangen wurde. Das heißt hier muss unser Motor sich drehen. Wie weit? Gute Frage.
In unserer Nachricht senden wir einen Winkel in Radiant. Diesen Wert müssen wir in Schritte umwandeln, da der Motor eine Anzahl an Schritten benötigt, die er drehen soll. Um Radiant in Grad zu überführen, multiplizieren wir mit 180 und teilen durch Pi. Um dementsprechend die gegebenen Radiant in Schritte zu überführen multiplizieren wir nicht mit 180, sondern mit einer halben Umdrehung in Schritten, also 1024 Schritten. Diese Formel verwenden wir nun in der Schrittmotor.step()
-Methode.
Das Vorgeben der Geschwindigkeit aus dem setup()-
Block übernehmen wir auch in die setup()
-Methode unseres neuen Programms. In der loop()
-Methode unseres Programms lassen wir den Node lediglich am Laufen. Der Subscriber erledigt seinen Job ja selbstständig immer dann, wenn eine neue Nachricht empfangen wird.
So sollte euer Programm dann am Ende aussehen:
#include <Stepper.h> // Die brauchen wir, um den Schrittmotor anzusteuern.
#include <ros.h>
#include <std_msgs/Float64.h>
Stepper Schrittmotor(2048, 3, 5, 4, 6);
ros::NodeHandle nh;
void messageCb(const std_msgs::Float64& msg) {
Schrittmotor.step(msg.data * 1024 / M_PI); // rad * 1024 / PI -> Steps
}
ros::Subscriber<std_msgs::Float64> sub("refillrobot_joint1_controller/command", &messageCb);
void setup() {
Schrittmotor.setSpeed(15);
nh.initNode();
nh.subscribe(sub);
}
void loop() {
nh.spinOnce();
delay(1);
}
Speichert euer Programm und übertragt es auf den Arduino. Jetzt wird es spannend.
Den Schrittmotor über eine Topic ansteuern
Auf dem Operator-PC starten wir nun unser ROS-Netzwerk:
roscore
Um die Kommunikation zwischen dem Operator und dem Arduino herzustellen, starten wir in einem neuen Terminal die Verbindung mit rosserial. Achtet darauf den richtigen Port anzugeben. Den könnt ihr in der Arduino IDE einsehen.
rosrun rosserial_python serial_node.py /dev/ttyUSB0
Nun könnt ihr mit rostopic list
sehen, ob die /refillrobot_joint1_controller
/command-Topic, beziehungsweise die Topic mit dem von euch gewählten Namen verfügbar ist. Versucht doch mal etwas in die Topic zu publishen. Falls ihr den Roboter aus meinen Videos nachgebaut habt, könnt ja auch mal die Simulation parallel öffnen. Dann sollten sowohl die Hardware als auch der simulierte Roboter auf die gleiche Topic subscriben und auf eure Befehle warten.
rostopic pub /refillrobot_joint1_controller/command std_msgs/Float64 "1.5708"
Jetzt sollt sich der Schrittmotor in den von euch angegebenen Winkel bewegen. Gar nicht so schwer oder? Wollt ihr sehen, wie aus einem Schrittmotor ein Getränke-Nachfüll-Roboter werden kann, schaut euch gern das Video zu diesem Tutorial an, dass ihr ganz unten auf dieser Seite findet.
Zusammenfassung
rosserial stellt das Interface zwischen unserem Operator PC und dem Arduino her. Zuerst haben wir uns angesehen, wie man mit dem Arduino einen Schrittmotor ansteuern kann. Ausgestattet mit unserem Schrittmotorcode haben wir uns das ros_lib-Blink-Beispiel aufgebohrt und mit ein paar einfachen Veränderungen zu unserem ultimativen Schrittmotorkontrollprogramm transformiert. Jetzt können wir einen kleinen Motor in unserem ROS-Netzwerk ansteuern und haben den ersten Schritt beim Bau unseres ersten Roboters geschafft.
Hier findet ihr das ganze Tutorial nochmal als Video, allerdings bauen wir dabei sogar aus dem kleinen Motor direkt einen Roboter. Den Durstlösch-Roboter!
Für Fragen und Diskussionen über das Robot Operating System hier ein Link zu einem Discord-Server, auf dem wir gemeinsam über eure Ideen und Herausforderungen sprechen können: https://discord.gg/Qs4MZT2n63
Unterstützt mich und gönnt mir einen Kaffee, sodass ich auch schneller eine neue Folge aufnehme 😉 : https://paypal.me/maxivu
Über ROS: https://www.ros.org/about-ros/
rosserial: http://wiki.ros.org/rosserial