LEGO Mindstorm NXT を買って久しいのですが、ずっと忙しかったこともあってあまり有効活用できていない気がします。(もったいない)
そもそも NXT を購入した目的は NXT を自在にプログラミングしてコントロールしたいということだったわけなんですが、せっかくなので最近買った Mac を使って、最近話題の Ruby を覚えつつ、ロボットでも作って遊べたら楽しいだろうなぁと思って、ちょっと調べてみました。
すると、どうやら Mac + Ruby + Mindstorm NXT という組み合わせを実現してくれそうな、ruby-nxt というオープンソースのライブラリがあるようです。ちなみにこれは Windows でも使えるようです。
[2007.11.25 追記] Windows でも試してみました。
DIGGING DEEPER
NXT をプログラムで制御する 2 つの方法
NXT をプログラムで制御する方法には大きくわけて 2 通りあります。
1 つは NXT のオリジナルのファームウェアのままで、ホストになるコンピュータと通信しつつ、ホスト側のプログラムで判断や制御のロジックを動かす方法です。
もう 1 つは NXT のファームウェアを書き換え、NXT 上に制御プログラムをダウンロードし、基本的にはスタンドアロンで動作させる方法です。
もちろん、後者でもホストと通信してコマンドを受け取ったりする場合もあります。主な違いは、ファームウェアを書き換える必要があるかどうかという点です。
ruby-nxt は前者のタイプです。
ruby-nxt を使うと、ホスト側で Ruby のプログラムを書き、Bluetooth の仮想 COM ポート経由で NXT とやりとりしながらセンサーの値を読み取ったりモータの制御をしたりできます。
この方法は、2 輪車のバランスをとるといったようなリアルタイム制御が必要な用途に使うことは難しそうですが、私のような初心者でも気軽に試してみることができそうです。
先日マカーになったばかりの私としてはこの ruby-nxt をまずは Mac で使ってみたいと思いますが、いずれ Windows でも試してみたいと思います。
というわけで Mac 編
まずは私の環境を書いておきます。
MacBook Pro (Core 2 Duo 2.2GHz)
Mac OS X Leopard 10.5.1
Memory 2GB
Apple Bluetooth ソフトウェアのバージョン: 2.0.0f20
といったところでしょうか。
Ruby 関連は初期状態のままです。
ruby-nxt を使うためには、先に ruby-serialport というモジュールをビルドする必要があるようです。
Bluetooth 経由で NXT をコントロールするためには仮想 COM ポートを使うので必要というわけですね。
ruby-nxt が USB 接続に対応しているのかどうかちょっとわからなかったので、以下の文章は Bluetooth を前提に書いています。最近の Mac は標準で Bluetooth 搭載のものが多いようなので問題ないでしょう。
ruby-serialport をインストール
ruby-serialport はこちらからダウンロードしました:
http://rubyforge.org/projects/ruby-serialport
私がダウンロードしたときのバージョンは 0.6 でした。
Mac 用にはコンパイル済みのものがないようでしたので、ソースをダウンロードしました。
(ruby-serialport-0.6.tar.gz)
新しいバージョンが出ていたら教えてください。
(といっても、最後のバージョンがリリースされたのが 2003 年のようなので、今後も滅多なことではバージョンがあがったりしなさそうですが)
ダウンロードしたら、これをコンパイルします。
ダウンロードした .tar.gz ファイルを展開したディレクトリに移動して、そこで以下の順で 3 つのコマンドを順に実行します。
1) ruby extconf.rb
2) make
3) make install
1) ruby extconf.rb
$ ruby extconf.rb
checking for OS... darwin
checking for termios.h... yes
checking for unistd.h... yes
creating Makefile
2) make
$ make
gcc -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 -I. -DHAVE_TERMIOS_H -DHAVE_UNISTD_H -fno-common -arch ppc -arch i386 -Os -pipe -fno-common -Ddarwin -c serialport.c
serialport.c: In function ‘sp_create’:
serialport.c:591: warning: passing argument 1 of ‘rb_io_close’ makes integer from pointer without a cast
serialport.c: In function ‘sp_create’:
serialport.c:591: warning: passing argument 1 of ‘rb_io_close’ makes integer from pointer without a cast
cc -arch ppc -arch i386 -pipe -bundle -o serialport.bundle serialport.o -L"." -L"/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib" -L. -arch ppc -arch i386 -lruby -lpthread -ldl -lm
3) make install
$ make install
/usr/bin/install -c -m 0755 serialport.bundle /Library/Ruby/Site/1.8/universal-darwin9.0
いろいろ表示されていますが、コマンドを実行したら表示されただけなので特に難しいことはないと思います。
ちなみに私は Leopard を買ってきてほとんどそのままの状況で上記の 3 つのコマンドを実行しました。
ほかに何かインストールされている場合や、Tiger などの OS の場合はもうちょっと事情が違うかもしれません。
ruby-nxt のインストール
次はいよいよ ruby-nxt をインストールします。
私がインストールした時点での最新バージョンは 0.8.1 でした。
gems のリンクもあったのですが、なぜかリモートから直接のインストールがうまく行きませんでしたので .gem ファイルをダウンロードし、ローカルからインストールします。
$ sudo gem install ruby-nxt-0.8.1.gem
Successfully installed ruby-nxt, version 0.8.1
Installing ri documentation for ruby-nxt-0.8.1...
Installing RDoc documentation for ruby-nxt-0.8.1...
これでインストールは完了です。
なんだか意外とあっけないですね。
ruby-nxt のテスト
インストールが完了したら、テストプログラムを実行してみましょう。
/usr/lib/ruby/gems/1.8/gems/ruby-nxt-0.8.1/ にインストールされているテストプログラムをホームディレクトリ等にコピーしてきて使いましょう。
実行する前に、テストプログラムをちょっと修正する必要があります。
ruby-nxt-0.8.1/test/test.rb を開いて、最初の方の行を以下のように修正します。
before
require "nxt_comm"
after
require "rubygems"
require "nxt_comm"
(require "rubygems" の行を追加します。 )
(RubyGems で ruby-nxt をインストールした場合はこの行が必須なようです。これから実行するほかのテストプログラムでも同様に修正する必要があります。)
それでは、いよいよ実行します。もちろんその前に NXT と Mac を Bluetooth で接続済みであることを確認してくださいね。
接続済みであることを確認できたら、以下のようにコマンドを実行します。
$ ruby test.rb
Connected to: /dev/tty.NXT-DevB-1
Sending Message: 0x07 0x00 0x00 0x03 0xf4 0x01 0xf4 0x01 0x00
Received Message: 0x03 0x00 0x02 0x03 0x00
スクリプトがコンパイルされてコマンドが NXT に送信されるまでの数秒間ドキドキしながら待つと、NXT からビープ音が聞こえてくるはずです。
もうひとつのテスト
続いてもう一つのテストプログラムを実行しましょう。
実行するプログラムは、ruby-nxt-0.8.1/test/unit/nxt_comm_test.rb です。
これも test.rb と同様に require "rubygems" の行を追加しておいてください。
さらに、今回のテストプログラムはタッチセンサーを NXT の 1 番のポートにつないでおくと楽しめるかもしれません。
それでは実行してみましょう。
$ ruby nxt_comm_test.rb
Loaded suite nxt_comm_test
Started ...................
Finished in 18.7951 seconds.
19 tests, 41 assertions, 0 failures, 0 errors
上記のように表示されましたか? 0 failures と表示されていれば OK でしょう。
実行中に NXT のディスプレイにミニフィグの顔が表示されたら、タッチセンサーを押してみましょう。ミニフィグが Oops! ってしゃべりますよ。
もっとも、タッチセンサーを触らなくても(つないでさえいなくても)テスト自体は通るようですが。
ちょっと長文になってきましたので、つづきは次回としたいと思います。