2013年3月26日火曜日

Raspberry Pi用のJVMとドリトルの動作について

Raspberry Pi搭載のセンサー付きロボットカーを構想しているところ。

ただし、本業の授業用なので、プログラミング言語としてはドリトルで、ということになる。ドリトルはJavaで記述されているので、JVMさえあればひとまずどんな環境でも起動させることはできることになっている。

一方で、Raspberry Piはメモリが512KBあるとはいえ、あくまで組み込みLinuxが主な動作環境なので、通常のJava SEが動くかどうかがはっきりしなかった。結果としては、OpenJDKであればRaspberry Piでもドリトルが通常通り使えることが確認できた。パッケージ名としては、現状ではopenjdk-7-jre。これをapt-get installするだけでいい。JVMはzeroとjamvmが入る。どちらもAWTやSwingなどX11の画面にグラフィクス描画ができ、JITも組み込まれた、ほぼJava SE互換のもの。しばらく前まではRaspberry Piの現在の基板に使われているSoCのhard floatには対応しておらず、Raspbian(Raspberry Pi用Debian)そのものがsoft floatでコンパイルされたバイナリ上でしか動作しなかったが、現在はarmhfに対応しているので通常のRaspbianからapt-getするだけでよい。

ドリトルは普通にLinux用に用意されているshell scriptから起動できる。ただし、起動まで6秒程度、また、ダイアログ等の表示がもたもたして、軽快とはいえない。zeroよりjamvmのほうがましだという説にしたがって、javaの起動オプションに「-jamvm」を加えてみたが、はっきりとわかる違いは感じられなかった。

ドリトルの特徴は日本語の命令語やパンクチュエーションが使えることにあるので日本語入力も入れておきたいところだが、これは一般的なibus-anthyを入れることで対応した。当初、英語キーボードをつないでいるせいかIMEの切り替えができないようだったが、自分の趣味でfonts-ipaex(IPAexフォント)を入れて、ibusの設定でそれを表示フォントにしたところでなぜだかうまく切り替えられるようになった。理由は追求していない。ibusの設定ファイルで肝心なものがそのタイミングで生成されたのかなにか、そんなところかと思う。

ドリトルの編集画面(プログラム記述画面)で日本語入力するが、やはり動作はもたつく。といっても、anthy自体が律速なのでしかたがない。入力が遅れてくるので先に確定をすると、確定だけが先に入って遅れてきた入力が捨てられるなど、うーむと思ってしまうところはある。ただ、授業の範囲では許容できると判断した。

OpenJDK上のドリトルの最大の問題は、やはりグラフィクスにある。定番の
カメ太=タートル!作る。
の1行を実行すると、タートルが現れるまでジャスト5秒待たされる。これはきつい。とはいえ、いったん現れたタートルを動かす分には全く遅さを感じなかったので、タートルの画像を読み込むところでの問題なのかもしれない(標準の画像はjarに同梱だがオンメモリになくてSDカードからunzipしながら読んでいるため遅くなるのかもしれない)。ロボット制御には関係なさそうなので気にしないか、オーバークロック設定をして時間を若干短縮するかは今後考えることにした。

なお、Raspberry Pi用でグラフィクスが使えるもうひとつのJVMにavianがあるが、これはフットプリント(メモリ専有量)を最小限にするためにJITを内蔵していないので、インストールして試してみたが、ひどい結果になった。起動に10秒強、タートルが現れるのもやはり10秒そこそこ、終了の際の確認ダイアログなども2秒待ちで現れるような状態で、これは全く使い物にならない。

一方、Oracleが提供しているJava ME 8のearly access版は「headless」といい、AWTやSwingは使えない。かわりにJavaFXを使えということのようだ。ただし、Raspberry Pi用のJavaFXはOpenGL ES2でフレームバッファに直接書き込む実装とのことで、X11の画面を上書きしてしまう。JVMそのものの速度、JavaFXの速度ともに十分ということなので、テレビに映し出すにはベストの選択といえるが、授業ではVNCを使ってモニタやキーボード・マウスすべて学生個人のノートPCのみで済ませるつもりなので、X11の画面転送しかできない既存のVNCの実装では対応できないし、JavaFXそのものについても知識がないので授業にはもう間に合わない選択肢となった。

OracleのRaspberry Pi用Java 8は、GPIOをフルアクセス(Serial, I2C, SPIなどを含む)できるクラスライブラリを持つとのことで、組み込みJavaならではの開発に特化した実装のようではある。

ともあれ、OpenJDK 7があれば、ドリトルの画面だけで完結するプログラムの利用には全く支障がないようだ。また、未確認だがRaspberry Piのフォーラムには、RXTXがそのまま使えるという風な記述があるので、シリアルポートでの通信もそのまま使える可能性があり、MYUロボへのプログラム転送程度ならば現状のまま動くのかもしれない。

残る問題は、GPIOのアクセスをどうするかという部分である。OpenJDKのまま正攻法でいくならば、WiringPiのJava NIO実装を用いてJavaのコードを追加するやりかたなのだろう。これはGPIOを/dev/mem経由でアクセスするとのことで、速度についての不安はまったくないように思われる。また、ArduinoのWiringクラス準拠のAPIのようだ。ただ、ドリトル本体をいじることになるのでこれがどの程度の工数になるのか僕には見積もることができない。

