2021年12月20日月曜日

ショートカット走行中の自己位置推定について (ロボトレース)

 この記事はマイクロマウス Advent Calendar 2021の20日目の記事です.昨日の記事はそらさんの全日本学生マイクロマウス大会2021(リアル大会)の感想でした.リアル大会は色々な方と交流できていいですよね.私も三月の全日本大会が楽しみです.

 今回は,ロボトレースのショートカット走行に必要な要素の一つである自己位置推定について,私が実装している方法を紹介します.


追記:今のところスマホ版では数式が正しく表示されません.PC版を見るか,脳内で数式をレンダリングしてください.たぶん解消されました.数式の表示にはMathJaxを使用しています.

ショートカット走行と自己位置推定

 ショートカット走行はロボトレース競技における上級者向けの技術課題の一つです.ロボトレースはラインを辿る速さを競う競技ですが,機体の一部がラインにかかってさえいればラインを忠実にたどる必要はありません.ラインとは別個に最速経路を生成し,走行することができれば大幅にタイムを短縮することができます.このようなショートカット走行の実現に向けた取り組みは少なくとも約10年前から存在し,近年では様々なコース形状についてショートカット経路を生成・走行しようとする競技者もちらほらと現れています.しかし,直線中のシケインのような単純なケースを除けば,実際の大会でショートカット走行を成功させている競技者の数はまだ多くありません.

 ショートカット走行の難しい要素の一つとしてショートカット走行中の自己位置推定が挙げられます.どんなに素晴らしい目標経路が生成できていたとしても,自己位置推定が誤っていればロボットは目標経路と全く異なる場所を走り,コースアウトします.そのためショートカット走行で完走するためには正確な自己位置推定が必要不可欠なのですが,外部のカメラなどから情報を取得することを許されていないロボトレースにおいてこれを実現することは容易ではありません.自立したロボットの自己位置推定方法として,ロータリーエンコーダやジャイロセンサなどの計測値を数値積分して自己位置を求めるデッドレコニングがよく知られています.しかし,数値積分は計測誤差が蓄積するため,長いコースをデッドレコニングだけを頼りにして走りきることは(少なくとも上位勢を意識した速度域では)不可能です.累積誤差を補正する方法として,コーナーマーカーやライン形状のパターンを特徴点(ランドマーク)として利用する方法が考えられます.もし,ショートカット走行中に検出された特徴点と一走目に記録したマップの中の特徴点の対応付けを行うことができれば,対応付けられた特徴点同士の位置ずれをなくすように位置推定結果を補正することができます.しかし,ロボトレースで広く用いられている一次元的なラインセンサはラインもマーカーもただの白い点として検出するため,特徴点の検出・対応付けを行うことは容易ではありません.そのため,自己位置推定はロボトレース競技者がショートカット走行にチャレンジする上での大きな障壁になっていると言えます.

 この記事では,ラインセンサのみを用いて,比較的単純な方法でデッドレコニングの累積誤差を(主に横方向とヨー角について)補正する方法を紹介します.正直なところ,本当にそれでいいの?という部分もあるのですが,完走実績のある方法ではあるので,ショートカット走行中の自己位置推定で悩んでいる方のヒントになればと考え,公開します.

ショートカット走行中の自己位置推定
ロボットの姿勢とラインの検出位置

デッドレコニングに基づいて計算されたライン検出位置と実際の位置の差
 図のように,差動二輪の足回りと一次元的にライン位置を検出するセンサを搭載したロボットを仮定します.このロボットの姿勢は旋回中心の座標 $(x, y)$ および進行方向 $\theta$ で表され,これらはデッドレコニングによって$(\hat{x}, \hat{y})$ および $\hat{\theta}$ のように推定されているとします.また,ロボットの旋回中心からみた相対的なラインの位置 $(t_s, n_s)$ がラインセンサによって計測されており,ラインの形状は一走目に正確に記録されていると仮定します.$(t_s, n_s)$ と記録したライン形状のつじつまが合うように $(\hat{x}, \hat{y}, \hat{\theta})$ を補正することがここでの目標になります.

 もし,ラインセンサが今検出しているライン上の点と一走目に記録したライン上の点の対応関係がわかっていれば,デッドレコニングに基づいて計算されたライン検出位置
