2014年12月12日金曜日

Intel Edisonで映像配信中のカメラのパン・チルトを制御してみた

はじめに



にて、Intel EdisonにてWebカメラを有効にし、mjpg-streamerで映像を配信してみました。

今回は、Intel Edisonを使ったデモとして、そのWebカメラにサーボモーターを2つ取り付け、Web経由でパン・チルト(水平方向と垂直方向)を制御してみました。

全体像は下図のようになります。カメラの他は、Intel Edison Breakout Board、レギュレータやレベルシフタを含む周辺回路、バッテリー(Eneloop Pro6本)が見えます。

コントローラーはPC、タブレット、スマートフォンなどのブラウザです。



動作状況の動画はこちらになります。




カメラ雲台の準備

カメラとサーボモータ2つを接続する方法ですが、なるべく楽をしたかったので、秋月電子通商にある


を用いました。



この組み立て方は


にあります。これを見るだけでも大変そうなのはわかりますが、実際に手元に届いてみると

  • ニッパ、ピンバイス、ヤスリによるパーツの加工が必須
  • 必要なネジが全然足りない(と思う)
  • 2つのサーボSG-90の品質が悪く、最初から正常動作しないことがある

のように、なかなか骨のあるキットです。

ちなみにサーボSG-90は秋月やamazonなどでも追加注文できますが、店によってはバージョン違いなのかサーボのケースサイズやサーボホーンの径が異なり、さらに加工が必要になったりします。なお、私の場合、SG-90を計12個入手して、正常動作したものは10個でした。

さらに、このキットに付属するWebカメラはMJPEGモードに対応していないので、「Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた 」で紹介した方法では映像配信できません。

私は手元で余っていたLogicool C210を加工して取り付けました。Logicoolのものなら大抵大丈夫だと思います(今にして思えば、もっと画質の良いものにすれば良かったかも)。


回路の接続

作成したカメラ雲台を下図のようにIntel Edisonと接続します。


いくつかコメントします。

USBカメラを使うため、電源は7V~15VをJ21に入力します。バッテリーを用いたかったので、Enelooop6本を用いることにしました。容量の大きいEneloop Proにしましたが、これはお好みで。

サーボモーターは5Vで駆動するため、レギュレータTA4805Sで5Vを作ります。これは手元にあったものをそのまま用いました。

Intel Edisonからは下記の5つの信号を引っ張りだしました。Intel Edisonを外した状態で、Breakout Boardにケーブルを直接半田づけしました。

  • J17-1:サーボ用PWM
  • J18-1:サーボ用PWM
  • J18-2:GPIO。プルアップされた入力として用いて、シャットダウンスイッチに利用します。
  • J19-2:1.8V
  • J19-3:GND
各ピンの情報はIntel Edison Breakout Board Hardware GuideのPDFファイルを参考にしてください。

サーボモータ用に出力するPWM信号は1.8Vなので、サーボモータに与えるために5Vにレベル変換します。これも手元にあった「8ビット双方向ロジックレベル変換モジュール」を用いました。

PCとの接続は、J3のシリアルコンソールにより行います。

libmraaライブラリの準備

ここからはIntel Edison上での作業になります。あらかじめ、「Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた」に基づいてWebカメラの映像配信を有効にしておいてください。エントリ作成当時はポート8080を用いていましたが、ポート9000を用いるように変更しましたので、ご注意ください。

さて、スイッチサイエンスさんのページ「Intel Edison opkgのフィードを設定する」および「libmraaを使ってC++で開発する」を参考に、GPIOにアクセスするためのlibmraaライブラリをインストールします。

# vi /etc/opkg/myfeeds.conf

このファイルに下記の内容を記述して保存します。

src intel-iotdk http://iotdk.intel.com/repos/1.1/intelgalactic
src all http://iotdk.intel.com/repos/1.1/iotdk/all
src i586 http://iotdk.intel.com/repos/1.1/iotdk/i586
src x86 http://iotdk.intel.com/repos/1.1/iotdk/x86

書けたら、下記のコマンドを実行します。

# opkg update
# opkg upgrade
# opkg install libmraa0

これでlibmraaのインストールが完了しました。

node.jsで用いるモジュールの準備

node.jsによるWeb連携で用いるconnectモジュールとsocket.ioモジュールをインストールします。

# npm install connect@2.27.4
# npm install socket.io@0.9.17

使っているスクリプトの関係上、バージョンを指定して最新のものではないファイルをインストールしました。

これらのモジュールは/home/root/node_modules以下にインストールされます。

なお、libmraaライブラリに対応するmraaモジュールは/usr/lib/node_modules/mraaとしてインストールされていますが、これを/home/root/node_modulesにリンクしておかないと、自作のnodeスクリプトを/etc/rc.localから起動するときに失敗します。そのため、下記を実行しておきます。

# ln -s /usr/lib/node_modules/mraa /home/root/node_modules/mraa

ソースのダウンロード

ソースのダウンロードのために、gitをインストールします。

# opkg update
# opkg install git

次に、ソースをダウンロードし、pantiltという名前のディレクトリに保存します。

# cd
# git clone https://github.com/neuralassembly/Edison_pantilt.git pantilt

以下、いくつか解説を加えていきます。

シャットダウンスイッチ

シャットダウンスイッチを有効にするためには、下記のコマンドを実行します。

# python /home/root/pantilt/shutdown.py &

この状態で、回路上のタクトスイッチを2~3秒程度長押しすると、poweroffコマンドが実行され、シャットダウンが始まります。

中身は下記のようなPythonプログラムになっています。GPIO15はJ18-2のことであり、プルアップ抵抗つきの入力として設定しています。GPIO番号とピン番号の対応はこちらを参照。

import mraa
import time
import subprocess

sw = mraa.Gpio(15)
sw.dir(mraa.DIR_IN)
sw.mode(mraa.MODE_PULLUP)

state = 0

while True:
    if sw.read() == 0:
        if state == 2:
            state = 0
            args = ['poweroff']
            subprocess.Popen(args)
        else:
            state += 1
    else:
        state = 0

    time.sleep(0.5)

このshutdown.pyスクリプトを起動時に有効にするには、mjpg-streamerの自動起動の際に作成した/etc/rc.localに上記のコマンドを追記してください。

サーバーの起動

サーバーを起動するには、下記のコマンドを実行してください。

# node /home/root/pantilt/pantiltserver.js &

その状態でブラウザで


  • http://(Intel EdisonのIPアドレス):8080/


にアクセスすると、操作用のアプリが開きます。使用されているポートは下記の通りです。

  • 8080:ページの閲覧
  • 8888:socket.ioによるソケット通信
  • 9000:mjpg-streamerによる映像配信

JavaScriptで記述したpantiltserver.jsの中では、下記のようにJ17-1およびJ18-1ピンに対してPWM信号を出力しています。

var mraa = require('mraa');
var p0 = new mraa.Pwm(0);  // J17-1
var p1 = new mraa.Pwm(14); // J18-1

p0.period_us(19500);
p0.enable(true);
p1.period_us(19500);
p1.enable(true);

// For upper servo
var duty0min = 0.03; // min
var duty0max = 0.11; // max
var duty0 = (duty0min + duty0max)/2;

// For lower servo
var duty1min = 0.031; // min
var duty1max = 0.115; // max
var duty1 = (duty1min + duty1max)/2;

p0.write(duty0);
p1.write(duty1);

サーボモータに50Hzの信号を与えるのですが、細かな周期やパルス幅はオシロスコープの波形を見たりサーボモーターの振る舞いを見ながら微調整しました。Duty比は0~1の実数で指定します。

