乱暴と待機

December 29, 2010

乱暴と待機

舞台のほとんどは小さな一軒家。
その家には片足が不自由な30手前の男と、男からの復讐を待つ妹が住んでいる。ある日、男は天井裏に身を隠す入り口を見つけ、妹を監視するようになる。

序盤の閉じた世界から徐々に変化が起きて、リアリティーの基準が変わっていくのが面白い。

この作者の本は、読み終わるといつもよく分からない興奮で頭がいっぱいになる。終盤で登場人物の感情がぶわぁーっと吹き出して、それにのまれてしまう感じ。とにかくなんか凄い。

本谷 有希子 (著)
単行本(ソフトカバー): 224ページ
出版社: メディアファクトリー (2008/2/27)

プログラマが知るべき97のこと


プログラマが知るべき97のこと

経験豊富なプログラマー達のエッセイ集。プロとはかくあるべきといった思想論から、コードテストについての細かなTIPSまで、様々な視点で書かれている。

自分は巨大プロジェクトに関わるようなプログラマとは違うのだけど、思想的な話はとても為になった。勉強し続ける事、自分の仕事に責任を持つ事。プロと呼ばれる為に肝に銘じておなかなくてはと思った。

具体的なTIPSとして気に入ったものをいくつか。
・見られて恥ずかしいデータを使わない事(ロッド・ベグビー)
・プログラミング言語は複数習得すべき(ラッセル・ワインダー)
・コードに書けないことのみをコメントにする(ケブリン・へニー)


和田 卓人 (監修), Kevlin Henney (編集), 夏目 大 (翻訳)
単行本(ソフトカバー): 276ページ
出版社: オライリージャパン (2010/12/18)

群れのルール 群衆の叡智を賢く活用する方法


群れのルール 群衆の叡智を賢く活用する方法

ピーター・ミラー (著)
単行本(ソフトカバー): 298ページ
出版社: 東洋経済新報社 (2010/7/16)
ofxKinect Test 2

ofxKinect Test 2

December 4, 2010
Kinectでジェスチャー操作を実験しました。
手のひらの前後で拡大縮小、左右に振ると回転します。

ofxKinect Test 3 from HR2 on Vimeo.

さてこれで準備が出来たので、次は放置していたFIOラジコンを動かしてみます。

ofxKinect Test

November 22, 2010
Kinectが届いたので、さっそくofxKinectを試してみました。
ofxKinect



深度や色の情報はかなり簡単に取り出せます。きちんとチューニングすれば結構いい精度がでそうです。
で、カメラの映像に奥行きを付けるデモを作ってみました。他の方もたくさんやられていますが、通過儀礼という事で。

ofxKinect Test 2 from HR2 on Vimeo.



ofxKinect Test 1 from HR2 on Vimeo.

上のデモでは赤外線による深度測定とカメラを利用していますが、他にも3軸加速度センサーとマイクが付いています。Xboxのゲームでは、マイクでアバターをクチパクさせていました。また、Kinect本体をチルトさせるためのモーターも内蔵されています。

使い方次第で可能性が広がりますね。

Geometory Wars : Touch の操作性を向上するハック

November 20, 2010
iPhoneでもGeometory Warsを快適にプレイしたい!
Geometory Warsというのは、Xbox 360のシューティングゲームで、DSにも移植されている人気シリーズです。グラフィック・サウンド・ゲーム性、すべてが素晴らしく、とても中毒性があります。そのiPhone/iPod版がGeometory Wars : Touchとして発売されました。
Geometory Wars : Touch

しかし、カスタマーレビューなどではタッチパネルでの操作性について問題が指摘されています。iPhoneのゲームとしては一般的な仕様ですが、レバーと比べると繊細な操作が難しいため、Xbox版をやり込んだ人ほど違和感を感じてしまうようです。僕も自由に操作できないために、面白さが半減していると感じました。グラフィックやゲーム性は忠実に再現されているだけに実に惜しい。

ローテクは強い
そこで操作しやすくするハックを考えました。用意するのはこのようなゴム足。直径が小さく、透明なものがいいです。


このゴム足をインターフェースの位置に合わせて貼り付けます。これだけ。



十字キーは偉大
タッチパネルで操作しにくい原因の一つは、手触りが無いため方向キーの起点が分からない事です。わずかでも突起があると、そこを中心に方向が分かります。
また、ゴム足の上はタッチに反応しないので、方向を瞬間的に変えられます。右ー>左と入力を切り替えたい場合、普通は起点の左側に指を滑らせます。ゴム足があると親指の傾きを変えて左右を切り替えられ、ファミコンの十字キーに近い感覚になります。わずかな違いですが、このゲームをプレイする上では大きな差です。

ちなみに、これを貼り付けたまま何日か過ごしましたが、メール・電話など他の操作の時も、"思ったより" 邪魔にならないです。


Geometory Wars : Touch from HR2 on Vimeo.

Arduino Fioでラジコン その3

September 14, 2010
Arduino Fioでラジコンシリーズ >その1 >その2 >その3

前回の予告通り、モータードライバを使ってモータをコントロールし、後進・旋回させたいと思います。

■準備したもの
楽しい工作シリーズ No.100 トラック&ホイールセット
モータドライバ TA7267BP


前回は、トランジスタを単純にON/OFFの為に使いましたが、うまい事回路を組むとモーターに流れる電流を逆転させる事ができます。>Hブリッジ回路
でも、世の中には、これらの回路がパッケージされた便利なICがあるので、今回はそれを使います。

TA7267BP。ちなみに、ピンの番号はこの向きで、左が1、右が7です。

回路はこんな感じ。FioのシンボルがなかったのでDuemilanoveで代用しています。使用しているピンの番号は同じです。



1つのドライバにつき2本の信号のon/offの組み合わせで、以下の4つの状態を制御します。
ブレーキは止める力がかかり、ストップは空転するみたいです。(ちがうかも)

右モーター
D10 = high, D11=high > ブレーキ
D10 = high, D11=low > 逆転
D10 = low, D11=high > 正転
D10 = low, D11=low > ストップ

左モーター
D5 = high, D6=high > ブレーキ
D5 = high, D6=low > 逆転
D5 = low, D6=high > 正転
D5 = low, D6=low > ストップ

そして、左右のモーターを組み合わせて、移動します。
右:正転、左:正転 > 直進
右:逆転、左:正転 > 右旋回
右:正転、左:逆転 > 左旋回
右:逆転、左:逆転 > 後進

Arduino Fio Demo1 from HR2 on Vimeo.



足回りをキャタピラにしたら戦車っぽくなってきたので、次回はその辺を強化したいと思います。そろそろoF使ったネタにしたいです。

Arduino Fioでラジコンシリーズ >その1 >その2 >その3
ベルカ、吠えないのか

ベルカ、吠えないのか

September 3, 2010

ベルカ、吠えないのか

太平洋戦争中にアメリカ軍に捕えられた4頭のイヌの子孫が、人間に翻弄されながら、世界に広がっていく物語。

