KOSAKA LABORATORY->Tips

 このBlogの一部が書籍になりました。
書籍:「WiiRemoteプログラミング」
著者:白井暁彦・小坂崇之・木村秀敬・くるくる研究室
表紙:タナカユカリ
発売:2009年7月25日 好評発売中
詳細:こちらから

内容:WiiRemoteを利用したインタラクティブ技術のプログラミング学習書

 話題の家庭用ゲーム機「Wii」の特徴的なコントローラーである「WiiRemote」をPCで使うプログラミングが注目されている。高性能な加速度センサーや赤外線センサーを持ち、Bluetooth接続が可能で、プログラミング可能なデバイスを、個人レベルで自作したり入手したりすることはできなかった。WiiRemoteの登場とともにそれが安価で手軽に入手可能になり、多くの人々が興味を持っている。

 本書は、WiiRemoteの応用に興味があるプログラミング初学者向けに、WiiRemoteをPCから扱うためのプログラミングを解説する。ハードウェア寄りのゲームプログラミング入門書として、ステップバイステップでソースコードを解説する。具体的なサンプルを開発しながら、インタラクション技術を独習できる。言語はC/C++、C#およびActionScript 3、Processingなどをサポート。

Wiiリモコン 複数台の制御

 WiimoteLIBにはWiiリモコンを複数台認識することができます。Bluetoothの限界である7台まで接続することが可能らしいですが、研究室に5台しかWiiリモコンがありませんので確認はできていません。
 今回はWiiリモコンを複数台接続する方法について解説します。
1.複数台をBluetoothで認識させます。
ここではWiiリモコンを2台接続する方法について解説します。

 

このとき、どれがどのWiiなのか分からなくなるので、下図のようにWiiに番号を振って登録すると便利です。
2.ファームにLabelを図のように4つ追加します。

 

3.Wiiリモコン複数台認識プログラム
Form1.csに以下の部分を追加する。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;                                         //WimoteLibの宣言


namespace WiimoteLib_Sample {


    public partial class Form1 : Form {
        public int Conect = 0;                            //接続数を格納
        public WiimoteCollection wc = null;               //WiimoteCollectionの宣言


        public Form1() {
            InitializeComponent();

            //他スレッドからのコントロール呼び出し許可
            Control.CheckForIllegalCrossThreadCalls = false;

            this.wc = new WiimoteLib.WiimoteCollection(); //WiimoteCollectionを生成

        }

        //接続ボタンが押されたら
        private void button1_Click(object sender, EventArgs e) {

            this.Conect = 0;                              //接続数を初期化
            this.wc.FindAllWiimotes();                    //Wiiリモコン登録を調べる

      //label1にPCに登録されているWiiリモコン数を表示
            this.label1.Text = "Wiiリモコン登録台数:" + this.wc.Count;

                foreach (WiimoteLib.Wiimote wm in wc) {
                    //Wiiリモコンが見つかった回数だけ繰り返す
                    try {
                        wm.Connect();                                          //接続
                        wm.SetReportType(WiimoteLib.InputReport.IRAccel, true);//レポートタイプの設定
 
                        switch (this.Conect) {
                            case 0:
                                wm.WiimoteChanged += wm_WiimoteChanged_01;     //イベント設定
                                break;
                            case 1:
                                wm.WiimoteChanged += wm_WiimoteChanged_02;     //イベント設定
                                break;
                        }

                        this.Conect++;//カウント++
                    } catch {
                    }
                }

      //label2に接続されたWiiリモコン数を表示
            this.label2.Text = "PC Wiiリモコン接続:" + this.Conect;

        }

        //切断ボタンが押されたら
        private void button2_Click(object sender, EventArgs e) {
            if (this.wc != null) {
                foreach (WiimoteLib.Wiimote wm in wc) {
                    //Wiiリモコンが見つかった回数だけ繰り返す
                    wm.Disconnect();                                           //接続を切る
                }
                this.wc.Clear();                                              //クリア

            }
        }

        //Wiiリモコンの値が変化したときに呼ばれる関数
        void wm_WiimoteChanged_01(object sender, WiimoteChangedEventArgs args){
           //WiimoteStageの値を取得
           WiimoteState ws = args.WiimoteState;
            this.label3.Text = "Wiimote01:" + ws.ButtonState.A;
        }

