2014年6月29日日曜日

Raspberry Piでドリトルを実行する(解決・追記あり)

(追記:最新のRaspbian(2014/6/20付)ではOracle JDKの7と8が最初から入っているので、以下の記述の先頭にある、apt-getでOracle版を入れる作業は不要です。2014-07-02)
(追記:Oracle Java EE 8 JDKを使うということと、RXTXが使えるようなshell scriptに訂正した。headlessとheadfulについても補足した。2014-07-01)

以前にも書いたのだけれども、教育用プログラミング言語「ドリトル」は、OpenJDK7で動作するが、いまはOracle Java EE 8がheadlessじゃなくてAWTも含む形で配布されているので、そちらを使うことにする。なので、
$ sudo apt-get install oracle-java8-jdk
でいくことにする。以前、openjdk-7-jreを入れていた人は、
$ sudo apt-get delete openjdk-7-jre
$ sudo apt-get autoremove
してから、Oracleのやつを入れることになると思う。というのも、どうも、OpenJDKでRXTXが使えているという話がなくって、Oracleのを使えという意見が散見されるから。実際には追ってないのでよくわからないけど。

ただ、Oracleので実行すると、日本語フォントが明朝になるのがどうも残念。このあたり誰か教えてほしいかもしれない。

(追記:OpenJDK-7が持っている、fontconfig.propertiesを/usr/lib/jvm/*/jre/lib以下に置いてやれば解決した。したがって、いったんOpenJDK-7を入れてから同ファイルをどこかにコピーしておき、apt-get remove後に当該の場所へ残しておいたファイルを入れてやればいいことになると思われる。なお、この設定ファイルはvlgothic, IPA, sazanamiあたりを使うので、もしこれらのフォントが入っていなければ、apt-get install fonts-ipafontなどで入れてやらなと効果が出ない。)

それで、ドリトル本体なのだが、普通にzipファイルを展開してもうまくいかないので、だいたい次のような手順をとればよいのではないかと思う。
$ cd   ←ホームディレクトリにいる。ここにダウンロードしたzipファイルを置いておく。
$ mkdir dolittle
$ cd dolittle
$ unzip ../dolittle232.zip ←適当に、その時点での最新のものを展開
$ rm -r lib* ← RXTXライブラリがIntel用なので捨てる
$ sudo apt-get install librxtx-java ← ARM版のRXTXをインストールする
それで、dolittle.shは、以下のものに置き換える。
#!/bin/sh
cd /home/pi/dolittle
java -cp /usr/share/java/RXTXcomm.jar:dolittle.jar -Djava.library.path=/usr/lib/jni -Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0 o3.UI 2>&1 /dev/null &
要するに、ドリトルを展開したディレクトリをカレントディレクトリにして、そこでjava実行し、標準エラー出力に出てくるJVMのエラーメッセージを/dev/nullに捨てるということ。

(追記:2>&1じゃないと、1って名前のファイルができますな。すみません。それと、/usr/lib/jniの下にRXTXのネイティブコードがあるんだけれど、そこをオプションで指さないとだめみたいだったので、追記しました。さらに、Raspbianの場合、シリアルポートをシステムプロパティで指定する必要があるんだそうで、この一連の作業でRXTXの問題が完全解決しました。2014-07-01)

Raspberry Piの場合、例えばArduinoを接続すると/dev/ttyACM0というデバイスができる。これは特にシステムプロパティで指定しなくてもドリトルから見つかるのだが、通信の設定が正しいかどうかは不明。デジタルもアナログも、コマンドはドリトル側から送信するのだがArduinoは正しく受け取っていないように見える。一方、GPIOに出ているシリアルポートは/dev/ttyAMA0で、これを使うと問題なくArduinoと通信することができた。

Arduinoのシリアルポートは5Vで、Raspberry PiのGPIOは3.3Vだから、直結してはいけない。正しくはレベルコンバータを通して(専用ICもあるけれどトランジスタと分圧抵抗で自作してよい)つながなければ、Raspberry Piを壊す可能性があるが、シリアルに関しては、この記事にあるように、RX端子だけ分圧するのでなんとかいけるようだ。同記事には、GPIOのシリアルポートをシリアルコンソールを解除して自由に使えるようにする設定も記述されているので参照されたい。

なお、Javaのシステムプロパティを操作しなければいけないという話は、ArduinoのサンプルJavaコードのコメントに書かれている。
(追記:今回の場合、dolittle.jarが相対パスなので、カレントディレクトリをdolittle.jarがある場所にしておかないと、headless modeという、グラフィック機能をオフにしたJVMが起動してしまうことがある。headfulかheadlessかのフラグは、システムプロパティのjava.awt.headlessに論理値で指定できるので、javaのオプションに「-Djava.awt.headless=false」を書いておけばheadlessが選ばれる可能性はなくなるが、カレントディレクトリが間違っていた場合は結局「o3.UIが見つかりません」とか「mainが見つかりません」のようなエラーになるので、よしあしではある。このへんは、Oracleのjava seにおけるheadlessについてのページに書かれている。 2014-07-01)

さらに、デスクトップにアイコンを置くために、ayumi.pngをjarから取り出しておく。
$ unzip dolittle.jar image/ayumi.png
$ mv image/ayumi.png .
$ rmdir image
で、デスクトップの設定を以下のように書いておく。ファイル名は、~/Desktop/dolittle.desktopでいいと思う。
[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Exec=/home/pi/dolittle/dolittle.sh
Icon=/home/pi/dolittle/ayumi.png
Terminal=false
Name=Dolittle
Name[ja]=ドリトル
Comment= Dolittle Programming System
Categories=Application;Education;Development;
MimeType=application/x-dolittle-program
Scratchの設定をパクらせてもらったので適当だけれど、まぁこんな感じなんではないかと思う。さらにこれをLXDEのメニューに反映させるため、
$ sudo cp dolittle.desktop /usr/share/applications
しておくと幸せな感じになるような気がします。
LXDEのメニューに追加された

ドリトル実行中