Raspberry-PiにおけるGPIO関係ツールのインストール方法

まだ検証の途中なのだけど、このままだと忘れそうなので一旦公開(2014.1.24)

Raspberry-PiのGPIOを操作するためのツールについてまとめた。
Raspberry-Piには基板上に13×2ピンのコネクタがあり、GPIOを利用することができる。

http://elinux.org/RPi_Low-level_peripheralsより)
GPIOへ直接アクセスする方法以外に、公開されているツールを利用することができる。
ここでは、PWMのためにWiringPiを、サーボ制御のためにServoBlasterを用いる方法について説明する。
続きを読む →

ARM版AndroidのためのPharoアプリケーションの構築方法

あまり知られていないかもしれないが、Android上でPharo Smalltalkを動かすことができる。実際にPharoで作られたDrGeoというアプリケーションがGoogle Playで配布されているくらいだ。
以下では、Android上で動くPharoアプリケーションをどのように作るかについてまとめる。
情報源としては、squeakvm-tabletを参考にした。
なお、上記サイトではCogDroidとPharoDroidの2つのVMが利用できると書かれているが、後者は現時点でダウンロードできないため、前者のCogDroidを用いた作成方法について説明する。また、一般的にARMアーキテクチャのデバイスを用いることが多いと思われるのでARMに絞った話にしてあるのと、私自身はMac上で開発を行っているので、Macでの方法であることを予め断っておく。
続きを読む →

PharoでXMLRPCを使う(2)

以前にPharoでXMLRPCを使う。という記事を書いたが、Pharo 2.0でXMLRPC使おうとすると問題が起こる。
というのもXMLRPCではKom系のWebサーバーを使っているのに対して、Pharo 2.0ではZincがデフォルトだからである。
過去の記事どおりにインストールしようとすると、いろいろなパッケージを入れた後でエラーとなってしまう。
手動でKom系を追加してもいいのだろうが、今後どのような扱いがされるのか不安なので、XMLRPCでZincが使えるようにした。
嘘です。嘘を言いました。ごめんなさい。
実は、既にXMLRPCではZincが使えるようにされているので若干の修正を加えればちゃんと動きます。
ConfigurationOfXMLRPCを書き換えるのが面倒だったので、以下では、手動で構築する手順について述べていきます。

準備

XMLParserとXMLWriterが必要なので、あらかじめパッケージをインストールしておきます。

MetacelloConfigurationBrowser open.

でMetacelloのブラウザを起動し、一覧からXMLParserを選んでInstallボタンを押してインストールします。
ついでにXMLWriterも自動的にインストールされるので、これで準備はOKです。

Client-Coreパッケージのロード

まずは、XMLRPCのClientパッケージをロードする。そのために、Monticelloにレポジトリを追加する。

MCHttpRepository
	location: 'http://ss3.gemstone.com/ss/XMLRPC'
	user: ''
	password: ''

上記のようにHTTPのレポジトリを追加して開くと、XMLRPC関係のパッケージが表示される。
XMLRPC-Client-Coreを選んだら、右側のペインでXMLRPC-Client-Core-SantiagoBragagnolo.30を選んでLoadする。
(おそらく、これ以降のパッケージを選んでも大丈夫だと思うが、EiichiroItoというシグネチャのものは選ばない方がいいと思われるwww。以下同様。)

Client-Testsパッケージのロード

この手のパッケージでテストしないのは地獄を見るだけなので、Testsパッケージも追加する。
先ほどのレポジトリから、XMLRPC-Clients-Testsを選び、右側のペインでXMLRPC-Client-Tests-SantiagoBragagnolo.14を選んでLoadする。

Server-Coreパッケージのロード

レポジトリの左側のペインでXMLRPC-Server-Coreを選び、XMLRPC-Server-Core-SantiagoBragagnolo.19をLoadする。

Server-Testsパッケージのロード

レポジトリの左側のペインでXMLRPC-Server-Coreを選び、XMLRPC-Server-Tests-SantiagoBragagnolo.9をLoadする。
これで一通りのパッケージがロードできた。
しかし、現在のテストコードはKom用なので、これをZinc用に書き換える必要がある。

XMLRPCTestクラスの修正

XMLRPCTestクラスのsetUpメソッドを修正する。このメソッドでは、XMLRPCKomServerEchoTestを使ってテストするように書かれているが、この部分をXMLRPCZNServerEchoTestに書き換える。

