全日本大会と2017年度のまとめ
Tweet2017年マイクロマウス全日本大会に出場し、オカリナを演奏してきました。 この記事は大会の色々と今年のまとめです。
全日本大会
マイクロマウスのクラシック競技エキスパートクラスにMIZUHOv2で出場しました。
去年クラシック競技のフレッシュマンクラスで完走(決勝出場)できたので、今年からはエキスパートクラスです。
結果
決勝出場 18位 + 特別賞
特別賞の副賞として、米が貰えました。
大会でオカリナを吹く
一番やりたかったことです。 決勝でオカリナスタートによる最短走行をしたときの動画はこちらです。
2017年度の実績
工大祭MATLABものつくりコンテスト
MATLAB TA賞を頂きました。
MATLABを用いて制御系の設計やシミュレーションを行ったことが評価されました。
東日本地区大会
完走し、斜め走行なしの最短走行はできました。
中部地区大会
完走すらできませんでした。
全日本大会
予選の最短走行中にギアが割れるアクシデントが発生しました。 探索走行の記録しか残せませんでしたが、ぎりぎり決勝に進めました。
決勝では斜めなしの最短走行が成功し、18位+特別賞でした。
MIZUHOv2まとめ
MIZUHOv2で使った技術的なことをまとめていきます。 今回だけでは書ききれないので、ここでは構成要素の概要だけ書きます。 そのうちこれらの項目について詳細にブログに書いていく予定です(3月までには)。
ちなみに機体のハードウェア的な部分については以前少し書いているので、こちらもご覧ください。
機構
マウンタもホイールも3Dプリンタ(DMM アクリルUltra)で作っていましたが、 ギアの歯が変な形だったり、アクリルなのですぐ割れるということが起こりました。 実は全日本の予選の走行中にもギアが割れてしまいました(最短走行中に引っかかってフェイルセーフで停止した)。 予備を用意していたので次の日の決勝はどうにかなりました。
壁センサ用のLEDマウンタも3Dプリンタ(部室 ABS)で作りました。 こちらは基板との固定方法を工夫することで、左右のセンサの傾きや位置をしっかり揃えることができました。
回路
壁センサの回路と信号処理の方法は、去年力を入れて取り組んでました。 今年も去年と全く同じものを使いました。 非常にいい出来です。
詳細については前作のMIZUHOのGithubのREADMEと、ロ技研内での報告会用に作った資料に書いてあったのですが、 このブログには書いてなかったので、そのうち書きます。
機体とは別に、機体を区画の中央に置くための冶具を3Dプリンタで作ってみました。 これは大会当日に壁センサーのキャリブレーションを行うために作りました。 冶具のおかげでいつも同じ場所にマシンを置けるようになり、 正確なキャリブレーションを手早く行うことができました。
制御
こんな感じの構成でやりました。
速度制御
以前マイクロマウスの機体を同定し、モーターへの入力電圧から機体の並進回転速度までを線形システムとしてモデリングしていました。
このシステム同定によって機体を線形なモデルとしてモデリングしていたので、MATLABを使って簡単に制御系を組むことができました。 具体的には2自由度のPIDコントローラを使い、各制御パラメータはMATLABのPIDTunerによって最適化しました。
マシンのモデルを得たことで、まずPC上で制御のシミュレーションができるようになり、 さらに制御パラメータの最適化もできたというのが今年度最大の成功だと思っています。
ちなみに、同じロ技研であるマキニスタもちゃんと機体のモデルを使ってMATLABでシミュレーション、制御系設計を行うことで開発時間を減らせると言ってます。 日本一のチームの言うことなので正しいでしょう。
ロボコン初優勝をはたした東工大ロボット技術研究会チーム「Maquinista」の秘密 ~MATLAB/Simulinkをフルに活用して開発期間を短縮
軌道追従制御
目標軌道(xr(t),yr(t),θr(t))(時間関数であることが重要)に機体を追従させる制御をすることで、マシンを走らせていました。 目標軌道は探索アルゴリズムから生成されるものです。
よく独立二輪の制御(位置に関する制御)は難しいといわれていますが、それは非線形システム(特に非ホロノミック拘束を受ける系)であるからです。 これについてはところさんのブログにも日本語で正確に分かりやすく書いてあります。
難しいことには変わりないのですが、 目標位置(点)に行く制御と目標軌道(時間関数)に追従する制御ではまた難しさがかなり違ってきます。 今回やりたいのは目標軌道に追従する制御であり、実はこっちの方が簡単です。
今回は入出力を線形化する非線形フィードバックを用いることで目標軌道に追従する制御系を組みました。
探索アルゴリズム
シミュレーター上で動かした動画がこちらになります。
最短経路の計算
マウスの状態(位置と機体の向き)をノードに、エッジに動作(ターンや直進)の重みをもつグラフを定義し、普通のA*で最短経路の計算を計算しています。
探索アルゴリズム
次のアルゴリズムで探索をしていました。
- 足立法でゴールに向かう
- ゴールに到達したら以下の3~5を繰り返す
- 未探索壁は通れるものとして最短経路を計算する
- 最短経路上の未探索壁を列挙する
- 4で列挙した壁のある区画をゴールとして足立法で壁を見に行く
- 最短経路上の未探索壁がなくなったらスタートに戻る
全ての区画を見に行かなくても、最短経路を見つけることができるはずです。
シミュレーターとテスト
上の動画にもあるGUIはQtで作っています。 実際の迷路(過去の迷路)で動くかを検証するために作りました。
これとは別にGoogleTestを使ってunit testも作ってみました。 あらかじめ作った入力データ(テストケース)に対して、想定通りの出力が得られるかを自動でチェックすることができます。 また、GUIでのシミュレーションがある意味全ての機能を統合したテストであるのに対して、 unit testではベクトルの計算部分や迷路データの更新といった機能一つ一つをテストしていきます。
テストケースを書くのが大変でしたが、どこで不具合が生まれているのかわからないだとか、 ある時点で生まれたバグ(まだ発動してない)が相当後になってから発動するといったことはかなり減りました。
CMake
CMakeを有効活用しました。 探索アルゴリズムの本質部分は静的ライブラリとしてビルドしておき、 QtのコードとリンクすればGUIのシミュレーターに、 GoogleTestとテストコードとリンクすればテストに、 コマンドラインで探索をシミュレーションするコードとリンクすればCLIのシミュレーターに なるというものを簡単に実現できました。
また、CMakeは簡単にクロスコンパイルもできます。 マイコン(STM32F4)用の簡単な設定ファイルを作ることで、 マイコン用の静的ライブラリを作ることもできます。
PC上で完璧に検証してからマイコン上で動かすというサイクルで効率的に開発を進めることができました。
オカリナの音を認識する
会場が盛り上がる最高の機能です。 やっていることは割とシンプルで、マイクから取った音をフーリエ変換し、音階を判定しているだけです。 音階の判定は、聞こえた音の周波数成分のうちで最もパワーが大きい周波数をドレミに直すということをしています。 音のピーク周波数しか見ていないので、オカリナ以外の楽器でも認識します。
マイクはSPM0405HD4Hというものを使いました。 マイコンからクロックを送ってやるとPDM信号(デジタル)で出てくるので、それを読み取って復号します(ローパスフィルタを通すだけ)。
おわりに
オカリナが目立っていますが、個人的には技術的に色々な挑戦ができた一年だったと思います。 また、それらを机上の空論ではなくてちゃんとマシンに実装し、マシンをエキスパートクラスの決勝に行けるくらいには走るようにできたこともよかったです。
来年に向けて、まずは今年やったことをブログにちゃんとまとめていきます。
おまけ
表彰式の時、突然オカリナを全員の前で吹くことになりました。 表彰式の間もNVSさんがカメラを回していたので、youtubeに上がっている動画を見てみました。 なぜかオカリナを吹き始めた瞬間SDカードでエラーが発生し、動画が途切れてしまっていました….