自動走行ハンズオン

1. 自己紹介
  個人事業主
  主に組込みソフト・ハードの受託開発
  愛知県立名古屋高等技術専門校組込みシステム科非常勤講師
  2018年からラズパイのOpenCVの画像処理で自動運転の研究
  DonkeyCarを使い画像AI自動運転の研究と布教活動(リンク)
  2022年にDonkeyCarから卒業し「あいちゃん」を開発
  CPUもラズパイからRock-5a/5bに乗り換え(リンク)
  トヨタ技術会のミニカーバトルに参戦(2021〜)(リンク)
   2023年のタイムアタックの動画(リンク)
   同カメラ画像から作成した動画(リンク)



2. 参考文献
  • CQ出版社 インターフェース 2023年3月号
      「自動運転ラジコン・カーの製作」(リンク)

  • PythonとKerasによるディープラーニング


  • Pythonによるディープラーニング(↑の新版)



    3. 本日の使用機材

  • ロボットカー
      あいこちゃん KSY WeBot
      RaspberryPi 3B
      ラズパイカメラV1(OmniVision)
      単三乾電池6本
      ラズパイ用5V電源アダプター
      コントローラー(Logicool F710/単三電池2本)

  • ホストPC
      HP Zbook 15 G3
      Windows10
      Intel i7,メモリ16G
      Nvidia Quadro M1000M GPUメモリ2G

  • コース
      黄色のプラダンボールに黒マジックペンでコースを描いたもの



    4. ロボットカーのラズパイのUSBマイクロ端子に電源アダプターを接続

      乾電池の消耗を抑えるため本体の電源スイッチはオンしない
       車を走らせるときに電池を使う



    5. Ubuntuを起動

      本日のPCはWindows10にwsl2でUbuntuをインストール済み
      スタートメニュー or タスクバーのUbuntuアイコンを起動



    6. アップデート(当日は不要)

    rm *.py
    
    wget http://ma2.la.coocan.jp/AI_Driver/webot/download/train.py
    
    wget https://raw.githubusercontent.com/mituhiromatuura/AI_Driver/main/maketensor.py
    


    7. Tensorflowのバージョンを確認(当日は不要)

    pip list
    



    8. ラズパイの起動を ping で確認
      PCのUbuntuで
    ping aicar00x(ラズパイのホスト名)
    

      応答があれば「ctrl+c」で停止
      PCのスタートメニュー or タスクバーにある RealVNC を起動

      RealVNCからラズパイに接続

      赤枠の中にラズパイのホスト名を入力してenter

      この画面が出たら「Continue」

      ユーザー名,パスワードを入力して「OK」

      Warningの画面は「OK」で閉じる
      赤矢印で示すアイコンをクリックしてターミナルを開く




    9. アップデート(当日は不要)

      VNCから
    pip install smbus2
    
    rm *.py
    
    wget http://ma2.la.coocan.jp/AI_Driver/webot/download/aidriver.py
    
    wget http://ma2.la.coocan.jp/AI_Driver/webot/download/cfg.py
    
    wget http://ma2.la.coocan.jp/AI_Driver/webot/download/movie.py
    
    wget https://raw.githubusercontent.com/KSY-IC/We-Bot/main/webot/webot.py
    



    10. Tensorflowのバージョン(当日は不要)

      VNCでTensorflowのバージョンを確認
    pip list
    



    11. カメラの接続を確認(当日は不要)

      VNCのターミナルで
    ls /dev
    
      と入力して video0 があること



    12. コントローラーの接続を確認(当日は不要)

      同じく
    ls /dev/input
    
      と入力して js0 があること
      同じく
    hexdump /dev/input/js0
    
      と入力
      コントローラーのスティックやボタンを操作してデータが表示されること
      コントローラーはスリープに入って反応しないことがある
       その時は青いボタンを押す
      背面のスライドスイッチはX側にする



    13. ラズパイをWinSCPに接続

      スタートメニュー or タスクバーのWinSCPアイコンを起動


      ラズパイのホスト名とユーザー名,パスワードを入力してログイン



    14. UbuntuをWinSCPに接続

      ホスト名は「localhost」



    15. プログラムの起動

      VNCのターミナルで
    python aidriver.py
    
      と入力

      カメラ画像が表示されるまで待つ

      カメラの前で手を動かして静止画でないことを確認
      赤枠のところに30秒間隔で電池の電圧が表示されるので数値を確認
       このときは外部電源なので表示は0.0V



    16. コントローラーの操作


    左スティック左右
    ステアリング
    	
    
    右スティック上下
    アクセル
    	
    
    緑ボタン
    モーターオンオフ
    PCのwキー
    
    黄ボタン
    自動運転走行オンオフ
    PCのeキー
    
    赤ボタン
    データ記録オンオフ
    PCのrキー
    
    青ボタン
    機能なし/スリープ解除
    	
    
    十字ボタン上下
    手動操縦の速度の微調整
    ↑:早くなる
    ↓:遅くなる
    十字ボタン左右
    直進の微調整
    ←:左に寄る
    →:右に寄る
      右のスティックを前方に倒すとカメラ画像内に白い線が伸びる
        車は動かない(モーターオフモード)
      その状態で左のスティックを左右に動かすと白い線が左右に傾く

      スティック操作の反応が無いときは青ボタンでスリープ解除



    17. ロボットカー動作確認

      ロボットカーの電源スイッチをオンする
      電池の電圧表示の数値を確認
       注:7.2V以下になると走らない
      ラズパイから電源アダプターを取り外す

      ロボットカーの周囲を広く空ける
      コントローラーの左右のスティックから手を放し 緑ボタンを押す(モーターオン)
      右のスティックを前後に(少しだけ)操作する→車が動く!
      再度 緑ボタンを押すとスティックを動かしても車は動かない(モーターオフ)



    18. 速度調整

      ロボットカーの速度が速すぎ or 遅すぎで操縦が難しいときは
      十字ボタンの上下で調整
      (アプリを再起動すると元に戻る)



    19. 直進チェック

      直進させても真っすぐ前に進まない(右や左に寄る)ときは
      コントローラーの十字ボタンの左右で調整
      (アプリを再起動すると元に戻る)




    20. コースを走行

      ロボットカーをコース上に置く
      緑ボタンを押してモーターオンモードにする
      走行練習



    21. 走行データを作成

      赤ボタンを押すとデータ記録が始まる
      4分間コースを周回
       4分×60秒×30FPS:約7200枚
      赤ボタンを押すとデータ記録が停止する

      コースアウトしたときは赤ボタンで記録を止めて車をコースに戻す



    22. データ取り終了

      自動運転プログラムを終了する
       VNCのカメラ画面が最前面の状態でQキーを押すとカメラ画面が消える

       赤矢印のデータ保存メッセージを確認
       VNCのターミナルにて ctrl+c を2回で終了




    23. 動画で操縦を確認

      記録した走行データから動画を作成することが出来る
    python movie.py
    


      mp4のファイルを右クリックで「開く」



    24. 操縦のチェック

      自分の操縦を可視化する
      WinscpのUbuntu(localhost)にて
      ~/AI_Driver/log/log.csv を右クリックして「実行」を選択
      Office の excel が開く
      servo と esc の列を選択して折れ線グラフを表示



    25. 走行データをラズパイからPCに転送

      PCの Ubuntuにて
    rsync -rtv --progress --partial pi@raspberrypi:~/AI_Driver/log ./
    




    26. PCにて訓練

      エポックをいくつにするか決めて
      6なら第2引数に6を指定
    time python train.py ./log 6
    


      loss(損失率)を数値とグラフで確認する

      右クリックで「開く」



    27. model.tflite をUbuntuからラズパイに転送

      Ubuntuで
    rsync -rvt --progress --partial ./model.tflite pi@raspberrypi:~/AI_Driver/
    




    28. 自動走行

      ロボットカーをコースに置く
      黄ボタンを押して自動運転モードにセット
      赤ボタンでデータ記録をオン
      緑ボタンを押すと自動運転で走り始める
      再度緑ボタンを押すと停止
      赤ボタンでデータ記録をオフ



    29. 調整箇所

      カメラの取り付け角度
      車を走らせる速度
      手動の操縦
      走行データの数
      訓練のエポック数
      ニューラルネットワークの構成



    30. 操縦のチェック

      AIの操縦を可視化する
      WinscpのUbuntu(localhost)にて
      ~/AI_Driver/log/log.csv を右クリックして「実行」を選択
      Office の excel が開く
      Steering と esc の列を選択して折れ線グラフを表示



    31. 処理時間のチェック

      time2 と time3 の列を選択して折れ線グラフを表示
       time2:一連の処理時間
       time3:推論の処理時間



    32. カメラの取り付け角度

      水平にして風景に向けると特徴が多いので良い
       周囲の特徴が少ないときはNG(全部白い壁)
       教師データ取得時と自動走行時とで特徴に違いがあるとうまく走らない
      路面に向けると周囲の変化の影響を排除できるが特徴が少ない
      天井に向けると良い場合がある



    33. 走行データの大きさ

      データの数を増やすと
       訓練の処理が重くなる
       本日のPCのGPUはメモリが2Gと小さいので Out Of Memory のエラーになる
        そのときはGPUの使用を諦める
       環境変数で設定
    export CUDA_VISIBLE_DEVICES=0
    GPUを使う
    
    export CUDA_VISIBLE_DEVICES=
    GPUを使わない
    
       GPUを使わずにCPUで処理すると訓練の時間が長くなる(例:1分が5分に)



    34. エポック数

      データの数に応じて設定
       過学習(over fit)
       学習不足(under fit)
      損失率を参考に(見極めるのは難しい)



    35. ニューラルネットワーク

      本日使用しているもの(ubuntuの~/AI_Driver/train.py)
    x = layers.Conv2D(16, 5, 2, activation = 'relu')(input_tensor)
    
    x = layers.Conv2D(32, 5, 2, activation = 'relu')(x)
    
    x = layers.Conv2D(64, 5, 2, activation = 'relu')(x)
    
    x = layers.Conv2D(128, 3, 1, activation = 'relu')(x)
    
    x = layers.Flatten()(x)
    
    x = layers.Dense(64, activation = 'relu')(x)
    

      Tensorflowが表示するパラメータの数に注意

      多いと訓練や推論に時間が掛かる



    36. 推論処理時間の確認

      WinSCPでラズパイの ./log/log.csv を右クリックで開く
      office の excelが開く

      time2 と time3を折れ線グラフで表示
       time2:一連の処理1回に掛かった時間
       time3:推論に掛かった時間

      推論の時間はカメラの画像データ取得間隔(1000msec÷FPS)以内であること
       オーバーすると画像データがキューに溜まってしまう



    37. 畳み込み層
    カーネルサイズ
    Conv2Dの第2引数
    
    ストライド
    Conv2Dの第3引数
    
    x = layers.Conv2D(8, 3, 2, activation = 'relu')(input_tensor)
    
    x = layers.Conv2D(16, 3, 2, activation = 'relu')(x)
    
    x = layers.Conv2D(32, 3, 2, activation = 'relu')(x)
    
    x = layers.Conv2D(64, 3, 2, activation = 'relu')(x)
    
    x = layers.Flatten()(x)
    
    x = layers.Dense(64, activation = 'relu')(x)
    



    38. 層を重ねる
       resnet(JetRacer)

      残差ネットワーク(リンク)



    39. パラメータ数を減らす

      プーリング層
    x = layers.Conv2D(8, 3, 1, activation = 'relu')(input_tensor)
    
    x = layers.MaxPooling2D(2)(x)
    
    x = layers.Conv2D(16, 3, 1, activation = 'relu')(x)
    
    x = layers.MaxPooling2D(2)(x)
    
    x = layers.Conv2D(32, 3, 1, activation = 'relu')(x)
    
    x = layers.MaxPooling2D(2)(x)
    
    x = layers.Conv2D(64, 3, 1, activation = 'relu')(x)
    
    x = layers.MaxPooling2D(2)(x)
    
    x = layers.Conv2D(128, 3, 1, activation = 'relu')(x)
    
    x = layers.MaxPooling2D(2)(x)
    
    x = layers.Flatten()(x)
    
    x = layers.Dense(64, activation = 'relu')(x)
    



    40. 過学習を抑止

      ドロップアウト層(ロバカー)
    x = layers.Conv2D(24, 5, 2, activation = 'relu')(input_tensor)
    
    x = layers.Dropout(0.2)(x)
    
    x = layers.Conv2D(32, 5, 2, activation = 'relu')(x)
    
    x = layers.Dropout(0.2)(x)
    
    x = layers.Conv2D(64, 5, 3, activation = 'relu')(x)
    
    x = layers.Dropout(0.2)(x)
    
    x = layers.Conv2D(64, 3, 1, activation = 'relu')(x)
    
    x = layers.Dropout(0.2)(x)
    
    x = layers.Conv2D(64, 3, 1, activation = 'relu')(x)
    
    x = layers.Dropout(0.2)(x)
    
    x = layers.Flatten()(x)
    
    x = layers.Dense(100, activation = 'relu')(x)
    
    x = layers.Dropout(0.2)(x)
    
    x = layers.Dense(50, activation = 'relu')(x)
    
    x = layers.Dropout(0.2)(x)
    



    41. カメラ

  • レンズ交換が可能な組込み用のカメラもある(M12マウント,Sマウント)
      標準
      広角
      魚眼

  • フレームレート
      カメラのフレームに同期して自動運転の処理が実行される
      フレームレートが高い方が処理の頻度が高くなるが画面が暗くなる



    42. まとめ

  • 最低限の浅いネットワークでもそこそこ走る

  • 現状「こうすればうまく走る」という明確なものは無い
      調整するパラメータは多岐に渡る
      コースや環境にも依存する
      客観的な性能の評価が出来ない
      過学習や学習不足の境界が分からない

  • 一番重要なのは訓練に使用する「教師データ」

  • 機械学習のフレームワーク
      Tensorflow
      PyTorch

  • 処理性能
      CPU:クロック,コア数
      GPU:NVidia
      TPU:Google Coral USB Accelerator(リンク)
      NPU:RockChipにも内蔵

  • SBC
      ラズベリーパイ4,5
      Jetson Nano/Jetson Orin Nano
      Rock-5a/5b
      Tinker Edge R(リンク)
      Khadas VIM4(リンク)

  • 小さい車(差動二輪)
      狭い場所で実験が可能
      WeBotは単三乾電池
       モバイルバッテリー(PD),充電式単三電池を使用するように改造は可能

  • 大きい車
      拡張性が高い
       各種センサーを搭載可能
       1/10ラジコンはオプションパーツが豊富

  • イベント
      今後は日本でも1/10自動運転レースが活発化していく

  • 走行会
      不定期に開催
      情報交換の場
      connpassのグループに登録(リンク)




  • このページのトップに戻る
    トップページに戻る