このpantiltserver.jsをIntel Edison起動時に自動実行する場合は、やはり/etc/rc.localに上記コマンドを追記してください。

ブラウザ上のアプリ

ブラウザのアプリは下図のように映像の下と右にjQuery UIによるスライダを配置してサーボモーターへの指令をJavaScriptで送るようにしています。iOSのSafari/ChromeやAndroidのChrome/Firefoxなどで動作を確認しています。画面の回転にも対応しています。



このアプリは、主に下記のファイルで構成されています。

  • index.html
  • js/pantilt.js
  • js/socket.io.js:node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.jsと同じもの
  • js/jquery/:jQuery UI用ファイル
  • css/pantilt.css

js/pantilt.js内で、映像の取得と命令の送信を行っています。

展示

このデモを2014年12月21日に東海大学高輪キャンパスで開催されたAndroid Bazaar and Conference 2014 Winterで展示しました(週アスPLUSさんにも写真があります)。


Androidのイベントなので、カメラを「Androidタブレットおよびそれとペアリングされた腕時計Android Wear」から操作できるデモとしました。Android Wearでの操作の技術的詳細は、「Android Wear (LG G Watch) でカメラからの映像を見ながら三輪ロボットを操作してみた」が関連します。

沢山の方にお越しいただき、ありがとうございました。

終わりに

Intel Edisonを用いた簡単なデモということで、カメラのパンチルトを制御してみました。

mraaモジュールを用いるとJavaScriptで直接GPIOにアクセスできるので、Web連携が容易であるという印象を持ちました。ただし、ドキュメントがあまり充実していないように思われるのが残念なところです(Pythonの入力ピンのプルアップ抵抗を有効にする方法を調べるために、mraaのソースをgrepしたりしました)。そのあたりは今後に期待でしょうか。

あとは、7V以上の電源の確保と1.8VのGPIO入出力のレベルシフトがやや面倒、というところです。

他のボードとの比較で言えば、Raspberry Piで同じことをやろうとする場合、Webカメラでは性能が出ないので、Raspberry Pi用のカメラモジュールを用いる必要があります。さらに、Raspberry PiではハードウェアPWMが一つしか使えないので、全く同じことをするのは少し面倒です。

BeagleBone Blackでは全く同じことを実現できるはずですが、私はBeagleBone BlackでのGPIOプログラミングは未経験なのでノーコメントです。

以上でした。

2014年12月3日水曜日

Intel EdisonでWebカメラを有効にしmjpg-streamerで映像を配信してみた

はじめに


2015.2.27 内容をアップデートしました

Intel Edisonは特に使い途が思いつかなかったので手を出していなかったのですが、2014月11月末のMaker Faire Tokyo 2014にて初めて実物を見たことと、スイッチサイエンスさんのブースで「スイッチサイエンス版Eaglet (MFTバージョン)」を購入したことをきっかけに、試してみることにしました。

目指すのは、いつもやっている「Webカメラを接続してmjpg-streamerで映像を配信する」こととします。

結果を先にお見せすると下図のような感じでです。Intel Edisonで配信した映像がAndroidタブレットに表示されていることがわかります。

なお、本ページで言う「Intel Edison」は、ほとんどの場合「Intel Edison Breakout Board Kit」を指していますのでご了承ください。


Intel Edisonのアップデート

このブログを執筆した2014年12月当時は、Intel EdisonでWebカメラを使うために、OSのイメージを自分でビルドする必要がありました。しかし、2015年1月に公開されたバージョンでは、デフォルトでWebカメラを利用可能になっています。

そこで、ここではまずその方法を解説します。Intel EdisonでのOSのイメージをビルドする方法が知りたい方は、このページの末尾に記録を残しておきますのでご覧ください。

本ページでは、Intel EdisonのアップデートをUbuntuで行うことにします。
まず、Ubuntuにて

$ sudo apt-get install dfu-util

を実行してdfu-utilをインストールしておきます。

次に、こちらよりYocto complete imageをダウンロードします。2015年2月27日の時点ではedison-image-ww05-15.zipがダウンロードされました。

その後、edison-image-ww05-15.zipと同じディレクトリにいるとして、下記のコマンドで書き込みます。

$ mkdir edison-image-ww05-15
$ cd edison-image-ww05-15
$ unzip ../edison-image-ww05-15.zip
$ sudo ./flashall.sh

このコマンドによりアップデートの待機状態になるので、Intel EdisonのJ16コネクタとUbuntuマシンをUSB接続してIntel Edisonに電源を投入すると、アップデートが始まります。J3コネクタにてシリアルコンソールに接続しておくと、進行状況がわかって安心です。

なお、UbuntuマシンとIntel Edisonとを既に接続済みだった場合はIntel Edisonをリブートすると、起動時に更新が始まります。

再起動が終わったら、Intel EdisonのJ16コネクタにUSBカメラ(要変換コネクタ)、J21ピンに7V~15Vの電源を接続します。J3コネクタのシリアルコンソールでログインすると、/dev/video0ができていることがわかります。

なお、この状態でIntel Edisonを再起動すると、カメラが認識されなくなります。一度電源を切ってから再投入することで認識されるようです。

mjpg-streamerのインストールと起動

ここからは主にシリアルコンソールで接続したIntel Edison上の作業になりますが、まず、「configure_edison --setup」コマンドにより、あらかじめIntel EdisonをWifi接続しておきます。詳細はスイッチサイエンスさんのページが詳しいです。

また、あらかじめUbuntuマシンでmjpg-streamerのソースをダウンロードしておきます。このダウンロードにはSubversionが必要なのですが、Intel Edison用のSubversionのパッケージが見当たらず、ソースからインストールするのは面倒だったため、Ubuntuであらかじめダウンロードしておく、というわけです。

(Ubuntuマシンで)
$ sudo apt-get install subversion
$ svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer

そして、できたmjpg-streamerディレクトリをWifi経由でIntel Edisonへ移動しておきます。

ここからIntel Edisonでの作業です。

まず、スイッチサイエンスさんのページ「Intel Edison opkgのフィードを設定する」を参考に、myfeeds.confというファイルを作成して編集を開始します。
# vi /etc/opkg/myfeeds.conf
このファイルに下記の内容を記述して保存します。
src intel-iotdk http://iotdk.intel.com/repos/1.1/intelgalactic
src all http://iotdk.intel.com/repos/1.1/iotdk/all
src i586 http://iotdk.intel.com/repos/1.1/iotdk/i586
src x86 http://iotdk.intel.com/repos/1.1/iotdk/x86
書けたら、下記のコマンドを実行します。
# opkg update
# opkg install libjpeg-dev libv4l-dev
# cd mjpg-streamer
# vi Makefile

ここで、Makefileの39行目でinput_testpicture.soをビルド対象に含めている部分を下記のようにコメントアウトします。

# PLUGINS += input_testpicture.so

input_testpicture.soのビルドにはImageMagickが必要なのですが、ImageMagickのIntel Edison用のパッケージがなく、またその名前の通り、input_testpicture.soはテスト時以外なくても困らないためです。

以上のもと、ビルドします。

# make

ビルドが完了したら、下記のコマンドにより、mjpg-streamerを起動します。

# export LD_LIBRARY_PATH="$(pwd)"
# ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "./output_http.so -p 9000 -w ./www"

あとは、ブラウザで

http://Intel EdisonのIPアドレス:9000/

にアクセスすると、映像が配信されていることがわかります(2014.12.11追記。後に追加するエントリとの整合性をとるため、ポート番号を8080から9000に変更しました)。

Androidの場合は簡単MJPEGビューアを使ってもよいです。ポート番号はソフトウェアキーボードで9000と変更してください。

mjpg-streamerの自動起動