イヌの血統を証人として、現代史を描くという構造がとてもユニーク。綿々と連なるイヌの歴史と、人の歴史。戦場で相対した2頭が、元をたどれば同じ始祖を持つというエピソードは、人間同士の敵対関係への皮肉のように思えます。主体がイヌだからこそ描かれた、激しい生への執着に胸が熱くなります。

ただ、この作品は決して重苦しいものではありません。勢いのある独特な文体と、魅力的なエピソードによって、すばらしいエンターテインメントとして仕上がっています。


古川 日出男 (著)
単行本: 344ページ
出版社: 文藝春秋 (2005/4/22)
発売日: 2005/4/22

Arduino Fioでラジコン その2

September 1, 2010
Arduino Fioでラジコンシリーズ >その1 >その2 >その3

前回、PCとArduino Fioが通信するところまで出来たので、今回は工作キットの車に乗せて、走らせてみました。

■準備したもの
楽しい工作シリーズ
No.168 ダブルギヤボックス 左右独立4速タイプ
No.101 トラックタイヤ 36mm
No.98 ユニバーサルプレートセット
No.152 単4電池ボックス 1本用 スイッチ付

説明書に従って作ります。久々の工作、楽しかったです。



■モーターを動かす回路
Fioの出力は、モーターを回せるほどの電流を供給できません。そこでトランジスタを使います。下図の2SC1815というパーツです。電池からモーターを通過した電流は、トランジスタに入ります。ここでD12,D13がOnの場合は、電流が流れてモーターが回り、Offなら流れません。こちらにしっかりとした説明があります。トランジスタ回路の基本設計法



上の回路図を組上げるとこんな感じになります。この状態で、前回テストで使ったProcessingのarduino_output を操作すると、左右のタイヤが動くと思います。


■openFrameworks
次に操作アプリを作ります。先ほどはProcessingを使いましたが、今後の拡張のしやすさを考えて、慣れているopenFrameworksを使います。
ofフォルダのapps/example/firmataExampleにArduinoを扱うサンプルがあります。これを必要な部分だけ残し、以下のように改造しました。上キーでD12,13をOn(前進)、右キーでD12だけOn(右旋回)、左キーでD13だけOn(左旋回)です。

testApp.h
#ifndef _TEST_APP
#define _TEST_APP

#include "ofMain.h"
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed  (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);

void setupArduino();
void updateArduino();
ofArduino ard;
bool bSetupArduino;
};
#endif


testApp.cpp
#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
ard.connect("/dev/cu.usbserial-A700eEMl", 57600); //適宜、変更してください
bSetupArduino = false;       // flag so we setup arduino when its ready, you don't need to touch this :)
}
//--------------------------------------------------------------
void testApp::update(){
if ( ard.isArduinoReady()){

// 1st: setup the arduino if haven't already:
if (bSetupArduino == false){
setupArduino();
bSetupArduino = true; // only do this once
}
// 2nd do the update of the arduino
updateArduino();
}
}
//--------------------------------------------------------------
void testApp::setupArduino(){
// this is where you setup all the pins and pin modes, etc
for (int i = 0; i < 13; i++){
ard.sendDigitalPinMode(i, ARD_OUTPUT);
}
ard.sendDigitalPinMode(12, ARD_OUTPUT);
ard.sendDigitalPinMode(13, ARD_OUTPUT);  // on diecimelia: 11 pwm?*/
}
//--------------------------------------------------------------
void testApp::updateArduino(){
// update the arduino, get any data or messages:
ard.update();
}
//--------------------------------------------------------------
void testApp::draw(){
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
switch ((int)key) {
case 357:
ard.sendDigital(12, ARD_HIGH);
ard.sendDigital(13, ARD_HIGH);
break;
case 356:
ard.sendDigital(12, ARD_LOW);
ard.sendDigital(13, ARD_HIGH);
break;
case 358:
ard.sendDigital(12, ARD_HIGH);
ard.sendDigital(13, ARD_LOW);
break;
default:
ard.sendDigital(12, ARD_LOW);
ard.sendDigital(13, ARD_LOW);
break;
}
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){
ard.sendDigital(12, ARD_LOW);
ard.sendDigital(13, ARD_LOW);
cout << "Release" << endl;
}


■試運転

Arduino Fio Demo1 from HR2 on Vimeo.



■まとめ
この回路ではモーターを回すか止めるかしかできないので、バックは出来ません。また、後輪を独立して動かすだけでは、左右に曲がれませんでした。
後進するためには、モーターに流す電流の向きを逆にする必要があります。今回のようにトランジスタを組み合わせて、回路を作る事も出来ますが、基板が大きくなるのと面倒なので、普通は専用のモータードライバICを使います。また、旋回は、左右のモーターを逆回転させて行います。


という事で、次回は戦車のようなキャラピラに変え、後進と旋回できるようにしたいと思います。

Arduino Fioでラジコンシリーズ >その1 >その2 >その3

Arduino Fioでラジコン その1

August 31, 2010
Arduino Fioでラジコンシリーズ >その1 >その2 >その3

遠隔操作は男の夢、という事でArduion Fioを使ってラジコンを作ってみます。
まずは、プロジェクトの要、Fioを制御します。

■準備したもの
XBee エクスプローラー USB ドングル
XBee U.FLコネクタ型
XBee用外部アンテナU.FLコネクタ型
Xbee チップアンテナ
Arduino Fio
リチウムイオン電池

http://code.google.com/p/funnel/からfunnel-1.0-r750.zipをDL。解凍して適当な場所に置きます。

■電池の充電
リチウムイオン電池のコネクタをFioに差し、USBを繋ぎます。USBは単純に電源をとっているだけです。

■XBeeのセットアップ
PC用とFio用、両方のXBeeにID等を登録し、セットアップします。

まず、Fio用から。
XBee エクスプローラーにFio用のXBeeを乗せ、PCに接続します。
funnel-1.0-r750/tools/XBeeConfigTool/application.macosx/XBeeConfigToolを起動します。ソフトのバージョンによって、文言が若干違うようです。

Serial Portは、usbserialってなってるものを選択。
ModeはPC側かFio側かということなので、Arsuino Fio radio。
Baud rate は使用するFioに合わせて適宜。今販売している物なら57600。
以下はModeを選ぶと自動的にデフォルト値が入るので、そのままでOK。

PAN IDは接続するグループを識別する番号かな。今の環境では1系統のみなので何でも良いと思います。
MY IDは個体識別番号らしいので、2台目以降はここを増やします。DL IDはよく分かりません。
「Configure」をクリックすると書き込み始めます。

続いてPC側。Fio用のXBeeを外し、PC用を乗せます。

ModeはProgramming radioを選択。
Serial Port, Baud rate等はFio用と同じ。ID類はデフォルトのまま。


これでPCからXBeeを経由してFioにプログラムを書き込めるようになりました。試しにsampleのBlinkを書き込んでみます。
Arduino IDEを起動し、File > Examples > Digital > Blinkを開きます。Tools > Board > Arduino Pro / Pro mini(3.3V,8MHz)w/ATmega328 を選択。
Tools > Serigal Port > 先ほど使用したusbserialを選択し、Uploadします。
書き込みに成功すれば、FioのLEDが点滅するはずです。周囲の電波に影響を受けるそうなので、うまくいかない場合はWifi等を切ってみてください。


