Lesson3 プチロボをC#言語で動かす(2)



3-1 ウィンドウのボタンの代わりにJoyStickのボタンで動かしてみる

前回に作ったプロジェクトを引き続き使いまわします。必要ならばプロジェクトの入っているフォルダごと圧縮してバックアップしておくと、いじり壊したときに簡単に復活できますので、たまに行うと良いでしょう。
JoyStickからの入力はDirectXを用いますので、これがインストールされていると仮定します。インストールしていない人は急いでインストールしてください。

  1. 右上にあるソリューションエクスプローラの参照設定を右クリックし「参照の追加」をクリックします。


    すると以下のようなウィンドウが出てきます。



    .NETのタブが選択されているのを確認し、Microsoft.DirectXを探し、ダブルクリックします。再度ソリューションエクスプローラの参照設定を右クリックし「参照の追加」をクリックし、同様にMicrosoft.DirectX.DirectInputを追加します。これらはJoyStickの入力のために必要です。

  2. C#でこのDirectXを用いたDirectInputを簡単に使えるようにするDLL(Dynamic Link Library)があるので次のファイルをダウンロードして、puchiRS232Cフォルダの中のpuchiRS232Cフォルダ(Form1.csが入っているフォルダ)に入れます。

    ┌bin┼
    ┌─puchiRS232C─┼obj┼
    ├Properties┼
    ├Form1.cs
    ├Form1.Designer.cs
    ├Form1.resx
    JoyStickWrapper.dll
    puchipuchiRS232C┼puchiRS232C.sln
    └puchiRS232C.suo


    上記と同様に「参照の追加」ウィンドウを表示させ、「参照」タブを選びJoyStickWrapper.dllのフォルダを探し、その中にあるJoyStickWrapper.dllを選択し「OK」を押す。

    Wrapperとは、ソフトウェア的なプロトコル変換機みたいなものと思ってください。たとえて言えば「二又のコンセントがある。そこへ三叉のコネクターを挿そうとしたら失敗(当たり前)した。そこで、二又のコンセントに三叉変換機をつけて対応した。この三叉変換機こそがラッパー」、ということです。ここでは、C++用のDirectInputのDLLが直接使えないのでそれを変換して使えるようにするDLLのことを言っています。



    すると以下のように参照設定にDLLが挿入されます。


  3. DirectXを使うので、以下のコードをForm1.csの上部にあるusingの羅列の一番下に挿入します。
    using ManagedDX;                     // JoyStickWrapper.dllのため
    using Microsoft.DirectX.DirectInput; // JoystickStateを読むため
    
  4. 次のコードをコンストラクタの上に挿入します。
            JoyStickWrapper joyStick; // ManagedDirectXでDirectInputからジョイスティックを使うラッパー
            int[] position = new int[9];
    
  5. コンストラクタを以下のように変更します。
            public Form1()
            {
                InitializeComponent();
                joyStick = new JoyStickWrapper(this);
                if (joyStick.init())
                {
                    timer1.Enabled = true; // ジョイスティック監視タイマーON
                }
                for (int i = 0; i < 9; i++) position[i] = 0;
            }
    
  6. タイマーを用いて一定期間ごとにJoyStickの状態を見るようにします。 タブをデザインに変えて、ツールボックスからTimerを選び、デザインウィンドウに落とします。timer1が下にできるので、それをダブルクリックすると以下のようなイベントに対応する空のメソッドができます。
            private void timer1_Tick(object sender, EventArgs e)
            {
    
            }
    
    これに必要なコードを書き入れると以下のようになります。
            private void timer1_Tick(object sender, EventArgs e)
            {
                JoystickState state = joyStick.update();
                //Capture Buttons.
                byte[] buttons = state.GetButtons();
                for (int i = 0; i < buttons.Length; i++)
                {
                    if (buttons[i] != 0)
                    {
                        if (i == 3) {
                            for (int j = 0; j < 9; j++)
                            {
                                position[j] = 1;
                                servo(j, position[j] % 220);
                            }
                        }
                        else servo(i, position[i] % 220);
                        position[i] += 10;
                    }
                }
            }
    
    ボタンが押されたらばそのボタンに対応するサーボモーターが10ステップずつ移動するようになっています。また、3番のボタンを押すとゼロの位置に戻ります。(3番のモーターは10ステップ毎に動かせないということです)