チュートリアル(EV3)

このページでは RTM講習会での EV3 操作手順を説明します。
実習では以下の Educator Vehicle 改を制御します。


/jp/node/6038

LEGO Mindstorms EV3 は LEGO の Mindstorms シリーズの新しいパッケージです。EV3 のメインのコントローラーは、Linux が標準搭載され、様々な言語でロボットの開発が可能になりました。

仕様

LEGO Mindstorms EV3 仕様
プロセッサ ARM9 300MHz
メモリ(ROM) 16MB Flash
メモリ(RAM) 64MB RAM
OS Linuxベース
ディスプレイ 178 x 128 pixels
出力ポート 4個
入力ポート 4個
アナログ
デジタル 460.8kbit/s
USB通信速度 High Speed (480Mbps)
USBインターフェース EV3同士の連結可能 (最大4台)
Wi-Fi通信ドングル利用可能
SDカードスロット Micro SDカード 32GBまでサポート
スマートデバイス接続 iOS、Android、Windows
ユーザーインターフェース 6ボタン, イルミネーション機能
プログラムサイズ (ライントレースの場合) 0.950KB
センサー通信性能 1000 回/秒、1ms
データロギング 最大 1,000サンプリング/秒
Bluetooth通信 最大7台のスレーブと接続可能
動力 リチャージブルバッテリー または、単3電池 6本

デバイス

EV3 には以下のデバイスが付属しています。

ジャイロセンサー
45505_GyroSensor.jpg
確度モード: 精度 +/- 3°
角速度モード: 最大 440 deg/sec
サンプリングレート 1,000 Hz
カラーセンサー
45506_color.jpg
計測: 赤色光の反射光、 周囲の明るさ、色
検出カラー数: 8色 (無色、黒、青、緑、黄、赤、白、茶)
サンプリングレート 1,000 Hz
距離 約1mm~18mm(アフレル調査値)
タッチセンサー
45507_TouchSensor.jpg
オン (1), オフ (0)
スイッチ可動域: 約4mm
超音波センサー
45504_UltrasonicSensor.jpg
距離計測可能範囲: 3cmから250cm
距離計測精度: +/- 1 cm
前面電飾: 点灯:超音波発信中、 点滅:超音波観測中
EV3 Lモーター
45502_LargeMotor.jpg
フィードバック: 1°単位
回転数: 160から170RPM
定格トルク: 0.21 N・m (30oz*in)
停動トルク: 0.42 N・m (60oz*in)
重さ: 76 g
EV3 Mモーター
45503_MediumMotor.jpg
フィードバック 1°単位
回転数: 240から250RPM
定格トルク: 0.08 N・m (11oz*in)
停動トルク: 0.12 N・m (17oz*in)
重さ: 36 g

ダウンロード

最初にPC側で使用する RTC 等をダウンロードしてください。

ZIPファイルを Lhaplus 等で展開してください。

EV3 の組み立て方

EV3 は分解した状態で参加者に配ります。 組み立て方は以下の通りです。

※超音波センサー、カラーセンサー、ジャイロセンサーについては、講習で使用しないため取り付ける必要はありません。 以下の※の作業については、時間が余った人が実施してください。

まずは土台部分を取り出してください。


s_DSC00463.JPG

最初にMモーターにケーブル(25cm)を接続します※。


s_DSC00446.JPG

次に EV3 本体を取り付けます。 Mモーターにケーブルを接続した場合は、ケーブルが左側の隙間から出るようにしてください。


s_DSC00448.JPG s_DSC00450.JPG



右側のタッチセンサーを取り付けてください。


s_DSC00451.JPG s_DSC00452.JPG



超音波センサーを取り付けてください※。


s_DSC00454.JPG

ケーブルを接続してください。 必須なのは車輪駆動用のLモーター右、Lモーター左、タッチセンサーだけです。

Lモーター右 ポート C 25cmケーブル
Lモーター左 ポート B 25cmケーブル
Mモーター※ ポートA 25cmケーブル
タッチセンサー右 ポート 3 35cmケーブル
タッチセンサー左 ポート 1 35cmケーブル
超音波センサー※ ポート 4 50cmケーブル
ジャイロセンサー※ ポート 2 25cmケーブル

ケーブルは EV3 の上下に A~D と 1~4 のポートがあるのでそこにケーブルを接続します。


s_DSC00.JPG s_DSC00471.JPG




s_DSC00455.JPG s_DSC00456.JPG



左右にパーツを取り付けます※。 Lモーター右、Lモーター左、Mモーター、タッチセンサー右、タッチセンサー左のケーブルを挟むようにして取り付けてください※。
Lモーター右、タッチセンサー右のケーブルは右側から、Lモーター左、Mモーター、タッチセンサー左は左側から通してください※。


