image

Buenas,

today already we will create an application that allows us to control the Lance missiles using Kinect gestures. For this I have thought of the following controls

  • The right hand controls the direction of the Lance missiles. You can go to the right, left, up or down.
  • The left hand controls the firing of the missile, shoot is raise your hand above the head.
  • If both hands are below the waist stop movements of the Lance missile

On this basis, and taking advantage of Visual controls of "Microsoft.Samples.Kinect.WpfViewers" I created a WPF application with the following code in the main window

 

   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: }

It is important to note that this window has almost nothing interesting logic only starts the sensors of the Kinect and the Lance missiles and then subscribe to the skeleton update notifications.

In this notification (line 54), it validates that the tracking of the skeleton is correct and then we use a class KinectRocketGestures that is what makes a little magic between Kinect and the Lance missiles.

This class code is as follows

   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: }

And that’s it! A bit of validation of the right hand and left hand positions and have control of the Lance missiles using Kinect.

Now I’m going fast to the MadridDotNet event and in the next post I put a video and the example of the application code.

 

Saludos @ La Finca

El Bruno

image image image

One response to “[#KINECTSDK] Kinect Missile Launcher (IV): Using the Rocket Launcher with Kinect”

  1. […] [#KINECTSDK] Kinect Missile Launcher (IV): Using the Rocket Launcher with Kinect […]

    Like

Leave a comment

Discover more from El Bruno

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

Continue reading