$$\hat{x_s} = \hat{x} + t_s \cos\hat{\theta}  - n_s \sin\hat{\theta} \,, $$
$$\hat{y_s} = \hat{y} + t_s \sin\hat{\theta}  + n_s \cos\hat{\theta} \,, $$
と実際のライン位置$(x_s, y_s)$ のずれをなくすようにデッドレコニング結果を補正すればよさそうです.しかし,実際には対応関係は未知なので,この方法をそのまま使うことはできません.代わりに,私のロボットでは $(\hat{x_s}, \hat{y_s})$ のライン上における最近傍点 $(x_n, y_n)$ を用いて,最小化するべきずれ $E$ を.
$$E = \frac{1}{2}\left(\hat{x_s} - x_n\right)^2 + \frac{1}{2}\left(\hat{y_s} - y_n\right)^2 \,, $$
のように計算しています.($\frac{1}{2}$は後の式を見やすくするための係数なのであまり気にしないでください.)

 ずれ $E$ を定義したので,あとはこれを最小化するような $(\hat{x}, \hat{y}, \hat{\theta})$ を求められればよいのですが,ここでもう一つ問題になるのが$E$を最小にする $(\hat{x}, \hat{y}, \hat{\theta})$ の組み合わせは無数に存在するということです.この解の曖昧さを真面目に解消しようとすると,複数の時刻の対応関係を利用したICPのような感じになると思いますが,私のロボットではより簡易的な方法で補正量を決定しています.具体的には,制御周期ごとに $E$ の $(\hat{x}, \hat{y}, \hat{\theta})$ に関する勾配
$$\frac{\partial E}{\partial \hat{x}} = \left(\hat{x_s} - x_n\right)$$
$$\frac{\partial E}{\partial \hat{y}} = \left(\hat{y_s} - y_n\right)$$
$$\frac{\partial E}{\partial \hat{\theta}}=(\hat{x_s}-x_n)(-t_s\sin\hat{\theta} - n_s\cos\hat{\theta}) + (\hat{y_s}-y_n)(t_s\cos\hat{\theta} - n_s\sin\hat{\theta})$$
を計算し,勾配の大きさに基づいて $(\hat{x}, \hat{y}, \hat{\theta})$ を
$$\hat{x}  \leftarrow \hat{x} - a \frac{\partial E}{\partial \hat{x}} \,,$$
$$\hat{y}  \leftarrow \hat{y} - a \frac{\partial E}{\partial \hat{y}} \,,$$
$$\hat{\theta}  \leftarrow \hat{\theta} - b \frac{\partial E}{\partial \hat{\theta}} \,,$$
のように更新しています.ただし, $a$ と $b$ は補正の強さを決める定数です.要するに,勾配降下法のような感じで $(\hat{x}, \hat{y}, \hat{\theta})$ を制御周期毎に少しずつ補正しています.本当にこの方法でいいのか(安定しているのか,真値 $(x, y, \theta)$に収束するのか) は未検証ですが,とりあえず,今のところこの方法で完走できています.

実装

 私のロボットでこの処理を実装している部分を以下に示します.2018年の全日本大会以降,私のロボットではずっとこの方法を使用しています.


おわりに

 この記事では,ショートカット走行中の自己位置推定について,私のロボットに実装している簡易的な方法を紹介しました.ロボトレースでショートカット走行にチャレンジしている方やマウスでユニークな経路を走ろうとしている方の参考になれば幸いです.

 明日の記事はhmsn_stsさんのギヤ発注にお時間を要した話(共有)です.私も最近トレーサの足回りを作り直したいと考えているので,内容がとても気になります.お楽しみに!

2021年12月17日金曜日

関西地区大会

 はロボトレースに出場して2位でした。自宅コースではたまに一走目でコースアウトしていたのでちゃんと走るのか心配でしたが、会場では特に不安定な様子はなく、むしろ太陽光をものともせずに走っていました。自宅コースはたわみやでこぼこがひどく、安定性のテストにはちょうどいいのですが、劣悪すぎるテスト環境というのも考えものだと最近感じています。

今回の大会に合わせてショートカット経路生成の移植を行ったことで、2019機体の走行が再現できたことになります。次の目標は純粋な走行速度の向上ですが、どこまで上げられるでしょうか…


大会のアーカイブ動画:



2021年9月12日日曜日

2021ロボトレース

2021年現在制作中のロボトレーサです.


スペック

全長:???mm
幅:???mm
高さ:??mm
重量:???.?g
バッテリー:BETAFPV Lipo 300mAh 45C 3S
マイコン:STM32H743VI
モータ:Maxon DCX10L 4.5V×2
モータドライバ:TB6614FNG×2
ダウンフォース用モータ:???
ロータリエンコーダ:ENX10 EASY 1024IMP×2 + 自作エンコーダ
ラインセンサ:TPR-105×24
IMU:ICM20649×2

ハードウェアの特徴(前作比)

マイコンをより高性能なものに変更.

デッドレコニングのためのセンサ類を強化.

タイヤがたくさん.

ソフトウェア

今のところ前作とあまり変わりません.というより未実装の部分が多いです.将来的には主に位置推定の精度を向上させたいと考えています.

ショートカット経路生成

適当な頂点と辺を考え,グラフの最短経路問題として解きます(未移植).

kyamashita5/robotrace-shortcut-path (github.com)

軌道追従制御

Kanayama の tracking control method

