image

Buenas,

hoy ya vamos a crear una aplicación que nos permita controlar el lanza misiles utilizando gestos de Kinect. Para esto he pensado en los siguientes controles

  • La mano derecha controla la dirección del lanza misiles. Puede ir a la derecha, a la izquierda, arriba o abajo.
  • La mano izquierda controla el disparo del misil, la forma de disparar es levantar la mano encima de la cabeza.
  • Si ambos manos están por debajo de la cintura se detienen los movimientos del lanza misiles

Con esta base, y aprovechando los controles visuales de “Microsoft.Samples.Kinect.WpfViewers” he creado una aplicación WPF con el siguiente código en la ventana principal

   1: using System.Linq;

   2: using System.Windows;

   3: using Microsoft.Kinect;

   4:  

   5: namespace ElBruno.Rocket.Ui

   6: {

   7:     public partial class MainWindow

   8:     {

   9:         private KinectSensor _sensor;

  10:         private Rocket _rocket;

  11:         public MainWindow()

  12:         {

  13:             InitializeComponent();

  14:             Loaded += MainWindowLoaded;

  15:         }

  16:  

  17:         private void MainWindowLoaded(object sender, RoutedEventArgs e)

  18:         {

  19:             InitRocket();

  20:             InitKinectSensor();

  21:         }

  22:  

  23:         private void InitRocket()

  24:         {

  25:             _rocket = new Rocket(@"vid_0a81", @"pid_ff01");

  26:             _rocket.Connect();

  27:         }

  28:  

  29:         private void InitKinectSensor()

  30:         {

  31:             // validate

  32:             if (KinectSensor.KinectSensors.Count == 0) return;

  33:  

  34:             // init Kinect

  35:             var parameters = new TransformSmoothParameters

  36:                                  {

  37:                                      Smoothing = 0.75f,

  38:                                      Correction = 0.1f,

  39:                                      Prediction = 0.0f,

  40:                                      JitterRadius = 0.05f,

  41:                                      MaxDeviationRadius = 0.08f

  42:                                  };

  43:  

  44:             _sensor = KinectSensor.KinectSensors[0];

  45:             _sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);

  46:             _sensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);

  47:             _sensor.SkeletonStream.Enable(parameters);

  48:             _sensor.Start();

  49:             colorViewer.Kinect = _sensor;

  50:             skeletonViewer.Kinect = _sensor;

  51:             _sensor.SkeletonFrameReady += SensorSkeletonFrameReady;

  52:         }

  53:  

  54:         private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)

  55:         {

  56:             Skeleton[] skeletons = null;

  57:             using (var frame = e.OpenSkeletonFrame())

  58:             {

  59:                 if (frame != null)

  60:                 {

  61:                     skeletons = new Skeleton[frame.SkeletonArrayLength];

  62:                     frame.CopySkeletonDataTo(skeletons);

  63:                 }

  64:             }

  65:  

  66:             if (skeletons == null) return;

  67:  

  68:             foreach (var kinectRocketGestures in (

  69:                 from skeleton in skeletons

  70:                 where skeleton.TrackingState == SkeletonTrackingState.Tracked

  71:                 let headJoint = skeleton.Joints[JointType.Head]

  72:                 where headJoint.TrackingState != JointTrackingState.NotTracked

  73:                 select skeleton).Select(skeleton => new KinectRocketGestures(skeleton, _rocket)))

  74:             {

  75:                 var gesture = kinectRocketGestures.ValidateGestures();

  76:                 textBlockInformation.Text = gesture;

  77:             }

  78:         }

  79:     }

  80: }

