INDEX(各項目ごとの目次)

[HOME]  [Processing関係]  [Arduino関係]  [マテリアル関係]  [秋葉原工作マップ]

2008年用ですが、部分的に内容を更新しています(2010/06/14)。
また、[建築農業工作ゼミ2009-2010]とも連動していますので、そちらにも幾つかサンプルがあります。
:

11/29/2008

Processing Webカメラ/モーショントラッキング

今回は、Webカメラ(USBカメラ)を使ってProcessing上で動体検知/動体追跡の実験を行ってみます。前回の「Processing Webカメラ/カラートラッキング」に似たプログラムですが、特定の色を追いかけるのではなく、画面上で動いている物体を検知し、その動きの方向に合わせて物体の座標値を取得します。逆に、動いている物体が画面内に見当たらない場合は、なにも検知しないことになります。

*Windowsの場合、そのままの設定ではこのVideoライブラリを使用することができません。WinVDIG 1.0.1をインストールする必要があります。


各ピクセルの色の取得:

・カメラ画像における、前回の画面と今回の画面の各ピクセルの色を比較します。
・320×240の画面サイズであれば76800個のピクセルをfor()を使って繰り返しの比較処理をさせることになります。
・各ピクセルの色を抽出するには、pixels[i]で順番にひとつずつピクセルを取り出します。
pixels[i]は、画面内のi番目のピクセルの色の値を返します。
・さらに、その一つのピクセルをRGBの3色に分解し、それぞれの値を取得します。
・3色のそれぞれの値を取得するには、red()green()blue()を用います。
・red(pixels[i])と書けば、そのピクセルの赤の値を取得できます(緑、青についても同様に処理)。

色の比較:
前回と今回の画面内のピクセルを比較するためには、一旦前回の全ピクセルの色情報を配列に代入して記憶させておきます。そして、記憶させておいた前回の色情報と今回の色情報を各ピクセルごとに比較します。
・色を比較するには、「前回の赤の値」から「今回の赤の値」を差し引きします(最終的に、絶対値abs()を使うので逆でも大丈夫です)。
・各色の値は0〜255までの段階があるので、その数値の差となります。緑や青についても同様に値の差を求めておきます。
・各色において、ある一定以上の差があるときに、画面内に「動作」があったと見なします。
・多少細かなノイズなどが含まれるので、差についてはある程度の許容値を設けておきます。例えば、±20以内の差であればノイズと見なし「動作なし」と判断し、それ以上の差があるときにだけ「動作あり」と見なすことにします。

平均値で座標を求める:
上記の方法で、設定した許容値を超えるピクセルがあったときに、そのピクセルの画面内でのXY座標値を調べておきます。今回の方法では、許容値を超えるピクセル(変化があったピクセル)のXY座標と個数から平均値を求め、その値をXとYの座標値として利用することにします。
例えば、X座標値100に10個、101に12個、102に8個あるときは、(100*10+101*12+102*8)/(10+12+8)=100.9333となり、この値を平均値としてX座標値にします。


(緑の部分が変化のあったピクセル、赤い正方形の位置がそれらの平均座標値、左上に許容値表示)


「変化があったピクセルを緑で表示し座標値を求めるプログラム」:
以下のプログラムでは、見やすくするために、変化があったピクセルを緑color(0,255,0)で塗りつぶすことにします。そして、それらのピクセルの平均座標値を求めて、赤い正方形を動かすことにします。
光や明るさの状況に合わせて許容値を調整できるプログラムにしておきます。
左右の矢印キーで色の許容値(変数:tolerance)を調節できるようにします(「←」:-1、「→」:+1)。

「c」キーを押せば、カメラセッティング画面に切り替わります(手動露出や手動コントラストなどに切り替えた方が認識しやすくなります)。

[プログラムを表示]



「Pongをプレイ」
次に、応用として「Pong」のパドルをモーショントラッキングで動かすサンプルをつくってみます。
動作によって変化があったピクセルの位置が画面内の左側あるいは右側を判別し、左右のパドルを個別に動かせるようにします。画面の端から50ピクセル幅のエリアで動作検知します(画面中央付近では反応しません)。


(モーショントラッキングで「Pong」をプレイする)

プレイしやすいように、カメラ映像は左右反転(鏡像)しています。
左右矢印キーで許容値を調整します(画面には許容値は表示されません)。
画面上部に点数を表示。
「c」キーでカメラセッティング。
「スペース」キーで点数をリセット。

[プログラムを表示]


関連:
Webカメラ:
Processing Video (Webカメラ)」--Webカメラの使い方/映像にフィルタをかけて表示。
Arduino+Processing マトリクスLED+Webカメラ」--Webカメラ映像をマトリクスLEDに映す。
Processing Webカメラを光センサとして使う」--点光源で画面内に線を描く。
Processing Webカメラ/定点記録画像」--Webカメラ映像を0.5秒おきに画像保存(JPEG)する。
Processing Webカメラ/カラートラッキング」--Webカメラを使い、色を手がかりに物体を追いかける。

ロジクールストア(ウェブカメラカテゴリ)

11/26/2008

Processing Webカメラ/カラートラッキング

今回はProcessingとWebカメラ(USBカメラ)を使い、色を手がかりとして画面内で動く物体の座標値を取得してみます。例えば、カメラに向かって動かした赤いボールの座標値を検出し、XY座標をArduinoへシリアル通信すれば、ボールの動きに応じてサーボなどを動かすことができます。
最初に物体の色を記憶させ、その色に近いピクセルを画面内から抜き出します。抜き出されたピクセルのXY座標値を調べ、中点や平均値を使って最終的なXY座標を導き出します。必ずしも単一の色面を背景にする必要はないのですが、色を手がかりとするので、対象とする物体と背景の色の差がある方が検出しやすくなります。