最後に、Intel Edisonに電源を入れた際にmjpg-streamerが自動で起動するようにしておきます。

まず、mjpg-streamerディレクトリにstart_mine.shファイルを作成します。

# cd
# vi mjpg-streamer/start_mine.sh

中には例えば以下の内容を記します。

#!/bin/sh

cd /home/root/mjpg-streamer
export LD_LIBRARY_PATH="$(pwd)"
./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "./output_http.so -p 9000 -w ./www"

次に、このスクリプトを/etc/rc.localに記述して、起動時に自動的に呼び出されるようにします。

# vi /etc/rc.local

内容は下記の通りです。

#!/bin/sh

sh /home/root/mjpg-streamer/start_mine.sh &

最後に、/etc/rc.localのパーミッションを755にしておきます。

# chmod 755 /etc/rc.local

以上が済んだ後、Intel Edisonの電源を切り、電源再投入してください(リブートでは駄目)。mjpg-streamerが自動で起動していることがわかるはずです。

終わりに

Intel EdisonでWebカメラの映像を配信してみましたが、Raspberry PiやBeagleBone Blackと比べた場合のメリットは、5GHz帯のネットワークにデフォルトで接続できることでしょうか。Raspberry PiやBeagleBone Blackで5GHz帯のネットワークにつなぐにはGW-450Dを使う方法がありますが、kernelの再構築が必要であるなど、やや面倒です。

とは言え、Intel Edisonの方でも、7V~15Vの電源が必要な点など使いにくいところはあります。

以上です。

こちらもどうぞ

このページの話の続きです。




kernelとOSイメージの作成

既に述べたように、2014年12月の時点では、EdisonのデフォルトのkernelはUSB Video Class (UVC)が有効になっていなかったので、それを有効にしたkernelと、それを含むOSイメージを作成する方法を解説しました。

現在はUVCがデフォルトで有効になっていますのでこの作業は必要ないのですが、記録としてその方法を以下に残しておきます。

この作業はUbuntuで行いました。作業の概略はIntel Edison BSP User Guideにまとめられています。

まず、Ubuntuに必要なパッケージをインストールします。

$ sudo apt-get update
$ sudo apt-get install build-essential git diffstat gawk chrpath texinfo libtool gcc-multilib

次に、こちらよりLinux source filesをダウンロードします。2015年2月27日の時点ではedison-src-ww05-15.tgzでした。このファイルを

$ tar zxf edison-src-ww05-15.tgz

により解凍します。edison-srcというディレクトリができますので、以下の順でまずはデフォルトのイメージを作成してみます。なお、この際環境変数PATHにカレントディレクトリ「.」が含まれているとエラーが出ますので、あらかじめPATHから「.」を削除しておきます。

$ cd edison-src
$ ./device-software/setup.sh
$ source poky/oe-init-build-env
  (ここで、自動的にedison-src/buildにcdされる)
$ bitbake edison-image

なお、最後のコマンドを実行すると、途中で様々なファイルのダウンロードが行われますが、環境やタイミングによりダウンロードエラーが起こることがありますので、エラー出ずにビルドが終了するまで繰り返します。

私の場合、成功時に下記のようなメッセージが現れてビルドが完了しました。

NOTE: Tasks Summary: Attempted 2802 tasks of which 29 didn't need to be rerun and all succeeded.

Summary: There were 79 WARNING messages shown.

ビルドが完了した後、以下のコマンドにより、書き込み用のファイル群をまとめます。

$ cd ../..
$ ./edison-src/device-software/utils/flash/postBuild.sh

以上により、書き込み用のファイルがディレクトリedison-src/build/toFlashにまとめられます。このイメージを上で行ったようにflashall.shを用いて書き込めます。

なお、kernelの設定を変更したい場合は下記のようにして再ビルドしてください。
kernelの設定ファイルはedison-src/device-software/meta-edison/recipes-kernel/linux/files/defconfigですので、手作業で変更する場合はこちらを編集します。

menuconfigにより設定を行う場合は以下のようにします。まず、
edison-src/build ディレクトリにて

$ bitbake virtual/kernel -c menuconfig

を実行します (Xが必要)。

Webカメラを有効にする場合は下記の操作を行ったのですが、既にこれはデフォルトで有効になっています。
Device Drivers→
MultiMedia Support→
Media USB Adapters でスペース→Enter
USB Video Class (UVC) で M
→Save
→Exit (複数回)
と辿ることで設定ファイルが

edison-src/build/tmp/work/edison-poky-linux/linux-yocto/3.10.17+gitAUTOINC+6ad20f049a_c03195ed6e-r0/linux-edison-standard-build/.config

として書き込まれます。これをkernelの設定ファイルの格納場所にコピーします。
edison-src/buildディレクトリにいるとして、

$ cp ../device-software/meta-edison/recipes-kernel/linux/files/defconfig ../device-software/meta-edison/recipes-kernel/linux/files/defconfig.orig
$ cp tmp/work/edison-poky-linux/linux-yocto/3.10.17+gitAUTOINC+6ad20f049a_c03195ed6e-r0/linux-edison-standard-build/.config ../device-software/meta-edison/recipes-kernel/linux/files/defconfig

さて、以上が済んだら、edison-src/build ディレクトリにて下記コマンドによりイメージの作成を行います。

$ bitbake virtual/kernel -c configure -f -v
$ bitbake edison-image
$ cd ../..
$ ./edison-src/device-software/utils/flash/postBuild.sh

以上で、edison-src/build/toFlashに書き込み用のファイルができました。


2014年11月2日日曜日

Raspberry PiとArduinoで16x32 RGB LEDパネルにカメラモジュールの映像を表示してみた

はじめに

5月頃に秋月で「RGBフルカラードットマトリクスLEDパネル 16x32ドット」を購入し、長いこと放置していたのですが、少し時間ができたので試してみることにしました。

最近ずっと仕事で使っていたRaspberry Piで試すことにします。ただし、Raspberry Piに直接接続するわけではなく、

RaspberryPi―(シリアル通信)→Arduino→RGB LEDパネル

という構成にしました。そうすることで、Adafruitで公開されているArduino用のライブラリを流用することができます。

なお、この構成で始めた後に、やはりAdafruitでRaspberry Pi用のチュートリアルが出てることを知りました。そちらのチュートリアルでは画像ファイルをスクロールする例を取り扱っていますが、本ページでは、それとは異なる構成でRaspberry Piのカメラモジュールの映像をRGB LEDパネルに表示するところまでを試してみます(下図)。


準備

まず、AdafruitのArduino用のチュートリアルを元に、Arduinoで動作することを確かめてください。ArduinoのIDEでFile→Examples→RGBmatrixPanelとたどった時に「16x32」が含まれているサンプルは動作します。

用いるArduinoはチュートリアルにあるようにArduino Unoで良いですが、私は「Arduino Pro Mini 328 5V 16MHz」+「FT232RL搭載小型USB-シリアルアダプタ 5V」の組み合わせを用いました。ソースを少し変更するだけでArduino Megaでもいけるようですが、こちらでは試していません。

C++ & OpenCVの場合

それでは、Raspberry Piでの準備に入っていきます。Raspberry Piのカメラモジュールの映像を取得し、それをRGB LEDパネルに表示することを目指しますが、そのためにC++とOpenCVの組み合わせを用いることにします。

最初はPythonと画像処理ライブラリのPillowの組み合わせで試していたのですが、思った速度が出なかったので、C++とOpenCVの組み合わせに切り替えました。Python+Pillow版についてはページ末尾にメモを残しますので、興味のある方はどうぞ。