次に、PCとやり取りするためのファームウェア(Firmata)を書き込みます。
ArduinoIDEで、funnel-1.0-r750/hardware/fio/firmware/StandardFirmataForFio/StandardFirmataForFio.pdeを開き、先ほどと同じようにしてFIoに書き込みます。データ量が多いため少し時間がかかります。Done uploading.表示されれば成功。

Firmataが動作するか試してみます。
Processingを立ち上げ、File/Sketchbook/Libraries/arduino/example/arduino_outputを実行します。14個のボタンが表示されるので、一番左側をクリックするとFioのLEDが反応すると思います。

これで、FioとPCがやり取りできるようになりました。次回は車を作って、モーターをコントロールします。

Arduino Fioでラジコンシリーズ >その1 >その2 >その3
罪と罰 宇宙の後継者

罪と罰 宇宙の後継者

August 30, 2010


罪と罰 宇宙の後継者

三人称視点のシューティングゲーム。ルートに沿ってステージを移動しながら、自機と照準を別々に操作します。
シューティングというジャンルは古典的かもしれませんが、演出・ゲームバランス・操作性によって、とても新しい体験をする事ができました。

ルートに沿って進む方式なので、初めは自由度が低いという印象を持ちましたが、強制的に視点を変える事で、映画のようにダイナミックな演出を実現しています。「覚えゲー」ではあるのですが、巧妙に仕組まれた構成によって、気持ちよく遊ばせてもらえます。

初めての時は、敵のあまりの猛攻に絶望しますが、何度か繰り返すうちに攻略の糸口が見つかります。しかし、頭では分かっても、なかなか思ったように動かせません。それでも毎回少しずつ先に進めるようになり、必ず突破する事ができます。この時に達成感を感じ、それが次のステージに向かう原動力になります。全編このサイクルが機能しているので、最後までモチベーションが落ちません。

繰り返しを前提とするゲーム性のため、それをフォローするシステムもしっかりしています。
 ・リトライに時間がかからない。
 ・オートセーブのポイントが多い。
 ・コンテニュー無制限
地味な要素のようですが、これらおかげで無駄な繰り返しが無く、確実に積み上げていく事ができます。


かなり難易度が高いですが、乗り越える喜びを味わうと、病みつきになってしまいます。
進撃の巨人(1)(2)

進撃の巨人(1)(2)

August 23, 2010

進撃の巨人 諫山 創 (著)

人を喰らう巨人から逃れ、巨大な壁で囲われたわずかな領土の中で、100年の間じっと耐えてきた人類。
しかし、その壁を凌駕する大巨人が現れ、仮初めの平和は破られた。
巨人に母を食われた少年は復讐のため、そして、未知の世界に知るため、兵士として訓練を積み絶望的な戦いに身を投じる。

続きが気になって、一気に読んでしまいました。とても勢いのある作品です。
正直、作画は拙いですが、それでも物語に引き込まれるのは、書きたい事がはっきりしていて、しっかりと展開が組み立てられているからかもしれません。必然性のある見せ場が、きちんと用意されています。

ところで、1巻で戦術について話し合うシーンを読んで、自分なりに対巨人戦術を考えてみました。
作中では立体機動による近接戦で、刀によって弱点を切り落とす事が最も有効な攻撃、とされていますが、他の方法も検討されるべきだと思います。たとえば、大砲は頭を吹き飛ばせるものの、弱点である後頭部を狙えないため、足止め程度にしか使われていません。しかし、巨人は大人数の方へ向かう習性があるので、機動力を優先した囮部隊を使い壁に背を向けさせ、弱点を狙うという事ができるかもしれません。また、50mの壁の内側に堀を準備しておけば、大巨人に壁を壊されても易々と進入を許さなかったでしょう。

スーパーヒーローが活躍するのでなく、非力な人類が、限られた資源・人口を使ってどのように戦術を組み立て、圧倒的な力を持つ巨人に対抗するか、という展開を期待してしまいます。



コミック: 192ページ
出版社: 講談社 (2010/3/17)
発売日: 2010/3/17
横井軍平ゲーム館 RETURNS

横井軍平ゲーム館 RETURNS



横井軍平ゲーム館 RETURNS ─ゲームボーイを生んだ発想力

任天堂を日本一のエンターテインメント企業に躍進させた開発者・横井軍平の仕事を紹介する本。

横井さんの関わった商品が時系列で紹介され、それにまつわるエピソードが横井さん自身の言葉として語られます。

商品開発する中で一貫しているのは、価格と機能のバランスをとても重要視しているという事。何が必要かは誰でも分かるけれど、何が必要でないかを説明できる人が少ない、という言葉が頭に残りました。物作りをしていると、言いたい事が多すぎたり、見た目を豪華にしようと考えてつい盛り込みすぎてしまいます。けど、それを抑えて本当に重要な部分に注力すると、自然と輪郭のはっきりしたものになるのだと思いました。



単行本: 224ページ
出版社: フィルムアート社 (2010/6/25)
発売日: 2010/6/25

横井軍平展 -ゲームの神様と呼ばれた男-

先週の土曜日、原宿VACANTで開催中の「横井軍平展 -ゲームの神様と呼ばれた男-」のトークショーを見てきました。出演者は、「横井軍平ゲーム館」の著者・牧野武文さん、株式会社クリーチャーズ代表取締役社長・田中宏和さん、メディアアーティストの岩井俊雄さん、真鍋大度さん。

興味深かったのは、岩井さん・真鍋さんが、共に「光線電話LT」という製品を紹介していた事。これは音声を光の信号に変えて相手に送り、受け手は逆に光を音に変換して通話できるという物です。岩井さんのサウンドレンズという作品と似た仕組みですが、これを1971年に製品として世に出していたという事が大変な驚きです。ただ開発目的は、並走する車同士での会話など、実用目的だったそうで、技術を逆手にとった使い方の面白さを意図したものではなかったようです。


展示は、横井さんが製作に関わった製品が多数あり、ファミコンのブロックなど一部触れる物もありました。ゲームウォッチ以降ですが、僕が子供の頃に遊んだ物もいくつかあり、懐かしかったです。もちろん、それだけでなく最新の製品に繋がる文脈も感じる事ができました。

会期は短いですが、物作りのヒントに満ちた展示会なので、制作に関わる人は是非。



期間:2010年8月18日(水)〜29日(日)
時間:平日13:00〜21:00, 土日12:00〜21:00(最終日の29日のみ18時まで)
定休日:8月23日(月)
美女と竹林

美女と竹林

August 15, 2010


美女と竹林 森見 登美彦 (著)

美女と同等に竹林を愛する著者が、その愛を形にするために、竹の伐採を始める。、、はずが、執筆とそれにまつわる諸々の多忙のため、手入れは遅々として進まない。そんな竹林に対する恋慕と、締め切りに追われる日々を綴ったエッセイ。

