PaxPowerGlove
This page is also available in English. Please visit here.

Oculus Riftの仮想空間内の物体に干渉したい。
ということで、ファミコンの特殊コントローラであるところのパックス社製パワーグローブにモーションセンサを埋め込み、Arduino→PCと接続して、Unityの仮想空間内の手のモデルの動きを制御してみようと思います。
完成動画はこちら。
パワーグローブは本来、2つの超音波振動子から時間差で超音波を発生させてモーションキャプチャを実現しています。
発想は革新的・野心的で素晴らしいのですが、精度がいまいちなので、今回はその機構は使わず、新たにモーションセンサを搭載しています。
本来の機構で残っているのは曲げセンサのみです。

次の順序で進めます。
- パワーグローブの指の曲げ具合の取得
- モーションセンサによる手のモーションの取得とUnity空間のオブジェクトの回転制御
- と2の統合
- 近接無線通信モジュールXBeeによる無線通信
- 3と4の統合
- 振動モーターによるハプティック(触覚フィードバック)の実現
- 5と6の統合
必要なもの
ハードウェア
項目 | 説明 |
---|---|
Arduino | 比較的小型で安価で簡単に使えるマイコンボード。無線化してパワーグローブに内蔵する場合は、後述するArduino Fioが小型かつXBeeが直接接続でき、便利です。 |
パックスパワーグローブ | 通常はファミコンに接続して使う手袋型コントローラ。 |
抵抗(100kΩ)* 4 | 何でも良いです。今回は千石電子通商で購入しました。 |
MPU-9150 9軸センサモジュール | InvenSense社の3軸加速度+3軸ジャイロ+3軸コンパスのモーションセンサチップMPU-9150が載ったモジュール。 |
ソフトウェア
項目 | 説明 |
---|---|
Arduino IDE | Arduino用の開発環境。オフィシャルサイトからダウンロードしてください。 |
Unity | マルチプラットフォーム対応のゲームエンジン。簡単に3D(or 2D)ゲームを作ることが出来る。オフィシャルサイトからダウンロードしてください。 |
I2C Device Library | I2Cデバイス用C++ライブラリとMPU-6050(兼MPU-9150)のArduinoサンプルスケッチ。 https://github.com/jrowberg/i2cdevlib を開き、右側の「Download ZIP」をクリックしてダウンロードしてください。 |
Unity用C#スクリプト | 上記サンプルスケッチの出力をUnity側で受け取ってGameObjectを制御するC#スクリプト。本ページ下部からダウンロードしてください。 |
手順1.パワーグローブの指の曲げ具合の取得
まずは指の曲げ具合を取得してみます。
ハードウェアの準備
- 手の甲の部分のカバーと基板をプラスドライバーで外す。
- はんだ吸い取り線などを使って、配線を基板から外す。
- 手の甲側の4本の赤い線をすべてGNDに接続する。
- Arduinoの5V→抵抗→手の甲側のセンサ線と繋ぎ、抵抗とセンサの間にArduinoのアナログ入力を接続する。後述のスケッチでのセンサ線とアナログ入力の関係は次の通り。
指 | センサ線 | アナログ入力端子 |
---|---|---|
親指 | 青 | A0 |
人差し指 | 黒 | A1 |
中指 | 白 | A2 |
薬指 | 茶 | A3 |
小指 | センサなし | - |

