KOSAKA LABORATORY->Tips

wiiリモコン 赤外線カメラ その4 「Wiiリモコンでマウス作成1」

 前回[その1][その2][その3]まで赤外線カメラの情報を取得するプログラムを作成してきました。 今回は、赤外線カメラを用いたマウスプログラムを作成します。赤外線を認識しマウスカーソルを移動させます。
1.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の宣言
        
        System.Drawing.Point ScreenSize;                              //画面サイズを格納
        
        public Form1() {
                        
            InitializeComponent();
            
            this.ScreenSize.X = Screen.PrimaryScreen.Bounds.Width;    //画面ザイズの横幅を取得
            this.ScreenSize.Y = Screen.PrimaryScreen.Bounds.Height;   //画面ザイズの縦幅を取得
                        
            //他スレッドからのコントロール呼び出し許可
            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 );

                //赤外線座標(0.0~1.0)を画面サイズと掛け合わせる
                int px = (int)(ws.IRState.IRSensors[0].Position.X * this.ScreenSize.X);
                int py = (int)(ws.IRState.IRSensors[0].Position.Y * this.ScreenSize.Y);

                //マウスカーソルを変更
                System.Windows.Forms.Cursor.Position = new System.Drawing.Point(px, py);
        
            }

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

        }

    }
}
実行

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

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


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


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

 赤外線が検出されると図のように赤い点が表示され、マウスカーソルが移動します。赤外線を検出している間にマウスカーソルを動かそうとしても思い通りに動きません。

 マウスカーソルの動きが激しすぎる場合は、Wiiとセンサーバーとの距離を2m~3mまで離してください。距離が長いほど安定した動きを行うことができます。

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

 


終了する場合は

 終了する場合は、赤外線を検出しないようにすると、マウスの制御が戻ります。切断ボタンを押してから終了させてください。

解説

 Wiiリモコンの赤外線カメラの値を取得して、マウスカーソルの座標を制御しています。
 Windowsの画面サイズ(縦横)を取得して、その値に赤外線検出の座標を掛け合わせて制御を行っています。

            this.ScreenSize.X = Screen.PrimaryScreen.Bounds.Width;    //画面ザイズの横幅を取得
            this.ScreenSize.Y = Screen.PrimaryScreen.Bounds.Height;   //画面ザイズの縦幅を取得
Windowsの画面の解像度(サイズ)を取得します。
それぞれの環境によって異なりますが、以下のような値を返すと思います。
横幅 x 高幅
 800 x  600
1024 x  768
1280 x 1024
1680 x 1050

                //赤外線座標(0.0~1.0)を画面サイズと掛け合わせる
                int px = (int)(ws.IRState.IRSensors[0].Position.X * this.ScreenSize.X);
                int py = (int)(ws.IRState.IRSensors[0].Position.Y * this.ScreenSize.Y);
取得した赤外線座標と画面解像度を掛け合わせ、マウス座標とします。
 たとえば赤外線カメラで取得した座標が(0.6,0.3)の時、画面解像度800X600の時は(480,180)を返します。また、画面解像度1680X1050の時は(1080,315)を返します。赤外線カメラの座標と画面解像度と割合の計算です。

                //マウスカーソルを変更
                System.Windows.Forms.Cursor.Position = new System.Drawing.Point(px, py);
マウスカーソルを設定します。
引数に指定した座標にマウスカーソルがセットされます。


 思ったより簡単にマウスを制御できたかと思います。WiimoteLibとC#を組み合わせることで複雑なプログラムを組むことなくマウスが制御できます。
 しかし、これでマウスプログラムは完成ではありません。実行して感じたかと思いますが、横移動ですが、Wiiリモコンと反対の動きをマウスカーソルが動いたかと思います。これは赤外線カメラの画像を元にしていますので、実際の動作と反対の動きをします。また、一番重要なマウスクリックに関してもも実装する必要があります。