s_DSC00457.JPG


s_DSC00459.JPG

これでとりあえず完成ですが、余裕のある人はジャイロセンサーを取り付けてみてください※。


s_DSC00460.JPG s_DSC00461.JPG



電源の入れ方/切り方

電源の入れ方

中央のボタンを押せば電源が投入されます。


ev3_on.jpg

電源の切り方

EV3 の電源を切る場合は最初の画面で EV3 本体の左上の戻るボタンを押して「Power Off」を選択してください。


ev3_off.jpg


s_DSC01033.JPG

再起動

再起動する場合は最初の画面で EV3 本体の左上の戻るボタンを押して「Reboot」を選択してください。

リセット

ev3dev の起動が途中で停止する場合には、中央ボタン、戻るボタン(左上)、左ボタンを同時押ししてください。画面が消えたら戻るボタンを離すと再起動します。


ev3_reset.jpg

EV3 への接続

EV3 へは原則として無線LANで接続するようにしてください

無線LANアクセスポイントへの接続

まずは EV3 の中央のスイッチを押して電源を投入してください。
ここで電源を投入する前に無線LANアダプタを取り付けておいてください。

以下の作業でスクリプトを実行するとアクセスポイントが起動します。

EV3 の操作画面から「File Browser」を上下ボタンで選択して中央のボタンを押してください。

 ------------------------------
 192.168.0.1
 ------------------------------
 [File Browser               > ]
  Device Browser             >
  Wireless and Networks      > 
  Battery                    >
  Open Roberta Lab           >
  About                      >
 ------------------------------

次に scripts を選択して中央ボタンを押してください。

 ------------------------------
 192.168.0.1
 ------------------------------
         File Browser
 ------------------------------
 /home/robot
 ------------------------------
 [scripts                     ]
 ・・
 ・・
 ------------------------------

次の画面から start_ap.sh を選択して中央ボタンを押すとスクリプトが起動します。

 ------------------------------
 192.168.0.1
 ------------------------------
         File Browser
 ------------------------------
 /home/robot/scripts
 ------------------------------
 ../
 Component/
 ・・
 [start_ap.sh                 ]
 ------------------------------

しばらくすると無線LANアクセスポイントが起動するので、指定の SSID のアクセスポイントに接続してください。 SSID、パスワードは EV3 に貼り付けたテープに記載してあります。


tutorial_ev3_irex26.png

アクセスポイントへの接続方法は以下のページを参考にしてください。

まず右下のネットワークアイコンをクリックしてください。


/ja/node/6042

次に一覧から ev3_***を選択してください。


tu_ev3_11.png

パスワードを入力してください。


/ja/node/6042

USBケーブルでの接続

以下の作業は有線で接続する場合の作業なので、無線で接続する場合は不要です。

付属の USBケーブルで EV3 と PC を接続してください。


s_DSC00467.JPG

中央のボタンを押して電源を投入してください。

ここで EV3 の電源を投入する前に無線LANアダプタは取り外しておいてください。
以下の画面が表示されていれば ev3dev の起動に成功していますが、起動途中で停止した場合は この手順 で再起動してください。


s_DSC00470.JPG

デバイスマネージャで「EV3+ev3dev」が「その他のデバイス」の下にある場合は正しく機能していないので、以下の手順でデバイスソフトウェアの更新を行ってください。

まずはコントロールパネルからデバイスマネージャを開いてください。


tu_ev3_17.png


tu_ev3_18.png

開いたら EV3+ev3dev を右クリックして「ドライバソフトウェアの更新」を選択してください。
ここで EV3+ev3dev がネットワークアダプターの下にある場合は正常に認識されているので以下の作業は不要です。


tu_ev3_1.png

「コンピューターを参照してドライバー ソフトウェアを検索します」を選択してください。


tu_ev3_3.png

「コンピューター上のデバイス ドライバーの一覧から選択します」を選択してください。


tu_ev3_4.png

ネットワーク アダプターを選択して次へをクリックしてください。


tu_ev3_5.png

製造元は「Microsoft Corporation」、ネットワークアダプタは「Remote RNDIS Compatible Device」を選択して次へをクリックしてください。


tu_ev3_9.png

ドライバー更新警告が出た場合は「はい」を選択してください。


tu_ev3_7.png

正常に更新されたら閉じるを選択してください。


tu_ev3_8.png

事前準備

このページ の手順に従ってネームサーバー、RTシステムエディタを起動してください。 予めネームサーバーを起動してある場合は再起動してください。