さて、Raspberry Pi、Arduino、RGB LEDパネルを下記のように接続しておきます。この場合、Arduinoの電源はRaspberry PiのUSBから供給されます。



さらに、Raspberry Piではカメラモジュールを使えるようにしておきましょう。「sudo raspi-config」で設定を起動し、「5. Enable Camera」→「Enable」とたどれば良いのでした。

次に、Raspberry PiでOpenCV、および後に必要なcmakeをインストールします。

sudo apt-get update
sudo apt-get install libopencv-dev cmake

次に、このRaspberry Piのカメラモジュールに対してOpenCVを用いることができるよう、「RaspiCam : C++ API for using Raspberry camera with/without OpenCv」をインストールします。まず、SourceForgeからraspicam-0.1.1.zip (129.5 kB)をダウンロードし、下記のコマンドでインストールします。

unzip raspicam-0.1.1.zip
cd raspicam-0.1.1
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

このRaspiCamを用いると、Raspberry Piのカメラモジュールで取得した画像に対してOpenCVを利用できるので良さそうです。私は普段OpenCVを使っているわけではなく、RaspiCamも今回初めて触ったので、「良さそう」という程度しか言えないのですが。

次に、RGB LEDパネル用に私が用意したファイルを準備します。

cd
git clone https://github.com/neuralassembly/raspi_16x32RGBLED
cd raspi_16x32RGBLED
make

makeを実行した後、しばらく待つとビルドが完了します。画像ファイル表示用のimage2LEDmatrix、カメラモジュール表示用のcamera2LEDmatrixの2つの実行ファイルができています。 

さらに、Arduino用のserial2LEDmatrix.inoというC言語ファイルが存在します。このserial2LEDmatrix.inoをWindowsなどであらかじめArduinoに書き込んでおきましょう。 

このスケッチは、下図のように16x32x3バイトの階調(各階調は0~Fで表示)をシリアル通信で受け取り、「.」(ピリオド)を受け取ったタイミングでLEDパネルの内容を更新するように記述されています。



以下、image2LEDmatrixとcamera2LEDmatrixの使用法を解説してきます。

画像ファイルの表示 

image2LEDmatrixはSDカード上の画像をRGB LEDパネルに表示するプログラムです。練習兼動作検証用に書きました。

任意サイズの画像を与えることができます。画像の形式は、JPEGやPNGなど、OpenCVが読み込みに対応しているものです。動作モードは下記の2モードあります。

./image2LEDmatrix filename 0

末尾の0は省略することができます。こちらは下図のように画像の全体をスケーリングして表示します。なお、このページの画像は、見やすくするために全てRGB LEDパネルに紙をかぶせて撮影しています。


一方、下記の用に末尾に1をつけて起動すると、下図のように画像の左右または上下を捨て、なるべく画像を大きく表示します。

./image2LEDmatrix filename 1


Raspberry Piのカメラモジュールの映像の表示

カメラモジュールの映像を表示するには、下記のコマンドを実行します。

./camera2LEDmatrix

すると、下図のようにカメラモジュールの映像がRGB LEDパネルに表示されます。真面目に計測していませんが、体感で5fps以上は出ているのではないかと思います。

なお、フレームレートが低いのは、動作の安定化のためにwhileループ内でusleep関数によるウェイトを入れているためです。RaspiCam自体は約30fpsで映像を取得する能力がありますのでご注意ください。


やってみるとわかりますが(いや、やる前にわかるか)、解像度があまりにも小さいことと、LEDが明るすぎることとがあいまって、何が映っているかわからないことが多く、ちょっと厳しいです。

普通に周囲の映像を映すと、ほとんどのLEDがかなりの輝度で輝くので、1.0A以上の電流がパネルに流れてしまいます。

そのため、使いこなすには何らかの画像処理が必要そうです。せっかくOpenCVを使っているので、エッジ抽出、ビット反転、時間差分などを試したのですが、解像度の小ささから、何が起こっているのかわからず、イマイチでした。

何か面白い応用があれば、お知らせ頂ければ幸いです。

(おまけ)Pythonの場合

上で、C++とOpenCVでの例を紹介しましたが、その前にはPython + Pillowで試していました。この方法にはいくつか欠点があったため途中でやめてしまったのですが、メモとして記録を残しておきます。

準備

まず回路ですが、Python用いてArduinoとシリアル通信する場合は、こちらのstackoverflowにかかれているように、ArduinoのRESETとGNDの間に220μF程度のコンデンサを挟む必要があります。ただし、このコンデンサはスケッチ書き込み時は外してください。
(追記:すいません、コンデンサなしでも問題なく動くかもしれません。追試の必要あり)


次に、Raspberry Piでpipとpython-devとlibjpeg8-devをインストールします。

sudo apt-get update
sudo apt-get install python-pip python-dev libjpeg8-dev

次に、Pillow をインストールします。

sudo pip install pillow

以上の準備のもと、次に、RGB LEDパネル用に私が用意したファイルを準備します。

git clone https://github.com/neuralassembly/raspi_16x32RGBLED_Python

raspi_16x32RGBLED_Pythonの中に、画像ファイル表示用のimage2LEDmatrix.pyとカメラモジュールの映像表示用のcamera2LEDmatrix.pyとが入っています。

これらを用いるのは、C++版でも用いたserial2LEDmatrix.inoをArduinoに書き込んでおいてください。これは https://github.com/neuralassembly/raspi_16x32RGBLED に含まれています。

画像ファイルの表示

C++版と同様に、画像全体表示

python image2LEDmatrix.py filename 0

および、画像の切り出し表示

python image2LEDmatrix.py filename 1

に対応しています(末尾の0は省略できます)。画像ファイルのサイズも任意ですが、画像リサイズのアルゴリズム(PIL.Image.NEAREST、PIL.Image.BILINEAR、PIL.Image.BICUBIC、PIL.Image.ANTIALIAS)がイマイチなため、縮小後の画像があまり綺麗に表示されないことがあるのが欠点です(OpenCV版ではINTER_AREAを用いました)。

そのため、Python版ではWindowsのgimpなどで事前に画像を横32x縦16にリサイズしておいた方が良い場合があります。

Raspberry Piのカメラモジュールの映像の表示

カメラモジュールの映像を表示するには、下記のコマンドを用います。この辺りを参考にしました。

python camera2LEDmatrix.py

残念ながら、こちらはでは、2秒に1回程度しか映像が更新されません。そのため、Pythonをあきらめ、C++とOpenCVによる方法に移行したのでした。



「カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」を執筆しました。


2014年9月6日土曜日

Android Wear (LG G Watch) でカメラからの映像を見ながら三輪ロボットを操作してみた

はじめに

Android wear (LG G Watch) で、カメラからの映像を見ながら三輪オムニホイールロボットをラジコンのように操作してみました。動画はこちら。




経緯など

Android Wear (LG G Watch) で三輪ロボットを操作してみた」にて、Android wear搭載のLG G Watchで三輪ロボットを制御しました。

このロボットにはRaspberry Piとそのカメラモジュールが搭載されており映像を配信しているのですが、せっかくなのでLG G Watchでもその映像を表示してみよう、というのが今回のお話。

仕組みなど

動画の後半にも示されているように、LG G WatchだけではなくペアリングされたAndroid端末とその上で動くアプリが必要です。システム全体の模式図は下図のようになります。


スマートフォン側のアプリが三輪ロボット上のカメラからの映像を受け取り、それをWear側のアプリに送ります。カメラからの映像は640x480、15fpsで送られてきますが、Wear側へはそれを280x280、5fps程度に変換してから送っています。スマートフォンとWearはBLEで接続されていますので、データ量を極力減らさないとまともに動作しません。

