Skip to content

Commit cf6743a

Browse files
authored
Merge pull request #10 from stereolabs/fix_1_avatar_moving_per_frame
bufferize received udp data and debufferize each frame
2 parents 545ae71 + 70a2293 commit cf6743a

File tree

3 files changed

+95
-18
lines changed

3 files changed

+95
-18
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ These are located on the `ZED Skeleton Tracking Manager` script in the `Fusion M
115115
- `Enable SDK Skeleton` : controls the visibility of the stickman view of the SDK keypoints. Whereas the 3D avatar is animated using local rotations derived from the keypoints, this show the actual positions of the keypoints detected by the SDK.
116116
- `Log Fusion Metrics` : enables logging the metrics sent by the Fusion module in the console.
117117

118+
### Troubleshooting
119+
120+
If no skeleton data is received in Unity, you can either try to :
121+
122+
- Disable your firewall.
123+
- Change the port used to send the data, it might already be used by another process.
124+
118125
## Support
119126
You will find guidance and assistance :
120127
- In the [documentation of the sample](https://www.stereolabs.com/docs/livelink/livelink-unity/)

ZEDUnityLivelink/Assets/ZEDFusion/Scripts/ZEDStreamingClient.cs

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.Net.Sockets;
55
using System.Text;
66
using UnityEngine;
7+
using System.Linq;
8+
using System;
79

810
public class ZEDStreamingClient : MonoBehaviour
911
{
@@ -17,28 +19,26 @@ public class ZEDStreamingClient : MonoBehaviour
1719
public string multicastIpAddress = "230.0.0.1";
1820

1921
public bool showZEDFusionMetrics = false;
20-
22+
2123
private object obj = null;
2224
private System.AsyncCallback AC;
2325
byte[] receivedBytes;
2426

25-
int bufferSize = 10;
26-
LinkedList<byte[]> receivedDataBuffer;
27-
2827
bool newDataAvailable = false;
2928
sl.DetectionData data;
3029

3130
public delegate void onNewDetectionTriggerDelegate(sl.Bodies bodies);
3231
public event onNewDetectionTriggerDelegate OnNewDetection;
3332

33+
object mutex_buffer = new object();
34+
SortedDictionary<ulong, List<sl.DetectionData>> detectionDataDict = new SortedDictionary<ulong, List<sl.DetectionData>>();
35+
3436
void Start()
3537
{
3638
InitializeUDPListener();
3739
}
3840
public void InitializeUDPListener()
3941
{
40-
receivedDataBuffer = new LinkedList<byte[]>();
41-
4242
ipEndPointData = new IPEndPoint(IPAddress.Any, port);
4343
clientData = new UdpClient();
4444
clientData.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, optionValue: true);
@@ -60,34 +60,101 @@ public void InitializeUDPListener()
6060

6161
void ReceivedUDPPacket(System.IAsyncResult result)
6262
{
63-
//stopwatch.Start();
6463
receivedBytes = clientData.EndReceive(result, ref ipEndPointData);
6564
ParsePacket();
6665
clientData.BeginReceive(AC, obj);
6766
} // ReceiveCallBack
6867

68+
// fill detectionDataDict with received data
6969
void ParsePacket()
7070
{
71-
if (receivedDataBuffer.Count == bufferSize) receivedDataBuffer.RemoveFirst();
72-
receivedDataBuffer.AddLast(receivedBytes);
73-
newDataAvailable = true;
71+
sl.DetectionData d = sl.DetectionData.CreateFromJSON(receivedBytes);
72+
73+
// initialize data if necessary
74+
if (data==null) { data = sl.DetectionData.CreateFromJSON(receivedBytes); }
75+
76+
lock (mutex_buffer) // lock dictionary.
77+
{
78+
// add to data dictionary
79+
if (detectionDataDict.ContainsKey(d.bodies.timestamp)) // if key (timestamp) exists
80+
{
81+
detectionDataDict.GetValueOrDefault(d.bodies.timestamp).Add(d);
82+
}
83+
else // key (timestamp) does not exist yet
84+
{
85+
List<sl.DetectionData> tmpL = new List<sl.DetectionData> { d };
86+
detectionDataDict.Add(d.bodies.timestamp, tmpL);
87+
}
88+
}
7489
}
7590

76-
public bool IsNewDataAvailable()
91+
// merge bodies data from dictionary into 1 bodies data
92+
public void PrepareData()
7793
{
78-
return newDataAvailable;
94+
if(data!=null)
95+
{
96+
lock (mutex_buffer) // lock dictionary.
97+
{
98+
if (detectionDataDict.Count > 0)
99+
{
100+
sl.Bodies bodies = new sl.Bodies();
101+
102+
// get oldest timestamp from dict
103+
bodies.timestamp = detectionDataDict.First().Key;
104+
105+
// get a ref bodies
106+
sl.Bodies refBodies = detectionDataDict.First().Value.First().bodies;
107+
108+
//initialize body_list
109+
bodies.body_list = new sl.BodyData[detectionDataDict.First().Value.Count];
110+
111+
// fill bodies.body_list with list of detection data for said timestamp
112+
for (int i = 0; i < bodies.body_list.Length; ++i)
113+
{
114+
bodies.body_list[i] = detectionDataDict.First().Value[i].bodies.body_list[0];
115+
}
116+
117+
// fill additional data
118+
data.fusionMetrics = detectionDataDict.First().Value.First().fusionMetrics;
119+
bodies.body_format = refBodies.body_format;
120+
bodies.is_tracked = refBodies.is_tracked;
121+
bodies.nb_object = refBodies.nb_object;
122+
bodies.is_new = refBodies.is_new;
123+
124+
data.bodies = bodies;
125+
126+
// remove from dictionary
127+
detectionDataDict.Remove(bodies.timestamp);
128+
129+
130+
newDataAvailable = true;
131+
}
132+
else
133+
{
134+
data.bodies.is_new = 0;
135+
}
136+
}
137+
}
79138
}
80139

81-
public sl.Bodies GetLastBodiesData()
140+
public bool IsNewDataAvailable()
82141
{
83-
data = sl.DetectionData.CreateFromJSON(receivedDataBuffer.Last.Value);
84-
85-
return data.bodies;
142+
return newDataAvailable;
86143
}
87144

88145
public sl.FusionMetrics GetLastFusionMetrics()
89146
{
90-
return data.fusionMetrics;
147+
lock (mutex_buffer)
148+
{
149+
return data.fusionMetrics;
150+
}
151+
}
152+
public sl.Bodies GetLastBodies()
153+
{
154+
lock (mutex_buffer)
155+
{
156+
return data.bodies;
157+
}
91158
}
92159

93160
public bool ShowFusionMetrics()
@@ -98,9 +165,11 @@ public bool ShowFusionMetrics()
98165

99166
private void Update()
100167
{
168+
PrepareData();
101169
if (IsNewDataAvailable())
102170
{
103-
OnNewDetection(GetLastBodiesData());
171+
OnNewDetection(GetLastBodies());
172+
104173
newDataAvailable = false;
105174

106175
if (ShowFusionMetrics())

zed-unity-livelink-mono/src/PracticalSocket.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include "PracticalSocket.h"
21+
#include <cstring>
2122

2223
#ifdef WIN32
2324
#include <winsock.h> // For socket(), connect(), send(), and recv()

0 commit comments

Comments
 (0)