XMLRPCStandardEchoクラスの修正

XMLRPCStandardEchoクラスのクラス側メソッドであるecho:を修正する。

echo: aValue
   ^aValue

元のコードでは、エコーで返されるコレクションのfirstをとるようになっているが、このfirstを削除してaValueそのものを返すようにする。

XMLRPCZNServerEchoTestクラスの修正

XMLRPCZNServerEchoTestクラスのsetUpを修正する。

setUp
	"self new setUp"
	"XMLRPCHttpModule stop"
	XMLRPCServer defaultClass: XMLRPCZNServer.
	newServer := false.
	XMLRPCStandardEcho addTests.
	XMLRPCHttpModule
		start;
		setDebugMode.
	(Delay forMilliseconds: 5) wait.
	newServer := true

元のコードでは、HttpServiceでサービスの登録有無を確認しているが、特に必要ないと思われるのでその部分をごっそり削除する。
以上でZincへの対応は終わり。テストクラスのうち、XMLRPCKomServerEchoTestとXMLRPCKomServerTestを除けばちゃんとグリーンでテストがとおるようになる。

問題点

実は大きな問題があり、この修正をかけた後でサーバーを起動したまま保存&終了すると、次回Pharoがフリーズするという現象を確認している。
Save & Quitする場合は確実にサーバーを止めないと非常に痛い目にあうので注意すること。

NativeBoostで音をならす(Windows版)

昨日のSmalltalk勉強会で学んだNativeBoostで何をやろうかいろいろ考えてたけど、今朝ふっと思い立ったのは「音を鳴らす」だった。
学園祭のゲームで音がないのが寂しかったけど、PharoSoundの状況は芳しくないしどうにもならないと考えていた。
でも、マルチメディア関数を使えば直接鳴るはずではないか!ということに気づいた。
ということで、適当なクラス(SoundTest1)を作って、以下のようなメソッドを追加した。

playSoundNamed: aString
  <primitive: #primitiveNativeCall module: #NativeBoostPlugin>
  ^ self nbCall: #( int PlaySoundA (String aString, 0, 1)) module: 'C:\Windows\System32\winmm.dll'

でもって適当なワークスペースで以下をDo itする。

SoundTest1 new playSoundNamed: 'C:\Windows\Media\chimes.wav'

チャイムが鳴った!
Windows XPでしか試していないけど、超手軽に音を鳴らせることができた。
あと1週間前に気づいていればゲームも華やかになったのだが…
来年の楽しみにしておこう。

ようやく形になってきた

現在開発中の新しいVPLであるFluoが少しずつ形になってきた。
Fluoは、データフロー風のメッセージ送信をベースとしたビジュアルなプログラミング環境であり、さまざまな入力データを「流れ」として捉え、少しずつ加工しながら出力データを作り出して行くもの。
もともとフィジカル系のデバイスから得るデータの処理に困ったときに、よりハンドリングしやすい環境が欲しいと思って作りはじめた。
ROSがtopicを介して通信することにインスパイアされ、その仕組みをSmalltalkにおけるメッセージ送信で実現しつつ、Pharoの強力な開発環境も利用できるように改良を続けてきた。
初期の頃に書いたFluoの説明はこちら
まだ開発は半ばで、どんなノードをどのように使うのがスマートなのか模索している。
ただ、当初思い描いていた機能の多くは実現できてきたように思う。
Fluo - TurtlesimBumperDemo
上のグラフはタートルの移動中の衝突時に行う動作を記述したプログラムである。これは動作テストのためのもので実際にはROS経由で何らかのロボットを動かすことを想定している。

  1. 画面左側に並んだボタンの中から→(Open)ボタンを選ぶとプログラムが起動する。
  2. 起動によってTimerがスタートし、1秒間隔で3つのDataPackBehaviorにtickメッセージを送る。
  3. それぞれのBehaviorはTurtleを前進、後退、右回転させるためのデータを生成し、Timerからのメッセージに従ってデータを送信する。
  4. Inhibitorは通常はラベルのないアークから受けとったデータを下流に垂れ流すだけだが、tickメッセージを受け取ると一定時間だけラベルの付いたアークからデータを流すようになる。
  5. 通常、左上のInhibitorは前進データをTurtleに送るが、左下のボタンが押されてtickメッセージを受け取ったときだけ、10秒間右下のInhivitorからのデータを送る。
  6. 右下のInhibitorは、通常は右回転し、tickメッセージ受信で5秒間後退するデータを送信する。
  7. ボタンからのtickメッセージは2つのInhibitorに同じタイミングで送られるので、実際にはTurtleは5秒間後退した後、残り5秒間右回転した後、前進を再開する。

