【入門編】Jetson nano×TAMIYA×Donkey Carで安定した自動走行までの軌跡。

#はじめに

この記事は、[AI RC Car Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ai-rc-car) 20日目の記事です。
![IMG_20191109_182309.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/ea7a8132-782c-6772-6514-8a4e36d5ce96.jpeg)

ある飲みの席で、「面白いものがあるんですよ！」という魅惑の一言をいただき、
はじまった私のDonkey Carライフ。
走るようになるまでの流れや、Maker Faire Tokyoや走行会などを経て、
少しずつブラッシュアップしたところを書き留めます。

★セットアップ方法やソフト的な部分などは、イベント・走行会での生の声や、以下のサイトを参考にさせていただきました。
基本的にはこちらのサイトの情報で、走らせることができています。
・[FBグループ　AIでRCカーを走らせよう！](https://www.facebook.com/groups/2249059025382644/)
 ↑イベント情報、新ネタ、Q&A等々。まずはここから。
・[FaBo DonkeyCar Docs](https://faboplatform.github.io/DonkeyDocs/)
 ↑キットを使用したセットアップ、走らせるまでの流れなど。
・[DonkeyCar　Docsサイト](https://docs.donkeycar.com/) 
 ↑DonkeyCarをラズパイからJetson nanoに変更する際に、特にセットアップでお世話になりました。
・[FaBo Store（日本）](https://fabo.store/)
 ↑キット、車体や部品入手ならこちら。

##First Donkey Car
Tesla?Waymo?DeepRacer?自動運転といえば、そんなイメージしかなかった私には、DonkeyCarの敷居の低さ（シンプルさ）と楽しさは衝撃的でした。
![IMG_20190615_153911.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/da86571b-d601-38fc-e137-a4c5395aa22c.jpeg)

やることといえば、
1.教師データーの取得（ラジコンを走らせる）
2.人が走らせた際の画像・ステアリング・スロットル値をもとに、学習データーを作成(ここが肝)
3.学習済みデーターを使って自動走行
の３ステップ。
この中に単純ではあるが、「畳み込みニューラルネットワーク」などの機械学習の基礎要素が隠れている。深く考えずに肌感覚でテクノロジーを味わえる・流れを知れるところに、大きな魅力があると思っています。

まずは、入門キットを買って走行会に参加しました。
テキストエディタすら普段の生活に全く出てこない日常を過ごしているので、流れ通りにやるのも精いっぱい。１回目では、走らせるところまでたどり着けませんでした・・・。
予習（基礎的なところで、各種ツールの操作・学習の流れ・wifi周り(wpa_supplicant)・myconfig.pyの内容・各学習モデルの特徴など）を行い、２回目の走行会で初めて自動走行を実現出来ました。
![IMG_20190615_160719.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/fdac71e5-f4c8-eb8f-cd54-160e39cff408.jpeg)

良くも悪くも操縦者の癖を反映して走るところに、ワクワク感と愛おしさ（？）を感じ、はじめてから３ヶ月でどっぷり沼にハマってしまいました。

##Donkeyくん　バージョンアップの軌跡
###コントローラーのプロポ化
Maker Faire Tokyoに参加する際に、会場内参加者の大量なWi-Fi機器の影響で干渉が起き、同じ2.4Ghz帯で通信しているコントローラー（F710）がノーコンになる可能性が出てきたため、FM帯を使用する古いラジコン用プロポを準備し、挑むことにしました。

####Arduinoって・・・万能！
![IMG_20190729_203259.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/334efbe8-101f-b7d3-8599-9503b546dab5.jpeg)
走行会やFBグループにて情報をいただき、プロポ->受信機で送られてきた信号（PWM）をArduino leonard（同様にHID機能があるMicroでも可）を使ってUSBジョイスティック化する方向で動きました。
「？」の連続でしたが、諸先生方に聞いたりトライ＆エラーを経て、めちゃくちゃなスケッチかもしれませんが、なんとか信号の認識に成功。
（後に、教えていただいたサーボのレスポンスアップ技、「pulseIn」から「Pin Change Interrupt」をつかったスケッチに変更。サーボの動きがスムーズに。）

####Maker Faire Tokyo開場後しばらくして・・・F710コントローラーの動作が怪しく…。
![IMG_20191215_114104.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/d2163d85-be6d-9f4a-2fa4-89be9257fedc.jpeg)
プロポ化はテスト走行する余裕もなかったので、まずは王道のUSBコントローラーF710で
チャレンジ。
始めの頃は問題はなかったが、徐々にコントローラーの挙動が怪しくなってきました。教える（ラジコンを走らせる）ことができなければ、自動運転もままならないので、FMプロポに変更。誤作動も無くプロポの使いやすさも相まって、安定の走行に。

###Jetson Nanoの活用
####colaboratoryでの学習ができません！
コントローラー問題が解決したのも束の間。学習のために使うGoogleの仮想マシン上Python実行環境「Google Colaboratory」への接続が不安定になり、エラーを吐き出す状態に。
（のちに伺った情報だと、参加者が一斉に学習を進めたことで、同一IPよりColaboratoryへの
アクセスが増加したため、帯域が絞られたのではないかという状況）
次なる方針として、学習も含めてスタンドアローン化できないかと考えるようになりました。
以下理由で、Jetson Nanoの採用を検討しました。
・Raspberry Piより余力があるので、高速走行に耐えられるのではないか。
・スタンドアローンで学習が完結できると、環境（ネットワーク・クラウド）に左右されない。

####打倒！Jetracer
![IMG_20190803_104144.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/1a3b23e5-bac0-0058-cfcb-388ce0cbc9df.jpeg)
Maker Faire Tokyoで快走していた、Nvidia謹製「Jetracer」のスムーズな走りが頭から離れず、あんなふうに走らせたい・・・という気持ちが強くなりました。
方針として、「ハードはJetracerベースで、あわよくば同ハードでDonkeyも楽しみたい」という方向になりました。
（Jetracerとdonkey carでは学習の仕方が異なるため、どちらも楽しみたく）

###TAMIYA 1/10シャーシの活用
GitHubのJetRacer docsではタミヤTT02なのだが、手に入ったのがタミヤTB05というシャーシ。
ちょうど良くシャーシの一部が、3Dプリンターで作るベースボード(Jetracer用)と、穴の位置調整だけでネジ止めできそうだったので、そのままTB05を使うことに。
![IMG_20191215_224859.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/1ecc2a61-6528-2529-57f6-36289d1aafa0.jpeg)

####試作機（２号機）
とりあえず、操作しやすいようにアクリル板に全部乗せてみました。
![IMG_20190831_234346.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/ba45c6ab-7c44-da63-4e56-dbacb16c06de.jpeg)
手始めに使い慣れたdonkey carのシステムとJetson Nanoの組み合わせで。
[DonkeyCar　Docs](https://docs.donkeycar.com/)のサイト通りにインストールしたところ、とりあえず挙動は正常の様子。自動運転も安定していて、好印象。だが・・・。

####やっぱりボディをつけたい！
ロールバーがついたDonkeyくん１号機はなんとなく“ずんぐりむっくり”でよい感じだが、２号機は重さも含めてイマイチ感が残る。
走行会に参加されていたNSXボディのAIカーがかっこよくて・・・。
そうだ、ボディをつけよう。
![IMG_20191020_002421.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/299efd15-9c6c-72a3-9612-ab1f785d449c.jpeg)

####３Dプリンターってすごい！
３D出力サービスをいろいろ見てみたが、いかんせんお高い。
プリンターを買って作ったほうが後々安く上がりそうだったので、評判の良い安めのプリンターを導入。ホットベッドの高さ調整が大変だったり、周囲の温度変化に弱かったりとポイントはいっぱいあるものの、比較的スムーズに出力できました。
（ソフトの使い方は０から勉強しつつ・・・）

形あるもの、なんでも作れちゃいますね。３Dプリンターって。
本当に凄い。

・Jetson Nanoのベースプレート
![IMG_20190923_084650.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/345f6074-9673-8e26-a17a-80942fc7cc66.jpeg)

・カメラステー（ボディとうまく合わせられるよう作成）
![IMG_20191215_114137.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/e17ca1fe-45d7-69f7-88fe-ec480da0b7d5.jpeg)
ボディをつけたことで、カメラケーブルの脱着が必須になってしまったため、フラットケーブルをHDMIに変換する基板を採用。少しは脱着に強くなったはず。
・[CSI to HDMI Cable Extension Module](https://www.arducam.com/product/arducam-csi-hdmi-cable-extension-module-15pin-60mm-fpc-cable-raspberry-pi-camera-specific-pack-2-1-set/) ←Amazon等で買えます。

####緊急停止させたい！
スピードアップを目指すと、怖いのがドンキーくんにありがちな大暴走。
せっかく多チャンネルプロポを使うので、ボタンを割り当てて緊急停止ができるようにすることに。
Jetracerで使用するサーボ マルチプレクサーを使い、ESCへの信号をプロポでダイレクトにカット（接続されているマスターと無接続のスレーブをプロポの信号で切替）できるように配線を行いました。反射神経さえ鍛えれば、マシンを壊さずに済むかもしれません。
![IMG_20191215_114305.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535934/b974fdc9-3b77-a119-7497-c21441930e1e.jpeg)


####学習をJetson Nanoで行ってみる。

・Jetson Nanoでの学習
そのままでは学習が最後まで完走できなかったので、myconfig.pyを２行変更。

```myconfig.py
BATCH_SIZE = 64          
CACHE_IMAGES = False

```

その後、10W(MAXN)モードで学習開始。

```bash
# 10Wモードに（走行中は5Wモードに）
sudo nvpmodel -m 0

#＜指定タブ＞
python ~/mycar/manage.py train --tub <tub folder names comma separated> --model ./models/mypilot.h5
#＜全タブ＞
python ~/mycar/manage.py train --model ~/mycar/models/mypilot.h5

```
・稼働状況を見たいときは・・・。
メモリーやGPU使用率など稼働状況を見る際は、jetson-statsを事前にインストール。

```bash
#jetson-statsのインストール
sudo -H pip3 install jetson-stats

#学習中に別窓でこちらを実行
sudo jtop
```

・学習結果はmodelsフォルダーに保存されるので、あとは走るだけ。

```bash
#5Wモードに変更
sudo nvpmodel -m 1

#自動走行
python manage.py drive --model ~/mycar/models/mypilot.h5
```

プログラム起動後、ブラウザで
IPアドレス:8887で車両にアクセス


画面の
model & pilot→Local Pilot (d)を選ぶと自動走行開始。
model & pilot→User (d)を選ぶと自動走行停止。
その後、CTRL+cでDonkeyCarを停止。

-------

nanoで学習を行うと10000レコードで１時間かかったりと問題はあるが、とりあえずは安定して走る状態なので、次の課題としてソフト面でのアプローチ（他の機械学習モデルや各種センサー活用や最適化）、ロボットアーム装着などに挑戦してみたいと思います。

#ドンキーカー通じて、現在まで学べたこと。
・３Dプリンターの使い方(CAD・ツール・プリンター本体など)
・Arduinoの使い方。
・機械学習の入り口知識
・世界と日本のAIに対する関心度の差
・ラジコンの操縦
・散財する楽しさ

#さいごに
2019年は折角面白いものに出会えたので、これから深く掘って見たいと思います。

とりあえず、なんとなくでも走ってしまう懐の深いDonkeyくん。
走行会で機械学習を肌で感じましょう！