        //Wiiリモコンの値が変化したときに呼ばれる関数
        void wm_WiimoteChanged_02(object sender, WiimoteChangedEventArgs args) {
           //WiimoteStageの値を取得
            WiimoteState ws = args.WiimoteState;
            this.label4.Text = "Wiimote02:" + ws.ButtonState.A;
        }

    }
}
実行

1.WiiRemoteを接続してください。
 接続する台数分、接続してください。

 

2.F5キーを押して実行してください。

 

3.接続ボタンをクリックしてください。
  ※もしエラーが発生する場合はWiiRemoteが正しく接続されているか確認してください。

 

4.二つのWiiリモコンのAボタンを押したり話したりしてください。
 ラベルにtrue, falseの値で変化します。

 

解説

 Wiiリモコン2台を認識させて、Aボタンの値を取得しています。

 

 

        public WiimoteCollection wc = null;               //WiimoteCollectionの宣言
 複数台を認識させるときは、WiimoteCollectionを用います。

 

 

            this.wc = new WiimoteLib.WiimoteCollection(); //WiimoteCollectionを生成
 WiimoteCollectionの生成を行います。

 

 

            this.wc.FindAllWiimotes();                    //Wiiリモコン登録を調べる
 Wiiリモコンの登録数を調べます。
 Bluetoothマネージャに登録されているWiiリモコンの数を取得します。接続された数とは別ものです。下図であれば2台登録されています。

 

 

                foreach (WiimoteLib.Wiimote wm in wc) {
                    //Wiiリモコンが見つかった回数だけ繰り返す
                    try {
                        wm.Connect();                                          //接続
                        //レポートタイプの設定
                        wm.SetReportType(WiimoteLib.InputReport.IRAccel, true);
 
                        switch (this.Conect) {
                            case 0:
                                wm.WiimoteChanged += wm_WiimoteChanged_01;     //イベント設定
                                break;
                            case 1:
                                wm.WiimoteChanged += wm_WiimoteChanged_02;     //イベント設定
                                break;
                        }

                        this.Conect++;//カウント++
                    } catch {
                    }
                }
 wc に登録されたWiimoteの数だけ繰り返します。wmにWiiリモコンの値が入ります。
switch文で
  1台目のWiiリモコンであれば、wm_WiimoteChanged_01イベントを追加します。
  2台目のWiiリモコンであれば、wm_WiimoteChanged_02イベントを追加します。

 

 また、foreach文を用いずfor文を用いた場合は以下のようになります。
            
           for (int i = 0; i < wc.Count; i++) {
                try {
                    wc[i].Connect();    //接続
                    //レポートタイプの設定
                    wc[i].SetReportType(WiimoteLib.InputReport.IRAccel, true);

                    switch (this.Conect) {
                        case 0:
                            wm[i].WiimoteChanged += wm_WiimoteChanged_01; //イベント設定
                            break;
                        case 1:
                            wm[i].WiimoteChanged += wm_WiimoteChanged_02; //イベント設定
                            break;
                    }

                    this.Conect++;//カウント++
                } catch {
                }
            }

 

 

 
                this.wc.Clear();                                              //クリア
 終了するときは、からなずクリアしてください。
クリアせずに、連続してFindAllWiimotesを実行するとWiiリモコンの登録数が増えていきます。

 

 

 このプログラムで重要なのは、BleutoothのWiiリモコン登録数と、Wiiリモコン接続数です。 BleutoothのWiiリモコン登録数は、Wiiリモコンの接続数とは別物です。接続数ではなくてBleutoothマネージャに登録された数です。 Wiiリモコン接続数は、Bleutoothマネージャで接続された数です。
 そして接続数に関係なくBleutoothマネージに登録された順番にWiimoteCollectionに登録されます。下図はWii01を非接続、Wii02を接続にして実行した結果です。接続の有無に関わらずBleutoothマネージャに登録された順番に取得しています。

 

 

 今回、Wiiリモコンを複数台制御するプログラムを作成しました。7台まで取得することができますので、体の部位につけることで簡易モーションキャプチャなどの応用も考えられると思います。アイディア次第でいろいろ楽しめます。