尚、Webカメラを使った画像認識や動体検知などのプログラムとしてFile>Examples>Libraries>Video(Capture)の中に「BrightnessTracking」や「FrameDifferencing」などのサンプルがあります。また、ライブラリとしては「JMyron」があります(「JMyron」のサンプルでは「Myron_CameraAsMouse」があります)。

Webカメラ(USBカメラ)を使用するには、ProcessingのVideoライブラリをインポートします。Webカメラの基本的な使い方は「Processing Video (Webカメラ)」や色抽出する方法として「Processing Webカメラを光センサとして使う」を参照して下さい。

*Windowsの場合、そのままの設定ではこのVideoライブラリを使用することができません。WinVDIG 1.0.1をインストールする必要があります。


「Processing上の画面」
(手に握った物体の動きに合わせて赤い円が動く)


今回の設定として:
・キャプチャする映像のサイズ(幅:w、高さ:h)を320×240(4:3)にします。
 (処理速度が遅くなる場合は160×120などの小さいサイズに変更して下さい。)
・最初に、画面内の対象となる物体をマウスでクリックし、そのピクセルの色を記憶しておきます。
 (背景とはできる限り異なる色の物体を選ぶ方が認識しやすくなります。)
・物体の動きに合わせて、画面上の図形(赤い円)が動くプログラムにします。

プログラムの手順としては:
・video.pixels[]で、カメラ映像内の各ピクセル(320×240=76800ピクセル)を全て読み込みます。
・対象となる物体の色(特定の1ピクセル分の色)をpixels[]で取り出します。
・各ピクセルをred()green()blue()でRGBに分解します。
・各ピクセルの色と物体の色を各RGB色ごとに比較します。
・比較した各RGB色が設定した許容値(tolerance)以内であるかを判別します。
・許容値以内のピクセルがある場合、そのピクセルの座標値を調べます。
・選択された複数のピクセルの座標を統合して、最終的にXY座標を導き出します。
・導かれた座標を図形(赤い円)の座標に代入し、物体に合わせて図形(赤い円)が動くようにします。


「選択したピクセルの色をRGBに分解し判別する」:
ひとつのピクセルであるpixels[i]には、color(R,G,B)の3つの値が含まれています(アルファ値/透明度も含めれば4つになりますが、今回はRGB値だけを扱います)。各RGB色に分解するには、red(pixels[i])、green(pixels[i])、blue(pixels[i])というようにred()、green()、blue()を用いてpixels[i]を括ります。得られる値はそれぞれ0.0~255.0の小数値になります。色を特定化しても光の反射などによって多少色が変化するので、特定化する色にある程度の許容値を与えておきます。例えば、赤の値が80の場合、許容値を10にすることで70~90の値であれば同等の色と見なすことにします。許容値が小さすぎれば、色が限定されすぎるので取りこぼしがでてきます。逆に許容値が大きすぎれば、他の色を混同してしまうので、状況に応じて調整できるようにプログラムすることにします。


「pixels[i]をXY座標に変換する方法」:
画面幅をw=320、高さをh=240とします。横一列には320個のピクセルが並んでおり、さらに320個のピクセルが240行並んでいます。つまり一つの画面内には、合計で76800個のピクセルがあります。
pixels[i]のiには、画面左上の0番目のピクセルから画面右下の76799番目のピクセルまでの連続した数値が入ります。例えば、画面上の(120,40)というXY座標は、画面幅をwとした場合、120+40*w=12920なので12920番目のピクセルであり、pixels[12920]になります。逆に、この12920番目のピクセルを画面上のX座標とY座標に変換するには、x=i%w、y=i/w(つまり、x=12920%320、y=12920/320)となります。「%」は割り算の余りを求める式で、「/」は割り算ですが整数(int)で割っているので小数点以下は切り捨てられます(四捨五入なし)。
マウスの座標値(mouseX,mouseY)であれば、pixels[mouseX+mouseY*w]になります。

上記の方法で選ばれたピクセル(物体の色のピクセル)は複数個あるので、それらのピクセルを座標値に置き換えるには幾つかの方法があります。
ひとつは:
画面内において最も右端にあるピクセルのX座標と左端にあるピクセルのX座標、ならびに上端にあるピクセルのY座標と下端にあるピクセルのY座標を調べ、右端と左端の中点をX座標、上端と下端の中点をY座標とみなす方法です。弱点としては、近似色がノイズとして画面上にある場合、そのピクセルも拾ってしまうことです。ノイズを除去するプログラムや予め画面全体にぼかしをかけることである程度回避できます。
もうひとつは:
選択したピクセル(物体の色のピクセル)が多く分布している箇所を調べ、ピクセルの分布数と位置から平均値を割り出す方法です。この場合、多少のノイズがあっても大きなずれは発生しなくなります。
その他の方法も考えられますが、今回は上記二つの方法で実験してみたいと思います。

「操作手順」:
プログラムが開始したら、画面上で対象となる物体をクリックして物体の色を記憶させます。画面左上に、10ピクセル角の矩形でその色が表示されます。直径20ピクセルの赤い円が、物体の移動に合わせて動きます(物体を追跡します)。
左右の矢印キーで色の許容値(変数:tolerance)を調節できるようにします(「←」:-1、「→」:+1)。
変化する数値をPFontを用いて表示するので、Tools>Create Font...をクリックし「Monaco-10.vlw」を取り込んでおいて下さい(「Processing 文字と画像」を参照)。
また、「c」キーを押せば、カメラセッティング画面に切り替わります(手動露出や手動コントラストなどに切り替えた方が認識しやすくなります)。
画面上に許容値を含めた物体の色がある場合は、「detected」という文字が表示されます。もし、近似色がない場合は「none」が表示され、赤い円は前回の位置に留まります。再度近似色が画面内に現れれば、赤い円はその位置に移動します。


「左右端、上下端の中点を座標値にするプログラム」:

 [プログラムを表示]


*プログラムを開始する前にTools>Create Font...をクリックし「Monaco-10.vlw」を取り込んでおいて下さい(スケッチフォルダの中のdataフォルダ内にフォントが保存されます)。
複数あるピクセルのうち左端、右端、上端、下端のピクセルを抜き出すために、最小値と最大値を求めるためのmin()max()を用いました。各ピクセルの座標値を比較し、X座標においては最小座標値を左端座標値とし、最大座標値を右端座標値として扱います。Y座標に対しても同様に導き出します。そして、それらの中点を最終的なXY座標値とします。



「分布するピクセルから割り出す方法」:
次は、物体の近似色のピクセルの分布から平均値を求めて座標値を割り出す方法についてです。
先ほどの方法と同様にfor()で全てのピクセルの色を識別し、その中から物体の近似色のピクセルを選びます。その際に近似色のピクセルの個数と、そのピクセルのXY座標値をそれぞれ加算しておきます。最終的に加算されたそれぞれの値を近似色のピクセル数で割って平均値を求めます。例えば、X座標値100に10個、101に12個、102に8個あるときは、(100*10+101*12+102*8)/(10+12+8)=100.9333となります。Y座標についても同様に求めておきます。

以下のプログラムでは、カメラからの映像を左右反転の鏡像として表示することにします(カメラに向かって、右に物体を動かせば、画面上でも右に動くようにします)。
「v」キーを押すことで、カメラからの映像を表示/非表示切り替え可能にします。
円の動きを滑らかにするために、移動量にフィルタをかけることにしました。
物体検知用のフラグがtrueの場合、許容値toleranceは自動的に下がり、falseの場合は自動的に上がるようにしました(変化の範囲は2~25に設定してあります)。設定した最大許容値:25以内の近似色が画面内にある場合は反応してしまいます(フラグがtrueになる)。不自然な反応をとる場合、最大許容値を下げるか、前回のプログラムのように手動で調整する内容に変更してみてください。
赤文字部分が、前回と異なる部分です。
前回同様、プログラムを開始する前に、使用するフォントを取り込んでおいて下さい(「Processing 文字と画像」を参照)。

「分布するピクセルから割り出すプログラム」:

 [プログラムを表示]


*プログラムを開始する前にTools>Create Font...をクリックし「Monaco-10.vlw」を取り込んでおいて下さい(「Processing 文字と画像」を参照)。
「filterX+=(x-filterX)*0.3;」の「0.3」は円の動きをゆっくり滑らかに(鈍く)するための係数です。1.0に近づくほどフィルタの効果はなくなり、0に近づくほど鈍く動くので適度に調整して下さい。
左右反転(鏡像)しているために、円のX座標値はそのままの値ではなく「w-filterX」になっています。

「ビット演算による色変換」:
color(R,G,B,A)は、A:アルファ値(透明度)、R:赤、G:緑、B:青の4種類の8ビット(合計32ビット)の値が含まれています。32ビットの内訳(2進数の場合)は

AAAAAAAARRRRRRRRGGGGGGGGBBBBBBBB

になります。32あるそれぞれの桁には0か1が入ります。
透明度が100%(不透明)の緑であれば、

11111111000000001111111100000000

になります。16進数であれば「0xFF00FF00」や「#00FF00」になります。10進数なら「255,0,255,0」です。
上記プログラムでは、ピクセルの赤の値を調べるためにpixels[i]red()で括って

red(pixels[i])

にしましたが、

(pixels[i] >> 16) & 0xFF

というビット演算を使っても求められます。32ビットを16桁右にシフト「>>」し、下位8桁(0xFF)だけを「&」を使って取り出す(ビットマスク)という方法になります。
結果的にはこの方法の方が処理速度が上がるようです。
緑と青については、

(pixels[i] >> 8) & 0xFF //緑:8ビット右にシフトし下位8桁だけを取り出す
pixels[i] & 0xFF //青:下位8桁だけを取り出す

になります。
もし、処理速度が不安定な場合は、上記のようなビット演算を用いるか、画面サイズを小さくするか、もともとのフレームレートを下げるかなどの工夫や調整を行ってみてください。


ドライバなしですぐにコンピュータに接続可能(UVC対応)なWebカメラとして以下のようなものがあります。
Macintosh/Windows兼用です。
      

関連:
Processing Video (Webカメラ)」--Webカメラの使い方/映像にフィルタをかけて表示。
Arduino+Processing マトリクスLED+Webカメラ」--Webカメラ映像をマトリクスLEDに映す。
Processing Webカメラを光センサとして使う」--点光源で画面内に線を描く。
Processing Webカメラ/定点記録画像」--Webカメラ映像を0.5秒おきに画像保存(JPEG)する。
Processing Webカメラ/モーショントラッキング」--Webカメラを使って動体検知する。

11/22/2008

工作機械について


「旋盤」では、取り付けた材料(金属や樹脂など)を回転させ、バイト(刃)で切削し、回転系の部品(車輪、プーリーなど)を制作することができます。旋盤加工できる部品の寸法は、旋盤の「心間(回転体材料の長さ)」と「心高(回転体材料の半径)」によって決まります。より大きな部品を制作する場合は、この二つの寸法が大きな機種を選ぶ必要があります。



「フライス盤」では、スライドテーブル上に取り付けた材料(金属や樹脂など)を移動させることで、直線や円形に溝加工したり、エッジを段状に加工したり、材料表面をフラットに切削したりすることができます。材料を固定するスライドテーブル(XY方向の移動量)や回転テーブルのサイズによって加工サイズが決まります。

