やってみよう!Kinectアプリ開発 - 第8回 初期化・終了処理

2012-07-20 18:01

アプリケーションの修正

今回のアプリケーションの修正は以下を行います。

  • Kinectセンサー接続時にKinectの初期化処理を行う
  • Kinectセンサー解除時にKinectの終了処理を行う
  • 画面にKinectセンサーの状態をテキストで表示する

以降で、これら実現するための修正を説明します。

  • 状態表示用のTextBlockを追加
    第3回の[コントロールの追加]で紹介した手順で、TextBlockを追加してください。ただしプロパティは以下のようにしてください。
    • Margin, Textをリセット (画面左上に配置・初期文字列なし)
    • Nameを"textBlockStatus"に設定
  • アプリケーション終了時のイベントハンドラの追加
    第3回の[イベントハンドラの設定]で紹介した手順で、イベントハンドラを設定します。 ただし、今回設定するのは、"Closed"イベントに"WindowClosed"というメソッドです。
  • usingディレクティブの追加
    "Microsoft.Kinect.Toolkit"と、そのイベントハンドラで使う"System.ComponentModel"を追加します。
  • フィールドの追加
    KinectSensorChooserを追加します。
  • 初期化処理の分離
    これまで、WindowLoadedで行っていた初期化処理をアプリケーションの初期化を行うWindowLoadedと、Kinectの初期化を行うInitKinectSensorの2つに分離します。

    • アプリケーションの初期化:
      画像の読み込みといったアプリケーション自身の初期化はWindowLoadedに残します。また、今回追加するKinectSensorChooserの初期化やイベントハンドラの登録もアプリケーションの初期化として、WindowLoadedに追加します。 なお、これまでWindowLoadedの先頭で「Kinectセンサーの取得(エラー処理など省略版)」としていた部分は不要になるので削除します。
    • Kinectセンサーの初期化:
      新しくInitKinectSensorメソッドを追加し、WindowLoadedに書いていたKinectセンサーの初期化処理をInitKinectSensorメソッドに移動します。ただしKinectセンサーの開始処理("kinect.Start();")KinectSensorChooserが行ってくれますので削除します。
  • Kinectセンサーの終了処理
    Kinectセンサー接続解除時の終了処理として、ハンドラメソッドの登録解除を行います。
  • KinectSensorChooserのイベントハンドラ
    ここでは、KinectChangedEventとPropertyChangedEventの2つのイベントを使います(ハンドラメソッドはそれぞれKinectChangedとKinectPropChangedとしています)。

    • KinectChanged
      Kinectの挿抜イベントに対して呼び出され、接続解除の場合(args.OldSensorがnullでない場合)そのKinectの終了処理を行い、接続された場合(args.NewSensorがnullでない場合)そのKinectの初期化処理を行います。
    • KinectPropChanged
      プロパティの変更時に呼び出されます。ここでは変更されるプロパティが"Status"の場合、画面に表示する状態を更新します。
  • アプリケーションの終了処理
    アプリケーションの終了処理ではKinectSensorChooserを停止します。 (ハンドラメソッドの登録解除などした方がいいのか悪いのか、 SDKのドキュメントにもはっきり書いていないようなので不明なのですが、 サンプルでも省略されていますし、特に動作上問題ないようなので省略しています)
  • 音声認識エンジンの終了処理
    お気づきの方もいると思いますが、実は前回のサンプルでは音声認識エンジンの終了処理も省略していました。 SpeechRecognitionEngineもIDisposableを実装したクラスですので、 第3回で簡単に説明した通り終了処理としてDisposeメソッドの呼び出しが必要です。

実行

修正は以上です。メニューから[デバッグ(D)]-[デバッグ実行(S)]を選択し、実行してみましょう。今回は以下の手順を試してみてください。

  1. Kinectを接続せずにアプリケーションを起動する ⇒ "NoAvailableSensors"と表示される。
  2. 1の後KinectセンサーのACアダプタを外した状態でPCに接続する ⇒ "SensorNotPowered"と表示される。
  3. 2の後KinectセンサーのACアダプタを接続する ⇒ "SensorStarted"と表示され、アプリケーションが処理を開始する。
  4. 3の後Kinectセンサーを抜く ⇒ "NoAvailableSensors"に戻る。
  5. 4の後再度Kinectセンサーを接続する ⇒ 再度"SensorStarted"と表示され、アプリケーションが処理を再開する。

また、他にも「USBの帯域不足」(USBポートにUSBハブを介してたくさんのUSB機器が接続されている状態)や「他のアプリで使用中」(接続されているKinectセンサーがすでに他のアプリケーションで使用されている状態)といった状態もあります。興味のある方はこちらも試してみてください。

KinectSensorManager

Kinect for Windows SDKのShapeGameのサンプルアプリケーションでは、 KinectSensorChooserをさらにラップした、 KinectSensorManagerを使っています。 余裕のある方はこちらも試してみてください。 このサンプルアプリケーションでは、Kinectセンサーの接続状態も画面に表示されます。

ElevationAngle