「恋文の技術」の評で、森見氏には学生時代に盟友(悪友)がいたのではなかろうか?というような事を書きましたが、この本に登場する明石さんが、そうなんでしょうね。社会人になり、お互い別の道を歩んでいても、再開すればまるで学生に戻ったように話ができる。そういう友人はいいもんです。

竹林の事が漠然と好きだった著者は、竹を分解してみたり、茶筅作りを研究する事で、竹の魅力を探しますが、答えは見つかりません。結局、部分に分けてみても本質はつかめず、好きな物は好き、という結論に至ります。
「恋文の技術」では、これが女性に対する気持ちとして登場します。書かれた時期も近いので、このエッセイも小説の肥しになったのだろうと想像します。

書き手の視点が、森見氏ではない第三者に置かれているのも面白い点です。氏のブログと同じ形式ですね。他人事のような語りが、それだけでユーモアに繋がっていると思いました。




単行本: 296ページ
出版社: 光文社 (2008/8/21)
発売日: 2008/8/21

メディア芸術祭 イスタンブール展

August 12, 2010
8月6日からトルコのイスタンブールで開催されている、「メディア芸術祭 イスタンブール展」にRGBy the Gatheringという新作を出展しています。
作品の内容はMONGOOSEのブログに書きましたので、そちらをご覧になっていただくとして、こちらには完全に観光モードで撮った写真を置いときます。とはいえ、一人きりだったので観光地に行っても写真を撮るより他にすることがないという、微妙にわびしい気持ちになったりもしました。その辺、汲んでいただけると幸いです。



展示会場のペラ美術館。宿泊していたホテルと目と鼻の先。大変便利でした。


スルタンアフメットジャーミー。通称ブルーモスク。僕が行ったときには、ちょうどお祈りの時間で中に入れず、しかも雨が降って外にも出られずという、袋小路でした。


30分ほどして、ようやく中に。外から見えたドームがそのまま天井になっていて、ステンドグラスが大変きれいでした。


たくさんありますので、続きはこちらで。
http://picasaweb.google.com/hirahara.makoto/yYrLLK#
恋文の技術

恋文の技術


恋文の技術 森見 登美彦 (著)
京都の大学から、遠く離れた実験所に飛ばされた男子大学院生が一人。無聊を慰めるべく、文通武者修行と称して京都に住むかつての仲間たちに手紙を書きまくる。手紙のうえで、友人の恋の相談に乗り、妹に説教を垂れ―。


終始、主人公の書いた手紙で物語が展開します。送る相手によって書き分けられる、いろいろな文体を読むのがとても楽しいです。

主人公は、作中の小説家・森見登美彦氏の大学の後輩で、氏の文章を研究したり、愚痴を言い合う間柄です。四畳半神話体系の小津然り、森見作品には主人公と腐れ縁の悪友が登場しますが、これは森見登美彦氏(実在)の大学時代の実際の状況が影響しているのだろうな、と想像しています。

中盤、主人公が恋文の技術のヒントを発見してから、その成果にたどり着くまで、途中のいくつかの章が蛇足に感じました。また、複数人の視点から出来事を多面的に描く、という手法上やむを得ないのかもしれませんが、繰り返しが多く冗長な部分が多かったように感じます。


単行本: 332ページ
出版社: ポプラ社 (2009/3/5)
発売日: 2009/3/5
ofxNetworkを使ってiPhoneとMacでTCP通信 その2

ofxNetworkを使ってiPhoneとMacでTCP通信 その2

May 9, 2010
前回、iPhoneとMacの間でTCP通信を行い、加速度センサーの値を送受信するところまでできたので、今回はその値を使って3Dオブジェクトを動かしてみます。

前回のサンプルでは、以下のように加速度センサーの値の下二ケタを取り出しカンマ区切りで連結していました。

if(weConnected){
msgTx =
ofToString( ofxAccelerometer.getForce().x, 2) + "," +
ofToString( ofxAccelerometer.getForce().y, 2) + "," +
ofToString( ofxAccelerometer.getForce().z, 2);
}


これをサーバー側で受信した後で、それぞれの値ごとに分割して格納します。networkTcpServerExampleのプロジェクトを開き、testApp.cppを開いてみます。

setup()で、TCPをセットアップし、

//setup the server to listen on 11999
TCP.setup(11999);

draw()の中の以下の部分で値を受け取っています。

//we only want to update the text we have recieved there is data
string str = TCP.receive(i);


ここで、strは「0.00,0.00,0.00」のような文字列になっているはずなので、ofSplitStringを使って分割しvectorとして格納します。それをFloatにしてから、角度に変換します。

// カンマ区切りで分割。
vector dataStr = ofSplitString( str, "," );

//Floatに変換して格納。
data.x = ofToFloat( dataStr[0] );
data.y = ofToFloat( dataStr[1] );
data.z = ofToFloat( dataStr[2] );

// 角度に変換
ofPoint rotation = 0.0;
rotation.x = asin(data.y) * ( 180.0/PI );
rotation.y = 0.0;
rotation.z = asin(data.x) * ( 180.0/PI );


さて、これで加速度センサーの値を受け取る事はできました。次に3Dオブジェクトの読み込みます。方法は以下を参考にしてください。
Shadeで作った3Dモデルをofx3DModelLoaderで読み込んでみる

読み込んだモデルに対し、先ほどの角度をセットします。

modelObj.setRotation( 0, rotation.x, 1, 0, 0 );
modelObj.setRotation( 1, rotation.y, 0, 1, 0 );
modelObj.setRotation( 2, rotation.z, 0, 0, 1 );


ざっくりではありますが、以上のような方法でiPhoneの動きをMacの3Dモデルに反映する事ができました。

iPhone Acc Demo from HR2 on Vimeo.



ただ、このままでは、値を取りこぼした時に、モデルが消えたり、ガクガクした動きになってしまうので、スムージングをかけるなど工夫が必要です。別件で作ったサンプルでは、その辺いろいろ工夫してみました。サウンドやiPhoneのタッチも使っています。

iPhone Acc Demo 2 from HR2 on Vimeo.



最後に今回のコードです。
testApp.h

#ifndef _TEST_APP
#define _TEST_APP

#include "ofMain.h"
#include "ofx3DModelLoader.h"
#include "ofxNetwork.h"

class testApp : public ofBaseApp{

public:
void setup();
void update();
void draw();

void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);

ofx3DModelLoader modelObj;
ofxTCPServer TCP;
};
#endif

testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){

// 基本設定 --------------------------
ofBackground(0, 0, 0);
ofSetFrameRate(60);
ofEnableSmoothing();
ofEnableSmoothing();
ofSetFullscreen(true);

// 隠面消去 --------------------------
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

// 照明 -----------------------------
GLfloat lt0_position[] = { 100, 100, -200, 0 };
GLfloat lt0_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat lt0_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lt0_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, lt0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lt0_diffuse);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

// モデルデータロード -----------------------------
modelObj.loadModel("modelSample.3ds", 20 );

