タミヤMidnight PUMPKINをJetRacerにしてAI自動運転（ハードウェア編）

# はじめに
* DeepLearning
 * これまで全く触れる機会が無かったが、新型コロナウィルスによる自宅待機で時間がたっぷりできた。
 * いい機会なので、ここぞとばかりに[Jetson Nano](https://www.nvidia.com/ja-jp/autonomous-machines/embedded-systems/jetson-nano/learn-ai/)を購入しイチから勉強してみることにした。
* JetRacer
 * NVIDIAのサイトでいくつかの適用事例に市販のラジコンをベースにした[JetRacer](https://github.com/NVIDIA-AI-IOT/jetracer)なるAIカーがあったので、これを最初の目標に設定した。
* やったこと
 * 手持ちのラジコンを改造し、JetRacer化した。（公式のJetRacerよりいくらか少ない部品構成で実現）
 * 屋内の自然環境（床にテープとか貼らない環境）での自動運転に成功した。
 * とりあえずDeepLearningを手を動かしながら習得する、という流れを経験できた。
* 結構ボリュームがあるので、2回に分けて記載する。
 * 「タミヤMidnight PUMPKINをJetRacerにしてAI自動運転（ハードウェア編）」
 * 「[タミヤMidnight PUMPKINをJetRacerにしてAI自動運転（ソフトウェア編）](https://qiita.com/Nabeshin/items/1988aeae839305fdeb05)」

![IMG_2769D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/b1bee09e-9a9e-855c-74a4-a6cd52539ebc.jpeg)


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Jetson Nano 搭載AIカー、タミヤのMidnight Pumpkinの荷台にボードとカメラを積み、約100個のデータで転移学習させ、ついにお部屋を走れるレベルになった。コーナリングは丁寧めに学習させたら上手く曲がれるようになった。<br>楽しい！！ <a href="https://t.co/p7irMapyHl">pic.twitter.com/p7irMapyHl</a></p>&mdash; Nabeshin (@desmoquattro996) <a href="https://twitter.com/desmoquattro996/status/1253686770127892483?ref_src=twsrc%5Etfw">April 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# Jetson Nano で基礎学習
* 先ずはJetRacerを実現する上で必要な文献が理解できる程度に基礎知識を獲得する。
 * この辺りは[@Karaage0703](https://qiita.com/karaage0703) さんの「[Jetson Nano関係のTIPSまとめ](https://qiita.com/karaage0703/items/b14c249aa33112669ee4)」など、潤沢な情報を参照させて頂いた。
 * （もちろん[書籍](https://www.amazon.co.jp/Jetson-Nano超入門-Japan-User-Group/dp/4800712513)も購入させて頂き、効率的にJetson Nano特有の設定等を把握する事が出来た。）
* 今回購入したものは以下。

| 品名 | 説明 | 購入価格 |
|--------|--------|----|
| Jetson Nano | [Jetson Nano Developer Kit](http://akizukidenshi.com/catalog/g/gM-14393/) | ¥10,800  |
| 冷却ファン | [アクリルケースと冷却ファンのセット](https://www.amazon.co.jp/gp/product/B07VLXHZLF) | ¥1,280 |
| カメラ | [Raspberry PiカメラV2](https://www.amazon.co.jp/gp/product/B01F1SWTZE) | ¥3,580  |
| 電源アダプタ | [スイッチングACアダプター 5V4A AD-A50P400](http://akizukidenshi.com/catalog/g/gM-09594) | ¥900 |
| microSD | microSDカード(32GB以上) できれば2,3枚 ([今回はこれを使用](https://www.amazon.co.jp/gp/product/B078NQ5BQ5) ) | ¥600 |
| 2ピンのジャンパ | 電源プラグから給電するためJ48ヘッダに取り付ける[2.54mmピッチのジャンパーピン](http://akizukidenshi.com/catalog/g/gP-03888/) | ¥100 |
| USB WiFiドングル | 自分が持ってるのはBUFFALOの古いやつ（今はモデルチェンジしたっぽい） | ¥800 |

（全てのパーツが写って無かったので写真を差し替えました）
（電源アダプタは、最初に記載した「[24Ｗ級スイッチングACアダプター5V4A GF24-US0540 ](http://akizukidenshi.com/catalog/g/gM-09594/) （¥1,280）」より多少安価なものがあったのでリストを更新しました。）

![IMG_2829D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/b38f6cb1-ba07-ba18-c691-59cd761f19c8.jpeg)


* 冷却ファン
 * Jetson Nanoをフルパワーで動かすとヒートシンクが触れないくらい高温になる。
 * 自分はアクリルケースと5V冷却ファンのセットを購入して使っている。
* microSDカードは高速読み書き出来るものが必要
 * 何種類か別のものを試したが、かなり性能に違いがあった。
 * 差額は数百円なので、これは良いものを用意した方がいい。待ってる時間が勿体無い。
 * 自分は32GB＆1000円以下で買えるものを3種類試したが、[TOSHIBA製品](https://www.amazon.co.jp/gp/product/B078NQ5BQ5)が一番良かった。
* USB WiFiドングル 
 * Linuxで認識できるものであれば使えるはず。
 * 自分は昔、Raspberry Pi Zero(Wi-Fi付いてないやつ)で使っていた物があったので、それを使用している。
* 電源アダプタは余裕があるものが必要
 * Jetson Nanoを本来の性能をで動かすための「性能優先モード：MAXN」にするには、スマホ充電用の5V2A電源アダプタではNG。 
 * 5V2A電源アダプタで機械学習処理を走らせるといつまで経っても処理が終わらなかったり、固まったりする。
* 2ピンのジャンパ
 * ACアダプタの電源プラグから給電するためのモード変更用ピン。
 * J48ヘッダに取り付けることでmicroUSB給電から電源プラグ給電に切り替わり、「性能優先モード：MAXN」で動かせるようになる。

![IMG_2832D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/7ea0d686-3b95-c91d-c7be-663e6e1b4f86.jpeg)




* NVIDIAの無料教材[「Jetson NanoでAIを始める」](https://courses.nvidia.com/courses/course-v1:DLI+C-RX-02+V1-JA/about)
 * NVIDAの教材内のリンクから入手できるイメージを専用のSDカードに焼き、環境を構築する。
 * 教材はJupyterLabの「Jupyter Notebook」で作られている。
 * ハンズオン形式のチュートリアルになっていて、AIのトレンド解説から、カメラを使った分類モデル構築のための画像収集、ニューラルネットワークの学習と推論（指のThumbsUp判定、指の本数判定、顔の表情判定）まで、ざっくり勉強することができる。
 * WebブラウザからJupyterLabにアクセスし、シェルが打てたりインタラクティブにPythonコードが実行できたりする。
 * JetRacerの実行環境もこれで作られているので、使い方とか色々知っておくために、これもやっとくと良い。
 
![IMG_2601.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/568f948b-beb1-b890-2989-0948a605c9eb.jpeg)



# JetRacer
* JetRacer([https://github.com/NVIDIA-AI-IOT/jetracer](https://github.com/NVIDIA-AI-IOT/jetracer) )とは
 * NVIDIA が提供するJetson Nanoを使ったAI自動運転カープロジェクト
 * 市販のラジコンにJetson Nanoとカメラを搭載し、AIにカメラの画像を学習させ、リアルタイムでステアリング角度を制御する。
 * 高速で走るRCカーにカメラを搭載するため、高速フレームレートで処理できるように最適化されている。
 * Webブラウザ（JupyterLab）でインタラクティブな操作（学習、自動走行）が可能。
 * ハードウェアの部品リストと組み立て手順が公開されており、ベース車両はタミヤのTT-02かLatrax Rallyの２種類。
 * これもgithubからイメージを入手してSDカードに焼き、専用環境を構築する。
* 参考リンク 
 * JetRacerの組み立てについてはhygradme’s diaryさんの「[JetRacerの組み立て](http://yhrscoding.hatenablog.com/entry/2019/09/12/014006)」と言う記事がとても参考になる。


![IMG_2730D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/cbdda313-0294-a27b-551f-4a3ab3d2f734.jpeg)

ざっくり、JetRacerのJupyter Notebookのコードを読み解くと、
最終的な制御対象となるRCカーのステアリングとモータの制御は以下のように実現していることが分かる。

* ステアリング
 * DeepLearningのフレームを使い、車体のカメラ画像に人間が目標座標を教えて学習させる。
 * 上記の目標座標をもとに画像回帰で-1から1までのパラメータを出力する。
 * 最後にこれに適当なゲインをかけた補正値をサーボへのPWM信号として入力する。
* モータ
 * **モータはAIで制御しておらず、前進のみ。** 
 * 固定値をESC(Electric Speed Controller)へのPWM信号として入力する。
 * 固定値は、0が停止、1がフルスロットルだとして、最初は0.2とかでテストし、学習状況に応じて徐々にスピードを上げていく。


# Midnight PUMPKINをベース車両にする。
* 車体を組み立てるにあたっての課題
 * 公式の手順に従うと、タミヤTT-02(自分の場合はTT-01)の車体にJetson Nanoをマウントするパーツを3Dプリンタで出力する必要がある。
 * 筆者は、3Dプリンタを持ってない。。
 * 適当な厚みのアクリル板を切り出して同じような部品を作る必要があるが、かなりの手間と時間がかかる。。。
* Midnight PUMPKINをベース車両に採用（以下、購入時の箱の写真）
 * 幸い、我が家には息子がお年玉で買ったピックアップトラック型のラジコン（Midnight PUMPKIN）がある。
 * 絶対に壊さないことを前提に、息子に頼んでこちらを使わせてもらう事にした。
* **Midnight PUMPKINをJetRacer化するメリット**
 * ピックアップトラックなので、そのまま荷台にJetson Nanoが積める。（3Dプリンタ不要）
 * しかも荷台中央に最初から数センチ四方の穴が空いており、配線するための穴あけが不要。
 * ロールバーがあり、ここにカメラを固定できる。
 * タイヤが巨大なため、TT-02より走行できるフィールドが広い。かなりの段差も乗り越えられる。
 * 公式のJetRacerだとスペース的にボディが乗らないが、こっちはボディを付けたままで大丈夫。
 * TT-02と同じ540モータなので、性能はそんなに変わらない。


![IMG_1456.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/b70ce949-115e-e609-4d38-b6479e5b6a4b.jpeg)


![IMG_2806D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/3d81f9ec-3773-1959-d052-15171d168f25.jpeg)



# JetRacerの組み立て（TAMIYA Midnight PUMPKINベース）

* JetRacer化するために追加で必要なもの

| 項目 | 説明 | 購入価格 |
|---|---|---|
| ラジコン本体  | [タミヤ Midnight PUMPKIN](https://www.amazon.co.jp/gp/product/B000FBMR0A) | ¥8,621 |
| プロポ       | [タミヤ FineSpec 2.4G電動RCドライブセット](https://www.amazon.co.jp/gp/product/B0077K0WM2) | ¥9,054 |
| モバイルバッテリ | [Anker PowerCore 13000](https://www.amazon.co.jp/gp/product/B00Y05BQ9A) (5V3A 13000mAh) | ¥3,199 |
| USB電源ケーブル | 5V3A流せる十分太いもの | 自作 |
| PCA9685ボード | [PWM Servo モーター ドライバー](https://www.amazon.co.jp/KKHMF-PCA9685-16チャンネル-12-ビット-Arduinoに対応/dp/B078YRJ8D7)  | ¥299 |
| ~~マルチプレクサ（ボード）~~ | ~~[Pololu 4-チャンネル RC サーボ マルチプレクサー](https://store.shopping.yahoo.co.jp/suzakulab/pololu-2806.html)~~ | ~~¥1,232~~ |
| ジャンパケーブル 1 | [Jetson NanoからPCA9685にI2C接続するための4ピン（メス/メス）コード](https://www.amazon.co.jp/gp/product/B00YQZFSIO/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1)  | ¥139 (40本)|
| ジャンパケーブル 2 | プロポの受信機からPCA9685に電源を入れるための2ピン（メス/メス）コード  | 40本から切り出す |
| その他| カメラ固定用のFRISKケース、マジックテープ、Jetson Nano固定のスポンジ、輪ゴムなど | 数百円？ |

![IMG_2778D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/23cf23fe-9691-d7ed-d8fd-b234668e4193.jpeg)


以下、詳細。

* モバイルバッテリ
 * **学習時にJetson Nanoを「性能優先モード：MAXN」で動かすために5V3Aタイプが必要。**
 * JetRacerは最初にコースを学習させる必要があるが、ここで「低電力モード:5W」だといつまで経っても処理が終わらない。
 * 自動運転時であれば、「低電力モード:5W」限定で動かす事が出来るため、スマホ充電用の5V2Aタイプでも動く。
 * 自分は軽量化のため、本番走行用に別途、小型バッテリ「Anker Astro E1 5200mAh(5V2A)」を使っている。
* USB電源ケーブル(5V3A流せるもの)
 * （写真の右から２番目。一番右のケーブルだと細すぎてNG、電源制御回路が働いてUbuntuが起動しない。）
 * 電源ケーブルも十分太いものを選ぶ必要がある。
 * 細いケーブルだと3A流せないため、せっかく3A出力できるモバイルバッテリがあっても性能が発揮できない。
 * 自分は手持ちのUSBケーブルが全部細くてダメだったため、余ってた12V用の太いケーブルにUSBコネクタを半田付けして自作した。
 * ケーブルの太さは20AWG。秋月で買った電源アダプタのケーブルは18AWGなのでこの位の太さのケーブルが必要。
 * 市販のUSBケーブルでこの用途に合うものってあるのかしら？？
* PCA9685（ボード）
 * 16ch PWM Servo モーター ドライバー。
 * Jetson NanoからI2Cでステアリングとモータの2ch分の信号を送り、サーボとESC(RCカーのモータコントローラ)にPWM信号を送る。
 * Jupyter Notebookのコードは、adafruit_servokitライブラリをimportしており、これら2ch分の出力制御を行う。
* ~~マルチプレクサ（ボード）~~ （公式にはこの記載があるが、実は必須ではない。）
 * マスタ、スレーブの2系統の信号をSELECT信号で切り替える回路。
 * SELECT信号ONでマスタ優先になる。**つまり、信号は全部で3ch必要。**
 * **スレーブ：** Jetson NanoのAIからの制御信号（ステアリング、モータ）を入力する。
 * **マスタ：** RCカーのプロポからの制御信号（ステアリング、モータ）と、SELECT信号を入力する事でいつでもプロポで緊急停止したりできるようにする。
 * が、そもそも、タミヤで普通に購入するRCカー用のプロポ「FINESPEC 2.4G」は2chしかないため、この用途には使えない。
 * フタバには3chのプロポがあるみたい。
* その他
 * カメラはFRISKケースにM2のボルトナットで固定。


## マルチプレクサを使わない構成
* 3chのプロポとマルチプレクサが無い構成でJetRacerを実現する。
* JetRacerを動かすために必要な作業フェーズと、その時に制御を担う信号発生源との対応は以下。

| 作業フェーズ | ステアリング制御 | モータ制御 |
|---|---|---|
| 学習（トレーニング） | プロポ（手動） | プロポ（手動） |
| 自動運転（テスト走行） | Jetson Nano（自動） | プロポ（手動） |
| 自動運転（本番走行） | Jetson Nano（自動） | Jetson Nano（自動） |

* それぞれの作業フェーズでやることについては後で詳しく記載する。

## 車体の組み立て

* 今回、一旦以下の構成で「学習（トレーニング）」、「自動運転（テスト走行）」まで行った。
 * 「自動運転（テスト走行）」時は、ステアリングは完全にAIが行うが、前進は人間がプロポで操作する。
 * （十分AIが学習したら、配線を変えて「自動運転（本番走行）」にすれば良い。）
* 配線はこんな感じ。

![スクリーンショット 2020-04-28 9.27.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/a54b6786-5d97-0950-426d-c8a506c09d6b.png)

* RC_RECIEVER_XX はプロポ受信機
 * ラジコン組立後の状態では、RC_RECIEVER_CH1はサーボ、RC_RECIEVER_CH2はESC(モータ)につながっている。
 * これを、RC_RECIEVER_CH1だけ外し、サーボとPCA9685のLED0(出力0-15チャンネルのうち、0チャンネル)を直接つなぐ。
 * ラジコン組立後の状態では、RC_RECIEVER_BATはどこにもつながっていない。
 * これを、「ジャンパケーブル 2」を使いPCA9685（使ってないCH15のVCC,GND）につなぎ、サーボに駆動電源(9V)を供給する。
* PCA9685ボード
 * I2Cで16チャンネルのPWM出力が可能。
 * 回路図には「メインチップ」との接続以外が表現出来てないが、「PCA9685ボード」には電源が2系統あり、通常は入力信号用と、サーボ駆動用の電源を分けて使う。
 * 入力信号用の電源はJetson Nanoから「ジャンパケーブル 2」を介して供給される。
 * サーボ駆動用の電源は、通常緑色のターミナル端子から供給し、黄（信号）、赤(VCC)、黒(GND)の16チャンネル分のオスピンから各サーボに供給する。
 * 16本の赤(VCC)、黒(GND)ピンはそれぞれ電気的に繋がっているため、今回、部品点数を減らすため「ジャンパケーブル 2」でプロポ受信機から電源を供給している。

![IMG_2751D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/2c194d0a-bd66-9bd7-f3ef-a887b90940b5.jpeg)

* Jetson Nanoは、ラジコンのボディに傷が付かないように適当なスポンジを座布団として挟んで、輪ゴムで荷台に固定。
 * 本物のトラックみたいに、隠れた荷台の下側に何箇所か引っ掛けられる部位がある。
 * そこと引っ掛け、テンションかけた状態で固定する。
* 本番走行用の5V2Aモバイルバッテリをロールバーに固定。
 * 学習（トレーニング）させる際は、5V3Aのでかいバッテリにつなぐ。
 * （写真には掲載してないが、実はボディと車体の隙間にかなりの空間があり、でかいバッテリが綺麗に収まる。） 
* PCA9685は適当に脇の空いてるスペースに固定。
 * Jetson Nanoに接触してショートすると怖いので、適当なプラ板を挟んでおけば安心。
![IMG_2752D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/0396a72b-768a-22f4-64c3-09d643475745.jpeg)

* カメラはお馴染みのフリスクケースにM2のボルトナットで固定。
* 更にフリスクケースをダイソーで買ったマジックテープでロールバーにしっかり固定。

![IMG_2754D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/cf5acb0a-2caf-219f-da2b-62027754cf54.jpeg)

![IMG_2755D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/cd2a7693-52aa-aeac-8e07-f75833678474.jpeg)

## 「自動運転（テスト走行）」を実現
* 恐らく、これがJetRacerの最小構成である。
* 「ゼロから始めるが、少しでも費用を抑えたい」「タイヤがデカイ方が好き」という場合はこんな感じの構成になると思う。

![IMG_2759D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/0dc15de4-55ea-36d0-7107-897b50b1070e.jpeg)


#「自動運転（本番走行）」に向けてバージョンアップ

* 追加で「マルチプレクサもどき」を自作した。
 * Jetson Nano、プロポの２系統の信号をSELECT信号の代わりに2つのジャンパピンで切り替えることが可能。
 * 写真の黄色のジャンパピンを切り替える事でSELECT信号を代替する。
 * だいたい100円以下で作れる。

![IMG_2782D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/63f813c3-16d9-0df9-358c-e426c1e739a5.jpeg)

![IMG_2781D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/39164e13-62ed-e6b3-b348-565287dbf5fb.jpeg)


* これにより、モータ側にも信号が送れるようになり、「自動運転（本番走行）」が実現できる。
* 配線はこんな感じ。
 * 中央にあるのが追加の「マルチプレクサもどき」。
 * 追加で3ピン(メス/メス)のケーブルが４本必要となるので、前述の40本ケーブルから切り出して使う。
 * 一応、電源ON/OFFステータス表示用にLEDも追加した。ちなみにVCCは9V。
 * RC_RECIEVER_BATに電源を入れる必要があるかと思ったが、要らなかった。

![スクリーンショット 2020-04-28 19.56.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/a1df86da-e71d-3812-cf8f-7c8c7d8a83bc.png)


![IMG_2807D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/fdb6580d-d487-8446-6ef6-f260ac350e96.jpeg)

![IMG_2808D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/c5c505b5-7032-b753-0215-2097ca7f1e1b.jpeg)

![IMG_2809D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/a9469a91-daf3-37b6-44bf-2592d8cfc716.jpeg)

![IMG_2810D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/77037dd5-32d8-53dc-cc11-c26a41a4070b.jpeg)

![IMG_2814D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/4bc2a752-ba1a-04b0-f832-370395261f10.jpeg)

* 怪しい赤い物体は以前、近所の製作所の方からウレタン素材の切れ端を頂き、取っておいたもの。
* 座布団になるものであれば何でも良い。

![IMG_2813D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/b678fc31-9c40-f6bc-d8f0-9271fce170d6.jpeg)

* 「マルチプレクサもどき」とPCA9685とをつなぐ3ピンケーブル
 * 最初、スッキリするかと思って短いやつで試したが、残念ながら届かないので長い方に交換。

![IMG_2815D.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283854/82570467-3f3c-edd1-c420-1a0376a66000.jpeg)


* だいぶ話が長くなってきたので、今回はハードウェア編として一旦区切り、Jupyter Notebookの使用方法等については、その2（ソフトウェア編）として記載する。
 * [タミヤMidnight PUMPKINをJetRacerにしてAI自動運転（ソフトウェア編）](https://qiita.com/Nabeshin/items/1988aeae839305fdeb05)


# ちなみに
* NVIDIAのプロジェクトにもう一つ、JetBotというものがある。
 * https://github.com/NVIDIA-AI-IOT/jetbot
 * こちらは可愛い車体で、AIで衝突回避出来たり、対象追尾が出来たりするみたい。
* タイヤ&モータ2個とドライバ回路があれば良いので、パーツを工夫すればJetRacerに比べてかなり安価に出来そう。
* 価格と仕上がりの面で「[タミヤのカムロボ](https://www.tamiya.com/japan/products/70227/index.html) 」が使えると最高
 * とにかく動かすだけなら、すぐ組めそうだが、車幅がちと狭いのでJetson Nanoをどう美しく積むかが課題かも。
* そのうちトライしたい。