「旋盤」と「フライス盤」を組み合わせれば、ほとんどの機械部品を制作することができると言われています。


小型工作機械メーカー/販売:
ベルメックスインターナショナル
寿貿易/メカニクス
東洋アソシエイツ
プロクソン





工具屋ドットコム楽天市場店
プロ工具にDIY モンジュSHOP
ケンチクボーイ
卸問屋 都築屋本舗

11/16/2008

次回(11/22)授業について

次回11/22(土)は、15:00から授業を開始します(お間違えないように)。

・空間内における制作物の配置、身体との関わり、空間全体のイメージなど(前回のコラージュ)を引き続き制作してきてください。
・使用される部品や材料なども持参して下さい。授業内で、個人ごとに制作の指導をします。
・必要に応じて「旋盤」「フライス盤」「ボール盤」で、金属部品制作(回転部分や固定部分の部品など)の実習も行う予定です。

精密小型旋盤 Compact3
精密小型旋盤 Compact3
posted with amazlet at 09.03.31
東洋アソシエイツ
売り上げランキング: 95873

11/15/2008

Arduino デジタルカラーセンサ S9706

今回は秋月電子で購入したデジタルカラーセンサS9706の実験をします。S9706は、RGB3色の同時測光が可能であり、9×9素子(高感度)と3×3素子(低感度)の感度設定が2段階あり、感度設定用の端子(Range端子)をHIGHまたはLOWで切り替えて設定できます。検出結果は12ビットの値でシリアル出力されます。S9706は表面実装用の小さな部品(1.27mmピッチ)なので、DIP変換基板などにハンダ付けして使用したほうが実験しやすくなります。

S9706には、

・Range端子(感度設定)
・Gate端子(測光時間の設定)
・CK端子(クロックパルス)
・Dout端子(出力)
・Vdd端子(5V電源)
・Gnd端子(グランド)

の6端子あります。
それぞれを以下のように接続します。尚、測光時間を調節できるように可変抵抗器も接続することにします。



データシートの動作手順によれば、以下のように説明されています。
(1)Gate端子とCK端子をLowにします。
(2)Range端子で、所望の感度を選択します(今回は、可変抵抗器で調節可能にしておきます)。
(3)Gate端子をLow→Highにして光量の積算を開始します。
(4)所望の積算時間の後にGate端子をHigh→Lowにして光量の積算を終了します。
(5)測定データは、CK端子に36のCKパルスを入れることで、Dout端子から出力されます。

Dout端子からの12ビットのシリアル出力を読み込むためには、CK端子へ12回のパルスを3回送る必要があります。最初の12パルスによって赤、次の12パルスによって緑、そして最後の12パルスによって青が出力されます。この部分の手続きは、shiftIn()というファンクション(名前は任意)を用意することにします。付属のデータシートのタイミングチャートに従ってプログラムしていくことにします。
最終的に得られたRGB三色の値(12ビット:0~4095)をシリアル通信でProcessingへ送信し、Processingの画面上で色表示することにします。

「Arduinoのプログラム」:

 [プログラムを表示]


アナログ入力に接続された可変抵抗器で、測光時間を1ミリ秒から1024ミリ秒まで可変的に設定可能になります。測光時間が短ければ全体的に暗い色として認識されるので適宜調節してください(白色LEDを取り付けて反射光を使って読み取らせることもできると思います)。
12ビットの値を読み込む処理をするint shiftIn(){...}では、一色につき12回CK端子へパルス(HIGH:1μsec+LOW:1μsec)を送ります。12回分のパルスをfor文で繰り返し処理させています。for(){...}の中では、digitalWrite(CK,HIGH)で1回HIGHを送ったあと1マイクロ秒待機すると、Dout端子から1ビット分の出力があるので、digitalRead(DOUT)でHIGHかLOWかを読み込みます。そしてdigitalWrite(CK,LOW)によって、CK端子をLOWに戻しておきます。
読み込み値を、
000000000000~111111111111(十進数の0~4095)
までの二進数で処理するため、digitalRead(DOUT)がHIGHの場合は12ビット中のその桁が1になります。S9706では、右の桁から出力されます。つまり、for(){...}では、最初に処理される桁は右側の一桁であり、最後に処理される桁は左側の一桁(12桁目)になります。



Processingの方では4つの矩形を用意し、RGBの三色それぞれの色面とRGBを合成した色面として表示します。Arduinoとのシリアル通信は文字列で行います(複数の文字列のシリアル通信は「Arduino-Processing シリアル通信5」を参照してください)。Processing側でクリックしたらシリアル通信を開始することにします。


Processing上の画面:左から赤、緑、青、3色合成

「Processingのプログラム」:

 [プログラムを表示]


Arduinoからは0~4095の範囲で値が送られてくるので、fill(r,g,b)の各値に代入するため、map()を使って0~255までの値(さらにint()で括って整数に変換)に変換しています。

「room01~03」について

「room01~03」概要:
既存のギャラリー空間に対して、各自の制作物(ツール/デバイス)を挿入することで、空間の機能や質あるいは空間に対する人間の知覚を変容させることを目標とします。
ギャラリーに訪れる人は、制作物(作品)に対する「鑑賞者」になるというよりも、制作物によって変容した空間の性質を体験する「体験者」になります。また、制作物を通して意味を生成したり理解されたりすることを目標とするのではなく、フィジカルに体験される物理的現象(あるいは肉体的な身体を通した感覚)を目標とします。つまり、解釈や理解によって空間の質を変容させるのではなく、実際的にあるいは物理的に空間が変容することに重点をおいてください。

