3

我正在使用 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 数据包的时间差,我的可视化将落后于模拟,因为它将读取下一个发出的数据包,而不是最后一个发出的数据包. 它将数据包视为一个队列。

无论如何只能从收到的最后一个数据包中获取数据?我知道至少有一种方法可以解决这个问题,因为如果我使用Rate Transfer Block设置为等于或更大的采样时间作为 UdpClient 超时,它将起作用;但我想让它比这更强大。

由于我的数据包包含有关我的模拟状态(位置、方向、时间等)的完整信息,因此我是否从不使用来自中间数据包的数据并不重要;只要我得到最新的数据,这将来自最后一个数据包。

4

1 回答 1

0

UDP 是不可靠的,并且不能保证以与发送的相同顺序接收数据包。我的建议是使用 TCP 或在数据包标头中放置某种序列号,并继续读取 UDP 数据包并只选择最新的数据包。

于 2013-04-22T18:47:01.163 回答