我正在使用Unity来可视化模拟,其中来自模拟的数据通过来自Simulink的UDP数据包发送给它。我遇到的问题源于Simulink发送UDP数据包的速率以及Unity中的脚本尝试从UDP客户端接收数据的速率。
对于我的Unity脚本,我创建了一个线程,该线程使用while循环执行一个简单的函数,并且睡眠的时间与客户端超时所需的时间相同(由我任意设置):
public void Start() {
// Setup listener.
this.mSenderAddress = IPAddress.Parse("127.0.0.1");
this.mSender = new IPEndPoint(this.mSenderAddress, 30001);
// Setup background UDP listener thread.
this.mReceiveThread = new Thread(new ThreadStart(ReceiveData));
this.mReceiveThread.IsBackground = true;
this.mReceiveThread.Start();
}
// Function to receive UDP data.
private void ReceiveData() {
try {
// Setup UDP client.
this.mClient = new UdpClient(30001);
this.mClient.Client.ReceiveTimeout = 250;
// While thread is still alive.
while(Thread.CurrentThread.IsAlive) {
try {
// Grab the data.
byte[] data = this.mClient.Receive(ref this.mSender);
// Convert the data from bytes to doubles.
double[] convertedData = new double[data.Length / 8];
for(int ii = 0; ii < convertedData.Length; ii++)
convertedData[ii] = BitConverter.ToDouble(data, 8 * ii);
// DO WHATEVER WITH THE DATA
// Sleep the thread.
Thread.Sleep(this.mClient.Client.ReceiveTimeout);
} catch(SocketException e) {
continue;
}
}
} catch(Exception e) {
Debug.Log(e.ToString());
}
}
这里,如果超时/休眠时间大于Simulink发送UDP数据包的时间差,我的可视化将落后于模拟,因为它将读取已发送的 next 数据包out而不是发送的 last 数据包。它将数据包视为队列。
无论如何只是从 last 数据包中获取数据?我知道至少有一种解决方法,因为如果我将Rate Transfer Block
设置为与UdpClient超时相等或更长的采样时间,它将起作用;但是我想让它比那更强大。
由于我的数据包包含有关模拟状态(位置,方向,时间等)的完整信息,因此我从不使用来自中间数据包的数据并不重要;只要我获得最新的数据,这将来自最后一个数据包。
答案 0 :(得分:0)
UDP不可靠,并且不保证按照发送的顺序接收数据包。我的建议是使用TCP或在数据包头中放入某种序列号,并继续读取UDP数据包,只选择最新的数据包。