最も簡単なのは、Wiring Piのコマンドライン実装を呼び出す方法だが、いちいちプロセスをexecすることになるので実用性の点で不安がある。割りきってしまうならば、WiringPiのexampleにあるようにデバイスごとの専用コマンドを作り(LCDやファミコン用リモコンなどのサンプルがある)、必要に応じて呼び出すやりかたでもよいのかもしれない。ただし、汎用性はない。

いまのところ、WiringPiサーバデーモンを作り、シンプルなバイナリプロトコルを通じてやりとりできないか、ということを考えている。現在の開発バージョン2.32はKineXというKinectの骨格情報をストリームするアプリケーションからsocket経由で値を取得する実装が含まれている。そこで2.32版ドリトルにはsocket通信に関する一般的なクラスが用意されているかと期待したが、KineX専用のクラスが実装されているようで、結局ドリトルに手を入れなければならないことにはかわらないようだ。ただし、WiringPiのNIOを組み込んでしまうとドリトルでしかうれしくないが、WiringPiサーバデーモンは他の言語からも利用可能という汎用性があり、世の中のためにはなるかもしれない。どちらにするかはわからないし、外部コマンドで済ませることになるかもしれないが、いずれにせよ時間との勝負ではある。

2013年3月1日金曜日

Raspberry PiのXMBCで日本語ファイル名表示

順番が間違っているような気がするが、Raspberry Piがあり、HDMIでディスプレイにつないでXBMCメディアセンターが動いているという状態からはじめる。

SMBでWindowsマシン上にある動画ファイルのフォルダをマウントして再生しようというわけである。

XBMCはPi用LinuxであるRaspianとは別に、最小限の内容にしぼったOpenELECという組み込みLinuxの上で動くイメージファイルが配布されている。このイメージファイルで起動すると、FAT16のパーティションの次にExt4パーティションができ、そこにOpenELECが展開され、以後ここから起動する。

Raspberry PiのGPUアクセラレーションのおかげで、全く問題のない性能が出ている。ところが、ファイル名に日本語が使われていると、その部分は空白になってしまい、どれがどれだかわからないことになる。理由は簡単で、Unicodeフォントを搭載しているものの、日本語のグリフが含まれないものだけがあるからだ。

このあたりは自分でソースからビルドするならばどうにでもなるのだが、あいにく手元に適当なLinuxマシンがなく、起動しているOpenELECにsshログインしてフォントを書き込みたいということになるものの、ルートパーティションはread onlyでマウントされており、面倒だ。また、OpenELECそのものが頻繁にアップデートされていることを考えると、バックアップできない場所にはフォントを置きたくない。

手っ取り早く書き換えできるのが、メディア(動画や音声、写真など)を置く/storage以下となる。

XBMCのUIは、Skinによって全く違うものに変更できる。UIはXMLで定義されていて、画像ファイルもフォントもメッセージもすべてSkinによって置き換えができる。要するに、日本語フォントを含むSkinを自前で作り、addonとして組み込んでしまえば解決というわけだ。

ここではひとまず、その前段階として、適当なSkinをaddonとして導入し、それをsshログインした状態で書き換えて対処してみる。

オフィシャルに提供されているSkinのなかで、今回はXeeboを選んでみた。デフォルトとは大きく異なり、タッチパネルでの操作を意識したという、UIパーツのサイズが大きめで、フラットデザインのすっきりした印象のものだ。

addonは、/storage/.xbmc/addon以下に書き込まれる。Xeeboは、skin.xeeboというディレクトリ以下に展開されている。フォントは720p/fonts以下、フォントの設定は720p/Fonts.xmlに記述されている。

そこで、適当な日本語グリフを含むUnicodeフォントとして、IPAexフォントを選んでみた。IPAexゴシックを使うことにする。ファイル名はipaexg.ttfだ。そこで、
$ scp ./ipaexg.ttf root@IPアドレス:/storage
として、書き込みができる/storageのところにコピーする。その後、OpenELEC側で
# mv ~/ipaexg.ttf ~/.xbmc/addon/skin.xeebo/720p/fonts
で、所定の場所に入れてやる。ここには専用にデザインされたxeebo.ttfとxeebo-light.ttfが入っている。ファイル名を表示するのはxeebo.ttfのほうなので、ipaexg.ttfをこの名前で上書きしてもいいかもしれない。ただ、XMLファイル~/.xbmc/addon/skin.xeebo/720p/Fonts.xmlを編集して、xeebo.ttfをipaexg.ttfに置き換えるのでも同じことだ。再起動すればちゃんと日本語のファイル名が表示される。

XBMCの設定で、autoupdateするようにしていると、Skinが置き換えられてすべてが無になるかもしれない。それを避けるなら、自分で別名のテーマを作成し、zipして、/storage直下に置き直接インストールするのが無難だろう。いまのXeebo改造版をzipしてバックアップをとっておくのがいちばん簡単といえる。

ひとまず、当面の解決ということでこの項を終わる。