アプリのスクリーンショットはこちら。

Wear側のアプリ



スマートフォン側のアプリ



ソース

操作命令送信のサンプルは「Android Wear (LG G Watch) で三輪ロボットを操作してみた」にあります。

映像受信のサンプルは neuralassembly/MjpegViewWear になります。Android Studio でインポートして、スマホとWearの両方にインストールしてください。

MjpegViewerWearを試すには、上の動画で行っているように、Raspberry Piで動画配信するという方法もありますが、より簡単に試すには、Androidスマートフォン(以下「別スマホ」と表記)を用意してその上でIPWebcamというアプリを動かすのが簡単です。以下、この方法を簡単に示します。

  1. 別スマホで、IPWebcamをインストールして起動します。設定は「Video preference / Video resolution を640x480」、「FPS Limit を15または10」程度に設定し、「Start server」。起動すると画面にIPアドレスとポート番号が表示されるのでメモします。FPS Limitが小さいほうがWear側のアプリは安定します
  2. WearとペアリングしたスマホでMjpegViewWearを起動。メニューの設定で、IPアドレスと番号をセットします。コマンドは「videofeed」。「画像スキップの頻度 n」は「n回に一回、Wearに画像を送る」の意味です。大きくすると安定しますが遅いです。小さくすると不安定になるので、nは3より小さくできなくしています。4か5程度にするとWear側のアプリが安定します
  3. ペアリングしたスマホで画像が表示されたら、メニューから「Wearアプリ起動」を実行します。Wearがスリープ状態のときは画面を一回タップしないと映像が表示されません。
注意
(2014.12追記) スマホとWear間の通信ですが、データを大量に送りすぎると、通信が切れてしまうことがあります。これは、Wear側の時計画面でクラウドアイコンに斜線が入ることでわかります。以前は、「通信が一度切れると、スマホ側かWear側の本体を再起動しないと通信が再開しない」ということがありましたが、Android Wearがアップデートされるにともない、その問題は起こりにくくなっているように思います。現在は「通信が一度切れたら、スマホ側とWear側のアプリを終了して通信が回復するのを待つ」で済むことが多いです。

展示

この内容を、2014年12月21日に東海大学高輪キャンパスで開催されたAndroid Bazaar and Conference 2014 Winterで展示しました(週アスPLUSさんTAPPLIさん、星影さんのブログにも写真があります)。


この時は下記の構成でデモしました。

  • 映像送信:Raspberry Pi + カメラモジュール (10fps)
  • ペアリングされたAndroid:Nexus 10 (画像スキップの頻度 5)
  • Android Wear:LG G Watch R

映像送信の頻度はかなり安全側に振って設定しましたが、その甲斐あってか10:00~17:00の展示時間中、かなり安定して動作しました。

たくさんの方にお越しいただき、ありがとうございました。

余談

今回実現したのは、2013年に「i'm Watch」というAndroidベースのスマートウォッチで実現したことの焼き直しです。下にリンクがあります。

それと比べると、Android Wearを搭載した、Googleにより正式に認証を受けた端末で実現した、というのが今回の違いです。

「i'm Watch」でのデモは「i'm Watch」という時計でしか実現できなかったのに対し、今回のデモは今後増えていくであろうAndroid Wear搭載の時計ならばどれでも動作する(はず)、というメリットがあります。

こちらもどうぞ

