Autonome Spurführung mit einem JetRacer ROS AI Robot

Autor: | Jonas Michael Beisler |
Modul: | Projektarbeit, MBP-B-2-6.05 |
Starttermin: | 19.02.2024 |
Abgabetermin: | 14.02.2025 |
Prüfungsform: | Modulabschlussprüfung als Hausarbeit (Praxisbericht als HSHL Wiki Artikel Pflege) |
Betreuer: | Prof. Dr.-Ing. Schneider, Tel. 806 |
Mitarbeiter: | Marc Ebmeyer, Tel. 847 |
Einführung
Der JetRacer ist ein Modellrennwagen im Maßstab 1:10. Hierbei handelt es sich um ein leistungsstarkes intelligentes KI-Modellfahrzeug, das speziell für Studierende entwickelt wurde, die den Umgang mit dem Robot Operation System (ROS) erlernen möchten. Das System besteht aus zwei Steuereinheiten. Den Host-Controller bildet das JETSON-NANO-DEV-KIT-A und als Sub-Controller wird ein Raspberry Pi RP2040-Mikrocontroller verwendet. Die Hauptplatine integriert die OLED, den Servomotor-Antriebsschaltkreis, den Batterieschutzschaltkreis, einen Audioausgangsschaltkreis usw., das lästige Löten des Schaltkreises erspart, das Entladen und Laden unterstützt und kein wiederholtes Entfernen des Akkus erfordert. Der verbauter IMU-Lagesensor und DC-Encodermotor regelt die Geschwindigkeit über einen PID-Regler und kann einen Radkilometerzähler ausgeben. Die Software ist mit dem Open-Source-Projektprogramm NVIDIA JetRacer kompatibel und unterstützt AI Deep Learning, SLAM-Mapping und -Navigation, visuelle OpenCV-Verarbeitung, intelligente Sprachinteraktion und andere Funktionen.
Getting started
Lesen Sie zum Einstieg diese Artikel
- HSHL-Wiki: JetRacer ROS AI Roboter
- Waveshare: JetRacer ROS AI Kit Wiki
- Gantt Diagramm erstellen
- Tipps zum Schreiben eines Wiki-Artikels
- PAP Designer Einstieg
- Einführung in SVN
- Einrichtung der ScienceBox (Sciebo)
LOP | Status | Bemerkung |
---|---|---|
Sicherheitseinweisung für die Labore von Marc Ebmeyer | ☑ | |
Schlüsselübergabe für die Labore von Marc Ebmeyer | ☑ | |
SVN-Zugang bereitstellen | ☑ | user: Jonas_Beisler
|
Vereinbarung wöchentlicher Meetings | ☑ | |
Wiki-Zugang bereitstellen | ☑ | user: Jonas_Beisler
|
Einleitung


