// Copyright (C) 2015 Marek Kowalski (M.Kowalski@ire.pw.edu.pl), Jacek Naruniec (J.Naruniec@ire.pw.edu.pl) // License: MIT Software License See LICENSE.txt for the full license. // If you use this software in your research, then please use the following citation: // Kowalski, M.; Naruniec, J.; Daniluk, M.: "LiveScan3D: A Fast and Inexpensive 3D Data // Acquisition System for Multiple Kinect v2 Sensors". in 3D Vision (3DV), 2015 International Conference on, Lyon, France, 2015 // @INPROCEEDINGS{Kowalski15, // author={Kowalski, M. and Naruniec, J. and Daniluk, M.}, // booktitle={3D Vision (3DV), 2015 International Conference on}, // title={LiveScan3D: A Fast and Inexpensive 3D Data Acquisition System for Multiple Kinect v2 Sensors}, // year={2015}, // } using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Net.Sockets; using System.Net; using System.ComponentModel; namespace KinectServer { public delegate void SocketListChangedHandler(List list); public class KinectServer { Socket oServerSocket; bool bServerRunning = false; KinectSettings oSettings; object oClientSocketLock = new object(); object oFrameRequestLock = new object(); List lClientSockets = new List(); public event SocketListChangedHandler eSocketListChanged; public int nClientCount { get { int nClients; lock (oClientSocketLock) { nClients = lClientSockets.Count; } return nClients; } } public List lCameraPoses { get { List cameraPoses = new List(); lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { cameraPoses.Add(lClientSockets[i].oCameraPose); } } return cameraPoses; } } public List lWorldTransforms { get { List worldTransforms = new List(); lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { worldTransforms.Add(lClientSockets[i].oWorldTransform); } } return worldTransforms; } set { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lClientSockets[i].oWorldTransform = value[i]; } } } } public bool bAllCalibrated { get { bool allCalibrated = true; lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { if (!lClientSockets[i].bCalibrated) { allCalibrated = false; break; } } } return allCalibrated; } } public KinectServer(KinectSettings settings) { this.oSettings = settings; } private void SocketListChanged() { if (eSocketListChanged != null) { eSocketListChanged(lClientSockets); } } public void StartServer() { if (!bServerRunning) { oServerSocket = new Socket(SocketType.Stream, ProtocolType.Tcp); oServerSocket.Blocking = false; IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 48001); oServerSocket.Bind(endPoint); oServerSocket.Listen(10); bServerRunning = true; Thread listeningThread = new Thread(this.ListeningWorker); listeningThread.Start(); Thread receivingThread = new Thread(this.ReceivingWorker); receivingThread.Start(); } } public void StopServer() { if (bServerRunning) { bServerRunning = false; oServerSocket.Close(); lock (oClientSocketLock) lClientSockets.Clear(); } } public void CaptureSynchronizedFrame() { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) lClientSockets[i].CaptureFrame(); } //Wait till frames captured bool allGathered = false; while (!allGathered) { allGathered = true; lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { if (!lClientSockets[i].bFrameCaptured) { allGathered = false; break; } } } } } public void Calibrate() { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lClientSockets[i].Calibrate(); } } } public void SendSettings() { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lClientSockets[i].SendSettings(oSettings); } } } public void SendCalibrationData() { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lClientSockets[i].SendCalibrationData(); } } } public void GetStoredFrame(List> lFramesRGB, List> lFramesVerts) { lFramesRGB.Clear(); lFramesVerts.Clear(); lock (oFrameRequestLock) { //Request frames lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) lClientSockets[i].RequestStoredFrame(); } //Wait till frames received bool allGathered = false; while (!allGathered) { allGathered = true; lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { if (!lClientSockets[i].bStoredFrameReceived) { allGathered = false; break; } } } } //Store received frames lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lFramesRGB.Add(new List(lClientSockets[i].lFrameRGB)); lFramesVerts.Add(new List(lClientSockets[i].lFrameVerts)); } } } } public void GetLatestFrame(List> lFramesRGB, List> lFramesVerts) { lFramesRGB.Clear(); lFramesVerts.Clear(); lock (oFrameRequestLock) { //Request frames lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) lClientSockets[i].RequestLastFrame(); } //Wait till frames received bool allGathered = false; while (!allGathered) { allGathered = true; lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { if (!lClientSockets[i].bLatestFrameReceived) { allGathered = false; break; } } } } //Store received frames lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lFramesRGB.Add(new List(lClientSockets[i].lFrameRGB)); lFramesVerts.Add(new List(lClientSockets[i].lFrameVerts)); } } } } public void ClearStoredFrames() { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { lClientSockets[i].ClearStoredFrames(); } } } private void ListeningWorker() { while (bServerRunning) { try { Socket newClient = oServerSocket.Accept(); //we do not want to add new clients while a frame is being requested lock (oFrameRequestLock) { lock (oClientSocketLock) { lClientSockets.Add(new KinectSocket(newClient)); lClientSockets[lClientSockets.Count - 1].SendSettings(oSettings); lClientSockets[lClientSockets.Count - 1].eChanged += new SocketChangedHandler(SocketListChanged); if (eSocketListChanged != null) { eSocketListChanged(lClientSockets); } } } } catch (SocketException) { } System.Threading.Thread.Sleep(100); } if (eSocketListChanged != null) { eSocketListChanged(lClientSockets); } } private void ReceivingWorker() { System.Timers.Timer checkConnectionTimer = new System.Timers.Timer(); checkConnectionTimer.Interval = 1000; checkConnectionTimer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e) { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { if (!lClientSockets[i].SocketConnected()) { lClientSockets.RemoveAt(i); if (eSocketListChanged != null) { eSocketListChanged(lClientSockets); } continue; } } } }; checkConnectionTimer.Start(); while (bServerRunning) { lock (oClientSocketLock) { for (int i = 0; i < lClientSockets.Count; i++) { byte[] buffer = lClientSockets[i].Receive(1); while (buffer.Length != 0) { if (buffer[0] == 0) { lClientSockets[i].bFrameCaptured = true; } else if (buffer[0] == 1) { lClientSockets[i].ReceiveCalibrationData(); } //stored frame else if (buffer[0] == 2) { lClientSockets[i].ReceiveFrame(); lClientSockets[i].bStoredFrameReceived = true; } //last frame else if (buffer[0] == 3) { lClientSockets[i].ReceiveFrame(); lClientSockets[i].bLatestFrameReceived = true; } buffer = lClientSockets[i].Receive(1); } } } Thread.Sleep(10); } checkConnectionTimer.Stop(); } } }