mruby on EV3RT + tecsでEV3wayを動かすまでの記録

西脇.rb & 神戸.rbの[Rubyプログラミングキャンプ2015](https://nishiwaki-koberb.doorkeeper.jp/events/29396)で[mruby on EV3RT + tecs](https://www.toppers.jp/tecs.html#mruby_ev3rt)を使ってEV3を動かしてみたので、やったことや詰まったことを記録しておきます。

## はじめに (mruby on EV3RT + tecs とは?)
[レゴ®マインドストーム EV3](http://www.lego.com/ja-jp/mindstorms/about-ev3)をmrubyのコードで動作させるためのプラットフォームです。  
2015年10月10日現在、1.0.2がリリースされています。  
今回は、[ETロボコン](http://www.etrobo.jp/)でも使うEV3wayを動作させてみました。

## ダウンロードとインストール
ダウンロードからインストールまでです。  
今回は最新の mruby-on-ev3rt+tecs_package-alpha1.0.2.tar.gz を使います。

なお、公式のドキュメントがWindows(Cygwin)向けのため、それに沿って行います。Linux版は後述します。

1. [mruby on EV3RT + tecs](https://www.toppers.jp/tecs.html#mruby_ev3rt)をダウンロードします。
2. 適当なフォルダに展開します。
3. 展開したフォルダの `doc/mruby_on_ev3rt+tecs_build.pdf` の手順に沿ってインストールします。  
   このとき、P.3の環境の構築 Cygwinインストールで、**rubygemsパッケージもインストールが必要**でした。  
   インストールされていないと、P.6 コンパイル手順のmrubyビルドの`make`でいきなり失敗します。

これ以外は、特に問題なくインストールできました。

## 2輪倒立振子のサンプルコードのビルドと実行
展開したフォルダの `hr-tecs/workspace/mruby_samples/` にあるボタンやセンサーなどのいくつかのサンプルファイルを動作させることができたので、ev3way_sampleの動作を試しました。

EV3wayは2輪倒立振子で自立して走行するロボットで、ちょうどセグウェイのような制御を行っています。

[組み立て手順書](http://sourceforge.net/projects/etroboev3/files/BuildingInstructions/EV3wayET03.pdf/download)に沿ってEV3wayを組み立てて、サンプルコードに沿って配線を行ったところ、素直に動作しました。

ただ、両肩にあるタッチセンサーとジャイロセンサーの一を入れ替えて、配線もジャイロセンサーを`port_1`に接続すると、ジャイロセンサーが利用できず動作しません。  
おそらく、Port1はシリアル通信用に設定されているため、ジャイロセンサーのような複雑なセンサーでは動作しないものと推測します(タッチセンサーのような単純なセンサーなら動作する模様)。

> （シリアルに使用するため、現在Port1にセンサを取り付けできない制約があります）
  mruby_on_ev3rt+tecs_build.pdf P.20

ということで、多少の問題はありますが、mrubyでEV3を動作させる環境は構築できました。

## Linuxへのインストール
続いてLinuxにインストールしてみます。
LinuxはDebian 8.2を使いました。

以下は mruby_on_ev3rt+tecs_build.pdf の手順を行った結果です。

### クロスコンパイラとmkimageのインストール
[ここ](https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q3-update/)から[gcc-arm-none-eabi-linuxをダウンロードし](https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q3-update/+download/gcc-arm-none-eabi-4_8-2014q3-20140805-linux.tar.bz2)て、展開して `bin` フォルダにパスを通します。

成功したかどうかの確認は、手順書の通りです

また、mkimageは`apt`でインストール可能です。

- `apt-get install u-boot-tools`

### mrubyのビルド
手順通りmrubyをビルドします。

- `apt-get install ruby bison make gcc`
- `cd mruby`
- `make`

こちらも、手順書にあるメッセージが表示されれば成功です。

### EV3RT+tecs・EV3ドライバのビルド
続いて手順書通りtecsをビルドします。  
ただ、`hr-tecs/workspace/mruby_samples/Makefile` はWindows用のため、Linux用に修正します。

```
diff Makefile{.bak,}
153c153
< #MKIMAGE = mkimage
---
> MKIMAGE = mkimage
155c155
< MKIMAGE = $(SRCDIR)/../bin/mkimage.exe
---
> #MKIMAGE = $(SRCDIR)/../bin/mkimage.exe
162c162
< TECSGEN = $(SRCDIR)/tecsgen/tecsgen/tecsgen.exe  -k euc --cpp="$(GCC_TARGET_PREFIX)gcc -E"
---
> # TECSGEN = $(SRCDIR)/tecsgen/tecsgen/tecsgen.exe  -k euc --cpp="$(GCC_TARGET_PREFIX)gcc -E"
166,167c166,167
< #RUBYLIB = $(SRCDIR)/tecsgen/tecsgen
< #TECSGEN =$(RUBY) $(SRCDIR)/tecsgen/tecsgen/tecsgen.rb -L $(RUBYLIB) -k euc --cpp="$(GCC_TARGET_PREFIX)gcc -E"
---
> RUBYLIB = $(SRCDIR)/tecsgen/tecsgen
> TECSGEN =$(RUBY) $(SRCDIR)/tecsgen/tecsgen/tecsgen.rb -L $(RUBYLIB) -k euc --cpp="$(GCC_TARGET_PREFIX)gcc -E"
```

その上で手順書のコマンドを実行します。

- `cd hr-tecs/workspace/mruby_samples`
- `make tecs`

これは大した問題もなく成功します。

### ファイルの依存関係の抽出
ここで `cfg` がないため引っかかりました。
先に `cfg` をビルドします。

- `apt-get install g++ libboost-all-dev libxerces-c-dev`
- `cd hr-tecs/cfg`
- `chmod +x configure`
- `./configure --with-libraries=/usr/lib/i386-linux-gnu`
- `make`

成功すると `cfg --version` で以下が表示されます

> $ cfg/cfg --version
> TOPPERS Kernel Configurator version 1.9.3

その上で、手順に沿って依存関係を抽出します。

- `cd hr-tecs/workspace/mruby_samples`
- `make depend`

確認方法は P.11 の通りです。

### アプリケーションのビルド
最後はアプリケーションのビルドですが、これは特に問題なくできました。

- `make`

これで、SDカードのルートに `uImage` ファイルが作成されます。

## 感想
EV3RT + tecsはバイナリになっている分起動が速く、動作もそれなりな雰囲気でした。

一方で都度のビルドが必要だったり、tecsの思想としてコンポーネントの静的な生成と結合を基本としていてどこまで動的なコードが許されるか分からないなど、Rubyらしさを活かした開発についてはまだまだこれからな様子でした。
調べる途中で[参考にしたQiita記事](http://qiita.com/yamanekko/items/c2adb87031bf38bb8a13)では、独自版の mruby-ev3rt を作って、動的ロードも対応されていたので、単純には行かないのかもしれません。

## 参考資料
- [組込み向けスクリプト言語mrubyをEV3で動かしてみよう](slideshare.net/takuyaazumi3/mrubyev3)
- [EV3RT用mrubyサンプルコードの使い方](http://qiita.com/yamanekko/items/c2adb87031bf38bb8a13)