このエントリは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 ); } } }