EurekaMoments

This is my studying logs about Autonomous driving, Machine learning technologies and etc.

書籍「SLAM入門」の読書録~システム概要編~

SLAM入門: ロボットの自己位置推定と地図構築の技術

SLAM入門: ロボットの自己位置推定と地図構築の技術

  • 作者:友納 正裕
  • 発売日: 2018/03/03
  • メディア: 単行本(ソフトカバー)

目次

目的

  • 書籍「SLAM入門」を参考に、SLAMシステムの全体構成について理解する。
  • サンプルコードを参考に、C++での設計思想について理解する

関連記事

www.eureka-moments-blog.com

www.eureka-moments-blog.com

SLAM問題

ロボットが自律移動するためには、地図のような環境の
モデルを事前に用意しておく必要がある。ただし、未知の
環境を探索するようなタスクを実行する場合は事前に
地図を持っておく事が困難であり、自己位置推定と地図
構築を同時に行うという問題が生じる。これをSLAM
(Simultaneous Localization and Mapping)問題と呼ぶ。

SLAM問題における不確かさ

ロボットの移動にはタイヤのスリップやモデル化誤差と、
センサによる周辺環境の観測にも雑音といった不確かさが
含まれる。
こういった不確かさが蓄積される事で自己位置推定の精度が
悪化し、それに基づいて作られる地図も正確でなくなると
いった問題が生じる。
そのためSLAMでは、こういった不確かさを影響を低減する
ような手法をとる必要がある。

SLAMにおける2種類のアプローチ

SLAMを実現する手法には、ベイズフィルタを用いる手法と、
最適化に基づく手法の2種類がある。

ベイズフィルタを用いるSLAM

不確実性のあるセンサデータを扱う際は、ベイズフィルタを
用いた確率的な自己位置推定・地図構築を行うのが主流と
なっている。
ベイズフィルタとは、ベイズの定理に基づく時系列フィルタ
を指す。カルマンフィルタやパーティクルフィルタがこれに
該当する。

カルマンフィルタについての分かりやすい記事
logics-of-blue.com

パーティクルフィルタについての分かりやすい記事
www.thothchildren.com

カルマンフィルタによるSLAM

SLAMで構築される地図とは、この図のような複数の
ランドマークq_iの集合として扱われる。
f:id:sy4310:20200624204832p:plain
それぞれのランドマークの状態変数は、
f:id:sy4310:20200624212338p:plain
であり、これらを観測するロボットの時刻tにおける
状態変数(姿勢)は、
f:id:sy4310:20200624212409p:plain
とする。この時、ロボットはn個のランドマークを
同時に観測するとして、これらを一つの状態変数
f:id:sy4310:20200624214538p:plain
にまとめる。
カルマンフィルタによるSLAMでは、ロボットの
位置と各ランドマーク位置の同時確率密度を
一つの正規分布で表現する事で、ロボットと
ランドマークの位置をまとめてカルマンフィルタで
推定できる。

パーティクルフィルタによるSLAM

推定したいロボットの状態を、複数のパーティクルと
いう仮説で表現し、それぞれの状態仮説に基づいて
地図を構築する。
この時、構築される地図上のランドマーク位置を
カルマンフィルタで推定する手法があり、それは
FastSLAM1.0として知られている。
また、パーティクルをばら撒く時に、それらを
観測寄りに撒きつつ尤度関数の分散を大きくする
事で、リサンプリング数を少なくなるように
工夫したのが、FastSLAM2.0である。
これらの詳細は、こちらの記事が図解もあって
分かりやすい。
qiita.com

最適化手法によるSLAM

カルマンフィルタによるSLAMでは、計算量が
ランドマークの数の2乗で増加し、パーティクル
フィルタによるSLAMでも大規模な地図になれば
パーティクルの数が増え計算量が増加する。

そのため、大規模な地図構築が必要とされる場合
は、最適化手法を用いたグラフベースSLAMという
手法をとるのが近年の主流である。

グラフベースSLAM

グラフベースSLAMのシステム構成は下記の
ようになる。

f:id:sy4310:20200625222248p:plain

このシステムは、逐次処理を行うフロント
エンドと、一括処理を行うバックエンドの
二つのパートに分かれているのが特徴。
これにより、それぞれの利点を活かした、
大規模な地図構築に適したシステムと
なるとされている。

フロントエンド

システム構成図におけるこの部分が
フロントエンド部分である。

f:id:sy4310:20200625223153p:plain

ここでは、観測されたセンサデータによる
地図の逐次生成を始め、データの対応付けや
ループ検出、ポーズグラフ生成を行う。

バックエンド

この部分がバックエンド。
ループ閉じ込みで必要となるポーズ調整、
地図の一括調整を行う。

f:id:sy4310:20200626203843p:plain

参考資料

こちらの記事が丁寧で良さそう。
後で読む。

github.com

qiita.com

サンプルプログラムの概要

「SLAM入門」では、2Dのグラフベース
SLAMを実行するC++プログラムを参考に
学習できるようになっている。

全体のクラス構成

縦の矢印はクラス間の呼び出し関係、
横の矢印は処理の実行順序を表している。

f:id:sy4310:20200626211724p:plain

Main関数の処理フロー

下記のコマンドで実行される。

LittleSLAM [-so] "Data file name" [Start scan index num]

データファイル名を与えなければ何もせずに終了。

-sオプションを付けると、SLAMは行わずに、
データファイルに記録されたスキャン点を描画する。

-oオプションを付けると、SLAMを行わずに、
データファイルに記録されたオドメトリデータと
スキャンデータに基づいて地図を作成する。

f:id:sy4310:20200626213629p:plain

SLAM実行部分

上記のmain関数内にあるこの部分が
SLAM実行部分となっている。

f:id:sy4310:20200626215216p:plain

SLAMの各種処理は全て"SlamLauncher"クラスに
集約されているので、このクラスのインスタンスを
main関数内で生成し、それが持つ実行メソッドを
呼び出している。

GitHub

今回の学習にて作成したサンプルプログラムの
UMLダイアグラムは、こちらのリポジトリで
公開済み。

github.com