// TCP のセットアップ -----------------------------
TCP.setup(11999);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
void testApp::draw(){
ofPoint data = 0.0;
for(int i = 0; i < TCP.getNumClients(); i++){
// クライアントから送られている文字列の受信
string str = TCP.receive(i);

if (str.length() > 0) {
// カンマ区切りで分割。Floatに変換して格納。
vector <string> dataStr = ofSplitString( str, "," );
data.x = ofToFloat( dataStr[0] );
data.y = ofToFloat( dataStr[1] );
data.z = ofToFloat( dataStr[2] );

// 角度に変換
ofPoint rotation = 0.0;
rotation.x = asin(data.y) * ( 180.0/PI );
rotation.y = 0.0;
rotation.z = asin(data.x) * ( 180.0/PI );

// オブジェクトに回転をセット
glPushMatrix();
glTranslatef(ofGetWidth()/2.0, ofGetHeight()/2,0);
modelObj.setRotation( 0, rotation.x, 1, 0, 0 );
modelObj.setRotation( 1, rotation.y, 0, 1, 0 );
modelObj.setRotation( 2, rotation.z, 0, 0, 1 );
modelObj.draw();
glPopMatrix();
}
}
}
鈴木敏夫のジブリマジック

鈴木敏夫のジブリマジック

April 30, 2010


鈴木敏夫のジブリマジック

「鈴木敏夫なくして、宮崎駿なし」―宮崎監督と二人三脚で、大ヒットを生み出し続けるスタジオジブリの名プロデューサー・鈴木敏夫。「アニメージュ」編集長時代から「崖の上のポニョ」まで、知られざる仕事術やビジネス手法を、本人や周囲の証言をもとに解明する貴重な一冊。



梶山 寿子 (著)
文庫: 304ページ
出版社: 日本経済新聞出版社 (2009/6/2)
発売日: 2009/6/2

ofxNetworkを使ってiPhoneとMacでTCP通信

April 29, 2010
ofxNetworkを使って、iPhoneとMacを連動させてみました。

Mac版v0061のaddonsExampleには、networkTcpClientExample、networkTcpServerExampleというサンプルがあり、Mac同士で通信を行っています。同様に、Macをサーバー、iPhoneをクライアントとすれば、データのやり取りがでるはず。

2つのプロジェクトを開いてみると、ofxNetworkとofxThreadというアドオンを利用しています。しかし、iPhone版のv0061には、これらのアドオンは含まれていないので、Mac版からコピーしてみます。

networkTcpClientExampleのコードを見てみます。

testApp.h
ofxTCPClient tcpClient; // これが通信とかいろいろやってくれるみたいです。便利君。
string msgTx, msgRx; // サーバーとやり取りする文字列

float counter; //再接続までのカウンターなどなど
int connectTime;
int deltaTime;

bool weConnected; //接続フラグ


testApp.cpp

■setup
クライアントのアドレスとポートを指定してセットアップします。アドレスは環境に応じて適宜。
weConnected = tcpClient.setup("127.0.0.1", 11999);


■update
接続されていればmsgTxをサーバーに投げ、そうでなければ一定時間後に接続しようとします。
渡したい値を文字列にし、msgTxに入れてあげれば良いようです。

if(weConnected){
tcpClient.send(msgTx);
//if data has been sent lets update our text
string str = tcpClient.receive();
if( str.length() > 0 ){
msgRx = str;
}
}else{
//if we are not connected lets try and reconnect every 5 seconds
deltaTime = ofGetElapsedTimeMillis() - connectTime;

if( deltaTime > 5000 ){
weConnected = tcpClient.setup("127.0.0.1", 11999);
connectTime = ofGetElapsedTimeMillis();
}
}




せっかくiPhoneを使うので、加速度センサーを使ってみます。加速度は以下のように取得できます。
ofxAccelerometer.getForce().x、ofxAccelerometer.getForce().y、ofxAccelerometer.getForce().z

これを文字列に変換し、カンマで区切ってmsgTxに入れます。

if(weConnected){
msgTx =
ofToString( ofxAccelerometer.getForce().x, 2) + "," +
ofToString( ofxAccelerometer.getForce().y, 2) + "," +
ofToString( ofxAccelerometer.getForce().z, 2);
}




それでは、新規のiPhoneプロジェクトを作り上記を加えます。
testApp.h

#ifndef _TEST_APP
#define _TEST_APP
#pragma once
#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxNetwork.h"

class testApp : public ofxiPhoneApp {

public:

〜中略〜

ofxTCPClient tcpClient;
string msgTx, msgRx;

ofTrueTypeFont mono;
ofTrueTypeFont monosm;

float counter;
int connectTime;
int deltaTime;

bool weConnected;

int size;
int pos;
bool typed;
};

#endif


testApp.cpp


#include "testApp.h"

#define RECONNECT_TIME 400

//--------------------------------------------------------------
void testApp::setup(){
// register touch events
ofRegisterTouchEvents(this);

// initialize the accelerometer
ofxAccelerometer.setup();

//iPhoneAlerts will be sent to this.
ofxiPhoneAlerts.addListener(this);

// we don't want to be running to fast
ofSetVerticalSync(true);

//load our type
mono.loadFont("type/mono.ttf",9);
monosm.loadFont("type/mono.ttf",8);

//some variables

//have we typed
typed = false;

//our typing position
pos = 0;

//our send and recieve strings
msgTx = "";
msgRx = "";

//are we connected to the server - if this fails we
//will check every few seconds to see if the server exists
weConnected = tcpClient.setup("192.168.1.27", 11999);

connectTime = 0;
deltaTime = 0;

tcpClient.setVerbose(true);
}

//--------------------------------------------------------------
void testApp::update() {
ofBackground(230, 230, 230);

//we are connected - lets send our text and check what we get back
if(weConnected){
tcpClient.send(msgTx);

//if data has been sent lets update our text
string str = tcpClient.receive();
if( str.length() > 0 ){
msgRx = str;
}
}else{
//if we are not connected lets try and reconnect every 5 seconds
deltaTime = ofGetElapsedTimeMillis() - connectTime;

if( deltaTime > 5000 ){
weConnected = tcpClient.setup("192.168.1.27", 11999);
connectTime = ofGetElapsedTimeMillis();
}
}

if(weConnected){
msgTx =
ofToString( ofxAccelerometer.getForce().x, 2) + "," +
ofToString( ofxAccelerometer.getForce().y, 2) + "," +
ofToString( ofxAccelerometer.getForce().z, 2);

typed = true;
}
}

//--------------------------------------------------------------
void testApp::draw() {
ofSetColor(20, 20, 20);
mono.drawString("openFrameworks TCP Send Example", 15, 30);

if(typed){
monosm.drawString("sending:", 15, 55);
monosm.drawString(msgTx, 85, 55);
}
else{
//if(weConnected)monosm.drawString("status: type something to send data to port 11999", 15, 55);
//else monosm.drawString("status: server not found. launch server app and check ports!\n\nreconnecting in "+ofToString( (5000 - deltaTime) / 1000 )+" seconds", 15, 55);
}
monosm.drawString("from server: \n"+msgRx, 15, 270);
}
〜後略〜