Abb.4: Gantt Diagramm der ursprünglichen Zeitplanung Abb.5: Gantt Diagramm des tatsächlichen Ablaufs
Vorstellung des Labors Autonome_Systeme
- Die Projektarbeit wurde im Labor Autonome Systeme unter Aufsicht von Herrn Professor Schneider und Herrn Ebmeyer durchgeführt. In dem Labor werden normalerweise Lehrveranstaltungen in den Bereichen Elektrotechnik und Systementwicklung durchgeführt. Außerdem werden dort auch viele Projekte ähnlich zu dieser Projektarbeit durchgeführt, einige Themen die behandelt werden sind zum Beispiel Autonomes Fahren oder Spurführung.
Aufgabenstellung
Anforderungen
Das Projekt erfordert Vorwissen in den nachfolgenden Themengebieten. Sollten Sie die Anforderungen nicht erfüllen müssen Sie sich diese Kenntnisse anhand im Rahmen der Arbeit anhand von Literatur/Online-Kursen selbst aneignen.
- Umgang mit Linux
- Python-Programmierung
- Dokumentenversionierung mit SVN
- Optional:
- Umgang mit ROS2
- Partikel Filter SLAM
Anforderungen an die wissenschaftliche Arbeit
- Wissenschaftliche Vorgehensweise (Projektplan, etc.), nützlicher Artikel: Gantt Diagramm erstellen
- Wöchentlicher Fortschrittsberichte (informativ), aktualisieren Sie das Besprechungsprotokoll - Live Gespräch mit Prof. Schneider
- Tägliche Sicherung der Arbeitsergebnisse in SVN
- Tägliche Dokumentation der geleisteten Arbeitsstunden
- Studentische Arbeiten bei Prof. Schneider
- Anforderungen an eine wissenschaftlich Arbeit
Konkrete Aufgabengebiete
- Einarbeitung in den JetRacer
- Zuerst sollte der JetRacer Roboter Bausatz zusammen gebaut werden und dann sollten die grundlegenden Fähigkeiten des Roboters ausprobiert werden. Im Laufe dieser Aufgaben sollte dann ein grundlegendes Verständnis aufgebaut werden welches durch eigene Ideen dann zu einem neuen Endergebnis führt.
- Ansteuerung des Antriebs und der Lenkung
- Einlesen der Sensoren
- Autonome Spurführung in der rechten Fahrspur mit SLAM LiDAR Mapping
- Als Endziel wurde festgelegt das der Roboter die im Labor aufgemalte Strecke (siehe Abb.2 und Abb.3) abfahren soll. Dies sollte anhand von automatisch gesetzten Navigationspunkten erfolgen. Als Automatisch wird in diesem Falle festgelegt das alle benötigten Punkte gesetzt werden sobald ein bestimmtes Skript im JetRacer ausgeführt wird. Dieses Skript kann ausgeführt werden sobald der Roboter und die VM beide im Navigationsmodus laufen.
- Systemtest
- Optimierung
- Dokumentation der Vorgehensweise im HSHL-Wiki
Thematische Einleitung
Zeitplanung/Projektplan
- Die Zeitplanung des Projektes wurde mit sogenannten Gantt Diagrammen dargestellt. In Abb.4 ist die ursprüngliche Planung dargestellt. In Abb.5 sieht man dann die im Nachhinein überarbeitet Planung welche den Ablauf des Projektes genauer darstellt.
Übersicht Inhalt
Theoretische Grundlagen
- Wie ist die Softwarestruktur? Welche Software wir benötigt?
- In diesem Projekt wurden verschiedene Software Aspekte benötigt um die Aufgabenstellung umzusetzen. Die beiden wichtigsten Aspekte waren dabei die Programmiersprache Python sowie das sogenannte Robot Operating System (ROS). Die mitgelieferten Skripte auf dem JetRacer waren in Python verfasst und das neu angelegte Skript wurde ebenfalls in Python umgesetzt, dementsprechend wurde ein Verständnis von Python sowie allgemeiner Programmierung benötigt. Das ROS war relevant für die Kommunkikation des Roboters, also der Sensoren im Auto, und den darüberliegenden Softwaresystemen. Diese Systeme waren zum einen das NVIDIA JetPack SDK sowie ein Ubuntu Linux System. Das Linux System war das grundlegende Level auf dem der Roboter sowie die Virtuelle Maschine liefen und das SDK wäre relevant gewesen für Bildverarbeitung oder Maschinelles Lernen.
- Wie ist die Hardwarestruktur? Wer kommuniziert wie mit wem?
Roboter Virtuelle Maschine auf Gastsystem Netzwerk(WLAN) im Labor
- Was ist ein LiDAR und welcher ist verbaut? Wie funktioniert der Sensor?
[1]
- Was ist Odometrie? Wie funktioniert diese?
- Als Odometrie wird das Verfahren bezeichnet mit welchem man die ungefähre Position und Orientierung eines mobilen Systems schätzt. Dieses Verfahren beruht normalerweise darauf das der Antrieb des Systems überwacht wird, und man so auf Entfernungen, die zurückgelegt wurden, schließt. Im Falle des JetRacers werden also die Radumdrehungen mitgezählt und über den bekannten Radumfang werden dann die zurückgelegten Strecken berechnet. Ebenfalls kann auf die Orientierung geschlossen werden wenn man die Winkel der Achseinstellung mit einbezieht.
- Allerdings ist dieses System alleine anfällig für Fehler und wird deswegen meist in Verbindung mit anderen Systemen für die Position des Roboters verwendet. Die Fehler in der Berechnung der Odometrie entstehen zum Beispiel durch eine Orientierung der Räder welche das Auto leicht nach links oder rechts anstatt gerade aus fahren lassen. Oder aber der Untergrund ist rutschig, was dazu führt das bei einer gezählten Radumdrehung nicht wirklich eine ganze Umdrehung nach vorne vollzogen wurde. [2]
- Welche Kamera ist verbaut? Wir die Kamera genutzt? Wie werden die Daten verarbeitet?
Kamera : In dieser Projektarbeit wurde die Kamera zwar ausgetestet und kalibriert, aber nicht für das Endergebnis verwendet.
- Wie ist ROS aufgebaut? Was ist der unterschied zu ROS 2? Wie funktioniert die Bahnplanung und Navigation?
Aufgebaut mit Subscriber und Publisher Unterschied: Move_Base Pfad-Planer
Möglichkeiten der Spurführung
Kamera & KI
- Eine Möglichkeit der Strecke im Labor zu folgen wäre per Kamera und KI Training umsetzbar gewesen. Dafür hätte man zuerst eine KI trainieren anhand von eigens erstellten Daten trainieren müssen. Also zum Beispiel die Strecke abfilmen, und dann die benötigten Steuerungsbefehle manuell eingeben und diese Informationen dann der KI zur Verfügung stellen.
- In dieser Projektarbeit wurde sich allerdings gegen das Verwenden der Kamera entschieden. Dementsprechend wurde eine Methode mit fest einprogrammierten Koordinaten für die Strecke bevorzugt.
Erstellen eigener Python Skripte Vorhandene Skripte umbauen
- Als Vorbild wurde das sogenannte "Multipoint Navigation Skript" genutzt. In diesem war der Code, der für das markieren der Punkte im Visualisierungs Tool RViz und das setzen der Zielpunkte für den Racer benötigt wird, vorhanden. Dieser Code wurde dann zuerst so abgeändert das mehrere Markierungen in RViz nicht nur bei einem Mausklick, sondern direkt beim ausführen des Skriptes gesetzt werden. Allerdings benötigte dieser Schritt ausführlicheren Publisher und Subscriber Code als im Skript ursprünglich vorhanden war.
- ROS Publisher & Subscriber
- Die sogenannten Publisher und Subscriber sind zwei der wichtigsten Systeme die es in ROS gibt. Sie sind dafür zuständig Daten, wie z.B. Informationen über Marker oder Odometrie, zwischen den verschiedenen Nodes hin und her zu schicken.
- Der "Publisher" ist ein Teilknoten, oder sogar ganzer Knoten, welcher Daten versendet. Diese Daten werden in ein sogenanntes "Topic", also quasi einen Kanal mit bestimmter Frequenz, gesendet. Dabei ist es egal ob ein anderer Knoten diesem Kanal zuhört oder nicht, der Publisher sendet immer Daten hinein.
- Der "Subscriber" ist dann ein Teilknoten, oder ganzer Knoten, der an diesem Kanal interessiert ist. Das besondere dabei ist das sich der Publisher und der Subscriber gegenseitig nicht kennen, sondern einfach nur beide etwas mit dem Kanal zu tun haben. Der ROS Master merkt sich auf beiden Seiten den jeweiligen Kanal der sie betrifft, und die Informationen werden dann weitergegeben.
- Da mehrere Publisher in einen einzelnen Kanal senden können, und auch mehrere Subscriber einem Kanal zuhören können, ist es wichtig das die jeweiligen Datentypen der gewünschten Informationen bei der Initialisierung der Knoten übereinstimmen.
- Publisher und Subscriber können in einem Python Skript wiefolgt initialisiert werden:
# Subscribe to the status of reaching the target point self.sub_goal_result = rospy.Subscriber('/move_base/result', MoveBaseActionResult, self.goal_result_callback) # Subscribe to the initial pose topic self.sub_initialpose = rospy.Subscriber('/initialpose', PoseWithCovarianceStamped, self.initialpose_callback)
Einbauen der benötigten Funktionen
- Automatische Marker
- Im erstellten Skript werden die Koordinaten der zu befahrenden Strecke zu erst in einem Array gesammelt. Dabei wird jeder zu markierender Punkt als eigenes Array im Format [X-Koordinate, Y-Koordinate] angelegt und dann in einem Gesamtarray gesammelt.
marker0 = [4.047, 0] marker1 = [7.078, 0.02] marker2 = [8.429, 1.128] marker3 = [8.761, 3.032] marker4 = [8.163, 5.253] marker5 = [7.643, 5.38] marker6 = [5.033, 5.052] marker7 = [4.003, 4.222] marker8 = [2.897, 2.374] marker9 = [3.386, 1.226] marker10 = [5.101, 1.705] marker11 = [5.721, 3.513] marker12 = [5.033, 5.052] marker13 = [4.971, 6.913] marker14 = [0.5, 6.462] marker15 = [-0.65, 4.98] marker16 = [-0.501, 4.029] marker17 = [-0.51, 2.805] marker18 = [-1.168, 1.74] marker19 = [-0.92, 0.498] marker20 = [0, 0] coordinates = [marker0, marker1, marker2, marker3, marker4, marker5, marker6, marker7, marker8, marker9, marker10, marker11, marker12, marker13, marker14, marker15, marker16, marker17, marker18, marker19, marker20]
- Danach wird dieses Array in einer For-Schleife durchgearbeitet und für jedes der Koordinatenpaare wird eine Markierung angelegt und dem sogenannten "markerArray" zugefügt. Jede dieser Markierungen hat ebenfalls verschiedene Parameter die gesetzt werden. Diese Parameter sind zum Beispiel die Farbe oder Größe der Markierung. Ebenfalls können hier "Header" oder "Text" der Markierung gesetzt werden.
for x in coordinates: # Create a marker object marker = Marker() marker.header.frame_id = 'map' # Character format marker.type = marker.TEXT_VIEW_FACING # marker model marker.action = marker.ADD # the size of the marker marker.scale.x = 0.6 marker.scale.y = 0.6 marker.scale.z = 0.6 # marker ColorRGBA marker.color.r = 1 marker.color.g = 0 marker.color.b = 0 marker.color.a = 1 # marker position XYZ markX = x[0] markY = x[1] markZ = 0 marker.pose.position.x = markX marker.pose.position.y = markY marker.pose.position.z = markZ # marker text marker.text = str(self.count) self.markerArray.markers.append(marker) self.count +=1 # Set the id of markers id = 0 for m in self.markerArray.markers: m.id = id print('marker: ' + str(m.id) + ' ' + str(m.pose.position.x)) id += 1
- Anfahren der Zielpunkte bzw. Abfahrend der Strecke
- Der erste Zielpunkt wird gesetzt bzw. veröffentlicht sobald das gesamte "markerArray" gefüllt ist. Dieses setzten ist fest im Code einprogammiert sodass das Abfahren der Strecke initial startet. Danach greift die sogenannte "goalCallback" Methode.
if self.count == 0: # Publish target point self.PubTargetPoint(coordinates[0][0],coordinates[0][1]) self.index+=1
- Sobald der Roboter dann den ersten Zielpunkt erreicht hat, wählt die unten dargestellte Methode anhand der IDs der Markierungen den nächsten Zielpunkt aus. Die Koordinaten des Punktes werden dabei aus den Parametern der Markierung herausgezogen und an die sogenannte "pubTargetPoint" Methode weitergegeben.
def goal_result_callback(self, msg): print('Goal Result started') if self.count == 0: return print ("Get the status of reaching the target point!!!") # Reach the target point if msg.status.status == 3: self.try_again = 1 # This round of cruise is completed, restart cruise if self.index == self.count: print ('Reach the target point ' + str(self.index - 1) + '.') self.index = 0 x = self.markerArray.markers[self.index].pose.position.x y = self.markerArray.markers[self.index].pose.position.y self.PubTargetPoint(x, y) # Cruise to the next point self.index += 1 # Cruise the remaining points of the round elif self.index < self.count: print ('Reach the target point ' + str(self.index - 1) + '.') x = self.markerArray.markers[self.index].pose.position.x y = self.markerArray.markers[self.index].pose.position.y self.PubTargetPoint(x, y) # Cruise to the next point self.index += 1 # Did not reach the target point else : rospy.logwarn('Can not reach the target point ' + str(self.index - 1) + '.') # Try again to reach the unreached target point if self.try_again == 1: rospy.logwarn('trying reach the target point ' + str(self.index - 1) + ' again!') x = self.markerArray.markers[self.index - 1].pose.position.x y = self.markerArray.markers[self.index - 1].pose.position.y self.PubTargetPoint(x, y) # It is not allowed to try again to reach the unreached target point self.try_again = 0 # Continue to the next target point elif self.index < len(self.markerArray.markers): rospy.logwarn('try reach the target point ' + str(self.index - 1) + ' failed! reach next point.') # If this round of cruise has been completed, the setting starts from the beginning if self.index == self.count: self.index = 0 x = self.markerArray.markers[self.index].pose.position.x y = self.markerArray.markers[self.index].pose.position.y self.PubTargetPoint(x, y) # Cruise to the next point self.index += 1 # Allow another attempt to reach the unreached target point self.try_again = 1
- Interessant ist außerdem noch das der Roboter sobald er die letzte im markerArray vorhandene Markierung angefahren hat, wieder die erste Markierung als nächsten Zielpunkt auswählt. Somit kann er also theoretisch unendlich oft die Strecker hintereinander abfahren.
- Orientierung an den Zielpunkten
- Die Orientierung an den Zielpunkten war eines der größten Probleme in der Erstellung des finalen Skriptes. Der Roboter konnte zwar früh die gewollten Koordinaten anfahren, aber er hatte Probleme mit seiner Orientierung.
- Der Roboter hat sich an jedem der gesetzten Zielpunkte immer so ausgerichtet wie er in seiner Startposition ausgerichtet war. Selbst wenn er sich z.B. nur um 90 Grad hätte drehen müssen und dann ein Stück vorwärts fahren müssen um den nächsten Punkt zu erreichen, hat der Roboter immer große Bögen gefahren um am Zielpunkt wieder in die gleiche Richtung zu schauen wie vorher.
- Die Lösung für dieses Problem waren dann die sogenannten Quaternions und eine Formel zur Berechnung des Anfahrtswinkels.
- Quaternions
- Allgemein versteht man unter Quaternions in der Mathematik eine Erweiterung der reellen Zahlen, welche durch mehrere Werte und Koeffizienten eine Startpunkt und eine Orientierung für einen "Vektor" angeben kann.
- Im Gebiet der Robotik werden deshalb Quaternions für genau diesen Umstand benutzt, sie geben die genauen Koordinaten des Roboters so wie seine Ausrichtung an. Ebenfalls kann eine gewünschte weitere Position, z.B. ein Ort der angefahren werden soll, mit einem Quaternion angegeben werden. Hierbei stehen die Koordinaten dann für die Koordinaten des Punktes und die Orientierung für die Orientierung die der Roboter am Zielort haben soll.
- Anfahrtswinkel Formel
- Um im Code Quaternions nutzen zu können wurde nach einiger Recherche eine Formel gefunden welche die derzeitige Position des Roboters sowie die Position des Zielortes verrechnet und somit einen natürlichen Winkel für die Anfahrt herausfindet.
- Aber, um diese Formel nutzen zu können mussten erstmal die genauen Koordinaten des Roboters per Odometry Subscriber herausgefunden werden. Sobald der Subscriber gestartet ist werden die Variablen welche die aktuellen Roboterkoordinaten enthalten aktualisiert und können dann genutzt werden.
- Aufgrund dieser Koordinaten kann dann der Anfahrtswinkel anhand der Formel ausgerechnet und in ein Quaternion eingesetzt werden. Danach wird dann eine Pose erstellt die das Quaternion sowie die X- und die Y-Koordinate welche der Methode übergeben wurden enthält. Diese Pose kann dann als neuer Zielpunkt veröffentlicht werden.
- Mit Hilfe der unten gezeigten Anpassung des Codes sollte der Roboter nun eine möglichst natürliche Orientierung an den Zielpunkten einnehmen und somit auch wie erwartet durch Kurven fahren können.
self.sub_Odometry = rospy.Subscriber('/odom', Odometry, self.odometry) angle_to_goal=math.atan2(y-self.testY, x-self.testX) q_angle = quaternion_from_euler(0, 0, angle_to_goal) q = Quaternion(*q_angle) poseTest = Pose(Point(x, y, 0.000), q) self.sub_Odometry.unregister()
Testen & Verbessern des Skriptes
- Das Skript für die Streckenabfahrt wurde im gesamten Zeitraum kontinuierlich entwickelt und verbessert. Bei jedem der oben genannten Zwischenschritten gab es kleinere Probleme die aus dem Weg geschafft werden mussten. Entweder geschah dies durch Recherche der jeweiligen Probleme oder durch Änderung der Herangehensweise an bestimmten Stellen.
- Einige Problemfälle waren zum Beispiel:
- 1. Nach der Montage des Roboters lies er sich nicht hochfahren. Dies lag daran das das Expansion Board, welches die Batterien hält, fehlerhaft war. Nachdem es ausgetauscht wurde ließ der Roboter sich hochfahren. Allerdings konnte man ihn immer noch nicht vernünftig steuern, und auch die LIDAR Funktion ging nicht. Dies lag an einem fehlerhaften Nano Module, nachdem dieses ausgetauscht wurde lief der Roboter.
- 2. Der Roboter fuhr zu Beginn des Skriptes nicht los um den ersten gesetzten Zielpunkt zu erreichen. Dies wurde behoben indem alle Marker in einem Array zusammengefügt wurden und dann erst der Aufruf zum Anfahren des ersten Punktes durchgeführt wird. Dies führt dazu das das System nicht mit zu vielen Aufgaben überlastet wird.
- 3. Ebenfalls in diesem Teilgebiet gab es das Problem das der Roboter den letzten Zielpunkt zuerst anfahren wollte, anstatt dem ersten. Dies lag daran das eine Zeit lang jeder Marker der angelegt wurde auch direkt als Zielpunkt gesetzt wurde, dies führte dann dazu das der zuletzt angelegte Marker, also der letzte Zielpunkt angefahren wurde. Dieses Problem wurde ebenfalls durch die neue Logik mit dem Array gelöst, da die Marker dadurch erst dann zum Zielpunkt gemacht wurden wenn der vorherige Marker erreicht war.
- 4 .Der Roboter wollte an jedem Punkt die gleiche Orientierung wie am Startpunkt einnehmen. Auf der Geraden war das kein Problem, in Kurven führte dies jedoch zu einem unnatürlichem Fahrverhalten. Theoretisch wurde dieses Problem durch die oben im Unterpunkt "Orientierung an den Zielpunkten" beschriebenen Änderungen behoben.
- 5. Die selber angelegten Python Skripte konnten zuerst nicht ausgeführt werden. Dies lag daran das die Berechtigungen an den Dateien nicht korrekt gesetzt waren. Mit dem Befehl chmod +x XYZ.py, wobei XYZ.py durch den jeweiligen Skriptnamen ersetzt werden muss,
Darstellung der Ergebnisse
Einarbeitung
- Zu Beginn der Projektarbeit wurde sich anhand von Tutorials auf der Website des Vertreibers des JetRacers in eben diesen eingearbeitet. Die Grundlagen sind in den nächsten Punkten wiedergegeben.
- Montage
- Die Montage war ein relativ selbsterklärender Prozess der aufgrund der Konzipierung des Systems als Baukasten gut durchführbar war.
- Die einzigen Veränderungen an der Montage waren das die Schraubenlöcher für den Servo tiefer gefeilt wurden, und kleine Gummiringe zur Dämpfung der Räder eingebaut wurden.
- Bewegung
- Ebenfalls konnte schnell ein Stand erreicht werden bei dem der Roboter frei gesteuert werden konnte. Dabei gab es drei verschiedene Modi:
- 1. Der Roboter konnte per einzelnen Eingaben in einer sogenannten "Publishing Node" gesteuert werden.
- 2. Ebenfalls konnte eine Tastatur benutzt werden um die verschiedenen Richtungen oder Orientierungen anzusteuern.
- 3. Oder es konnte ein Spiele-Kontroller benutzt werden um den Roboter frei steuern zu können.
- LIDAR
- Die LIDAR Funktion konnte ebenfalls schnell gestartet und getestet werden. Mit ihr ließen sich leicht Hindernisse erkennen und Karten erstellen.
- Odometrie
- Um einen reibungslosen Ablauf der verschiedenen Bewegungssysteme zu gewährleisten wurden ebenfalls einige Odometrie Tests durchgeführt, wie z.B. zu überprüfen das der Roboter nicht auf einer Geraden schief fährt oder das er wirklich einen Meter fährt wenn er aufgefordert wird einen Meter zu fahren.
- Kamera
- Ebenfalls wurde die Kamera überprüft und mit Hilfe eines Schachbrettes kalibriert.
Die Tutorials zu den verschiedenen Punkten können auf der Hauptseite des JetRacers eingesehen werden
Raum Kartographieren