ざっとこんな感じの動作内容である。
1つのノードから発せられるデータは、アークで接続された全てのノードに配信されるので、全体のノードが並列的に動作する。
途中に流れるデータの様子が知りたければTranscriptに出したり、グラフとして表示することができる。
まだいろんな応用で使えるようなBehaviorは不足しているが、今後少しずつ充実させていく予定である。

Raspberry piのインストール

以前に3台購入した後、1台のみセットアップしたのだが手順をすっかり忘れてしまったので、新たな1台のセットアップを兼ねて備忘として残す。

SDカードへのイメージ書き込み

SDカードをMacに差し込んだ後、

diskutil list

にて/dev/disk1以下にマウントされていることを確認。

diskutil unmount /dev/disk1s1

にてアンマウント後、以下にて最新のイメージを書き込む。

sudo dd if=2013-09-25-wheezy-raspbian.img of=/dev/disk1 bs=1m

config.txtの書き換え

書き込みが終わるとbootがマウントされるので、この中のconfig.txtを修正する。
(以下はHDMI対応オンダッシュモニタの設定。接続するディスプレイ毎に設定は異なるはず)

vi /Volumes/boot/config.txt

先頭に以下を挿入。

hdmi_mode=4
overscan_left=-32
overscan_right=-32
overscan_top=-32
overscan_bottom=-32

終わったら以下でSDカードをイジェクトしてRaspberry piへ挿入する。

diskutil eject /dev/disk1

接続

セルフパワーのUSBハブのPC側をRaspberry piのUSB-Aポートに接続し、USBハブのポート側をRaspberry piのmicro USBポートに接続する。
HDMIケーブルでHDMIポートとHDMIディスプレイとをつなぎ、ディスプレイの電源を入れておく。タイミングが悪いと起動後表示されないので注意する。
LANケーブルやキーボード、マウスを適当につないでUSBハブの電源を入れる。

起動

起動後、初回は自動的にraspi-configが起動する。Expand Filesystemで最初だけSDカードのパーティションを拡張する。
次にInternationalisation Optionsで、localeの変更を行う。en_US.UTF-8およびja_JP.UTF-8だけをセットし、デフォルトのlocaleはNoneにした。
TimezoneはAsia/Tokyoを選ぶ。HHK2 LiteのUSモデルなのでキーボードレイアウトは、Generic 101keyとし、レイアウトはUSにした。(テキトー)
Advanced Optionsでは、hostnameの設定とSSHの有効化を行う。
raspi-config終了後にrebootを促されるので再起動。

最新パッケージへのアップグレード

お決まりのアップデート&アップグレード。

sudo apt-get update
sudo apt-get upgrade

NesTalkでマリオを動かす

Pharo上でマリオが動くという。ウチのゼミではマリオゲームもどきを作っているだけに、どんなものかを試してみた。
NesTalkというパッケージがそれらしい。パッケージ名のとおりNESのエミュレータをPharoで実装したもののようである。
YouTubeのビデオを見るとちゃんと動いていることがわかる。
そのままインストールしようとするとパッケージが不足している旨の警告が出るため、BabyMockのインストールからはじめる。

MCHttpRepository
    location: 'http://ss3.gemstone.com/ss/BabyMock'
    user: ''
    password: ''

上記のレポジトリから、ConfigurationOfBabyMockをインストールする。続いて、

ConfigurationOfBabyMock loadDevelopment.

によってBabyMockをインストールする。
次に、以下のレポジトリからNesTalkをインストールする。

MCHttpRepository
	location: 'http://smalltalkhub.com/mc/zeroflag/NesTalk/main'
	user: ''
	password: ''

適当にロムイメージを入手して、以下のように起動する。パス名の指定のところは適当に変える必要がある。

nes := NesTalk new.
nes insertCartridge: (NtCartridge romFile: (FileSystem disk workingDirectory / 'mario_bros' / 'Mario Bros.nes') pathString).
nes powerOn.