「room01~03」までのステップ:
(1)ある現象を測定したり記録/伝達するような「ツール/デバイス」の実験的なプロトタイプ制作。
(2)「ツール/デバイス」を体験可能なかたちとする(「体験者」との関わりを配慮した形態)。
(3)「ツール/デバイス」と「体験者」を「空間」内に配置する(「体験者」に応じた設置方法や配置方法の工夫)。
(4)「体験者」の身体の変化と「ツール/デバイス」の変化が「空間」に与える影響力を強化する。

演習:
(1)デバイスのコラージュ
(2)デバイスと身体のコラージュ
(3)空間内に配置されるデバイスと身体のコラージュ
(4)変容する空間のコラージュ

11/13/2008

センサについて2

以下は、「秋月電子」、「千石電商」、「共立エレショップ」、「Sparkfun(米国)」の各サイトにおけるセンサの分類です。目的や機能ごとに分かれているので、センサを選ぶ際の参考にして下さい(各店舗の各センサのページへリンクしています)。




秋月電子

センサ一般
湿度/温度

赤外線センサ
リモコン受光部
紫外線関連

ペーハー(pH)
アルコール/ガス 
方位

千石電商

ホール素子/ホールセンサ 
温度センサー
角速度(ジャイロ)
加速度
距離
圧力
衝撃
曲げ
焦電
サーミスタ
共立エレショップ

感圧
ひずみ/曲げ
温度
湿度

赤外線
紫外線
カラー
超音波
磁気
電流
位置
位置(アクセサリ) 
動き
Sparkfun(米国)

Accelerometer(加速度)
Biometrics(生物測定)
Capacitive(静電容量)
Current(電流)
Flex/Force(曲げ/力)
ID(証明/認証)
IMU/Gyros(慣性力/角速度) 
Infrared(赤外線)
Light/Imaging(光/画像)
Magneto(磁力)
Proximity(距離)
Temperature(温度)
Weather(天候)






その他のショップやセンサについては、このブログページ右側の「ショップリスト」にも記載してあるので参考にして下さい。

11/08/2008

Arduino書籍:「Making Things Talk」日本語版

『Making Things Talk--Arduinoで作る「会話」するモノたち』(日本語版)が発売されるそうです。

Making Things Talk -Arduinoで作る「会話」するモノたち
Tom Igoe
オライリージャパン
売り上げランキング: 16017

Processing ドラッグした図形の動きを記録/保存/再生する

Processing画面上の図形をマウスでドラッグし、その動きを記録する方法、記録した内容をテキストデータとして外部に保存する方法、さらにそのテキストデータを読み取って動きを再生させるサンプルです。

まずは、ドラッグする図形を円とした場合のプログラムから始めます。今回はmouseDragged()は使わず、startDragというフラグを用意し、mousePressed()でドラッグ開始(startDrag=true)、mouseReleased()でドラッグ終了(startDrag=false)とみなす方法を用います。
円の中心座標から少しずれた位置にマウスを合わせてそのままドラッグできるように、円の中心座標とマウス座標の差分を計算しておき、その差分を足した値を最終的に円の座標に反映されるようにします。
また、dist()を使って円の中心座標からマウス座標までの距離を計算し、その距離が円の半径以内であれば円の上にマウスがあることとみなしてドラッグ可能にします。dist()は、dist(x1,y1,x2,y2)のように(x1,y1)と(x2,y2)の二点間の距離を計算します。


「円をドラッグする」:

 [プログラムを表示]



「円をドラッグ+記録機能」:
上記プログラムに、ドラッグした円の動き(連続する座標値)を記録する機能を付け加えます(以下のプログラム)。「r」キーを押すことで記録開始にします。再度「r」キーを押すと記録停止するようにし、記録中は円の塗色を赤に変化させます。プログラム的には、recordStartというフラグを用意し、記録開始/停止を判別できるようにします。xPosとyPosという座標を記録するための配列を用意しておき、記録中はそれらの配列に座標値を付け加えていきます。
赤文字の部分が付け足したプログラムです。

 [プログラムを表示]


xPos={}というように空の配列をはじめに用意しておき、append()を使って変化する座標値を配列xPosに付け加えていきます。よって、配列xPosに含まれる要素は、記録されるごとに増えていきます。xPos.lengthを用いれば、記録された配列内の座標の個数を調べることができます。
記録停止しているときに「r」キーが押されればstartRecord=trueにし、逆に記録停止しているときに押されれば、startRecord=falseに切り替えられるように、フラグstartRecordを使い分けます。


「円をドラッグ+記録機能+保存機能」:
さらに以下では、記録された内容をテキストファイルとして外部保存する機能と記録した座標値を消去する機能を付け足します(赤い文字部分)。「r」キーで記録、「s」キーでファイル保存、「c」キーで記録内容を消去することにします。

 [プログラムを表示]


上記プログラムでは、printWriterを使って外部ファイルとして座標値データを保存しています。「s」キーを押すとselectOutput()によってダイアローグ画面が現れるので、保存名と保存先を指定します。「positions.txt」のように、「.txt」の拡張子をつけて任意の場所(デスクトップなど)に保存します。再度上書き保存する場合は、ダイアローグ画面上で、同じファイルを選択し保存ボタンを押します(上書き保存の確認メッセージが現れます)。


「円をドラッグ+記録機能+保存機能+再生機能」:
次に、記録された内容や保存された内容のデータを読み取り、そのデータに基づいて動きを再生するプログラムをします。再生中は円の塗色が緑に変化し、再生終了すれば黒に戻ります。
まず、「r」キーを押して記録開始し、マウスで円をドラッグします(ドラッグ記録中)。
次に再度「r」キーを押して記録を停止します。
記録された内容を再生するために、「p」キーを押します。動きが再生されている間は円が緑色になります。
「s」キーを押すことで、記録内容を外部ファイルとしてデスクトップなどの任意の場所にファイル名(拡張子「.txt」)をつけて保存します。
「s」キーで保存されたファイルを読み込むには、「l」(小文字のエル)キーを押してファイル選択画面の中でファイル選択します。読み込んだファイルのデータは配列xPosとyPosに記憶されます。「p」キーを押せば、読み込んだ記録を再生します。
「c」キーによって、配列内のデータを空にしないかぎり、「r」キーによる記録した座標値は追加されていきます。

