ROSで動かすロボットカー作り(SLAMをできるようにしてみた編)

※最初に

このエントリーのオチはパッケージの僕の理解不足で地図が作成されませんでした。

とにかくてっとり速く動いたパッケージのセットアップ方法を知りたい方は以下のエントリーをどうぞ

supernove.hatenadiary.jp

以前Lidarセンサーを動かして無事にセンサーの情報を取得することができたので、今回はこのLidarセンサーを使ってSLAMをできるようにしてみます。

Lidarセンサーを試した記事はこちら

supernove.hatenadiary.jp

今回の成果物はいつものように以下のレポジトリの backlog/step5ブランチで切っています。

github.com

用意するもの

ロボットには他にもいくつかパーツ使っていますが、今回のブログで使う機材だけを紹介します

動作環境

今回はRaspberry Pi上で試すのでRaspberry Piの動作環境を紹介します

Gmappingのインストール

まずはSLAMに必要なパッケージをインストールします。

今回は最もメジャーなSLAMパッケージであるGmappingをインストールします。

ワークスペースディレクトリ直下のsrcディレクトリ内で以下のコマンドを実行してパッケージのソースコードをクローンしてきます。

cd rober_catkin_ws/src
git clone https://github.com/ros-perception/slam_gmapping

続いて、依存パッケージであるopenslam-gmappingも合わせてクローンします。

git clone https://github.com/ros-perception/openslam_gmapping.git

これで必要なパッケージのインストールができたので、ビルドします。

catkin build

エラーが出なければインストールは完了です。

lauchファイルの用意

続いてマッピング用のlaunchファイルを用意します。

Gmapping向けにX2LでSLAMできるようにLidar, gmapping, tfの各ノードの設定をしたlaunchファイルが以下の内容です。

ファイル名は slam_gmapping.launchとします

<launch>
  <!-- X2L -->
  <node name="ydlidar_node"  pkg="ydlidar_ros"  type="ydlidar_node" output="screen" respawn="false" >
    <param name="port"         type="string" value="/dev/ydlidar"/>
    <param name="baudrate"         type="int" value="115200"/>
    <param name="frame_id"     type="string" value="base_link"/>
    <param name="resolution_fixed"    type="bool"   value="true"/>
    <param name="auto_reconnect"    type="bool"   value="true"/>
    <param name="reversion"    type="bool"   value="false"/>
    <param name="angle_min"    type="double" value="-180" />
    <param name="angle_max"    type="double" value="180" />
    <param name="range_min"    type="double" value="0.1" />
    <param name="range_max"    type="double" value="12.0" />
    <param name="ignore_array" type="string" value="" />
    <param name="frequency"    type="double" value="8"/>
    <param name="samp_rate"    type="int"    value="3"/>
    <param name="isSingleChannel"    type="bool"   value="true"/>
  </node>

  <!-- gmapping -->
  <node pkg="gmapping" type="slam_gmapping" name="mapper">
    <param name="maxUrange" value="8.0" type="double" />
    <param name="delta" value="0.03" />
    <param name="xmax" value="30" type="double" />
    <param name="ymax" value="30" type="double" />
    <param name="xmin" value="-30" type="double" />
    <param name="ymin" value="-30" type="double" />
  </node>

  <!-- tf -->
  <node pkg ="tf" type="static_transform_publisher" name="map_to_odom" args="0.0 0.0 0.0 0.0 0.0 0.0 /map /nav 40"/>
  <node pkg ="tf" type="static_transform_publisher" name="odom_to_base_link" args="0.0 0.0 0.0 0.0 0.0 0.0 /nav /base_footprint 40"/>
  <node pkg ="tf" type="static_transform_publisher" name="base_link_to_laser" args="0.2245 0.0 0.2 0.0 0.0 0.0 /base_footprint /base_link 40" />
</launch>

動かしてみる

いよいよ動かしてみます。

以下のコマンドでslam_gmapping.launchを起動します

roslaunch my_rober slam_gmapping.launch

エラーなくログに以下の1行が表示されたらセンサーは正常に起動しています。

[YDLIDAR INFO] Now YDLIDAR is scanning ......

続いてRvizでマッピングした内容を表示します。

ワークスペースディレクトリ上で以下のコマンドを実行し、設定ファイルを読み込んでRvizを起動します。

rosrun rviz rviz -d $(find $(pwd) -name gmapping.rviz)

実行すると以下のようにLidarから作成した地図が表示されるようになります。

ACアダプターに接続していて大きく移動してないので地図は更新されることはありません。

多分ロボットが自由に動かせる状態にして動き回れば更新させられるはずです…

ここでSLAMで必要になる座標情報を扱うtfで配信されているフレームのtransformツリーを確認するために以下のコマンドを実行します。

rosrun tf view_frames

実行すると 以下のようにtransformツリーのframes.pdfが出力されます。

まとめ

今回はRaspberry PiでSLAMをできるようにしてみました。

SLAMはなかなか日本語の文献がなくて、しかもYDLidar向けだとなかなか情報が見つからなくてここまでできるのに結構時間がかかりました。

この辺の知識は学生時代に授業でやってたことだとは思うのですが、真面目に授業受ければよかったなと後悔しましたw。

これでSLAMがなんとかできるようになったので次回は実際に走行させて地図を作成していきます。