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 }