自由課題

学んだり、考えたり、試したりしたこと。

Jetson Nanoで自律走行ラジコンを作る(1)

「JetsonでFPVラジコンを作る」というシリーズ記事で、ラジコンにカメラを取り付けてbluetoothゲームパッドで操作できるようにした。
記事一覧はここ

今回からは上記の環境をベースにラジコンの自律走行にチャレンジしようと思う。現状システム(LunchJetと命名した)は以下のような感じである。

f:id:kimito_k:20210420072705p:plain

JetsonではDeep Leaningのフレームワークが使用できるので、DNNベースのモデルを実行する。
具体的には、車載カメラの映像と人間が操縦している際の制御値(ステアリングの方向やアクセル強度)をそれぞれ入出力とした教師あり学習のモデルを作成するつもりでシステムを組組んでみるつもりである。

f:id:kimito_k:20210505052059p:plain

汎化性能次第ではあるが、まずはライントレーサーのラインなし版ができれば上出来といったレベルではないだろうかと思っている。何をするにしてもまずは訓練データが必要なので、カメラ映像と対応する制御値をJetson内に収集する機能から作り込んでいくことにする。

現時点のソフトウェア構成は以下。矢印はデータの流れを表している。
<<gst-element>>はGStreamerのエレメントである。

f:id:kimito_k:20210505111508p:plain

現時点では、momoによりカメラ映像を配信する処理パスと、ゲームパッドの入力を元にモーターを制御するパスの2系統が存在する。

これを以下のようにする。

f:id:kimito_k:20210513053008p:plain

図が少しややこしくなったように見えるが、要は右下のRC car serverにカメラ映像を入力して、訓練データとしてラジコンの制御値と画像を所定のディレクトリに保存するようにしただけである。

めでたくモデルが出来上がって推論できるようになったら、ゲームパッドの代わりにモデルから出力された制御値をつかってラジコンを制御する。

これを実現するために、カメラ画像のストリーム上流(左側)にteeを挿入し、カメラ映像のストリームを複製して解像度やフレームレートを落としつつRC car serverに映像を入力する。その上で、RC car server上に実装を加えれば訓練データをJetsonのSDカードに保存できる(はずである)。

なお、teeの直後のqueueは分枝した2つのストリームを別スレッドで並列に動作させるために必要となる(Gsteamerのチュートリアルを参照)。

上記のデータフローを実現するGStreamerのコマンドは以下となる。かなり長くなった。

$ /usr/bin/gst-launch-1.0 -v nvarguscamerasrc ! 'video/x-raw(memory:NVMM), format=NV12, width=1280, height=720, framerate=30/1' ! tee name=t
 ! queue ! nvvidconv flip-method=2 ! 'video/x-raw, format=I420, width=1280, height=720' ! identity drop-allocation=1 ! v4l2sink device=/dev/video1
 t. ! queue ! nvvidconv flip-method=2 ! videorate ! 'video/x-raw, format=I420, width=360, height=240, framerate=15/1' ! identity drop-allocation=1 ! v4l2sink device=/dev/video2

teeをtという名前付きエレメントとして定義し、このエレメントにqueueを2つ連結している。

RC car serverで/dev/video2側のカメラ映像を取得・保存するのにOpenCVを使用した。
映像の取得にはcv::VideoCaptureクラス(ドキュメントはここ)を、各フレームの画像の保存にはcv::imwrite()(ドキュメントはここ)を使用した。

LunchJetでは、映像の取得はこのあたり

github.com

に、保存はこのあたり

github.com

に実装がある。いずれも非常に簡単である。

訓練データとして、

  • カメラ画像(JPEG)
  • カメラ画像のファイル名と制御値のセット(テキストファイル)

をJetsonのSDカードに保存することにする。
テキストファイルは以下のような簡単なフォーマットにした。

/var/log/lunchjet$ cat control/annotations/2021_05_12_08_22_17_434.log
2021_05_12_08_22_17_434.jpg 1.5259e-05 0.135875

一番目がカメラ画像のファイル名で、二番目・三番目がそれぞれステアリングと駆動モーターの制御値である。 ちなみにカメラ画像はミリ秒単位で時刻をファイル名としている。

ということで、ラジコンを適当に走らせていれば秒間15枚ずつ訓練データが蓄積されていくようになった。訓練データを5000枚収集するとすると、5〜6分遊んでいればよい。

次回以降で、Google Colabを使ってこの訓練データをネタにぼちぼちモデルを作ってみる。

「JetsonでFPVラジコンを作る」記事一覧

Jetson NanoでFPVラジコンを作る(1) - 自由課題
Jetson NanoでFPVラジコンを作る(2) - 自由課題
Jetson NanoでFPVラジコンを作る(3) - 自由課題
Jetson NanoでFPVラジコンを作る(4) - 自由課題
Jetson NanoでFPVラジコンを作る(5) - 自由課題
Jetson NanoでFPVラジコンを作る(6) - 自由課題
Jetson NanoでFPVラジコンを作る(7) - 自由課題
Jetson NanoでFPVラジコンを作る(8) - 自由課題
Jetson NanoでFPVラジコンを作る(9) - 自由課題
Jetson NanoでFPVラジコンを作る(10) - 自由課題