ETロボコンシミュレータを作ってみた！

本記事は、ETロボコンAdventCalender2017の22日目のエントリです。

#経緯
はじめまして。私は、2010年～2013年のETロボコン参加者で、現在はETロボコン東京地区実行委員2年生です。
去年から自分の興味でETロボコンシミュレータを作っていたところ、東京地区Unity部ができて、東京地区大会でシミュレータのブースを設置させてもらえたり、ETロボコンランキングサイトのTOP画像に使ってもらえたり、地区大会やCS大会で競技説明動画として一部利用してもらえたりしました。ありがとうございました！
今回は、そのETロボコンシミュレータの開発について記事にさせていただきました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/224412/fb8f3a00-b5f9-a77e-5501-903b5e127c25.png "(上)ランキングサイトTOP, (真ん中)東京地区大会でのUnityブース設置, (下)競技説明動画")

>[ETロボコン2017ランキング](http://etroboranking.azurewebsites.net/)
>[ETロボコン2017　デベロッパー部門プライマリークラス競技説明](https://www.youtube.com/watch?v=N-Hb3cFr5f0)
>[ETロボコン2017　デベロッパー部門アドバンストクラス競技説明](https://www.youtube.com/watch?v=9Gm0AOVyUwc)

私がETロボコンに参加していた年は、走行体はEV3ではなく、NXTの時代だったので、EV3を使って開発した経験がありません。EV3で開発してみたいなーと思っていても、お金の問題で個人では購入できなくて。だったら自分で作って遊んでみようと思ったのが、ETロボコンシミュレータ開発しようとしたきっかけでした。最初は、ここまで大きなものになるとは思っておらず、久しぶりにライントレースできればいいや！くらいの気持ちで開発していました。

#ETロボコンシミュレータで実現できたこと
ざっくりと何ができるようになったかをまとめてみました。
遡って調べてみたら2016年7月頃に開発を始めていて、気が向いたときや時間があるときにちょっとずつ進めて、1年ちょっとの期間で下記のことが実装できました。本気で頑張っていたのは4カ月ほど・・・？

**走行体関連**

- 走行体（HackEV、EV3way-ET）の再現
- モータ、ホイールの再現
- 各種センサ（ライトセンサ、カラーセンサ、ソナーセンサ）の再現
- （補助ありの）倒立走行
- ライントレースで走行
- 自己位置推定で走行
- アーム、尻尾の制御
- JOYスティックで操作

**コース関連**

- コース
- ゲートと難所（ブロック並べ、ET相撲、階段、ルックアップゲート、ガレージ）
- 新幹線
- コース上のその他オブジェクト

**その他**

- 通信機能（2人で競走）
- ゲート、難所の判定
- VR化

![image.png](https://qiita-image-store.s3.amazonaws.com/0/224412/53b83a46-7807-f503-fa00-f354fc63eb6f.png "ETロボコンシミュレータ")

#何を使って作ったか？
今回、ETロボコンシミュレータを作る手段として

- 3Dモデルを作成するのに**Blender**
- テクスチャやその他画像を作成・加工するのに**GIMP**
- シミュレータ化するのに**Unity**

を使いました。それぞれのツールを選んだ理由を軽くまとめておきます。

###Blenderについて
3DのCGを作るソフト！

- **無料**で使える！（オープンソース）
- 無料にしては機能が豊富
- いろんな形式にエクスポートできる（fbxしか使ってないけど）

###GIMPについて
画像を編集するためのソフト！

- **無料**で使える！

ので使用しましたが、絵を描くツールはたくさんあるので、絵が描ければGIMPじゃなくてもいいです。

###Unityについて
本来はゲームを作るソフト！

- **無料**で使える！（誰でも使える！プロも使ってる！）
- 作ったものをいろんなプラットフォームで動かせる
- 3D物理エンジンがプログラミング無しで使える
- アセットストアで効率UP（誰かが作ったリソースやプログラムを利用できる）

重要だったのは3つとも無料で利用できるツールであることと、操作が簡単なことでした。
BlenderもUnityも、仕事では扱ったことがない私でも扱えるレベルのツールたちです。DirectXのAPIをC言語から直接叩いてゲームを作ったこともありましたが、3Dを表示したりアニメーションさせたりするのに1000行近くもコードを書く必要がありました。そこにUnityを使うことで1行もコードを書くことなく表示や実行することができます。すごく楽！

#シミュレータを作ってみよう！
ETロボコンシミュレータの開発の中でポイントになった部分を簡単に説明します。

**①Blenderでロボットの3Dモデルを作成する**
立方体のメッシュを置いて、サイズを変えたり、切り取りしたり、位置を調整したりを繰り返して、ロボットになります。サイズや部品の位置は手元に実機が無かったので組み立て図を見ながら目分量で作りました。
3Dモデルを作る際のポイントは、ロボット本体とホイールやアーム、尻尾などの可動部分を別パーツに設定しておいたり、それぞれのパーツの原点を適切な場所（回転の中心など）に設定しておくと、Unity上で動かすのが楽になります。
このあと、テクスチャを設定したら、ファイルをfbxでエクスポートして完了です！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/224412/124a0b66-b08b-0d2f-4700-08d02c563410.png "blenderで作ったEV3way-ETとHackEVの3Dモデル")

**②ロボットとコースをUnityにインポートして表示する**
表示するまでは簡単で、ほぼドラッグアンドドロップの操作だけで実現できます。

**③ロボットに物理処理の機能をつける**
Unityを使うことで、重力や衝突判定などの制御はすぐにできます。
ただ、ホイールの制御がかなり面倒くさかったです。初めはWheelColliderを使って動かせる？と思っていました。が、ETロボコンの走行体は自動車のホイールのように左右に向きを変えるわけではなく、ロボット本体に対して常に垂直に固定されたまま、左右どちらかのホイールが回転することで進みます。
そのため、初めはスクリプトでコースが黒だったら右のホイールを、白だったら左のホイールを回転させたように見せて。走行体の位置は、ETロボコンでよく使っていた自己位置推定を使って制御していました。
この頃に、ロボットの3Dモデルを東京地区のAさんに提供したところ、AさんがHingeJointを使ってモータの動きを再現できることを発見しました。それからは本当の意味で物理演算を使えるようになって、かなりいろんなことができるようになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/224412/9d7c0253-9083-67e2-a8b9-28cf035b5b6c.png "UnityのHingeJointでモータを再現できた")

**④ロボットにカラーセンサなどの機能をつける**
カラーセンサやソナーセンサの作り方は検索したらたくさんヒットしたので、そんなに苦戦はしなかったです。

**⑤ロボットを動かしてみる**
あとは、動かして直して、トライアンドエラーでした！
ロボットの重量の制御や、位置リセット機能、難所の自律走行など大変だったり面倒だったことがたくさんありました。デバッグしていると、なぜか走行体がバラバラに破裂したり、走行体が空高く跳んで行ったり、新幹線が走行体を押しのけるほど強かったり、現実では起こりえないことが発生して。解析や修正を放棄したエラーもいくつかあったような。

#残った問題たち
**走行スピードの高速化**
今回、ラントレースなどで走行することはできましたが、走行スピードを上げると、ホイールが空転する現象が発生しました。原因は、走行体やホイールの重量や摩擦力のパラメータ調整がうまくできなかったことと、ホイールの弾力がなかったことかな？

**倒立振子の再現**
ジャイロセンサが今回は実現できなかった（する気がなかった？）です。ジャイロセンサができれば、倒立振子を作って試してみたかった・・・。
モータを独立したオブジェクトにできればジャイロセンサも実装できそう？でしたが、ソースやプレハブの管理が雑すぎて、構造を整理できずに開発を断念しました（笑）。初めから作り直せばできそうだけど、やる気が・・・。やっぱり設計は大事です。

**シミュレータの活用先**
今回作ったシミュレータで、**もしETロボコン参加者だったら何に使えるか**を考えてみましたが、有効な活用方法が思いつきませんでした・・・。チームで走行戦略を考えるときに、実機無し（プログラム無し）で動かしてみて情報共有できる。くらい？
東京地区大会でシミュレータの展示をしているときに、参加者に活用法を聞いてみると、シミュレータで動かしたプログラムをそのまま実機に入れて走行できればデバッグの手間が省けるのでは？との意見がありました。が、今回はプログラムをすべてUnityで作ったため、実機を使う場合とは制御が全く異なるものになった部分があり、難しそうでした。Unityと実機との間にMATLABみたいなソフトを利用すればできるかな？

#最後に
Unityで本格的なアプリケーションを作るのは初めてで、分からないことだらけでした。ETロボコン参加者OBとしては残念ですが、今回は曖昧な目標だけで開発が進んで、設計は全く行わずに開発しました。来年も何か別のものを作りたいと思っていますが、今度はちゃんと計画・設計して。
今回、シミュレータを作ったことで自分が今年得たものはかなり大きかったです。ETロボコンもそうですが、一つの開発を最初から最後まで自分たちだけで行う経験は貴重だと感じました。