「えんとつむらのぷぺりん」の自律移動に関して記載する.
いかにスムーズに移動して,有利な状況で敵に遭遇できるか
具体的に言うと
「周回スピードを極力上げ」フィールド上のマーカを取得しながら「敵に追いつき」,自機体のマーカを取られるリスクを抑えながら,敵機体のマーカを取得する
ことを目指した.
どうせみんな時計回りで移動していくでしょう,という前提あり.
基本的には,上記フィールド平面図における 経由地をスムーズに通り抜けれるかがすべて なので
以下のやったことはこの対策になる.
- 高分解能の地図生成
- 自己位置推定手法の選択とパラメータ調整
- 経路生成手法の選択とパラメータ調整
- 周回する際の waypoint の設計と調整
- stuck してしまった場合の対策
これらについて簡単に説明する.
運営から navigation するための地図が既に与えられていたが,分解能が低い(= 占有格子地図の1グリッドのサイズが大きい).
経由地をスムーズに通り抜けるには,もう少し分解能を上げる必要があると考え,高分解能の地図を gmapping ( http://wiki.ros.org/gmapping ) を用いて作成した.
分解能を上げすぎると(特に実機で)処理が重くなるので,上げればいいってものではない.
自己位置推定には,みんな大好き LiDARを用いた AMCL : adaptive Monte Carlo localization ( http://wiki.ros.org/amcl ) を選択.
パラメータ調整したのは,以下だけ.
- 初期位置と初期姿勢の分散値(デフォルトの launch ファイルには項目がないので追加が必要)
実機の際に,運営のみなさんが丁寧かつ慎重にロボットを置いてくださるとは思いながらも,どうしてもずれてしまうときがあるので,particle を広めにばらまいておこう,という考え.
経路生成の手法も navigation stack のデフォルトのものを使用.
Global Planner : global_planner ( http://wiki.ros.org/global_planner )
Local Plannner : DWA ( http://wiki.ros.org/dwa_local_planner )
他の手法も検討したが,動的障害物が少ない(敵機体だけ)ロボコン環境では,上記で十分かなと考えた.
パラメータ調整したのは以下.
厳密に言うと,「経路生成の」というよりは「move_base や costmap の」パラメータ調整だが,今回はまとめて.
- controller_patience
- recovery behavior 実行前に,制御入力(cmd_vel)が送られてくるのを待機する時間
- デフォルトよりちょい短めに設定
- max_planning_retries(デフォルトの launch ファイルには項目がないので追加が必要)
- 経路再生成を何回行うか
- デフォルトは上限なしのため,回数を設定
- clearing_rotation_allowed(デフォルトの launch ファイルには項目がないので追加が必要)
- recovery behavior で回転を許可するかどうか
- 許可しない,に設定
- 理由はもちろん,敵機体の近くで不用意にその場旋回すると,敵に大量得点を与える可能性が高いため
設計思想としては
「ごちゃごちゃ悩むくらいだったら,早めに stuck 状態(= ABORTED)になってくれ」
あとで出てくる,stuck した際の対応があれば,stuck は大体脱出できるので,
周回スピードを極力上げたかったから.
デフォルトの move_base の状態遷移だと,(当たり前だけど)stuck 状態(= ABORTED)になるまで結構粘る.
そんなの待ってられない(せっかち).
- obstacle_range
- obstacle_range 以下のオブジェクトは障害物としてみなし,costmap に反映
- obstacle_range は costmap の一辺の半分が良いとされている(ほんまかは知らんけど,割とうまくいく気もする)ので,その値に設定
- raytrace_range
- raytrace_range 以上の長さを検出したら,そこまでの間をクリアする(= 障害物は何もない)
- raytrace_range は obstacle_range + 0.5 に設定
- robot_radius
- ロボットの footprint
- 実際の外形よりちょい小さめに設定
- inflation_radius
- 障害物から影響を受ける距離
- デフォルトより小さめに設定
- cost_scaling_factor
- 障害物から上記 inflation_radius まで指数関数的に減衰しながら影響を受けるが,その減衰具合
- デフォルトよりかなり大きめに設定
設計思想としては
「とにかく経由地をスムーズに通り抜けたい」
デフォルトの設定だと,経由地はなかなか安定して通り抜けることができない.
ただただ試行を繰り返して調整するのみ.
どれくらい刻むべきか,具体的に言うと
マーカ取得に関係しない waypoint をどれくらい置くか
が重要になると思う.
ただ,置き過ぎも都度到着判定が入り結果として周回スピードが落ちるため,最小限の数に.
やることはすごい単純で
もう一つ先の waypoint に強制的に移動させる だけ
基本的に stuck するのは決まって経由地なので,経由地の waypoint をキャンセルして,
次の waypoint に向かわせるだけ.
次の waypoint への経路が生成されると,途端に動き出せるようになることが多い.
結果としてどのチームよりも 周回スピードを保ったまま安定して自律移動ができた から優勝できた,と思っている.
やっぱり当たり前だけど,自律移動ロボットは自律移動がすべて で,ここがままならないと戦略は何の意味もない,というのを再認識できた.
自律移動以外にも優勝できた要因があるので,簡単にだけ.
- Judge server を利用した効率的な移動
- LiDAR による敵検知
Judge server にはリアルタイムでのマーカ取得状況が保存されており,ロボット側から Judge server にアクセスできる.
そこで考えたのが
2週目以降は,敵に直近で奪われた(奪い返された)マーカを取りに行く
というもの.
目的は以下2つ.
- 効率的にマーカを取得したいから
- 2週目以降も1週目と同様,すべてのマーカを取得する周回コースにしてもいいが,自分が既に取得しているマーカを繰り返し見に行くのは意味がないため
- 敵に近づきたいから
- 「敵に直近で奪われた」というのがポイントで,敵がある程度そのマーカ付近にいる,という予想がつく
振り返ると,2つ目の「敵に近づきたいから」というのが結構効果的だったと思う.
点群を愚直に使っての敵検知.
obstacle_detector 使おうかな,とも考えたが,動的障害物が少ない環境なので,点群で判断する簡単な方法で十分と考えた.
特にPD制御のゲインを細かく調整した,ということはないが,実機においても結構安定して敵検知ができていたと思う.