このページでは RTM講習会での EV3 操作手順を説明します。
実習では以下の Educator Vehicle 改を制御します。
| 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 には以下のデバイスが付属しています。
最初にPC側で使用する RTC 等をダウンロードしてください。
ZIPファイルを Lhaplus 等で展開してください。
EV3 は分解した状態で参加者に配ります。 組み立て方は以下の通りです。
※超音波センサー、カラーセンサー、ジャイロセンサーについては、講習で使用しないため取り付ける必要はありません。 以下の※の作業については、時間が余った人が実施してください。
まずは土台部分を取り出してください。
右側のタッチセンサーを取り付けてください。
超音波センサーを取り付けてください※。
| Lモーター右 | ポート C | 25cmケーブル |
| Lモーター左 | ポート B | 25cmケーブル |
| Mモーター※ | ポートA | 25cmケーブル |
| タッチセンサー右 | ポート 3 | 35cmケーブル |
| タッチセンサー左 | ポート 1 | 35cmケーブル |
| 超音波センサー※ | ポート 4 | 50cmケーブル |
| ジャイロセンサー※ | ポート 2 | 25cmケーブル |
ケーブルは EV3 の上下に A~D と 1~4 のポートがあるのでそこにケーブルを接続します。
左右にパーツを取り付けます※。 Lモーター右、Lモーター左、Mモーター、タッチセンサー右、タッチセンサー左のケーブルを挟むようにして取り付けてください※。
Lモーター右、タッチセンサー右のケーブルは右側から、Lモーター左、Mモーター、タッチセンサー左は左側から通してください※。
中央のボタンを押せば電源が投入されます。
EV3 の電源を切る場合は最初の画面で EV3 本体の左上の戻るボタンを押して「Power Off」を選択してください。
再起動する場合は最初の画面で EV3 本体の左上の戻るボタンを押して「Reboot」を選択してください。
ev3dev の起動が途中で停止する場合には、中央ボタン、戻るボタン(左上)、左ボタンを同時押ししてください。画面が消えたら戻るボタンを離すと再起動します。
EV3 へは原則として無線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 に貼り付けたテープに記載してあります。
まず右下のネットワークアイコンをクリックしてください。
以下の作業は有線で接続する場合の作業なので、無線で接続する場合は不要です。
付属の USBケーブルで EV3 と PC を接続してください。
ここで EV3 の電源を投入する前に無線LANアダプタは取り外しておいてください。
以下の画面が表示されていれば ev3dev の起動に成功していますが、起動途中で停止した場合は この手順 で再起動してください。
まずはコントロールパネルからデバイスマネージャを開いてください。
このページ の手順に従ってネームサーバー、RTシステムエディタを起動してください。 予めネームサーバーを起動してある場合は再起動してください。
またネットワークインターフェースが2つ以上ある場合に通信に失敗する可能性があるため、有線で接続した場合は他のネットワークデバイスを無効にしてからネームサーバーを起動してください。
続いて RTシステムエディタのネームサーバー追加ボタンで192.168.0.1(無線LANで接続する場合は192.168.11.1)を追加してください。
するとEducatorVehicle0という RTC が見えるようになります。
EducatorVehicle は EV3 の走行速度の入力、センサーのデータの出力等を行うためのコンポーネントです。
| 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型は以下のように定義されています。
struct Velocity2D
{
double vx;
double vy;
double va;
}; struct TimedVelocity2D
{
Time tm;
Velocity2D data;
};vx、vy、va はロボット中心座標系での速度を表しています。
Educator Vehicle のように2個の車輪が左右に取り付けられているロボットの場合、横滑りしないと仮定すると vy は0になります。
vx、va を指定することでロボットの操作を行います。
sound による音声の入力には以下のコマンドを利用できます。
tone,100,1000
LCD で表示する画像は付属資料の software/saveBinaryImage/EXE/saveBinaryImage.exeで変換したものを利用してください。
画像ファイルを saveBinaryImage.exe にドラッグ・アンド・ドロップすれば変換できます。
付属資料のstart_component_ev3.batを起動してください。 ※OpenRTM-aist Python版をインストールしていない場合、もしくはインストールに失敗している場合は個別に実行ファイル入りのUSBメモリーを配布いたしますので、その中のstart_component_ev3_exe.batを利用してください。
すると以下の2つの RTC が起動します。
まずはジョイスティックで EV3 を操作してみます。
RTシステムエディタで EducatorVehicle、FloatSeqToVelocity、TkJoyStick を以下のように接続します。
まずは FloatSeqToVelocity の out と EducatorVehicle の target_velocity_in のコネクタを切断してください。
FloatSeqToVelocity と EducatorVehicle の間に自作の RTC を接続して、タッチセンサーがオンになった場合に停止して音を鳴らすようにします。
RTC ビルダを起動してください。
以下のように設定を行ってください。 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 | |
[コード生成] ボタンを押したらコードが生成されます。
コードが生成できたら C++ の場合は CMake で Visual Studio のプロジェクト(Ubuntu の場合は Code::Blocks)を生成してください。
まず CMake (cmake-gui) を起動します。
| Where is the source code | RTCBuilder で生成したコードのフォルダー(C:\workspace\TestEV3CPP) |
| Where to build the binaries | RTCBuilder で生成したコードのフォルダーの下に作成したbuildフォルダー(C:\workspace\TestEV3CPP\build) |
build ディレクトリーの TestEV3CPP.sln を開いてください。
次にコードの編集を行います。
Pythonの場合はまず変数の初期化部分を修正してください。
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関数を呼び出すとデータが送信されます。
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の場合は以下のようになります。
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 に記述します。
private:
bool m_last_sensor_data[2];
Pythonの場合はコンストラクタに記述します。
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 以上の場合には前進しているため障害物に接触するかもしれないと判定して、タッチセンサーがオンの場合は停止してブザーを鳴らします。
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の場合は以下のようになっています。
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)を以下のように接続してください。
RTシステムを保存する場合は System Diagram 上で右クリックして Save As... を選択してください。
復元する場合は Open and Restore を選択して、先ほど保存したファイルを選択してください。
RTC を終了する場合は RTシステムエディタ上で RTC を exit してください。
EV3 のボタン操作で File Brower を選択すると/home/robot以下のディレクトリーの操作ができます。
scripts フォルダー内のシェルスクリプトを実行することで以下の操作ができます。
| スクリプトファイル名 | 内容 |
| run_rtcs.sh | RTC を起動する |
| stop_rtcs.sh | RTC を終了する |