位置推定

基本的にデッドレコニングですが,ラインの位置を利用した角度・横ずれの補正も行います(未移植).

2021年2月21日日曜日

ロボトレースのショートカット経路生成

 お久しぶりです.


ロボトレースのショートカット経路生成方法のリポジトリを作りました.

https://github.com/kyamashita5/robotrace-shortcut-path

説明はまだあまり書けていませんが,とりあえず公開します.

2020年1月25日土曜日

マイクロマウスのゴール突き抜け

自分のマウスは,斜め走行の際にゴールの入り口で止まらずにそのまま直進し続けるようになっている.大抵の場合ゴールの中で止まるが,進行方向に壁がなければゴールを突っ切って行けるところまで進む.斜め直進でそのままゴールを突っ切るのは珍しいということで2018年の学生大会で特別賞を貰ったりもした.

ゴールの斜め突っ切り.まだ進めるのに途中で止まっているのはそれ以上進む必要がないと判定しているから…だとかっこいいが,実際はその先の部分を最速経路に無関係な袋小路と判定して探索していないだけ.

で,理論も実装も比較的単純なこの機能についてなぜ急に語りだしたかというと,導入した目的を書いておこうと思ったからだ.ゴールの突き抜けはタイム短縮のための機能だと解釈されることが多い.ゴールの入り口で止まらず突き抜ければ減速の開始を遅らせることができ,僅かではあるがタイム短縮が期待できる.確かにそういったご利益もあるのだが,自分はどちらかというと完走率を上げる効果に期待してこの機能を入れている.

マイクロマウスでは機体全体がゴール領域に入らないと記録として認定されない.ゴール入口で止まるようになっていると,タイヤの滑りなどによって走行距離が少し縮んだだけでもゴールの手前で止まってリタイアになってしまう.ゴールを突き抜けるようにすることで,あまり実装の手間をかけずにこのリスクを低減することができる.

マイクロマウスは探索にしろ二次走行にしろ完走そのものの難易度が高い.ハードウェア性能やシステム全体の完成度を高めることももちろん大事だが,ちょっとした工夫を色々仕込むのも大会で実力を出し切るためには大事だと思っている.

2020年1月22日水曜日

ロボトレースのコース記録

ロボトレース競技のコース記録について,よく使われる方法と自分のマシンの記録方法について紹介します.どのようにコースを記録するべきかはマシンのコンセプトによって変わると思いますが,何らかのヒントになれば幸いです.

コース記録とは

ロボトレース競技ではコース情報の記録・活用が重要です.ロボトレースでは3回まで走行を行うことができ,最も速い1回のタイムで順位が決まります.1走目で記録したコース情報を2走目以降に利用することが認められており,直線では速く,コーナーでは滑らないように減速するといった賢い走りをすることがタイム短縮の鍵となります.グリップの限界ギリギリを攻めた走りをするためにはコース形状の正確な把握が必要になります.

ロボトレース競技のコースの例.様々な曲率・長さの区間がある.スピードを出しすぎるとコースアウトしてしまうが,スピードを落としすぎるとタイムロスになる.良いタイムで走破するためには各区間で出せる速度を見極めなければならない.


マーカーを使ったコース記録

よく用いられるコース記録方法として,マーカー間の走行距離と角度変化を記録する方法があります.ロボトレースのコースには曲率変化点の左側にマーカーが配置されており,マーカー間の区間は曲率が一定の円弧または直線になっています.区間長と曲率は各区間の形状を表現するのに必要十分な情報であり,この2つを各区間について記録すればコース形状を記録したことになります.区間長についてはロータリーエンコーダを使えば計測することができます.曲率については,区間の始点と終点でのマシンの角度(向き)の変化をロータリーエンコーダやジャイロセンサで記録すれば,(曲率)=(角度変化)/(区間長)という関係を使って求めることができます.この方法は各区間について区間長と曲率だけを記録すればよく,メモリ容量の少ないマイコンでも実装することができます.しかし,マーカーを1つでも読み飛ばすと実際とは大きく異なる曲率が計算されてしまいます.また,区間長が短い場合はラインと走行軌道の違いやマーカー検出位置と曲率変化位置の違いが無視できず,正確な曲率計算は困難です.

マーカーを使わず密に曲率を記録する

コース全域について密に曲率を記録するというアプローチもあります.走行軌道の曲率はマシンの並進速度と旋回角速度(ヨーレート)から求めることができます.センサで計測した並進速度と旋回角速度をもとに各地点での曲率を求め,そのまま全て記録することでコース形状に関する密な情報が得られます.メモリの使用量が多いのがこの方法の欠点ですが,最近のマイコンはRAMサイズが大きいのでこの点はあまり気になりません.


コースを2次元点列として記録する