またネットワークインターフェースが2つ以上ある場合に通信に失敗する可能性があるため、有線で接続した場合は他のネットワークデバイスを無効にしてからネームサーバーを起動してください。


/ja/node/6042


/ja/node/6042

ネームサーバー追加

続いて RTシステムエディタのネームサーバー追加ボタンで192.168.0.1(無線LANで接続する場合は192.168.11.1)を追加してください。


/jp/node/6042 tu_ev3_25.png



するとEducatorVehicle0という RTC が見えるようになります。

EducatorVehicle は EV3 の走行速度の入力、センサーのデータの出力等を行うためのコンポーネントです。


 /ja/node/6030

EducatorVehicle
InPort
名前 データ型 説明
velocity2D RTC::TimedVelocity2D 目標速度
angle RTC::TimedDouble Mモーターの角度
lcd RTC::TimedString LCDに表示する画像ファイル名
sound RTC::TimedString 出力する音声
OutPort
名前 データ型 説明
odometry RTC::TimedPose2D 現在の位置・姿勢
ultrasonic RTC::RangeData 超音波センサーで計測した距離
gyro RTC::TimedDouble ジャイロセンサーで計測した角度
color RTC::TimedString カラーセンサーで計測した色
light_reflect RTC::TimedDouble カラーセンサーで計測した反射光の強さ
touch RTC::TimedBoolean タッチセンサーのオンオフ。右側が0番目の要素、左側が1番目の要素
コンフィギュレーションパラメーター
名前 デフォルト値 説明
wheelRadius 0.028 車輪の半径
wheelDistance 0.054 タイヤ間距離の1/2
medium_motor_speed 1.6 Mモーターの速度

TimedVelocity2D型について

TimedVelocity2D型は以下のように定義されています。

     struct Velocity2D
     {
         double vx;
         double vy;
         double va;
     };

     struct TimedVelocity2D
     {
         Time tm;
         Velocity2D data;
     };

vx、vy、va はロボット中心座標系での速度を表しています。


tu_ev3_19.png

vx は X方向の速度、vy は Y方向の速度、va は Z軸周りの角速度です。

Educator Vehicle のように2個の車輪が左右に取り付けられているロボットの場合、横滑りしないと仮定すると vy は0になります。

vx、va を指定することでロボットの操作を行います。

音声の出力

sound による音声の入力には以下のコマンドを利用できます。

  • beep
    beep と入力するとビープ音が鳴ります。
  • tone
    以下のように tone、周波数、時間と入力すると指定周波数の音を指定ミリ秒数だけ鳴らします。

 tone,100,1000

  • それ以外
    それ以外は指定文字列を発音します

LCD に表示する画像について

LCD で表示する画像は付属資料の software/saveBinaryImage/EXE/saveBinaryImage.exeで変換したものを利用してください。
画像ファイルを saveBinaryImage.exe にドラッグ・アンド・ドロップすれば変換できます。

サンプルコンポーネント起動

付属資料のstart_component_ev3.batを起動してください。 ※OpenRTM-aist Python版をインストールしていない場合、もしくはインストールに失敗している場合は個別に実行ファイル入りのUSBメモリーを配布いたしますので、その中のstart_component_ev3_exe.batを利用してください。

すると以下の2つの RTC が起動します。

tu_ev3_24.png

動作確認

まずはジョイスティックで EV3 を操作してみます。

RTシステムエディタで EducatorVehicle、FloatSeqToVelocity、TkJoyStick を以下のように接続します。


tutorial_ev3_16.png

そして RTC をアクティブ化するとジョイスティックで EV3 の操作ができるようになります。


tutorial_ev3_21.png

自作の RTC で制御

まずは FloatSeqToVelocity の out と EducatorVehicle の target_velocity_in のコネクタを切断してください。

tutorial_ev3_17.png

FloatSeqToVelocity と EducatorVehicle の間に自作の RTC を接続して、タッチセンサーがオンになった場合に停止して音を鳴らすようにします。

ひな形コードの作成

RTC ビルダを起動してください。


/jp/node/6038

起動したら新規にプロジェクトを作成します。


/jp/node/6038

プロジェクト名は TestEV3CPP(TestEV3Py)にします。

以下のように設定を行ってください。 C++、もしくは Python で作成します。

基本
モジュール名 TestEV3CPP、もしくはTestEV3Py
アクティビティ
有効アクション onInitialize、onExecute、onActivated、onDeactivated
データポート
InPort
名前 データ型 説明
velocity_in RTC::TimedVelocity2D 入力目標速度
touch RTC::TimedBooleanSeq タッチセンサーのオンオフ
OutPort
名前 データ型 説明
velocity_out RTC::TimedVelocity2D 出力目標速度
sound RTC::TimedString 音声
コンフィギュレーション
名前 説明
sound_output string タッチセンサーが ON の時に発する音声。デフォルト値は beep
言語・環境
言語 C++、もしくはPython