Mac側でnetworkTcpServerExampleを起動しておき、上記のアプリをiPhoneで実行すると、接続がうまくいけば加速度センサーの値が表示されます。今は垂直に立てている状態です。


さて次回は、受け取った値を使って、3Dオブジェクトを動かしてみます。
自省録

自省録

April 25, 2010

自省録

著者はローマ皇帝で哲人.蕃族の侵入や叛乱の平定のために東奔西走したが,僅かにえた孤独の時間に自らを省み,日々の行動を点検し,ストアの教えによって新なる力をえた.本書は静かな瞑想のもとに記されたものではあるが,著者の激しい人間性への追求がみられる.古来,もっとも多く読まれ,数知れぬ人々を鞭うち励ました書.



他人に読ませる事が目的ではなく、自分を戒める為に書かれた物なので、考えを押し付けるようなものではなく、著者自身への厳しさとして読む事ができました。著者がここに書かれている事を実践していたは分かりませんが、こうありたい、という思いを突き詰めた事で、多くの人に理想を示しているのだと思います。実は、アウレーリウス自身は、すぐに怒ったり怠けたりする人で、毎日、猛烈に後悔しながらこれを書いたのだったら面白いなと思いました。

繰り返し登場する考えをいくつか。
・全ての物事は変化する。名声を得たとしても、自分も、それを伝える人々もすぐに死んでしまうのだから、そんなことに拘るな。
・世界は完全無欠の神々が作ったので、自然に適った事しか起きない。だから、自分の身に起きる事は、なんであれ自然に適っている。
・最もよい復讐の方法は、相手に同じ事をしない事だ。



マルクスアウレーリウス (著), 神谷 美恵子 (翻訳)
文庫: 327ページ
出版社: 岩波書店; 改版版 (2007/02)
発売日: 2007/02

Shadeで作った3Dモデルをofx3DModelLoaderで読み込んでみる

March 21, 2010
タイトルの通りですが、Shadeで作った3Dモデルをofx3DModelLoaderで読み込んでみます。

addonsExamplesの3DModelLoaderExampleを見ると、3dsのリスのモデルデータを読み込んでいます。
(どーでもいいですが、このモデル、JOJO第二部のカーズが腕から作り出したリスみたいでちょっと怖い。)
ソースを見るとofx3DModelLoaderオブジェクトを作って、loadさせるだけのようです。

//load the squirrel model - the 3ds and the texture file need to be in the same folder
squirrelModel.loadModel("squirrel/NewSquirrel.3ds", 20);


■Shade から3dsの書き出し
Shadeでモデルを作ります。oF側のデフォルトで表示させた場合、Shade内の10mmくらいのサイズで、ちょうどいい大きさになります。大きすぎるとカメラがモデルの中に入ってしまい、表示されなくなります。





次に、3ds形式に書き出します。[エクスポート][3D Studio]を選択。グループ名は[インデックス]。他のを選ぶとoFに読み込まれませんでした。


保存先は、プロジェクトのbin/dataの中です。テクスチャを貼ってある場合は自動的に同階層に保存されます。

■openFrameworks

testApp.h

#ifndef _TEST_APP
#define _TEST_APP

#include "ofMain.h"
#include "ofx3DModelLoader.h"

class testApp : public ofBaseApp{

public:
void setup();
void update();
void draw();

void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);

ofx3DModelLoader modelObj;
};

#endif



testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){

// 基本設定 --------------------------
ofBackground(0, 0, 0);
ofSetFrameRate(60);
ofEnableSmoothing();

// 隠面消去 --------------------------
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

// 照明 -----------------------------
GLfloat lt0_position[] = { 100, 100, 200}; //ライトの位置
GLfloat lt0_ambient[] = { 0.5, 0.5, 0.5, 0.5 }; //環境光
GLfloat lt0_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; //スポットライト

glLightfv(GL_LIGHT0, GL_POSITION, lt0_position); //0番ライトに設定
glLightfv(GL_LIGHT0, GL_AMBIENT, lt0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lt0_diffuse);

glEnable(GL_LIGHTING); //ライティング開始
glEnable(GL_LIGHT0); //0番のライトを点灯

// モデルデータロード -----------------------------
modelObj.loadModel("modelSample.3ds", 20 );
}

//--------------------------------------------------------------
void testApp::update(){

}

//--------------------------------------------------------------
void testApp::draw(){
static float count = 0;
count+=0.5; //回転角度を増やす

glPushMatrix(); //現在の表示位置を記憶

glTranslatef(ofGetWidth()/2.0, ofGetHeight()/2,0); //画面中心に移動
glRotatef( count, 0, 1, 0 ); //Y軸に回転
modelObj.draw(); //モデルを描画

glPopMatrix(); //記憶した位置に戻す

}

// 以下略



FlashのPV3Dの感覚では、オブジェクトは個別に位置情報を持っていて、それぞれに移動や回転を行えばOKですが、oF(というかOpenGL)は毎回位置を設定して描画するので、glPushMatrix();とglPopMatrix();が必要になります。最初、この考え方が分からず悩みました。現在は、プリミティブな形状をクラス化して、PV3Dライクに使えるように準備をしています。
創るセンス 工作の思考

創るセンス 工作の思考

March 20, 2010


創るセンス 工作の思考

作ることで得られるセンス、ものづくりから生まれる知とは? かつての日本では、多くの少年が何らかの工作をしていた。しかし、技術の発展で社会が便利になり、手を汚して実際にものを作るという習慣は衰退し、既製品を選んだり、コンピュータの画面上で作業することが主になった。このような変化の過程で失われた、大切なものがある。それは、ものを作ったことのない人には、想像さえつかないものかもしれない。「ものを作る体験」でしか学べない創造の領域、視覚的な思考、培われるセンスとは何か。長年、工作を続けている人気作家が、自らの経験を踏まえつつ論じていく。



筆者自身が述べている通り、全体的に「最近の若者は・・。自分が若かった頃は・・。」という雰囲気で書かれています。それが少し鼻につくところありましたが、実践して思考せよという主張にはおおいに共感しました。
外から見えない部分であっても、手を抜かず作り込むのは「工作の神様が見ているから」。神様=本人。職人気質とも言えますが、自分が納得するまでやるという態度には、共感しつつも、自分はそこまで突き詰めて物を作っているだろうかと、振り返ってしまいました。
また、仕事は他者の評価、趣味は本人の評価。どっちにしますか?というくだりも、自分の場合はどうか、と考えさせられました。




森 博嗣 (著)
新書: 204ページ
出版社: 集英社 (2010/2/17)
発売日: 2010/2/17
Beyond Interaction ―メディアアートのためのopenFrameworksプログラミング入門

Beyond Interaction ―メディアアートのためのopenFrameworksプログラミング入門

March 5, 2010


Beyond Interaction ―メディアアートのためのopenFrameworksプログラミング入門

