ROS Lkw-Wagen. Teil 7. Lokalisierung des Roboters: Gmapping, AMCL, Referenzpunkte auf der Raumkarte

Beiträge in der Reihe:
8. Wir steuern von der Telefon-ROS-Steuerung, GPS-Knoten
7. Roboterlokalisierung: Gmapping, AMCL, Referenzpunkte auf der Raumkarte
6. Kilometerzähler mit Radgebern, Raumkarte, Lidar
5. Wir arbeiten in RVIZ und Pavillon: XACRO, neue Sensoren.
4. Erstellen Sie mit den Editoren rviz und gazebo eine Robotersimulation.
3. Beschleunigen, Kamera wechseln, Gang korrigieren
2. Software
1. Eisen

Letztes Mal, nachdem wir das Budget-Lidar RPlidar-A1 installiert hatten, gelang es uns, eine Raumkarte zu erstellen und mit Kilometerzähler zu arbeiten. Trotz einer Karte und der Anpassung der Kilometerzähler von optischen Sensoren fühlt sich der Roboter in der Umgebung immer noch unsicher.
Vielmehr sieht er sie überhaupt nicht. Und er reitet weit und breit auf der fertigen Karte, Hindernisse sind nichts für ihn. Dies ist gleichzeitig erfreulich und beunruhigend. Machen Sie sich einerseits keine Sorgen um Hindernisse und reisen Sie, wohin Ihr Herz begehrt, andererseits ist es unwahrscheinlich, dass Sie in einen anderen Raum oder in die Küche gehen. Daher werden wir über die Lokalisierung des Roboters im Weltraum unter Verwendung der von ROS bereitgestellten Algorithmen sowie über den Lidar- und Encoder-Satz unseres Herrn sprechen. Bevor wir jedoch direkt zur Lokalisierung übergehen, sprechen wir über ein anderes ROS-Paket, mit dem Sie auch 2D-Karten des Raums erstellen können. Manchmal funktioniert es für ihn besser als das ROS-Paket aus dem vorherigen Beitrag. Lernen Sie gmapping kennen.

Rm Clan Gmapping


Wir werden keine Originale sein und Entwicklungen aus dem bereits vorhandenen Habr-Artikel zu diesem Thema verwenden, aber wir werden die darin enthaltenen Informationen erweitern, aktualisieren und vertiefen. Der Artikel heißt Erstellen einer Karte und Lokalisieren eines mobilen Roboters in ROS ohne Kilometerzähler mit Laser_scan_matcher .

Ein Teil der Manipulationen (Hochlastanwendungen - rviz) wird auf dem Computer (außerhalb des Roboters) ausgeführt, der Rest (Bewegungstreiber, Lidar-Startknoten) - auf dem Roboter.

Installieren Sie zuerst den laser_scan_matcher für ROS-kinetic auf dem Computer gemäß dem Szenario des obigen Artikels (der Artikel war Indigo):

sudo apt-get install ros-kinetic-laser-scan-matcher 

Jetzt renn.

Nicke mit einem Lidar auf dem Roboter:

 roslaunch rplidar_ros rplidar.launch 

Auf einem Computer:

 roslaunch laser_scan_matcher demo.launch 

* Es ist nicht erforderlich, roscore auszuführen, da der Masterknoten jedes Mal startet, wenn der Roboter geladen wird.

Im Start-Rviz sind die Konturen des Raums und der Müll darin sichtbar:

Bild

Wir benötigen laser_scan_matcher, um mit dem gmapping ROS-Paket arbeiten zu können. Es ist nicht erforderlich, gmapping selbst zu installieren. Es befindet sich bereits als Teil von ROS Kinetic auf der virtuellen Maschine. Überprüfen Sie das Paket im System:



Erstellen wir nun eine Startdatei mit gmapping auf dem Computer (nicht auf dem Roboter), wie im obigen Artikel beschrieben:

 roscd roscd rosbots_description/launch nano my_gmapping_launch.launch     