自分のマシンではコースの2次元的な形状をそのまま1cm間隔の2次元点列として記録します.走行中,マシンはデッドレコニングによってスタートからの相対的な2次元位置を計算しています.このマシンの位置もとに今センサが見ているラインの2次元的な位置を計算し,マシンが1cm移動するごとに記録します.二次走行ではこのコース情報を使って経路計画や位置推定を行います.



2019全日本大会における自分のマシンのコース記録結果.(スタートとゴールが少しずれているのはデッドレコニングの累積誤差のため.)


走行軌道ではなくライン形状を記録する

自分のマシンのコース記録では旋回中心とラインセンサの位置のずれの補正を明示的に行っており,走行軌道ではなくラインの形状を記録しています.ロボトレース競技のラインは曲率変化点で曲率が不連続に変化し,完全に追従することはできません.そのため,マシンの旋回中心が描く走行軌道とラインは少し違います.この差分を補正する計算を行うことで,コース形状をより正確に記録することができます(ライン位置がラインセンサで正確に検出できていれば,ですが).ちなみに,上位のマシンの中には,センサ配置や制御の具合を調整してライントレースの走行軌道自体を少しショートカットっぽくしているものも見受けられます.

マシンの走行軌道を記録するべきか,ラインの形状を記録するべきかは二次走行の戦略によって変わると思います.ライントレースそのものをショートカットっぽくして二次走行で加減速によるタイム短縮のみを行うのであれば,走行軌道を記録した方が無駄な減速をせずに済むでしょう.一方,私のマシンのように二次走行で一走目と全く違う軌道を走るのであれば,ラインの形状そのものを記録した方が位置推定などに利用しやすいと考えています.



2019年12月17日火曜日

2019RT テクニカルデータ

大会時にテクニカルデータとして登録したもの.

ロボット名:
F2P
メカニズム(機械):
製作者名:
製作期間:2週間
自分自身で設計したオリジナルです
ハード(電気):
製作者名:
製作期間:1週間
自分自身で設計した回路を主にプリント基板で作りました
ソフト:
製作者名:
製作期間:4ヶ月
自分自身で作ったオリジナルプログラムです
CPU:
系列 : ARM系
メーカ名:STmicro
CPU型番: STM32F4
動作周波数: 84[MHz]
ROM 1.024 [MB] / RAM 320 [kB] / Data Flash 0 [kB]
バッテリー【CPU関係】:
種類・数 :LiPo / 2 [セルor本]
使用電圧(公称電圧):7.4[V]
容量:300 [mAh]
メーカ名:Turnigy
バッテリー【モータ関係】:
CPU関係と共用
モータドライバICの型番やメーカ名など:
DRV8835(Texas Instruments)
走行(推進)用モータ:
DCモータ
2(個)
メーカ名や型番:FAULHABER 1717-003SR
走行用以外のモータ 1:
用途:ダウンフォースのためのプロペラ
DCブラシレスモータ
4(個)
メーカ名や型番:1103
走行用以外のモータ 2:
無し
センサ(種類、個数、メーカ名):
赤外線センサ:28(個)
メーカ名や型番、用途や特徴 :TPR-105F / ラインセンサ(反射光量をAD変換)
ジャイロセンサ:1(個)
メーカ名や型番、用途や特徴 :MPU6500(TDK) / デジタル値出力型
エンコーダ:2(個)
メーカ名や型番、用途や特徴 :AS5050A(ams) / デジタル値出力型
動輪(車輪の個数と寸法):
2[輪]
直径:26.5[mm]
幅:12[mm]
補助輪(車輪の個数と寸法):
無し
ロボットの寸法:
長さ:150[mm]
横幅:240[mm]
高さ:35[mm]
重さ:135[g]
ロボットの操舵機構:
左右(2輪)速度差方式
運動性能:
直進時の最高速度 [m/s]
最高加速度 [m/s/s]
ターン時の最高速度 [m/s]
開発ツール:
マイコン統合環境やコンパイラなどのツール :
   GCC

機械CAD、基板CADなどのツール :
   Fusion 360, kicad
探索アルゴリズム:
トレース コース記憶あり
ロボットPR:
2次走行では最速経路の走行(いわゆるショートカット走行)を目指す.
- ライントレース的な制御は一切しない.ラインと異なる目標経路に追従するよう制御する.
- 経路生成を無理矢理グラフの最短経路問題に落とし込んで最速経路っぽいものを得る.
- 記録したコースマップから推定されるライン位置と実際に観測したライン位置のずれをもとにオドメトリによる自己位置推定を修正.
自己PR:
二次走行が完走したら嬉しいです.
ロボット製作の目的、大会参加目的:
ポイント獲得,実戦テスト
競技参加歴、成績(ロボット名):
競技会参加歴:5~9年目
マイクロマウス経験:3年目
トレースロボット経験:5~9年目
2015年:
2016年:
2017年:
2018年:
備考: