読者です 読者をやめる 読者になる 読者になる

Natural Software

KinectなどのDepthセンサーを中心に活動しています

OpenNI で KINECT のチルトモーターを動かす( C# ) #openni_ac

Kinect

このエントリはOpenNI Advent Calendar 2011 : ATNDの12月16日分です
Advent Calendarでの、僕の全プロジェクトはこちらです

OpenNIからKINECTを操作できないこととして、チルトモーターと音声方向の認識がありました。
しかし、OpenNIの内部APIを読んで、Windowsでチルトモーターを操作することに成功した方がいました。

今回は、これをC#からやってみることにします。ただし、非公式なやり方ですので、これによってKINECTが壊れたりしても責任は持てません
といっても、引数が結構やっかいだったので、ネイティブC++のクラス→C++/CLIのクラス→C#という順で呼び出しています。

コード

やってることは、同じで何層かに分かれてるくらいですね

// TiltMotorCLI.h

#pragma once

#include <XnUSB.h>

using namespace System;

namespace OpenNI {
    // ネイティブC++クラス
    class NTiltMotor
    {
    public: 

        NTiltMotor()
        {
            XnUInt32 nCount = 0;

            xnUSBInit();
            xnUSBEnumerateDevices( VID_MICROSOFT, PID_NUI_MOTOR, &pastrDevicePaths, &nCount );
            xnUSBOpenDeviceByPath( *pastrDevicePaths, &dev );
        }

        ~NTiltMotor()
        {
            xnUSBCloseDevice( dev );
            xnUSBFreeDevicesList( pastrDevicePaths );
            xnUSBShutdown();
        }

        void SetAngle( UInt16 angle )
        {
            XnUChar empty[1];
            xnUSBSendControl( dev, XN_USB_CONTROL_TYPE_VENDOR, 0x31,angle * 2, 0, empty, 0, 0 );
        }


    private:
        
        static const UInt32 VID_MICROSOFT = 0x45e;
        static const UInt32 PID_NUI_MOTOR = 0x02b0;

        XN_USB_DEV_HANDLE dev;
        const XnUSBConnectionString* pastrDevicePaths;
    };

    // C++/CLIラッパー
    public ref class TiltMotor
    {
    public:

        TiltMotor()
        {
            motor = new NTiltMotor();
        }

        !TiltMotor()
        {
            delete motor;
        }

        ~TiltMotor()
        {
            this->!TiltMotor();
        }

        void SetAngle( UInt16 angle )
        {
            motor->SetAngle( angle );
        }

    private:

        NTiltMotor* motor;
    };
}
using System;
using OpenNI;

namespace TiltMotorWPF
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        TiltMotor motor;

        public MainWindow()
        {
            InitializeComponent();

            motor = new TiltMotor();
            motor.SetAngle( 20 );
        }
    }
}