最後にKinectセンサーの上下方向の角度の取得・変更を紹介します。 Kinect for Windows SDKでは、KinectSensorオブジェクトのElevationAngleプロパティを参照・編集することで、角度の取得・変更ができます。

なおSDKのドキュメントによると「Kinectセンサーのモーターは継続した操作を想定していないので、モーターの操作をできるだけ少なくすること」と注意書きがありますので注意しましょう。(目安としては、「1秒間に操作は1回まで」、また「15回操作した後は最低20秒間をあけること」とあります)

アプリケーションの修正

それでは、この機能をアプリケーションに実装しましょう。 今回は以下の2つを実装します。

  • アプリケーションの起動時にKinectセンサーが接続されていた場合角度を0に戻す
  • アプリケーションの終了時にKinectセンサーが接続されていた場合角度を最小にする(つまり下を向きます)

コードの修正は、アプリケーションの初期化処理と終了処理に、それぞれElevationAngleプロパティに値を設定するだけです。

  • アプリケーション起動時
  • アプリケーション終了時

実行

修正は以上です。メニューから[デバッグ(D)]-[デバッグ実行(S)]を選択し、実行してみましょう。こちらは以下の手順を試してみてください。

  • アプリケーションを起動し、Kinectセンサーを接続したままアプリケーションを終了させる ⇒ Kinectセンサーが下を向く
  • この状態で、Kinectセンサーを接続したまま、再度アプリケーションを起動する ⇒ Kinectセンサーが正面を向く

※ なお、Kinectセンサーを元の角度に戻したい場合は、以下の手順で戻せます。

  1. Kinectセンサーを接続したままアプリケーションを起動します(角度が0になる)
  2. この状態でKinectセンサーをUSBポートから外します
  3. アプリケーションを終了させます

まとめ

今回は、SDKドキュメントのインストール、KinectSensorChooserによる初期化・終了処理、Kinectセンサーの角度の参照・設定を紹介しました。次回からはポーズ・モーションの利用方法を説明します。

商標について

Kinect、Microsoft、Visual C#、Visual Studio、Windowsは、米国Microsoft Corporationの米国およびその他の国における登録商標または商標です。

2件の質問スレッド
  • ElevationAngleについて mkama 2012-08-29 07:47 >なおSDKのドキュメントによると「Kinectセンサーのモーターは継続した操作を想定していないので、モーターの操作をできるだけ少なくすること」と注意書きがありますので注意しましょう。(目安としては、「1秒間に操作は1回まで」、また「15回操作した後は最低20秒間をあけること」とあります)

    知らなかったので、目一杯モーターを動かしていました。(~_~;)

    モータ保護用の判定ルーチンを作ってみました。
    一つ質問ですが、20秒間隔が空けば、15回の回数制限は解除して良いのですか?

    // モータ保護用の判定ルーチン
    private const int MaxElevation = 15;
    private DateTime dtNextElevation = DateTime.Now;
    private int intCountElevation = MaxElevation;

    private bool CheckElevation()
    {
      if (intCountElevation-- <= 0)
      {
        intCountElevation = MaxElevation;
        dtNextElevation = DateTime.Now.AddSeconds(20);
        return false;
      }
      else
      {
        TimeSpan ts = DateTime.Now - dtNextElevation;
        if (ts.TotalSeconds >= 1)
        {
          if (ts.TotalSeconds >= 20)
            intCountElevation = MaxElevation;

          dtNextElevation = DateTime.Now;
          return true;
        }
        else
          return false;
      }
    }
    1件のコメント
    • kinection.jp管理人 すみません、我々もSDKのドキュメントに書いてあること以上には情報を持っていません。
      ただ、ドキュメントを読む限りでは、20秒間隔が空けば、15回の回数制限は解除して良いと思われます。
      2012-08-29 16:02
  • ヘルプについて kazgb 2012-08-16 22:56
    さぁがんばろう!
    と思って始めたらいきなり挫折しそうになりました><。

    ヘルプ・・・普通に表示された方いらっしゃるでしょうか?
    もしかしたら自分だけかもしれませんが、表示されずに悩んでしまいました。

    一応解決しましたが、同じ人が”もし”いたら役立つかもしれないのでカキカキ。

    色々見比べてみたところ、
    自分の環境には
    「Microsoft ヘルプ ビューアー 1.1」がインストールされていないようでした。
    いや・・・もしかしたら別の理由があったかもしれませんが、
    上記を解消するためにサービスパック1を適用しました。

    http://www.microsoft.com/ja-jp/download/details.aspx?id=23691

    こんなのあったんですね。。。皆さん適応されているのでしょうか?
    (もしかしたら自分が見落としているだけかもしれませんが・・・)
    1件のコメント
    • kinection.jp管理人 ご指摘ありがとうございます。連載第2回では「Service Pack などの更新プログラムを適用しておきましょう」とさらっと書いただけでした。追記しておきます。 2012-08-29 15:53

ジグソープレミアムレビュー

  • やってみようKinect(キネクト)アプリ開発 - ラボクルー集まれ!