Praktische Anwendung von ROS auf dem Raspberry Pi - Teil 3

Guten Tag, liebe Leser von Habr!

Ich setze eine Reihe von Artikeln über die praktische Anwendung von ROS auf dem Raspberry Pi fort ( erster Artikel , zweiter Artikel ).
In diesem Artikel verwenden wir das Paket teleop_twist_keyboard aus dem ros-teleop-Stapel , um den Roboter durch Drücken der Tasten auf der Tastatur zu steuern. Der ros-teleop-Stack enthält neben diesem Paket mehrere weitere Pakete für verschiedene Steuerungsmethoden, beispielsweise mit dem Joystick. Wer bereit ist, teleop_twist_keyboard zu studieren, bitte unter cat.

Multiterminal mit tmux


In der Zwischenzeit möchte ich Ihnen einen Trick erläutern, mit dem Sie in mehreren Terminals gleichzeitig über SSH remote am Raspberry Pi arbeiten können. Installieren Sie dazu das Dienstprogramm tmux auf RPi.

$ sudo apt-get install tmux

Führen Sie danach das Dienstprogramm aus:

$ tmux

Am unteren Rand des Terminalfensters sollte eine grüne Leiste mit einer Fensternummer von 0
angezeigt werden . TMux ist ein sehr praktischer Terminalfenstermanager, mit dem Sie eine beliebige Anzahl von Fenstern in einem Terminalfenster erstellen können, indem Sie sie auf verschiedene Arten platzieren (separates Terminalfenster (Fenster), Fensterfenster ( Fenster)) und es ist bequem, zwischen ihnen zu wechseln.

Drücken Sie Strg + B und C auf der Tastatur. Ein weiteres Fenster mit der Nummer 1 sollte angezeigt werden. Versuchen Sie auch die Kombination von Strg + B und%. Das aktuelle Terminalfenster wird in der Mitte durch einen vertikalen grünen Streifen in zwei Fenster (Bereich) unterteilt. Wenn Sie die Kombination Strg + B: drücken und "Fenster teilen" eingeben, wird das Fenster horizontal in zwei identische Fenster unterteilt. Um ein Bedienfeld (Fenster) zu entfernen, verwenden Sie die Kombination Strg + B, X und drücken Sie dann Y. Um zu einem anderen Bedienfeld im selben Fenster zu wechseln, verwenden Sie die Kombination Strg + B, O. Um zwischen Terminalfenstern anhand der Fensternummer zu wechseln, verwenden Sie die Kombination Strg + B, <Fensternummer>.

Fügen Sie nun den Start des Programms zur Datei ~ / .bashrc hinzu, um automatisch zu starten, wenn Sie ein neues Terminal öffnen. Fügen Sie der Datei die folgenden Zeilen hinzu:

[[ $TERM != "screen" ]] && exec tmux


Arbeiten mit teleop_twist_keyboard


Machen wir uns nun mit dem Paket teleop_twist_keyboard vertraut.
Führen Sie das Skript teleop_twist_keyboard.py aus dem Paket teleop_twist_keyboard als regulären ROS-Knoten aus:

$ roscore
$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py

Wir bekommen eine Schlussfolgerung wie folgt:

Reading from the keyboard  and Publishing to Twist!
---------------------------
Moving around:
   u    i    o
   j    k    l
   m    ,    .

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%
anything else : stop

CTRL-C to quit

Lassen Sie uns alle derzeit aktiven Themen auflisten:

$ rostopic list

Das Thema / cmd_vel sollte in der Liste erscheinen. Zu diesem Thema veröffentlicht der Knoten teleop_twist_keyboard jedes Mal Nachrichten, wenn eine Taste auf der Tastatur gedrückt wird.
Lassen Sie uns die Ausgabe der im Thema / cmd_vel veröffentlichten Nachrichten anzeigen:

$ rostopic echo cmd_vel

Führen Sie rqt_graph aus, um das berechnete ROS-Diagramm in grafischer Form darzustellen. Das Berechnungsdiagramm zeigt alle aktiven Knoten und Themen, die sie verbinden.

$ rosrun rqt_graph rqt_graph

Bild

Hier sehen wir, dass der Knoten teleop_twist_keyboard Nachrichten an das Thema / cmd_vel veröffentlicht und der rostopische Knoten dieses Thema abonniert (Befehl rostopic echo).
Lassen Sie uns herausfinden, welche Art von Nachrichten im Thema / cmd_vel veröffentlicht werden:

$ rostopic type /cmd_vel

Der Befehl gibt die folgende Zeile aus:

geometry_msgs/Twist

