概要
近年, マイクロマウスで流行っている軌道追従について自分が行っているKanayama Control Method をもとにした制御の話をしていきます.
はじめに
この記事ではこの半年, 論文を読んで自分なりに試行錯誤して実装した話を書いています.
タイトルには独立2輪車型のロボットと書いてありますが, 実装は私が作っているマイクロマウスで行っています.
実装するモチベとしては, 「ロボットを複雑な軌道に対しても追従できるようにしたい」, 「再現性のある動きをさせたい」, 「マイクロマウスに出てくる壁が無くても走れるようにしたい」 といった感じで, 「めっちゃ速く走りたい」 といったものではないのでご注意.
本文
前提
まずは制御対象を以下のように扱います.
ロボットの状態は絶対座標での位置と姿勢を表していて, $V$はロボットの並進速度, $w$はロボットの角速度になります.
ここでは入力として$V,w$を与えています. ここで, $V,w$ と $x, y, \theta$の間では以下の関係が成り立っています.
\begin{eqnarray}
\begin{array}{ c }
\dot{x} =V\cos\theta \\\
\dot{y\ } =V\sin\theta \\\
\dot{\theta } =w
\end{array}\
\end{eqnarray}
今回の目標は目標軌道にロボットを追従させることです.
軌道と経路の違いや, 軌道に追従させるとは何かという話はidさんやTokoroさんがこちらのブログで説明しているので, そちらを見てくれると分かりやすいと思います.
独立二輪車型ロボットで目標軌道に追従する制御をする①
軌道と経路の違い | Tokoro’s Tech-Note
実装はこちらの論文を読んで行いました.
A stable tracking control method for an autonomous mobile robot
こちらの論文をざっくりと読むと, 軌道とのズレをコントローラーの入力にフィードバックすることで, 目標とする軌道との誤差が0に漸近収束するという内容です.(正直これは私が説明するよりも読んでみたほうが理解がしやすいと思います)
自分の現在位置を$P_c$, 目標の点を$P_r$, そして誤差を$P_e$とした際に, 以下の関係が成り立ちます.
\begin{equation}
P_{e} =\ \begin{bmatrix}
x_{e}\\\
y_{e}\\\
\theta _{e}
\end{bmatrix} =\begin{bmatrix}
\cos \theta _{c} & \sin \theta _{c} & 0\\\
-\sin \theta {c} & \cos \theta {c} & 0\\\
0 & 0 & 1
\end{bmatrix}( P{r} -P{c})
\end{equation}
図に表すとこんな感じです. (こちらは論文の図を参考に描いております)
そして, コントロールへの入力は以下のようになります.
ここでは$V_r$を目標並進速度, $w_r$を目標角速度としています.
\begin{equation}
\left(\begin{array}{ c }
v\\\
w
\end{array}\right) =\left(\begin{array}{ c }
V_{r}\cos \theta {e} +K{x} x_{e}\\\
w_{r} +V_{r}( K_{y} y_{e} +K_{\theta }\sin \theta _{e})
\end{array}\right)
\end{equation}
ここで,
- $x_{e} ,\ y_{e} ,\ \theta _{e} $: ロボット座標系から見た目標点に対する誤差
- $V_{r} ,\ w_{r} $: 目標並進速度, 角速度
- $K_{x} ,\ K_{y} ,\ K_{\theta } $:パラメータ
となります.
さて, ここまでで軌道追従に必要なものは出揃いました.
ここで私達がマイコンの上にプログラムとして落とし込む上で次のことを考えなくてはいけません. すなわち,
- どのように軌道をロボットに与えるか.
- 経路上のどこを目標とするか. (軌道を表す点列の中でどれを目標とするか)
といったことを考慮していく必要があります.
これは様々な実装方法があり,
- 弧長パラメータを使ってオフラインで軌道を生成し, それを追いかける.
- 予め$V_r,w_r$をある値に設定してシュミレーションを行い, その結果として得られた$x,y,\theta$とともに, 時系列情報として$x,y,\theta , V_r, w_r$を構造体に入れる.
などの実装方法があります. しかし, 前者は近似式を求めるのがめんどくさい, 後者は決められた目標並進速度と角速度でしか走ることができず, 気軽にパラメーター上げができない, といった問題があります.
一長一短のそれぞれの実装方法ですが, 私は最もシンプルな
目標角速度を与えて一定間隔で点列を作り, その点列群の$x,y,\theta$情報をマイコンに構造体でもたせる
という実装方法を行いました.
以下では私の実装方法について書いていきます.
実装
前段階
前段階の処理として, 軌道の点列を生成する必要があります.
私はけりさんがブログに上げているMATLABコードを使いました.
MATLABでスラローム軌道生成 KERI’s Lab
|
|
出力はこんな感じになります.
そしてこれをマイクロマウスの最短走行に使われる全ての軌道について生成しました.
種類としては, 大回り90度ターン, V90, 135度ターン, 180度ターンについてそれぞれ生成しています.
スクリプトの最後でdlmwrite関数を使って1mm間隔で$x,y,\theta$の点列データを作成します.
マイコンでの実装
先程得られた点列の$x,y,\theta$のデータをMATLABでファイルに書き込んだものをコピーしてきて, 構造体の初期化をするところに直接突っ込みます.
構造体に入れやすいようにデータをファイルに書き込む, いっそCコードをMATLABから生成するのがおすすめです.
ここから, 実際にプログラムを書きていきます. 制御周期を1ms, 追いかける軌道を5msで更新します.
方針としてはわりかし単純で
- まず, 軌道追従の最初の点を目標の点として現在の自己位置との誤差を計算し, (3)式に代入してモーターへの入力を与える.
- 5msごとに5msの間の並進方向の速度の積分をとって, 次の目標点を考える.
例えば, 5msの間1000mm/sで動いてたなら, $1000m/s * 0.005s = 5mm$より, 前回の目標点より5つ先の点列を目標点として与える.(軌道は1mm間隔でとってるの5つ先) - 次の目標点と自己位置との誤差を計算して, また(3)式に代入する.
- 2.3.を繰り返す.
イメージとしてはマリオカートで眼の前にいる最速タイムを出しているゴーストを追いかけているという感じです.
以下がイメージ図です.(右下は雅号です. 気にしないでください)
実装としてはこんな感じです.(変数が宣言されてなかったりしてますが, 方針を示しているだけなので気にしないで下さい)
ただし, 私の座標系はこのようになってるので, 速度コントローラへの入力($e_x$)につく符号が違ったりしています.
|
|
ロボットのソースコードはGitHubにあげているので参考にしてみてください.
src/mazesolver.cpp辺りです.
Dangoromouse
するとこんな感じに走ります.
走っているロボットはシステム同定をした際のロボットです. 詳細はこちら.
NigLacerto
『速いマウスを作る』『自己位置を推定する』「両方」やらなくっちゃならないってのがシステム少女のつらいところだな。覚悟はいいか?オレはお布団。
— イェーイ (@dango_bot) November 27, 2018
(スリップ角を考慮して自己位置を推定したら良くなった pic.twitter.com/Yw2dgm2TCd
マイコン内部のデータをプロットした結果, このようになりました. オレンジが目標軌道, 水色と黄色が自己位置です.
以下, 軌道追従をした所感です.
所感
走行がセンサーに対して敏感になる.
自己位置を推定してそれに頼って走ることになるので, 壁にぶつかる, タイヤが空転すると自己位置がおかしくなり, 即座に走れなくなります.
外界センサーを使って位置を直すにしてもやはりそれでもセンサーに対して敏感になってしまいます.
高速化するとスリップ角を無視できなくなる.
上述のツイートでも書いてますが, スリップ角が生じるとそもそも, 自己位置を正しく取れなくなります.
自己位置の推定にスリップ角の概念を導入しないと全く別の場所を走ったりするようになってしまうので注意です.
ロボットが突然速くなるわけではない
上述の理由より, 軌道追従をしたからといってマウスが速くなるわけではないです.
正確に, そして速く走るためにも自己位置を正確に推定することが大切のように思えます.
ターンの終わりなどで振動する & パラーメータの選定がよく分からない.
Kanayama Control Method は上で見たとおり, 実装はとても簡単なものになりますが, 論文内でも漸近安定までしか証明できてないせいか. 軌道に追従するものの, 遅かったり, 振動してしまうように感じます.
今の私の実装では, (3)の式の角速度の項に位相補償するものを付け加えてほんの少し改善したかと思います.
ただ, 私が正しく(3)式に出てくるパラメータを選べなかった, そもそもハードの作りが甘かった等の問題があるので, 今後も調べていきます.
しかし, マイクロマウスの競技上, 速度をかなり上げて走らせてるので, ロボットがターンするときに1G以上かかるみたいな事がない分には十分に追従していくと思います.
まとめ
軌道追従はこんな感じになります. 色々と改善点はありますが, 軌道追従の一番の魅力は軌道さえ生成できればその通りに走る事と再現性のある走りができる事じゃないんかなと思います.(ロボトレースとかでやるとすごく面白そうですが, 私はロボトレースをやる気運はないので誰か頼む)
今後はこちらのブログで紹介されている線形化フィードバックを作った後に, 軌道追従コントローラーを作って軌道追従をさせたいかなと思いました.
独立二輪車型ロボットで目標軌道に追従する制御をする②
最後に元気に軌道追従で走る私のマウスの動画を貼って終わりにしたいと思います.
全日本大会行くぞい pic.twitter.com/zXH3NKBJn7
— イェーイ (@dango_bot) November 30, 2018