2013年1月30日水曜日

Raspberry Pi到着~

昨年から気になってましたが、今年になって出荷等そろそろ落ち着いたかなと考えて、Raspberry Piを注文しました。ARMだったらスマホ等でプログラムを試してみてるんだけど、面白そうだしね。さて注文方法ですが、昨年夏くらいから注文が殺到して、全然届かない~~という記事多数でした。なんか裏道の注文方法とかも紹介されてましたが、おとなしくRS コンポーネンツで注文しました。(文句の記事が多いということは、それだけ利用者も多いということだろうし)
問題は代金の支払い方法です。海外なのでクレカくらいしかないんですが、相手の会社よくわからないし・・・抵抗感つよいんですよね。なので、次善の策として避けてはいたんですがPay Pal登録しました。海外通販してるとクレカかPay Palになることが多いです。Pay Palが安心できるかと言われると何とも言えませんが、一応個人情報が漏れたという話は聞いてないので大丈夫でしょうと。(なんかPay Palから業者への支払いって、すごいタイムラグがありひどいそうだという話も聞いてます。それもあっていい感じを持ってなかったんですが、クレカの情報を海外の業者に渡すのは避けたい・・・国内ならコンビニ決済してくれるところも多いんですが。)

2週間ほどほっといたら届きました!

Webでもよく見る、RSコンポーネンツのパッケージです。今回はケースも一緒に頼みました。
ケースは白い箱、本体はピンクのプラスチック・ケースに入ってます。
さて基板のチェックです。以前みたWebで、ハンダ割れがあったとか(;°ロ°) 入念にチェックしますが、特に問題は見つかりませんでした。
その後、近くの量販店で32GBのmicroSDHDを購入し、RaspbianをDL、SDにイメージを焼いて(ちょっと表現がへんな気もしますが)電源を入れると、無事起動してくれました。
さて周辺機器ですが、もともと家にHDMIのモニタは2台ありますし、USBキーボード(USタイプ多数)、マウスも余っています。問題は電源です。5V, 0.7A必要とのことですが、最初はNexus7用の電源(2Aあります)で、次からはiPadの電源ユニットでやってます。(iPad2台あって、古い方はほとんど使ってない)

使い勝手のレポートは次回に。

2013年1月19日土曜日

初めてのeclipseでc++ プログラミング

これまで散々、C++プログラム作ってきましたが、基本Linuxとかでemacs使うのがほとんでした。(makefileは毎回自作)あるいは、WindowsでVisual Studioだったので、eclipseでC++のプログラム作成/デバッグをしたことがありませんでした。
gdbでデバッグは十分だったんですが、やはりLinuxでも統合環境の使い方覚えといたほうがいいだろうと思い直し、eclipseでC++プログラミングをしてみることにしました。(eclipseでJavaは随分やってきたんですけどね)

最初に悩んだのが、「Makefileどうしたらいいんだ?」ということです。調べてみると、基本的には自動的に作成してくれるようです。(既存のコードをeclipse管理下において、自分でMakefile作成という方法もあるそうです)今回は、とりあえずc++プログラミングとデバッグをしてみたかったので、自動生成で作ってみました。

1.プロジェクトの作成
Linux(Ubuntu)の環境でeclipse+CDTを用意します。そこでまず、C++プロジェクトを作成します。

こんなダイアログがでてきます。"Makefile project"がおそらく自分でMakefileを作成するものなんだろうと思いますが、今回は素直にデフォルトで選択されてるExecutableのEmpty Projectを選択します。(ちなみにCross GCCというのは、ARM等の異なるCPU用にプロジェクトを作成するためのものです)

プロジェクト(StringSample)を作成した直後です。なんと、srcフォルダすらありません。

2.コード作成
まず、自分でsrcフォルダを作成し(このあたりは自分の好みの構成で)、main.cppを作成します。
(単に"Hello!"を出力するだけのお約束のコードを書きました)
さて実はここで問題が起きることがあります。この"cout"が解決できない(not resolved)と言われることが多々あります。ググってみると、結構みんな悩んでいるようです。
あまりに単純な問題で、なんで?と思ってしまうんですが解決方法は簡単です。それはいったんeclipseを終了して、再度実行すればあら不思議、解決されています。どうも、eclipseの反応がにぶいせいのようです。(プロジェクトをいったんcloseして、再openしてもいいようです。)

3.Makefileの作成
さて、コードはできましたがMakefileができてません。どうしたらいいのかと悩んだのですが、右クリックで、Build Configuration→Build Allで自動的に作成してくれます。
これでMakefileを作成してくれて、Buildまでしてくれます。
Buildが成功しました。

