SLAM - Mapping - Localization mit Python für Robot

  • Hallo zusammen,


    ich möchte meinem kleinen (fahrenden) Robot die Fähigkeit geben, sich in meiner Wohnung zurecht zu finden. Dazu gehört:


    1) Selbstständig eine 2D Karte der Wohnung zu erstellen

    2) Aufgrund einer bereits erstellten Karte sich grob zu lokalisieren

    3) Path Finding - zumindest einen halbwegs schnellen Weg zum Zielpunkt zu finden

    4) Wenn die aktuelle Position nicht präzise genug lokalisiert werden kann, dann soll er ein wenig "random" herumfahren, um eine "bessere" Position zu finden, anhand derer er sich dann weiterbewegen kann


    Ich habe folgende Seite schon gefunden:
    https://pythonrobotics.readthe…/latest/modules/slam.html

    https://atsushisakai.github.io/PythonRobotics/

    Ziemlich viele Arbeiten (Bachelor, Master etc.) darüber. Scheint zum einen ein "hot topic" zu sein, zum anderen wohl auch nicht gänzlich trivial.


    So, nun meine Idee / mein Ansatz:

    Ich möchte das Ganze mit Python 3 programmieren. Der Robot soll mehr oder weniger random (darf gerne auch gezielt sein, zB indem er in einem Raster die Wohnung abfährt) eine Karte erstellen, diese abspeichern und für spätere Runs abrufen können (deswegen wäre SLAM cool, aber nicht zwingend notwendig). Aufgrund seiner Startposition, diversen Sensoren (Ultraschall, Kompass), der Kenntnis über seine eigene Größe und seines Bewegungsprofils (Schrittmotoren als Antrieb) soll er seine ungefähre Position auf der Karte ausfindig machen können und im Anschluss auch mehr oder weniger direkt zu Zielpunkten steuern können (ist noch nicht endgültig, aber mein Ansatz - bin für Vorschläge offen). Mit einem Kompass, seinen gelaufenen Schritten und dem Wissen, was links, rechts und vor ihm liegt, sollte er grob seine Position abschätzen können.

    Mir ist klar, dass Schrittmotoren nicht perfekte Ergebnisse liefern und das gleiche kann man wohl auch über Ultraschallsensoren sagen. Allerdings geht es mir auch nicht darum, eine perfekte Position zu ermitteln, sondern mir würde es reichen, wenn er grob weiß, wo er sich befindet und wie er zum Zielpunkt kommt. Er sollte also sowohl aufgrund der bereits ermittelten Daten / Karte, als auch aufgrund seiner live-Daten seinen Weg anpassen können und im Idealfall mithilfe statistischer Methoden halbwegs abschätzen können, ob die Daten, die er grade bekommt, valide sind (zum Beispiel gibt der US-Sensor manchmal unsinnige Ergebnisse aus). Wenn eine perfekte Position gebraucht wird (zum Beispiel könnte man sich vorstellen, eine "Ladestation" zu bauen, an die er andockt), dann könnte man das über "Line Following" machen, was wahrscheinlich deutlich präziser möglich ist für kleines Geld?


    Nice-to-have wäre es außerdem, wenn die Kartendaten als "Karte" auch für den User (also mich) anzuschauen wäre und Bereiche definiert werden könnten (zum Beispiel Zimmer oder Sperrgebiete). Damit könnte ich ihn dann gezielt ins Wohnzimmer oder in die Küche rufen.


    Was habe ich schon:

    Ein fahrendes Etwas, das im Moment von einem US-Sensor (HC-SR04) auf einem Servo Daten erhält. Das soll ausgeweitet werden auf mindestens einen US-Sensor an jeder Seite, sodass Es jederzeit weiß, was vor ihm, links und rechts liegt. Es kann fahren und auch selbstständig anhalten, wenn ihm etwas zu nahe kommt. Die Daten werden gespeichert. Die Distanzdaten kann ich natürlich auch graphisch auftragen, mithilfe seiner eigenen Schritten und der Distanzdaten kann ich auch schon ganz grob mal ein Bild von seiner unmittelbaren Umgebung machen. Allerdings ist das noch weit von einer "Karte" entfernt. Ich weiß, ist nicht sonderlich viel, aber immerhin.


    Was suche ich / meine Frage:
    Hat jemand von Euch schon mal Mapping / Lokalisierung aufgebaut bzw. ein Tutorial an der Hand, in dem das in Python programmiert wurde? Gibt es dafür Module? Auf der Website von oben habe ich versucht, mich durchzukämpfen, hänge allerdings noch ein wenig fest (schon relativ früh, muss ich zugeben: Was ist überhaupt von den obigen Ideen ein Ansatz für meine Problemstellung?). Vielleicht gibt es ja bessere / leichtere oder sogar zugeschnittenere Module / Tutorials? Ich muss dazu sagen, dass ich mich in Python halbwegs zurecht finde (und mir auch aneignen kann, wenn mir was fehlt), allerdings C++ oÄ Programmiersprachen weder schreiben noch lesen kann. Also Module / Tutorials in der "falschen" Programmiersprache sind quasi nur semi-hilfreich, wäre aber immer noch besser als nichts ;)


    Wenn jemand eine Idee / Vorschlag oder sogar ein Tutorial zur Hand hat, wäre das cool =)
    LG
    Michi


    PS: Sorry für den langen Text und danke für's Durchlesen, wer bis hierher gekommen ist ;) Aber ich wollte die Problemstellung möglichst präzise beschreiben =)

    PPS: Bin mir unsicher über die Forenwahl. Falls falsch: Ich habe keine Ahnung, ob ich das Thema oder nur der Mod verschieben kann? Aber verschieben an sich ist natürlich kein Problem ;)

    Edited 2 times, last by elchico ().

  • Da hast du doch schöne Seiten rausgesucht, die eine Reihe von Ansätzen gut darstellen. Und so wie du es beschreibst, ist SLAM schon der richtige Begriff. Denn du hast ja keine Karte, sondern der Roboter soll die sich “erfahren”.


    Was du allerdings aus meiner Sicht unterschätzt: Koppelnavigation ist mit deinem mechanischen und sensorischen Equipment sehr ungenau. Durch Schlupf, starke Missweisung des Kompass, Latenzen in der Regelung und numerischen Ungenauigkeiten wirst du keine größeren Strecken geplant mit guter Wiederholgenauigkeit abfahren können. Genau darum macht man ja SLAM: der Roboter baut sukzessive aus einer Position hoher Sicherheit eine Karte auf, an der er sich selbst wieder lokalisiert, und seinen Radius erweitern kann.


    Was ebenfalls aus meiner Sicht ungünstig ist: du hast wenige Sensoren, die vor allem auch nur durch Bewegung des Roboters selbst Informationen in mehrere Richtungen liefern. Ich habe mir für meinen Roboter (Roboter 🤖 in Rust) daher einen von den hier gegönnt (noch nicht verbaut im Video): https://www.robotshop.com/en/y…x2-360-laser-scanner.html


    Alternativ kannst du auch einen deiner USS mit einem pan/tilt Modul schwenken. Etwas langsamer und unpräziser, aber schon ein großer Schritt nach vorn.

    Hier habe ich eine Seite gefunden, die Implementierungen von SLAM Algorithmen


    https://openslam-org.github.io/


    Die sind aber nicht notwendigerweise in Python! Da wirst du selbst nochmal suchen müssen.


    Zu guter letzt: das was ich hier üblicherweise an Code und Ansätzen so gesehen habe, ist leider meistens ungeeignet, den Schritt von einem simplen fernsteuern zu einer autonomen Bewegung zu gehen. Dazu bedarf es einen Systems, welches (Quasi)parallel mehrere Aufgaben gleichzeitig erledigt: gezielte Steuerung um zb einen gewünschten Pfad abzufahren, Berechnung der Odometrie zur eigenen (Groben!)Positionsbestimmung, gleichzeitige Akquise von Sensor-Daten, Not-Aus basierend auf den Daten, Verarbeitung eben dieser Daten, die dann mit der odometriein die SLAM Maschinerie geworfen wird, etc.


    Ich bin in meinem Projekt gerade am ersten Punkt! Und da ist schon viel Arbeit. Und ich vermute mal, du bist da noch nicht mal so weit.


    Ggf ist es also ein besserer Ansatz, ein fertiges Projekt zu suchen, und das dann aufzusetzen. Auch da ist die Randbedingung Python eine ziemliche Einschränkung.


    Nachtrag: hier ein paper zu FastSLAM das auf einer der ersten Slides schön zeigt, wie rein Odometrie/Koppelnavigation basierte Karten von der Realität abweichen!


    http://ais.informatik.uni-frei…f/slam13-gridfastslam.pdf



    Edited once, last by MistyFlower59469 ().

  • Vielen Dank erstmal für die Antwort!


    Gedanklich ist man natürlich immer schon etwas weiter, aber rein praktisch stecke ich wohl auch noch im ersten Punkt ;)


    Mal ein paar Antworten zu deinen Anregungen:
    1) Pan/Tilt ist im Moment wohl noch etwas "over-powered", weil ich zum einen "nur" eine 2D Map brauche und zum anderen meinen US Sensor schon auf einem Servo habe ==> Ist also eine ähnliche Richtung, aber für mich noch etwas zu viel =)

    2) LIDAR ist definitiv eine Option, die ich auch schon in Erwägung gezogen habe, allerdings ist es im momentanen Stadium noch etwas zu teuer. Wenn mein Es dann mal fährt und tut, was es soll, wird das dann evtl. als Optimierung / Verbesserungsmodul aufgesetzt.

    3) Das mit den Ungenauigkeiten ist mir auch ein Dorn im Auge ... Ich muss auch gleich zugeben, dass ich mich über Genauigkeiten von zB. GPS Sensoren (bezahlbaren Sensoren) noch nicht auseinander gesetzt habe. Steht auf der Agenda.

    4) Zumindest das Parallele werde ich wohl früher oder später auf einen Arduino auslagern müssen. Zumindest für die Motorensteuerung + Sensorik sollte das dann am Ende eine kleine Verbesserung bedeuten. Da bin ich aber zeitlich noch etwas entfernt von.

    5) Halbwegs verlässliche Eigen-Lokalisierung: Das ist definitiv ein Problem, bei welchem ich noch nicht genau weiß, wie ich das handhaben werde. Da meine Wohnung räumlich begrenzt ist (man glaubt es kaum), könnte ich mir vorerst vorstellen, diese zu rastern (zB ein Zimmer = ein Bereich) und diese Bereiche abzustecken (zB mit einer Laserdiode). Dann kann Es sich quasi immer neu kalibrieren über die Übertritte in einen neuen Bereich, indem bei Durchschreiten der Laserschranke und Abständen nach links rechts (wo in der Tür befindet Es sich) eine halbwegs passable Lokalisierung möglich ist. Ab dann gibt es eine Neukalibrierung. Außerdem stelle ich mir vor, dass Es quasi kontinuierlich (da wären wir wieder beim parallelen) die Abstände zu den (seitlichen) Wänden misst und so halbwegs präzise weiß, wie weit es von links / rechts entfernt ist.


    Die restlichen Punkte werde ich im Hinterkopf behalten.


    Deswegen zwei Nachfragen, um da jetzt Schritt für Schritt dran zu gehen:
    1) Gibt es eine Software für den Raspberry (vorzugsweise als Modul in Python, solange ich das noch nutze), die Messpunkte (in meinem Fall Distanzen) graphisch aufbereiten kann? Damit ich mal visuell abschätzen kann, wie gut / schlecht mein Ansatz funktioniert und wo definitiv Verbesserungen nötig sind? Also ich würde mir vorstellen: Ich habe Rohdaten (x,y1,y2,y3), wobei x die aktuelle Position ist und y die Distanz in die Richtungen 1,2,3 (also zB links, vorne, rechts). Diese werden dann geplottet, sodass man durch "Random fahren" eine Art "Karte" erstellt? Geht auf jeden Fall "manuell", indem bekannte Softwares (Excel, OriginLab etc.) missbraucht werden, aber die sind ja eigentlich nicht dafür gemacht ... Zumal ich es gern auf dem Raspberry laufen lassen würde.

    2) Gibt es ein Modul, welches solche Daten einliest, um theoretisch zu berechnen, dass am Punkt x links im Abstand y1 bzw. vorne oder rechts (y2,y3) etwas sein sollte? Klingt jetzt auf Anhieb auch (an sich) nicht so schwer von der Grundidee her, allerdings würde das doch einiges an Zeit fressen, das manuell zu programmieren, deswegen die Frage nach einem Modul (welches sicherlich auch noch besser / umfangreicher programmiert ist als ich es je könnte).


    LG und danke nochmal,
    Michi


    Edit: Habe dein Projekt schon gesehen gehabt und werde hin und wieder mal reinschauen ;) Bin mal gespannt, wie Du das mit der Wegplanung machst.

  • Nur horizontal bewegen ist schon ok, ich plane auch erstmal nicht meinen LIDAR zu tilten. GPS ist nur auf ~1m genau, funktioniert verlaesslich nur draussen. Hat also kein Einfluss auf dein Projekt. Indoor-Lokalisierungssysteme, basierend auf Funk oder IR, kosten mal schnell 3-4 stellige Summen. Fuer jemanden, der noch nicht mal das Geld fuer 3 Kaesten Bier in einen LIDAR investieren kann, wohl eher nicht die Loesung ;)


    Einen Arduino reinzunehmen hat diverse Vorteile, aber das erstreckt sich nur auf die basalen Funktionen. Die verschiedenen Aufgaben auf hoeherer Ebene - Selbstlokalisation ist ja nur eine, Wegeplanung und uebergeordnete Aufgabenplanung wollen ja auch erledigt werden - sind sinnvoll nur auf dem PI zu machen.


    Und was die Frage 5 angeht: genau das IST der SL-Teil von SLAM. Natuerlich ist es eine gute Strategie, a-priory Wissen wie eine Karte deiner Wohnung, oder klar identifizierbare Merkmale (manchmal als Beacons bezeichnet, koennten aber auch QR-Codes oder aehniches sein) in der Umgebung zu platzieren. Dadurch wird das Problem einfacher zu loesen.


    Aber - und hier beziehe ich mich auf deinen letzten Absatz 2 - gerade damit sinkt die Wahrscheinlichkeit, eine moeglichst fertige Loesung zu bekommen. Der heilige Gral, und das kommerziell interessanteste Problem, ist eben SLAM. Was hilft es Roomba, wenn ihr Roboter eine Karte der Fabrik in der er gebaut wurde hat, aber deine Wohnung eben nicht kennt.


    Wenn du also nicht so vorgehen willst, dass du dir ein bestehendes Projekt (und irgendwas wird es geben) nimmst, und "nur" auf deinen Roboter anpasst (oder den Roboter auf das Projekt), dann wirst du dich intensiver mit diesen Algorithmen und ihren Randbedingungen auseinander setzen muessen. Nicht so weit, dass du sie nachprogrammieren kannst/musst. Es gibt sie ja. Aber soweit, dass du ihre Vorbedingungen und Ergebnisse beurteilen und benutzen kannst.


    Zu guter Letzt die Frage nach Tools: da gibt es vieles, auch fuer Python. matplotlib, bokeh, plotly, wenn es um eine relativ fixe Darstellung geht, wobei bokeh zumindest auch online (im Sinne von: permanent geupdatet) funktioniert, mache ich gelegentlich. Qt, vielleicht auch VTK. Da ich versuche Rust zu lernen, nehme ich SDL2 und ggf. nannou.


    Auf dem PI wuerde ich die allerdings nicht einsetzen. Zum einen sitzt der doch im Roboter. Wie willst du die dann sehen? Zieht der einen Bildschirm hinter sich her? Und diese Aufgabe ist durchaus auch rechenintensiv, da kommt der im Zweifel nicht so gut mit klar. Ich schicke alle meine Telemetriedaten per nanomsg auf meinen PC, und der erledigt dann mit 16 Kernen die Drecksarbeit. Ob der angepeilte SLAM irgendwann mal wirklich eigenstaendig auf dem PI laeuft - wer weiss. Ich hoffe. Aber die Bequemlichkeit, erstmal am PC damit zu arbeiten, wuerde ich nicht missen wollen.

  • Danke für die ausführliche Antwort.


    Werde also das Rechnen auf meinen Laptop auslagern und die Daten online / live streamen. Hier muss ich mich aber noch einlesen. Früher oder später soll Es dann allein arbeiten können (ohne, dass der Laptop nebenbei läuft), aber das ist wohl weiter entfernt als ich gehofft hatte ;) Deswegen hatte ich eigentlich auch gehofft, dass es quasi alles (inklusive der Visualisierung) auf dem Pi läuft und ich bei Bedarf mich online dazuschalten kann (online meint: gleiches Netzwerk, aber während der Graph auf dem Pi kontinuierlich erweitert wird). Aber ich sehe ein, dass das noch ein weiter Weg ist.


    Arduino war mir klar, dass das nur bei den Low-Level Aufgaben hilft (Motorsteuerung etc.), aber wäre zumindest für die Genauigkeit der Daten definitiv eine große Hilfe. Bin aber auch hier noch von entfernt. Möchte erstmal was Grundlegendes auf dem Pi schaffen, auf dem ich dann aufbauen möchte.
    Deine anderen Vorschläge / Anregungen werde ich bei Bedarf dann aufgreifen, danke dafür.


    Eine letzte Frage noch, nachdem Du das jetzt schon zweimal erwähnt hast: Hast Du einen Link zu einem bestehenden Projekt, das evtl. das Vorgehen beschreibt und im Idealfall auch Code zur Verfügung stellt? Ich möchte das früher oder später selbst programmiert haben, aber ohne Anleitung braucht man bei sowas wohl 10fach so lange und es wird nur halb so gut (fehlende Funktionen usw). Deswegen wäre da ein Leitfaden, evtl. mit Material zum Anschauen (Code) hilfreich ;)


    Danke und einen schönen Abend noch,
    Michi

  • Den Link habe ich doch gerade gepostet ;)


    Ueber die Qualitaet des Projektes kann ich nicht viel sagen, ich habe das auch nur gefunden.

  • War da noch im Schreibfluss, sorry ;)


    Danke, werde ich mir zu Gemüte führen (auf den ersten Blick sieht es ja tatsächlich fast identisch zu dem aus, was ich mir vorstelle).


    Danke =)