Erstellen einer Karte und Lokalisieren eines mobilen Roboters in ROS ohne Kilometerzähler mit laser_scan_matcher

Guten Tag Leser! Wir haben einmal in einem Artikel über Hector SLAM das Thema Lokalisierung und SLAM angesprochen . Wir sind weiterhin mit den Algorithmen zur Erstellung von Geländekarten und zur Lokalisierung in ROS vertraut. Heute werden wir versuchen, eine Karte des Gebiets ohne Quelle für Kilometerzähler zu erstellen , wobei wir nur das Lidar Hokuyo URG-04LX-UG01 und den Gmapping- Algorithmus verwenden und den Roboter auf der konstruierten Karte mithilfe des amcl- Algorithmus lokalisieren . Laser_scan_matcher hilft uns dabei . Wen kümmert es bitte unter der Katze.

Installieren des laser_scan_matcher-Pakets


Also fangen wir an! Für Experimente verwenden wir ROS Indigo, aber Sie können eine andere Version von ROS (Jade, Kinetic, Hydro) verwenden. Die Installation von Paketen sollte auf die gleiche Weise erfolgen (möglicherweise sind einige Pakete nur in ROS Kinetic nicht über apt-get verfügbar).

Das Paket laser_scan_matcher ist ein Tool zur inkrementellen Aufzeichnung von Laserdaten, das auf der Grundlage der Canonical Scan Matcher-Methode implementiert wird, über die hier gelesen werden kann . Über das Paket können Sie hier lesen . Das Paket kann ohne Kilometerzählerdaten verwendet werden und führt die Kilometerzählerbewertung selbst durch.

Installieren Sie das Paket:

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

Probieren wir die Demo aus:

roscore
roslaunch laser_scan_matcher demo.launch

Wir werden etwas Ähnliches in rviz sehen:



Hier wird laser_scan_matcher für Lidar-Daten angezeigt, die in einer Beuteldatei aufgezeichnet sind. Probieren Sie das Paket jetzt live aus. Um keine Zeit zu verlieren, werden wir es sofort mit dem Gmapping-Algorithmus versuchen. Erstellen Sie ein Paket mit der Datei my_gmapping_launch.launch, um gmapping zu starten:

cd ~/catkin_ws/src
catkin_create_pkg my_laser_matcher
cd src/my_laser_matcher
mkdir launch
vim launch/my_gmapping_launch.launch

Kopieren Sie den folgenden Code in die Datei my_gmapping_launch.launch:

Code my_gmapping_launch.launch
<?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>


Hier führen wir static_transform_publisher aus dem tf-Paket aus, um die Transformation zwischen den Knoten base_link → laserkoordinatensystemen, laser_scan_matcher und slam_gmapping zu veröffentlichen. Der Quellcode der Datei kann hier heruntergeladen werden . Um das Hokuyo-Lidar zu verwenden, müssen wir das ROS- Paket hokuyo_node installieren :

sudo apt-get install ros-indigo-hokuyo-node

Führen Sie den getID-Knoten aus dem Paket hokuyo_node aus, um Lidar-Informationen abzurufen:

rosrun hokuyo_node getID /dev/ttyACM0

Ein Fehler kann auftreten:

Error: Failed to open port. Permission denied.
[ERROR] 1263843357.793873000: Exception thrown while opening Hokuyo.
Failed to open port: /dev/ttyACM0. Permission denied (errno = 13). You probably don't have premission to open the port for reading and writing. (in hokuyo::laser::open) You may find further details at http://www.ros.org/wiki/hokuyo_node/Troubleshooting

In diesem Fall müssen wir Berechtigungen für den Port / dev / ttyACM0 hinzufügen:

sudo chmod a+rw /dev/ttyACM0

Führen Sie getID erneut aus dem hokuyo_node-Paket aus und erhalten Sie eine ähnliche Ausgabe:

Device at /dev/ttyACM0 has ID H0906078

Führen Sie nun den Knoten hokuyo_node aus:

rosrun hokuyo_node hokuyo_node

Führen Sie abschließend unsere Launcher-Datei my_gmapping_launch.launch aus:

roslaunch my_laser_matcher my_gmapping_launch.launch
rosrun rviz rviz

Lassen Sie uns die Themen auflisten:

rostopic list

Unter den Themen werden wir folgendes sehen:

/initialpose
/move_base_simple/goal
/odom
/pose2D
...
/imu/data

Auf diese Weise erhalten wir dank laser_scan_matcher Kilometerzähler und Roboterposition.

Fügen Sie eine Anzeige vom Typ LaserScan mit dem Thema / scan hinzu, wie im Artikel beschrieben . Fügen Sie auch eine Anzeige für die Map Map und für die Transformation von TF hinzu. Erweitern Sie den TF-Abschnitt und die darin enthaltenen Frames und notieren Sie sich die Punkte: odom, map, base_link. Ich möchte Sie daran erinnern, dass dies die Kilometerzähler-, Karten- und Roboterkoordinatensysteme sind. Denken Sie daran, den Wert / map auf das Feld Fixed Frame im linken Anzeigefeld im Abschnitt Globale Optionen festzulegen.

In rviz sehen wir ein ähnliches Bild:

Bild

Als nächstes bewegen Sie den Roboter einfach in den Weltraum, um eine vollständige Karte des Gebiets zu erstellen. Wir verwenden das Dienstprogramm map_saver aus dem Paket map_server, um die Karte zu speichern:

rosrun map_server map_saver

Lokalisierung mit amcl


Versuchen wir nun, den Roboter mithilfe des amcl-Algorithmus zu lokalisieren. Erstellen Sie die Datei my_localize.launch in unserem Paket mit folgendem Inhalt:

