2 June 2008
ページ ツール |
その他必要な道具や工具がありますので、各章をご確認ください。
当記事で紹介するGainerアプリケーションの完成図
この記事の発端は、2007年11月に開催されたAdobe Max Japan 2007でIAMAS(岐阜県立国際情報科学芸術アカデミー) 准教授 小林茂氏と、一緒にスピーカーとして出演させていただいた「フィジカルコンピューティングへの招待 Gainer/Funnelで広がるFlash/ActionScriptの新しい可能性」というセッションでした。 同セッションでは、同時期に出版された、「+GAINER—PHYSICAL COMPUTING WITH GAINER」で用意したサンプルを使い、Flashの新たな表現の可能性を紹介しました。 今回その縁もあり、新たな作成したサンプルを紹介することで、フィジカルコンピューティングをもっと知っていただけたらと思います。
この記事では、Adobe Flash CS3を利用して、直感的な操作を体感できるフィジカルコンピューティングの世界に触れていただこうと思います。
フィ ジカルコンピューティングとは、もともとアメリカ、ニューヨーク大学のITP(Interactive Telecommunications Program でDan O'SullivanとTom Igoeが教えていたコースの名称です。このコースでは、身体(フィジカル)を使った人とコンピューターのコミュニケーションの方法を考えていました。 普段、「マウス」と「キーボード」でパソコンを操作してきた私たちにとって、「身体のちょっとした動き」でパソコンを操作するというのはとても新鮮なことでした。 フィジカルコンピューティングは実際に、アーティストの表現手法として、メディア・インスタレーションで多く利用されています。最近では、某リモコンなどゲームのハードウェアもそれに対応し世を騒がせまし た。
フィジカルコンピューティングに欠かせないものが3つあります。それは、センサー、アクチュエーターそしてプロセッサです。
センサーとは、人の動きや、温度・湿度など周りの状況に反応するものです。例えば、センサーからあるものまでの距離だったり、温度や光、圧力などを計る、様々なセンサーがあります。
LEDやモーターを指すもので、電気信号を物理現象に変換するものです。これにより、Flashでボタンをつくり、クリックするとLEDが光るサンプルなどが作れます。
センサーとアクチュエーター間に入り、情報交換を行う部分を指します。今回の場合は、Gainer(I/Oモジュール)とパソコンがそれにあたります。
Gainer (ゲイナー)はユーザー・インタフェースやメディア・インスタレーションを作るための環境で、オープンソースで開発が進められています。2005年9月に IAMAS(岐阜県立国際情報科学芸術アカデミー) 准教授 小林 茂氏がはじめとなり、プログラマブル・デバイス・プロジェクト(PDP)の有志からなる開発チームによって開発が始められ、2006年6月に最初の公式リ リース(v1.0.0)を公開し、I/Oモジュール・キットの頒布を開始しました。 Gainerを利用することにより、センサーやアクチュエータをPCに接続し、Flash、Max/MSP、Processingといった幅広いプログラ ミング環境から利用できるようになります。
最初のサンプルでは、上のビデオのような曲げセンサーを使ったものを作成します。
曲げセンサーは、文字通り、曲がり具合を測定するセンサーです。
センサーの曲がり具合をGainerで取得し、Flashの画面に表示してみましょう。
*ここから先のサンプルは、Gainerのセットアップが完了していることが必須条件です。Gainerのセットアップ方法は、Gainer公式サイトにて丁寧に解説されているので、そちらを参考にしてください。

曲げセンサーをGainerに繋ぐには、以下のような回路図の電子回路を作成します。
上記の物をもうすこしわかりやすく描くと、このようになります。
GND、+5Vのように、電子工作をあまりしない人にはよくわからない記号がありますが、GNDはGND同士、+5Vは+5V同士を結んでください。
では早速、この回路図を元にブレッドボード上で回路を組んでみましょう。
回路図の意味がわからなくても、まずはこの図のとおりに回路を作成してみてください。
まず、GAINERのGNDと曲げセンサーを繋ぎます。曲げセンサーには2本の端子がありますが、+極や-極はありませんのでどちらに繋いでも構いません。
その後、10kΩの抵抗を経由して、GAINERの+5Vに結線します。また、曲げセンサーと10kΩの抵抗を繋いでる箇所からジャンプワイヤを引き出し、GAINERのain アナログ入力 の0番に結線します。
この写真のように各部品が接続できればOKです。
曲げセンサーの値取得用の「test.fla」を作成します。(今回はGainerのAS3用のライブラリを使用しますので、AS3.0用のflaファイルにしてください。)
test.flaのステージにダイナミックテキスト「ain0_text」を配置します。
このダイナミックテキストに、曲げセンサーからの値を表示してみたいと思います。
ファイル構成:
┌test.fla
├Test.as
└lib/
└gainer/
test.flaのドキュメントクラスを「Test.as」として設定します。
また、gainerパッケージを利用するので、クラスパスの設定を忘れないようにしてください。
Testクラスのソースは以下の通りです。
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import gainer.*;//gainerパッケージをインポートしておくこと
public class Test extends Sprite{
private var _gnr:Gainer;//Gainerインスタンス
private var _ain0_text:TextField;//ステージ上のain0の値を表示するダイナミックテキスト
public function Test() {
_ain0_text = this["ain0_text"];
//初期化
_init();
}
//------------------------
// 初期化
//------------------------
private function _init():void {
//Gainer準備
//MODE1で設定
_gnr = new Gainer("localhost", 2000, Gainer.MODE1, false);
//Gainerの準備が完了したら_runを実行
_gnr.onReady = function() {
_run();
}
}
//------------------------
// 開始
//------------------------
private function _run():void {
//アナログ入力の取得を開始
_gnr.beginAnalogInput();
//EnterFrameでGainerからのアナログ入力を監視
addEventListener(Event.ENTER_FRAME, _update);
}
//-----------------------------------
// EnterFrame更新
//-----------------------------------
private function _update(e:Event):void {
//Gainerのain0の値をダイナミックテキストに表示
_ain0_text.text = _gnr.analogInput[0];
}
}
}
スクリプトが記述できたらGainerのserial proxy サーバーを起動します。
以下のようにserial proxyサーバーとGainerとの接続が確立されたのを確認してから、Flashをパブリッシュして動作確認を行います。
いかがでしょう?
曲げセンサーを曲げるとダイナミックテキスト内の数値が変化したと思います。
筆者の場合はまっすぐの場合から約90度に曲げたときに、値が約128-178に変化しました。 この変化はセンサーによって若干個体差があるので、作品作りの際にはそれぞれのデータを調査しておく必要があります。
バーチャルグローブとは、手袋の指の部分などにセンサーを取り付けることにより関節の動きを検知し、コンピュータ内で手の動きを再現することができるものです。
最先端のものは手の位置や疑似的な触覚まで再現されているようですが、今回は曲げセンサーだけを使って、指の動きを取得できるものを作ってみたいと思います。
スキー用グローブの指の部分に曲げセンサーを埋め込み、その曲がり具合をGainerで検知します。
FlashでGainerからのデータを受け取り、それを「手」のアニメーションとして表示させたいと思います。
バーチャルグローブ用の回路図は以下の様になります。
一見難しそうに見えますが、先ほどのサンプルで作成した回路を5つに増やしただけです。
GAINERのアナログ入力のチャンネルはデフォルトでは4つです。
チャンネル数が足りないと思われるかもしれませんが、実はこれはプログラムである程度変更することができます。
今回はアナログ入力チャンネルが8chまで扱えるGainer.MODE2を使用する前提で話を進めます。
工具など(*は必須のもの)
ユニバーサル基盤上に、Gainerや10kΩの抵抗、曲げセンサーをどのように配置すれば効率が良いか考えます。
メンテナンスのことも考え、今回は以下のように配置していきたいと思います。
ピンソケットはGainerの端子分だけニッパーで切り取って配置します。
2Pコネクタの先には曲げセンサーがあるものと仮定します。
赤字がGainerの各端子の場所、青字が部品同士の配線予定図になります。
各部品の配置ができたら基盤をひっくり返し、裏から配線図通りに半田付けを行います。
曲げセンサーにリード線を取り付け、基盤に接続したいと思います。
この曲げセンサーですが、センサーのプリント部分と端子部分の接着がデリケートで、端子部分を半田で熱しすぎると接触不良になる可能性があります。その対策として、今回用意したピンソケットと曲げセンサーが接続できるので、曲げセンサーに直接リード線を半田付けするのではなく、ピンソケットにリード線を半田付けし、基盤と接続できるようにしたいと思います。
まずはピンソケットを2端子分、ニッパーで切断します。
ピンソケットとリード線を半田付けします。
半田付けできたら熱収縮チューブで保護しておきます。
この先に曲げセンサーをカチリとはめ込み、接続したいと思います。
リード線の反対側に2Pコネクタを取り付けます。
このコネクタとユニバーサル基盤上のコネクタを接続します。
以上の部品を指の数だけ作成します。
5組作らないといけないので大変ですが、頑張って下さい。
すべてのパーツを接続:
基盤、コネクタ、曲げセンサを接続します。
キングギドラみたいになってカッコよかったので、思わずもう一枚写真を撮ってしまいました。
グローブ部分を作成していきます。
スキー用のグローブが扱いやすいと思いますが、なければゴム手袋でもなんでも構いません。
実際、今回のサンプルは最初のほうはゴム手袋を使用していました。とはいえ完成したものの見栄えがあまり良くなかったので、急きょ、 押入れの隅っこで眠っていたスキーグローブを使うこととなりました。
5年くらい前に買った思い出の品。
まさかこのような作品に使われるとは思いませんでした。
100均にて購入。裁縫は15年ぶりくらいでしたが意外と面白いです。
手の甲あたりに、電子回路を取り付けたいと思います。
基盤を直接手袋に縫い付けてもよいのですが、基盤が壊れてしまった時のメンテナンスを考え、マジックテープで張り付けるようにしたいと思います。
実際に手袋を履いて、手をいろんな方向に動かしてみます。
なるべく動きが少なく邪魔にならない場所にマジックテープを縫いつけます。
各指の部分、曲げセンサーを入れるポケットの作成:
指の部分に布を縫い付け、曲げセンサーを入れるポケットを作成します。
布ができるだけピンと張った状態で縫いつけます。
緩みがひどすぎると曲げセンサーがうまく曲がりません。
また、ポケットの上部は開けておくか、閉じたとしても十分に余裕を持たておいてください。
拳を握ったときに曲げセンサーが指先のほうにスライドするためです。
曲げセンサーの位置を固定できるよう、指の根元にマジックテープを縫いつけておきます。
先ほど作成した電子回路本体の基盤の裏に直接マジックテープを張り付けると、メンテナンスができなくなってしまいます。 そこで、余っているユニバーサル基盤を利用してメンテナンス性の高いものを作成することにしました。
まずは余っている基盤に接着剤でマジックテープを貼り付けます。
そして、スペーサーを使って電子回路の本体とマジックテープを貼ったユニバーサル基盤を取り付けます。
メンテナンスしたくなったら、スペーサーのねじを緩めて上の基盤だけを取り外すことができます。
最後にGainerを取り付けて完成です。
グローブに電子回路を取り付けます。マジックテープがあるので簡単に貼付けできると思います。
各指のポケットに曲げセンサーを収納します。
実際に手袋を履いてみて、手を握ったり開いたりしてみて下さい。
動きにくいところや接続に不安があるところがあれば、修正してください。
グローブアニメーション用の「glove.fla」を作成します。ファイルはAS3.0形式にしておいてください。
手全体のムービークリップ「hand_mc」内に手を描いていきます。
手の甲や各指はできるだけ別レイヤーで描いておくと、後々のアニメーションが楽になります。
指は関節ごとにシンボル化しておきます。
各パーツが完成したら、指ごとにムービークリップ化していきます。
親指から順に「finger0_mc」「finger1_mc」「finger2_mc」「finger3_mc」「finger4_mc」としました。
各指のムービークリップ内で、指を開いてから握るまでの動作を100フレームのアニメーションで作成します。
最初に作った曲げセンサーテスト用のTest.flaを少し改造して各センサーから入力されるデータの調査を行います。
まず、GainerのMODEを1→2に変更します。これにより、4チャンネルのアナログ入力を8チャンネルまでに拡大できます。
//------------------------
// 初期化
//------------------------
private function _init():void {
//Gainer準備
//MODE2で設定
_gnr = new Gainer("localhost", 2000, Gainer.MODE2, false);
//Gainerの準備が完了したら_runを実行
_gnr.onReady = function() {
_run();
}
}
次に各指に対しての入力情報を調べていきます。
下記スクリプトの赤い部分を変更することにより、アナログ入力0チャンネルから4チャンネルの値を取得できるようになります。グローブに手を入れ、実際に手を開いたり閉じたりしながら、各センサーがどのような値になっているかを確認します。
//-----------------------------------
// EnterFrame更新
//-----------------------------------
private function _update(e:Event):void {
//Gainerのain0の値をダイナミックテキストに表示
//analogInputの配列の要素(赤字部分)を0~5に変更すると、Ginerのain0~4の値を取得できる
_ain0_text.text = _gnr.analogInput[0];
}
テストの結果、私の環境では以下のような数値が取れました。
各指とも大体同じ結果だったのですが、中指のセンサーの精度があまり良くないようです。
また、親指はほかの指に比べてモーションが小さく、手を握ってもそれほど大きな値の変化を示しませんでした。
| 開いているとき | 閉じている時 | |
|---|---|---|
| 小指 | 135 | 165 |
| 薬指 | 138 | 168 |
| 中指 | 185 | 200 |
| 人差し指 | 135 | 170 |
| 親指 | 124 | 139 |
Glove.asを作成し、glove.flaのドキュメントクラスとします。
ファイル構成はこのようにしました。
┌glove.fla
├Glove.as
└lib/
└gainer/
gainerパッケージを利用するので、クラスパスの設定を忘れないようにしてください。
Glove.asは以下の通りです。
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import gainer.*;
public class Glove extends Sprite{
private var _gnr:Gainer;
private var _hand_mc:MovieClip;
private var _finger0_mc:MovieClip;
private var _finger1_mc:MovieClip;
private var _finger2_mc:MovieClip;
private var _finger3_mc:MovieClip;
private var _finger4_mc:MovieClip;
public function Glove() {
//ムービークリップ
//手
_hand_mc = this["hand_mc"];
//指
_finger0_mc = _hand_mc["finger0_mc"];//親指
_finger1_mc = _hand_mc["finger1_mc"];//人差し指
_finger2_mc = _hand_mc["finger2_mc"];//中指
_finger3_mc = _hand_mc["finger3_mc"];//薬指
_finger4_mc = _hand_mc["finger4_mc"];//小指
//指初期化
_init();
//Gainer準備
_gnr = new Gainer("localhost", 2000, Gainer.MODE2, false);//MODE2
_gnr.onReady = function() {
_start();
}
}
//------------------------
// 指初期化
//------------------------
private function _init(){
//指を開いた状態にセット
_setFinger(1,1,1,1,1);
}
//------------------------
// 開始
//------------------------
private function _start():void {
_gnr.beginAnalogInput();//アナログ入力取得開始
addEventListener(Event.ENTER_FRAME, _update);
}
//-----------------------------------
// EnterFrame更新
//-----------------------------------
private function _update(e:Event):void {
//各チャンネルの入力情報を取得し、1-100の値にリマップ
var ain_0:uint = Math.floor(Gainer.remap(_gnr.analogInput[0], 135, 165, 1, 100));
var ain_1:uint = Math.floor(Gainer.remap(_gnr.analogInput[1], 138, 168, 1, 100));
var ain_2:uint = Math.floor(Gainer.remap(_gnr.analogInput[2], 185, 200, 1, 100));
var ain_3:uint = Math.floor(Gainer.remap(_gnr.analogInput[3], 135, 170, 1, 100));
var ain_4:uint = Math.floor(Gainer.remap(_gnr.analogInput[4], 124, 139, 1, 100));
//指の状態をセット
_setFinger(ain_4, ain_3, ain_2, ain_1, ain_0);
}
//-----------------------------------
// 指の動きをセット
//-----------------------------------
private function _setFinger(ain_4, ain_3, ain_2, ain_1, ain_0):void{
_finger0_mc.gotoAndStop(Math.floor(ain_4));//親指
_finger1_mc.gotoAndStop(Math.floor(ain_3));//中指
_finger2_mc.gotoAndStop(Math.floor(ain_2));//人差し指
_finger3_mc.gotoAndStop(Math.floor(ain_1));//薬指
_finger4_mc.gotoAndStop(Math.floor(ain_0));//小指
}
}
}
スクリプトを保存したら、Gainerのserial proxyサーバを起動します。
その後、パブリッシュして動作確認してください。
グローブを履いて手を開いたり握ったりすると、それにあわせて画面内の手が動けば成功です。
もし、グローブの動きとアニメーションがうまく合わない時は、Gainerの入力値を見直すなどして、細かな調整を行うようにしてください。
今回はWeb以外でのFlashコンテンツの可能性を知ってたいただくために、「バーチャルグローブ」を作成しました。グローブ作りは少し大変だったかもしれないですが、Flash自体はとてもシンプルで簡単だと思います。 このバーチャルグローブでは曲げセンサーを使用しましたが、他にも様々なセンサーがあるので、アイデア次第でいろいろな応用ができるでしょう。さらにFMSと組み合わせて遠距離にあるセンサーの値を取得したり、遠隔地にあるアクチュエーターを操作することもできると思います。ちょっとしたアイデアで見たこともないFlashコンテンツを作ることができるので、皆さんも是非挑戦してください!
このサンプルのように、Flash CS3が一つあれば、プログラムとアニメーションが連動したコンテンツを気軽に作ることができます。今後も新しいものにどんどんチャレンジしていくので、またみなさんに何か発表ができればうれしいです。フィジカルコンピューティングによって、Flashの更なる可能性を期待しています。
当「くるくる研究室」記事はEdge Newsletterの連載も予定しております。
※Edge Newletterは毎月一回ニュースレターとして配信されます。登録はこちら