KOSAKA LABORATORY->Tips

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

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

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

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

wiiリモコン 赤外線カメラ その3

 次にWiiリモコンの赤外線カメラを用いた応用プログラミングを行っていきます。先のプログラムでは赤外線の検出の有無を判断しました。
 今回は、検出した赤外線の座標を取得し画面に表示させるプログラムを追加します。
1.ピクチャボックスの追加
1.フォームにピクチャボックスを張り付けてください。

2.貼り付けたpictureBox1をプロパティのザイズを「200,200」に設定する。
2.ボタンの追加
1.フォームにボタンを2つ張り付けてください。

2.貼り付けたbutton1のプロパティのTextを「接続」に、button1のプロパティのTextを「切断」に設定する。


3.ボタンイベントの追加
1.接続をボタンをダブルクリックし、以下のプログラムを追加する。
        //接続ボタンが押されたら
        private void button1_Click(object sender, EventArgs e) {
           this.wm.Connect();                                        //Wiimoteの接続
           this.wm.WiimoteChanged += wm_WiimoteChanged;              //イベント関数の登録
           this.wm.SetReportType(InputReport.IRExtensionAccel, true);//レポートタイプの設定
        }
2.切断をボタンをダブルクリックし、以下のプログラムを追加する。
        //切断ボタンが押されたら
        private void button2_Click(object sender, EventArgs e) {
           this.wm.Disconnect();                                     //Wiimote切断
        }
4.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 {

        Wiimote wm = new Wiimote();                                   //Wiimoteの宣言
        
        public Form1) {
                        
            InitializeComponent();
            //他スレッドからのコントロール呼び出し許可
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        //接続ボタンが押されたら
        private void button1_Click(object sender, EventArgs e) {
           this.wm.Connect();                                        //Wiimoteの接続
           this.wm.WiimoteChanged += wm_WiimoteChanged;              //イベント関数の登録
           this.wm.SetReportType(InputReport.IRExtensionAccel, true);//レポートタイプの設定

        }

        //切断ボタンが押されたら
        private void button2_Click(object sender, EventArgs e) {
           this.wm.Disconnect();                                     //Wiimote切断
        }

      //Wiiリモコンの値が変化したときに呼ばれる関数
      void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args){
         WiimoteState ws = args.WiimoteState;                //WiimoteStateの値を取得 
         DrawForms(ws);            ////フォーム描写関数へ
      }

        //フォーム描写関数
        public void DrawForms(WiimoteState ws) {
            Graphics g = this.pictureBox1.CreateGraphics();//グラフィックスを取得

            g.Clear(Color.Black);//画面を黒色にクリア


            //もし赤外線を1つ発見したら
            if (ws.IRState.IRSensors[0].Found) {
            //赤色でマーカを描写
                g.FillEllipse( Brushes.Red ,
                               ws.IRState.IRSensors[0].Position.X * 200 ,
                               ws.IRState.IRSensors[0].Position.Y * 200 , 10 , 10 );
            }

            //もし赤外線を2つ発見したら
            if (ws.IRState.IRSensors[1].Found) {
            //青色でマーカを描写
                g.FillEllipse( Brushes.Blue ,
                               ws.IRState.IRSensors[1].Position.X * 200 ,
                               ws.IRState.IRSensors[1].Position.Y * 200 , 10 , 10 );
            }

            //もし赤外線を3つ発見したら
            if (ws.IRState.IRSensors[2].Found) {
            //黄色でマーカを描写
                g.FillEllipse( Brushes.Yellow ,
                               ws.IRState.IRSensors[2].Position.X * 200 ,
                               ws.IRState.IRSensors[2].Position.Y * 200 , 10 , 10 );
            }

            //もし赤外線を4つ発見したら
            if (ws.IRState.IRSensors[3].Found) {
            //緑色でマーカを描写
                g.FillEllipse( Brushes.Green ,
                               ws.IRState.IRSensors[3].Position.X * 200 ,
                               ws.IRState.IRSensors[3].Position.Y * 200 , 10 , 10 );
            }

            g.Dispose();//グラフィックスの解放

        }

    }
}
実行

1.WiiRemoteを接続してください。

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


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


3.WiiリモコンをWiiセンサーバーに向けてください。

 赤外線が検出されると図のようにマーカ点が表示さます。
 マーカの動きが激しすぎる場合は、Wiiとセンサーバーとの距離を2m~3mまで離してください。距離が長いほど安定した動きを行うことができます。

※センサーバーがない場合は、赤外線が発生するもの(太陽、ロウソクの火、テレビのリモコン、携帯電話の赤外線通信 など)に向けてください。

 

 赤外線の光源が1つ発見されると下図のように赤マーカが表示される。

 赤外線の光源が2つ発見されると下図のように赤マーカ、青マーカが表示される。

終了する場合は

 終了する場合は、切断ボタンを押してから終了させてください。

解説

 Wiiリモコンの赤外線カメラの値を取得して、赤外線を発見したら画面に描写しています。

複数の赤外線が見つからない場合は、日中(太陽に向けるなど)に窓の外に向けると複数の赤外線を検出できると思います。赤外線の発光機に近づけすぎず、1~2mほど離すことにより安定した動作を行うことができます。

      ws.IRState.IRSensors[0].Position.X 
赤外線のX座標の位置を0.0~1.0の値を出力します。
本プログラムでは、その値にpictureBoxの横幅の200を掛けて出力しています。

      ws.IRState.IRSensors[0].Position.Y 
赤外線のY座標の位置を0.0~1.0の値を出力します。
本プログラムでは、その値にpictureBoxの縦幅の200を掛けて出力しています。