Code my_localize.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 name="hokuyo" pkg="hokuyo_node" type="hokuyo_node" respawn="false" output="screen">
    <param name="calibrate_time" type="bool" value="false"/> 
    <param name="port" type="string" value="/dev/ttyACM0"/> 
    <param name="intensity" type="bool" value="false"/>
  </node>

  <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/vladimir/catkin_ws/map.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"/>
  <!-- translation std dev, m -->
  <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>


Hier veröffentlichen wir ähnlich wie beim Launcher für Gmapping den Transformations- / Laser → / base_link mit den Knoten static_transform_publisher, hokuyo_node und laser_scan_matcher. Dann führen wir map_server aus, um unsere erstellte Karte zu veröffentlichen, wobei wir in args den Pfad zur Karte in der yaml-Datei übergeben. Starten Sie abschließend den amcl-Knoten mit den Parametern. Informationen zu amcl-Parametern finden Sie auf der offiziellen Algorithmus-Seite .

Der Launcher- Dateicode kann auch aus dem Github-Repository heruntergeladen werden . Führen Sie unsere Launcher-Datei aus:

roslaunch my_laser_matcher my_localize.launch

Gehen wir jetzt zu rviz. Legen Sie den Kartenwert für den festen Rahmen im Abschnitt Globale Optionen fest. Lassen Sie uns die Themen auflisten:

rostopic list

Neue Themen werden in der Liste angezeigt:

...
/amcl/parameter_descriptions
/amcl/parameter_updates
/amcl_pose
...
/map
/map_metadata
/map_updates
...
/particlecloud

Das Thema amcl_pose entspricht der Position des von amcl veröffentlichten Roboters.
Sehen wir uns die Beiträge im Thema an:

rostopic echo /amcl_pose

Holen Sie sich die Daten über die Position des Roboters:

header: 
  seq: 15
  stamp: 
    secs: 1482430591
    nsecs:  39625000
  frame_id: map
pose: 
  pose: 
    position: 
      x: 0.781399671581
      y: 0.273353260585
      z: 0.0
    orientation: 
      x: 0.0
      y: 0.0
      z: -0.636073020536
      w: 0.771628869694
  covariance: [0.2187289446708912, -0.010178711317316846, 0.0, 0.0, 0.0, 0.0, -0.010178711317316819, 0.23720047371620548, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07106236846890918]
---

In rviz erhalten wir das folgende Bild:

Bild

Wie Sie sehen können, stimmen die Scanpunkte vom Lidar teilweise mit den Wänden auf der Karte überein. So sah mein Setup wirklich aus:

Bild

Versuchen wir, den Roboter zu bewegen. Die Position des Roboters und der Blickwinkel der Karte sollten sich gleichzeitig im rviz-Fenster ändern. Nach dem Bewegen des Roboters kann die Position des Roboters durch den amcl-Algorithmus möglicherweise nicht genau bestimmt werden. Wir müssen die Position des Roboters mit dem 2D-Positionsschätzungswerkzeug anpassen. Klicken Sie dazu in der oberen Symbolleiste von rviz auf die Schaltfläche 2D-Posenschätzung, klicken Sie in rviz auf den ungefähren Punkt der Mitte des Roboterkoordinatensystems auf der Karte (base_link-Koordinatensystem) und halten Sie die Maustaste gedrückt. Ein grüner Pfeil erscheint in der Mitte des Roboters:

Bild

Ziehen Sie den Pfeil, ändern Sie seine Richtung und versuchen Sie, die Punkte des Scans vom Lidar mit schwarzen Rändern (Wänden) auf der Karte zu kombinieren. Nachdem Sie die beste Kombination erhalten haben, lassen Sie die Maustaste los.

Bild

Wir erhalten solche Nachrichten in dem Terminal, in dem my_localize.launch ausgeführt wird:

[ INFO] [1482431993.717411186]: Setting pose (1482431993.717383): -0.413 -0.071 0.057

Auf einem kurzen Video können Sie alles in Aktion sehen:



Topic / Particlecloud präsentiert Daten zur Unsicherheit der Position des Roboters in Form von orientierten Positionen (Pose) oder der sogenannten Partikelwolke. Der Nachrichtentyp ist geometr_msgs / PoseArray.

Hinzufügen einer Anzeige mit dem Namen topic / Partikelwolke :

Bild

In rviz erscheint eine Partikelwolke in Form einer dicken Gruppe roter Pfeile:

Bild

Je dicker die Partikelgruppe ist, desto höher ist die Wahrscheinlichkeit, dass sich der Roboter in dieser Position befindet. Weitere Informationen zum 2D-Pose-Schätzwerkzeug, zur Partikelwolke und zu anderen Konzepten finden Sie in amcl im Tutorial auf ros.org.

Das ist alles! Alle berücksichtigten Algorithmen (gmapping und amcl) sind Teil des großen Navigationsstapels in ROS. Viele Informationen dazu finden Sie im Internet. Heute haben wir das Tool laser_scan_matcher, gmapping und amcl Lokalisierungsalgorithmen in Aktion ausprobiert. Jetzt können Sie ganz einfach mit der Lokalisierung und Navigation eines mobilen Roboters beginnen und einen vollständig autonomen Roboter erstellen, der ohne manuelle Steuerung im Weltraum navigieren kann.
Abonnieren Sie unsere Gruppe auf ROS Vkontakte und halten Sie sich über neue Artikel und Neuigkeiten zur ROS-Plattform auf dem Laufenden. Ich wünsche euch allen viel Glück bei den Experimenten und bis bald!

PS: Alles mit dem kommenden 2017!

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


All Articles