※最初に
このエントリーのオチはパッケージの僕の理解不足で地図が作成されませんでした。
とにかくてっとり速く動いたパッケージのセットアップ方法を知りたい方は以下のエントリーをどうぞ
以前Lidarセンサーを動かして無事にセンサーの情報を取得することができたので、今回はこのLidarセンサーを使ってSLAMをできるようにしてみます。
Lidarセンサーを試した記事はこちら
今回の成果物はいつものように以下のレポジトリの backlog/step5
ブランチで切っています。
用意するもの
ロボットには他にもいくつかパーツ使っていますが、今回のブログで使う機材だけを紹介します
- Raspberry Pi 4
- YdLidar X2L
動作環境
今回はRaspberry Pi上で試すのでRaspberry Piの動作環境を紹介します
- Raspberry Pi OS Legacy(Busterベース)
- ROS melodic
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がなんとかできるようになったので次回は実際に走行させて地図を作成していきます。