[コード生成] ボタンを押したらコードが生成されます。


tutorial_raspimouse10.png

プロジェクト生成

コードが生成できたら C++ の場合は CMake で Visual Studio のプロジェクト(Ubuntu の場合は Code::Blocks)を生成してください。

まず CMake (cmake-gui) を起動します。

  • Windows 7

/jp/node/6038

  • Windows 8.1


/jp/node/6038

起動したらソースコードのディレクトリー、ビルドを行うディレクトリーに以下を指定します。 括弧内は eclipse の作業ディレクトリーを C:\workspace にした場合の例です。

Where is the source code RTCBuilder で生成したコードのフォルダー(C:\workspace\TestEV3CPP)
Where to build the binaries RTCBuilder で生成したコードのフォルダーの下に作成したbuildフォルダー(C:\workspace\TestEV3CPP\build)


tutorial_ev3_24.png

[Configure] ボタン→ [Generate] ボタンをクリックするとVisual Studioのプロジェクトが生成されます。

ソースコードの編集

build ディレクトリーの TestEV3CPP.sln を開いてください。

次にコードの編集を行います。

Pythonの場合はまず変数の初期化部分を修正してください。

  • TestEV3Py.py

     def __init__(self, manager):
         #self._d_velocity_in = RTC.TimedVelocity2D(*velocity_in_arg)
         self._d_velocity_in = RTC.TimedVelocity2D(RTC.Time(0,0),RTC.Velocity2D(0,0,0))

         #self._d_distance_sensor = RTC.TimedShortSeq(*distance_sensor_arg)
         self._d_distance_sensor = RTC.TimedShortSeq(RTC.Time(0,0),[])

         #self._d_velocity_out = RTC.TimedVelocity2D(*velocity_out_arg)
         self._d_velocity_out = RTC.TimedVelocity2D(RTC.Time(0,0),RTC.Velocity2D(0,0,0))

         #self._d_buzzer = RTC.TimedShort(*buzzer_arg)
         self._d_buzzer = RTC.TimedShort(RTC.Time(0,0),0)

まずは onExecute で入力速度をそのまま出力するコードを書いてみます。
C++の場合は以下のようになります。
isNew関数で新規の入力データが存在するかを確認して、read関数で変数(m_velocity_in)に格納します。 そして m_velocity_out に出力データを格納して write関数を呼び出すとデータが送信されます。

  • src/TestEV3CPP.cpp

     if (m_velocity_inIn.isNew())
     {
         m_velocity_inIn.read();
         //入力速度をそのまま出力
         m_velocity_out.data.vx = m_velocity_in.data.vx;
         m_velocity_out.data.vy = m_velocity_in.data.vy;
         m_velocity_out.data.va = m_velocity_in.data.va;
         setTimestamp(m_velocity_out);
         m_velocity_outOut.write();
 
 
     }

Pythonの場合は以下のようになります。

  • TestEV3Py.py

         if self._velocity_inIn.isNew():
             data = self._velocity_inIn.read()
             #入力速度をそのまま出力する
             self._d_velocity_out.data.vx = data.data.vx
             self._d_velocity_out.data.vy = data.data.vy
             self._d_velocity_out.data.va = data.data.va
             OpenRTM_aist.setTimestamp(self._d_velocity_out)
             self._velocity_outOut.write()

次にタッチセンサーがオンの場合に停止する処理を記述します。
常にタッチセンサーのデータが入力されるとは限らないので、センサーのデータを格納する変数を宣言します。
C++の場合は TestEV3CPP.h に記述します。

  • include/TestEV3CPP/TestEV3CPP.h

  private:
      bool m_last_sensor_data[2];


Pythonの場合はコンストラクタに記述します。

  • TestEV3Py.py

     def __init__(self, manager):
         OpenRTM_aist.DataFlowComponentBase.__init__(self, manager)
 
         self._last_sensor_data = [False, False]

