/ WPF App / FirstWPFApp / MainWindow.xaml.cs
MainWindow.xaml.cs
  1  using System;
  2  using System.Collections.Generic;
  3  using System.Linq;
  4  using System.Text;
  5  using System.Threading.Tasks;
  6  using System.Windows;
  7  using System.Windows.Controls;
  8  using System.Windows.Data;
  9  using System.Windows.Documents;
 10  using System.Windows.Input;
 11  using System.Windows.Media;
 12  using System.Windows.Media.Imaging;
 13  using System.Windows.Navigation;
 14  using System.Windows.Shapes;
 15  
 16  //for Kinect (duh)
 17  using Microsoft.Kinect;
 18  //for serial com with Arduino
 19  using System.IO.Ports;
 20  //for timer usage
 21  using System.Timers;
 22  
 23  namespace FirstWPFApp
 24  {
 25      /// <summary>
 26      /// Interaction logic for MainWindow.xaml
 27      /// </summary>
 28      public partial class MainWindow : Window
 29      {
 30          private KinectSensor sensor;
 31          private BodyFrameReader bodyReader;
 32          private SerialPort sp = new SerialPort();
 33          private int framesRead;
 34  
 35          // Array for the bodies, index for the currently tracked body, flag to assess if a body is currently tracked
 36          private Body[] bodies = null;
 37          private int bodyIndex;
 38          private bool bodyTracked = false;
 39  
 40          public MainWindow()
 41          {
 42              InitializeComponent();
 43              this.Loaded += OnLoaded;
 44          }
 45  
 46          void OnLoaded(object sender, RoutedEventArgs e)
 47          {
 48              this.sensor = KinectSensor.GetDefault();
 49              this.sensor.Open();
 50  
 51              this.bodyReader = this.sensor.BodyFrameSource.OpenReader();
 52              this.bodyReader.FrameArrived += OnFrameArrived;
 53  
 54              //Arduino serial com set up
 55              try
 56              {
 57                  sp.PortName = "COM3";
 58                  sp.BaudRate = 9600;
 59                  sp.Open();
 60  
 61                  framesRead = 0;
 62  
 63                  Timer serialTimer = new Timer(50);
 64                  serialTimer.Elapsed += new ElapsedEventHandler(ResetSerial);
 65                  serialTimer.Enabled = true;
 66                  serialTimer.Start();
 67  
 68              }
 69              catch (Exception)
 70              {
 71                  MessageBox.Show("Please give a valid port number or check your connection");
 72              }
 73          }
 74  
 75          //Reset the serial out buffer every 50 ms
 76          private void ResetSerial(object source, ElapsedEventArgs e)
 77          {
 78              sp.DiscardOutBuffer();
 79          }
 80  
 81          void OnFrameArrived(object sender, BodyFrameArrivedEventArgs e)
 82          {
 83              bool dataReceived = false;
 84  
 85              using (BodyFrame bodyFrame = e.FrameReference.AcquireFrame())
 86              {
 87                  if (bodyFrame != null)
 88                  {
 89                      if (this.bodies == null)
 90                      {
 91                          this.bodies = new Body[bodyFrame.BodyCount];
 92                      }
 93                      bodyFrame.GetAndRefreshBodyData(this.bodies);
 94                      dataReceived = true;
 95                  }
 96              }
 97  
 98              if (dataReceived)
 99              {
100                  Body body = null;
101                  if (this.bodyTracked)
102                  {
103                      if (this.bodies[this.bodyIndex].IsTracked)
104                      {
105                          body = this.bodies[this.bodyIndex];
106                      }
107                      else
108                      {
109                          bodyTracked = false;
110                      }
111                  }
112                  if (!bodyTracked)
113                  {
114                      for (int i = 0; i < this.bodies.Length; ++i)
115                      {
116                          if (this.bodies[i].IsTracked)
117                          {
118                              this.bodyIndex = i;
119                              this.bodyTracked = true;
120                              break;
121                          }
122                      }
123                  }
124  
125                  if (body != null && this.bodyTracked && body.IsTracked)
126                  {
127                      // body is currently being tracked
128                      framesRead++;
129  
130                      //prepare data for output every 10 frames
131                      if (framesRead % 10 == 0)
132                      {
133                          String data = "";
134  
135                          data += trackNeck(body);
136                          data += trackLeftArm(body);
137  
138                          //send data to Arduino
139                          sp.WriteLine(data);
140                      }
141                  }
142              }
143          }
144  
145          //interpret neck movement
146          String trackNeck(Body body)
147          {
148              //string to return angle data
149              String data = "H";
150  
151              Joint head = body.Joints[JointType.Head];
152              Joint neck = body.Joints[JointType.Neck];
153  
154              //Kinect too inaccurate for exact neck angle, so set angle to 1 of 3 set values
155              double dx = head.Position.X - neck.Position.X;
156              double dy = head.Position.Y - neck.Position.Y;
157              double angleRadians = Math.Atan(dy / dx);
158              double angle = angleRadians / Math.PI * 180;
159  
160              if (angle > 0 && angle < 65){
161                  data += "120";
162              }
163              else if(angle < 0 && angle > -65)
164              {
165                  data += "60";
166              }
167              else
168              {
169                  data += "90";
170              }
171  
172              data += "/";
173              return data;
174          }
175  
176          //interpret left arm movement
177          String trackLeftArm(Body body)
178          {
179              //string to return angle data
180              String data = "L";
181  
182              Joint leftShoulder = body.Joints[JointType.ShoulderLeft];
183              Joint leftElbow = body.Joints[JointType.ElbowLeft];
184  
185              double deltaX = leftShoulder.Position.X - leftElbow.Position.X;
186              double deltaY = leftShoulder.Position.Y - leftElbow.Position.Y;
187              double thetaRadians = Math.Atan(deltaX / deltaY);
188              double theta = thetaRadians / Math.PI * 180;
189  
190              //convert theta to more friendly angle
191              double angle;
192              if (theta < 0)
193              {
194                  angle = -1 * theta;
195              }
196              else
197              {
198                  angle = ((1.0 - (theta / 90.0)) * 90) + 90;
199              }
200  
201              data += Math.Truncate(angle);
202              data += "/";
203              return data;
204          }
205      }
206  }