# 環境地図を使った位置推定および地図の構築
---
---
**必要なパッケージのインストール**
ノートパソコンにはgmappingパッケージがインストールされていません。
インストールするため、以下のコマンドを実行してください。
```bash
sudo apt install -y ros-noetic-openslam-gmapping ros-noetic-slam-gmapping
```
---
---
## 主なROSパッケージ
- 地図サーバー
- `map_server`
- ローカリゼーション
- `amcl`
- 地図構築(SLAM)
- `gmapping`
---
## 地図サーバー
### パッケージ`map_server`
- 地図(占有グリッド地図)は白黒画像(.pgm、.png形式など)として保存されます。
- 使用するためのパラメータ(原点、解像度など)は.yamlファイル内に入っています。
```yaml
image: testmap.png
resolution: 0.1
origin: [0.0, 0.0, 0.0]
occupied_thresh: 0.65
free_thresh: 0.196
negate: 0
```
ノード`map_server`
- 地図をROSサービスおよびROSメッセージとして公開します
```bash
rosrun map_server map_server watashi_no_chizu.yaml
```
地図を保存するツール(SLAMアルゴリズムによって作成): `map_saver`
---
## ローカリゼーション(自己位置推定)
### パッケージ`amcl`
ノード`amcl`
- (適応型)MCLローカリゼーションアルゴリズムの実装
- 使用する情報:
- レーザースキャン(通常は`/scan`トピック)
- TF(odom座標系)で公開されたオドメトリ
- `map_server`ノードによって公開された地図
- 初期位置を手動で設定するために使用できる`initialpose`トピック(メッセージはRVizからパブリッシュできます)
- 公開する情報:
- トピック`amcl_pose`に推定ポーズのメッセージ
- パーティクル(粒子)群のメッセージ
- TFには、地図座標系(`map`)⇔`odom`の変換
- グローバルローカリゼーションを開始するための`global_localization`サービスも提供します。
- 呼ばれるとパーティクルが再初期化されます(地図全体に)
---
### amclのパラメータ
多くのパラメータを設定できます
例えば、オドメトリのノイズ:
- `odom_alpha1`、`odom_alpha2`、`odom_alpha3`、`odom_alpha4` ⇒ 速度測定ノイズパラメータ(大きくすると、パーティクルがより広がります)
多くの場合、デフォルトのパラメータのままで使うので充分です。
詳細は: https://wiki.ros.org/amcl
---
### その他の自己位置推定パッケージ(任意)
この演習では使いませんが、その他のROSローカリゼーションパッケージもあります:
- https://wiki.ros.org/mrpt_localization - `amcl`に似ていますが、より多くのアルゴリズムが含まれています
- 「Kalmanフィルター」を使用したローカリゼーション: https://wiki.ros.org/robot_localization
---
### AMCLの使用例
---
## 環境地図構築
### パッケージ`gmapping`
`slam_gmapping`ノード ⇒ 地図を構築するためのSLAMアルゴリズム(粒子フィルター)の実装
- 使用する情報:
- レーザースキャンを含むメッセージ(通常、トピック`/scan`)
- TFで公開されたオドメトリ(座標系`odom`)
- 公開する情報:
- `map`トピックに地図を含むメッセージ
- TFには、地図座標系と`odom`の間の変換
- `map`トピックに地図は`map_server`パッケージの`map_saver`ツールで保存できます
---
### slam_gmapping:基本的なパラメーター
amclと同様に、多くのパラメータを設定できます。
- 例えば:`srr`、`srt`、`str`、`stt` ⇒ 名前が違いますが、`amcl`の`odom_alphaX`と同じです
- `map_update_interval` ⇒ 地図の更新期間
amclと同様に、多くの場合、デフォルトのパラメータのままで使うので充分です。充分です。
すべてのパラメーターの説明はこちらです: https://wiki.ros.org/gmapping
---
### その他の地図構築パッケージ(任意)
地図構築ツールもいろいろあります
- https://wiki.ros.org/mrpt_slam
- https://wiki.ros.org/cartographer
- https://wiki.ros.org/hector_slam
---
### 地図構築の動画
---
## 試してみましょう
### 地図構築
(1) 以下のリンクから robot_house パッケージの圧縮ファイルをダウンロードし、catkin_ws/src/フォルダに解凍してください。
https://www.robot.soc.i.kyoto-u.ac.jp/roboprog/materials/robot_house.zip
そのパッケージから`robot_house.launch`ファイルを実行して、Gazeboのシミュレーションが開始します。
(CPU負荷を軽減するために、Gazeboによる視覚化を無効にしています。3次元のシミュレーションを表示したい場合は、別のターミナルで`gzclient`を実行するか、launchファイルを編集してGazeboの引数`gui`を`false`に設定してください。)
RVizを起動して、ロボットとレーザースキャンを表示してください。
turtlebot3_teleopパッケージを使ってロボットを動かしてみてください。
---
(2) `gmapping`パッケージの`slam_gmapping`ノードを実行します。
RVizで地図(トピック`/map`)を表示して、ロボットを移動させてみてください。地図が少しずつ構築されることが見えるはずです。パーティクル(`/particlecloud`)を表示してみてもいいです。
---
(3)
環境全体のデータをとるようにロボットを動かします。よさそうな地図ができたら、`map_server`パッケージの` map_saver`ツールを使用してディスクに保存してください。
保存されたファイルの中身を確認してください。
### 位置推定
(1) 以上と同様に、`robot_house`パッケージの`robot_house.launch`ファイルを起動します。
RVizを起動し、ロボットの位置とレーザースキャンを表示するようにしてください。
---
(2) 地図サーバ(`map_server`)のノードを実行し、先ほど構築した地図をパブリッシュしてください。
(注意:この時点でRVizで地図を表示しようとすると、mapフレームとodomフレームの間から変換がないというエラーが表示されます。この変換は自己位置推定ノード(amcl)によって提供されます。)
---
(3) AMCL(パッケージ`amcl`内のノード`amcl`)を実行します。
RVizに地図とパーティクル群の表示を追加してください。ロボットを移動させて、ローカリゼーションがうまく機能することを確認してください。レーザースキャンが地図の障害物(壁など)と一致する必要があります。
RVizでは、「2D Pose Estimate」ツールを使用して、現在のロボットポーズを設定することができます(`initialpose`トピックにメッセージが送信されます)。試してみてください。
---
(4) `/global_localization`サービスを呼び出して、グローバル位置推定を実行してみてください。パーティクルに何が起こるかに注意して見てください。
グローバル位置推定がうまくいかないことがあります(例えば、初期化の時にどのパーティクルもロボットの近くに配置されない可能性があります)。その時はグローバル位置推定をもう一度開始してください。
---
→ [課題](v5_task.html)
← [実習その1](v5_1.html)
↑ [ホームページ](index.html)