PaxPowerGlove
This page is also available in English. Please visit here.
Oculus Riftの仮想空間内の物体に干渉したい。
ということで、ファミコンの特殊コントローラであるところのパックス社製パワーグローブにモーションセンサを埋め込み、Arduino→PCと接続して、Unityの仮想空間内の手のモデルの動きを制御してみようと思います。
完成動画はこちら。
パワーグローブは本来、2つの超音波振動子から時間差で超音波を発生させてモーションキャプチャを実現しています。
発想は革新的・野心的で素晴らしいのですが、精度がいまいちなので、今回はその機構は使わず、新たにモーションセンサを搭載しています。
本来の機構で残っているのは曲げセンサのみです。
次の順序で進めます。
- パワーグローブの指の曲げ具合の取得
- モーションセンサによる手のモーションの取得とUnity空間のオブジェクトの回転制御
- 1と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スケッチ
PowerGlove.ino
|
抵抗値は個体毎に違うと思うので、適宜調整してください。
手順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本体のリセットボタンを押してみてください。
お疲れ様でした。
【参考】Unity用C#スクリプト(上記PaxPowerGlove.zipに含まれています)
ControlHandByPaxPowerGloveAndMPU9150InUnity.cs
|
手順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本分用意する。
ソフトウェアの準備
執筆中。
|
手順7.5と6の統合
執筆中。
備考
SerialPort.ReadLine()をUpdate()内で使うと遅延が大きく、使い物になりません。
今回はMSDNの記述にしたがって、別スレッドでReadLine()しています。
パワーグローブを入手できない場合
市販の手袋にスイッチサイエンスの曲げセンサSEN-08606を接着するとよいかもしれません。