Added new UI for the Temporal Sync Feature, made the software more robust including:

-Settings window can only be opened once
    -When the client can't open a device, it tries multiple times
    -Recording bins are now saved with a unique ID per device, to allow multiple clients to record on the same PC
    -Synchronized & Unsynchronized devices can be both used in one server
    -Included a workaround for a bug in the Azure Kinect SDK regarding exposure (microsoft/Azure-Kinect-Sensor-SDK#1378)
This commit is contained in:
Christopher Remde
2020-10-14 23:21:18 +02:00
parent 2b15ed0f5b
commit 76bf5e9dba
15 changed files with 744 additions and 129 deletions
+154 -16
View File
@@ -22,6 +22,7 @@ using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.ComponentModel;
using System.Windows.Forms;
namespace KinectServer
{
@@ -31,9 +32,15 @@ namespace KinectServer
Socket oServerSocket;
bool bServerRunning = false;
bool waitForSubToStart = false;
bool bWaitForSubToStart = false;
//This lock prevents the user from enabeling/disabling the Temp Sync State while the cameras are in transition to another state.
//When starting the server, all devices are already initialized, as the LiveScanClient can only connect with an initialized device
bool allDevicesInitialized = true;
KinectSettings oSettings;
SettingsForm fSettingsForm;
MainWindowForm fMainWindowForm;
object oClientSocketLock = new object();
object oFrameRequestLock = new object();
@@ -133,6 +140,21 @@ namespace KinectServer
this.oSettings = settings;
}
public void SetSettingsForm(SettingsForm settings)
{
fSettingsForm = settings;
}
public void SetMainWindowForm(MainWindowForm main)
{
fMainWindowForm = main;
}
public SettingsForm GetSettingsForm()
{
return fSettingsForm;
}
private void SocketListChanged()
{
if (eSocketListChanged != null)
@@ -226,6 +248,7 @@ namespace KinectServer
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].SendCalibrationData();
@@ -234,33 +257,115 @@ namespace KinectServer
}
/// <summary>
/// Send temporal Sync Data to all clients
/// Request the device Sync state, so that we know which Device is Master and which are Subordinates before starting them
/// </summary>
public void RequestDeviceSyncState()
{
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].RequestTempSyncState();
}
}
}
/// <summary>
/// When a client has send its Device Sync State, we try to Set the Client Sync State
/// </summary>
public void SendTemporalSyncData()
{
lock (oClientSocketLock)
{
if(lClientSockets.Count > 1 && oSettings.bEnableSync)
{
byte syncOffSetCounter = 1;
int masterCount = 0;
int subordinateCount = 0;
for (int i = 0; i < lClientSockets.Count; i++)
//First we check if we have recieved the Device Sync State of all Devices
//If not, we return and the next client who confirms their state starts this function again
for (int i = 0; i < lClientSockets.Count; i++)
{
if(lClientSockets[i].currentDeviceTempSyncState == KinectSocket.eTempSyncConfig.MASTER)
{
masterCount++;
}
if (lClientSockets[i].currentDeviceTempSyncState == KinectSocket.eTempSyncConfig.SUBORDINATE)
{
subordinateCount++;
}
if (lClientSockets[i].currentDeviceTempSyncState == KinectSocket.eTempSyncConfig.UNKNOWN)
{
return;
}
}
//On a second step we check if we have exactly one master and at least one subordinate
if(masterCount != 1 || subordinateCount < 1)
{
//If not, we show a error message and disable the temporal sync
fMainWindowForm?.SetStatusBarOnTimer("Temporal Sync cables not connected properly", 5000);
fSettingsForm?.ActivateTempSyncEnableButton();
return;
}
allDevicesInitialized = false;
byte syncOffSetCounter = 0;
for (int i = 0; i < lClientSockets.Count; i++)
{
if(lClientSockets[i].currentDeviceTempSyncState == KinectSocket.eTempSyncConfig.SUBORDINATE)
{
lClientSockets[i].SendTemporalSyncStatus(true, syncOffSetCounter);
syncOffSetCounter++;
}
waitForSubToStart = true;
lClientSockets[i].SendTemporalSyncStatus(true, syncOffSetCounter);
}
else
bWaitForSubToStart = true;
}
}
/// <summary>
/// Sets all clients as standalone
/// </summary>
public void DisableTemporalSync()
{
allDevicesInitialized = false;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
for (int i = 0; i < lClientSockets.Count; i++)
lClientSockets[i].SendTemporalSyncStatus(false, 0);
}
}
}
public void ConfirmTemporalSyncDisabled()
{
if (bWaitForSubToStart)
return;
lock (oClientSocketLock)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (lClientSockets[i].currentClientTempSyncState != KinectSocket.eTempSyncConfig.STANDALONE)
{
lClientSockets[i].SendTemporalSyncStatus(false, 0);
return;
}
}
}
allDevicesInitialized = true;
}
/// <summary>
@@ -268,7 +373,7 @@ namespace KinectServer
/// </summary>
public void CheckForMasterStart()
{
if (!oSettings.bEnableSync || !waitForSubToStart)
if (!bWaitForSubToStart)
{
return;
}
@@ -279,23 +384,40 @@ namespace KinectServer
{
for (int i = 0; i < lClientSockets.Count; i++)
{
if (!lClientSockets[i].bSubStarted && lClientSockets[i].currentTempSyncState == KinectSocket.eTempSyncConfig.SUBORDINATE)
if (!lClientSockets[i].bSubStarted && lClientSockets[i].currentClientTempSyncState == KinectSocket.eTempSyncConfig.SUBORDINATE)
{
allSubsStarted = false;
break;
}
}
bWaitForSubToStart = false;
if (allSubsStarted)
{
for (int i = 0; i < lClientSockets.Count; i++)
{
lClientSockets[i].SendMasterInitialize();
if(lClientSockets[i].currentDeviceTempSyncState == KinectSocket.eTempSyncConfig.MASTER)
{
lClientSockets[i].SendMasterInitialize();
return;
}
}
}
}
}
}
/// <summary>
/// Tells the server that it is now ok to start recieving user changes again
/// </summary>
public void MasterSuccessfullyRestarted()
{
allDevicesInitialized = true;
}
public bool GetAllDevicesInitialized()
{
return allDevicesInitialized;
}
public bool GetStoredFrame(List<List<byte>> lFramesRGB, List<List<Single>> lFramesVerts)
@@ -369,6 +491,7 @@ namespace KinectServer
//Wait till frames received
bool allGathered = false;
while (!allGathered)
{
allGathered = true;
@@ -384,6 +507,7 @@ namespace KinectServer
}
}
}
}
//Store received frames
@@ -396,6 +520,7 @@ namespace KinectServer
lFramesBody.Add(new List<Body>(lClientSockets[i].lBodies));
}
}
}
}
@@ -427,6 +552,9 @@ namespace KinectServer
lClientSockets[lClientSockets.Count - 1].SendSettings(oSettings);
lClientSockets[lClientSockets.Count - 1].eChanged += new SocketChangedHandler(SocketListChanged);
lClientSockets[lClientSockets.Count - 1].eSubInitialized += new SubOrdinateInitialized(CheckForMasterStart);
lClientSockets[lClientSockets.Count - 1].eMasterRestart += new MasterRestarted(MasterSuccessfullyRestarted);
lClientSockets[lClientSockets.Count - 1].eSyncJackstate += new RecievedSyncJackState(SendTemporalSyncData);
lClientSockets[lClientSockets.Count - 1].eStandAloneInitialized += new StandAloneInitialized(ConfirmTemporalSyncDisabled);
if (eSocketListChanged != null)
{
@@ -509,6 +637,16 @@ namespace KinectServer
lClientSockets[i].ReceiveTemporalSyncStatus();
}
else if(buffer[0] == 5)
{
lClientSockets[i].RecieveMasterHasRestarted();
}
else if(buffer[0] == 6)
{
lClientSockets[i].RecieveDeviceSyncState();
}
buffer = lClientSockets[i].Receive(1);
}
}
+13 -1
View File
@@ -42,7 +42,11 @@ namespace KinectServer
public bool bMergeScansForSave = true;
public bool bSaveAsBinaryPLY = true;
public bool bEnableSync = false;
public bool bSyncEnabled = false;
public bool bAutoExposureEnabled = true;
public int nExposureStep = -8;
public KinectSettings()
{
@@ -102,6 +106,14 @@ namespace KinectServer
bTemp = BitConverter.GetBytes(iCompressionLevel);
lData.AddRange(bTemp);
if (bAutoExposureEnabled)
lData.Add(1);
else
lData.Add(0);
bTemp = BitConverter.GetBytes(nExposureStep);
lData.AddRange(bTemp);
return lData;
}
}
+90 -8
View File
@@ -18,12 +18,15 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using OpenTK.Graphics;
namespace KinectServer
{
public delegate void SocketChangedHandler();
public delegate void SubOrdinateInitialized();
public delegate void MasterRestarted();
public delegate void RecievedSyncJackState();
public delegate void StandAloneInitialized();
public class KinectSocket
{
@@ -35,11 +38,19 @@ namespace KinectServer
public bool bNoMoreStoredFrames = true;
public bool bCalibrated = false;
public bool bSubStarted = false;
public bool bMasterStarted = false;
public enum eTempSyncConfig { MASTER, SUBORDINATE, STANDALONE, UNKNOWN }
//Shows how the *Device* is configured (Determined only by the Sync-Cables hooked up to the device)
public eTempSyncConfig currentDeviceTempSyncState = eTempSyncConfig.STANDALONE;
//Shows how the Client-Software is configured (This is set by the server)
public eTempSyncConfig currentClientTempSyncState = eTempSyncConfig.STANDALONE;
public enum eTempSyncConfig { MASTER, SUBORDINATE, STANDALONE }
public eTempSyncConfig currentTempSyncState = eTempSyncConfig.STANDALONE;
//The pose of the sensor in the scene (used by the OpenGLWindow to show the sensor)
public AffineTransform oCameraPose = new AffineTransform();
//The transform that maps the vertices in the sensor coordinate system to the world corrdinate system.
public AffineTransform oWorldTransform = new AffineTransform();
@@ -51,6 +62,9 @@ namespace KinectServer
public event SocketChangedHandler eChanged;
public event SubOrdinateInitialized eSubInitialized;
public event MasterRestarted eMasterRestart;
public event RecievedSyncJackState eSyncJackstate;
public event StandAloneInitialized eStandAloneInitialized;
public KinectSocket(Socket clientSocket)
{
@@ -135,7 +149,10 @@ namespace KinectServer
/// <param name="tempSyncOn">Enable/Disable Temporal Sync</param>
/// <param name="syncOffSetMultiplier">Only set when this device should be a subordinate. Should be a unique number in ascending order for each sub</param>
public void SendTemporalSyncStatus(bool tempSyncOn, byte syncOffSetMultiplier)
{
{
bSubStarted = false;
currentClientTempSyncState = eTempSyncConfig.UNKNOWN;
if (tempSyncOn)
{
byte[] data = new byte[2];
@@ -161,6 +178,49 @@ namespace KinectServer
SendByte();
}
/// <summary>
/// Asks the client in which way the Sync-Cables are hooked up to the device
/// </summary>
public void RequestTempSyncState()
{
currentDeviceTempSyncState = eTempSyncConfig.UNKNOWN;
byteToSend[0] = 10;
SendByte();
}
public void RecieveDeviceSyncState()
{
byte tempSyncState;
byte[] buffer = new byte[1024];
while (oSocket.Available == 0)
{
if (!SocketConnected())
return;
}
oSocket.Receive(buffer, 3, SocketFlags.None);
tempSyncState = buffer[0];
if (tempSyncState == 0)
{
currentDeviceTempSyncState = eTempSyncConfig.SUBORDINATE;
}
else if (tempSyncState == 1)
{
currentDeviceTempSyncState = eTempSyncConfig.MASTER;
}
else if (tempSyncState == 2)
{
currentDeviceTempSyncState = eTempSyncConfig.STANDALONE;
}
eSyncJackstate.Invoke();
}
public void ReceiveCalibrationData()
{
bCalibrated = true;
@@ -205,25 +265,36 @@ namespace KinectServer
if (tempSyncState == 0)
{
currentTempSyncState = eTempSyncConfig.SUBORDINATE;
currentClientTempSyncState = eTempSyncConfig.SUBORDINATE;
bSubStarted = true;
bMasterStarted = false;
eSubInitialized?.Invoke();
}
else if(tempSyncState == 1)
{
currentTempSyncState = eTempSyncConfig.MASTER;
currentClientTempSyncState = eTempSyncConfig.MASTER;
bSubStarted = false;
}
else if (tempSyncState == 2)
{
currentTempSyncState = eTempSyncConfig.STANDALONE;
currentClientTempSyncState = eTempSyncConfig.STANDALONE;
bSubStarted = false;
bMasterStarted = false;
eStandAloneInitialized?.Invoke();
}
UpdateSocketState();
}
public void RecieveMasterHasRestarted()
{
bMasterStarted = true;
eMasterRestart?.Invoke();
}
public void ReceiveFrame()
{
lFrameRGB.Clear();
@@ -241,6 +312,9 @@ namespace KinectServer
oSocket.Receive(buffer, 8, SocketFlags.None);
nToRead = BitConverter.ToInt32(buffer, 0);
int iCompressed = BitConverter.ToInt32(buffer, 4);
if (nToRead == -1)
@@ -249,6 +323,14 @@ namespace KinectServer
return;
}
//Sometimes we recieve negative values when the cameras are restarting, I don't know why yet.
//I'm just patching this up for now.s
if (nToRead <= 0)
{
return;
}
buffer = new byte[nToRead];
int nAlreadyRead = 0;
@@ -371,7 +453,7 @@ namespace KinectServer
{
string tempSyncMessage = "";
switch (currentTempSyncState)
switch (currentClientTempSyncState)
{
case eTempSyncConfig.MASTER:
tempSyncMessage = "[MASTER]";
+17 -7
View File
@@ -75,8 +75,6 @@ namespace KinectServer
IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Stream stream = new FileStream("settings.bin", FileMode.Open, FileAccess.Read);
oSettings = (KinectSettings)formatter.Deserialize(stream);
//This always needs to be set to false on startup, as we can only activate it when all Kinects are already connected
oSettings.bEnableSync = false;
stream.Close();
}
catch(Exception)
@@ -127,10 +125,16 @@ namespace KinectServer
//Opens the settings form
private void btSettings_Click(object sender, EventArgs e)
{
SettingsForm form = new SettingsForm();
form.oSettings = oSettings;
form.oServer = oServer;
form.Show();
if(oServer.GetSettingsForm() == null)
{
SettingsForm form = new SettingsForm();
form.oSettings = oSettings;
form.oServer = oServer;
form.Show();
oServer.SetSettingsForm(form);
oServer.SetMainWindowForm(this);
}
}
//Performs recording which is synchronized frame capture.
@@ -265,6 +269,12 @@ namespace KinectServer
while (!worker.CancellationPending)
{
Thread.Sleep(1);
if (!oServer.GetAllDevicesInitialized())
{
continue;
}
oServer.GetLatestFrame(lFramesRGB, lFramesVerts, lFramesBody);
//Update the vertex and color lists that are common between this class and the OpenGLWindow.
@@ -474,7 +484,7 @@ namespace KinectServer
OpenGLWorker.RunWorkerAsync();
}
private void SetStatusBarOnTimer(string message, int milliseconds)
public void SetStatusBarOnTimer(string message, int milliseconds)
{
statusLabel.Text = message;
+119 -45
View File
@@ -33,9 +33,15 @@
this.lbICPIters = new System.Windows.Forms.Label();
this.txtICPIters = new System.Windows.Forms.TextBox();
this.grClient = new System.Windows.Forms.GroupBox();
this.grSync = new System.Windows.Forms.GroupBox();
this.grExposure = new System.Windows.Forms.GroupBox();
this.lbManualExposure = new System.Windows.Forms.Label();
this.chAutoExposureEnabled = new System.Windows.Forms.CheckBox();
this.trManualExposure = new System.Windows.Forms.TrackBar();
this.grTempSync = new System.Windows.Forms.GroupBox();
this.btSyncDisable = new System.Windows.Forms.Button();
this.btSyncEnable = new System.Windows.Forms.Button();
this.lbTempSync = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.chSync = new System.Windows.Forms.CheckBox();
this.grBody = new System.Windows.Forms.GroupBox();
this.chSkeletons = new System.Windows.Forms.CheckBox();
this.chBodyData = new System.Windows.Forms.CheckBox();
@@ -82,9 +88,10 @@
this.rAsciiPly = new System.Windows.Forms.RadioButton();
this.txtRefinIters = new System.Windows.Forms.TextBox();
this.lbOuterIters = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.grClient.SuspendLayout();
this.grSync.SuspendLayout();
this.grExposure.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trManualExposure)).BeginInit();
this.grTempSync.SuspendLayout();
this.grBody.SuspendLayout();
this.grMarkers.SuspendLayout();
this.grBounding.SuspendLayout();
@@ -131,30 +138,108 @@
//
// grClient
//
this.grClient.Controls.Add(this.grSync);
this.grClient.Controls.Add(this.grExposure);
this.grClient.Controls.Add(this.grTempSync);
this.grClient.Controls.Add(this.grBody);
this.grClient.Controls.Add(this.grMarkers);
this.grClient.Controls.Add(this.grBounding);
this.grClient.Controls.Add(this.grFiltering);
this.grClient.Location = new System.Drawing.Point(12, 12);
this.grClient.Name = "grClient";
this.grClient.Size = new System.Drawing.Size(632, 291);
this.grClient.Size = new System.Drawing.Size(632, 408);
this.grClient.TabIndex = 43;
this.grClient.TabStop = false;
this.grClient.Text = "KinectClient settings";
//
// grSync
// grExposure
//
this.grSync.Controls.Add(this.label3);
this.grSync.Controls.Add(this.label1);
this.grSync.Controls.Add(this.chSync);
this.grSync.Location = new System.Drawing.Point(271, 211);
this.grSync.Name = "grSync";
this.grSync.Size = new System.Drawing.Size(355, 80);
this.grSync.TabIndex = 48;
this.grSync.TabStop = false;
this.grSync.Text = "Temporal Sync";
this.grSync.Enter += new System.EventHandler(this.grSync_Enter);
this.grExposure.Controls.Add(this.lbManualExposure);
this.grExposure.Controls.Add(this.chAutoExposureEnabled);
this.grExposure.Controls.Add(this.trManualExposure);
this.grExposure.Location = new System.Drawing.Point(9, 283);
this.grExposure.Name = "grExposure";
this.grExposure.Size = new System.Drawing.Size(249, 115);
this.grExposure.TabIndex = 49;
this.grExposure.TabStop = false;
this.grExposure.Text = "Exposure Settings";
//
// lbManualExposure
//
this.lbManualExposure.AutoSize = true;
this.lbManualExposure.Location = new System.Drawing.Point(79, 52);
this.lbManualExposure.Name = "lbManualExposure";
this.lbManualExposure.Size = new System.Drawing.Size(91, 13);
this.lbManualExposure.TabIndex = 7;
this.lbManualExposure.Text = "Manual exposure:";
//
// chAutoExposureEnabled
//
this.chAutoExposureEnabled.AutoSize = true;
this.chAutoExposureEnabled.Checked = true;
this.chAutoExposureEnabled.CheckState = System.Windows.Forms.CheckState.Checked;
this.chAutoExposureEnabled.Location = new System.Drawing.Point(11, 20);
this.chAutoExposureEnabled.Name = "chAutoExposureEnabled";
this.chAutoExposureEnabled.Size = new System.Drawing.Size(135, 17);
this.chAutoExposureEnabled.TabIndex = 6;
this.chAutoExposureEnabled.Text = "Auto exposure enabled";
this.chAutoExposureEnabled.UseVisualStyleBackColor = true;
this.chAutoExposureEnabled.CheckedChanged += new System.EventHandler(this.chAutoExposureEnabled_CheckedChanged);
//
// trManualExposure
//
this.trManualExposure.Enabled = false;
this.trManualExposure.LargeChange = 1;
this.trManualExposure.Location = new System.Drawing.Point(6, 62);
this.trManualExposure.Maximum = -5;
this.trManualExposure.Minimum = -11;
this.trManualExposure.Name = "trManualExposure";
this.trManualExposure.Size = new System.Drawing.Size(237, 45);
this.trManualExposure.TabIndex = 5;
this.trManualExposure.Value = -8;
this.trManualExposure.Scroll += new System.EventHandler(this.trManualExposure_Scroll);
//
// grTempSync
//
this.grTempSync.Controls.Add(this.btSyncDisable);
this.grTempSync.Controls.Add(this.btSyncEnable);
this.grTempSync.Controls.Add(this.lbTempSync);
this.grTempSync.Controls.Add(this.label1);
this.grTempSync.Location = new System.Drawing.Point(271, 211);
this.grTempSync.Name = "grTempSync";
this.grTempSync.Size = new System.Drawing.Size(355, 97);
this.grTempSync.TabIndex = 48;
this.grTempSync.TabStop = false;
this.grTempSync.Text = "Temporal Sync";
//
// btSyncDisable
//
this.btSyncDisable.Location = new System.Drawing.Point(104, 19);
this.btSyncDisable.Name = "btSyncDisable";
this.btSyncDisable.Size = new System.Drawing.Size(92, 23);
this.btSyncDisable.TabIndex = 4;
this.btSyncDisable.Text = "Disable";
this.btSyncDisable.UseVisualStyleBackColor = true;
this.btSyncDisable.Click += new System.EventHandler(this.btSyncDisable_click);
//
// btSyncEnable
//
this.btSyncEnable.Location = new System.Drawing.Point(6, 19);
this.btSyncEnable.Name = "btSyncEnable";
this.btSyncEnable.Size = new System.Drawing.Size(92, 23);
this.btSyncEnable.TabIndex = 3;
this.btSyncEnable.Text = "Enable";
this.btSyncEnable.UseVisualStyleBackColor = true;
this.btSyncEnable.Click += new System.EventHandler(this.btSyncEnable_click);
//
// lbTempSync
//
this.lbTempSync.Location = new System.Drawing.Point(3, 45);
this.lbTempSync.Name = "lbTempSync";
this.lbTempSync.Size = new System.Drawing.Size(342, 47);
this.lbTempSync.TabIndex = 2;
this.lbTempSync.Text = "Before activating, make sure that all Kinects are connected to the server and pro" +
"perly connected via the sync cables. When Temporal Sync is activated, the exposu" +
"re needs to be set manually!";
//
// label1
//
@@ -166,17 +251,6 @@
this.label1.TabIndex = 1;
this.label1.Text = "Notice: All devices need to be connected to the server and via sync cabel before" +
" enabeling! First Device in Server List will become the master";
//
// chSync
//
this.chSync.AutoSize = true;
this.chSync.Location = new System.Drawing.Point(6, 19);
this.chSync.Name = "chSync";
this.chSync.Size = new System.Drawing.Size(133, 17);
this.chSync.TabIndex = 0;
this.chSync.Text = "Enable Temporal Sync";
this.chSync.UseVisualStyleBackColor = true;
this.chSync.CheckedChanged += new System.EventHandler(this.chSync_CheckedChanged);
//
// grBody
//
@@ -192,6 +266,7 @@
// chSkeletons
//
this.chSkeletons.AutoSize = true;
this.chSkeletons.Enabled = false;
this.chSkeletons.Location = new System.Drawing.Point(11, 41);
this.chSkeletons.Name = "chSkeletons";
this.chSkeletons.Size = new System.Drawing.Size(154, 17);
@@ -203,6 +278,7 @@
// chBodyData
//
this.chBodyData.AutoSize = true;
this.chBodyData.Enabled = false;
this.chBodyData.Location = new System.Drawing.Point(11, 19);
this.chBodyData.Name = "chBodyData";
this.chBodyData.Size = new System.Drawing.Size(113, 17);
@@ -560,7 +636,7 @@
this.grServer.Controls.Add(this.txtICPIters);
this.grServer.Controls.Add(this.chMerge);
this.grServer.Controls.Add(this.lbICPIters);
this.grServer.Location = new System.Drawing.Point(12, 311);
this.grServer.Location = new System.Drawing.Point(12, 426);
this.grServer.Name = "grServer";
this.grServer.Size = new System.Drawing.Size(632, 114);
this.grServer.TabIndex = 44;
@@ -649,32 +725,25 @@
this.lbOuterIters.Size = new System.Drawing.Size(118, 13);
this.lbOuterIters.TabIndex = 26;
this.lbOuterIters.Text = "Num of refinement iters:";
//
// label3
//
this.label3.Location = new System.Drawing.Point(7, 36);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(342, 44);
this.label3.TabIndex = 2;
this.label3.Text = "Before activating, make sure that all Kinects are connected to the server and pro" +
"perly connected via the sync cables. The first device in the server list will be" +
"come the master!";
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(656, 431);
this.ClientSize = new System.Drawing.Size(656, 554);
this.Controls.Add(this.grServer);
this.Controls.Add(this.grClient);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "SettingsForm";
this.Text = "Settings";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.SettingsForm_FormClosed);
this.Load += new System.EventHandler(this.SettingsForm_Load);
this.grClient.ResumeLayout(false);
this.grSync.ResumeLayout(false);
this.grSync.PerformLayout();
this.grExposure.ResumeLayout(false);
this.grExposure.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trManualExposure)).EndInit();
this.grTempSync.ResumeLayout(false);
this.grBody.ResumeLayout(false);
this.grBody.PerformLayout();
this.grMarkers.ResumeLayout(false);
@@ -742,9 +811,14 @@
private System.Windows.Forms.CheckBox chSkeletons;
private System.Windows.Forms.ComboBox cbCompressionLevel;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.GroupBox grSync;
private System.Windows.Forms.CheckBox chSync;
private System.Windows.Forms.GroupBox grTempSync;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label lbTempSync;
private System.Windows.Forms.Button btSyncDisable;
private System.Windows.Forms.Button btSyncEnable;
private System.Windows.Forms.TrackBar trManualExposure;
private System.Windows.Forms.GroupBox grExposure;
private System.Windows.Forms.Label lbManualExposure;
private System.Windows.Forms.CheckBox chAutoExposureEnabled;
}
}
+100 -10
View File
@@ -30,6 +30,8 @@ namespace KinectServer
public KinectSettings oSettings;
public KinectServer oServer;
private Timer scrollTimer = null;
bool bFormLoaded = false;
public SettingsForm()
@@ -62,7 +64,12 @@ namespace KinectServer
txtICPIters.Text = oSettings.nNumICPIterations.ToString();
txtRefinIters.Text = oSettings.nNumRefineIters.ToString();
chSync.Checked = oSettings.bEnableSync;
btSyncEnable.Enabled = true;
btSyncDisable.Enabled = false;
chAutoExposureEnabled.Checked = oSettings.bAutoExposureEnabled;
trManualExposure.Value = oSettings.nExposureStep;
if (oSettings.bSaveAsBinaryPLY)
{
@@ -83,7 +90,6 @@ namespace KinectServer
if (bFormLoaded)
{
oServer.SendSettings();
oServer.SendTemporalSyncData();
}
}
@@ -348,21 +354,105 @@ namespace KinectServer
UpdateClients();
}
private void chSync_CheckedChanged(object sender, EventArgs e)
private void btSyncEnable_click(object sender, EventArgs e)
{
oSettings.bEnableSync = chSync.Checked;
if (oServer.GetAllDevicesInitialized() && oServer.nClientCount > 1)
{
oServer.RequestDeviceSyncState();
btSyncEnable.Enabled = false;
btSyncDisable.Enabled = true;
//Disable the Auto Exposure, as this could interfere with the temporal sync
chAutoExposureEnabled.Enabled = false;
trManualExposure.Enabled = true;
chAutoExposureEnabled.CheckState = CheckState.Unchecked;
}
}
private void btSyncDisable_click(object sender, EventArgs e)
{
if (oServer.GetAllDevicesInitialized())
{
oServer.DisableTemporalSync();
btSyncEnable.Enabled = true;
btSyncDisable.Enabled = false;
chAutoExposureEnabled.Enabled = true;
}
}
public void ActivateTempSyncEnableButton()
{
//As a Form code is run on a single UI thread, we need to communicate with that thread via Invoke
this.BeginInvoke(new MethodInvoker(delegate
{
btSyncEnable.Enabled = true;
btSyncDisable.Enabled = false;
chAutoExposureEnabled.Enabled = true;
}));
}
private void chAutoExposureEnabled_CheckedChanged(object sender, EventArgs e)
{
oSettings.bAutoExposureEnabled = chAutoExposureEnabled.Checked;
UpdateClients();
trManualExposure.Enabled = !oSettings.bAutoExposureEnabled;
}
private void grSync_Enter(object sender, EventArgs e)
{
/// <summary>
/// When the user scrolls on the trackbar, we wait a short amount of time to check if the user has scrolled again.
/// This prevents the Manual Exposure to be set too often, and only sets it when the user has stopped scrolling.
/// Code taken from: https://stackoverflow.com/a/15687418
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void trManualExposure_Scroll(object sender, EventArgs e)
{
if (scrollTimer == null)
{
// Will tick every 500ms
scrollTimer = new Timer()
{
Enabled = false,
Interval = 300,
Tag = (sender as TrackBar).Value
};
scrollTimer.Tick += (s, ea) =>
{
// check to see if the value has changed since we last ticked
if (trManualExposure.Value == (int)scrollTimer.Tag)
{
// scrolling has stopped so we are good to go ahead and do stuff
scrollTimer.Stop();
// Send the changed exposure to the devices
//Clamp Exposure Step between -11 and 1
int exposureStep = trManualExposure.Value;
int exposureStepClamped = exposureStep < -11 ? -11 : exposureStep > 1 ? 1 : exposureStep;
oSettings.nExposureStep = exposureStepClamped;
UpdateClients();
scrollTimer.Dispose();
scrollTimer = null;
}
else
{
// record the last value seen
scrollTimer.Tag = trManualExposure.Value;
}
};
scrollTimer.Start();
}
}
private void lbSyncWarning_Click(object sender, EventArgs e)
private void SettingsForm_FormClosed(object sender, FormClosedEventArgs e)
{
oServer.SetSettingsForm(null);
}
}
}
}