本書は、インタラクションデザインやメディアアートの現場で現在最も注目されている制作環境、「openFrameworks」の世界初の解説書です。openFrameworksというC++のフレームワークを使用して、プログラミングの初歩から高度な応用まで、具体的なサンプルを作成しながら実践的に学んでいくことを目的にしています。プログラミングの経験のない初心者から、メディアアートに興味を持ち自分で何かを作りたいと考えている方、ProcessingやFlashなど他の環境は経験しているがより強力なプログラミング環境を探し求めている方まで、多くの方々にとって有益な情報を提供しています。


開発環境の導入から基本的な構文、便利なクラスの紹介と、openFrameworksを始めるために必要な情報が網羅されています。エディトリアルも綺麗で読みやすいです。ただ、sbaw09と違い、iPhoneアプリの作成については触れていません。

田所 淳 (著), 比嘉 了 (著), 久保田 晃弘 (著)
単行本: 304ページ
出版社: ビー・エヌ・エヌ新社 (2010/2/21)
発売日: 2010/2/21
立体隠し絵 アッタコレダ的なものをFlashで作ってみる

立体隠し絵 アッタコレダ的なものをFlashで作ってみる

March 3, 2010
本日発売のDSi Ware「立体隠し絵 アッタコレダ」がとても面白いので、似たような仕組みをFlashで作ってみました。


アッタコレダはDSi専用のソフトで、ディスプレイの奥の世界を覗き込み、隠された文字や絵を探すというゲームです。面白いのは、ユーザーの視点に合わせて描画し、まるでDSの奥の小さな箱を覗き込むように操作できる点です。こちらの動画が分かりやすいです。


で、Flashでも顔認識のライブラリーを使って似たような事をできるんじゃないかと思い、作ってみました。









[全画面版]


・顔の位置はカメラで取得するので、「許可」を選んでください。
・赤い表示された後、全く動かない場合は、右クリックから 設定のカメラアイコンを選び、プルダウンから使用するWebカメラを変更してみてください。僕の環境(MacBookPro)の場合は、「USB Video Class Video」で動作しました。
・ディスプレイの上部にWebカメラを置き、50cmくらい離れると認識されやすいです。





アッタコレダ的なものをFlashで作ってみる from HR2 on Vimeo.




環境にもよりますが、動作がかなりもっさりしています。顔認識の精度と速度はトレードなので、実際に使うには何らかの工夫が必要ですね。
アッタコレダは、顔認識ではなく色面の移動量だけを認識しているようです。多分。あと、アニメーションを滑らかにしているので、滑らかに見えます。

今回使わせていただいた顔認識のライブラリーはこちら。Marilena

openFrameworksとArduinoで音量メーター

February 20, 2010
 前回、ようやくArduinoを繋ぐ事ができたので、LEDを光らせて何か作ってみようと思います。せっかくopenFrameworksからコントロールしているのでPC側の機能を使った物ということで、マイクで拾った音量をLEDで表示してみます。

■サンプルの内容
 まず、firmataExampleを見てLEDのon/offの方法を調べます。

□ testApp.h
 ofArduino というのがArduinoを管理してくれるクラスですね。

□testApp.cpp - setup
 ard.connectで接続開始しています。前回ハマったのはこのドライバ名(?)でした。

□testApp.cpp - update
 接続チェックかな。

□testApp.cpp - setupArduino
 ピンのモード設定。ARD_OUTPUT=デジタル出力用、ARD_ANALOG=アナログ入力用、ARD_PWM=PWM出力用。PWMというのは、デジタル出力を細かくOn/Offする事で階調を表現する事。たとえば、LEDを1秒間に0.1秒点灯、0.1秒消灯を5回繰り返せば、常につけている場合と比べて、半分の明るさになる。

□testApp.cpp - updateArduino
 Arduinoオブジェクトをアップデートしています。ard.sendPwm()で、Pin11に50%〜100%の明るさになるようにPWMを送っています。

□testApp.cpp - draw
 ard.getAnalog(0)で、pin0(半固定抵抗)のアナログ入力の値を取得しています。


 という事で、以下の命令でコントロールする事ができます。簡単!便利!
     : 送る : 受け取る
 デジタル:sendDigital:getDigital
 アナログ:sendPwm:getAnalog
(sendPwmはアナログを出力するわけではありません)




■音量を扱ったサンプル
 LEDのコントロールが分かったところで、今度は音量を取得する方法を探します。examplesにaudioInputExampleというのがあるので、開いてみます。PCのマイクの音を周波数別に表示しているみたいです。

□ testApp.h
 float * left、float * right、左右の音量が格納されます。周波数ごとの配列として使われます。

□testApp.cpp - setup
 ofSoundStreamSetup(0,2,this, 44100, 256, 4);
 left = new float[256];
 right = new float[256];
 音の入出力のセットアップですね。周波数を256段階に分けて取り込みます。

□testApp.cpp - draw
 left[]とright[]に入っている値を使って、波形を描画しています。

□testApp.cpp - audioReceived
 引数として渡されるinputに左右の値が交互に入っているみたいですね。それを分けて、left,rightに入れています。


 音量を直接取り出す命令が分からなかったのですが、left,rightに入っている全ての値を合算すれば、全体の音量になるはず。多分。



■組み合わせる
 以上でそれぞれ必要な準備と使い方が分かったので、新しいプロジェクトを作って、各要素をコピーしてきます。

testApp.h

#ifndef _TEST_APP
#define _TEST_APP


#include "ofMain.h"

class testApp : public ofBaseApp{

public:
void setup();
void update();
void draw();

void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);

void setupArduino();
void updateArduino();

// Arduino
ofArduino ard;
bool bSetupArduino; // flag variable for setting up arduino once

// Sound
void audioReceived (float * input, int bufferSize, int nChannels);
float * left;
float * right;
};

#endif


testApp.cpp

#include "testApp.h"

//--------------------------------------------------------------
void testApp::setup(){
ofSetVerticalSync(true);
ofSetFrameRate(60);
ofBackground(255,255,255);

// Arduino setup
ard.connect("/dev/tty.usbserial-A7005OBP", 57600);
bSetupArduino = false;

// Sound setup
ofSoundStreamSetup(0,2,this, 44100, 256, 4);
left = new float[256];
right = new float[256];
}

//--------------------------------------------------------------
void testApp::setupArduino(){
// 全てのPinをデジタル出力モードに設定
for (int i = 0; i < 13; i++){
ard.sendDigitalPinMode(i, ARD_OUTPUT);
}
}

//--------------------------------------------------------------
void testApp::update(){

if ( ard.isArduinoReady()){

// 1st: setup the arduino if haven't already:
if (bSetupArduino == false){
setupArduino();
bSetupArduino = true; // only do this once
}
// 2nd do the update of the arduino
updateArduino();
}
}

//--------------------------------------------------------------
void testApp::updateArduino(){
ard.update();
}