Code
 <?xml version="1.0"?> <launch> <node pkg="tf" type="static_transform_publisher" name="base_link_to_laser" args="0.0 0.0 0.0 0.0 0.0 0.0 /base_link /laser 40" /> <node pkg="laser_scan_matcher" type="laser_scan_matcher_node" name="laser_scan_matcher_node" output="screen"> <param name="fixed_frame" value = "odom"/> <param name="use_odom" value="true"/> <param name="publish_odom" value = "true"/> <param name="use_alpha_beta" value="true"/> <param name="max_iterations" value="10"/> </node> <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen"> <param name="map_udpate_interval" value="1.0"/> <param name="delta" value="0.02"/> </node> </launch> 


Wie Sie dem Code entnehmen können, startet der Autor drei Knoten: tf, laser_scan_matcher und gmapping.

Lassen Sie uns den Lidar erneut auf dem Roboter ausführen:

 roslaunch rplidar_ros rplidar.launch 

Auf dem Computer die neu gebackene Startdatei und der rviz-Editor:

 roslaunch rosbots_description my_gmapping_launch.launch 

 rosrun rviz rviz 

In rviz erhalten wir ein ähnliches Bild wie beim Erstellen der Karte in unserem vorherigen Beitrag über den Roboterwagen. Nur dieses Mal funktioniert das Gmapping-Paket.

Und ich muss zugeben, es funktioniert nicht schlecht. Wenn hector_slam beim Drehen des Lidars um seine Achse zahlreiche Artefakte auf der Karte hinterlassen hat, gibt es diesmal fast keine Artefakte:



Nach Ausflügen durch den Raum wird auch die erstellte Karte gespeichert:
rosrun map_server map_saver -f map-1 , wobei map-1 der Name der zu speichernden Karte ist.

Lokalisierung mit amcl