- Damit der Roboter sich im Raum orientieren kann wird eine Karte benötigt. Diese wurde per LIDAR bzw. SLAM Mapping erstellt (siehe SLAM Mapping). Wichtig dabei war das der Mapping Algorithmus dort gestartet wurde, wo das Auto später für das Abfahren der Strecke starten wird. Dadurch wird die Karte mit dem korrektem Fokus angezeigt, und der Ursprung liegt gleichzeitig im Startpunkt.
- Die gespeicherte Karte wird im Navigationsmodus automatisch ausgewählt und genutzt.
- In der Karte (siehe Abb.4) sind in hellgrau die freien Flächen, und in schwarz die erfassten Hindernisse dargestellt. Die beiden Säulen von Punkten an beiden Seiten des Raumes sind z.B. Tischbeine.
Finale Vorführung des Ziels
- Navigationsmodus starten
- Damit der Roboter die Strecke abfahren kann muss er zuerst im Navigationsmodus sein, dafür muss am Roboter im Terminal erst der ROS Hauptknoten und die Navigations Systeme gestartet werden.
- Dies geschieht über die Befehle
roscore
undroslaunch jetracer nav.launch
, welche in zwei verschiedenen Terminals ausgeführt werden müssen. - Dafür kann entweder das NoMachine Programm genutzt werden um von Außerhalb auf den Roboter zuzugreifen, oder man steckt die benötigten Peripheriegeräte an.
- Danach muss dann noch innerhalb der Virtuellen Maschine im Terminal der Befehl
roslaunch jetracer view_nav.launch
eingegeben werden. Das sorgt dafür das sich das RViz Tool öffnet, in welchem man die Karte und die Position des Roboters sieht.
- Skript ausführen
- Jetzt muss der Roboter an seine gewünschte Startposition, hier also den Start/Ziel Strich der Strecke, gesetzt werden. Danach kann dann per NoMachine Zugriff in einem weiteren Terminal auf dem Roboter das, in diesem Falle streckeFahren.py benannte, Skript ausgeführt werden.
- Der Befehl hierfür lautet
rosrun jetracer streckeFahren.py
- Nach einer kurzen Verzögerung werden dann die Markierungen die der Strecke entsprechen im RViz Tool erscheinen und der Roboter fährt los.
Zusammenfassung und Ausblick
- Als Fazit kann gesagt werden das eine Grundlage zur weiteren Entwicklung gelegt wurde. Die meisten Funktionen des Roboters wurden erfolgreich implementiert und getestet und es wurde ein neues Skript erstellt welches als Grundlage genutzt werden kann um demnächst verschiedenste Formen abzufahren.
- Allerdings wurde nicht das komplette Ziel erreicht, der Roboter sollte eigentlich ähnlich einem Menschen durch die Strecke fahren. Dies wurde zwar durch die Quaternions im Code umgesetzt, aber wirkt sich beim wirklichen Abfahren nicht aus. Dies könnte verschiedene Gründe haben, entweder wird die Orientierung im Pfadplaner im Hintergrund überschrieben oder die Formel für die Berechnung des Anfahrtswinkels enthält noch nicht alle Parameter. Dieser Umstand müsste also bei einem anschließendem Projekt zuerst gelöst werden.
- Außerdem kann dieses Skript nur fest eingetragene Koordinaten abfahren, ein ändern der Strecke würde also relativ mühsam Koordinate für Koordinate eingetragen werden müssen. Eine mögliche Weiterentwicklung wäre also vielleicht das automatische Erstellen der Koordinaten durch eine KI. Hierfür könnte man z.B. verschiedene Formen zur Auswahl geben oder sogar eine frei aufgemalte Strecke an die KI weitergeben und diese gibt dann automatisch einen Block an Markierungen im [x-Koordinate, y-Koordinate] Format aus. Somit müsste dann nur noch dieser Textblock in den Code kopiert werden.
- Ein weiteres Gebiet welches noch Weiterentwicklung benötigt ist das Fahrverhalten bzw. die gesamte Odometrie des Roboters. Hier müssten vielleicht noch einmal die Einzelteile wie Achsen und Räder neu oder besser angebaut werden und das gesamte System neu kalibriert werden. Dies würde dazu führen das der Roboter geradliniger und genauer fahren kann.
Quellenverzeichnis
- [1] Internetforum. Wikipedia. Lidar [online]. [Zugriff am: 26. Februar 2025]. Verfügbar unter: https://de.wikipedia.org/wiki/Lidar
- [2] Internetforum. Wikipedia. Odometrie [online]. [Zugriff am: 26. Februar 2025]. Verfügbar unter: https://de.wikipedia.org/wiki/Odometrie
- [3] Internetforum. Wikipedia. Quaternion [online]. [Zugriff am: 10. Februar 2025]. Verfügbar unter: https://de.wikipedia.org/wiki/Quaternion
Anhang
Repositorium
- SVN-Projektordner: https://svn.hshl.de/svn/HSHL_Projekte/trunk/JetRacer/
- Sciebo-Abgabeordner: \Jonas_Beisler\Projektarbeit\
Links zu wichtigen Dateien
Dateiname | Link | Bemerkung |
---|---|---|
Finale Skript "streckeFahren.py" | [[1]] | |
"multipointNavigation.py" | [[2]] | |
Screencapture Video des Ausführen des Skriptes | / | |
Video der finalen Vorführung | / | |
Virtualbox Image | [[3]] | Der Inhalt der Zip kann aus dem Oracle VM Programm heraus geöffnet werden |
JetRacer Image | [[4]] | Diese komprimierten Dateien sind wahrscheinlich nicht mehr benutzbar da die Linux geschützten Ordner das hochladen nicht mitgemacht haben |
unverändertes JetRacer Image | [[5]] | Dieses Image kann auf eine SD-Karte gezogen werden von der dann gebootet werden kann. Danach muss nur das streckeFahren.py Skript in den Ordner /catkin_ws/src/jetracer_ros/scripts/ abgelegt werden |
Karten Dateien | [[6]] | Die .pgm Datei ist dabei eine Visualisierung der Karte und die .csv Datei sollte die Grauwerte für jeden Pixel in tabellarischer Form enthalten. Beim Übertragen durch ein Python Skript sind aber vielleicht Fehler entstanden. Die benutzbare Datei für zukünftiger Roboter ist also die .pgm Datei.' |
→ zurück zum Hauptartikel: Studentische Arbeiten