曲げセンサは出力が抵抗値なので、同程度の抵抗器を使うことで抵抗値→電圧値に変換してArduinoに入力する、という回路が上記です。
ソフトウェアの準備
- 下記ArduinoスケッチをArduinoに書き込む。
動作確認
- シリアルモニタを開く。
- 指を曲げ伸ばしして数値が変化することを確認する。
Arduinoスケッチ
int fingers[4];
void setup() {
Serial.begin(9600);
}
void loop() {
int i;
fingers[0] = constrain(map(analogRead(A0), 678, 760, 0, 10), 0, 10) * 10;
fingers[1] = constrain(map(analogRead(A1), 835, 935, 0, 10), 0, 10) * 10;
fingers[2] = constrain(map(analogRead(A2), 770, 905, 0, 10), 0, 10) * 10;
fingers[3] = constrain(map(analogRead(A3), 750, 910, 0, 10), 0, 10) * 10;
for (i = 0; i < 4; i++) {
Serial.print("finger");
Serial.print(i);
Serial.print(":");
Serial.print(fingers[i]);
Serial.print("\t");
}
Serial.println();
delay(200);
}
抵抗値は個体毎に違うと思うので、適宜調整してください。
手順2.モーションセンサによる手のモーションの取得とUnity空間のオブジェクトの回転制御
パワーグローブはグローブ側から超音波を発射し、テレビの周りに設置した超音波センサで検知することによって、位置を検出しています。
今回はこの機構をInvenSense社のモーションセンサチップMPU-9150で置き換えて、手全体のモーションを取得し、Unity空間のオブジェクトの回転を制御してみます。
詳細は、モーションセンサをご覧ください。
手順3.1と2の統合
さあついに、上記1と2を統合します。
ハードウェアの準備
- 1と2の回路を組み合わせる。Arduino Unoであれば、ピンが重複しないので、単に組み合わせるだけです。
ソフトウェアの準備(1):Arduinoスケッチ
- モーションセンサで作成したArduinoスケッチを次のように修正する。
- 286-297行目を次のように変更する。 (unidiff風に書いています。要するに先頭が-の行を削除して、先頭が+の行を追加するだけです。)
#ifdef OUTPUT_READABLE_QUATERNION
// display quaternion values in easy matrix form: w x y z
mpu.dmpGetQuaternion(&q, fifoBuffer);
Serial.print("quat\t");
Serial.print(q.w);
Serial.print("\t");
Serial.print(q.x);
Serial.print("\t");
Serial.print(q.y);
Serial.print("\t");
- Serial.println(q.z);
+ Serial.print(q.z);
+ Serial.print("\t");
+ Serial.print(constrain(map(analogRead(A0), 678, 760, 0, 10), 0, 10) * 6);
+ Serial.print("\t");
+ Serial.print(constrain(map(analogRead(A1), 835, 935, 0, 10), 0, 10) * 6);
+ Serial.print("\t");
+ Serial.print(constrain(map(analogRead(A2), 770, 905, 0, 10), 0, 10) * 6);
+ Serial.print("\t");
+ Serial.println(constrain(map(analogRead(A3), 750, 910, 0, 10), 0, 10) * 6);
#endif
ソフトウェアの準備(2):Unityプロジェクト
- 下記ファイルをダウンロードし、解凍して、PaxPowerGlove.unityを開く。
動作確認
- Unityの再生ボタンを押す。
- パワーグローブを傾けてみて、手のモデルが動けば成功! 動かない場合は、Arduino本体のリセットボタンを押してみてください。
お疲れ様でした。 :)
手順4.XBeeによる無線通信

上記までは有線で通信をしていましたが、近接無線通信モジュールXBeeを使って無線通信をしてみます。
詳細は XBee をご覧ください。
手順5.3と4の統合
さあついに、上記3と4を統合します。
- 先ほどのArduinoスケッチを次のように修正する。 (unidiff風に書いています。要するに先頭が-の行を削除して、先頭が+の行を追加するだけです。)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
- TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
+ TWBR = 12; // for Arduino Fio
// initialize serial communication
// (115200 chosen because it is required for Teapot Demo output, but it's
// really up to you depending on your project)
- Serial.begin(115200);
+ Serial.begin(57600); // for Arduino Fio
手順6.振動モーターによるハプティック(触覚フィードバック)の実現
ハードウェアの準備
右図のような回路を5本分用意する。

ソフトウェアの準備
執筆中。
char c = Serial.read();
if (c != -1) {
c -= '0';
for (int i = 0; i < 5; i++) {
if ((c & 0b00010000) != 0) {
digitalWrite(3, HIGH);
}
if ((c & 0b00001000) != 0) {
digitalWrite(4, HIGH);
}
if ((c & 0b00000100) != 0) {
digitalWrite(5, HIGH);
}
delay(7);
digitalWrite(3, LOW);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
if ((c & 0b00000010) != 0) {
digitalWrite(6, HIGH);
}
if ((c & 0b00000001) != 0) {
digitalWrite(7, HIGH);
}
delay(7);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
}
}
手順7.5と6の統合
執筆中。
備考
SerialPort.ReadLine()をUpdate()内で使うと遅延が大きく、使い物になりません。
今回はMSDNの記述にしたがって、別スレッドでReadLine()しています。
パワーグローブを入手できない場合
市販の手袋にスイッチサイエンスの曲げセンサSEN-08606を接着するとよいかもしれません。
プロトタイプからの変遷