Dies bedeutet, dass die Nachrichten vom Typ Twist aus dem Standard-ROS-Paket geometr_msgs sind.
Informationen zur Nachrichtenstruktur können wir auch mit dem Befehl rosmsg abrufen:

$ rosmsg show geometry_msgs/Twist


geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z

Das Feld 'linear' ist für die Lineargeschwindigkeit verantwortlich, 'Winkel' ist für die Winkelgeschwindigkeit.
Drücken Sie die Taste 'i'. Die Ausgabe sieht folgendermaßen aus (verbunden mit dem Vorwärtsbewegen):

linear: 
  x: 0.5
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 0.0
---

Drücken Sie die Taste 'k'. Die Ausgabe sieht folgendermaßen aus (Stopp):

linear: 
  x: 0.0
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 0.0
---

Drücken Sie die Taste 'u'. Die Ausgabe sieht folgendermaßen aus (biegen Sie links ab):

linear: 
  x: 0.5
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 1.0
---

Und schließlich, wenn Sie die Taste 'o' drücken, erhalten wir die folgende Ausgabe (biegen Sie rechts ab):

linear: 
  x: 0.5
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: -1.0
---

Die Tasten 'j' und 'l' sind dafür verantwortlich, sich nach links und rechts zu drehen (ohne sich vorwärts zu bewegen).

Tastaturrobotersteuerung mit teleop_twist_keyboard


Ich habe bereits die rosserielle Skizze zur Steuerung des Roboters durch Drücken von Tasten geschrieben. Wir abonnieren einfach das Thema / cmd_vel und geben dem Motion Controller abhängig vom empfangenen Wert jeder Geschwindigkeit den erforderlichen Befehl (vorwärts bewegen, anhalten, links oder rechts drehen). Die Skizze kann hier heruntergeladen werden .
Lassen Sie uns den Skizzencode genauer analysieren.
Am Anfang der Datei verbinden wir zusätzlich zur Standard-Header-Datei ros.h zwei zusätzliche Dateien mit den Nachrichtentypen Geometrie_msgs / Twist.h und Geometrie_msgs / Vector3.h:

#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Vector3.h>

Wir deklarieren einen Node-Handler ros :: NodeHandle:

ros::NodeHandle nh;

Der Hauptwert ist die messageCb-Methode:

void messageCb(const geometry_msgs::Twist& message) 
{
  geometry_msgs::Vector3 linear = message.linear;
  float forward_vel = float(linear.x);
  
  if(forward_vel == 0) { stop(); return; }
  
  geometry_msgs::Vector3 angular = message.angular;
  float ang_vel = float(angular.z);
  
  if(ang_vel > 0) { turnLeft(); }
  else if(ang_vel < 0) { turnRight(); }
  else { goForward(); }
}

Bei dieser Methode verarbeiten wir die empfangene Nachricht aus dem Thema cmd_vel. In der Variablen forward_vel behalten wir die lineare Geschwindigkeit bei, in der Winkelvariablen - Winkel. Mit der linearen Geschwindigkeit können wir den Stoppbefehl (Wert 0) verfolgen. Die Winkelgeschwindigkeit bestimmt die Drehrichtung (wenn größer als 0, dann links abbiegen, kleiner als 0 - nach rechts, wenn 0 - vorwärts bewegen).
Erstellen Sie einen Abonnenten für das Thema / cmd_vel:

ros::Subscriber<geometry_msgs::Twist> sub("/cmd_vel", &messageCb);

mit einem Verweis auf die Nachrichtenverarbeitungsmethode (messageCb) und den Typ der empfangenen Nachricht - geometr_msgs :: Twist.
Am Ende des Skripts folgen die Standardskizzenmethoden für rosserial_arduino:

nh.initNode();
nh.subscribe(sub);
Serial.begin(57600);

Führen Sie den Server rosserial_arduino aus:

$ rosrun rosserial_python serial_node _port:=/dev/ttyACM0

und lade die Skizze auf das Arduino-Board hoch.

Wechseln Sie zu dem Terminal, auf dem der Knoten teleop_twist_keyboard ausgeführt wird, drücken Sie die Tasten 'u', 'i', 'o' und 'k' und überprüfen Sie die Ausgabe des Rosserial-Servers im Terminal.

Mit dem Paket teleop_twist_keyboard können wir nun eine einfache Fernsteuerung des Roboters durchführen, indem wir Bewegungsbefehle übertragen: vorwärts bewegen, anhalten, nach links oder rechts drehen. In Zukunft werden wir lernen, wie man den Roboter mit dem Joystick steuert, was mit einem anderen Paket in ROS viel bequemer ist. Aber mehr dazu im nächsten Artikel.

Source: https://habr.com/ru/post/de390851/


All Articles