[#KINECTSDK] Kinect Missile Launcher (II): Moviendo el lanza misiles

image

Buenas.

En el post de ayer explicaba como trabajar con un dispositivo HID. Hoy veremos como trabajar con el mismo, enviando información al device.

Lo primero que tenemos que hacer es decidir que biblioteca utilizaremos para trabajar con un dispositivo HID. En mi caso utilizaré una que funciona bastante bien, creada por Florian Leitner-Fischer, y que se puede descargar desde aquí.

En el post del link anterior, Florian explica las bases necesarias sobre como funciona su creación. En este post haremos lo siguiente:

  • Conectarnos al dispositivo
  • Validar la conexión
  • Enviar un mensaje para mover el lanza misiles USB

Para esto seguimos los siguientes pasos

1. Crear una aplicación de Consola

2. Agregar una referencia a la biblioteca USBHIDDRIVER

image

3. Cambiamos la configuración para que la aplicación sea X86, en lugar de AnyCPU

4. Ya tenemos lista nuestra aplicación

Lo siguiente es determinar el VendorId y el ProductId de nuestra aplicación. Si bien lo vimos en el post anterior, las siguientes líneas de código nos muestran todos los dispositivos HID que tengamos conectados

   1: var getAllDevices = new USBHIDDRIVER.USBInterface("_");

   2: getAllDevices.Connect();

   3: var devices = getAllDevices.getDeviceList();

   4: foreach (var device in devices)

   5: {

   6:     Console.WriteLine("device: " + device);

   7: }

Cuando ejecutamos la aplicación, vemos este output en la consola de Windows

device: \\?\hid#vid_413c&pid_3012#7&39484631&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

device: \\?\hid#vid_0a81&pid_ff01#7&b08aa68&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

Asumiendo que nuestro dispositivo es el segundo, los valores quedarían así:

  • VendorId = vid_0a81
  • ProductId = pid_ff01

Si queremos por ejemplo mover el lanzamisiles hacia abajo, tenemos que pasar un array de bytes con 2 elementos, zero y dos. El código quedaría de la siguiente forma:

   1: var usb = new USBHIDDRIVER.USBInterface(@"vid_0a81", @"pid_ff01");

   2: usb.Connect();

   3: var startCMD = new byte[2] {0, 2};

   4: // move down

   5: usb.UsbDevice.writeDataSimple(startCMD);

Ahora bien, si te has bajado la biblioteca de Florian, verás que la funcion writeDataSimple() no existe. Esto es porque Florian agrega un proceso de doble validación para enviar siempre arrays “limpios” a los dispositivos USB.

Yo soy una persona que vive al límite y como no le tengo miedo al BSOD, cree la siguiente función para enviar mensajes al dispositivo.

   1: public bool writeDataSimple(byte[] bDataToWrite)

   2: {

   3:     var success = false;

   4:     if (getConnectionState())

   5:     {

   6:         try

   7:         {

   8:             var myOutputReport = new OutputReport();

   9:             success = myOutputReport.Write(bDataToWrite, myUSB.HidHandle);

  10:         }

  11:         catch (AccessViolationException ex)

  12:         {

  13:             success = false;

  14:         }

  15:     }

  16:     return success;

  17: }

La función anterior evita validaciones sobre el buffer a enviar al dispositivo y le envía directamente el array de bytes. En bastantes ocasiones esto nos puede retornar un false o lanzar una excepción no manejada, pero si ya sabemos que el lanza misiles funciona con un buffer de 2 bytes, pues lo tenemos más fácil.

Ahora bien, para conocer esta información he vuelto a utilizar la herramienta SimpleHIDWrite. La misma cuando se selecciona un dispositivo nos muestra la cantidad de elementos que tiene que tener el array de entrada.

image

En mi caso, y sabiendo que eran 2 los bytes a poner en el buffer de escritura, pues comencé a probar con el método de prueba/error y llegué a los siguientes valores:

  • 00, 00. Stop
  • 00, 01. Down
  • 00, 02. Up
  • 00, 04. Giro anti horario
  • 00, 08. Giro horario
  • 00, 10. Dispara misiles

Con estos datos ya tengo casi todo para comenzar. Pero claro, en el camino me encuentro con que en CodePlex hay un proyecto que ya me da interacción con el lanza misiles, con el WiiMote, etc. Pero claro, no funciona a la primera y no tengo lugar para escribir el porqué. Pero tienen una implementación de una clase Rocket, que la verdad es que está muy bien.

Así que he reemplazado el componente que se utiliza para la conexión con el HID, he hecho un poco de refactoring y me ha quedado una clase con la siguiente estructura.

image

Ahora solo queda un poco de trabajo con KinectSDK y listo !!!

 

Referencias:

 

 

Saludos @ Home

El Bruno

image image image
Advertisement

3 comments

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: