レゴマインドストームEV3の黒ライントレースをディープラーニングでやってみる | そう備忘録

レゴマインドストームEV3の黒ライントレースをディープラーニングでやってみる

ディープラーニングによるライントレース

先日レゴ・マインドストームEV3✕Chainer(実践! Chainerとロボットで学ぶディープラーニング)の記事がTwitterのタイムラインで流れてきた。

どうやらレゴ・マインドストームEV3とラズパイでディープラーニングによるライントレースができるまでの教材をPreferred Networks、株式会社アフレル、山梨大学が共同で開発したらしい。

自分はレゴEV3もRaspberryPi 3 B+もすでに持っている。

そして今年の7月にJDLA(一般社団法人日本ディープラーニング協会)のDeep Learning for GENERAL(2019#2)の検定に合格したこともあってディープラーニングにも興味を持っている(プログラミングレベルはまだまだしょぼい)

おまけに山梨県在住なので親近感もあったので早速挑戦してみることにした。

尚、ブログの最後で動画で同内容を紹介している

実際の動きを見たい人は動画を参照して欲しい。

EV3、ラズパイ、Chainerによるライントレース

ちなみにこの教材は無料だった。

こんなおもしろい教材を無料で公開してくれた関係者の方々にはとても感謝している。

唯一の不安材料はChainerを全く使ったことが無かったこと。

Preferred Networksといえばトヨタから出資受けたりファナックと業務提携したりと世界的にも有名な企業だけどTensorFlowのサンプルコードは頻繁に見かける一方、Chainerはあまり見かけないので今まで触ったことが無かった。(申し訳ない)

だけどせっかくなのでこの機会に色々と触ってみたいと思って教材をダウンロードした。

用意したモノ

教材(PDF)

実践! Chainerとロボットで学ぶディープラーニング」のページでメールアドレスとパスワードを登録すると無料でダウンロードできる。

レゴ・マインドストームEV3

教育版レゴ・ マインドストーム EV3基本セット。

自分は以前に正規代理店のアフレルから購入している。

アマゾンで並行輸入品も売っているので興味がある方はそちらでも良いと思うが自分はBIOSが壊れかけた時など何回かサポートにもお世話になっているので正規代理店で購入して正解だったと思っている。

RaspberryPi

RaspberryPi 3 B+をアマゾンで2019年4月に購入している。

RaspberryPi 4が発売されてから何故か3の値段も上昇した気がする・・・。

ラズパイ用カメラ

Raspberry Pi Camera Module V2を2019年7月に購入した。

今回はこのカメラで撮影した映像をディープラーニングで学習してライントレースするプログラムを動かすことになる。

EV3用コンソールアダプター

LinuxマシンとEV3とを接続するアダプター(Console Adapter for EV3)

持っていなかったので今回新たにRobot Shop テクノロジアで購入した。

EV3コンソールアダプター

モバイルバッテリー

以前にアマゾンで購入したAnkerのモバイルバッテリー(10000mAh)を使った。

セットアップや学習の時はコンセントから給電してライントレースの時だけモバイルバッテリーで動作させるのであればそれほど大きな容量は必要ない。

動作構成図

大まかな構成は以下の通り。

  • レゴで3輪のロボットを組み立てる
  • RaspberryPi上のPythonからEV3のロボットを制御する
  • RaspberryPiとEV3はEV3用コンソールアダプターで接続する
  • RaspberryPiはモバイルバッテリーで動作する
  • カメラモジュールはRaspberryPiに接続して楕円のコースのラインを撮影する
  • PythonのプログラムはJupyterLabで編集する
  • Raspberry Pi 上のJupyterLab をリモートでPCブラウザで編集する

動作環境の概要図

ロボットの組み立てや細かい接続については前述の教材で確認ができる。

ライントレースまでの手順

ロボットがラインを学習してトレースできるようになるまでの大まかな手順は以下の通り。

  1. レゴのカラーセンサーを使ったライントレースでラインの画像情報を集める
  2. 集めた画像情報を学習したモデルを作成する
  3. 学習済のモデルを元にライントレースする

1.画像の収集

最初に既存のカラーセンサーを使った方法で左右の車輪を制御して楕円コースのライントレースを行うと同時にラズパイに接続したカメラモジュールでラインを撮影して画像を収集する。

カラーセンサーでライントレースをしながらカメラモジュールで画像を収集

ライントレースの基本的な考え方は以前にアップした「黒ラインをトレースするプログラム」と大きな違いはない。

違いは下記の様にグラフィカルなブロックでプログラミングするか、

グラフィカルなプログラミング

プログラム全体

今回の様にPythonでプログラミングするかの違いだ。

PythonによるEV3の制御

PythonによるEV3の制御

上記のプログラムを実行すると

  1. 画像ファイル名と角度と対応させたリスト(list.txt)
  2. 様々な角度の画像ファイル(2値化している)

の2つが収集される。

list.txt

ファイル名と角度との対応表

0000231.pngは-8(度)でほぼ直線、0000250.pngは-38(度)と記録されている。

以下は収集された画像。

カメラで読み取った画像を2値化(白と黒だけ)に変換している。

0000231.png

231.png

0000250.png

250.png

学習

次に上記のリストと画像を元にChainerを使って学習する。

Chainerは株式会社Preferred Networks社が開発した国産のディープラーニングの為のフレームワーク。

簡潔なコードでディープラーニングのコードを書くことができる。

まだざっと見ただけだが確かにシンプルなコードが並んでいる。

コードの抜粋

ディープラーニングのコード

やっている事をざっくり書くと画像と角度のリストから「こんな特徴の画像の時はこの角度」という事を学習している。

いわゆる「教師あり学習」の分野で上記1の手順で取得した正解データを教師(入力)にして画像を読んでは角度を予測して(最初は当たらない)正解データと比較して違っていれば誤差を補正する。

上記を繰り返すことで新しい画像を読んだ時に「この画像の特徴なら以前に見たこの画像と特徴が近いのでこの角度だよね」とラインの角度(EV3ロボットのラインへの進入角度)を予測できるようになる。

そして学習結果を”学習済みモデル”として保存する。

以下、プログラムの補足。

層はl1、l2、l3と3層、入力層を含めて4層のニューラルネットワークが定義されていた。

ニューラルネット模式図

活性化関数はディープラーニングではよく使われるReLU関数が使われていた。

またバッチサイズ(一度に同時に学習するデータの数)は100、エポック数(データを何度学習に用いたか)も100が指定されていた。

ディープラーニングによるトレース

以下のプログラムで学習済みモデルを読み込んでカメラモジュールからの画像をラインの角度を予測してEV3のモーターを制御している。

学習済モデルを読み込んでライントレース

下記の動画が実際のライントレースの様子。

カラーセンサーを使ってライントレースしているわけでは無い(ライトが点灯していない)

カメラモジュールからの画像を元に前方のラインと自車との角度を予測してステアリングしている。

尚、台風のさなかに撮影したので若干雨の音がうるさいのはご容赦いただきたい。

感想

とにかく面白かった!

EV3をPythonで制御するのも初めてだったのでもっと試行錯誤するのかと思ったのだがあっさり繋がった。

グラフィカルなコードと同様にカラーセンサーやタッチセンサーの数値を読み取ったり、Lモーターのパワーを制御できるのでケースによってはPythonの方が細かい制御ができるのかも知れないと感じた。

またChainerは初めて使ったけど非常にシンプルなコードが”書ける”と感じた。

ただ”書ける”と”書く”は別問題でTelsorFlowでも書けるのだろうけど技術レベルの問題で”書けていない”(←自分)

せっかくラズパイにChainerをインストールしたので色々と触ってみたいと思っている。

動画

ブロブの内容を動画で解説している。

実際の動きが分かるので是非見て欲しい。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

3件のフィードバック

  1. イチ より:

    初心者です。
    c++で、ソケット通信を用いて、pythonに数字を送りたいです。どんなプログラムを書けばよいでしょうか?教えていただけると幸いです。

souichirou へ返信する コメントをキャンセル

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。