「各キーの機能割当」:
r:記録開始(record)/記録停止
c:記録消去(clear)
s:保存(save)
l:ファイル読み込み(load)
p:再生(play)

赤文字部分がさらに追加した再生機能の内容です。

 [プログラムを表示]


「p」キーを押すことで、再生用フラグstartPlayがtrueになり、ループ内で再生用の処理が行われます。変数countを用意しループするごとにcountを+1ずつ増加させ、配列内の座標データをひとつずつ円の座標に代入していきます。配列内のデータ数をxPos.lengthで調べ、最後のデータまで読み込んだら再生用フラグstartPlayをfalseにし再生停止させます。
「l」キーを押し、selectInput()によってファイル選択画面が現れ、保存したファイルを選択します。選択したファイル内のデータをloadStrings()によって、「X座標値+コンマ+Y座標値」という一行ずつの文字列をsplit()でコンマ記号を境目として二つのデータに分けて、同時にそれら文字列をint()で整数化し、append()によって座標用の配列xPosとyPosに追加していきます(代入する前にxPosとyPosを空の配列にしておきます)。

誤作動が起こらないように、再生中はキー入力を禁止したり、読み込まれるファイルが相応しくない場合の例外処理などが実際には必要になりますが、今回のプログラムでは省略しています。

FILCO ポータブルタッチパッド スマートトラックライト ATP-400UB
ダイヤテック (2008-06-26)
売り上げランキング: 19889

11/02/2008

Processing サウンド/Sonia JSynプラグイン

Processingのサウンドライブラリの「Sonia」を、MacOSX(Intel)で使用する場合、新たにJSynプラグインをインストールする必要があります。現ライブラリフォルダにはMacOSX(PowerPC版)のJSyncプラグインしか含まれていないようです。
ここをクリックすると、インストール画面に移動します。移動先のページ上の「Click Here to Install JSyn Plugin」のボタンを押して新しいバージョンのJSyncプラグインをインストールしてください。

関連:
Processing サウンド4/スクラッチ」--Soniaライブラリを使って曲をスクラッチ演奏する
Processing サウンド3/テンポ」--Soniaライブラリで音源再生のテンポ変換をする
Processing サウンド2/逆再生」--Soniaライブラリで逆再生の音源をつくる
Processing サウンド1/Sonia」--Soniaライブラリで音源の再生/停止/ポーズする

 iTunes Music Store(Japan)

11/01/2008

Arduino Ethernet Shield

今回は、Arduino Ethernet Shieldスイッチサイエンスストロベリーリナックスにて販売)を使って、Arduinoをサーバとして機能させ、Webブラウザ(IE、Safari、FireFoxなど)から閲覧可能なページの表示実験を行いたいと思います。
そのために、Arduino開発環境の最新版「Arduino 0012」に含まれている「Ethernetライブラリ」を使います。
*Arduino MegaとEthernet Shieldを重ねて使う場合の説明はこちら


(Arduino Ethernet Shield)


Arduinoのサイトによれば、デジタルI/Oピンの11、12、13番ピンはSPI通信に使われているようなので、それらのピンにはセンサなどを接続しないことにします。


今回は、Arduino 0012に含まれている「Web Server」というサンプル(File>Sketchbook>Examples>Library-Ethernet>Web Server)を参考にブラウザで閲覧可能なWebベージを表示させます。元々のサンプルでは、アナログ入力値をWebページに表示させていますが、ブラウザのタイトルバーの表示文字、リンクさせた画像の表示など多少変更した内容にしてみます。
基本的な入力情報として、

・MACアドレス
・サーバのIPアドレス
・ポート番号

が必要となります。尚、ローカルネットワーク内から閲覧できる設定にします。

Arduinoのプログラム(サーバ):

//イーサネットライブラリを取り入れる
#include <Ethernet.h>

//MAC ID(各シールドに記載)
byte mac[] = { 0x00, 0x50, 0xC2, 0x97, 0x20, 0x11 };
//サーバ用IPアドレスの設定
byte ip[] = { 192, 168, 3, 100 };
//ポート設定(80:HTTPプロトコル)
Server server(80);

void setup(){
//イーサネット通信開始
Ethernet.begin(mac, ip);
//サーバ開始
server.begin();
}

void loop(){
//クライアントからのデータ受信
Client client = server.available();
//クライアントからの受信がある場合
if (client) {
//ブラウザからのHTTPリクエストの空白行の有無のフラグ
boolean current_line_is_blank = true;

//クライアントとの接続中の処理
while (client.connected()) {
//クライアントから受信データがあるとき
if (client.available()) {
//HTTPリクエスト(受信データ)を一つずつ読み込む
char c = client.read();
//HTTPリクエストにラインフィード(改行)があり、
//現在空白行である場合
if (c == '\n' && current_line_is_blank) {
//HTTPレスポンス(返信)
server.println("HTTP/1.1 200 OK");//リクエスト成功
server.println("Content-Type: text/html");//HTML文書形式
server.println();//空白行を入れる

//タイトルバー表示
server.println("<title>KOUSAKU WEB SITE</title>");
server.print("ANALOG INPUT: ");//文字表示
server.print(analogRead(0));//アナログ入力値
server.println("<br/>");//改行
//リンク画像表示
server.println("<img src=\"http://2.bp.blogspot.com/_7uyXRm_coS4/SQeoW-PJB2I/AAAAAAAAAbA/0Go85aRfLDY/s400/ethernet.png\">");
server.println("<br/>");//改行
//このブログへのリンク
server.println("<a href=\"http://kousaku-kousaku.blogspot.com\">GO TO: KOUSAKU BLOG PAGE<a>");
break;
}
if (c == '\n') {//読み込んだ文字がラインフィードの場合
//現在の行を空白行とみなす
current_line_is_blank = true;
} else if (c != '\r') {//読み込んだ文字がキャリッジリターン以外の場合
//現在の行を空白行としない
current_line_is_blank = false;
}
}
}
delay(1);
client.stop();
}
}


