// 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<KinectSocket> list);
public class KinectServer
{
Socket oServerSocket;
bool bServerRunning = false;
KinectSettings oSettings;
object oClientSocketLock = new object();
object oFrameRequestLock = new object();
List<KinectSocket> lClientSockets = new List<KinectSocket>();
public event SocketListChangedHandler eSocketListChanged;
public int nClientCount
{
get
{
int nClients;
lock (oClientSocketLock)
{
nClients = lClientSockets.Count;
}
return nClients;
}
}
public List<AffineTransform> lCameraPoses
{
get
{
List<AffineTransform> cameraPoses = new List<AffineTransform>();
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
cameraPoses.Add(lClientSockets[i].oCameraPose);
}
}
return cameraPoses;
}
set
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].oCameraPose = value[i];
}
}
}
}
public List<AffineTransform> lWorldTransforms
{
get
{
List<AffineTransform> worldTransforms = new List<AffineTransform>();
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 bool GetStoredFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts)
{
bool bNoMoreStoredFrames;
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;
bNoMoreStoredFrames = false;
while (!allGathered)
{
allGathered = true;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].bStoredFrameReceived)
{
allGathered = false;
break;
}
if (lClientSockets[i].bNoMoreStoredFrames)
bNoMoreStoredFrames = true;
}
}
}
//Store received frames
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lFramesRGB.Add(new List<byte>(lClientSockets[i].lFrameRGB));
lFramesVerts.Add(new List<Single>(lClientSockets[i].lFrameVerts));
}
}
}
if (bNoMoreStoredFrames)
return false;
else
return true;
}
public void GetLatestFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts, List<List<Body>> lFramesBody)
{
lFramesRGB.Clear();
lFramesVerts.Clear();
lFramesBody.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<byte>(lClientSockets[i].lFrameRGB));
lFramesVerts.Add(new List<Single>(lClientSockets[i].lFrameVerts));
lFramesBody.Add(new List<Body>(lClientSockets[i].lBodies));
}
}
}
}
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();
}
}
}