今後、ソースファイルが増えてったらどうなるかまだこれからですが、多分Build Configurationで自動的にやってくれるんだろうと思います。(今回はDebugでやりましたが、Release用のMakefileもできちゃってます)

2013年1月14日月曜日

リアルタイムのEthernet通信はないか?

複数の計算機を並列で動かしていると、複数の計算機間で「同期をとって」通信をしたくなります。現状、主流のWindowsやLinuxではEthernetが非常に安価で高速なんですが、いかんせんCSMA/CDというでたとこ勝負の通信方式のため、この「同期」のためのリアルタイム性が保障されていません。(そのかわり、「安価」で非常に頑丈な通信システムにできています)ただ、やっぱ10~20台程度の計算機を並列で動かすとき、リアルタイム性の欲しいシステムを作りたいときがあります。2~4Hz程度なら普通のTCP/IPでもなんとかごまかせますが、10Hzでも怪しくなります。(たまに抜けてもいいというならいいんですが、1個のパケットも抜けちゃダメ!と言われるともう保障できません。数時間くらいならいけると思いますが、たいていそういう要求するシステムは計測のログ収集が目的なんでダメです。

こういう時は、やはり昔IBMが出してたToken-Ring方式が確実です。でも性能-コストの関係でかなり初期の段階でEthernetに負けてしまいました。こうなると物理層はEthernetでTokenとばす通信スタックはないもんかと思って探してみたんですが、同じこと考える人がやはりいました。目的が産業用のセンサーやモーター制御のためなんですが、Ether CatとEthernet/IPというのがありました。どちらも一応Openな規格をうたってるんですが、詳しい仕様は会員にならないと入手できないようです。また参考実装もなく、見つかったのは商品のソフトウェアだけでした。(Ethernet/IPはSourceforgeに通信ソフトがあったんですが、使い方が全然わからない。おまけに、windowsのCygwin環境に調整してあるようで、そのままではLinuxでビルドもできない)もうちょっと頑張ってみますが、簡単にわかった仕様をメモしておきます。

1.Ether CAT
文字通り自分の考えてた構想をそのまま実現してます。TCP/IPの通信スタックをまるきり置き換える感じで、Token飛ばして通信するようです。(イメージ下図)


通信のトポロジーは図のようなものだけでなく、通常のツリー型だろうがサポートするとはありましたが、基本的には図のようにMasterからTokenとばして、端のRepeaterでそれを折り返すという感じです。さすがにこの形態なので反応速度は速く、通信量にもよるんでしょうが、100us以下で通信できるとのことです。(通信帯域も80%くらいは使いきれるとのこと)
ただ文字通り産業用機器の通信のようで、専用のI/Fカードとか使います。(通常のEhternetカードでもいけそうなのもありましたが、基本はセットで販売という感じでした)

2.Ethernet/IP
これはTokenとかは特に使ってないようで、UDPで通信するようです。(ただTCPでもできるとあり、その場合のリアルタイム性どうするんだ?という気はしますが)TCP/IPの通信スタックは既存のものを使い、アプリケーション層でなんとかするというタイプです。そのため、通常のLANも使いながらでもOKらしいんですが、その場合のリアルタイム性の保障はどうするんだ?という不安はあります。そのため、リアルタイム性もぐっと落ちて数10msオーダーの反応速度です。(自分的には産業用の機器制御するつもりはないんで、それで十分なんですが)


調べてたら、オムロンとかキーエンスとかのHPが普通にひっかかり、自分は専門外で知らなかったんですが、結構使われてるんでしょうか?(Ethernetは昔から光ファイバーがありましたから、工場等の雑音が多いところでもその気になれば安定して通信できますから、下手に専用の通信機器作るよりは高速で安価にできそうな気もします)

2013年1月5日土曜日

Androidプログラム開発-ファイル入出力

プログラムを移植するのに、あと一つ乗り越えないといけない壁があります。「ファイル入出力」です。

計算結果をログとしてstorageに出力したいですし、各種設定データをファイルとして読み込む必要があります。またそれらは、Android端末をUSB接続したときに簡単にアクセスできる場所がいいです。
試しに従来のJavaプログラムで作成した簡単なログ書き込みのプログラムを移植してみようとしたら、「そんなクラスはない!」と怒られてしまいました。Android用のiostreamじゃなきゃだめだということが確認できたので(事前に予測はしてました)、ググってみるとどうしてもファイルエクスプローラのアプリ紹介のページにいってしまいます。キーワードを考えて、やっと見つけました。
ファイル出力の方ではFileOutputStreamを使い以下の様なメソッドだとか。

outputStreamObj=context.openFileOutput( )

ところでこのcontextなるインスタンスは何者?ページをよく読むと、Androidプログラムの本体のインスタンスらしく、これを使うと/data/data/(パッケージ名)以下のパスしか指定できないとか。ここ普通のファイルエクスプローラではPermissionがありませんといって、見ることすらできません。(jail breakして、root化すればいけますが、そもそもUSB接続して簡単に参照したいのでそれでは困ります。)
さらに調べると、普通のjava.ioパッケージでもできるとの情報がありました。これならフルパスでファイルを指定できますが、ことごとくPermission denyで怒られます。セキュリティがガチガチですね。
USB接続して簡単にアクセス、というのが目標なので/sdcard以下にファイルを作ろうとしたんですが、そもそもeclipseに”/sdcard”のパスを直接コードするんじゃありません、と注意される始末。調べてみると、以下のメソッドを使いAndroid端末に合わせたパスを取得しろとのこと。

String str = Environment.getExternalStorageDirectory().getPath();
writeFile(str+"/Documents/log.csv","abcdefg","UTF-8");

Environment自体はstaticで定義されていますから、当該パッケージをimportするだけでそのまま使えます。上記ではとりあえずDocuments以下にファイルを作成してみました。
さてこれでいいだろうと思ったら、まだPermissionがないと怒られます。再度、ググった結果当該パッケージのManifest.xmlに以下の記述が必要なのだとか。(デフォルトではファイルアクセス禁止のプログラムしか作れないんですか Orz)

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>


Manifest.xmlのどこに記述したらいいのかわからなかったので、そこはeclipseのUIにおまかせしました。(結果見ると、自前でタグ定義しているんでどこでもよさそうです。)

これでやっと準備ができたと思います。(移植しようと考えてるJavaプログラムのファイル入出力のモジュールをAndroid用に修正しないといけません)

追記:
ところで実際にAndroid端末(Nexus7を使ってます)をUSBでPCと接続し、先ほどプログラムで作成したファイルを見てみようとしたんですが、なんと見えません!Nexus7のファイルエクスプローラ・アプリでは確かにファイルが存在しいるんですが、PCではファイルが表示されません。同じディレクトリにある別のファイルはNexus7でもPCでも見えるんですが。。。
またまたググって、しかし今回はどんなキーワードで検索したらいいのか思いつきません。結構時間がかかりましたが、原因と思えるものが見つかりました。

・MTP(メディアデバイス)
Nexus7の設定みているとUSBストレージという名称じゃない別の名称のMTPで接続というのがあります。これは従来のUSBストレージだとUSBスティックのようにFATでファイルシステムを作り、それをPCから参照します。これって考えると結構危険です。Nexus7側のアプリが開いているファイルでもPCから修正できちゃうことになりますから。なのでMTPは一種のネットワークドライブのようにPCからは見せて、ファイルシステムとして認識しなくてもいいようにします。(Android3.1からこの機能がついたようです)
端末によっては従来のUSBストレージによる接続も残しているようですが、Nexus7では見当たりませんでした。(まあAndroidを主導しているGoogleとしては、新しい方式にして欲しいだろうし)

・マルチアカウント
最新のAndroid4.2.1からでしたか、マルチユーザーの機能が付加されました。当然、ファイルシステムだってその影響がでます。具体的には外部ドライブだろうが、各ユーザーが使えるエリアはユーザーアカウント毎に用意されています。具体的にいうと以下のような感じになるそうです。

/sdcard/0/Documents等

数字のところがユーザーに割り振られた番号で(UIDのようなものです)、各ユーザーごとに番号が振られます。つまりNexus7に異なるユーザーで使っていると、他人のユーザーの外部ストレージは見えません。(セキュリティ上のためもあります)更にいやらしいことに、上記の数字よりTopの"/sdcard"というのもAndroidの実装まかせで固定していないんだそうです。(いやこれは強制しようよ、Googleさん)それを回避して一つのアプリで複数の機種に対応するため、/sdcard/0までを取得するメソッド(getExternalStorageDirectory())が用意されたそうです。

さてここまで調べて、ファイルが見えなかった理由の推測ですが、Android4.0になってからでしたっけ、明示的なタスク管理のタスクマネージャーがなくなりました。そのため、試験的に作成したプログラムが停止していると思っても、実は裏でファイルハンドルをつかんで離さないから、PC側からは見えないんではなかろうかと。確実に確認するためにNexus7を再起動して、PCに接続すると無事プログラムが作成したファイルを見ることができました。(設定→アプリケーションで選択して強制終了してもいいと思います)


2013年1月4日金曜日

Androidプログラム開発-数値の入力

久しぶりに、Androidのプログラム開発(あえてアプリとはいいません。個人的に楽しむのが主目的なんで)をしてみました。

Javaで少し計算プログラムを作ってたんですが、それをAndroidに移植したくなりました。Javaプログラムの時はGUIも作ってみたんですが、計算諸元の設定は基本ファイルか、プログラムに直にコーディングで済ませてしまっていましたが、さすがにAndroidプログラムではそれはまずかろうと、GUI作って、その入力部分の作成からです。

Android開発環境ができていれば、GUI部分の開発(?)は簡単です。

(ラベルのところはあえて消してあります。ご容赦を_(._.)_)
ところで、このプログラムはAndroid4.0.3以降(API15)でプロジェクトの作成をしたんですが、昔はあった記憶のあるラベルwidgetがありません。しかたないので、Text widgetを貼り付け、初期の文字列を設定します。(activity_main.xmlに直に文字列書くと、eclipseがwarning出してくるので、面倒くさいんですが、文字列定義はstring.xmlを使うようにしました。多国語対応が簡単にできるようになんでしょうが、どうせ日本語しか作るきはないので無視してもいいんですが。)

1.ラベル相当が作れない
Textでラベルを作ろうと思っても、デフォルトは編集可能です。これをなんとか編集不可にしないといけません。調べてみると、当該widgetのandroid:editableという属性を"false"にすればいいらしいんですが、非推奨ということでeclipseではwarningがでてきます。それじゃどうしたらいいかというと、android:inputTypeで設定しろとのことですが、入力不可の"none"にしても(画面上では)編集はできてしまいます。どうしてもいい方法が見つからず、あきらめてandroid:editable属性をactivity_main.xmlで定義しました。(ただこの方法だと非推奨なので、warningはでます。)

2.(数値の)入力
これが一番苦しみました。widget自体はEditTextで作成すればいいんですが、ここで(符号付)数値のみの入力に制限しようとしますが、なかなかうまくいきません。関連したのは以下です。

number:数値入力する場合に指定します
numberSigned:符号付数値を入力する場合に指定します
numberDecimal:少数入力する場合に指定します

色々試してみましたが、numberSigned|numberDecimalがよさげです。(numberだと小数点が入力できません)
続いてこれの読み取りですが、結局以下のような感じになります。

double ldlat;
EditText latText=(EditText)findViewById(R.id.editLat);
String input=latText.getText().toString();
ldlat = Double.parseDouble(input);

文字列で入力された数値をdouble型に入れたいんですが、結構面倒でした。int型等それぞれparse関数があります。方法を見つけるのに時間がかかったのが、EditTextからgetしてくるとき、どうやってString型にするかでした。それさえわかれば、あとは簡単でした。

本来の作業はこれからですが、入力さえ解決してしまえば後は単純作業です。(問題になるとしたら、Android端末側のCPUパワーやメモリ等のリソースからくる制限でしょうね)

2013年1月2日水曜日

Clangのこと

FreeBSDのデフォルトCコンパイラがLLVM Clangになったとのこと。
従来のgccを2012年11月のFreeBSD 10-Currentから替えたそうです。(もっともgccをデフォルトで使う設定も残されます。完全に互換性がなく、まだgccでないとビルドが通らないものがあるそうです)

なんでこんことをメモしたかというと、gnuの新しいライセンスGPLv3が色々と物議を醸している影響です。実際、LinuxのkernelもGPLv2のままでGPLv3への移行はしないと決定したと聞いています。問題なのが、GPLv3に入れられた条項で、特許を放棄しろというような項目があるんだそうです。わかりやすくいうと、GPLv3を表明しているgccでプログラムを作成すると、当該プログラムは特許を放棄することが要求されるようです。(このあたり解釈が難しいらしい。完全強制するという表現ではないようです。ただ企業としてはいやですよね。)
このところライセンスよりも、企業の利権を守るために特許でさんざん争われてるため、copyleftだけでは自由なプログラムの実現が困難だと考えたんでしょうね、Richard Stallmanさん。ちょっと過激すぎる気もします。(でもLinux kernelはgccでビルドされてたはず。そのあたり完全な強制力はないのか、あるいはLinux kernelは今後GPLv2のgccでしかビルドしないのか、よくわかりませんが)

それでBSDライセンスのLLVM Clangが注目されてるんだそうです。しばらくは、gccのライセンスやら、GPLv3がどうなるのか見てないといけません。(確か、GPLv3の文言決めて公開するのにもずいぶん時間がかかった記憶があるから、まだ流動するでしょう。)