Arduino基板のアナログ入力0番端子に可変抵抗器をひとつ接続し、その読み取り値もページに表示されます。Arduinoのプログラム上では、MACアドレス、IPアドレス、ポート番号をそれぞれ設定しておき(説明以下)、クライアントのブラウザからの「HTTPリクエスト」(説明以下)を受け、「HTTPリクエスト」内の空白行を確認したら、「HTTPレスポンス」(説明以下)を返します。そのとき同時にHTML形式のページ表示内容データも送信されます。送信されたら、client.stop()で、クライアントとの接続を一旦停止します。再度、クライアントから「HTTPリクエスト」があれば、同様に処理されます。

「MACアドレス」:
MACアドレスは、Ethernet Shield固有のアドレスであり(ハードウェアごとに異なる)、スイッチサイエンスから購入したものであれば、Ethernet Shield裏面に貼られたシールに記載されている「00-50-C2-97-20-11」のような16進数の6つの数値です。これらの数値を16進数表記であたまに「0x」を付け加え記入しておきます。
もし、MACアドレスが不明の場合は、MacOSXなら「アプリケーション>ユーティリティ」内にある「ターミナル」を起動し、「ping -c 3 192.168.3.100」(IPアドレスは設定したものを入力してください)というように入力しリターンキーを押してください。その後、「arp -a」を入力しリターンキーを押すと、入力したIPアドレスの右横にMACアドレスが表示されます。
Windowsの場合、アクセサリ内の「コマンドプロンプト」を起動して、「ping 192.168.3.100」(「ping」の後に半角スペースを入れ、設定したEthernet ShieldのIPアドレスを入力)を入力しリターンキーを押すと、返答として「reply from...」などと数行表示されます。その後、すぐに「arp -a」を入力しリターンキーを押せば、Ethernet ShieldのIPアドレスの右横にMACアドレス(Physical Address)が表示されるはずです。

「IPアドレス」:
IPアドレスを設定するには、Ethernet Shieldに接続するイーサネットケーブルをコンピュータに接続し、まずイーサネット経由でのコンピュータのIPアドレスを調べてみます。IPアドレスが「192.168.3.xxx」であれば、最後の桁に任意の数値(他のIPアドレスと重ならないような数値)を入力すれば、大丈夫なはずです(今回の場合は「100」にしました)。同時に、ルータ(gateway)のIPアドレスも調べておくといいでしょう。この場合「192.168.3.1」(最後の桁が「1」)になっているはずです。
「ターミナル(MacOSX)」や「コマンドプロンプト(Windows)」で、MACアドレスを調べると(前述)、ルータのIPアドレスやMACアドレスも表示されるはずです。
尚、「Processing HTTPサーバ/Webページ表示」の冒頭でも、IPアドレスの調べ方について記載しているので参照して下さい。

「ポート」:
ポートは、通常のインターネットで使用している「80」に設定されています(プロトコル:HTTP用)。例えば任意のポート「12345」に設定する場合、ブラウザ上でIPアドレスを入力する際に「http://196.168.3.100:12345」というように「:12345」をIPアドレスの後ろに付け加えます。

「HTTPリクエスト」:

通常、ブラウザからURLを入力しページを表示させる場合、「GET / HTTP/1.1」(HTTPリクエスト)というサーバへの要求内容が送信されます。「GET /index.html HTTP/1.1」にすれば、サーバ上の「index.html」を指定して表示要求することもできます。
実際のブラウザ「Fire Fox 3.0.3」からサーバへ送信されるHTTPリクエストは、以下のような内容になっていました。

GET / HTTP/1.1 (リクエスト行)
Host: 192.168.3.100:12345 (メッセージヘッダ:以下の空白行手前まで)
User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; ja-JP-mac; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0
(空白行)
(メッセージボディ:今回は特に何も送るデータは含まれていない)

「リクエスト行」では、サーバへの要求内容が書かれています。
「メッセージヘッダ」では、サポートされるデータ形式や言語などの様々な情報が記載されています。
「空白行」を挿入することで、要求内容の終わり部分を知らせます。
「メッセージボディ」は、サーバに入力情報などを送る際に使われます。
各行末には「\r\n」(CR+LFの改行コード)がついていました。


「HTTPレスポンス」:

サーバはブラウザからのHTTPリクエストを受け取って、「HTTP/1.1 200 OK」という受信確認した返事を返してきます。「200」はHTTPステータスコードと呼ばれ、「Not Found」(ページが見当たらない)の場合は「404」を返します。
「content-type:text/html」は、内容がHTML文書であるという形式について返答しています。
その後で、println()で空白行を送信します(CR+LF/キャリッジリターン+ラインフィードを送信)。
次に、HTMLなどのコンテンツを送ります。
つまり、以下のような内容になります。

HTTP/1.1 200 OK    (ステータス行)
content-type:text/html (メッセージヘッダー)
            (空白行:CR+LF)
<html>         (メッセージボディ)
<head>...</head>
<body>...</body>
</html>