終わったらビデオの通り、以下のようにシャットダウンする。

nes powerOff.

うちの環境(MacBookAir)では、8キーで左、0キーで右に移動できたが、その他のキーがよくわからないためクリアすることはできなかった。
どうやらキーコードの取り方の問題のようで、NesTalkWindow>>#handlesKeyDown:と#handlesKeyUp:を変更することで操作できるようになった。

handlesKeyDown: anEvent
	anEvent keyValue = 6 ifTrue: [joypad pressButtonAt: NtJoypad buttonA. ^ true].
	anEvent keyValue = 7 ifTrue: [joypad pressButtonAt: NtJoypad buttonB. ^ true].
	anEvent keyValue = 125 ifTrue: [joypad pressButtonAt: NtJoypad buttonDown. ^ true].
	anEvent keyValue = 126 ifTrue: [joypad pressButtonAt: NtJoypad buttonUp. ^ true].
	anEvent keyValue = 123 ifTrue: [joypad pressButtonAt: NtJoypad buttonLeft. ^ true].
	anEvent keyValue = 124 ifTrue: [joypad pressButtonAt: NtJoypad buttonRight. ^ true].
	anEvent keyValue = 36 ifTrue: [joypad pressButtonAt: NtJoypad buttonStart. ^ true].
	anEvent keyValue = 49 ifTrue: [joypad pressButtonAt: NtJoypad buttonSelect. ^ true].
	^ false
handlesKeyUp: anEvent
	anEvent keyValue = 6 ifTrue: [joypad releaseButtonAt: NtJoypad buttonA. ^ true].
	anEvent keyValue = 7 ifTrue: [joypad releaseButtonAt: NtJoypad buttonB. ^ true].
	anEvent keyValue = 125 ifTrue: [joypad releaseButtonAt: NtJoypad buttonDown. ^ true].
	anEvent keyValue = 126 ifTrue: [joypad releaseButtonAt: NtJoypad buttonUp. ^ true].
	anEvent keyValue = 123 ifTrue: [joypad releaseButtonAt: NtJoypad buttonLeft. ^ true].
	anEvent keyValue = 124 ifTrue: [joypad releaseButtonAt: NtJoypad buttonRight. ^ true].
	anEvent keyValue = 36 ifTrue: [joypad releaseButtonAt: NtJoypad buttonStart. ^ true].
	anEvent keyValue = 49 ifTrue: [joypad releaseButtonAt: NtJoypad buttonSelect. ^ true].
	^ false

なお、上記の変更を行えば、Mac以外の環境では動かないと思われるので注意。

古いIntel iMacにWindows8をインストールする

BootCamp 5.0では古いiMacにWindows8をインストールできない。そこでその対処方法。

必要なもの

  • Windows 8のインストールディスク
  • Windows 7のインストールディスク
  • 空のDVD-RWディスク
  • Windowsの動いているPC

手順1:WindowsAIKのインストール

後述のようにBootCampをインストールしてから、Windows8のインストールディスクを入れてブートしても、「Select CD-ROM Boot Type:」のように表示されるだけで先に進むことができない。
そこで、ここの手順に従ってWindowsAIK(自動インストールキット)により新たなインストールディスクを作成する。
AIKインストールの手順は省略。
Windows8のインストールディスクをドライブに挿入してから、「スタート-Microsoft Windows AIK-Deploymentツールのコマンドプロンプト」を選んでコマンドプロンプトを起動し、以下を入力する。
(なお、DVDドライブはR:とし、作成するisoファイルはC:のルートに格納するものとする)
oscdimg -n -m -bR:\boot\etfsboot.com R:\ C:\Win8.iso
isoファイルが作成できたら空きDVD-RWディスクにWin8.isoを書き込む。

手順2:MacでWindows8用のパーティションを作成する

とりあえずBootCampをインストールする。
Windows用のパーティションを作成するために、Windows7のインストールディスクを挿入する。
(Windows8のインストールディスクを入れても続行できなくなる)
自動的に再起動するタイミングでOptionキーを押したままにし、HDDからブートさせる。
(でないとWindows7がインストールされてしまう)
Windows7のインストールディスクを取り出し、Win8.isoを書き込んだ新しいディスクに入れ替える。
Macをリブートして、Optionキーを押したままにし、DVDドライブを選んで進む。
後は問題なくインストールを進めることができる。