Der Algorithmus, mit dem der Standort des Roboters auf der Karte bestimmt wird, heißt AMCL. AMCL verwendet einen Mehrpartikelfilter, um die Position des Roboters auf der Karte zu verfolgen. In unserem Roboter verwenden wir das ROS-Paket (http://wiki.ros.org/amcl), um AMCL zu implementieren.

Führen Sie AMCL für unseren Roboter aus.

Erstellen Sie dazu auf dem Computer im Projektordner eine weitere Startdatei.

Rufen wir ihn an

amcl-2.launch
 <launch> <param name="/use_sim_time" value="false"/> <node pkg="tf" type="static_transform_publisher" name="base_link_to_laser" args="0.0 0.0 0.0 0.0 0.0 0.0 /base_link /laser 40" /> <node pkg="laser_scan_matcher" type="laser_scan_matcher_node" name="laser_scan_matcher_node" output="screen"> <param name="fixed_frame" value = "odom"/> <param name="use_alpha_beta" value="true"/> <param name="max_iterations" value="10"/> </node> <node name="map_server" pkg="map_server" type="map_server" args="/home/pi/catkin_ws/src/rosbots_description/maps/map-3.yaml"/> <node pkg="amcl" type="amcl" name="amcl" output="screen" > <!-- Publish scans from best pose at a max of 10 Hz --> <param name="odom_model_type" value="diff"/> <param name="odom_alpha5" value="0.1"/> <param name="transform_tolerance" value="0.2" /> <param name="gui_publish_rate" value="10.0"/> <param name="laser_max_beams" value="30"/> <param name="min_particles" value="500"/> <param name="max_particles" value="5000"/> <param name="kld_err" value="0.05"/> <param name="kld_z" value="0.99"/> <param name="odom_alpha1" value="0.2"/> <param name="odom_alpha2" value="0.2"/> <!-- laser, translation std dev, m --> <param name="laser_min_range" value="-1"/> <param name="laser_max_range" value="-1"/> <param name="odom_alpha3" value="0.8"/> <param name="odom_alpha4" value="0.2"/> <param name="laser_z_hit" value="0.5"/> <param name="laser_z_short" value="0.05"/> <param name="laser_z_max" value="0.05"/> <param name="laser_z_rand" value="0.5"/> <param name="laser_sigma_hit" value="0.2"/> <param name="laser_lambda_short" value="0.1"/> <param name="laser_lambda_short" value="0.1"/> <param name="laser_model_type" value="likelihood_field"/> <!-- <param name="laser_model_type" value="beam"/> --> <param name="laser_likelihood_max_dist" value="2.0"/> <param name="update_min_d" value="0.2"/> <param name="update_min_a" value="0.5"/> <param name="odom_frame_id" value="odom"/> <param name="base_frame_id" type="str" value="base_link" /> <param name="global_frame_id" type="str" value="map" /> <param name="resample_interval" value="1"/> <param name="transform_tolerance" value="0.1"/> <param name="recovery_alpha_slow" value="0.0"/> <param name="recovery_alpha_fast" value="0.0"/> <param name="use_map_topic" value="true" /> <param name="first_map_only" value="true" /> </node> </launch> 


Der Code ist vollständig identisch mit dem bereits erwähnten Artikel, mit Ausnahme von:
- den Knoten ausgeschlossen, der das Hokuyo-Lidar startet (es läuft auf dem Roboter)
- Pfad und Name der Raumkarte sind unterschiedlich (map-3.yaml)
Der Code führt 4 Knoten aus:
- tf
- map_server
- laser_scan_matcher
- amcl
Der amcl-Knoten verwendet die von map_server veröffentlichte Karte für die nachfolgende Roboterlokalisierung.

Führen Sie die Startdateien aus und sehen Sie sich das Ergebnis an.

Aber zum Roboter:

 roslaunch rplidar_ros rplidar.launch 

Auf einem Computer:
1. Terminal: roslaunch rosbots_description amcl-2.launch
2. Terminal: roslaunch rosbots_description rviz.launch

Nach dem Start von rviz lauten die nächsten Schritte in diesem Editor wie folgt:
- Hinzufügen von Anzeigen zu rviz:
• LaserScan
• Karte
• PoseArray


- Lokalisieren Sie den Roboter in der Anfangsphase, da amcl beim Starten nicht weiß, wo der Roboter gestartet wurde und wo er sich befindet. Benötigen Sie "Erstinitialisierung".
Dazu müssen Sie in rviz „2D-Posenschätzung“ auswählen und den grünen Pfeil rechts im Fenster verwenden, in dem der Roboter seine Position anzeigt:



Dieser Vorgang muss durch Auswahl von Frame "map" in rviz ausgeführt werden:



Im Terminal erhalten wir die Koordinaten (Pose) des Roboters:

 [ INFO] [1572374324.454855505]: Setting pose (1572374324.454806): -0.014 -0.012 0.655 

Sie können die Position des Roboters auf der Karte mithilfe des grünen Pfeils auf der Karte wiederholt einstellen.
Es ist wünschenswert, dass die Daten vom Lidar (roter Rand) auf der Karte übereinstimmen oder nahe an der tatsächlichen Position der Wände des Raums liegen:



Im rviz-Visualisierungsfenster erhalten wir die charakteristischen roten Pfeile um den Roboter *:



* Als Roboter haben wir eine Achse für Klarheit (das gesamte gemalte Rviz-Modell ist immer noch versteckt).
** Wenn die Pfeile nicht angezeigt wurden, können Sie versuchen, die zu rviz hinzugefügte PoseArray-Anzeige zu entfernen und erneut zu überprüfen.

Trotz der Tatsache, dass wir direkt auf der Karte angegeben haben, wo sich der Roboter befindet, geht das System immer noch davon aus, dass er sich an den Stellen befinden kann, an denen die roten Pfeile gezeichnet sind. Dies ist der wahrscheinliche Standort des Roboters auf der Karte. Eine große Anzahl von Pfeilen und ihre Streuung auf der Karte zeigen an, dass das System den genauen Standort des Roboters immer noch nicht kennt. An dem Ort, an dem der Schütze dichter ist, ist der Roboter jedoch wahrscheinlicher.

Damit das System genauer verstehen kann, wo sich der Roboter befindet, müssen Sie auf einer Karte mit laufenden Knoten fahren, die den Standort des Roboters bestimmen. Wir haben aus diesem Set: Lidar und Encoder.
Wir fahren aber nur mit dem gestarteten Lidar auf der Karte und finden gleichzeitig heraus, ob es möglich ist, den Roboter nur mit seiner (Lidar-) Hilfe zuverlässig zu lokalisieren.
-
reite einen Roboter auf einer Karte
Auf dem Roboter:

 rosrun rosbots_driver part2_cmr.py 

Auf einem Computer:

 rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/part2_cmr/cmd_vel 


Während der Reise beginnt amcl mit dem Lesen der Themen / scan, / map, / tf und veröffentlicht den Standort des Roboters in den Themen / amcl_pose und / Partikelcloud.

Während Sie reisen, können Sie beobachten, dass die Anzahl der Pfeile abnimmt und sie an einem Punkt mit dem tatsächlichen Standort des Roboters zunehmend verdichtet werden:


Das Bild zeigt, wie sich das Modell bewegt (in Form eines Verbindungsbaums). Und es ist auch zu sehen, dass der Lidar die Lokalisierung an mehrdeutigen Grenzen des Raums nicht genau genug bewältigt.

Was bedeuten die anderen Parameter im amcl-Knotencode?


Herkömmlicherweise werden sie in grundlegende (Allgemein), Filterparameter (Filter), Laserparameter (Lidar) (Laserparameter) unterteilt.

Schlüsselparameter:
  • odom_model_type (Standard: "diff"): Bestimmt, welches Kilometerzählermodell verwendet werden soll. Wir haben diff, was different bedeutet. Kann in "omni", "diff-korrigiert" oder "omni-korrigiert" geändert werden.
  • odom_frame_id (Standard: "odom"): Definiert den Frame (lesen Sie das Thema), dem die Odometrie zugeordnet wird. Es wird normalerweise im Odom-Thema veröffentlicht.
  • base_frame_id (Standard: "base_link"): Frame für die Basis des Roboters.
  • global_frame_id (Standard: "map"): Frame der Map, in der Regel veröffentlicht der Map-Server ihn in der Topic Map
  • use_map_topic (Standard: false): Legt fest, ob die Karte über das Thema oder durch Aufrufen des Dienstes geladen wird (wir erinnern uns, dass es neben Themen in ROS auch Dienste und Aktionen gibt.


Filterparameter
Mit diesen Optionen können Sie die Funktionsweise des Partikelfilters anpassen.

  • min_particles (Standard: 100): Legt die Mindestanzahl von Partikeln für den Filter fest. Wir haben 500.
  • max_particles (Standard: 5000): Legt die maximale Anzahl von Partikeln für den Filter fest.
  • kld_err (Standard: 0,01): Legt den maximal zulässigen Fehler zwischen der wahren Verteilung und der berechneten Verteilung fest. Wir haben 0,05
  • update_min_d (Standard: 0,2): Legt die lineare Entfernung (in Metern) fest, die der Roboter zurücklegen muss, um den Filter zu aktualisieren.
  • update_min_a (Standard: pi / 6.0): Legt den Winkelabstand (im Bogenmaß) fest, den der Roboter bewegen muss, um den Filter zu aktualisieren. Wir haben 0,5
  • resample_interval (Standard: 2): Legt die Anzahl der Filteraktualisierungen fest, die vor dem erneuten Abrufen erforderlich sind. Wir haben 1.
  • transform_tolerance (Standard: 0.1): Die Zeit (in Sekunden), über die die veröffentlichte Transformation datiert werden soll, um anzuzeigen, dass diese Transformation in Zukunft gültig ist.
  • gui_publish_rate (Standard: -1,0): Die maximale Geschwindigkeit (in Hz), mit der Scans und Pfade zur Visualisierung veröffentlicht werden. Wenn dieser Wert -1,0 ist, ist diese Funktion deaktiviert. Wir haben 10.


Parameter des Lasers (Lidar) (Laserparameter)
Mit diesen Parametern können Sie konfigurieren, wie amcl mit dem Lidar-Laser interagiert.

  • laser_min_range (Standard: -1,0): Der zu berücksichtigende Mindestabtastbereich; -1,0 verwendet den im Laserbericht angegebenen Mindestbereich.
  • laser_max_range (Standard: -1,0): Der maximal zu berücksichtigende Scanbereich; -1,0 verwendet die maximale Laserreichweite.
  • laser_max_beams (Standard: 30): Wie viele gleichmäßig verteilte Strahlen in jedem Scan werden beim Aktualisieren des Filters verwendet.
  • laser_z_hit (Standard: 0,95): Die Gewichte der z_hit-Komponente des Robotermodells.
  • laser_z_short (Standard: 0.1): Die Gewichte der z_short-Komponente des Robotermodells.
  • laser_z_max (Standard: 0,05): Das Gewicht der z_max-Komponente des Robotermodells.
  • laser_z_rand (Standard: 0.05): Die Gewichte der z_rand-Komponente des Robotermodells.


Mal sehen, wie sich die Parameter min_particles und max_particles auswirken. Wenn Sie ihre Werte reduzieren, ist die Anzahl der Partikel im visuellen Editor beim Starten der Startdatei deutlich geringer.

Alle Parameter tragen eine semantische Last, aber es ist schwierig, den Effekt der Änderung jedes einzelnen Parameters innerhalb des Artikels zu analysieren.

Referenzpunkte auf der Raumkarte


Der Name ist eingängig und impliziert die Position des Roboters auf der Karte in diesem bestimmten Moment.

Wofür sind sie? Um zu verstehen, dass der Roboter von Punkt A im Raum zu Punkt B in der Küche kam.

Daten über die Position (Pose) des Roboters können mit dem amcl-Arbeitsknoten abgerufen werden (was im obigen Artikel begonnen hat).

Und schauen Sie im Thema / amcl_pose:

 rostopic echo -n1 /amcl_pose 

* Taste n1 - zum "Korrigieren" des Nachrichtenflusses im Thema.



Lassen Sie uns einen Dienst erstellen, der beim Aufruf die Position (Koordinaten) des Roboters angibt, damit er sich nicht jedes Mal mit dem Thema befasst.

1.Erstellen Sie ein neues Ros-Paket.

 cd catkin_ws/src catkin_create_pkg get_pose rospy cd get_pose/src 

2. Erstellen Sie im Ordner die Datei:

get_pose_service.py
 #! /usr/bin/env python import rospy from std_srvs.srv import Empty, EmptyResponse # Import the service message python classes generated from Empty.srv. from geometry_msgs.msg import PoseWithCovarianceStamped, Pose robot_pose = Pose() def service_callback(request): print "Robot Pose:" print robot_pose return EmptyResponse() # the service Response class, in this case EmptyResponse def sub_callback(msg): global robot_pose robot_pose = msg.pose.pose rospy.init_node('service_server') my_service = rospy.Service('/get_pose_service', Empty , service_callback) # create the Service called get_pose_service with the defined callback sub_pose = rospy.Subscriber('/amcl_pose', PoseWithCovarianceStamped, sub_callback) rospy.spin() # mantain the service open. 


* Vergessen Sie nicht, es ausführbar zu machen chmod + x get_pose_service.py
3. Erstellen wir einen Start für die Datei mit dem Knotencode:

 cd .. mkdir launch && cd launch 

Nano

get_pose_service.launch
 <launch> <node pkg="get_pose" type="get_pose_service.py" name="service_server" output="screen"> </node> </launch> 


4. Vergessen Sie nicht, Catkin wieder aufzubauen:

 cd catkin_ws catkin_make 

Jetzt werden wir alles neu starten, einschließlich der neuen Startdatei.

Aber zum Roboter:

 roslaunch rplidar_ros rplidar.launch 

Auf einem Computer:

 1- : roslaunch rosbots_description amcl-2.launch 2- : roslaunch rosbots_description rviz.launch 3- : roslaunch get_pose get_pose_service.launch 

Wir wenden uns dem neuen Dienst zu, der uns die aktuelle Position des Roboters auf der Karte anzeigen soll (wir werden den ROS-Dienst anrufen):

 rosservice call /get_pose_service 

Im Terminal, in dem start get_pose ausgeführt wird, werden die Koordinaten des Roboters auf der Karte angezeigt:



Mögliche Fehler.

[rviz.launch] ist weder eine Startdatei im Paket [rosbots_description] noch [rosbots_description] ein Startdateiname
Lösung:

 cd catkin_ws source devel/setup.bash 

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


All Articles