Es importante tener en cuenta que esta ventana no posee casi nada de lógica interesante, solo inicia los sensores del Kinect y del lanza misiles y luego se suscribe a las notificaciones de actualización de skeleton.
En esta notificación (línea 54), se valida que el tracking del skeleton sea correcto y luego utilizamos una clase KinectRocketGestures que es la que hace un poco la magia entre Kinect y el lanza misiles.
El código de esta clase es el siguiente
   1: using Microsoft.Kinect;

   2:  

   3: namespace ElBruno.Rocket.Ui

   4: {

   5:     class KinectRocketGestures

   6:     {

   7:         private readonly Skeleton _skeleton;

   8:         private readonly Rocket _rocket;

   9:  

  10:         public KinectRocketGestures(Skeleton skeleton, Rocket rocket)

  11:         {

  12:             _skeleton = skeleton;

  13:             _rocket = rocket;

  14:         }

  15:  

  16:         public string ValidateGestures()

  17:         {

  18:             var gesture = @"Not defined";

  19:             // STOP

  20:             // Right hand and Left hand hanging at the side

  21:             if (_skeleton.Joints[JointType.HandRight].Position.Y < _skeleton.Joints[JointType.HipCenter].Position.Y &&

  22:                 _skeleton.Joints[JointType.HandLeft].Position.Y < _skeleton.Joints[JointType.HipCenter].Position.Y)

  23:             {

  24:                 _rocket.StopAll();

  25:                 _rocket.StopFiring();

  26:                 _rocket.StopMovements();

  27:                 gesture = @"STOP";

  28:                 return gesture;

  29:             }

  30:  

  31:             // FIRE

  32:             if (_skeleton.Joints[JointType.HandLeft].Position.Y > _skeleton.Joints[JointType.Head].Position.Y)

  33:             {

  34:                 gesture = @"FIRE";

  35:                 _rocket.FireOnce();

  36:             }

  37:  

  38:             // MOVE RIGHT OR LEFT

  39:             // Right hand in front of right shoulder

  40:             // Right hand below shoulder height but above hip height

  41:             if (

  42:                 (_skeleton.Joints[JointType.HandRight].Position.Z < _skeleton.Joints[JointType.ElbowRight].Position.Z &&

  43:                 _skeleton.Joints[JointType.HandLeft].Position.Y < _skeleton.Joints[JointType.HipCenter].Position.Y)

  44:                 &&

  45:                 (_skeleton.Joints[JointType.HandRight].Position.Y < _skeleton.Joints[JointType.Head].Position.Y &&

  46:                 _skeleton.Joints[JointType.HandRight].Position.Y > _skeleton.Joints[JointType.HipCenter].Position.Y)

  47:                 )

  48:             {

  49:                 // Right hand right of right shoulder

  50:                 if (_skeleton.Joints[JointType.HandRight].Position.X > _skeleton.Joints[JointType.ShoulderRight].Position.X)

  51:                 {

  52:                     gesture = @"MOVE RIGHT";

  53:                     _rocket.MoveRight();

  54:                 }

  55:                 // Right hand left of left Shoulder

  56:                 if (_skeleton.Joints[JointType.HandRight].Position.X < _skeleton.Joints[JointType.ShoulderLeft].Position.X)

  57:                 {

  58:                     gesture = @"MOVE LEFT";

  59:                     _rocket.MoveLeft();

  60:                 }

  61:             }

  62:  

  63:             // MOVE UP OR DOWN

  64:             // Right hand in front of body with Left hand hanging at the side

  65:             // Right hand between shoulders

  66:             if (

  67:                 (_skeleton.Joints[JointType.HandRight].Position.Z < _skeleton.Joints[JointType.ShoulderCenter].Position.Z &&

  68:                 _skeleton.Joints[JointType.HandLeft].Position.Y < _skeleton.Joints[JointType.HipCenter].Position.Y)

  69:                 &&

  70:                 (_skeleton.Joints[JointType.HandRight].Position.X < _skeleton.Joints[JointType.ShoulderRight].Position.X &&

  71:                 _skeleton.Joints[JointType.HandRight].Position.X > _skeleton.Joints[JointType.ShoulderLeft].Position.X)

  72:                 )

  73:             {

  74:                 // Right hand above the shoulders

  75:                 if (_skeleton.Joints[JointType.HandRight].Position.Y > _skeleton.Joints[JointType.ShoulderCenter].Position.Y)

  76:                 {

  77:                     gesture = @"MOVE UP";

  78:                     _rocket.MoveUp();

  79:                 }

  80:                 // Right hand below the chest/gut

  81:                 if (_skeleton.Joints[JointType.HandRight].Position.Y < _skeleton.Joints[JointType.Spine].Position.Y)

  82:                 {

  83:                     gesture = @"MOVE DOWN";

  84:                     _rocket.MoveDown();

  85:                 }

  86:                 return gesture;

  87:             }

  88:         }

  89:     }

  90: }

 

Y listo! Un poco de validación de posiciones de la mano derecha y la mano izquierda y ya tenemos el control del lanza misiles utilizando Kinect.

Ahora me voy rápido al evento de MadridDotNet y en el próximo post pongo un video y el código de ejemplo de la aplicación.

Saludos @ La Finca

El Bruno

image image image

One response to “[#KINECTSDK] Kinect Missile Launcher (IV): Controlando el lanza misiles con Kinect”

  1. […] Asp.Net en IIS[TFS2010] HowTo: Configure more than one Build Controller on the same computer[#KINECTSDK] Kinect Missile Launcher (IV): Controlando el lanza misiles con KinectFiltrar datos dentro de un DataTable[# KINECTSDK] HowTo: Paint a skeleton[Spanish] Visual Studio […]

    Like

Leave a reply to [#KINECTSDK] Kinect Missile Launcher (V): Video y codigo fuente | El Bruno Cancel reply

Discover more from El Bruno

Subscribe now to keep reading and get access to the full archive.

Continue reading