SLAMとは、Simultaneous Localization and Mappingの略で、自己位置推定を行いながら地図作成を行うことです。
このSLAMで作成した地図を使って、ロボットを地図上の任意の位置に移動させることができます。
SLAMパッケージには、OpenSlamのgmappingや、GoogleのCartographerを使うためのSLAMパッケージがあります。今回は、ROSのSLAM機能の確認のため、ロボットモデルは、Turtlebot3を利用します。Turtlebot3を使うと、gazeboやSLAMと連携するためのパッケージも提供されているため、簡単に使えるからです。
英語版のチュートリアルもあります。このチュートリアルを参考にして、SLAMで地図作成をし、Navigationで経路を決めて動かしてみます。
Turtlebot3を利用する場合、端末を開く毎に、環境変数でTurtlebot3の種類を設定する必要があります。
$ export TURTLEBOT3_MODEL=burger
毎回設定するのは面倒なので、.bashrcに設定しておくと良いです。
ターミナルを開き、下記のコマンドを実行すると、gazeboにTurtlebot3が表示されます。
$ roslaunch turtlebot3_gazebo turtlebot3_world.launch
別の端末を開き、下記のコマンドでSLAMの地図作成メソッドを実行します。今回は、openslamのgmappingを使って地図作成を行います。
$ roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=gmapping
下記の画面となり、センサーが働いていることを確認できます。
別の端末を開き、下記のコマンドを実行します。
$ roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
キーボードの「w a s d x」キーで、Turtlebot3を動かして地図を作成すると、下記のような画面になります。
地図が完成したら、別のウインドウを開き、下記のコマンドで地図を保存します。
$ mkdir ~/maps
$ rosrun map_server map_saver -f ~/maps/world_map
world_mapは、地図名ですので、任意の名前を指定できます。
mapsフォルダの中を見ると、下記の2つのファイルが作成されています。
yamlファイルは、オブジェクトを文字列化したデータ形式で、設定ファイルなどで使われています。インデントを使って階層構造を表したテキストファイルです。
maps/world_map.yaml | オブジェクトをテキスト化したyamlファイル |
maps/world_map.pgm | 地図データの画像ファイル |
ナビゲーションパッケージは、自己位置推定機能や、経路探索機能や、ロボットの自律走行に必要な動作機能などを含んでいます。SLAMパッケージで作成した地図を使って、指定した位置にロボットを動かすことができます。
すべてのノードを終了させた後、端末を開き、下記のコマンドを実行します。
$ roslaunch turtlebot3_gazebo turtlebot3_world.launch
別の端末を開き、下記のコマンドを実行して地図を表示します。
$ roslaunch turtlebot3_navigation turtlebot3_navigation.launch map_file:=$HOME/maps/world_map.yaml
rvizの「2D Pose Estimation」を選択して、Turtlebot3の初期位置を設定します。
初期位置は、地図上のTurtlebot3の位置からTurtlebot3が向いている方向にドラッグして設定します。
rvizの「2D Nav Goal」を選択して、Turtlebot3を移動させたい目的地を設定します。
目的地は、目的地の位置からTurtlebot3を向かせたい方向にドラッグして設定します。
目的地の設定が終わると、Turtlebot3は目的地に向かって動き出します。
目的地への途中に、柱などの障害物があったても、柱に衝突せずに移動してくれます。
rqt_graphを使うと、ナビゲーションを行うときに、どのようなノードが動作しているかを調べることができます。別の端末を開き、下記のコマンドを実行します。
$ rqt_graph
下記のような画面が表示されます。ノードは ROSパッケージ内の実行ファイルで、rqt_graphでは、○に囲まれて表示されます。rqt_graphの表示を見ると、move_baseが、gazebo上で、robot_state_publisherからロボットの情報を取得し、map_serverから地図データを取得し、amclで自己位置を推定しながらナビゲーションを行っていることが分かります。