三輪オムニホイールロボットの操作について
Raspberry Piでの映像配信について
時計での模型操作について(i'm Watchという時計でのデモ)

2014年8月6日水曜日

Android Wear (LG G Watch) で三輪ロボットを操作してみた

はじめに

Android wear (LG G Watch) で三輪オムニホイールロボットをラジコンのように操作してみました。
動画はこちら。




仕組みなど

システム全体の模式図は下記のようになります。


まず、三輪ロボットに搭載されたRaspberry Piではnode.jsが動作しており、操作命令をWeb経由で受け付けています。

それに対してAndroid Wearとペアリングされたスマートフォンから指令を送りますが、その際には「Androidアプリからnode.js+Socket.IOと双方向通信する」の解説を参考に、Gottox/socket.io-java-clientを使いました。

そして、その操作命令の決定に、Android Wearからのタッチ情報を用いています。

スマートフォンとAndroid Wear用のアプリはAndroid SDK (API 20)に含まれているサンプルwearable/DataLayerをベースに作成します。時計と電話の間のデータのやり取りには下記のページのようにいくつかありますが、今回は送信データ量が大きくないので、シンプルなMessageApiを用います。

参考


解説用に簡単なサンプルを作成してみました。スマートフォンとAndroid Wear間の通信だけを実装しています。Android Studioでインポートして利用できます。

Wear側のアプリ

タッチ位置を電話のアプリにMessageApiにより送ります。ただし、タッチイベントから得た座標を毎回送るとデータ送信回数が多すぎ、通信が止まってしまうことがありました。その場合、Wearの時計画面に戻ると、クラウドアイコンに斜線が入り、通信が切れていることがわかります。

そこで、下記の対策を施し、通信を安定化させました。
  • タッチの座標の解像度を20ピクセル刻みとし、座標が変化したときのみ座標データを送信する
  • 連続的に送信するのではなく、「時計から座標データ送信」→「電話側でデータを受け取ったことを時計へ通知」→「時計側は電話からの通知を待ってから次の座標データ送信」…を繰り返すようにする
2番目の変更が安定化には重要のようでした。

(追記 2014.12 エントリ追加時は、「データを送りすぎて通信が切れると、Wearかスマホの本体を再起動しないと通信が再開されない」ということが起こっていました。現在は「通信が切れたらWearとスマホのアプリをそれぞれ終了してしばらく待つことで通信が復活する」という動作になっているように思えます。しかしいずれにせよ、通信量を減らすことは重要のようです)



電話側のアプリ

Wearから送られたWearのタッチ位置を表示します。また、既に述べたように、Wearからデータを受信したらその受信通知をWear側に送り返しています。




こちらもどうぞ

三輪ロボットに搭載したカメラからの映像をWearに表示する
三輪オムニホイールロボットの操作について

2014年3月17日月曜日

Raspberry Piの低消費電力化を目指した話

はじめに

これまで、


Android Bazaar and Conference 2013 AutumnMaker Faire Tokyo 2013などで展示してきました。

三輪ロボットにはnode.jsが動作するRaspberry Piが搭載されており、Firefox OS/enchantMOON/android/iOSなど、OSに依存しない操作がWeb技術により可能になっています。

Raspberry Piはモバイルバッテリーで稼働させているのですが、展示を行う上ではこのバッテリーの消費が早いのが問題でした。

Raspberry PiではLinuxのディストリビューションであるRaspbianが動作しており、シャットダウンと再起動にそれなりに時間がかかります。そのため、展示を見に来て下さっている方がたくさんいる状況でモバイルバッテリーの残量を示すLEDが赤くなると、どのタイミングでバッテリーを交換すべきか悩んでしまうわけです。

そこで、せめてモバイルバッテリー一つで展示1日(典型的には10:00~17:00)をもたせられないか、検討してみることにしました。

検討するのは

  • 電力消費の小さいWifiドングルを探す
  • Raspberry Pi上のレギュレータ(RG2)をDC-DCコンバータに変更する

の2点です。

電力消費の小さいWifiドングルを探す

最も電力を消費しそうなのはWifiドングルなので、消費電力の小さいものを探すのが効果がありそうに思いました。さらに、私がこれまで用いていたのはPCI GW-US54Miniというかなり古いものなので、これも電力消費が大きい原因の一つと思われました。

なお、この三輪ロボットは図の赤矢印で示すように、Raspberry Piと、テザリング機能をオンにしたXperia rayとの間でWifi通信を行っています(見ての通りとても近い)。


検討するWifiドングルは、NOOBS v1.3.4でインストールしたRaspbian (2014-01-07) のデフォルト状態で利用可能だった下記の4つです。
IO-DATAのものが2つありますが、これらにはハイパワータイプと超小型タイプという違いがあります。なお、下図で最も左にあるのが、これまで用いてきたPCI GW-US54Miniです。古いだけあって大きいですね。


計測は、Raspberry Piに安定化電源で5Vを供給し、その電流を読むことで行います。電流は、Raspberry Piを起動し、命令を受け付ける待機状態になった頃に読みます(実際の展示でも、待機している時間が長いと思われるため)。


なお、結果を示す前に注意ですが、以下のデータは、上の写真で示したように、非常に近い距離でWifi通信を行う際のものです。通信の距離が遠くなると電流は大きくなりますし、そうなった際に電流の大小関係は逆転する可能性があります。そのため、以下のデータは私のケースのみに当てはまる、あくまで目安と考えて下さい。

変更前
変更後
PCI GW-US54Mini 0.58A IO-DATA WN-G150U 0.45A
IO-DATA WN-G150UMK 0.39A
LOGITEC LAN-W150NU2AB 0.50A
BUFFALO WLI-UC-GNM2 0.50A

結果は上記のように、IO-DATA WN-G150UMKが最も電流の小さいWifiドングルでした。なお、実際には電流の揺らぎが大きいので、平均的な値を記しています。

どのWifiドングルもRalinkのチップを使っているようなので、あまり違いが出ないのではないかと予想していたのですが、IO-DATAの2つは電流が小さくなりました(上で記したように、あくまで私のケースでは、ですが)。

というわけで、以後、IO-DATA WN-G150UMKを用いることにします。

Raspberry Pi上のレギュレータ(RG2)をDC-DCコンバータに変更する

(注1)本項の内容は、Raspberry Piを破壊する可能性がある(文字通り壊さないと実現できないのですが…)ため、自己責任でお願いします。
(注2)本項の内容は、2014年7月に出たModel B+を用いることで同様の効果が得られるはずです。

実は上でのWifiドングルの交換でほとんど満足してしまっているのですが、後で思い返して気になるのも嫌なので、もう一つのレギュレータの交換についても試してみます。

今回検索して初めて知ったのですが、Raspberry Piを低消費電力化するには、RG2というレギュレータを交換する、というのが定番のようで、既にいくつかの報告があります。

用いたのは、取扱いが容易そうだった
です。

作業は
  1. 表面実装されたRG2を取り外す
  2. DC-DCコンバータを取り付ける
の順で進めます。

1.の作業は「Replacing the Raspberry Pi's Main Voltage Regulator」にて細かく解説されています。RG2のヒートシンクも兼ねているTABですが、ヒートシンクにはんだをモリモリと盛れば熱が効率的に伝わり簡単に取り外せます。

2.のDC-DCコンバータ取り付けですが、下図のように3点(PSピンをGNDに接続するので正確には4点)を接続しました。DC-DCコンバータはユニバーサル基板の裏に隠れています。


接続がちょっと安直すぎるかなと思いましたが、SDカードへのOSのインストール、Xを起動してのクライアントとしての利用、など一通りの機能は問題なく動作しました。

三輪ロボットでの電流を調べた見たところ、下記のようになりました。

変更前
変更後
純正Raspberry Pi +
IO-DATA WN-G150UMK
0.39A 改造Raspberry Pi +
IO-DATA WN-G150UMK
0.34A

およそ50mAだけ電流が減っていることがわかります。他のWifiドングルでも試してみましたが同様の結果が得られました。

Replacing the Raspberry Pi's Main Voltage Regulator」でもやはり50mA程度の減少が報告されていますので、こんなものでしょう。

効果は?

既に示したように、Wifiドングルの変更とDC-DCコンバータの利用により、待機状態の電流は0.58A→0.34Aと大幅に減少しました。それに伴って待機時のモバイルバッテリーの持ちが良くなっていることは確認済です。

ただし、実際の展示では

  • 三輪ロボットの操作時(=通信時)に電力消費が増える
  • 展示会場ではWifiの干渉によりさらに電力消費が増えると考えられる

などの理由により、「モバイルバッテリーで展示1日もたせる」という当初の目的が満たされているかはわかりません。

この点についてはAndroid Bazaar and Conference 2014 Springの展示にて検証してみたいと思います。

(追記 2014.3.22)
展示にて検証したところ、10:00~17:00まで、一つのモバイルバッテリー(5400mAhのQE-QL201)で動作可能でした。ちょうど展示終了の17:00間際にLEDがオレンジ→赤と変わったので、あと1、2時間はいけたのではないかと思います。

低消費電力化した効果があって良かったです。

Raspberry Pi Type Aに変更してさらなる低消費電力化

(2014.6.16追記)

上記の試みはRaspberry PiのType B (Model B)を用いたものなのですが、
Type A (Model A)を用いると
  • Ethernetインターフェイスが省略されている
  • USBが1ポートのみ
により、さらなる低消費電力化が見込めます。

ただし、私の場合USBポートとして
の2つのデバイスを用いているので、そのままではType Aへ変更できません。

そこで、シリアル通信をUSB-シリアルコンバータからGPIOのUARTピンに変更し、
USBポートを1ポートで済むようにしてみました。
下記のサイトを参考にしました。
また、条件をそろえるためにこのType AもDC-DCコンバータを用いて改造しています。
(注)なお、この「改造」は、2014年11月に出たModel A+を用いることで同様の効果が得られるはずです。

結果は下記の通りです。

変更前
変更後
改造Raspberry Pi Type B +
IO-DATA WN-G150UMK
0.34A 改造Raspberry Pi Type A +
IO-DATA WN-G150UMK
0.20A

劇的に電流が減ったので驚きです。

ここまで消費電力が下がると、現在はXperia rayで行っている映像配信を
Raspberry Pi+カメラモジュールで行っても良いかな?という気がしてきます。

ただし、今まではコマンドのみの受信だったものに、映像の送信を加えると
通信量が増えて新たなトラブルが起こるかも知れない、とは思います。

おまけ

この三輪ロボットはシールド交換の要領でBluetooth + androidによる操作も可能になっています(動画はこちら)。下図のようにPIC24FJ64GB002+Bluetoothドングル(これもちょっと古いBuffalo BSHSBD02BK)で実現していますが、こちらの電流もせっかくなので調べてみたところ、

  • 0.04A

でした。ちょうど一桁違う感じですね。




「カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」を執筆しました。


スタービルドストライクガンダムっぽいドロイド君を作った話

はじめに

ガンダムビルドファイターズの後半の主人公機、スタービルドストライクガンダムをベースにしたドロイド君をつくったのでそのまとめ。

個別写真


スタービルドストライクドロイド君

背負い物:HG BUILD CUSTOM 1/144 ユニバースブースター プラフスキーパワーゲート
青い羽根:HGBF 1/144 スタービルドストライクガンダム プラフスキーウイング
腕:BB戦士 ビルドストライクガンダム フルパッケージ

その他写真


背負い物が重いのでスタンド必須
SEEDポーズ
鎧武ドロイド、バロンドロイドと一緒に
本家のスタービルドストライクガンダムと一緒に


作り方

ほとんどプラモのパーツをくっつけているだけなので、作るのは割と簡単です。今回は腕だけでなく、背負い物のために背中にもポリキャップを仕込んでいます。あと、スタンドを利用するために底に3mm径の穴を開けました。


FXバーストドロイド君もそうですが、クリアパーツをいっぱいつけるとカッコいいですね(小並感

ではでは。

こちらもどうぞ






2014年3月7日金曜日

仮面ライダー鎧武っぽいドロイド君を作った話

はじめに

これまでガンダムAGE1タイタス風に改造したドロイド君をSNSのアイコンにして来ましたが、テレビ放映も終わってしばらくたつし、そろそろ変更したいと考えていました。

見た目のインパクトから、今回の素材は仮面ライダー鎧武をチョイスしてみました。

個別写真


ドロイド鎧武

武装:AC01 仮面ライダー鎧武 オレンジアームズ
肩パーツ:BB戦士ガンダムAGE2
腕パーツ:BB戦士ガンダムAGE3

腕がちょっと手抜きですが…
ドロイド鎧武、変身途中

後述するように、もともとのオレンジアームズをいったんばらしているので、この程度までしか変形できません。
ドロイドバロン

武装:AC02 仮面ライダーバロン バナナアームズ
肩パーツ:BB戦士ガンダムAGE2
腕パーツ:BB戦士ガンダムAGE1

こいつをSNSのアイコンにしたくて作り始めました。

ドロイドバロン、変身途中。


本家と一緒に


AC04 パインアームズを装着した鎧武と。
AC06 マンゴーアームズを装着したバロンと。



作り方

アームズチェンジシリーズのアームズをニッパーで一旦バラバラにした後、下図のように真鍮線で結合します。


ドロイド君本体の方にこの真鍮線がはまる溝をつくってはめ込みます。

腕はガンダムAGE風ドロイド君と同じく本体にポリキャップを仕込んで取り付けます。


上記のような作り方をしているので、アームズチェンジできます。

これが…


こうじゃ。カッコイイ。


おわりに

新しいSNSのアイコンを作りたいという目的は達せられたので満足です。

ただ、わりとお高いアームズチェンジシリーズをニッパーでバラバラにしなければならないので、作る際ちょっと心理的に抵抗がありました。本当は斬月も欲しいのだけど次は作らないかも。

あと、この2体は2014年3月21日に秋葉原で行われるAndroid Bazaar and Conference 2014 Springで展示する際のブースのマスコットとして登場予定です。

ではでは。

こちらもどうぞ

PandaBoard ESにUbuntu12.04 Serverを載せてmjpg-streamerを動かした話

はじめに

Raspberry Pi用赤外線カメラPi NoIRの映像をandroidで表示してみた」で、
Raspberry Piの赤外線カメラの映像をandroidにストリーミングしてみましたが、
Raspberru Piの性能では解像度320x240、フレームレート10fps程度が安定に動作する限界でした。
USBカメラを用いてもこれは大差ないと思います。

2014/3/21(金)に秋葉原で開催されるAndroid Bazaar and Conference 2014 Spring (ABC2014S)
でもこのような動画のストリーミングを用いた展示を行おうと考えているのですが、
320x240の10fpsでは動画のクオリティとしては少し物足りないです。

そのため、Raspberry Piよりも高性能なボードが必要になります。
気になるのはBeagleBoneBlackだったのですが、ABC2014Sではコンセントが使えるので、
より高性能なボードを使って確実な動作を目指すことにしました。
そこで用いたのが、職場で余っていたPandaBoard ESです。

以下、PandaBoard ESにUbuntuを導入し、mjpg-streamerを動かすまでの解説です。



OSのインストール

Omap4用のUbuntu 12.04 Serverをこちらの解説に従いインストールします。
SDカードへの書き込みは私の場合PC上のUbuntuで下記のように行いました。
/dev/sdeの部分は環境に応じて書き換えます。
$ sudo dd bs=4M if=ubuntu-12.04-preinstalled-server-armhf+omap4.img of=/dev/sde

書き込んだSDカードをPandaBoard ESに差します。
さらに、シリアルケーブルでPCとPandaBoard ESを接続し、
115200bpsでPCからPandaBoardにシリアル接続しておきます。

以上の準備の元、電源を投入すると、インストールが始まります。

デフォルトのネットワークインターフェイスはここでは有線のeth0を選択しましたが、
後でWifiドングルの設定を行うので、ここではネットワークの設定をスキップしました。

途中、インストールするパッケージを聞かれますので
  • Basic Ubuntu server 
  • OpenSSH server
を選択しました。

Wifiの設定

まず、ネットワークの接続にWifiを用いたかったのでその設定をします。
Ubuntuをインストールするとボード上のWifiデバイスがwlan0として使えるのですが、
技適の問題があることと、パフォーマンスがあまり良くないらしい(ただし試してない)ことの
2点より、市販のWifiドングルを用いることにしました。

用いたのはIO-DATAのWN-G150Uです。

まず、ボード上のWifiデバイスを無効にするために、 /etc/modprobe.d/blacklist.conf の末尾に
下記の内容を追記します。

blacklist wl12xx_sdio

記述したら再起動し、Wifiドングルをさします。

$ ifconfig -a

を実行し、wlan0が存在することを確認します。
wlan1となっていたら、 /etc/udev/rules.d/70-persistent-net.rules を編集して
wlan0として認識されるようにします。

次に、 /etc/network/interfaces の末尾にに下記の内容を追記します。
これは192.168.1.9という固定IPアドレスとするための設定なので、
環境に応じて書き換えます。

auto wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet static
address 192.168.1.9
netmask 255.255.255.0
gateway 192.168.1.1

次に、/etc/wpa_supplicant/wpa_supplicant.confを作成し例えば下記のように記述します。
接続先のSSID、暗号化プロトコル、パスフレーズなどは環境に応じて変更します。

network={
        ssid="YOUR SSID"
        proto=RSN
        key_mgmt=WPA-PSK
        pairwise=CCMP
        group=CCMP
        psk="YOUR_PASSPHRASE"
}


最後に、/etc/resolv.confを作成してDNSサーバーを記述します。例えば下記の通り。
本当はresolvconfに自動生成させるらしいのですが
Server版のためかうまくいかなかったので手作業で記述しました。

nameserver 192.168.1.1

以上の設定がうまくいくと、再起動によりWifiでネットワークに接続されているはずです。

mjpg-streamerのインストール

まず、OSを最新にします。

$ sudo apt-get update
$ sudo apt-get upgrade

そして、mjpg-streamerのビルドに必要な下記をインストールします。

$ sudo apt-get install build-essential libjpeg8-dev libv4l-dev imagemagick subversion

それが済んだら、下記のようにmjpg-streamerのダウンロードからビルドまで行います。

$ cd ~/
$ svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer mjpg-streamer
$ cd mjpg-streamer
$ make

mjpg-streamerの起動

起動の前に、/etc/modprobe.d/blacklist.conf の末尾に

blacklist snd_usb_audio

を記述して再起動しておきます。一部のUSBカメラとUSBオーディオのドライバとの相性が悪いためです。
このあたりに書いてあります。

起動は下記のような流れで行います。解像度640x480のフレームレート15fpsとしています。
30fpsでもPandaBoard側は問題なく動作しますが、受信側にそこまでの性能はないと考え
控えめに15fpsとしました。

$ cd ~/mjpg-streamer
$ export LD_LIBRARY_PATH="$(pwd)"
$ sudo ./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "./output_http.so -w ./www"

動作確認

PCのブラウザで、PandaBoardが動いているIPアドレスの8080ポートを見ると(http://xx.xx.xx.xx:8080/)、
映像が配信されていることがわかります。

この映像をandroidで受け取るには、いつも通り簡単MJPEGビューアを使います。
このアプリのソースはこちらにあります。

アプリを起動したら、メニューから「設定」を選択し、解像度を640x480に、ポート番号を8080に設定します。

ABC2014Sでは望遠カメラをストリーミングし、観光地にある望遠鏡のように
上下左右に動かすデモを行う予定です。
Wifiを使うので、うまくいくかは当日にならないとわからないのがつらいところ。

mjpg-streamerの自動起動

mjpg-streamerを自動で起動するためには、例えば下記のようにします。

mjpg-streamerをビルドしたディレクトリが/home/username/mjpg-streamer
であると仮定します。このディレクトリにstart-mjpg-streamer.shというファイルを作成し、
下記の内容を記述します。

#!/bin/sh

cd /home/username/mjpg-streamer
export LD_LIBRARY_PATH="$(pwd)"
./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -r 640x480 -f 15" -o "./output_http.so -w ./www"


次に、このスクリプトを/etc/rc.localに記述することで、自動起動します。

(中略)

sudo sh /home/username/mjpg-streamer/start-mjpg-streamer.sh &

exit 0 ←この行はもともとある行

おしまい。

んー、やっぱり後でBeagleBoneBlackでも試そう。

2014年2月6日木曜日

Nexus 4 用に日本語対応の Firefox OS をビルドした話

今までGalaxy S3やXperia arc/rayに android 4.0 (Ice Cream Sandwich) ベースの
Firefox OS1.1をビルドしてきましたが、android 4.3 (Jelly Bean) ベースのものは
試したことがなかったので、練習として Nexus 4 に最新の Firefox OS をビルドしてみました。

使ってみたところ、日本語IMEが実用レベルに近づいており、
twitter/Facebook/Google+などのSNSの読み書きができたのでメモします。



ビルド済みファイル

下記のファイルをダウンロードします。

(md5sum: bd173d4d1b6cedd080256c1e14a4e2fc)
このファイルの利用は自己責任でお願いします。

書き込み

ダウンロードしたファイルを解凍して、boot.img、system.img、userdata.imgを
あらかじめ取り出しておきます。

これらを書き込む前に、radioがandroid 4.3のときのものでないとWifiが使えませんので、
あらかじめfastbootで書き込んでおきます。
Factory Images for Nexus Devicesよりoccam-jwr66y-factory-74b1deab.tgzをダウンロードしておき、
中に含まれる radio-mako-m9615a-cefwmazm-2.0.1700.84.img を下記のように書き込みます。

$ fastboot flash radio radio-mako-m9615a-cefwmazm-2.0.1700.84.img

あとは、 boot.img、system.img、userdata.img を以下のようにfastbootで書き込み、再起動します。
SDカード領域は初期化されますので、バックアップはPCなどに退避しておきます。
なお、初回の起動は黒い画面のまま15秒くらい待たされます。

$ fastboot flash boot boot.img
$ fastboot flash system system.img
$ fastboot flash userdata userdata.img
$ fastboot reboot

日本語キーボードの有効化など

設定アプリから
キーボード→使用中のキーボード→他のキーボードを追加
と辿り、Japanese - Kanjiにチェックを入れると、日本語キーボードが使えます。
テキストエリアをタップすると自動でキーボードが現れます。

初回の変換時にIMEが固まるので、一度ホームボタンでホームに回避してから、
もう一度変換を試みると、以後普通に使えるようになります。

その他

なお、docomoのXi SIMを差してmopera.netを指定したのですが、
アンテナは立つものの、回線をつかんでくれません。
ただし、Wifiが使えるのでそれなりに使えます。

また、adb が使えるので、adb push hoge.mp3 /sdcard/
などとしてファイルを送り込めば音楽や動画を再生できます。

「ブラウザ」というのがFirefoxかなーと思うのですが、
これ、ブックマークとかないのかな?Firefox OSはご無沙汰なのでよくわかりません。

ソースは2014年2月3日の時点のものを利用しました。
gaia は 1.4.0.0prerelease
gecko は 29.0a1です。

ビルドに関して

以下のサイトを参考に、ビルド法を以下に記します。
なお、上での述べたように、ビルド済みファイルは2014年2月3日のソースを用いましたが、
2014年2月5日頃のソースでは、gecko が 30.0a1になったことが影響しているのか、
下記のように色々おかしなところが出てきています。
  • ホームボタンのサイズが合っておらず、Firefoxアイコンが欠けている
  • セットアップ時の地域の変更が画面に反映されない(内部的には処理されている)
  • テキストエリアをタップしてもキーボードが現れない(Wifiのパスフレーズが入力できず困る)
このように、Firefox OSのmasterは頻繁に更新されており、
常に期待の動作をするとは限りませんので、うまくいかない場合は
何日かおいてからまた試してみるのがよいかもしれません。

以下、ビルド法です。

ソースの準備

ソースを下記のようにダウンロードします(環境によりますが30分~1時間くらいかかります)。

$ mkdir ~/b2g_work
$ cd ~/b2g_work
$ export B2G_WORK=`pwd`
$ git clone git://github.com/mozilla-b2g/B2G.git
$ cd B2G
$ ./config.sh nexus-4

日本語対応など

日本語ロケールの追加、日本語辞書の追加などを行います。

まずはgaiaのロケールの追加。

$ mkdir $B2G_WORK/B2G/locales
$ cd $B2G_WORK/B2G/locales
$ hg clone http://hg.mozilla.org/gaia-l10n/ja
$ wget http://sola-dolphin-1.net/data/B2G/source/languages-japan.json

次にgeckoのロケールの追加。

$ mkdir $B2G_WORK/B2G/gecko-l10n
$ cd $B2G_WORK/B2G/gecko-l10n
$ hg clone http://hg.mozilla.org/l10n-central/ja
$ hg clone http://hg.mozilla.org/build/compare-locales

次に日本語辞書の追加

$ cd $B2G_WORK
(naist-jdic-0.4.3.tar.gzを http://sourceforge.jp/projects/naist-jdic/releases/ からダウンロードして配置)
$ tar zxvf naist-jdic-0.4.3.tar.gz
$ cd $B2G_WORK/B2G/gaia/apps/keyboard/js/imes/jskanji/dict
$ mkdir ipadic
$ cp $B2G_WORK/naist-jdic-0.4.3/naist-jdic.dic ipadic/
$ make json (この命令は環境変数LANGの値によっては失敗します。ja_JP.utf8 にセットすればよいです)

環境変数設定

次に、環境変数設定を行います。

$ export MOZILLA_OFFICIAL=1
$ export GAIA_DEV_PIXELS_PER_PX=2
$ export LOCALE_BASEDIR=$B2G_WORK/B2G/locales
$ export LOCALES_FILE=$B2G_WORK/B2G/locales/languages-japan.json
$ export L10NBASEDIR=$B2G_WORK/B2G/gecko-l10n
$ export MOZ_CHROME_MULTILOCALE="ja"
$ export PATH="$PATH:$B2G_WORK/B2G/gecko-l10n/compare-locales/scripts"
$ export PYTHONPATH="$B2G_WORK/B2G/gecko-l10n/compare-locales/lib"
$ export GAIA_KEYBOARD_LAYOUTS=en,jp-kanji

ビルド

以下のようにビルドを行います。

$ cd $B2G_WORK/B2G
$ ./build.sh

ビルドが終わると、
  out/target/product/mako/
に boot.img、system.img、userdata.img ができていますので、これをfastbootで書き込みます。



備考

私が2014年2月3日にビルドした時のコミット情報は

  • gaiaのコミット e9222d3b3e6047f05b929948b631e4bd6b5b0180
  • geckoのコミット 1fded49c645d068599f4f6f17ae17505cf05d2b3
で、この時のソースで日本語辞書を追加するときは


の方法で行う必要がありました。参考までに。