次に onExecute に停止する処理を記述します。
C++の場合は以下のようになっています。
まずインポート touch に isNew 関数で新規にデータが入力されたかを確認して、入力されている場合は read関数で読み込みます。そして変数 m_last_sensor_data に格納します。
そしてインポート velocity_in で受信したデータの vx が 0 以上の場合には前進しているため障害物に接触するかもしれないと判定して、タッチセンサーがオンの場合は停止してブザーを鳴らします。

  • src/TestEV3CPP.cpp

 RTC::ReturnCode_t TestEV3CPP::onExecute(RTC::UniqueId ec_id)
 {
     //データを新規に受信した場合に、データをm_last_sensor_dataを格納する
     if (m_touchIn.isNew())
     {
         m_touchIn.read();
         if (m_touch.data.length() == 2)
         {
             for (int i = 0; i < 2; i++)
             {
                 //タッチセンサがOFFからONになった時に音を鳴らす
                 if (!m_last_sensor_data[i] && m_touch.data[i])
                 {
                     m_sound.data = m_sound_output.c_str();
                     setTimestamp(m_sound);
                     m_soundOut.write();
 
 
                 }
                 m_last_sensor_data[i] = m_touch.data[i];
             }
         }
     }
     if (m_velocity_inIn.isNew())
     {
         m_velocity_inIn.read();
         //vxが0以上(前進)のときのみ停止するか判定する
         if (m_velocity_in.data.vx > 0)
         {
             for (int i = 0; i < 2; i++)
             {
                 //タッチセンサがONの時に停止する
                 if (m_last_sensor_data[i])
                 {
                     //停止する
                     m_velocity_out.data.vx = 0;
                     m_velocity_out.data.vy = 0;
                     m_velocity_out.data.va = 0;
                     setTimestamp(m_velocity_out);
                     m_velocity_outOut.write();
 
 
                     return RTC::RTC_OK;
                 }
             }
         }
         //入力速度をそのまま出力
         m_velocity_out.data.vx = m_velocity_in.data.vx;
         m_velocity_out.data.vy = m_velocity_in.data.vy;
         m_velocity_out.data.va = m_velocity_in.data.va;
         setTimestamp(m_velocity_out);
         m_velocity_outOut.write();

   return RTC::RTC_OK;
 }

Pythonの場合は以下のようになっています。

  • TestEV3Py.py

     def onExecute(self, ec_id):
         #データを新規に受信した場合に、データをm_last_sensor_dataを格納する
         if self._touchIn.isNew():
             data = self._touchIn.read()
             if len(data.data) == 2:
                 for i in range(2):
                     #タッチセンサがOFFからONになった時に音を鳴らす
                     if not self._last_sensor_data[i] and data.data[i]:
                         self._d_sound.data = self._sound_output[0]
                         OpenRTM_aist.setTimestamp(self._d_sound)
                         self._soundOut.write()
                 self._last_sensor_data = data.data[:]
 
         if self._velocity_inIn.isNew():
             data = self._velocity_inIn.read()
             #vxが0以上(前進)のときのみ停止するか判定する
             if data.data.vx > 0:
                 for d in self._last_sensor_data:
                     #タッチセンサーがONの時に停止する
                     if d:
                         #停止する
                         self._d_velocity_out.data.vx = 0
                         self._d_velocity_out.data.vy = 0
                         self._d_velocity_out.data.va = 0
                         OpenRTM_aist.setTimestamp(self._d_velocity_out)
                         self._velocity_outOut.write()
                         
                         return RTC.RTC_OK
 
             #入力速度をそのまま出力する
             self._d_velocity_out.data.vx = data.data.vx
             self._d_velocity_out.data.vy = data.data.vy
             self._d_velocity_out.data.va = data.data.va
             OpenRTM_aist.setTimestamp(self._d_velocity_out)
             self._velocity_outOut.write()
         return RTC.RTC_OK

コードの編集が終わったら C++ の場合はビルドしてください。
ビルドに成功すると build\src\Release(Debug) に TestEV3CPPComp.exe が生成されます。

動作確認

TestEV3CPPComp.exe (TestEV3CPPComp.py) をダブルクリックして起動してください。
TestEV3CPP(TestEV3Py)を以下のように接続してください。


tutorial_ev3_18.png

最後に RTC をアクティブ化して動作確認してください。

RTシステム保存

RTシステムを保存する場合は System Diagram 上で右クリックして Save As... を選択してください。


tutorial_ev3_20.png


/jp/node/6038


RTシステム復元

復元する場合は Open and Restore を選択して、先ほど保存したファイルを選択してください。


/ja/node/6042

RTC 終了

RTC を終了する場合は RTシステムエディタ上で RTC を exit してください。


tutorial_ev3_19.png

補足

スクリプトファイルについて

EV3 のボタン操作で File Brower を選択すると/home/robot以下のディレクトリーの操作ができます。
scripts フォルダー内のシェルスクリプトを実行することで以下の操作ができます。

スクリプトファイル名 内容
run_rtcs.sh RTC を起動する
stop_rtcs.sh RTC を終了する