コンテンツはHTML形式で、println()の括弧内に記述します。基本的に<>(タグ)で囲い、ブラウザのタイトルバーを表示させるために「<title>KOUSAKU WEB SITE</title>」としています。ひとつ問題になることは、println()の括弧内に「"..."」ダブルクオーテーションマークで文字列をくくらなければならないのですが、画像リンクやURLリンク先を記入する場合に「"」を文字列として扱いたい時、そのまま入力するとエラーになってしまうので、「"」を「\"」に置き換えて入力します(エスケープシーケンス)。そのため、「println("<img src="リンク先URL">")」(二重に「"」で括られてしまう)を「println("<img src=\"リンク先URL\">")」という表記にします。<br/>は、ブラウザ表示される際の改行です。

「ブラウザ上での閲覧」:
ポートを「80」に設定している場合、「http://192.168.3.100」(設定したIPアドレス)を入力しリターンキーを押せば、Arduino Ethernet Shieldからデータが送られ、ブラウザにコンテンツが表示されるはずです。
ポートを「12345」などの任意の番号にしている場合、「http://192.168.3.100:12345」というように、アドレスの最後に「:12345」(コロンとポート番号)をつけてアクセスして下さい。

「ローカルネットワーク外からのアクセス」:
外部からインターネットによってアクセスする場合は、グローバルIPアドレス、ルータ、ポートマッピングなどの設定が必要になります(「Processing-Arduino ネットワーク制御」の後半に、ポートマッピングなどの設定方法が書いてあるので参照してください)。
尚、LAN内の別のコンピュータからグローバルIPアドレスを使ってアクセスはできないので、実際にLAN外部からアクセスして見てください。

Arduinoイーサネット・シールド
スイッチサイエンス
売り上げランキング: 15483






Processing HTTPサーバ/Webページ表示

今回は、ProcessingのNetworkライブラリを利用して、ウェブブラウザで閲覧可能なウェブサイトのサーバとして機能させます。
サーバとして、IPアドレスならびにポート番号をあらかじめ確認/設定しておきます。

LAN内のローカルIPアドレスの場合:
コンピュータのIPアドレスを調べるには、MacOSXであれば、「システム環境設定>ネットワーク」を開き、AirMacを使用している場合は「AirMac」を選択、ケーブル接続している場合は「内蔵Ethernet」を選択し、「TCP/IP」タグを選択すると2段目あたりに「IPアドレス:10.0.1.2」などと表示されています。Windowsの場合は、コマンドプロンプトを開いて、「ipconfig」と打ってリターンすれば、幾つかの情報が現れ「IP Address....10.0.1.2」などと表示されるはずです。

グローバルIPアドレスを調べる場合:
以下のようなサイトで調べることができます。
http://dog.tele.jp/lookup.php
「あなたのパソコンのグローバルIPアドレスは」と書かれている場所に表示されます。

尚、ローカルネットワークの外からアクセス可能にするためには、ルータ上でのポートマッピング(ポート転送)などの設定が必要になります。設定については、「Processing-Arduino ネットワーク制御」の後半に説明があるので参照してください。

参照:YahooBBのモデムのポート転送設定方法


Processingのプログラム:

//ライブラリのインポート
import processing.net.*;
//サーバのインスタンス
Server server;
//カウンタ用変数
int val = 0;

void setup() {
size(200, 200);
//サーバの設定(ポート:12345)
server = new Server(this, 12345);
}

void draw() {
//クライアントからの受信確認
Client client = server.available();

//クライアントがいる場合
if (client!=null) {
//クライアントIPアドレス出力
println("Client IP Address : "+client.ip());
//クライアントからのデータがあるとき
if(client.available()>0){
//データ読み込み(HTTPリクエスト読み込み)
String clientData=client.readString();

//データを改行コードをもとに区切り、
//改行コードを取り除いてから配列に代入していく
String[] httpRequest=trim(split(clientData,'\n'));

//受信データの最初の内容が「GET / HTTP/1.1」の場合
if(httpRequest[0].equals("GET / HTTP/1.1")){
//以下の内容をクライアントへ返信する(HTTPレスポンス)
client.write("HTTP/1.1 200 OK\n");//接続成立
client.write("Content-Type: text/html\n");//HTML文書形式
client.write("\n");//空白行

//以下HTML文書表示内容
client.write("<title>KOUSAKU SERVER</title>");//タイトルバー表示

client.write("THIS IS KOUSAKU WEB SITE");//表示テキスト
client.write("<br/>");//改行

client.write("YOUR IP ADDRESS: "+client.ip());//IPアドレス表示
client.write("<br/>");//改行

//リンク画像表示(インターネット上のリンク先)
client.write("<img src=\"http://3.bp.blogspot.com/_7uyXRm_coS4/SPRtCNVY1gI/AAAAAAAAATk/UR4Tl5ytviA/s400/network.png\">");
client.write("<br/>");//改行

//リンクページへ移動する
client.write("<a href=\"http://kousaku-kousaku.blogspot.com\">GO TO: KOUSAKU BLOG PAGE<a>");
client.write("<br/>");//改行

//カウンタ機能
val++;
client.write("COUNTER: "+val);//カウンタ表示
client.write("\n\n");//空白行
}
client.stop();//クライアントとの接続を停止
}
}
}


上記のサーバ用のプログラムを起動し、クライアント用コンピュータ上でブラウザ(IE、Safari、FireFoxなど)で指定したIPアドレスとポート番号を入力してアクセスしてください。
例えば、「192.168.3.3」がサーバのIPアドレスであれば、「http://192.168.3.3:12345」をブラウザ上で入力して下さい。

HTTPリクエスト、HTTPレスポンスについては、「Arduino Ethernet Shield」を参照してください。



独自ドメインが使えて基本使用料0円レンタルサーバー





[目次:Processing関係]  [HOMEへ戻る]  [目次:Arduino関係]