//--------------------------------------------------------------
void testApp::draw(){
// draw the left:
ofSetColor(0x333333);
ofRect(0, 0, ofGetWidth(), ofGetHeight() );
ofSetColor(0xFFFFFF);

for (int i = 0; i < 256; i++){
ofSetLineWidth(4);
ofLine(i*4, ofGetHeight()/2, i*4, ofGetHeight()/2+left[i]*100.0f);
}

if (!ard.isArduinoReady()){
cout << "arduino not read" << endl;
} else {
float volume = 0;
for (int i = 0; i < 256; i++){
volume += left[i];
}

volume *= 100;

for (int j = 1; j<6; j++) {
if (volume > j * 30) {
ard.sendDigital(j+1, 1);
}else {
ard.sendDigital(j+1, 0);
}
}
}
}

//--------------------------------------------------------------
void testApp::audioReceived (float * input, int bufferSize, int nChannels){
for (int i = 0; i < bufferSize; i++){
left[i] = input[i*2];
right[i] = input[i*2+1];
}
}


■Arduino側の配線
 テストでLEDを1つ点けましたが、ほぼ一緒です。2〜6Pinの5個になっただけです。0と1Pinは書き込みのために使われているので空けています。(ん?今回は書き込みしないから使ってもいいのかな・・?)




■動画
太陽の塔

太陽の塔



太陽の塔

私の大学生活には華がない。特に女性とは絶望的に縁がない。三回生の時、水尾さんという恋人ができた。毎日が愉快だった。しかし水尾さんはあろうことか、この私を振ったのであった!クリスマスの嵐が吹き荒れる京の都、巨大な妄想力の他に何も持たぬ男が無闇に疾走する。失恋を経験したすべての男たちとこれから失恋する予定の人に捧ぐ、日本ファンタジーノベル大賞受賞作。


 小説的なストーリー展開はあまり無くて、ひたすら主人公の妄念が語られています。筋が少ない分、筆者の体験の欠片という印象を持ちました。デビュー作だし。「夜は短し」>「四畳半」>「太陽の塔」と遡る順番で読んできたので、作品として再構成する前の生の体験に戻っていくように感じられたのかもしれません。だから、大好きな作家の源流を知るという意味で楽しめました。


森見 登美彦 (著)
文庫: 237ページ
出版社: 新潮社 (2006/05)
発売日: 2006/05
京都魔界案内―出かけよう、「発見の旅」へ

京都魔界案内―出かけよう、「発見の旅」へ



京都魔界案内―出かけよう、「発見の旅」へ

日本を代表する「雅」の都・京都は、陰陽師や呪術僧が活躍する、呪いや怨念の渦巻く霊的空間でもあった。晴明神社、神泉苑、貴船神社…、名うての「魔界」を巡り歩くうちに、「異なる者」たちが跳梁跋扈する刺激に充ちた時空が蘇ってくる―そんな「魔界」発見の旅へようこそ!読んでから行くか、行ってから読むか。


小松 和彦 (著)
文庫: 264ページ
出版社: 光文社 (2002/02)
発売日: 2002/02

Arduinoを繋いでみる

February 18, 2010
今回は、openFrameworksでArduinoをコントロールしてみます。

Arduinoとは、単純な入出力を備えた基板と Processing/Wiring 言語を実装した開発環境から構成されるシステム、だそうです。要するに、PCとの通信・書き込みもセットになったI/Oボードという事かな。詳しくはWikiで。


■Arduinoの準備

□ハードの準備
 Arduinoはオープンハードウェアなので、仕様をみて作ろうと思えば作れますが(僕には無理ですが)、最近はAmazonでも購入できます。たくさんの種類がありますが、最初は基本的なものを用意するのがいいと思います。その辺の事情はこちらで書かれています。スタパ齋藤の「週刊スタパトロニクスmobile」

 僕が買ったのはこれ。電源をUSB、ACアダプタで供給でき、シールド(拡張ボード)と組み合わせる事もできます。
Arduino Duemilanove 328

 電子工作をやった事が無く、ブレッドボードを持っていなければ、Arduinoをはじめようキットも一緒に買うといいかもしれません。





□ソフトの準備
 Arduino IDE(開発環境)はこちらから自分の環境にあったものをダウンロードしてください。Download the Arduino Software
 解凍したフォルダの中の「FTDIUSBSerialDriver」を実行して、USB-Serialドライバーをインストールします。

□サンプルの実行
 まずは最もシンプルなLEDが点滅するサンプルを動かしてみます。

 下の写真のように13番のOutput PinにLEDを繋ぎ、USBでパソコンに接続します。

 
 次にAruduino IDE を起動し、File > Examples > Digital > Blink を選択すると、以下のようなウィンドウが開きます。

「Upload」のアイコンをクリックすると、Arduinoへプログラムを書き込みを始め、正常に終了するとLEDが1秒ごとに点滅します。IDEに戻り、loop()の中のdelay(1000)をdelay(500)に変えて再度Uploadすると、0.5秒毎の点滅に変わると思います。

 

■サンプルを開く
 Arduinoへの書き込み確認ができたので、いよいよopenFrameworksからコントロールしてみます。そのためには「Firmata」という物を使います。Firmataとは、マイクロコントローラとホストコンピュータ上で通信するための一般的なプロトコル、だそうです。PCからの命令に受け答えるソフトをArduinoに入れ、openFrameworksからはそのソフトが分かるように命令を渡してあげる、という事のようです。なので、Firmataに従っていれば、Processingからコントロールする事もできます。

 まず、Arduinoにfirmataを入れます(こういう言い方でいいのかな?)File > Examples > Firmata > StandardFirmataを開き、Uploadします。

 次にoFのapps/firmataExample/firmataExample.xcodeproj を開きます。まずはそのままビルドしてみてください。下記のようにアプリは起動しますが、Arduinoが接続されていないと表示されます。

 写真に従ってLED, 半固定抵抗を繋ぎます。半固定抵抗は「始めようキット」に入っていないので、別に用意する必要があります。Amazonでは半固定可変抵抗器セットがありますが高いので、千石電商などの電子パーツ屋さんで買うのがよいと思います。

 この状態でビルドしてエラーが出なければ成功です。右上に半固定抵抗の値が表示されます。ちなみに僕はここで躓きました。ビルドでエラーはでませんが、Arduinoが認識されません。試しにProcessingのFirmataサンプル(SketchBook > librarys > arduino > examples > arduino_output)を試したところ、ちゃんと動きました。
 かなり悩んだ結果、ようやく分かったのは、Processingのメッセージでusb serialを探している(?)表示がありますが、この名前とopenFrameworksのfirmataExampleのtestApp.cppで呼び出している名前が違っていました。Processingで表示されている名前に書き換えたところ、ちゃんと動くようになりました。

Processingのarduino_output、実行時のメッセージ
 [0] "/dev/tty.usbserial-A7005OBP"

openFrameworks > firmatExample > testApp.cpp
 ard.connect("/dev/ttyUSB0", 57600);
 ↓
 ard.connect("/dev/tty.usbserial-A7005OBP", 57600);




こんな感じで、ようやくopenFrameworksでArduinoをコントロールできるようになったので、次回はLEDで音量を表示するメーターを作ってみます。